From f8ff530bced2bcafe5e0e8670c6154861aa0aaed Mon Sep 17 00:00:00 2001 From: Will Mayfield Date: Mon, 7 Nov 2022 22:29:20 -0700 Subject: [PATCH 1/7] added python embedding script, conf file, and docs for new UGRID use case --- ...lysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.png | Bin 0 -> 29977 bytes .../unstructured_grids/README.rst | 4 + ...alysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py | 160 ++++++++++++++ ...ysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf | 85 +++++++ .../ugrid_lfric_mpr.py | 209 ++++++++++++++++++ 5 files changed, 458 insertions(+) create mode 100644 docs/_static/unstructured_grids-StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.png create mode 100644 docs/use_cases/model_applications/unstructured_grids/README.rst create mode 100644 docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py create mode 100644 parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf create mode 100644 parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py diff --git a/docs/_static/unstructured_grids-StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.png b/docs/_static/unstructured_grids-StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.png new file mode 100644 index 0000000000000000000000000000000000000000..4475eeac05cff148a0e7d230a34a56c6938d4ad9 GIT binary patch literal 29977 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 z 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 ZCj{q(` for more details. +# +# **YOU SHOULD NOT SET ANY OF THESE ENVIRONMENT VARIABLES YOURSELF! THEY WILL BE OVERWRITTEN BY METPLUS WHEN IT CALLS THE MET TOOLS!** +# +# If there is a setting in the MET configuration file that is currently not supported by METplus you'd like to control, please refer to: +# :ref:`Overriding Unsupported MET config file settings` +# +# .. note:: See the :ref:`StatAnalysis MET Configuration` section of the User's Guide for more information on the environment variables used in the file below: +# +# .. highlight:: bash +# .. literalinclude:: ../../../../parm/met_config/STATAnalysisConfig_wrapped + +############################################################################## +# Python Embedding +# ---------------- +# +# This use case uses a Python embedding script to read input data +# +# parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py +# +# .. highlight:: python +# .. literalinclude:: ../../../../parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py +# + +############################################################################## +# Running METplus +# --------------- +# +# It is recommended to run this use case by: +# +# Passing in StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf then a user-specific system configuration file:: +# +# run_metplus.py -c /path/to/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf -c /path/to/user_system.conf +# +# The following METplus configuration variables must be set correctly to run this example.: +# +# * **INPUT_BASE** - Path to directory where sample data tarballs are unpacked (See Datasets section to obtain tarballs). +# * **OUTPUT_BASE** - Path where METplus output will be written. This must be in a location where you have write permissions +# * **MET_INSTALL_DIR** - Path to location where MET is installed locally +# +# Example User Configuration File:: +# +# [dir] +# INPUT_BASE = /path/to/sample/input/data +# OUTPUT_BASE = /path/to/output/dir +# MET_INSTALL_DIR = /path/to/met-X.Y +# +# **NOTE:** All of these items must be found under the [dir] section. +# + + +############################################################################## +# Expected Output +# --------------- +# +# A successful run will output the following both to the screen and to the logfile:: +# +# INFO: METplus has successfully finished running. +# +# Refer to the value set for **OUTPUT_BASE** to find where the output data was generated. +# Output for this use case will be found in StatAnalysis_UGRID (relative to **OUTPUT_BASE**) +# and will contain the following file: +# +# * dump.out + +############################################################################## +# Keywords +# -------- +# +# .. note:: +# +# * StatAnalysisToolUseCase +# * PythonEmbeddingFileUseCase +# * TCandExtraTCAppUseCase +# * NOAAEMCOrgUseCase +# +# Navigate to the :ref:`quick-search` page to discover other similar use cases. +# +# +# sphinx_gallery_thumbnail_path = '_static/unstructured_grids-StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.png' diff --git a/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf new file mode 100644 index 0000000000..205c961ed6 --- /dev/null +++ b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf @@ -0,0 +1,85 @@ +[config] + +# Documentation for this use case can be found at +# https://metplus.readthedocs.io/en/latest/generated/model_applications/data_assimilation/StatAnalysis_fcstHAFS_obsPrepBufr_JEDI_IODA_interface.html + +# For additional information, please see the METplus Users Guide. +# https://metplus.readthedocs.io/en/latest/Users_Guide + +### +# Processes to run +# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#process-list +### + +PROCESS_LIST = StatAnalysis + + +### +# Time Info +# LOOP_BY options are INIT, VALID, RETRO, and REALTIME +# If set to INIT or RETRO: +# INIT_TIME_FMT, INIT_BEG, INIT_END, and INIT_INCREMENT must also be set +# If set to VALID or REALTIME: +# VALID_TIME_FMT, VALID_BEG, VALID_END, and VALID_INCREMENT must also be set +# LEAD_SEQ is the list of forecast leads to process +# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#timing-control +### + +LOOP_BY = VALID + +VALID_TIME_FMT = %Y%m%d%H +VALID_BEG=2021050500 +VALID_END=2021050500 +VALID_INCREMENT = 6H + +LEAD_SEQ = 0 + + +### +# File I/O +# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#directory-and-filename-template-info +### + +MODEL1_STAT_ANALYSIS_LOOKIN_DIR = python {PARM_BASE}/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py {INPUT_BASE}/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/fcst_data/lfric_ver_20210505_0000.nc {INPUT_BASE}/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/obs_data + +STAT_ANALYSIS_OUTPUT_DIR = {OUTPUT_BASE}/StatAnalysis_UGRID +STAT_ANALYSIS_OUTPUT_TEMPLATE = job.out +MODEL1_STAT_ANALYSIS_DUMP_ROW_TEMPLATE = dump.out + + +### +# StatAnalysis Settings +# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#statanalysis +### + +MODEL1 = NA +MODEL1_OBTYPE = NA + +STAT_ANALYSIS_JOB_NAME = aggregate_stat +STAT_ANALYSIS_JOB_ARGS = -out_line_type CNT -dump_row [dump_row_file] -line_type MPR -by FCST_VAR + +MODEL_LIST = +DESC_LIST = +FCST_LEAD_LIST = +OBS_LEAD_LIST = +FCST_VALID_HOUR_LIST = +FCST_INIT_HOUR_LIST = +OBS_VALID_HOUR_LIST = +OBS_INIT_HOUR_LIST = +FCST_VAR_LIST = +OBS_VAR_LIST = +FCST_UNITS_LIST = +OBS_UNITS_LIST = +FCST_LEVEL_LIST = +OBS_LEVEL_LIST = +VX_MASK_LIST = +INTERP_MTHD_LIST = +INTERP_PNTS_LIST = +FCST_THRESH_LIST = +OBS_THRESH_LIST = +COV_THRESH_LIST = +ALPHA_LIST = +LINE_TYPE_LIST = + +GROUP_LIST_ITEMS = +LOOP_LIST_ITEMS = MODEL_LIST diff --git a/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py new file mode 100644 index 0000000000..4596190759 --- /dev/null +++ b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py @@ -0,0 +1,209 @@ +from __future__ import print_function + +import math +import pandas as pd +import numpy as np +import os +from glob import glob +import sys +import xarray as xr +import datetime as dt +import iris +from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD +#geovista from https://github.com/bjlittle/geovista/ +import geovista as gv +import geovista.theme +from geovista.common import to_xyz +import netCDF4 +import pyvista as pv +from pykdtree.kdtree import KDTree + +from pathlib import Path +from typing import Optional + +import matplotlib.pyplot as plt + +print(f"{iris.__version__=}") +print(f"{gv.__version__=}") + +######################################################################## + +def read_ascii_obs(files): + paths = sorted(glob(files)) + datasets = [pd.read_table(p, header=None, delim_whitespace=True) for p in paths] + combined = pd.concat(datasets) + return combined + +def load_ugrid( + fname: str, + data: Optional[bool] = False, + constraint: Optional[str] = None, + verbose: Optional[bool] = False +) -> pv.PolyData: +# fname = BASE_DIR / fname + with PARSE_UGRID_ON_LOAD.context(): + cube = iris.load_cube(fname, constraint=constraint) + + if cube.ndim > 1: + cube = cube[(0,) * (cube.ndim - 1)] + + if verbose: + print(cube) + + data = cube.data if data else None + + face_node = cube.mesh.face_node_connectivity + indices = face_node.indices_by_location() + lons, lats = cube.mesh.node_coords + + mesh = gv.Transform.from_unstructured( + lons.points, + lats.points, + indices, + data=data, + start_index=face_node.start_index, + name=cube.name(), + ) + + if data is None: + mesh.active_scalars_name = None + + return mesh + +def info(mesh: pv.PolyData) -> None: + print(f"The mesh is a C{int(math.sqrt(mesh.n_cells / 6))}, with 6 panels, {int(mesh.n_cells / 6):,d} cells per panel, and {mesh.n_cells:,d} cells.") + +def find_nearest(tree, points, poi, k): + # lat/lon to xyz + xyz = to_xyz(*poi) + + # find the k nearest euclidean neighbours + dist, idxs = tree.query(xyz, k=k) + + if idxs.ndim > 1: + idxs = idxs[0] + + # retieve the associated xyz points of the k nearest neighbours + nearest = points[idxs] + + return xyz, nearest, idxs + +def to_centers(mesh: pv.PolyData) -> pv.PolyData: + tmp = mesh.copy() + tmp.clear_cell_data() + tmp.clear_point_data() + tmp.clear_field_data() + return tmp.cell_centers() + +######################################################################## +print('Python Script:\t', sys.argv[0]) + +# Input is directory of .nc lfric files and a directory of ascii obs filess + +if len(sys.argv) == 3: + # Read the input file as the first argument + input_fcst_dir = os.path.expandvars(sys.argv[1]) + input_obs_dir = os.path.expandvars(sys.argv[2]) + try: + print("Input Forecast Dir:\t" + repr(input_fcst_dir)) + print("Input Observations Dir:\t" + repr(input_obs_dir)) + + #Read all obs from directory + obs_data = read_ascii_obs(input_obs_dir+'/*.ascii') + print(obs_data.shape) + obs_data = obs_data.iloc[::1000, :]#thin for testing + obs_data = obs_data.rename(columns={0:'message_type', 1:'station_id', 2:'obs_valid_time', 3:'obs_lat', 4:'obs_lon', \ + 5:'elevation', 6:'var_name', 7:'level', 8:'height', 9:'qc_string', 10:'obs_value'}) + + obs_vars = ['UGRD', 'VGRD', 'TMP', 'RH'] + fcst_vars = ['u10m', 'v10m', 't1p5m', 'rh1p5m'] + + #open the netcdf forecast to access data values and list of times + fcst_data = xr.open_dataset(input_fcst_dir) + fcst_times = pd.to_datetime(fcst_data.coords['time_centered']) + + match_df = pd.DataFrame(columns=['message_type', 'station_id', 'obs_valid_time', 'obs_lat', 'obs_lon', \ + 'elevation', 'var_name', 'level', 'height', 'qc_string', 'obs_value', 'idx_nearest, fcst_value']) + + for idx1, (obs_var, fcst_var) in enumerate(zip(obs_vars, fcst_vars)): + + #load forecast as an iris cube + fcst_mesh = load_ugrid(input_fcst_dir, constraint=fcst_var) + info(fcst_mesh) + + #get indices of nearest cell center + fcst_centers = to_centers(fcst_mesh) + points = fcst_centers.points + tree = KDTree(points) + + #get the forecast data values loaded + fcst_df = fcst_data[fcst_var].to_dataframe() + print(fcst_df) + + #get obs data for variable + var_data = obs_data.loc[obs_data['var_name'] == obs_var].reset_index(drop=True) + + for idx2, row in var_data.iterrows(): + xyz, nearest, idx_nearest = find_nearest(tree, points, [row['obs_lat'], row['obs_lon']], k=1) + var_data.at[idx2,'idx_nearest'] = int(idx_nearest) + + #get the obs time, search for closest in the forecast data + time = dt.datetime.strptime(row['obs_valid_time'],'%Y%m%d_%H%M%S') + match_time = min(fcst_times, key=lambda d: abs(d - time)) + match_idx = np.argmin(np.abs(fcst_times - time)) + + #add matched fcst value to data + var_data.at[idx2, 'fcst_value'] = fcst_df.loc[(match_idx,int(idx_nearest)), fcst_var] + var_data.at[idx2, 'fcst_lat'] = fcst_df.loc[(match_idx,int(idx_nearest)), 'Mesh2d_face_x'] + var_data.at[idx2, 'fcst_lon'] = fcst_df.loc[(match_idx,int(idx_nearest)), 'Mesh2d_face_y'] + var_data.at[idx2, 'fcst_time'] = fcst_df.loc[(match_idx,int(idx_nearest)), 'time_centered'] + + #check results + #with pd.option_context('display.max_rows', None): + # print(var_data[['obs_lat','fcst_lat','obs_lon','fcst_lon','obs_value','fcst_value','obs_valid_time','fcst_time']]) + with pd.option_context('display.max_columns', 500, 'display.max_rows', 100, 'display.width', 500): + print(var_data) + ob_vals = var_data['obs_value'].values + f_vals = var_data['fcst_value'].values + plt.scatter(ob_vals, f_vals) + plt.title(str(obs_var)) + plt.xlabel('observation') + plt.ylabel('forecast') + plt.savefig('./scatter' + str(obs_var) + '.png') + plt.close() + + match_df = pd.concat([match_df, var_data], ignore_index=True) + + nlocs = len(match_df.index) + print('Number of locations in matched set: ' + str(nlocs)) + + # Add additional columns + match_df['lead'] = '000000' + match_df['MPR'] = 'MPR' + match_df['nobs'] = nlocs + match_df['index'] = range(0,nlocs) + match_df['na'] = 'NA' + match_df['QC'] = '0' + + # Arrange columns in MPR format + cols = ['na','na','lead','obs_valid_time','obs_valid_time','lead','obs_valid_time', + 'obs_valid_time','var_name','na','lead','var_name','na','na', + 'var_name','na','na','lead','na','na','na','na','MPR', + 'nobs','index','station_id','obs_lat','obs_lon', + 'level','na','fcst_value','obs_value', + 'QC','na','na'] + + match_df = match_df[cols] + + # Into a list and all to strings + mpr_data = [list( map(str,i) ) for i in match_df.values.tolist() ] + + except NameError: + print("Can't find the input files or the variables.") + print("Variables in this file:\t" + repr(var_list)) +else: + print("ERROR: read_ioda_mpr.py -> Must specify directory of files.\n") + sys.exit(1) + +######################################################################## + From ba4587a3b4f3876dd0509a2e18d5aa4dd9fd192d Mon Sep 17 00:00:00 2001 From: Will Mayfield Date: Thu, 10 Nov 2022 00:27:34 -0700 Subject: [PATCH 2/7] added use cases for testing and some minor fixes to python embedding script and docs --- .github/parm/use_case_groups.json | 5 +++++ .../model_applications/unstructured_grids/README.rst | 2 +- .../StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py | 5 +++-- internal/tests/use_cases/all_use_cases.txt | 4 ++++ .../ugrid_lfric_mpr.py | 8 +------- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 2f6814059a..cc41d9c034 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -218,5 +218,10 @@ "category": "tc_and_extra_tc", "index_list": "3-5", "run": false + }, + { + "category": "unstructured_grids", + "index_list": "0", + "run": false } ] diff --git a/docs/use_cases/model_applications/unstructured_grids/README.rst b/docs/use_cases/model_applications/unstructured_grids/README.rst index 0fd940caca..01adec3a07 100644 --- a/docs/use_cases/model_applications/unstructured_grids/README.rst +++ b/docs/use_cases/model_applications/unstructured_grids/README.rst @@ -1,4 +1,4 @@ Unstructured Grids ----------------- -Unstructured Grids used by model for numerical weather prediction +Unstructured grids used by models for numerical weather prediction. diff --git a/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py b/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py index 46ff94c4a9..4df8361f92 100644 --- a/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py +++ b/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py @@ -23,8 +23,9 @@ # pairs to pass to stat_analysis. In order to perform the interpolation using a # nearest-neighbors approach, the geovista python package is also used to form a # KD tree to be used in identifying the interpolation points to be used. This -# package is located at https://github.com/bjlittle/geovista/. ASCII files containing -# observations are also ingested. +# package is located at https://github.com/bjlittle/geovista/ and can be installed +# from a development version. It is also required to install the pyvista python +# package. ASCII files containing observations are also ingested. # # The python embedding script itself performs the interpolation in time, and # for this use case thins the observation data in order to reduce the run time. diff --git a/internal/tests/use_cases/all_use_cases.txt b/internal/tests/use_cases/all_use_cases.txt index ef633503aa..844213ad20 100644 --- a/internal/tests/use_cases/all_use_cases.txt +++ b/internal/tests/use_cases/all_use_cases.txt @@ -166,3 +166,7 @@ Category: tc_and_extra_tc 3::GridStat_fcstHAFS_obsTDR_NetCDF:: model_applications/tc_and_extra_tc/GridStat_fcstHAFS_obsTDR_NetCDF.conf:: py_embed 4::TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample:: model_applications/tc_and_extra_tc/TCPairs_TCStat_fcstADECK_obsBDECK_ATCF_BasicExample.conf 5::TCGen_fcstGFS_obsBDECK_2021season:: model_applications/tc_and_extra_tc/TCGen_fcstGFS_obsBDECK_2021season.conf + + +Category: unstructured_grids +0::StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed:: model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf diff --git a/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py index 4596190759..d78e17e82c 100644 --- a/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py +++ b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed/ugrid_lfric_mpr.py @@ -165,12 +165,6 @@ def to_centers(mesh: pv.PolyData) -> pv.PolyData: print(var_data) ob_vals = var_data['obs_value'].values f_vals = var_data['fcst_value'].values - plt.scatter(ob_vals, f_vals) - plt.title(str(obs_var)) - plt.xlabel('observation') - plt.ylabel('forecast') - plt.savefig('./scatter' + str(obs_var) + '.png') - plt.close() match_df = pd.concat([match_df, var_data], ignore_index=True) @@ -202,7 +196,7 @@ def to_centers(mesh: pv.PolyData) -> pv.PolyData: print("Can't find the input files or the variables.") print("Variables in this file:\t" + repr(var_list)) else: - print("ERROR: read_ioda_mpr.py -> Must specify directory of files.\n") + print("ERROR: ugrid_lfric_mpr.py -> Must specify directory of files.\n") sys.exit(1) ######################################################################## From 8d0a84fdce000936d99571f907746b5c914da396 Mon Sep 17 00:00:00 2001 From: Will Mayfield Date: Thu, 10 Nov 2022 00:33:40 -0700 Subject: [PATCH 3/7] updated docs for use case --- .../StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py b/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py index 4df8361f92..dd52057d21 100644 --- a/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py +++ b/docs/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.py @@ -152,8 +152,7 @@ # # * StatAnalysisToolUseCase # * PythonEmbeddingFileUseCase -# * TCandExtraTCAppUseCase -# * NOAAEMCOrgUseCase +# * UnstructureGridsUseCase # # Navigate to the :ref:`quick-search` page to discover other similar use cases. # From c5efe7c0cecc596289ab48c5d35269d097922cd4 Mon Sep 17 00:00:00 2001 From: Will Mayfield Date: Thu, 10 Nov 2022 00:39:59 -0700 Subject: [PATCH 4/7] fixed error in conf file comments --- .../StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf index 205c961ed6..bbca987ddf 100644 --- a/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf +++ b/parm/use_cases/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf @@ -1,7 +1,7 @@ [config] # Documentation for this use case can be found at -# https://metplus.readthedocs.io/en/latest/generated/model_applications/data_assimilation/StatAnalysis_fcstHAFS_obsPrepBufr_JEDI_IODA_interface.html +# https://metplus.readthedocs.io/en/latest/generated/model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.html # For additional information, please see the METplus Users Guide. # https://metplus.readthedocs.io/en/latest/Users_Guide From a5e8c3b55bd7a3ec9542c74914a0f11446da2e7d Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 10 Nov 2022 09:02:49 -0700 Subject: [PATCH 5/7] Add keywords for automated tests --- internal/tests/use_cases/all_use_cases.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tests/use_cases/all_use_cases.txt b/internal/tests/use_cases/all_use_cases.txt index 844213ad20..a41b56b269 100644 --- a/internal/tests/use_cases/all_use_cases.txt +++ b/internal/tests/use_cases/all_use_cases.txt @@ -169,4 +169,4 @@ Category: tc_and_extra_tc Category: unstructured_grids -0::StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed:: model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf +0::StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed:: model_applications/unstructured_grids/StatAnalysis_fcstLFRIC_UGRID_obsASCII_PyEmbed.conf:: geovista_env, py_embed From 89f2f87cb3a21b0232914f31845b3c8d0daf383a Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 10 Nov 2022 09:36:40 -0700 Subject: [PATCH 6/7] fix underline --- docs/use_cases/model_applications/unstructured_grids/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/use_cases/model_applications/unstructured_grids/README.rst b/docs/use_cases/model_applications/unstructured_grids/README.rst index 01adec3a07..7b8d40d0f2 100644 --- a/docs/use_cases/model_applications/unstructured_grids/README.rst +++ b/docs/use_cases/model_applications/unstructured_grids/README.rst @@ -1,4 +1,4 @@ Unstructured Grids ------------------ +------------------ Unstructured grids used by models for numerical weather prediction. From 0f4ad8017ab4823094946140eabcec66eaa0a348 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 10 Nov 2022 11:20:46 -0700 Subject: [PATCH 7/7] fixed check for unset or empty docker cred env vars --- .github/jobs/docker_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/jobs/docker_setup.sh b/.github/jobs/docker_setup.sh index ad20f64ecc..47116c0232 100755 --- a/.github/jobs/docker_setup.sh +++ b/.github/jobs/docker_setup.sh @@ -67,7 +67,7 @@ fi # skip docker push if credentials are not set -if [ -z ${DOCKER_USERNAME+x} ] || [ -z ${DOCKER_PASSWORD+x} ]; then +if [ -z "${DOCKER_USERNAME}" ] || [ -z "${DOCKER_PASSWORD}" ]; then echo "DockerHub credentials not set. Skipping docker push" exit 0 fi