From e1b47693427b7d26518e5023f81a637e727ffa31 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:47:28 -0600 Subject: [PATCH] Update develop-ref after #2710 (#2731) --- .github/update_truth_change_log.txt | 1 + .github/workflows/sonarqube.yml | 3 + docs/Contributors_Guide/add_use_case.rst | 306 +++++++++++++++--- .../continuous_integration.rst | 4 + docs/Users_Guide/glossary.rst | 20 ++ docs/Users_Guide/wrappers.rst | 54 +++- .../use_case_documentation_template.py | 213 ++++++++++++ .../test_ensemble_stat_wrapper.py | 5 + .../point_stat/test_point_stat_wrapper.py | 4 + metplus/VERSION | 2 +- metplus/wrappers/ensemble_stat_wrapper.py | 9 + metplus/wrappers/point_stat_wrapper.py | 9 + parm/met_config/EnsembleStatConfig_wrapped | 5 + parm/met_config/PointStatConfig_wrapped | 6 + .../EnsembleStat/EnsembleStat.conf | 3 + .../met_tool_wrapper/PointStat/PointStat.conf | 3 + ..._fcstGFS_obsJASON3_satelliteAltimetry.conf | 2 +- .../read_satData.py | 15 +- .../calc_amdar_pblh.py | 2 - ...sis_fcstNMME_obsCPC_seasonal_forecast.conf | 12 +- ush/master_metplus.py | 11 +- 21 files changed, 631 insertions(+), 58 deletions(-) create mode 100644 docs/use_cases/use_case_documentation_template.py mode change 120000 => 100755 ush/master_metplus.py diff --git a/.github/update_truth_change_log.txt b/.github/update_truth_change_log.txt index 59e370f2e9..731c759593 100644 --- a/.github/update_truth_change_log.txt +++ b/.github/update_truth_change_log.txt @@ -9,3 +9,4 @@ [20240926_16:50:38 develop] #2701 - #2701 added a new use case (SeriesAnalysis_aggr) that produces new output [20241014_19:42:56 develop] dtcenter/MET#2988 - dtcenter/MET#2988 -- see issue #2719 for details -- retry because there was an issue with convert not being available in the ubuntu image that runs the unit tests [20241015_17:11:29 develop] dtcenter/MET#2988 - dtcenter/MET#2988 -- see issue #2719 for details -- retry (again) because there was an issue with convert not being available in the ubuntu image that runs the unit tests and METdbLoad use cases were broken +[20241016_20:39:30 develop] #2710 - #2710 fixed a bug in a use case diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index 694697b94c..613a06bcdd 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -64,6 +64,9 @@ jobs: python3 -m pip install --upgrade pip python3 -m pip install -r internal/tests/pytests/requirements.txt + - name: Install ImageMagick convert + run: sudo apt install imagemagick + - name: Run Pytests run: coverage run -m pytest internal/tests/pytests env: diff --git a/docs/Contributors_Guide/add_use_case.rst b/docs/Contributors_Guide/add_use_case.rst index 56f8815dbe..5f61469bc1 100644 --- a/docs/Contributors_Guide/add_use_case.rst +++ b/docs/Contributors_Guide/add_use_case.rst @@ -8,6 +8,8 @@ Adding Use Cases .. |metplus_staging_dir| replace:: /d2/projects/METplus/METplus_Data_Staging .. |dtc_web_server| replace:: mohawk.rap.ucar.edu +.. _work_in_a_feature_branch: + Work in a Feature Branch ======================== @@ -147,10 +149,48 @@ Use Case Rules be used so that users can locate other use cases that exhibit common *functionality/data sources/tools/etc*. If a new keyword is used, it should be added to the Quick Search Guide (*docs/Users_Guide/quicksearch.rst*). More - information can be found :ref:`here `. + information can be found :ref:`here `. - The use case should be run by someone other than the author to ensure that it runs smoothly outside of the development environment set up by the author. +Use Cases That Involve METcalcpy/METplotpy/METdataio +---------------------------------------------------- + +Some use cases call scripts that are located in METcalcpy, METplotpy, and/or METdataio. +This could include the calculation of an index or pre-processing steps in METcalcpy, +plotting in METplotpy, reading data using METdataio, or a combination of all three. +These use cases typically run with a driver script that is called from METplus with +the UserScript option. A driver script calls specific programs in METcalcpy, METplotpy, +and/or METdataio and passes data from one program to the other. + +Any changes to METcalcpy, METplotpy, and/or METdataio must be merged into the +develop branch of those repositories so they will be available in the use case tests. +This means that any pull requests in METcalcpy, METplotpy, and METdataio must +be completed before use case testing can proceed in GitHub Actions. +Please confirm that the use case can run successfully before creating a pull request. + +To run in GitHub Actions, the environment specified in all_use_cases.txt must contain +all required dependencies. This includes a Conda environment that contains the +required Python packages needed to run the METplus Analysis Python tools, e.g. +metplotpy_env. +A list of the existing Conda Environments and the packages they contain can also be +found in the :ref:`Conda Environments ` section. +If the package requirements aren’t met by one of the existing +Conda Environments, please create a post on the `METplus GitHub Discussions Forum +`_ for assistance. + +Existing Use Case Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Below is a list of some (not all) of the use cases which use driver scripts and involve +calculations in METcalcpy, METplotpy, and/or METdataio. +This list is provided for reference and examples. + +- *model_applications/s2s_mid_lat/UserScript_fcstGFS_obsERA_WeatherRegime* +- *model_applications/s2s_stratosphere/UserScript_fcstGFS_obsERA_StratosphereQBO* +- *model_applications/s2s_mjo/UserScript_obsCFSR_obsOnly_MJO_ENSO* +- *model_applications/s2s/UserScript_fcstS2S_obsERAI_CrossSpectra* + .. _actions-failure-use-cases: Use Cases That Cannot be Run in GitHub Actions @@ -204,62 +244,248 @@ category in the User's Guide > METplus Use Cases > `Model Applications `_ page. +.. _add_sphinx_documentation_file: + Add Sphinx Documentation File ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In the corresponding documentation MET tool name directory -(**docs**/*use_cases/met_tool_wrapper/*) for a met_tool_wrappers +(*docs*/*use_cases/met_tool_wrapper/*) for a met_tool_wrappers use case OR category directory for a model_applications use case -(**docs**/*use_cases/model_applications/*), add: +(*docs*/*use_cases/model_applications/*), users will need to add a +Python Sphinx Documentation (.py) file with the same name as the METplus configuration file. + +The following is a discussion of the use case documentation template and all of its sections. +The `example template `_ is available within the METplus repository. +The example template should be used by users as a starting point, but will need to be completely +updated with the use case's information. The template applies to both met_tool_wrappers and model_applications use cases. +When completing the template, users should read through each section and its description +below before filling in a section, as some sections may not apply +to the use case being documented. To assist reviewers and contributors, a special string:: + +# [UPDATE_SECTION_CONTENT] + +has been added to each section described below. As you review the template and adapt it for your use case, +please remove this line when you've decided the existing content is sufficient or after you've added +content specific to your use case. For real examples, users are encouraged to review +existing `Model Applications `_ +use case documentation. Except for the Header and Path to Use Case Configuration File section, +all lines should begin with the '#' character to signify text, followed by at least one space before +the text content. These are already provided in the example template. + +* Use Case Template Description: + + * Header and Path to Use Case Configuration File + + * This section begins with {PrimaryAnalysisToolName}: Brief (12 words or less) + and a unique description of use case, followed on the next line by ‘=’ characters + equal in length to the header (spaces included). Follow this with one line of no characters, + then the path to the use case configuration file. This should be written in the format of + model_applications/{use_case_category}/{use_case_configuration_file}. + This section is preceded and followed by three ‘“‘ characters (i.e. `PEP 257 Docstring convention. `_ + + * Internal Table of Contents + + * This section consists of set language using Read The Docs notation, generating a + table of contents within the use case documentation. This should be copied with + no alterations. + + * Scientific Objective + + * This section should answer why this use case was created and included in the repository. + What is a user gaining by using this use case? If the details do not add to + the why this use case exists, those details do not belong in this section. + + * Version Added + + * This represents the METplus version number that this use case was added to + the METplus repository. It also represents the minimum or lowest METplus version + this use case has been tested against. It should not include + betas (ex. Version 5.1 beta 3), but should include the two-digit version number. + + * Datasets + + * This section should include a brief description of each model dataset + and variable field (10 m wind speed, 2 m temperature, etc.) being used + in the use case, as well as which field (forecast, observation, climatology, masking, etc.) + is using which dataset. At a minimum, users should list the + Forecast, Observation, and Climatology fields. If they are not being used, + "None" can be listed. + Acronyms should be spelled out (i.e not GFS, but Global Forecast System). + This section also includes a Location description consisting of + set language of how users can access the use case data for themselves. + + * METplus Components + + * This section lists the tools that will be used during the use case. + If there are multiple tools, a brief overview should be provided of what each tool + is responsible for (i.e. GenVxMask for creating masks that are used in + the verification step, which is completed by GridStat). If Python embedding + is used, it can be mentioned here as well. + It’s important to note that this section should NOT give detailed + descriptions into why each tool is used, detailed information on how each tool + is being used and interacting with other tools (if any), etc. If there is a desire + to explain more about each tool’s role in the use case, the information can be + presented in the “METplus Workflow” section. + + * METplus Workflow + + * This section should begin with the init or valid times (both beginning and end), + time increment, as well as any lead times being used. This should be followed + by descriptions of the number of times the use case will run + (which could also be inferred from the init/valid times), what each tool is doing + to a level of detail sufficient for users to understand the use case workflow, + and any other special notes that users should be aware of. + Note that if there is Python embedding, descriptions of what it accomplishes + should be saved for the “Python Embedding” section. A mention of the input to + the Python script and its returned dataset is sufficient for this section. + + * METplus Configuration + + * This section has set language that describes how all of the configuration files + are loaded into METplus, followed by what’s passed in by the user at runtime, + and used to produce the final configuration file that controls the METplus run. + It concludes with an embedded link (and image) of the user’s configuration file + the use case will run. The only two pieces that will change are the path to the + use case’s configuration file, and the embedded configuration file for the use case. + + * MET Configuration + + * This section has set language that describes how settings in the MET configuration file + will ultimately be used to run METplus, along with any changes made from the default + by the user’s configuration file. It concludes with an embedded link (and image) of + the default configuration file(s) for all MET tool(s) used. Any configuration file(s) + listed will be hidden by default using a dropdown option. The only changes that need + to occur for this section is which MET configuration file(s) is(are) embedded and the name of + the dropdown. + If no MET tool(s) are used, that should be noted here along with replacing the default language. + + * Python Embedding + + * This section should provide a description of any Python embedding that’s used + in the use case. + For a common definition, Python embedding is used to ingest a dataset not + natively available for METplus intake, and results in a dataset being + returned to METplus for analysis and verification purposes. + This section should discuss what is passed to the script from METplus, + what is being done by the script, and what data structure is passed back + to METplus for evaluation. The end of this section is set language + directing users to review the Python requirements in the MET User’s Guide, + as well as an embedded link (and image) of all Python scripts used in + Python Embedding. The links to these scripts will need to be updated by + the user. + If no Python embedding is used, that should be noted here. + + * User Scripting + + * This section should provide a description of any Python scripting that’s used + in the use case. For a common definition, User scripting is any condition where + the evaluation/verification/output processes are being completed inside the Python script, + outside of METplus. Essentially, if a Python script is called and a + METplus-readable dataset is not passed back to METplus, it is User Scripting. + The METplus wrapper usage only exists to call the Python script. + This section should discuss what is being done by the script and why the decision was + made to use User scripting rather than Python embedding. The end of this section is + an embedded link (and image) of all Python scripts used in User Scripting. The links + to these scripts will need to be updated by the user. + If no User scripting is used, that should be noted here. + + * Running METplus + + * Similar to “MET Configuration”, this section has set language that should not be altered. + The only change between use cases is the path entered in the run command, + which is use case specific. + + * Expected Output + + * This section begins with set language that shows what message a + successful METplus run concludes with. Then, it should direct users to the + proper folder (folders, if multiple outputs are made) and directory structure + where the final output is. If the use case creates intermediate output, it should + be mentioned here as well. A list of the files and folders that are created + should be provided. Currently the documentation notation used to list all output + is a copyable block which is created from the use of spacing and two ":" characters. + This is done so that a browser's rendering of the Expected Output list will not + run off the page. + If a netCDF is the output, the total number and name of each variable field + inside the file should be listed. If there are numerous variable fields + within the file, a summary is sufficient. + If an image is created, it should be used as the use case image and referenced in + this section as output. + If no output is created, this section should explain why and what the user accomplished + by running the use case. + + * Keywords + + * All keywords relevant to the use case should be added to this section + as a bulleted list, as well as keeping the set language at the end of the list. + If an important identifier for this use case is not currently set as a + keyword in the :ref:`quick-search`, be sure to add it to the list of keywords + before using it in the use case documentation. Instructions for doing so can + be found in the :ref:`create-quick-search-keyword` section. + Users should also use the end of this section to reference an image that + will serve as a thumbnail for the use case. If no image is provided, + a default image will be used; this is the same image used for all met_tool_wrapper + use cases. -* A Python Sphinx Documentation (.py) file with the same name as the METplus - configuration file +.. note:: + Text that ends with an underscore (_) may be interpreted as a reference, so + avoid ending a line with this character to avoid generating warnings in the + documentation. + +In addition to completing the above template, users should complete all of the (applicable) +following documentation steps: + +* Update the list of External Dependencies (if applicable) to include any + required Python packages. Update the :ref:`components_python_packages` + section. If the package is already listed, add a link to the documentation + page for this new use case in the dropdown menu for that package, following the + format in the dropdown menu. If the package is not already listed, update + the dropdown menus to include the name of the required package, the version, + the METplus component (e.g. METplus wrappers, METcalcpy, METplotpy), the + source, a brief description of the package, and a link to this new use + case that uses this new Python package. + - * Users are encouraged to copy an existing documentation file and modify it - to describe the new use case. +* Add an image to use as the thumbnail. Images can be added + to the *docs/_static* directory and should be named + -.png + where is the use case category and is the name of the + configuration file, i.e. + **air_quality_and_comp-EnsembleStat_fcstICAP_obsMODIS_aod.png.** + This is the same image that is referenced in the documentation file with this syntax: - * Update any references to the .conf file to use the correct name. +:: - * Update the Scientific Objective section to describe the use case. + # sphinx_gallery_thumbnail_path = '_static/air_quality_and_comp-EnsembleStat_fcstICAP_obsMODIS_aod.png' - * Update the description of the input data in the Datasets section. - * Update the list of External Dependencies (if applicable) to include any - required Python packages. Update the :ref:`components_python_packages` - section. If the package is already listed, add a link to the documentation - page for this new use case in the dropdown menu for that package, following the - format in the dropdown menu. If the package is not already listed, update - the dropdown menus to include the name of the required package, the version, - the METplus component (e.g. METplus wrappers, METcalcpy, METplotpy), the - source, a brief description of the package, and a link to this new use - case that uses this new Python package. - - * Update the list of tools used in the METplus Components section. +.. _create-quick-search-keyword: - * Update the list of run times in the METplus Workflow section. +Create New Quick Search Keyword +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * Update the list of keywords, referring to :ref:`quick-search` for - a list of possible keywords to use (Note: The link text for the - keywords must match the actual keyword exactly or it will not - show up in the search, i.e. **ASCII2NCToolUseCase** must match - https://metplus.readthedocs.io/en/latest/search.html?q=**ASCII2NCToolUseCase**. +If a review of the keywords in the :ref:`quick-search` reveals that a new +keyword would be beneficial, users can add a keyword using the following steps. +Note that a keyword should be applicable to more than one existing use case, or +seen as beneficial to upcoming use cases. - * Add an image to use as the thumbnail (if desired). Images can be added - to the *docs/_static* directory and should be named - -.png - where is the use case category and is the name of the - configuration file, i.e. - **air_quality_and_comp-EnsembleStat_fcstICAP_obsMODIS_aod.png.** - The image can be referenced in the documentation file with this syntax: +* Open the quicksearch.rst file +* Determine a name for the keyword following the format of the existing keywords in the appropriate section. -:: + * All keywords should be one word with the first letter of each word capitalized (i.e. CamelCase). + * All keywords should end with "UseCase" + * Keywords in the "Use Cases by MET Tool" section should end with "ToolUseCase" + * Keywords in the "Use Cases by Application" section should end with "AppUseCase" + * Keywords in the "Use Cases by Organization" section should end with "OrgUseCase" + * Keywords in the "Use Cases by File Format" section should end with "FileUseCase" - # sphinx_gallery_thumbnail_path = '_static/air_quality_and_comp-EnsembleStat_fcstICAP_obsMODIS_aod.png' +* Add new entries in alphabetical order under both html and latex sub-sections. -.. note:: - Text that ends with an underscore (_) may be interpreted as a reference, so - avoid ending a line with this character to avoid generating warnings in the - documentation. + * Under html, use the format | \` <../search.html?q=&check_keywords=yes&area=default>`_ where is a human-readable description of the keyword and is the keyword. + * Under latex, use the format | ****: ** where is a human-readable description of the keyword and is the keyword. + +* Add the keyword to the end of each use case documentation file under docs/use_cases that corresponds to the keyword. Accessing the Documentation --------------------------- diff --git a/docs/Contributors_Guide/continuous_integration.rst b/docs/Contributors_Guide/continuous_integration.rst index f98fbb14f2..976a05ae5f 100644 --- a/docs/Contributors_Guide/continuous_integration.rst +++ b/docs/Contributors_Guide/continuous_integration.rst @@ -780,6 +780,8 @@ Example:: met_tool_wrapper/GridStat/GridStat.conf,met_tool_wrapper/GridStat/GridStat_forecast.conf,met_tool_wrapper/GridStat/GridStat_observation.conf +.. _cg-ci-dependencies: + dependencies """""""""""" @@ -799,6 +801,8 @@ Example:: Use Case Dependencies ^^^^^^^^^^^^^^^^^^^^^ +.. _cg-ci-conda-environments: + Conda Environments """""""""""""""""" diff --git a/docs/Users_Guide/glossary.rst b/docs/Users_Guide/glossary.rst index 2dcd640c4f..4ed26829ba 100644 --- a/docs/Users_Guide/glossary.rst +++ b/docs/Users_Guide/glossary.rst @@ -12970,3 +12970,23 @@ METplus Configuration Glossary using the -aggr command line argument. | *Used by:* SeriesAnalysis + + POINT_STAT_POINT_WEIGHT_FLAG + Specify the value for 'point_weight_flag' in the MET configuration file for PointStat. + + | *Used by:* PointStat + + ENSEMBLE_STAT_POINT_WEIGHT_FLAG + Specify the value for 'point_weight_flag' in the MET configuration file for EnsembleStat. + + | *Used by:* EnsembleStat + + POINT_STAT_OBTYPE_AS_GROUP_VAL_FLAG + Specify the value for 'obtype_as_group_val_flag' in the MET configuration file for PointStat. + + | *Used by:* PointStat + + ENSEMBLE_STAT_OBTYPE_AS_GROUP_VAL_FLAG + Specify the value for 'obtype_as_group_val_flag' in the MET configuration file for EnsembleStat. + + | *Used by:* EnsembleStat diff --git a/docs/Users_Guide/wrappers.rst b/docs/Users_Guide/wrappers.rst index aa2794377c..5ca93e9dd0 100644 --- a/docs/Users_Guide/wrappers.rst +++ b/docs/Users_Guide/wrappers.rst @@ -233,6 +233,7 @@ METplus Configuration | :term:`ENSEMBLE_STAT_CUSTOM_LOOP_LIST` | :term:`ENSEMBLE_STAT_SKIP_IF_OUTPUT_EXISTS` | :term:`ENSEMBLE_STAT_DESC` +| :term:`ENSEMBLE_STAT_OBTYPE_AS_GROUP_VAL_FLAG` | :term:`ENSEMBLE_STAT_ENS_SSVAR_BIN_SIZE` | :term:`ENSEMBLE_STAT_ENS_PHIST_BIN_SIZE` | :term:`ENSEMBLE_STAT_CLIMO_CDF_BINS` @@ -356,6 +357,7 @@ METplus Configuration | :term:`ENSEMBLE_STAT_ENS_MEMBER_IDS` | :term:`ENSEMBLE_STAT_CONTROL_ID` | :term:`ENSEMBLE_STAT_GRID_WEIGHT_FLAG` +| :term:`ENSEMBLE_STAT_POINT_WEIGHT_FLAG` | :term:`ENSEMBLE_STAT_PROB_CAT_THRESH` | :term:`ENSEMBLE_STAT_PROB_PCT_THRESH` | :term:`ENSEMBLE_STAT_ECLV_POINTS` @@ -849,6 +851,18 @@ ${METPLUS_OBS_ERROR_FLAG} * - :term:`ENSEMBLE_STAT_OBS_ERROR_FLAG` - obs_error.flag +${METPLUS_OBTYPE_AS_GROUP_VAL_FLAG} +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :widths: 5 5 + :header-rows: 1 + + * - METplus Config(s) + - MET Config File + * - :term:`ENSEMBLE_STAT_OBTYPE_AS_GROUP_VAL_FLAG` + - obtype_as_group_val_flag + ${METPLUS_ENS_SSVAR_BIN_SIZE} """"""""""""""""""""""""""""" @@ -1091,6 +1105,18 @@ ${METPLUS_GRID_WEIGHT_FLAG} * - :term:`ENSEMBLE_STAT_GRID_WEIGHT_FLAG` - grid_weight_flag +${METPLUS_POINT_WEIGHT_FLAG} +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :widths: 5 5 + :header-rows: 1 + + * - METplus Config(s) + - MET Config File + * - :term:`ENSEMBLE_STAT_POINT_WEIGHT_FLAG` + - point_weight_flag + ${METPLUS_OUTPUT_PREFIX} """""""""""""""""""""""" @@ -7070,6 +7096,7 @@ Configuration | :term:`POINT_STAT_HIRA_SHAPE` | :term:`POINT_STAT_HIRA_PROB_CAT_THRESH` | :term:`POINT_STAT_MESSAGE_TYPE_GROUP_MAP` +| :term:`POINT_STAT_OBTYPE_AS_GROUP_VAL_FLAG` | :term:`FCST_POINT_STAT_IS_PROB` | :term:`FCST_POINT_STAT_PROB_IN_GRIB_PDS` | :term:`FCST_POINT_STAT_WINDOW_BEGIN` @@ -7097,6 +7124,7 @@ Configuration | :term:`POINT_STAT_UGRID_MAX_DISTANCE_KM` | :term:`POINT_STAT_UGRID_COORDINATES_FILE` | :term:`POINT_STAT_UGRID_CONFIG_FILE` +| :term:`POINT_STAT_POINT_WEIGHT_FLAG` | .. warning:: **DEPRECATED:** @@ -7472,7 +7500,19 @@ ${METPLUS_MESSAGE_TYPE_GROUP_MAP} - MET Config File * - :term:`POINT_STAT_MESSAGE_TYPE_GROUP_MAP` - message_type_group_map - + +${METPLUS_OBTYPE_AS_GROUP_VAL_FLAG} +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :widths: 5 5 + :header-rows: 1 + + * - METplus Config(s) + - MET Config File + * - :term:`POINT_STAT_OBTYPE_AS_GROUP_VAL_FLAG` + - obtype_as_group_val_flag + ${METPLUS_CLIMO_MEAN_DICT} """""""""""""""""""""""""" @@ -7787,6 +7827,18 @@ ${METPLUS_OUTPUT_PREFIX} * - :term:`POINT_STAT_OUTPUT_PREFIX` - output_prefix +${METPLUS_POINT_WEIGHT_FLAG} +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :widths: 5 5 + :header-rows: 1 + + * - METplus Config(s) + - MET Config File + * - :term:`POINT_STAT_POINT_WEIGHT_FLAG` + - point_weight_flag + ${METPLUS_MET_CONFIG_OVERRIDES} """"""""""""""""""""""""""""""" diff --git a/docs/use_cases/use_case_documentation_template.py b/docs/use_cases/use_case_documentation_template.py new file mode 100644 index 0000000000..99e1ce8e23 --- /dev/null +++ b/docs/use_cases/use_case_documentation_template.py @@ -0,0 +1,213 @@ +“”” + PointStat: Use Python embedding to calculate temperature terciles + ================================================================= + + model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsASCAT_satelliteWinds.conf + +“”” +############################################################################## +# .. contents:: +# :depth: 1 +# :local: +# :backlinks: none + +############################################################################## +# Scientific Objective +# -------------------- +# [UPDATE_SECTION_CONTENT] +# +# To provide statistical information on the forecast hail size compared to +# the observed hail size from MRMS MESH data. Using objects to verify hail size +# avoids the “unfair penalty” issue, where a CAM must first generate convection +# to have any chance of accurately predicting the hail size. In addition, studies +# have shown that MRMS MESH observed hail sizes do not correlate one-to-one with +# observed sizes but can only be used to group storms into general categories. +# Running MODE allows a user to do this. + +############################################################################## +# Version Added +# ------------- +# [UPDATE_SECTION_CONTENT] +# +# METplus version 6.0 + +############################################################################## +# Datasets +# -------- +# [UPDATE_SECTION_CONTENT] +# **Forecast:** Global Forecast System (GFS) 25km resolution, 2m temperature +# +# **Observation:** ECMWF Reanalysis v5 (ERA5) 5 degree resolution, 2m temperature +# +# **Climatology:** None +# +# **Location:** All of the input data required for this use case can be +# found in a sample data tarball. Each use case category will have +# one or more sample data tarballs. It is only necessary to download +# the tarball with the use case’s dataset and not the entire collection +# of sample data. Click here to access 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 :ref:`running-metplus` section for more information. + +############################################################################## +# METplus Components +# ------------------ +# [UPDATE_SECTION_CONTENT] +# +# The only tool this use case calls is GridStat. Within GridStat a Python +# script is used for ingesting forecast data, once for each year of data of +# the CFSv2 ensemble. + +############################################################################## +# METplus Workflow +# ---------------- +# [UPDATE_SECTION_CONTENT] +# +# **Beginning time (INIT_BEG):** 1982-01-01 +# **End time (INIT_END):** 2010-01-02 +# **Increment between beginning and end times (INIT_INCREMENT):** 1 year +# **Sequence of forecast leads to process (LEAD_SEQ):** None +# +# With an increment of 1 year, all January 1st’s from 1982 to 2010 are processed +# for a total of 29 years, with 24 members in each ensemble forecast. This use case +# initially runs SeriesAnalysis 24 times, once for each member of the CFSv2 ensemble +# across the 29 years of data. The resulting 24 outputs are read in by GenEnsProd +# which uses the normalize option to normalize each of the ensemble members +# relative to its climatology (FBAR) and standard deviation (FSTDEV). The output from +# GenEnsProd are 29 files containing the uncalibrated probability forecasts for +# the lower tercile of January for each year. The final probability verification +# is done across the temporal scale in SeriesAnalysis, and the spatial scale in GridStat. + +############################################################################## +# METplus Configuration +# --------------------- +# [UPDATE_SECTION_CONTENT] +# +# METplus first loads all of the configuration files found in parm/metplus_config, +# then it loads any configuration files passed to METplus via the command line, +# i.e. parm/use_cases/model_applications/s2s/SeriesAnalysis_fcstCFSv2_obsGHCNCAMS_climoStandardized_MultiStatisticTool.conf +# +# .. highlight:: bash +# .. literalinclude:: ../../../../parm/use_cases/model_applications/s2s/SeriesAnalysis_fcstCFSv2_obsGHCNCAMS_climoStandardized_MultiStatisticTool.conf +# + +############################################################################## +# MET Configuration +# ----------------- +# [UPDATE_SECTION_CONTENT] +# +# 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` +# +# .. dropdown:: GridStatConfig_wrapped +# +# .. literalinclude:: ../../../../parm/met_config/GridStatConfig_wrapped + +############################################################################## +# Python Embedding +# ---------------- +# [UPDATE_SECTION_CONTENT] +# +# This use case calls the read_ASCAT_data.py script to read and pass to PointStat +# the user-requested variable. The script needs 5 inputs in the following order: +# a path to a directory that contains only ASCAT data of the “ascat_YYYYMMDDHHMMSS_*” +# string, a start time in YYYYMMDDHHMMSS, an end time in the same format, +# a message type to code the variables as, and a variable name to read in. +# Currently the script puts the same station ID to each observation, but there is +# space in the code describing an alternate method that may be improved upon to +# allow different satellites to have their own station IDs. +# This code currently ingests all files it finds in the directory, pulls out the +# requested variable, and arranges the data in a list of lists following the +# 11-column format for point data. This list of lists is passed back +# to PointStat for evaluation and the requested statistical output. The location +# of the code is +# parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsASCAT_satelliteWinds/read_ASCAT_data.py +# +# For more information on the basic requirements to utilize Python Embedding in METplus, +# please refer to the MET User’s Guide section on `Python embedding `_ +# +# .. highlight:: python +# .. literalinclude:: ../../../../parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsASCAT_satelliteWinds/read_ASCAT_data.py + +############################################################################## +# User Scripting +# -------------- +# [UPDATE_SECTION_CONTENT] +# +# This use case uses a Python script to perform plotting, which at the time of +# this use case creation was not an ability METplus had. Additionally some of +# the plotting features used in this script are not currently slated for METplus +# analysis suite development. +# In order to create the plots, the script reads in a yaml file and sets up +# the correct environment. Plot parameters (which are hard coded in the script) are set, +# and the datasets are read in from the input file. The desired variable fields +# are placed into arrays, which are then treated for bad data and squeezed to the +# appropriate dimensions. Additional basic math is completed on the resulting arrays +# to create the cross spectra values with the results being graphed. +# +# .. highlight:: python +# .. literalinclude:: ../../../../parm/use_cases/model_applications/s2s/UserScript_fcstS2S_obsERAI_CrossSpectra/cross_spectra_plot.py + +############################################################################## +# Running METplus +# --------------- +# [UPDATE_SECTION_CONTENT] +# +# 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/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsASCAT_satelliteWinds.conf /path/to/user_system.conf +# +# See :ref:`running-metplus` for more information. + +############################################################################## +# Expected Output +# --------------- +# [UPDATE_SECTION_CONTENT] +# +# 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 +# {OUPUT_BASE}/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsASCAT_satelliteWinds +# and will contain the following files:: +# +# * grid_stat_198201_000000L_19700101_000000V_pairs.nc +# * grid_stat_198201_000000L_19700101_000000V_pstd.txt +# * grid_stat_198201_000000L_19700101_000000V.stat +# +# Each file should contain corresponding statistics for the line type(s) requested. +# For the netCDF file, five variable fields are present (not including the lat/lon fields). +# Those variables are:: +# +# * FCST_fcst_ENS_FREQ_lt-0.43_0_0_all_all_FULL(lat, lon) +# * OBS_tmp2m_20100101_000000_all_all_FULL(lat, lon) +# * CLIMO_MEAN_tmp2m_20100101_000000_all_all_FULL(lat, lon) +# * CLIMO_STDEV_tmp2m_20100101_000000_all_all_FULL(lat, lon) +# * CLIMO_CDF_tmp2m_20100101_000000_all_all_FULL(lat, lon) + +############################################################################## +# Keywords +# -------- +# [UPDATE_SECTION_CONTENT] +# +# .. note:: +# +# * PointStatToolUseCase +# * PythonEmbeddingFileUseCase +# * GRIB2FileUseCase +# * MarineAndCryosphereAppUseCase +# +# Navigate to the :ref:`quick-search` page to discover other similar use cases. +# +# +# +# sphinx_gallery_thumbnail_path = ‘_static/short-range-MODEMultivar_fcstRRFS_obsGOES_MRMS_BrightnessTemp_Lightning.png’ diff --git a/internal/tests/pytests/wrappers/ensemble_stat/test_ensemble_stat_wrapper.py b/internal/tests/pytests/wrappers/ensemble_stat/test_ensemble_stat_wrapper.py index b17171495d..963966513b 100644 --- a/internal/tests/pytests/wrappers/ensemble_stat/test_ensemble_stat_wrapper.py +++ b/internal/tests/pytests/wrappers/ensemble_stat/test_ensemble_stat_wrapper.py @@ -829,6 +829,11 @@ def test_ensemble_stat_field_info(metplus_config, config_overrides, 'time_interp_method = NEAREST;' 'match_month = TRUE;day_interval = 30;' 'hour_interval = 12;}')}), + ({'ENSEMBLE_STAT_POINT_WEIGHT_FLAG': 'SID', }, + {'METPLUS_POINT_WEIGHT_FLAG': 'point_weight_flag = SID;'}), + ({'ENSEMBLE_STAT_OBTYPE_AS_GROUP_VAL_FLAG': 'FALSE', }, + {'METPLUS_OBTYPE_AS_GROUP_VAL_FLAG': 'obtype_as_group_val_flag = FALSE;'}), + ] ) @pytest.mark.wrapper_c diff --git a/internal/tests/pytests/wrappers/point_stat/test_point_stat_wrapper.py b/internal/tests/pytests/wrappers/point_stat/test_point_stat_wrapper.py index 3660a1b37a..b76ac81d53 100755 --- a/internal/tests/pytests/wrappers/point_stat/test_point_stat_wrapper.py +++ b/internal/tests/pytests/wrappers/point_stat/test_point_stat_wrapper.py @@ -863,6 +863,10 @@ def test_met_dictionary_in_var_options(metplus_config): 'time_interp_method = NEAREST;' 'match_month = TRUE;day_interval = 30;' 'hour_interval = 12;}')}), + ({'POINT_STAT_POINT_WEIGHT_FLAG': 'SID', }, + {'METPLUS_POINT_WEIGHT_FLAG': 'point_weight_flag = SID;'}), + ({'POINT_STAT_OBTYPE_AS_GROUP_VAL_FLAG': 'FALSE', }, + {'METPLUS_OBTYPE_AS_GROUP_VAL_FLAG': 'obtype_as_group_val_flag = FALSE;'}), ] ) @pytest.mark.wrapper_a diff --git a/metplus/VERSION b/metplus/VERSION index 36f86d732d..4ba6860f7e 100644 --- a/metplus/VERSION +++ b/metplus/VERSION @@ -1 +1 @@ -6.0.0-beta5 +6.0.0-beta6-dev diff --git a/metplus/wrappers/ensemble_stat_wrapper.py b/metplus/wrappers/ensemble_stat_wrapper.py index 92364bab17..8121eec8bf 100755 --- a/metplus/wrappers/ensemble_stat_wrapper.py +++ b/metplus/wrappers/ensemble_stat_wrapper.py @@ -68,9 +68,11 @@ class EnsembleStatWrapper(CompareGriddedWrapper): 'METPLUS_ENS_MEMBER_IDS', 'METPLUS_CONTROL_ID', 'METPLUS_GRID_WEIGHT_FLAG', + 'METPLUS_POINT_WEIGHT_FLAG', 'METPLUS_PROB_CAT_THRESH', 'METPLUS_PROB_PCT_THRESH', 'METPLUS_ECLV_POINTS', + 'METPLUS_OBTYPE_AS_GROUP_VAL_FLAG', ] # deprecated env vars that are no longer supported in the wrapped MET conf @@ -267,6 +269,8 @@ def create_c_dict(self): extra_args={'remove_quotes': True, 'allow_empty': True}) + self.add_met_config(name='obtype_as_group_val_flag', data_type='bool') + self.add_met_config(name='ens_ssvar_bin_size', data_type='float') self.add_met_config(name='ens_phist_bin_size', data_type='float') @@ -354,6 +358,11 @@ def create_c_dict(self): extra_args={'remove_quotes': True, 'uppercase': True}) + self.add_met_config(name='point_weight_flag', + data_type='string', + extra_args={'remove_quotes': True, + 'uppercase': True}) + self.add_met_config(name='prob_pct_thresh', data_type='list', extra_args={'remove_quotes': True}) diff --git a/metplus/wrappers/point_stat_wrapper.py b/metplus/wrappers/point_stat_wrapper.py index 13d797af2a..bce6459366 100755 --- a/metplus/wrappers/point_stat_wrapper.py +++ b/metplus/wrappers/point_stat_wrapper.py @@ -52,12 +52,14 @@ class PointStatWrapper(CompareGriddedWrapper): 'METPLUS_HSS_EC_VALUE', 'METPLUS_HIRA_DICT', 'METPLUS_MESSAGE_TYPE_GROUP_MAP', + 'METPLUS_OBTYPE_AS_GROUP_VAL_FLAG', 'METPLUS_FCST_FILE_TYPE', 'METPLUS_OBS_FILE_TYPE', 'METPLUS_SEEPS_P1_THRESH', 'METPLUS_UGRID_DATASET', 'METPLUS_UGRID_MAX_DISTANCE_KM', 'METPLUS_UGRID_COORDINATES_FILE', + 'METPLUS_POINT_WEIGHT_FLAG', ] # deprecated env vars that are no longer supported in the wrapped MET conf @@ -279,6 +281,8 @@ def create_c_dict(self): self.add_met_config(name='message_type_group_map', data_type='list', extra_args={'remove_quotes': True}) + self.add_met_config(name='obtype_as_group_val_flag', data_type='bool') + self.add_met_config(name='seeps_p1_thresh', data_type='string', extra_args={'remove_quotes': True}) @@ -286,6 +290,11 @@ def create_c_dict(self): self.add_met_config(name='ugrid_max_distance_km', data_type='int') self.add_met_config(name='ugrid_coordinates_file', data_type='string') + self.add_met_config(name='point_weight_flag', + data_type='string', + extra_args={'remove_quotes': True, + 'uppercase': True}) + if not c_dict['FCST_INPUT_TEMPLATE']: self.log_error('Must set FCST_POINT_STAT_INPUT_TEMPLATE ' 'in config file') diff --git a/parm/met_config/EnsembleStatConfig_wrapped b/parm/met_config/EnsembleStatConfig_wrapped index 9f508ff4c7..92a79082a1 100644 --- a/parm/met_config/EnsembleStatConfig_wrapped +++ b/parm/met_config/EnsembleStatConfig_wrapped @@ -136,6 +136,9 @@ message_type_group_map = [ { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } ]; +//obtype_as_group_val_flag = +${METPLUS_OBTYPE_AS_GROUP_VAL_FLAG} + // // Ensemble bin sizes // May be set separately in each "obs.field" entry @@ -234,6 +237,8 @@ rng = { //grid_weight_flag = ${METPLUS_GRID_WEIGHT_FLAG} +//point_weight_flag = +${METPLUS_POINT_WEIGHT_FLAG} //output_prefix = ${METPLUS_OUTPUT_PREFIX} //version = "V9.0"; diff --git a/parm/met_config/PointStatConfig_wrapped b/parm/met_config/PointStatConfig_wrapped index 0d12bd0a73..780fb829e8 100644 --- a/parm/met_config/PointStatConfig_wrapped +++ b/parm/met_config/PointStatConfig_wrapped @@ -93,6 +93,9 @@ ${METPLUS_OBS_PERC_VALUE} //message_type_group_map = ${METPLUS_MESSAGE_TYPE_GROUP_MAP} +//obtype_as_group_val_flag = +${METPLUS_OBTYPE_AS_GROUP_VAL_FLAG} + //////////////////////////////////////////////////////////////////////////////// // @@ -208,6 +211,9 @@ ${METPLUS_UGRID_COORDINATES_FILE} //////////////////////////////////////////////////////////////////////////////// +//point_weight_flag = +${METPLUS_POINT_WEIGHT_FLAG} + tmp_dir = "${MET_TMP_DIR}"; // output_prefix = diff --git a/parm/use_cases/met_tool_wrapper/EnsembleStat/EnsembleStat.conf b/parm/use_cases/met_tool_wrapper/EnsembleStat/EnsembleStat.conf index 3ac91314f2..5d08f98ac4 100644 --- a/parm/use_cases/met_tool_wrapper/EnsembleStat/EnsembleStat.conf +++ b/parm/use_cases/met_tool_wrapper/EnsembleStat/EnsembleStat.conf @@ -131,6 +131,8 @@ ENSEMBLE_STAT_SKIP_CONST = False ENSEMBLE_STAT_OBS_ERROR_FLAG = FALSE +#ENSEMBLE_STAT_OBTYPE_AS_GROUP_VAL_FLAG = + ENSEMBLE_STAT_ENS_SSVAR_BIN_SIZE = 1.0 ENSEMBLE_STAT_ENS_PHIST_BIN_SIZE = 0.05 @@ -246,3 +248,4 @@ ENSEMBLE_STAT_NC_ORANK_FLAG_WEIGHT = FALSE #ENSEMBLE_STAT_CONTROL_ID = #ENSEMBLE_STAT_GRID_WEIGHT_FLAG = +#ENSEMBLE_STAT_POINT_WEIGHT_FLAG = diff --git a/parm/use_cases/met_tool_wrapper/PointStat/PointStat.conf b/parm/use_cases/met_tool_wrapper/PointStat/PointStat.conf index 6d793e2bf9..92816c297b 100644 --- a/parm/use_cases/met_tool_wrapper/PointStat/PointStat.conf +++ b/parm/use_cases/met_tool_wrapper/PointStat/PointStat.conf @@ -259,8 +259,11 @@ POINT_STAT_MESSAGE_TYPE = ADPUPA, ADPSFC #POINT_STAT_HIRA_PROB_CAT_THRESH = #POINT_STAT_MESSAGE_TYPE_GROUP_MAP = +#POINT_STAT_OBTYPE_AS_GROUP_VAL_FLAG = #POINT_STAT_UGRID_DATASET = #POINT_STAT_UGRID_MAX_DISTANCE_KM = #POINT_STAT_UGRID_COORDINATES_FILE = #POINT_STAT_UGRID_CONFIG_FILE = + +#POINT_STAT_POINT_WEIGHT_FLAG = diff --git a/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry.conf b/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry.conf index 8f830a1049..fb8c9000f0 100644 --- a/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry.conf +++ b/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry.conf @@ -110,7 +110,7 @@ FCST_VAR1_NAME = WIND FCST_VAR1_LEVELS = Z0 OBS_VAR1_NAME = wind_speed_alt -OBS_VAR1_LEVELS = Z0 +OBS_VAR1_LEVELS = Z10 POINT_STAT_OUTPUT_PREFIX = wind diff --git a/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry/read_satData.py b/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry/read_satData.py index 0614efa4a2..463d9348ed 100644 --- a/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry/read_satData.py +++ b/parm/use_cases/model_applications/marine_and_cryosphere/PointStat_fcstGFS_obsJASON3_satelliteAltimetry/read_satData.py @@ -12,7 +12,9 @@ import datetime as dt import xarray as xr import pandas as pd -#from met.point import convert_point_data + +DATA_GROUP = "/data_01" +DATA_KU_GROUP = "/data_01/ku" #Users are responsible for passing the following arguements at runtime: ##input file @@ -29,12 +31,12 @@ if file_type == 'JASON' or file_type == 'SENTINEL': #need to check if the variable is in the data_01 group or data_01/ku group try: - ds = xr.open_dataset(input_file, group="/data_01/ku") - du = xr.open_dataset(input_file, group="/data_01") + ds = xr.open_dataset(input_file, group=DATA_KU_GROUP) + du = xr.open_dataset(input_file, group=DATA_GROUP) obs_hold = ds[field_name] except KeyError: - ds = xr.open_dataset(input_file, group="/data_01") - du = xr.open_dataset(input_file, group="/data_01") + ds = xr.open_dataset(input_file, group=DATA_GROUP) + du = xr.open_dataset(input_file, group=DATA_GROUP) obs_hold = ds[field_name] obs = obs_hold.values latitude = np.array(du.latitude.values) @@ -76,7 +78,7 @@ #adding additional check; if 'wind' appears in the variable name, it's assumed #to be a wind speed and gets a height of 10m; otherwise its a height of 0 if field_name.rfind('wind') != -1: - hgt = np.full(len(latitude),0,dtype=int).tolist() + hgt = np.full(len(latitude),10,dtype=int).tolist() else: hgt = np.full(len(latitude),0,dtype=int).tolist() qc = np.full(len(latitude),'NA').tolist() @@ -91,7 +93,6 @@ obs = obs.tolist() l_tuple = list(zip(typ,sid,vld,lat,lon,elv,var,lvl,hgt,qc,obs)) point_data = [list(ele) for ele in l_tuple] - #met_point_data = convert_point_data(point_data) print("Data Length:\t" + repr(len(point_data))) print("Data Type:\t" + repr(type(point_data))) diff --git a/parm/use_cases/model_applications/pbl/PointStat_fcstHRRR_obsAMDAR_PBLH_PyEmbed/calc_amdar_pblh.py b/parm/use_cases/model_applications/pbl/PointStat_fcstHRRR_obsAMDAR_PBLH_PyEmbed/calc_amdar_pblh.py index 7c4a810caa..732e048f52 100644 --- a/parm/use_cases/model_applications/pbl/PointStat_fcstHRRR_obsAMDAR_PBLH_PyEmbed/calc_amdar_pblh.py +++ b/parm/use_cases/model_applications/pbl/PointStat_fcstHRRR_obsAMDAR_PBLH_PyEmbed/calc_amdar_pblh.py @@ -164,8 +164,6 @@ def get_tn(tn): alt_gap = alt_d[pblh_ind]-alt_d[pblh_ind-1] if alt_gap < (gap_max + alt_d[pblh_ind]/20.): - pblh[i] = alt_d[pblh_ind] - # linear interpolate PBLH between this data point and the one below it pblh[i] = np.interp((pt_min[i]+pt_delta), pt_d[pblh_ind-1:pblh_ind+1], alt_d[pblh_ind-1:pblh_ind+1]) diff --git a/parm/use_cases/model_applications/s2s/GridStat_SeriesAnalysis_fcstNMME_obsCPC_seasonal_forecast.conf b/parm/use_cases/model_applications/s2s/GridStat_SeriesAnalysis_fcstNMME_obsCPC_seasonal_forecast.conf index c30b22a23c..5e055b2cdb 100644 --- a/parm/use_cases/model_applications/s2s/GridStat_SeriesAnalysis_fcstNMME_obsCPC_seasonal_forecast.conf +++ b/parm/use_cases/model_applications/s2s/GridStat_SeriesAnalysis_fcstNMME_obsCPC_seasonal_forecast.conf @@ -57,8 +57,7 @@ SERIES_ANALYSIS_OUTPUT_TEMPLATE = series_analysis_{MODEL}_{OBTYPE}_stats_F{lead? [full_stats] -SERIES_ANALYSIS_CLIMO_MEAN_INPUT_DIR = {SERIES_ANALYSIS_OUTPUT_DIR} -SERIES_ANALYSIS_CLIMO_MEAN_INPUT_TEMPLATE = series_analysis_{MODEL}_{OBTYPE}_stats_F{lead?fmt=%2m}_climo.nc +SERIES_ANALYSIS_CLIMO_MEAN_FILE_NAME = {SERIES_ANALYSIS_OUTPUT_DIR}/series_analysis_{MODEL}_{OBTYPE}_stats_F{lead?fmt=%2m}_climo.nc [config] @@ -122,9 +121,12 @@ SERIES_ANALYSIS_GENERATE_ANIMATIONS = no SERIES_ANALYSIS_RUN_ONCE_PER_STORM_ID = False -SERIES_ANALYSIS_STAT_LIST = OBAR +SERIES_ANALYSIS_OUTPUT_STATS_CNT = OBAR [full_stats] +SERIES_ANALYSIS_CLIMO_MEAN_FIELD = {name="series_cnt_OBAR"; level="(*,*)";} -SERIES_ANALYSIS_STAT_LIST =TOTAL, FBAR, OBAR, ME, MAE, RMSE, ANOM_CORR, PR_CORR -SERIES_ANALYSIS_CTS_LIST = BASER, CSI, GSS +SERIES_ANALYSIS_CLIMO_MEAN_DAY_INTERVAL = NA + +SERIES_ANALYSIS_OUTPUT_STATS_CNT = TOTAL, FBAR, OBAR, ME, MAE, RMSE, ANOM_CORR, PR_CORR +SERIES_ANALYSIS_OUTPUT_STATS_CTS = BASER, CSI, GSS diff --git a/ush/master_metplus.py b/ush/master_metplus.py deleted file mode 120000 index ffbf916c4b..0000000000 --- a/ush/master_metplus.py +++ /dev/null @@ -1 +0,0 @@ -run_metplus.py \ No newline at end of file diff --git a/ush/master_metplus.py b/ush/master_metplus.py new file mode 100755 index 0000000000..e8eef52e67 --- /dev/null +++ b/ush/master_metplus.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + +import sys + +def main(): + print("ERROR: master_metplus.py is deprecated. Please use run_metplus.py instead") + sys.exit(1) + +if __name__ == "__main__": + main()