diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 2a4da1ef67..5da16d779e 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -1,7 +1,7 @@ [ { "category": "met_tool_wrapper", - "index_list": "0-29", + "index_list": "0-29,59-61", "run": false }, { @@ -9,11 +9,6 @@ "index_list": "30-58", "run": false }, - { - "category": "met_tool_wrapper", - "index_list": "59-60", - "run": false - }, { "category": "air_quality_and_comp", "index_list": "0", diff --git a/docs/Contributors_Guide/add_use_case.rst b/docs/Contributors_Guide/add_use_case.rst index cc884963eb..1651d3aa40 100644 --- a/docs/Contributors_Guide/add_use_case.rst +++ b/docs/Contributors_Guide/add_use_case.rst @@ -638,7 +638,8 @@ created and tested. Trigger Input Data Ingest ------------------------- -If working in the *dtcenter/METplus repository*, please skip this step. +**IF WORKING IN THE *dtcenter/METplus REPOSITORY*, PLEASE SKIP THIS STEP.** + If working in a forked METplus repository, the newly added input data will not become available for the tests unless it is triggered from the dtcenter repository. A METplus developer will need to run the following steps. Please @@ -952,7 +953,7 @@ Copy data from the feature directory into the next version directory **CONDITION 2:** MET Tool Wrapper Use Cases:: - from_directory=${METPLUS_DATA_TARFILE_DIR}/${METPLUS_FEATURE_BRANCH}/met_test + from_directory=${METPLUS_DATA_TARFILE_DIR}/${METPLUS_FEATURE_BRANCH}/met_test/new echo $from_directory ls $from_directory diff --git a/docs/Users_Guide/glossary.rst b/docs/Users_Guide/glossary.rst index cf8ff44469..052c4f30d9 100644 --- a/docs/Users_Guide/glossary.rst +++ b/docs/Users_Guide/glossary.rst @@ -9653,3 +9653,258 @@ METplus Configuration Glossary Specify the value for 'match_points' in the MET configuration file for TCPairs. | *Used by:* TCPairs + + PLOT_POINT_OBS_MSG_TYP + Specify the value for 'msg_typ' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_SID_INC + Specify the value for 'sid_inc' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_SID_EXC + Specify the value for 'sid_exc' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_OBS_VAR + Specify the value for 'obs_var' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_OBS_GC + Specify the value for 'obs_gc' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_OBS_QUALITY + Specify the value for 'obs_quality' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_VALID_BEG + Specify the value for 'valid_beg' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_VALID_END + Specify the value for 'valid_end' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_LAT_THRESH + Specify the value for 'lat_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_LON_THRESH + Specify the value for 'lon_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_ELV_THRESH + Specify the value for 'elv_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_HGT_THRESH + Specify the value for 'hgt_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_PRS_THRESH + Specify the value for 'prs_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_OBS_THRESH + Specify the value for 'obs_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_CENSOR_THRESH + Specify the value for 'censor_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_CENSOR_VAL + Specify the value for 'censor_val' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_DOTSIZE + Specify the value for 'dotsize' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_LINE_COLOR + Specify the value for 'line_color' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_LINE_WIDTH + Specify the value for 'line_width' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_FILL_COLOR + Specify the value for 'fill_color' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_INPUT_DIR + Directory containing input point observation data for PlotPointObs. + This variable is optional because you can specify the full path to the + input file(s) using :term:`PLOT_POINT_OBS_INPUT_TEMPLATE`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_INPUT_TEMPLATE + Filename template of the input point observation file(s) for PlotPointObs. + See also :term:`PLOT_POINT_OBS_INPUT_DIR`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_INPUT_DIR + Directory containing input grid data for PlotPointObs. + This variable is optional because you can specify the full path to the + input file using :term:`PLOT_POINT_OBS_GRID_INPUT_TEMPLATE`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_INPUT_TEMPLATE + Filename template of the input grid file for PlotPointObs. + See also :term:`PLOT_POINT_OBS_GRID_INPUT_DIR`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_OUTPUT_DIR + Directory containing output generated by PlotPointObs. + This variable is optional because you can specify the full path to the + output file using :term:`PLOT_POINT_OBS_OUTPUT_TEMPLATE`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_OUTPUT_TEMPLATE + Filename template of the output generated by PlotPointObs. + See also :term:`PLOT_POINT_OBS_OUTPUT_DIR`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_TITLE + Sets the title for the output plot generated by PlotPointObs. + + | *Used by:* PlotPointObs + + LOG_PLOT_POINT_OBS_VERBOSITY + Overrides the log verbosity for plot_point_obs only. If not set, + the verbosity level is controlled by :term:`LOG_MET_VERBOSITY`. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_FILL_PLOT_INFO_FLAG + Specify the value for 'fill_plot_info.flag' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_FILL_PLOT_INFO_COLOR_TABLE + Specify the value for 'fill_plot_info.color_table' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MIN + Specify the value for 'fill_plot_info.plot_min' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MAX + Specify the value for 'fill_plot_info.plot_max' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_FILL_PLOT_INFO_COLORBAR_FLAG + Specify the value for 'fill_plot_info.colorbar_flag' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_FIELD + Specify the value for 'grid_data.field' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_REGRID_TO_GRID + Specify the value for 'grid_data.regrid.to_grid' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_REGRID_METHOD + Specify the value for 'grid_data.regrid.method' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_REGRID_WIDTH + Specify the value for 'grid_data.regrid.width' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_REGRID_VLD_THRESH + Specify the value for 'grid_data.regrid.vld_thresh' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_REGRID_SHAPE + Specify the value for 'grid_data.regrid.shape' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLOR_TABLE + Specify the value for 'grid_data.grid_plot_info.color_table' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MIN + Specify the value for 'grid_data.grid_plot_info.plot_min' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MAX + Specify the value for 'grid_data.grid_plot_info.plot_max' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLORBAR_FLAG + Specify the value for 'grid_data.grid_plot_info.colorbar_flag' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_POINT_DATA + Specify the value for 'point_data' in the MET configuration file for PlotPointObs. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_SKIP_IF_OUTPUT_EXISTS + If True, do not run plot_point_obs if output file already exists. + Set to False to overwrite files. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_RUNTIME_FREQ + Frequency to run PlotPointObs. See :ref:`Runtime_Freq` for more information. + + | *Used by:* PlotPointObs + + PLOT_POINT_OBS_MET_CONFIG_OVERRIDES + Override any variables in the MET configuration file that are not + supported by the wrapper. This should be set to the full variable name + and value that you want to override, including the equal sign and the + ending semi-colon. The value is directly appended to the end of the + wrapped MET config file. + + Example: + PLOT_POINT_OBS_MET_CONFIG_OVERRIDES = desc = "override_desc"; model = "override_model"; + + See :ref:`Overriding Unsupported MET config file settings` for more information + + | *Used by:* PlotPointObs diff --git a/docs/Users_Guide/quicksearch.rst b/docs/Users_Guide/quicksearch.rst index 1c4070a668..64de40cb9b 100644 --- a/docs/Users_Guide/quicksearch.rst +++ b/docs/Users_Guide/quicksearch.rst @@ -27,6 +27,7 @@ Use Cases by MET Tool: | `PCPCombine <../search.html?q=PCPCombineToolUseCase&check_keywords=yes&area=default>`_ | `Point2Grid <../search.html?q=Point2GridToolUseCase&check_keywords=yes&area=default>`_ | `PlotDataPlane <../search.html?q=PlotDataPlaneToolUseCase&check_keywords=yes&area=default>`_ + | `PlotPointObs <../search.html?q=PlotPointObsToolUseCase&check_keywords=yes&area=default>`_ | `PointStat <../search.html?q=PointStatToolUseCase&check_keywords=yes&area=default>`_ | `RegridDataPlane <../search.html?q=RegridDataPlaneToolUseCase&check_keywords=yes&area=default>`_ | `SeriesAnalysis <../search.html?q=SeriesAnalysisUseCase&check_keywords=yes&area=default>`_ @@ -53,6 +54,7 @@ Use Cases by MET Tool: | **PCPCombine**: *PCPCombineToolUseCase* | **Point2Grid**: *Point2GridToolUseCase* | **PlotDataPlane**: *PlotDataPlaneToolUseCase* + | **PlotPointObs**: *PlotPointObsToolUseCase* | **PointStat**: *PointStatToolUseCase* | **RegridDataPlane**: *RegridDataPlaneToolUseCase* | **SeriesAnalysis**: *SeriesAnalysisUseCase* diff --git a/docs/Users_Guide/wrappers.rst b/docs/Users_Guide/wrappers.rst index ad359da405..3a1b7c0af7 100644 --- a/docs/Users_Guide/wrappers.rst +++ b/docs/Users_Guide/wrappers.rst @@ -5368,7 +5368,370 @@ Configuration | :term:`PLOT_DATA_PLANE_RANGE_MIN_MAX` | :term:`PLOT_DATA_PLANE_CONVERT_TO_IMAGE` | :term:`PLOT_DATA_PLANE_SKIP_IF_OUTPUT_EXISTS` -| + +.. _plot_point_obs_wrapper: + +PlotPointObs +============ + +Description +----------- + +The PlotPointObs wrapper is a Python script that encapsulates the MET +plot_point_obs tool. It provides the infrastructure to read in any input that +MET can read and plot them. + +Configuration +------------- + +| :term:`PLOT_POINT_OBS_RUNTIME_FREQ` +| :term:`PLOT_POINT_OBS_INPUT_TEMPLATE` +| :term:`PLOT_POINT_OBS_INPUT_DIR` +| :term:`PLOT_POINT_OBS_GRID_INPUT_TEMPLATE` +| :term:`PLOT_POINT_OBS_GRID_INPUT_DIR` +| :term:`PLOT_POINT_OBS_OUTPUT_TEMPLATE` +| :term:`PLOT_POINT_OBS_OUTPUT_DIR` +| :term:`PLOT_POINT_OBS_SKIP_IF_OUTPUT_EXISTS` +| :term:`PLOT_POINT_OBS_TITLE` +| :term:`LOG_PLOT_POINT_OBS_VERBOSITY` +| :term:`PLOT_POINT_OBS_GRID_DATA_FIELD` +| :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_TO_GRID` +| :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_METHOD` +| :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_WIDTH` +| :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_VLD_THRESH` +| :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_SHAPE` +| :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLOR_TABLE` +| :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MIN` +| :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MAX` +| :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLORBAR_FLAG` +| :term:`PLOT_POINT_OBS_MSG_TYP` +| :term:`PLOT_POINT_OBS_SID_INC` +| :term:`PLOT_POINT_OBS_SID_EXC` +| :term:`PLOT_POINT_OBS_OBS_VAR` +| :term:`PLOT_POINT_OBS_OBS_GC` +| :term:`PLOT_POINT_OBS_OBS_QUALITY` +| :term:`PLOT_POINT_OBS_VALID_BEG` +| :term:`PLOT_POINT_OBS_VALID_END` +| :term:`PLOT_POINT_OBS_LAT_THRESH` +| :term:`PLOT_POINT_OBS_LON_THRESH` +| :term:`PLOT_POINT_OBS_ELV_THRESH` +| :term:`PLOT_POINT_OBS_HGT_THRESH` +| :term:`PLOT_POINT_OBS_PRS_THRESH` +| :term:`PLOT_POINT_OBS_OBS_THRESH` +| :term:`PLOT_POINT_OBS_CENSOR_THRESH` +| :term:`PLOT_POINT_OBS_CENSOR_VAL` +| :term:`PLOT_POINT_OBS_DOTSIZE` +| :term:`PLOT_POINT_OBS_LINE_COLOR` +| :term:`PLOT_POINT_OBS_LINE_WIDTH` +| :term:`PLOT_POINT_OBS_FILL_COLOR` +| :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_FLAG` +| :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_COLOR_TABLE` +| :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MIN` +| :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MAX` +| :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_COLORBAR_FLAG` +| :term:`PLOT_POINT_OBS_POINT_DATA` +| :term:`PLOT_POINT_OBS_MET_CONFIG_OVERRIDES` + + +.. _plot-point-obs-met-conf: + +MET Configuration +----------------- + +Below is the wrapped MET configuration file used for this wrapper. +Environment variables are used to control entries in this configuration file. +The default value for each environment variable is obtained from +(except where noted below): + +`MET_INSTALL_DIR/share/met/config/PlotPointObsConfig_default `_ + +Below the file contents are descriptions of each environment variable +referenced in this file and the corresponding METplus configuration item used +to set the value of the environment variable. For detailed examples showing +how METplus sets the values of these environment variables, +see :ref:`How METplus controls MET config file settings`. + +.. literalinclude:: ../../parm/met_config/PlotPointObsConfig_wrapped + +**${METPLUS_GRID_DATA_DICT}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_GRID_DATA_FIELD` + - grid_data.field + * - :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_TO_GRID` + - grid_data.regrid.to_grid + * - :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_METHOD` + - grid_data.regrid.method + * - :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_WIDTH` + - grid_data.regrid.width + * - :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_VLD_THRESH` + - grid_data.regrid.vld_thresh + * - :term:`PLOT_POINT_OBS_GRID_DATA_REGRID_SHAPE` + - grid_data.regrid.shape + * - :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLOR_TABLE` + - grid_data.grid_plot_info.color_table + * - :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MIN` + - grid_data.grid_plot_info.plot_min + * - :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MAX` + - grid_data.grid_plot_info.plot_max + * - :term:`PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLORBAR_FLAG` + - grid_data.grid_plot_info.colorbar_flag + +**${METPLUS_MSG_TYP}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_MSG_TYP` + - msg_typ + +**${METPLUS_SID_INC}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_SID_INC` + - sid_inc + +**${METPLUS_SID_EXC}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_SID_EXC` + - sid_exc + +**${METPLUS_OBS_VAR}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_OBS_VAR` + - obs_var + +**${METPLUS_OBS_GC}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_OBS_GC` + - obs_gc + +**${METPLUS_OBS_QUALITY}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_OBS_QUALITY` + - obs_quality + +**${METPLUS_VALID_BEG}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_VALID_BEG` + - valid_beg + +**${METPLUS_VALID_END}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_VALID_END` + - valid_end + +**${METPLUS_LAT_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_LAT_THRESH` + - lat_thresh + +**${METPLUS_LON_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_LON_THRESH` + - lon_thresh + +**${METPLUS_ELV_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_ELV_THRESH` + - elv_thresh + +**${METPLUS_HGT_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_HGT_THRESH` + - hgt_thresh + +**${METPLUS_PRS_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_PRS_THRESH` + - prs_thresh + +**${METPLUS_OBS_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_OBS_THRESH` + - obs_thresh + +**${METPLUS_CENSOR_THRESH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_CENSOR_THRESH` + - censor_thresh + +**${METPLUS_CENSOR_VAL}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_CENSOR_VAL` + - censor_val + +**${METPLUS_DOTSIZE}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_DOTSIZE` + - dotsize + +**${METPLUS_LINE_COLOR}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_LINE_COLOR` + - line_color + +**${METPLUS_LINE_WIDTH}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_LINE_WIDTH` + - line_width + +**${METPLUS_FILL_COLOR}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_FILL_COLOR` + - fill_color + +**${METPLUS_FILL_PLOT_INFO_DICT}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_FLAG` + - fill_plot_info.flag + * - :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_COLOR_TABLE` + - fill_plot_info.color_table + * - :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MIN` + - fill_plot_info.plot_min + * - :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MAX` + - fill_plot_info.plot_max + * - :term:`PLOT_POINT_OBS_FILL_PLOT_INFO_COLORBAR_FLAG` + - fill_plot_info.colorbar_flag + +**${METPLUS_POINT_DATA}** + +.. list-table:: + :widths: 5 5 + :header-rows: 0 + + * - METplus Config(s) + - MET Config File + * - :term:`PLOT_POINT_OBS_POINT_DATA` + - point_data + .. _point2grid_wrapper: diff --git a/docs/_static/met_tool_wrapper-PlotPointObs.png b/docs/_static/met_tool_wrapper-PlotPointObs.png new file mode 100644 index 0000000000..72dc459b91 Binary files /dev/null and b/docs/_static/met_tool_wrapper-PlotPointObs.png differ diff --git a/docs/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.py b/docs/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.py new file mode 100644 index 0000000000..ce93b0f5dd --- /dev/null +++ b/docs/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.py @@ -0,0 +1,113 @@ +""" +PlotPointObs: Basic Use Case +============================ + +met_tool_wrapper/PlotPointObs/PlotPointObs.conf + +""" +############################################################################## +# Scientific Objective +# -------------------- +# +# Generate a postscript image to plot point observations using a gridded +# file to define the domain to plot the points. + +############################################################################## +# Datasets +# -------- +# +# | **Point Observations:** NetCDF generated by PB2NC and ASCII2NC +# | **Grid:** GRIB2 NAM +# +# | **Location:** All of the input data required for this use case can be found in the met_test sample data tarball. Click here to the METplus releases page and download sample data for the appropriate release: https://github.com/dtcenter/METplus/releases +# | This tarball should be unpacked into the directory that you will set the value of INPUT_BASE. See 'Running METplus' section for more information. +# +# | **Data Source:** NAM and NDAS +# | + +############################################################################## +# METplus Components +# ------------------ +# +# This use case utilizes the METplus PlotPointObs wrapper to generate a +# command to run the MET tool plot_point_obs if all required files are found. + +############################################################################## +# METplus Workflow +# ---------------- +# +# PlotPointObs is the only tool called in this example. +# It processes the following run time: +# +# | **Valid:** 2012-04-09 12Z +# | **Forecast lead:** 12 hour +# | + +############################################################################## +# METplus Configuration +# --------------------- +# +# METplus first loads the default configuration file found in parm/metplus_config, +# then it loads any configuration files passed to METplus via the command line: +# parm/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.conf +# +# .. highlight:: bash +# .. literalinclude:: ../../../../parm/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.conf + +############################################################################## +# MET Configuration +# ----------------- +# +# METplus sets environment variables based on user settings in the METplus configuration file. +# See :ref:`How METplus controls MET config file settings` 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:`PlotPointObs 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/PlotPointObsConfig_wrapped + + +############################################################################## +# Running METplus +# --------------- +# +# Pass the use case configuration file to the run_metplus.py script +# along with any user-specific system configuration files if desired:: +# +# run_metplus.py /path/to/METplus/parm/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.conf /path/to/user_system.conf +# +# See :ref:`running-metplus` for more information. + +############################################################################## +# 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 plot_point_obs +# (relative to **OUTPUT_BASE**) +# and will contain the following file: +# +# * nam_and_ndas.20120409.t12z.prepbufr_CONFIG.ps + +############################################################################## +# Keywords +# -------- +# +# .. note:: +# +# * PlotPointObsToolUseCase +# * GRIBFileUseCase +# * NetCDFFileUseCase +# +# Navigate to the :ref:`quick-search` page to discover other similar use cases. +# +# sphinx_gallery_thumbnail_path = '_static/met_tool_wrapper-PlotPointObs.png' diff --git a/docs/use_cases/met_tool_wrapper/PlotPointObs/README.rst b/docs/use_cases/met_tool_wrapper/PlotPointObs/README.rst new file mode 100644 index 0000000000..672cc5d895 --- /dev/null +++ b/docs/use_cases/met_tool_wrapper/PlotPointObs/README.rst @@ -0,0 +1,2 @@ +PlotPointObs +------------ diff --git a/internal_tests/pytests/wrappers/plot_point_obs/test_plot_point_obs_wrapper.py b/internal_tests/pytests/wrappers/plot_point_obs/test_plot_point_obs_wrapper.py new file mode 100644 index 0000000000..3e779d81a3 --- /dev/null +++ b/internal_tests/pytests/wrappers/plot_point_obs/test_plot_point_obs_wrapper.py @@ -0,0 +1,301 @@ +#!/usr/bin/env python3 + +import pytest + +import os + +from datetime import datetime + + +from metplus.wrappers.plot_point_obs_wrapper import PlotPointObsWrapper + +obs_dir = '/some/path/obs' +input_template_one = ( + 'pb2nc/ndas.{valid?fmt=%Y%m%d}.t{valid?fmt=%H}z.prepbufr.tm00.nc' +) +input_template_two = ( + 'pb2nc/ndas.{valid?fmt=%Y%m%d}.t{valid?fmt=%H}z.prepbufr.tm00.nc,' + 'ascii2nc/trmm_{valid?fmt=%Y%m%d%H}_3hr.nc' +) + +grid_dir = '/some/path/grid' +grid_template = 'nam_{init?fmt=%Y%m%d%H}_F{lead?fmt=%3H}.grib2' + +output_dir = '{OUTPUT_BASE}/plot_point_obs' +output_template = 'nam_and_ndas.{valid?fmt=%Y%m%d}.t{valid?fmt=%H}z.prepbufr_CONFIG.ps' + +title = 'NAM 2012040900 F12 vs NDAS 500mb RH and TRMM 3h > 0' + +point_data = ['{msg_typ = "ADPSFC";obs_gc = 61;obs_thresh = > 0.0;' + 'fill_color = [0,0,255];}', + '{msg_typ = "ADPSFC";obs_var = "RH";' + 'fill_color = [100,100,100];}'] +point_data_input = ', '.join(point_data) +point_data_format = f"[{point_data_input}];" + +time_fmt = '%Y%m%d%H' +run_times = ['2012040912', '2012041000'] + + +def set_minimum_config_settings(config): + # set config variables to prevent command from running and bypass check + # if input files actually exist + config.set('config', 'DO_NOT_RUN_EXE', True) + config.set('config', 'INPUT_MUST_EXIST', False) + + # set process and time config variables + config.set('config', 'PROCESS_LIST', 'PlotPointObs') + config.set('config', 'LOOP_BY', 'VALID') + config.set('config', 'VALID_TIME_FMT', time_fmt) + config.set('config', 'VALID_BEG', run_times[0]) + config.set('config', 'VALID_END', run_times[-1]) + config.set('config', 'VALID_INCREMENT', '12H') + config.set('config', 'LEAD_SEQ', '12H') + config.set('config', 'PLOT_POINT_OBS_INPUT_DIR', obs_dir) + config.set('config', 'PLOT_POINT_OBS_INPUT_TEMPLATE', input_template_one) + config.set('config', 'PLOT_POINT_OBS_OUTPUT_DIR', output_dir) + config.set('config', 'PLOT_POINT_OBS_OUTPUT_TEMPLATE', output_template) + + +@pytest.mark.parametrize( + 'config_overrides, env_var_values', [ + # 0: no additional settings + ({},{}), + # 1: input template with 2 paths + ({'PLOT_POINT_OBS_INPUT_TEMPLATE': input_template_two}, + {}), + # 2: grid input + ({'PLOT_POINT_OBS_GRID_INPUT_TEMPLATE': grid_template, + 'PLOT_POINT_OBS_GRID_INPUT_DIR': grid_dir}, + {}), + # 3: input template with 2 paths and grid input + ({'PLOT_POINT_OBS_INPUT_TEMPLATE': input_template_two, + 'PLOT_POINT_OBS_GRID_INPUT_TEMPLATE': grid_template, + 'PLOT_POINT_OBS_GRID_INPUT_DIR': grid_dir}, + {}), + # 4: title + ({'PLOT_POINT_OBS_TITLE': title}, + {}), + # 5: input template with 2 paths and grid input and title + ({'PLOT_POINT_OBS_INPUT_TEMPLATE': input_template_two, + 'PLOT_POINT_OBS_GRID_INPUT_TEMPLATE': grid_template, + 'PLOT_POINT_OBS_GRID_INPUT_DIR': grid_dir, + 'PLOT_POINT_OBS_TITLE': title}, + {}), + # 6: grid_data.field + ({'PLOT_POINT_OBS_GRID_DATA_FIELD': '{ name = "RH"; level = "P500"; }'}, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {field = [{ name = "RH"; level = "P500"; }];}'}), + # 7: grid_data.regrid.to_grid + ({'PLOT_POINT_OBS_GRID_DATA_REGRID_TO_GRID': 'FCST', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {regrid = {to_grid = FCST;}}'}), + # 8: grid_data.regrid.method + ({'PLOT_POINT_OBS_GRID_DATA_REGRID_METHOD': 'NEAREST', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {regrid = {method = NEAREST;}}'}), + # 9: grid_data.regrid.width + ({'PLOT_POINT_OBS_GRID_DATA_REGRID_WIDTH': '2', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {regrid = {width = 2;}}'}), + # 10: grid_data.regrid.vld_thresh + ({'PLOT_POINT_OBS_GRID_DATA_REGRID_VLD_THRESH': '0.4', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {regrid = {vld_thresh = 0.4;}}'}), + # 11: grid_data.regrid.shape + ({'PLOT_POINT_OBS_GRID_DATA_REGRID_SHAPE': 'SQUARE', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {regrid = {shape = SQUARE;}}'}), + # 12: grid_data.plot_info.color_table + ({'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLOR_TABLE': 'MET_BASE/colortables/met_default.ctable', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {grid_plot_info = {color_table = "MET_BASE/colortables/met_default.ctable";}}'}), + # 13: grid_data.plot_info.plot_min + ({'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MIN': '0.1', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {grid_plot_info = {plot_min = 0.1;}}'}), + # 14: grid_data.plot_info.plot_max + ({'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MAX': '100.0', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {grid_plot_info = {plot_max = 100.0;}}'}), + # 15: grid_data.plot_info.colorbar_flag + ({'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLORBAR_FLAG': 'false', }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {grid_plot_info = {colorbar_flag = FALSE;}}'}), + # 16: grid_data all + ({'PLOT_POINT_OBS_GRID_DATA_FIELD': '{ name = "RH"; level = "P500"; }', + 'PLOT_POINT_OBS_GRID_DATA_REGRID_TO_GRID': 'FCST', + 'PLOT_POINT_OBS_GRID_DATA_REGRID_METHOD': 'NEAREST', + 'PLOT_POINT_OBS_GRID_DATA_REGRID_WIDTH': '2', + 'PLOT_POINT_OBS_GRID_DATA_REGRID_VLD_THRESH': '0.4', + 'PLOT_POINT_OBS_GRID_DATA_REGRID_SHAPE': 'SQUARE', + 'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLOR_TABLE': 'MET_BASE/colortables/met_default.ctable', + 'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MIN': '0.1', + 'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MAX': '100.0', + 'PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLORBAR_FLAG': 'False', + }, + {'METPLUS_GRID_DATA_DICT': 'grid_data = {field = [{ name = "RH"; level = "P500"; }];regrid = {to_grid = FCST;method = NEAREST;width = 2;vld_thresh = 0.4;shape = SQUARE;}grid_plot_info = {color_table = "MET_BASE/colortables/met_default.ctable";plot_min = 0.1;plot_max = 100.0;colorbar_flag = FALSE;}}'}), + # 17: msg_type + ({'PLOT_POINT_OBS_MSG_TYP': 'ADPUPA, AIRCFT', }, + {'METPLUS_MSG_TYP': 'msg_typ = ["ADPUPA", "AIRCFT"];'}), + # 18: sid_inc + ({'PLOT_POINT_OBS_SID_INC': '72364,72265', }, + {'METPLUS_SID_INC': 'sid_inc = ["72364", "72265"];'}), + # 19: sid_exc + ({'PLOT_POINT_OBS_SID_EXC': '72274,72426', }, + {'METPLUS_SID_EXC': 'sid_exc = ["72274", "72426"];'}), + # 20: obs_var + ({'PLOT_POINT_OBS_OBS_VAR': 'SPFH,TMP', }, + {'METPLUS_OBS_VAR': 'obs_var = ["SPFH", "TMP"];'}), + # 21: obs_gc + ({'PLOT_POINT_OBS_OBS_GC': '2,1', }, + {'METPLUS_OBS_GC': 'obs_gc = [2, 1];'}), + # 22: obs_quality + ({'PLOT_POINT_OBS_OBS_QUALITY': '2,1', }, + {'METPLUS_OBS_QUALITY': 'obs_quality = ["2", "1"];'}), + # 23: valid_beg + ({'PLOT_POINT_OBS_VALID_BEG': '20101231_00', }, + {'METPLUS_VALID_BEG': 'valid_beg = "20101231_00";'}), + # 24: valid_end + ({'PLOT_POINT_OBS_VALID_END': '20101231_12', }, + {'METPLUS_VALID_END': 'valid_end = "20101231_12";'}), + # 25: lat_thresh + ({'PLOT_POINT_OBS_LAT_THRESH': '>1.0', }, + {'METPLUS_LAT_THRESH': 'lat_thresh = >1.0;'}), + # 26: lon_thresh + ({'PLOT_POINT_OBS_LON_THRESH': '>1.0', }, + {'METPLUS_LON_THRESH': 'lon_thresh = >1.0;'}), + # 27: elv_thresh + ({'PLOT_POINT_OBS_ELV_THRESH': '>1.0', }, + {'METPLUS_ELV_THRESH': 'elv_thresh = >1.0;'}), + # 28: hgt_thresh + ({'PLOT_POINT_OBS_HGT_THRESH': '>1.0', }, + {'METPLUS_HGT_THRESH': 'hgt_thresh = >1.0;'}), + # 29: prs_thresh + ({'PLOT_POINT_OBS_PRS_THRESH': '>1.0', }, + {'METPLUS_PRS_THRESH': 'prs_thresh = >1.0;'}), + # 30: obs_thresh + ({'PLOT_POINT_OBS_OBS_THRESH': '>1.0', }, + {'METPLUS_OBS_THRESH': 'obs_thresh = >1.0;'}), + # 31: censor_thresh and censor_val + ({'PLOT_POINT_OBS_CENSOR_THRESH': '>12000', + 'PLOT_POINT_OBS_CENSOR_VAL': '12000'}, + {'METPLUS_CENSOR_THRESH': 'censor_thresh = [>12000];', + 'METPLUS_CENSOR_VAL': 'censor_val = [12000];'}), + # 32: dotsize + ({'PLOT_POINT_OBS_DOTSIZE': '10.0', }, + {'METPLUS_DOTSIZE': 'dotsize(x) = 10.0;'}), + # 33: line_color + ({'PLOT_POINT_OBS_LINE_COLOR': '100,105,110', }, + {'METPLUS_LINE_COLOR': 'line_color = [100, 105, 110];'}), + # 34: line_width + ({'PLOT_POINT_OBS_LINE_WIDTH': '4', }, + {'METPLUS_LINE_WIDTH': 'line_width = 4;'}), + # 35: fill_color + ({'PLOT_POINT_OBS_FILL_COLOR': '0,10,15', }, + {'METPLUS_FILL_COLOR': 'fill_color = [0, 10, 15];'}), + # 36: fill_plot_info.flag + ({'PLOT_POINT_OBS_FILL_PLOT_INFO_FLAG': 'true', }, + {'METPLUS_FILL_PLOT_INFO_DICT': 'fill_plot_info = {flag = TRUE;}'}), + # 37: fill_plot_info.color_table + ({'PLOT_POINT_OBS_FILL_PLOT_INFO_COLOR_TABLE': 'MET_BASE/colortables/met_default.ctable', }, + {'METPLUS_FILL_PLOT_INFO_DICT': 'fill_plot_info = {color_table = "MET_BASE/colortables/met_default.ctable";}'}), + # 38: fill_plot_info.plot_min + ({'PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MIN': '0.1', }, + {'METPLUS_FILL_PLOT_INFO_DICT': 'fill_plot_info = {plot_min = 0.1;}'}), + # 39: fill_plot_info.plot_max + ({'PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MAX': '100.0', }, + {'METPLUS_FILL_PLOT_INFO_DICT': 'fill_plot_info = {plot_max = 100.0;}'}), + # 40: fill_plot_info.colorbar_flag + ({'PLOT_POINT_OBS_FILL_PLOT_INFO_COLORBAR_FLAG': 'False', }, + {'METPLUS_FILL_PLOT_INFO_DICT': 'fill_plot_info = {colorbar_flag = FALSE;}'}), + # 41: fill_plot_info all + ({ + 'PLOT_POINT_OBS_FILL_PLOT_INFO_FLAG': 'true', + 'PLOT_POINT_OBS_FILL_PLOT_INFO_COLOR_TABLE': 'MET_BASE/colortables/met_default.ctable', + 'PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MIN': '0.1', + 'PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MAX': '100.0', + 'PLOT_POINT_OBS_FILL_PLOT_INFO_COLORBAR_FLAG': 'false', + }, + {'METPLUS_FILL_PLOT_INFO_DICT': 'fill_plot_info = {flag = TRUE;color_table = "MET_BASE/colortables/met_default.ctable";plot_min = 0.1;plot_max = 100.0;colorbar_flag = FALSE;}'}), + # 42: point_data + ({'PLOT_POINT_OBS_POINT_DATA': point_data_input, }, + {'METPLUS_POINT_DATA': f'point_data = {point_data_format}'}), + + ] +) +@pytest.mark.wrapper_c +def test_plot_point_obs(metplus_config, config_overrides, env_var_values): + + config = metplus_config() + + set_minimum_config_settings(config) + + # set config variable overrides + for key, value in config_overrides.items(): + config.set('config', key, value) + + wrapper = PlotPointObsWrapper(config) + assert wrapper.isOK + + app_path = os.path.join(config.getdir('MET_BIN_DIR'), wrapper.app_name) + verbosity = f"-v {wrapper.c_dict['VERBOSITY']}" + config_file = wrapper.c_dict.get('CONFIG_FILE') + input_dir = wrapper.c_dict.get('INPUT_DIR') + out_dir = wrapper.c_dict.get('OUTPUT_DIR') + expected_cmds = [ + (f"{app_path} {verbosity} " + f"{input_dir}/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc " + f"{out_dir}/nam_and_ndas.20120409.t12z.prepbufr_CONFIG.ps"), + (f"{app_path} {verbosity} " + f"{input_dir}/pb2nc/ndas.20120410.t00z.prepbufr.tm00.nc " + f"{out_dir}/nam_and_ndas.20120410.t00z.prepbufr_CONFIG.ps"), + ] + + # add -point_obs argument if template has 2 items + if ('PLOT_POINT_OBS_INPUT_TEMPLATE' in config_overrides and + len(config_overrides['PLOT_POINT_OBS_INPUT_TEMPLATE'].split(',')) > 1): + common_str = f' -point_obs {input_dir}/ascii2nc/trmm_' + expected_cmds[0] += f'{common_str}2012040912_3hr.nc' + expected_cmds[1] += f'{common_str}2012041000_3hr.nc' + + # add -plot_grid argument if provided + if 'PLOT_POINT_OBS_GRID_INPUT_TEMPLATE' in config_overrides: + common_str = f' -plot_grid {grid_dir}/nam_' + expected_cmds[0] += f'{common_str}2012040900_F012.grib2' + expected_cmds[1] += f'{common_str}2012040912_F012.grib2' + + # add -config argument + expected_cmds = [f'{item} -config {config_file}' for item in expected_cmds] + + # add -title if set + if 'PLOT_POINT_OBS_TITLE' in config_overrides: + expected_cmds = [f'{item} -title "{title}"' for item in expected_cmds] + + all_cmds = wrapper.run_all_times() + print(f"ALL COMMANDS: {all_cmds}") + assert len(all_cmds) == len(expected_cmds) + assert not wrapper.errors + + for (cmd, env_vars), expected_cmd in zip(all_cmds, expected_cmds): + # ensure commands are generated as expected + assert cmd == expected_cmd + + # check that environment variables were set properly + # including deprecated env vars (not in wrapper env var keys) + env_var_keys = (wrapper.WRAPPER_ENV_VAR_KEYS + + [name for name in env_var_values + if name not in wrapper.WRAPPER_ENV_VAR_KEYS]) + for env_var_key in env_var_keys: + match = next((item for item in env_vars if + item.startswith(env_var_key)), None) + assert match is not None + actual_value = match.split('=', 1)[1] + assert env_var_values.get(env_var_key, '') == actual_value + + +@pytest.mark.wrapper_c +def test_get_config_file(metplus_config): + fake_config_name = '/my/config/file' + + config = metplus_config() + default_config_file = os.path.join(config.getdir('PARM_BASE'), + 'met_config', + 'PlotPointObsConfig_wrapped') + + wrapper = PlotPointObsWrapper(config) + assert wrapper.c_dict['CONFIG_FILE'] == default_config_file + + config.set('config', 'PLOT_POINT_OBS_CONFIG_FILE', fake_config_name) + wrapper = PlotPointObsWrapper(config) + assert wrapper.c_dict['CONFIG_FILE'] == fake_config_name diff --git a/internal_tests/use_cases/all_use_cases.txt b/internal_tests/use_cases/all_use_cases.txt index 0d20c7ce2b..bac039a77a 100644 --- a/internal_tests/use_cases/all_use_cases.txt +++ b/internal_tests/use_cases/all_use_cases.txt @@ -60,6 +60,7 @@ Category: met_tool_wrapper 58::GenEnsProd::met_tool_wrapper/GenEnsProd/GenEnsProd.conf 59::IODA2NC::met_tool_wrapper/IODA2NC/IODA2NC.conf 60::PointStat_python_embedding_obs:: met_tool_wrapper/PointStat/PointStat_python_embedding_obs.conf +61::PlotPointObs:: met_tool_wrapper/PlotPointObs/PlotPointObs.conf Category: air_quality_and_comp 0::EnsembleStat_fcstICAP_obsMODIS_aod::model_applications/air_quality_and_comp/EnsembleStat_fcstICAP_obsMODIS_aod.conf diff --git a/metplus/util/doc_util.py b/metplus/util/doc_util.py index 9338a69369..5430084d6c 100755 --- a/metplus/util/doc_util.py +++ b/metplus/util/doc_util.py @@ -26,6 +26,7 @@ 'pb2nc': 'PB2NC', 'pcpcombine': 'PCPCombine', 'plotdataplane': 'PlotDataPlane', + 'plotpointobs': 'PlotPointObs', 'point2grid': 'Point2Grid', 'pointtogrid': 'Point2Grid', 'pointstat': 'PointStat', diff --git a/metplus/wrappers/plot_point_obs_wrapper.py b/metplus/wrappers/plot_point_obs_wrapper.py new file mode 100755 index 0000000000..3648003c87 --- /dev/null +++ b/metplus/wrappers/plot_point_obs_wrapper.py @@ -0,0 +1,262 @@ +""" +Program Name: plot_point_obs_wrapper.py +Contact(s): George McCabe +Abstract: Wrapper for plot_point_obs MET tool +History Log: Initial version +Usage: Not meant to be run +Parameters: None +Input Files: None +Output Files: None +Condition codes: 0 for success, 1 for failure +""" + +import os + +from ..util import do_string_sub, ti_calculate, get_lead_sequence +from ..util import skip_time +from . import RuntimeFreqWrapper + + +class PlotPointObsWrapper(RuntimeFreqWrapper): + """! Wrapper used to build commands to call plot_point_obs """ + + WRAPPER_ENV_VAR_KEYS = [ + 'METPLUS_GRID_DATA_DICT', + 'METPLUS_MSG_TYP', + 'METPLUS_SID_INC', + 'METPLUS_SID_EXC', + 'METPLUS_OBS_VAR', + 'METPLUS_OBS_GC', + 'METPLUS_OBS_QUALITY', + 'METPLUS_VALID_BEG', + 'METPLUS_VALID_END', + 'METPLUS_LAT_THRESH', + 'METPLUS_LON_THRESH', + 'METPLUS_ELV_THRESH', + 'METPLUS_HGT_THRESH', + 'METPLUS_PRS_THRESH', + 'METPLUS_OBS_THRESH', + 'METPLUS_CENSOR_THRESH', + 'METPLUS_CENSOR_VAL', + 'METPLUS_DOTSIZE', + 'METPLUS_LINE_COLOR', + 'METPLUS_LINE_WIDTH', + 'METPLUS_FILL_COLOR', + 'METPLUS_FILL_PLOT_INFO_DICT', + 'METPLUS_POINT_DATA', + ] + + def __init__(self, config, instance=None): + self.app_name = 'plot_point_obs' + self.app_path = os.path.join(config.getdir('MET_BIN_DIR', ''), + self.app_name) + super().__init__(config, instance=instance) + + def create_c_dict(self): + c_dict = super().create_c_dict() + app = self.app_name.upper() + + # set default runtime frequency if unset explicitly + if not c_dict['RUNTIME_FREQ']: + c_dict['RUNTIME_FREQ'] = 'RUN_ONCE_FOR_EACH' + + c_dict['VERBOSITY'] = self.config.getstr('config', + f'LOG_{app}_VERBOSITY', + c_dict['VERBOSITY']) + + # get point obs input files + c_dict['INPUT_TEMPLATE'] = self.config.getraw('config', + f'{app}_INPUT_TEMPLATE') + c_dict['INPUT_DIR'] = self.config.getdir(f'{app}_INPUT_DIR', '') + + if not c_dict['INPUT_TEMPLATE']: + self.logger.warning(f'{app}_INPUT_TEMPLATE is required ' + 'to run PlotPointObs wrapper.') + + # get optional grid input files + c_dict['GRID_INPUT_TEMPLATE'] = self.config.getraw( + 'config', + f'{app}_GRID_INPUT_TEMPLATE' + ) + c_dict['GRID_INPUT_DIR'] = self.config.getdir(f'{app}_GRID_INPUT_DIR', + '') + + # get output path + c_dict['OUTPUT_TEMPLATE'] = self.config.getraw( + 'config', + f'{app}_OUTPUT_TEMPLATE' + ) + c_dict['OUTPUT_DIR'] = self.config.getdir(f'{app}_OUTPUT_DIR', '') + + # get optional title command line argument + c_dict['TITLE'] = self.config.getraw('config', f'{app}_TITLE') + + # read config file settings + + # get the MET config file path or use default + c_dict['CONFIG_FILE'] = ( + self.get_config_file('PlotPointObsConfig_wrapped') + ) + + # handle grid_data dictionary + self.add_met_config_dict('grid_data', { + 'field': ('list', 'remove_quotes'), + 'regrid': ('dict', '', { + 'to_grid': ('string', 'uppercase,to_grid'), + 'method': ('string', 'uppercase,remove_quotes'), + 'width': 'int', + 'vld_thresh': 'float', + 'shape': ('string', 'uppercase,remove_quotes'), + }), + 'grid_plot_info': ('dict', '', { + 'color_table': 'string', + 'plot_min': 'float', + 'plot_max': 'float', + 'colorbar_flag': 'bool', + }), + }) + + # string lists + config_lists = [ + 'msg_typ', + 'sid_inc', + 'sid_exc', + 'obs_var', + 'obs_quality', + ] + for config_list in config_lists: + self.add_met_config(name=config_list, data_type='list') + + # integer and thresh lists + config_lists = [ + 'obs_gc', + 'censor_thresh', + 'censor_val', + 'line_color', + 'fill_color', + ] + for config_list in config_lists: + self.add_met_config(name=config_list, data_type='list', + extra_args={'remove_quotes': True}) + + config_strings = [ + 'valid_beg', + 'valid_end', + ] + for config_string in config_strings: + self.add_met_config(name=config_string, data_type='string') + + config_threshs = [ + 'lat_thresh', + 'lon_thresh', + 'elv_thresh', + 'hgt_thresh', + 'prs_thresh', + 'obs_thresh', + ] + for config_thresh in config_threshs: + self.add_met_config(name=config_thresh, data_type='string', + extra_args={'remove_quotes': True}) + + self.add_met_config(name='dotsize(x)', data_type='string', + extra_args={'remove_quotes': True}, + metplus_configs=[f'{app}_DOTSIZE'], + env_var_name='METPLUS_DOTSIZE') + self.add_met_config(name='line_width', data_type='int') + + self.add_met_config_dict('fill_plot_info', { + 'flag': 'bool', + 'color_table': 'string', + 'plot_min': 'float', + 'plot_max': 'float', + 'colorbar_flag': 'bool', + }) + + self.add_met_config(name='point_data', + data_type='list', + extra_args={'remove_quotes': True}) + + c_dict['ALLOW_MULTIPLE_FILES'] = True + return c_dict + + def get_command(self): + return (f"{self.app_path} -v {self.c_dict['VERBOSITY']}" + f" {self.infiles[0]} {self.get_output_path()}" + f" {' '.join(self.args)}") + + def run_at_time_once(self, time_info): + """! Process runtime and try to build command to run plot_point_obs. + + @param time_info dictionary containing timing information + @returns True if command was built/run successfully or + False if something went wrong + """ + # get input files + if not self.find_input_files(time_info): + return False + + # get output path + if not self.find_and_check_output_file(time_info): + return False + + # get other configurations for command + self.set_command_line_arguments(time_info) + + # set environment variables if using config file + self.set_environment_variables(time_info) + + # build command and run + return self.build() + + def find_input_files(self, time_info): + """! Get all input files for plot_point_obs. Sets self.infiles list. + + @param time_info dictionary containing timing information + @returns List of files that were found or None if no files were found + """ + input_files = self.find_data(time_info, + return_list=True, + mandatory=True) + if input_files is None: + return None + + self.infiles.extend(input_files) + + # get optional grid file path + if self.c_dict['GRID_INPUT_TEMPLATE']: + grid_file = self.find_data(time_info, + data_type='GRID', + return_list=True) + if not grid_file: + return None + + if len(grid_file) > 1: + self.log_error('More than one file found from ' + 'PLOT_POINT_OBS_GRID_INPUT_TEMPLATE: ' + f'{grid_file.split(",")}') + return None + + self.c_dict['GRID_INPUT_PATH'] = grid_file[0] + + return self.infiles + + def set_command_line_arguments(self, time_info): + """! Set all arguments for plot_point_obs command. + + @param time_info dictionary containing timing information + """ + # if more than 1 input file was found, add them with -point_obs + for infile in self.infiles[1:]: + self.args.append(f'-point_obs {infile}') + + if self.c_dict.get('GRID_INPUT_PATH'): + grid_file = do_string_sub(self.c_dict['GRID_INPUT_PATH'], + **time_info) + self.args.append(f'-plot_grid {grid_file}') + + config_file = do_string_sub(self.c_dict['CONFIG_FILE'], **time_info) + self.args.append(f'-config {config_file}') + + if self.c_dict.get('TITLE'): + title = do_string_sub(self.c_dict['TITLE'], **time_info) + self.args.append(f'-title "{title}"') diff --git a/parm/met_config/PlotPointObsConfig_wrapped b/parm/met_config/PlotPointObsConfig_wrapped new file mode 100644 index 0000000000..2194f01fee --- /dev/null +++ b/parm/met_config/PlotPointObsConfig_wrapped @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Plot-Point-Obs configuration file. +// +// For additional information, please see the MET Users Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// Gridded data plotting options + +//grid_data = { +${METPLUS_GRID_DATA_DICT} + +//////////////////////////////////////////////////////////////////////////////// + +// Point data filtering options +// May be set separately in each "point_data" entry + +//msg_typ = +${METPLUS_MSG_TYP} + +//sid_inc = +${METPLUS_SID_INC} + +//sid_exc = +${METPLUS_SID_EXC} + +//obs_var = +${METPLUS_OBS_VAR} + +//obs_gc = +${METPLUS_OBS_GC} + +//obs_quality = +${METPLUS_OBS_QUALITY} + +//valid_beg = +${METPLUS_VALID_BEG} + +//valid_end = +${METPLUS_VALID_END} + +//lat_thresh = +${METPLUS_LAT_THRESH} + +//lon_thresh = +${METPLUS_LON_THRESH} + +//elv_thresh = +${METPLUS_ELV_THRESH} + +//hgt_thresh = +${METPLUS_HGT_THRESH} + +//prs_thresh = +${METPLUS_PRS_THRESH} + +//obs_thresh = +${METPLUS_OBS_THRESH} + +// Point data pre-processing options +// May be set separately in each "point_data" entry + +//convert(x) = x; + +//censor_thresh = +${METPLUS_CENSOR_THRESH} + +//censor_val = +${METPLUS_CENSOR_VAL} + + +// Point data plotting options +// May be set separately in each "point_data" entry + +//dotsize = +${METPLUS_DOTSIZE} + +//line_color = +${METPLUS_LINE_COLOR} + +//line_width = +${METPLUS_LINE_WIDTH} + +//fill_color = +${METPLUS_FILL_COLOR} + +//fill_plot_info = { +${METPLUS_FILL_PLOT_INFO_DICT} + +// Array of point data filtering, pre-processing, and plotting options +//point_data = +${METPLUS_POINT_DATA} + +tmp_dir = "${MET_TMP_DIR}"; + +//////////////////////////////////////////////////////////////////////////////// + +${METPLUS_MET_CONFIG_OVERRIDES} diff --git a/parm/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.conf b/parm/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.conf new file mode 100644 index 0000000000..304e1c5253 --- /dev/null +++ b/parm/use_cases/met_tool_wrapper/PlotPointObs/PlotPointObs.conf @@ -0,0 +1,133 @@ +[config] + + +# Documentation for this use case can be found at +# https://metplus.readthedocs.io/en/latest/generated/met_tool_wrapper/PlotPointObs/PlotPointObs.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 = PlotPointObs + + +### +# 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 +### + +PLOT_POINT_OBS_RUNTIME_FREQ = RUN_ONCE_FOR_EACH + +LOOP_BY = VALID +VALID_TIME_FMT = %Y%m%d%H +VALID_BEG = 2012040912 +VALID_END = 2012040912 +VALID_INCREMENT = 1M + +LEAD_SEQ = 12H + + +### +# File I/O +# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#directory-and-filename-template-info +### + +PLOT_POINT_OBS_INPUT_DIR = {INPUT_BASE}/met_test/new/test_out +PLOT_POINT_OBS_INPUT_TEMPLATE = + pb2nc/ndas.{valid?fmt=%Y%m%d}.t{valid?fmt=%H}z.prepbufr.tm00.nc, + ascii2nc/trmm_{valid?fmt=%Y%m%d%H}_3hr.nc + +PLOT_POINT_OBS_GRID_INPUT_DIR = {INPUT_BASE}/met_test/new/model_data/grib2/nam +PLOT_POINT_OBS_GRID_INPUT_TEMPLATE = nam_{init?fmt=%Y%m%d%H}_F{lead?fmt=%3H}.grib2 + +PLOT_POINT_OBS_OUTPUT_DIR = {OUTPUT_BASE}/plot_point_obs +PLOT_POINT_OBS_OUTPUT_TEMPLATE = nam_and_ndas.{valid?fmt=%Y%m%d}.t{valid?fmt=%H}z.prepbufr_CONFIG.ps + +#PLOT_POINT_OBS_SKIP_IF_OUTPUT_EXISTS = False + + +### +# PlotPointObs Settings +# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#plotpointobs +### + +PLOT_POINT_OBS_TITLE = NAM {init?fmt=%Y%m%d%H} F{lead?fmt=%2H} vs NDAS 500mb RH and TRMM 3h > 0 + +#PLOT_POINT_OBS_CONFIG_FILE = {PARM_BASE}/met_config/PlotPointObsConfig_wrapped + +#LOG_PLOT_POINT_OBS_VERBOSITY = 2 + +PLOT_POINT_OBS_GRID_DATA_FIELD = { name = "RH"; level = "P500"; } +PLOT_POINT_OBS_GRID_DATA_REGRID_TO_GRID = NONE +#PLOT_POINT_OBS_GRID_DATA_REGRID_METHOD = +#PLOT_POINT_OBS_GRID_DATA_REGRID_WIDTH = +#PLOT_POINT_OBS_GRID_DATA_REGRID_VLD_THRESH = +#PLOT_POINT_OBS_GRID_DATA_REGRID_SHAPE = +PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLOR_TABLE = MET_BASE/colortables/NCL_colortables/BlueGreen14.ctable +#PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MIN = +PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_PLOT_MAX = 100.0 +#PLOT_POINT_OBS_GRID_DATA_GRID_PLOT_INFO_COLORBAR_FLAG = + +#PLOT_POINT_OBS_MSG_TYP = +#PLOT_POINT_OBS_SID_INC = +#PLOT_POINT_OBS_SID_EXC = +#PLOT_POINT_OBS_OBS_VAR = +#PLOT_POINT_OBS_OBS_GC = +#PLOT_POINT_OBS_OBS_QUALITY = +#PLOT_POINT_OBS_VALID_BEG = +#PLOT_POINT_OBS_VALID_END = +#PLOT_POINT_OBS_LAT_THRESH = +#PLOT_POINT_OBS_LON_THRESH = +#PLOT_POINT_OBS_ELV_THRESH = +#PLOT_POINT_OBS_HGT_THRESH = +#PLOT_POINT_OBS_PRS_THRESH = +#PLOT_POINT_OBS_OBS_THRESH = +#PLOT_POINT_OBS_CENSOR_THRESH = +#PLOT_POINT_OBS_CENSOR_VAL = +#PLOT_POINT_OBS_DOTSIZE = +#PLOT_POINT_OBS_LINE_COLOR = +#PLOT_POINT_OBS_LINE_WIDTH = +#PLOT_POINT_OBS_FILL_COLOR = + +#PLOT_POINT_OBS_FILL_PLOT_INFO_FLAG = +#PLOT_POINT_OBS_FILL_PLOT_INFO_COLOR_TABLE = +#PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MIN = +#PLOT_POINT_OBS_FILL_PLOT_INFO_PLOT_MAX = +#PLOT_POINT_OBS_FILL_PLOT_INFO_COLORBAR_FLAG = + +PLOT_POINT_OBS_POINT_DATA = + { + msg_typ = "ADPSFC"; + obs_gc = 61; + obs_thresh = > 0.0; + fill_color = [0, 0, 255]; + }, + { + msg_typ = "ADPSFC"; + obs_var = "RH"; + fill_color = [100, 100, 100]; + }, + { + msg_typ = "ADPUPA"; + obs_var = "RH"; + prs_thresh = == 500; + dotsize(x) = 7.5; + line_color = [0, 0, 0]; + fill_plot_info = { + flag = TRUE; + color_table = "MET_BASE/colortables/NCL_colortables/BlueGreen14.ctable"; + plot_min = 0.0; + plot_max = 100.0; + colorbar_flag = FALSE; + } + }