From aca29d1b60d2a413f36ae8854be86cd906c1e061 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:56:03 -0600 Subject: [PATCH] Update develop-ref after #2094 (#2108) Co-authored-by: Julie Prestopnik Co-authored-by: johnhg Co-authored-by: cristianastan2 Co-authored-by: John Halley Gotway Co-authored-by: bikegeek Co-authored-by: Lisa Goodrich Co-authored-by: Julie Prestopnik Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> Co-authored-by: Hank Fisher Co-authored-by: Dan Adriaansen Co-authored-by: jprestop Co-authored-by: Tracy Hertneky Co-authored-by: j-opatz <59586397+j-opatz@users.noreply.github.com> Co-authored-by: lisagoodrich <33230218+lisagoodrich@users.noreply.github.com> Co-authored-by: bikegeek <3753118+bikegeek@users.noreply.github.com> Co-authored-by: j-opatz Co-authored-by: Will Mayfield <59745143+willmayfield@users.noreply.github.com> Co-authored-by: metplus-bot <97135045+metplus-bot@users.noreply.github.com> Co-authored-by: Tracy Hertneky <39317287+hertneky@users.noreply.github.com> fixing some spacing #770 Fixing formatting, typos etc. #770 Fixing formatting #770 fixing typos, spacing, etc. #770 fixing typos, grammar and punctuation. #770 Fixing TOC and coding block #770 fixing note #770 fix. Updating bolding and italics for file names and directories #770 fixing space #770 fixing conflict #2 #770 fixing typos #770 fixing typos #2 #770 fixing formatting #770 fixing errors #650 fixing errors take 2 #650 fixing errors take 3 #650 fixing errors take 4 #650 fixing errors take 5 #650 fixing question order #650 fix #1706 fix PhaseDiagram use case to avoid writing into INPUT_BASE (#1708) fix #1713 develop METPLOTPY_BASE (#1715) fix #1691 remove whitespace from output file paths (#1721) fix Contributor's Guide GitHub Workflow page (#1774) fix release (#1790) fix GitHub Actions warnings (#1864) fix #1884 develop PCPCombine {custom} in subtract method (#1887) fix #1939 develop - failure reading obs when zipped file also exists (#1941) Closes https://github.com/dtcenter/METplus/issues/1986 fix develop Fix broken documentation links (#2004) fix #2026 develop StatAnalysis looping (#2028) fix priority of obs_window config variables so that wrapper-specific version is preferred over generic OBS_WINDOW_BEGIN/END (#2062) fix #2070 var list numeric order (#2072) fix #2087 develop docs_pdf (#2091) fix #2096/#2098 develop - fix skip if output exists and do not error if no commands were run (#2099) --- .github/parm/use_case_groups.json | 5 + .github/workflows/documentation.yml | 1 + docs/Users_Guide/release-notes.rst | 375 +++++++++--------- docs/Users_Guide/statistics_list.rst | 2 +- ...-MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.png | Bin 0 -> 83777 bytes docs/conf.py | 1 + docs/requirements.txt | 5 +- ...sProd_fcstHRRR_fcstOnly_SurrogateSevere.py | 10 +- .../MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.py | 196 +++++++++ .../installation/modulefiles/5.0.0.lua_wcoss2 | 26 -- .../installation/modulefiles/5.0.0_casper | 18 - .../installation/modulefiles/5.0.0_cheyenne | 18 - .../installation/modulefiles/5.0.0_frontera | 22 - .../installation/modulefiles/5.0.0_gaea | 18 - .../installation/modulefiles/5.0.0_orion | 17 - .../modulefiles/{5.0.0_hera => 5.1.0_hera} | 12 +- .../modulefiles/{5.0.0_jet => 5.1.0_jet} | 11 +- .../config_metplus/test_config_metplus.py | 155 ++++---- .../util/config_util/test_config_util.py | 8 +- .../command_builder/test_command_builder.py | 57 +++ .../wrappers/pb2nc/test_pb2nc_wrapper.py | 35 -- internal/tests/use_cases/all_use_cases.txt | 1 + metplus/util/config_metplus.py | 32 +- metplus/util/config_util.py | 6 +- metplus/util/run_util.py | 4 +- metplus/util/string_manip.py | 6 +- metplus/wrappers/command_builder.py | 19 +- .../UserScript_fcstGFS_obsERA_Blocking.conf | 3 + ...MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf | 134 +++++++ 29 files changed, 740 insertions(+), 457 deletions(-) create mode 100644 docs/_static/short_range-MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.png create mode 100644 docs/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.py delete mode 100644 internal/scripts/installation/modulefiles/5.0.0.lua_wcoss2 delete mode 100644 internal/scripts/installation/modulefiles/5.0.0_casper delete mode 100644 internal/scripts/installation/modulefiles/5.0.0_cheyenne delete mode 100644 internal/scripts/installation/modulefiles/5.0.0_frontera delete mode 100644 internal/scripts/installation/modulefiles/5.0.0_gaea delete mode 100644 internal/scripts/installation/modulefiles/5.0.0_orion rename internal/scripts/installation/modulefiles/{5.0.0_hera => 5.1.0_hera} (66%) rename internal/scripts/installation/modulefiles/{5.0.0_jet => 5.1.0_jet} (61%) create mode 100644 parm/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf diff --git a/.github/parm/use_case_groups.json b/.github/parm/use_case_groups.json index 056013dd1b..b5787cec6b 100644 --- a/.github/parm/use_case_groups.json +++ b/.github/parm/use_case_groups.json @@ -54,6 +54,11 @@ "index_list": "10-12", "run": false }, + { + "category": "short_range", + "index_list": "13", + "run": false + }, { "category": "data_assimilation", "index_list": "0-1", diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 762752c7e5..6f8c9b3d45 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -24,6 +24,7 @@ jobs: run: | python -m pip install --upgrade sphinx sphinx-gallery sphinx_rtd_theme python -m pip install python-dateutil requests Pillow + python -m pip install -r docs/requirements.txt - name: Build Documentation run: ./.github/jobs/build_documentation.sh - uses: actions/upload-artifact@v3 diff --git a/docs/Users_Guide/release-notes.rst b/docs/Users_Guide/release-notes.rst index e31fb0c9ef..e6cffdac4a 100644 --- a/docs/Users_Guide/release-notes.rst +++ b/docs/Users_Guide/release-notes.rst @@ -34,206 +34,205 @@ describes the bugfix, enhancement, or new feature. METplus Version 5.1.0-beta1 Release Notes (2023-02-28) ------------------------------------------------------ -* Enhancements: + .. dropdown:: Enhancements - * Add support for multiple interp widths - (`#2049 `_) - * TCPairs - Add support for setting consensus.write_members - (`#2054 `_) + * Add support for multiple interp widths (`#2049 `_) + * TCPairs - Add support for setting consensus.write_members + (`#2054 `_) -* Bugfix: + .. dropdown:: Bugfix - * StatAnalysis - allow run once for each valid time - (`#2026 `_) + * StatAnalysis - allow run once for each valid time + (`#2026 `_) -* Documentation: + .. dropdown:: Documentation - * Update the METplus Components Python Requirements Documentation - (`#2016 `_) + * Update the METplus Components Python Requirements Documentation + (`#2016 `_) -* Internal: + .. dropdown:: Internal - * Improve use case testing - (`#685 `_) - * Update conda environments to use 3.10 for automated use case tests - (`#2005 `_) - * Add modulefiles to the repository - (`#2015 `_) - * **Upgrade to using Python 3.10.4** - (`#2022 `_) - * Add 'License.txt' to the METplus repo - (`#2058 `_) + * Improve use case testing + (`#685 `_) + * Update conda environments to use 3.10 for automated use case tests + (`#2005 `_) + * Add modulefiles to the repository + (`#2015 `_) + * **Upgrade to using Python 3.10.4** + (`#2022 `_) + * Add 'License.txt' to the METplus repo + (`#2058 `_) METplus Version 5.0.0 Release Notes (2022-12-09) ------------------------------------------------ -.. warning:: **MAJOR CHANGES**: - - * The LOOP_ORDER config variable was removed. The variable set in a user's - config file will be ignored in favor of executing the logic that - corresponds to *LOOP_ORDER = processes*, where all times are processed for - the first item in the PROCESS_LIST, then all times are processed for the - second item in the PROCESS_LIST, etc. This may change the order that - commands are executed in a use case, but it should not change the results. - * The METplus Dockerfile was moved to internal/scripts/docker. - It was previously found in scripts/docker. - * Use cases that include **EnsembleStat** wrapper will require config file - updates. See :ref:`upgrade-instructions`. - * The default value of :term:`SCRUB_STAGING_DIR` is now *True*. - This means some intermediate files that are auto-generated by METplus such - as file lists and uncompressed files will automatically be removed unless - this option is set by the user. - These files are typically only used to debug unexpected issues. - * The default value of :term:`METPLUS_CONF` now includes the - :term:`LOG_TIMESTAMP` so each METplus run will generate a unique final - config file, e.g. metplus_final.conf.20220921121733. - - -* Enhancements: - - * **Enhance MODE wrapper to support multi-variate MODE** - (`#1585 `_) - * **Allow FCST_IS_PROB variable setting specific to tool - (FCST__IS_PROB)** - (`#1586 `_) - * **Enhance climatology field settings to be consistent with fcst/obs field** - (`#1599 `_) - * Update Hovmoeller Use case to use updated Hovmoeller plotting - (`#1650 `_) - * **Update the EnsembleStat wrapper and use case examples to remove - ensemble post processing logic** - (`#1816 `_) - * Enhance logic to consistently create directories - (`#1657 `_) - * Create checksum for released code - (`#262 `_) - * Add the user ID to the log output at beginning and end of each - METplus wrappers run - (`dtcenter/METplus-Internal#20 `_) - * Update logic to name final conf and intermediate files with a unique - identifier - (`dtcenter/METplus-Internal#32 `_) - * Change default logging time information - (`dtcenter/METplus-Internal#34 `_) - * **Remove LOOP_ORDER config variable** - (`#1687 `_) - * **Add unique identifier for each METplus run to configuration** - (`#1829 `_) - * StatAnalysis - Support setting multiple jobs - (`#1842 `_) - * StatAnalysis - Set MET verbosity - (`#1772 `_) - * StatAnalysis - Support using both init/valid variables in - string substitution - (`#1861 `_) - * StatAnalysis - Allow filename template tags in jobs - (`#1862 `_) - * StatAnalysis - Support looping over groups of list items - (`#1870 `_) - * StatAnalysis - Allow processing of time ranges other than daily - (`#1871 `_) - * StatAnalysis - Add support for using a custom loop list - (`#1893 `_) - * Remove MakePlots wrapper - (`#1843 `_) - * Add support in EnsembleStat wrapper for setting -ens_mean - command line argument - (`#1569 `_) - * Enhance METplus to have better signal handling for shutdown events - (`dtcenter/METplus-Internal#27 `_) - * TCPairs and TCStat - add support for new config options and - command line arguments - (`#1898 `_) - * Enhance the GridStat and PointStat wrappers to handle the - addition of SEEPS - (`#1953 `_) - * SeriesAnalysis - add support for setting mask dictionary - (`#1926 `_) - * Update Python requirement to 3.8.6 - (`#1566 `_) - * Enhance StatAnalysis wrapper to support now and today - (`#1669 `_) - * **Clean up use case configuration files** - (`#1402 `_) - * Add support for creating multiple input datasets - (`#1694 `_) - -* Bugfixes: - - * PCPCombine - custom loop list does not work for subtract method - (`#1884 `_) - * Set level properly in filename template for EnsembleStat forecast input - (`#1910 `_) - * Prevent duplicate observation files using a file window if - compressed equivalent files exist in same directory - (`#1939 `_) - * Allow NA value for _CLIMO_[MEAN/STDEV]_HOUR_INTERVAL - (`#1787 `_) - * Reconcile setting of METPLOTPY_BASE for use cases - (`#1713 `_) - * Add support for the {custom} loop string in the MODEL config variable - (`#1382 `_) - * Fix PCPCombine extra options removal of semi-colon - (`#1534 `_) - * Fix reset of arguments for some wrappers - (i.e. GenEnsProd) after each run - (`#1555 `_) - * Enhance METDbLoad Wrapper to find MODE .txt files - (`#1608 `_) - * Add missing brackets around list variable values for StatAnalysis wrapper - (`#1641 `_) - * Allow NA value for _CLIMO_[MEAN/STDEV]_DAY_INTERVAL - (`#1653 `_) - -* New Wrappers: - - * PlotPointObs - (`#1489 `_) - -* New Use Cases: - - * PANDA-C use cases - (`#1686 `_) - * MJO-ENSO diagnostics - (`#1330 `_) - * Probability of Exceedence for 85th percentile temperatures - (`#1808 `_) - * FV3 Physics Tendency plotting via METplotpy - (`#1852 `_) - * StatAnalysis Python Embedding using IODA v2.0 - (`#1453 `_) - * StatAnalysis Python Embedding to read native grid (u-grid) - (`#1561 `_) - -* Documentation: - - * Update documentation to include instructions - to disable UserScript wrapper - (`dtcenter/METplus-Internal#33 `_) - -* Internal: - - * Organize utility scripts used by multiple wrappers - (`#344 `_) - * Fix GitHub Actions warnings - update the version of actions - and replace set-output - (`#1863 `_) - * Update diff logic to handle CSV files that have rounding differences - (`#1865 `_) - * Add unit tests for expected failure - (`dtcenter/METplus-Internal#24 `_) - * Add instructions in Release Guide for "Recreate an Existing Release" - (`#1746 `_) - * Add modulefiles used for installations on various machines - (`#1749 `_) - * Document GitHub Discussions procedure for the Contributor's Guide - (`#1159 `_) - * Create a METplus "Release Guide" describing how to build - releases for the METplus components - (`#673 `_) - * Update documentation about viewing RTD URLs on branches - (`#1512 `_) + .. warning:: **MAJOR CHANGES**: + + * The LOOP_ORDER config variable was removed. The variable set in a user's + config file will be ignored in favor of executing the logic that + corresponds to *LOOP_ORDER = processes*, where all times are processed for + the first item in the PROCESS_LIST, then all times are processed for the + second item in the PROCESS_LIST, etc. This may change the order that + commands are executed in a use case, but it should not change the results. + * The METplus Dockerfile was moved to internal/scripts/docker. + It was previously found in scripts/docker. + * Use cases that include **EnsembleStat** wrapper will require config file + updates. See :ref:`upgrade-instructions`. + * The default value of :term:`SCRUB_STAGING_DIR` is now *True*. + This means some intermediate files that are auto-generated by METplus such + as file lists and uncompressed files will automatically be removed unless + this option is set by the user. + These files are typically only used to debug unexpected issues. + * The default value of :term:`METPLUS_CONF` now includes the + :term:`LOG_TIMESTAMP` so each METplus run will generate a unique final + config file, e.g. metplus_final.conf.20220921121733. + + + .. dropdown:: Enhancements + + * **Enhance MODE wrapper to support multi-variate MODE** + (`#1585 `_) + * **Allow FCST_IS_PROB variable setting specific to tool + (FCST__IS_PROB)** + (`#1586 `_) + * **Enhance climatology field settings to be consistent with fcst/obs field** + (`#1599 `_) + * Update Hovmoeller Use case to use updated Hovmoeller plotting + (`#1650 `_) + * **Update the EnsembleStat wrapper and use case examples to remove + ensemble post processing logic** + (`#1816 `_) + * Enhance logic to consistently create directories + (`#1657 `_) + * Create checksum for released code + (`#262 `_) + * Add the user ID to the log output at beginning and end of each + METplus wrappers run + (`dtcenter/METplus-Internal#20 `_) + * Update logic to name final conf and intermediate files with a unique + identifier + (`dtcenter/METplus-Internal#32 `_) + * Change default logging time information + (`dtcenter/METplus-Internal#34 `_) + * **Remove LOOP_ORDER config variable** + (`#1687 `_) + * **Add unique identifier for each METplus run to configuration** + (`#1829 `_) + * StatAnalysis - Support setting multiple jobs + (`#1842 `_) + * StatAnalysis - Set MET verbosity + (`#1772 `_) + * StatAnalysis - Support using both init/valid variables in + string substitution + (`#1861 `_) + * StatAnalysis - Allow filename template tags in jobs + (`#1862 `_) + * StatAnalysis - Support looping over groups of list items + (`#1870 `_) + * StatAnalysis - Allow processing of time ranges other than daily + (`#1871 `_) + * StatAnalysis - Add support for using a custom loop list + (`#1893 `_) + * Remove MakePlots wrapper + (`#1843 `_) + * Add support in EnsembleStat wrapper for setting -ens_mean + command line argument + (`#1569 `_) + * Enhance METplus to have better signal handling for shutdown events + (`dtcenter/METplus-Internal#27 `_) + * TCPairs and TCStat - add support for new config options and + command line arguments + (`#1898 `_) + * Enhance the GridStat and PointStat wrappers to handle the + addition of SEEPS + (`#1953 `_) + * SeriesAnalysis - add support for setting mask dictionary + (`#1926 `_) + * Update Python requirement to 3.8.6 + (`#1566 `_) + * Enhance StatAnalysis wrapper to support now and today + (`#1669 `_) + * **Clean up use case configuration files** + (`#1402 `_) + * Add support for creating multiple input datasets + (`#1694 `_) + + .. dropdown:: Bugfixes + + * PCPCombine - custom loop list does not work for subtract method + (`#1884 `_) + * Set level properly in filename template for EnsembleStat forecast input + (`#1910 `_) + * Prevent duplicate observation files using a file window if + compressed equivalent files exist in same directory + (`#1939 `_) + * Allow NA value for _CLIMO_[MEAN/STDEV]_HOUR_INTERVAL + (`#1787 `_) + * Reconcile setting of METPLOTPY_BASE for use cases + (`#1713 `_) + * Add support for the {custom} loop string in the MODEL config variable + (`#1382 `_) + * Fix PCPCombine extra options removal of semi-colon + (`#1534 `_) + * Fix reset of arguments for some wrappers + (i.e. GenEnsProd) after each run + (`#1555 `_) + * Enhance METDbLoad Wrapper to find MODE .txt files + (`#1608 `_) + * Add missing brackets around list variable values for StatAnalysis wrapper + (`#1641 `_) + * Allow NA value for _CLIMO_[MEAN/STDEV]_DAY_INTERVAL + (`#1653 `_) + + .. dropdown:: New Wrappers + + * PlotPointObs + (`#1489 `_) + + .. dropdown:: New Use Cases + + * PANDA-C use cases + (`#1686 `_) + * MJO-ENSO diagnostics + (`#1330 `_) + * Probability of Exceedence for 85th percentile temperatures + (`#1808 `_) + * FV3 Physics Tendency plotting via METplotpy + (`#1852 `_) + * StatAnalysis Python Embedding using IODA v2.0 + (`#1453 `_) + * StatAnalysis Python Embedding to read native grid (u-grid) + (`#1561 `_) + + .. dropdown:: Documentation + + * Update documentation to include instructions + to disable UserScript wrapper + (`dtcenter/METplus-Internal#33 `_) + + .. dropdown:: Internal + + * Organize utility scripts used by multiple wrappers + (`#344 `_) + * Fix GitHub Actions warnings - update the version of actions + and replace set-output + (`#1863 `_) + * Update diff logic to handle CSV files that have rounding differences + (`#1865 `_) + * Add unit tests for expected failure + (`dtcenter/METplus-Internal#24 `_) + * Add instructions in Release Guide for "Recreate an Existing Release" + (`#1746 `_) + * Add modulefiles used for installations on various machines + (`#1749 `_) + * Document GitHub Discussions procedure for the Contributor's Guide + (`#1159 `_) + * Create a METplus "Release Guide" describing how to build + releases for the METplus components + (`#673 `_) + * Update documentation about viewing RTD URLs on branches + (`#1512 `_) .. _upgrade-instructions: diff --git a/docs/Users_Guide/statistics_list.rst b/docs/Users_Guide/statistics_list.rst index 320c570334..537c3063fc 100644 --- a/docs/Users_Guide/statistics_list.rst +++ b/docs/Users_Guide/statistics_list.rst @@ -2295,7 +2295,7 @@ ____________________ Use Case - n/a * - Spatial distance between :raw-html:`
` - (𝑥,𝑦)(x,y) coordinates of :raw-html:`
` + :math:`(x,y)` coordinates of :raw-html:`
` object spacetime centroid - SPACE :raw-html:`
` _CENTROID :raw-html:`
` diff --git a/docs/_static/short_range-MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.png b/docs/_static/short_range-MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.png new file mode 100644 index 0000000000000000000000000000000000000000..2c45df04c29f9f68ce4891fad2d35980cc0c6618 GIT binary patch literal 83777 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

-)2J&;=Olpw8tI3uIpwyZ2Ui6C)rCj8!Vy!91ol<*}X>=6cv zH!?VwK$pVn9D79cNeILjc*s2T#nE%RRkG=oj-9yPDp2zPqX?=`N;NHCRAd^|4f@Pa1m_3JQP zZsQJMCDElvaQ9A^#RvdmM@9GDvz~aw0xN@pBu6Sv6AVy@gt`AV-c(DPAi;WjOvX zYMb9-`+5MR;Q=*%i4NXMy{J&SQKXelMO#ueJge8RZPjN5 zlE)bMKr<#BvvXmKUqNa0yoO=p5kOTQFe&Wao&k%F(TKI{0*zf%O6XmHz!I&&dsf%RRJ1-^fpuMpo`EFIbT+k zS{Wt2o=n{(r{JHP@{Fr!J|Iay+PnnFsAmRS{oi4s+xO@BqNYHbA5M&SYjop0V!uP7!AWZ0H1L^-R3dZ1(G7!*2fsD`^jVSGWSh?%mNEru0YGNJ_F-HnebaeR`^ukX!cR4P)q+&W z$O(?4I0HpGHfbR!*@K2A1tm1Qm&|3c9l%BdAv?6Eu*e{=W`LSO2~744Jezeavvgi4 zAkuGaWogtQPp&jNy{7Oyh8J`>q~V^THzg8qWPpuDM?~(JL1OG?Vg3(lpqtJtWBFKn zeV2Td&uFt`Rq{)Y)*m73!|VWyDjN!;@zf@;Wu8t&!I)yq;z*M-9&CYT5Q2EQ>LDgHf4dbdYLFVt@i<9jT9D)D)sX+x0RM8xvI`?XZh!V9H2{^hi z^H|1hxR%87|M}fzrhhd@=&rpbMGZ;v$hD@h7L7_fV@CW0!Z3>c3x zy?;`oiYOe{4y2Nbyn2}K0IUa~8weVFx`VSl6dkOuoESFz`8XwHZ~={(Pl*u)tnEos zebIIr=Hf|N5T*sDpx%}F(Ct?hm=Np_ip|zPLnC?)k0hv|6@SdCIPBIXT7Yj9nw-r5 z6OSuoh%_&pCrePmfLZTo*69UEv8QO-FI^pSpOvVJNK2Z=x(clHW=L`;tPYJ0LNqcM zSMMUVgoB6nu5d#6=}0rBSg`m3JCg@S5C?ipaYIAHwhBhIpQEi%=;hJM5nI!G=xYG1 z6{}WTrFgo2E*(jV$|!m^$l0*!hkgxmm|?A;ZMLVOFWwzMs}5UJKxB}ZNHES5azv2b zuQ|DWOgG7M>yWzNr_L9|r+AuQ=>2f9a5>_ZJoENR?_aW*qt&vDwchGl5XCl-Ev=`d zl4GZ9-(I~@KidA{0{}Ra3WH(V7uFJwM!OpzN^*DDH}gxw7XGh>ZDN>PCZ16ZT(0OX zK7YRSIMxI5@$2!8YEL+dSG(~m-v!~L-!T{j>Hf7d@O`sDfea0J}|an>Mu z=OGrhTa!cY?EpQIo}T_EKb_q@yXaNpx6L*lbO$3O&Ug7>*fcA$e>ZxteLhM9eYrzJ zJymx-U+YD=FYG6H>q~rpFGcMQn2bALuR9udKt-$gh7f%a{3XMKN9Nb!EU(NmMQa=S ze?}n3nO0p>(;mb>e?6Gx0Qa~aK#0FrB7KfYiZXi!>PejF(jAzL7g){oVJrInawz6j zA=?<-0$AUbNR3a)@jI!#;4qL?PoWnP`u$C zrBVbz*DISVReX=!nQ>n{vK8psJORQMXa~b!Dxv>4{ot^LcM8O!7~-4yUjxF5Y!WBW#}F0B97t^WsaMp%$N4DU)*p~ zdr956``@uc!iaAsZ2oeYd`A`m*5r`j8;7}=J93tr9BA1~KUnP^SW+xiV4Lf0WD{#& zmE^4x7`NKk&KI)|zYLOxVd=wxJzVeev+C>lm;{%zy|Nx5MQ;r*Da2`O|R=x zr(>4TR_lGt2e)s}GDukzsVp6mM@Kzn6l)F%w?NoT|hwYISQXn3dUYB_MZL1+6N9VK$x z3q1hA+|-<$Tt8Ps5LjOI_hIHZ*`5#f_r$RpDFHsOq>Ih>?@RM$n+igzm`ns zW56JW^8>R=a}#*G$j!T47{_1YTY0bRiEhG>Z)@FB4WLPlvNYJQL7y`{+;zN}F;w9- zi&jNyw^OQhGcHmudD8aPH{oP}(_sjG2TY!!*`1qd299ig`k`h&BF9{X_7?ovT+d=X zcur-_IBwS48frTCz z=3qd}DzhOY&@=&F8BQSGdRmF55(fiO5Qp`xn(g&#@z`9STc8I%p=f=2ydx6z7J>qY z_=71hdawY|Ft8Qg4tQTRt(*WdfylaRM6llP|Es+(4X5(`+TNxVG9*(O$`F-VBC|r7 z=XsW7DDx09L_cI!eq`K2$V_D1=2_-3vnW$+gl*iOwg2yPyw7pGpWly9A99p*@B6;5 zYpr#i>pai(o|Ne;AEUl)c1^7ZLebP z(6&7!6t4FiVP(I4+@=ex<*YS<%?4j?-h^HjLdNS7ulO54So>G~Y- zJ0;cy-1X^aPd;3>8NPcaRC06f594BXK(m&F&~R?$P#Cho3>&iD#!;pE`A*`A3LUFt z-Me~p^8jkq`9{ob%YmRKZ~ucym0c-5QZ8!y>)odMOhcridfiCKGE;UFe2UojtK9C! zG}}O$Tuk&wL2-y1Blu#f;vMjHk2g+#@dYe`{s=nN8IKhd6lDA^!>lkSP=wmRaRo=2 z#HpfT_y)lsjFbmRsGstkiYQmVo?P=atz!L4A$Nryk~FwKRxnFzzPLj3eA&Q7kor+r zUvw#3n1Wy7SlOl9d;f-NbVTPJJKEXp479!=H~x1FuaU3rk03;AT?CG3iF@uxF^d10 z-~or)nDtY|RFlDjG~4>u`?yh%c4oCcyL6;MPZ76V)x+5VbFjg1J0EWD-dmd;ys=9x z)nY6p!1v-HW+9RpOf{q7A4jg2$?TPUW`7?R=6Dxxv_J~zotH0u)NErwh_gv%N>N{zmnC(C5xXxUjE3tb>RHOY5u3IC5iJQl%yP*1BX`u52( z`W4}aO{F&KI$qj$8Q6w9YMi|7-8V5_6Ni5l*WXk??(z#zi2uMhO=bVy)z>mM?yXr#cbICZsY$|}yI|xk&KR|k z3JZch2GCCe2_M{|1;{|YJm0bC?2JZXT&G`Fwci^zxM;>6RHkf5+;nw^yMLgXmOlai zQjm@mOW^;fDG7HH(dGmO5yQ=vH2!l(>7pU%Bx@OlK=cqDc#kxIA4MW#iyD?d*9M zXn;QJCd3V9c0WS-#M>iRxi# zh=lPhbM!6FR=)j+TPKgJ?>X5l^U)vg;Cc`+U#tNC!XZR8qQjplIB_1%iU<1?5+)-q zkkLl$T=hBl(+%^BZgX>I=j4Pa^VYltF4U-#Hjs(`pOJb;f4;8b^F`?4Dek>g%Eu4a zm#?^ZQOu{P>rOryNU(a8_P<0i-R3f*(cRhq1jFC-=faI$-*0wv>Z&|0KN9n<`b}iQ zO9v_=SxQjyAaLgod0pLexiHk*4u7mk+t5~hbIdk`gbD77{(UH+Je zhCM~*LoRJ|CJ_I@kMHTml@7t+^l#YB{aKRm%)^y?K$3+yY`lrR0cpbAX7wMv|NcH& zS%!DJd!UVGizt^C9I56T>#kP5S3vz6(&1r;&q5FV_gx}8om-rf4(UwnK*wI*f9 zZ|n=&;Z_%8-!x&)v%lGr7(}@KP?6-DKEC*)C$S60zEfgjQ(eqNI;9tW?A%_MCgpxZ z*prgJbvIE5#v7G_<8=9*8yT!?`40Lzl%KqvNfN$YA$2<0PajyQ`LOb&% z-ItA`w2HFtuWpBL(viq$y~?n?%Uea1Sa;_4tg`E35D9Z!Rf2lw)OgoYovHyLa%y5~ ze8L;#id>59aiZ=H_<4)T4#kUfjfX@~Yyw|*Xmqp<$ASmP7}aU$8U%d%XJ*F4ANph4 z&|*5iWFZQ~DBKYkjMMtT{)BBDdHA=%zgy`jLE(V6IOj0Z#3$16{HIiPc{GeDp+C-g zSROImn5^$t!R+~4@K3o!ImvKR2w&I6vA*ZxOs?~~X_iafEH-ce@*10=q2W!u3?Rz> zkLA$5u!8gtSkJM*-@@WiFz4Ozw5jf4lgj2h~ zG#go2yhg}hS;-?6#-W1#r?0R+Lj`0Kbz#g)U(fa_xC@qH+)9Y)OlYd?8g>__>X{sF zTkZ9IpFGc;{_MoKGjD#r=k4`lt1`@ri4DOvfSp5wgH1$L1D8LJtUvbD1Q{=X?)ee& zd=X?j*=1#MFo>$hyy3+U!QXu;bo{w?Rpg&Nov8mcZp;$h(81kEz!}d*l_nM|+kf7C z1OnY=^9J`dEfDSZPy`&d20F~pVC-NvZT)V~U6)x-esfe%^ z_K1uN9B>jm;j!gBm^PD?nVqw_b(TXIftqc$h4i=W!>w{uazH^5SjjhTp-ji%>+-Gf z`-YyuNkd{J-tEZb8w3sYzoQ)Eo`sIAe%P{9krlTqei1iWX`C@(AU+a4?Uun}TcIUO zqMge7g5_Ih9^*?dH+pfl5V3A4A-e4!4oK*wAn-7DV7vL~clJC67-jgIk%@%0?w^&;&5n`9XR z2u107KNH6daj->U-%O(Zocg==s-7DsH$*SOuS9DRi9vNl{JJ`7P&R!Mp`YIm1STe|U zCO@?pxh~>3(^OU~_B{r#m^m?uz5)el?5zwTgHmd_K2(9myAVdBgvwnk4ctg%{r&xOZF&ASpy_yw;PHvcs|FsNuXR_meChR@_oXdhU<*hH zf9f#MWVS>ms(^TdR`d|38j>|en9j0lF1d+`=#X0cIoDn22;SkJb^L@c!4v4hNn*V_&Y`WqFWbz7`IKtZq8;dM!sv?e`9K)ML03?=7Z3#6Pi>5dnHIjclBl7!fTCYF# z0-=fEvS_-dre;^Es!aUwUYS%$?Eo9rvfy_FsfW~NIZ$G`aXqALOY->{>qngGoPk_2Bh%Rm z?Y16Im300g$wKK9oOz5b=1RBtSvTVlV;T@H{Pjnn_`P@SRzs4NTfRQS`lUlh!8{Yb z(aj0O1>NGGW5?{rX6ECQJttoI^dC1UIEKpjGIMsh)~(dCVm5mttcIv5y673>0tl+z zNH*9>Vr|MlHLjV-NSp`@32D!MZ;zmh`|u$cP9005U$oO-&XE&ig_)%O9LYG>n7}4l zeR(ZVdkcTxKX>Gv*mI^A)zqF~rRF_2%wrk){G)YLkL zvK|M|nHw17)y-6SIDt_B1OtUE>=sD>ifSZbTFC`f-KG7ar2vhL1+!;d#S8fPGc zOvL5UnItDCag0Q!B#r8(@za%d#}`f(^V@X!Y@uevglLJzhQ&6K8$O2p=D|9;tz#r3 zJjV`Q4!^*r*z~DHQBoDM1YO~Ig)Xb%)|}WQk7L_>jWqedkOA6{2v0f3s_SYl zO_BU${PQt*)s3}=nbQ?ROnIa0d3J?ft?l2j`Osa^KyoZs) zm&=sAbd-p!;vJvpZ4uny@(ds%e(^;3b8Df&VDBi)Qat)o(>~Qq^$5vMk^|rH4!_jx z`FC5hj|OfhfBZ;a`u&$HF1gDk@|r@`EC5ApU(+wxXzgf!j5rJw&hI_-9rSWn@Sl&k zSd2vd$m7dtzQ=L;&rc@)A16drpM#Ne{!TBp|E^s2Z;o~AKoxC`p@0JtJW>0>h ziFVs#R^atYJt6Un)#5$9L|;xiiu;_-ZpPS_*47=Eq$Z5Lo`zNuX5q$ph6&4FkVt_gFf4%=GIBHw1bsagG);m?ujS`e{H7J(7I`XVLHoQ&9{ z@i)4xlbO`uU@aHfvgo`3ZlZVy)kA_nw#U&ocz7;TQBjF{tY4+&HJQv~cp`?MRgc~` z!kZ;;UTZY9A3n&=uazZ`B{*IjsPdrLCQM|Om!WvoVqW^mG|29c;idDlxzX*FlWT_q z=nW>4+{#wuc_B*!JvOhXV#5U?9^Tt8TIXwuu*(lb z#nRM33}^1PSfg2?w;3a``($vVZBJ(@#Ktqm3S%ewOO5!ASq^qJmyGO{iJ6(1%ptfd zvE-bExY!Ul{;jBJ)8pAaL{R4a%(K2Mt}t1ldsNvlxPKL)o8) z%o^XP#s_lL99C)Uw{1{{x9hdz+gbP?pAws|hBO}k9(MdAGcb21CCr-pgC{`7;_z?! zF)C#-CXc6#sFWyjZI?YW-k|d7L;iiHR6o9O$BT)*{}2$9!>FMl+0I9Q3XKX5_V(OC z%#NEz)((SGw&8)_x83#T<77N6*&r~W3^9B1R@o&(34bMj{Hb8l_D&~DR!+_Zi1f7^ zP^v@fQ%M!20$6%{kC#YdqSGf=_)lTvUIWF)@$ZE<>|U#zJkY{RRBqg#^i91)6BxfS z#!nD-c5AO`pkZ;KE`2Vrf8X?Lo_o|KpIh0V>Q82^^@7H?#^N1VQAGh>LZ@Z>F;iMA zQa<0}o@ifHQL;F6=&5o+%f_eO-%1At0VObAZXgCK?C1SA)+~2GuFZ7){);B?EGq-F zAa>fh<;`7Dy1_V60RgH+-Zf;)-;gAWMT%{Am0hNk{&`%#-k?Yip8hOyZot+}ql$B% z=*E})1G4+CQP-Z-5KD$%8{b{I98m2nkLoCCI9r$eHI+(v_+)Z~KQ!gu65EB5QF4K~ zap@3gL6UTQM-Ejn3;>dB=te-HUt=}myQ%-v-6EETh7g+(nMZ+tD`&o zwF}HnR<2`bDl0FimCA`2Mh6+nCo z$_bIav28)OzVKWyi67)aKI)QQ3SM;w0#7?KN=qq$zt@Jdk^(v4Q=q);r@ya%eI)qp z#g8Cp!dn4JVzSnw;I~l&RDgizQq#~J=SD3pEybm$N5k?ZOvUc^^z_*KSn_0-x$%i~ z%+6uFK2#G;ggeU2cqJ!XpZ-Zx+Lv$N#=@sxvhg=W+N3)3;QhYj=5*{*%5A|bPqqru z^7s%oNh|0riu|i)ojv-+N!+4##E`tNuFM z9wiNw_;=jjw9%glK4k}hKOX2R18x}KC<40bOx_b%3Q+)W=zKNv^t=zw#94Jw(4%Ku zTU)EeoWYp2w)Y&$WDL<_SqZCu7Oqd8PV7hPEU?69_fYSBzl6e1zR*#f4&3*UUd>x)5K`t z6q#*<0`NAoLMOl=3RVw5526{BJ7<{rPKOfI_*$#E?=0qJv$baIt{lt9*Ew#aW2`Fy zNGB&twBOd0QFZaZ_Wt#lHJ%aDfMo3fsYQywYuIZ(XXd57rhE3p4?`P|4?Rz9FJW_i zjqjXNRfhDRDGr4s`(9H}_q#c`>6ryKjG8DN@rVNxUjqaB@~>ZowNXdC0|Sq(tXMs_ zW-cKS(M9szJxb_^5z;hFfTL394D=VvZS-OB2@Nfhz-_0s%nCAUG zO}y$e(lg@XzUy!CFDkA8lL}6hOJ2c83`^;xO-IO5eBS?91Vd&%{tc!KW$TGoEfQ4HpEZz^CG3 za;OV9`W*0tX6P28$a zKjGKAjCmEUe!iyjPe1BEniHCvVsaFpkuuMZ|483dRP-pn06jxIQzJb^QoZS{khD-f zVcF5unwLM0R?$V82Y5*%HnHC4BSVO-*RHcDlbcd%eBA{id|nfQ^Dk=}x#l^+V z+9Au?S`P!1kFb)GQY?f7oDI%$>bEBe+#HDFC*!CYPHia8-B`_Rp zhZ{n?>Im}P8+sg%Xiul8qT@--Z? z!cm-g|J%r#oQeurKj`M}|068p?fpPdP;e9}8+@VJsw^Wj6CVuRp9Hpah3+G=X#nV~5b3}zF{$aJ<^Rzbllu(gwsG{rjon>RYg`D^*hNtIEj%V)P7}bF8ddW@fw)zvKBDPqpOazFg@ z8l5&3Bz{*uhTx=SX!zymOF_YiDQ5RqFTM=D}pKzP)A z_Sb1j9bH_?5V2rHnnUxbb`pP5jVnBp9N$D&_n)oVx>oy2D|p>FA2?WvAsf?GB|fGh zVKSOm;pKYhy@kPpmM~2a5ePJ+n}7zXOYFR@eF1-yoREFM1qNGu_1pM}%?&MW?cnWg z=eEvHz$2XmlY+*bs-}U0843JehxGxd8>%GNUOSjW{4fhR^LQH?O0Z3aw>ZXtK{;(A zN-di4aSYtqItOC9t;iFm!EtH7V|S1I#==5wlZMv}YPruDtN-UIK-U1yI%B7V8{3mv zk161zn$&r!emwo&`&?M40>>EP z4Jdh(ft3R*AtOTuhEM*2qsWKhVJ&!z?rZPm6cobyY(9YTQ#T;Mcfb!LU^!I!^ixKFk^n2K)z=^F zf`VGSX7yY^W{8F0(*-e<4LVnJRB`Z_l;H?5O*f8csMOcf3vaiI0{}|V#wG_Wsd~nX zjDod9Mqk2!_bqgT(IT#!eprCy5Q@0KmbP^DqY5 zY2=H!dYGTSmT9Ivk$yPA%X)>0i3dEdbe#rLA82Et>I|Jxdpv`|R-&gWm0`$>_rZRujRFwPojTboKgrbtt zd)UL>uyWu&@-V6&`DLMDkZTwK5kk;*@Wv$yio~0bLb{;b&aMdnb`t)Lg-+inE@27+ z3vmrCE!Lr-A=l$QJ1Qzz+>veV?cHDm7ETL$)o=;s4|D@@kk(b4$z^_HY^&fCPau;^ zW5nu2Bb>%yS;zfd84!8(e{Y|yHU-}4I|!RNf7oY}rIv#3s~YC}v3`0FE;Zzj>j}peg;9?D~D2 z6U%ax$XuS6IP9>@tgL6inO!djOJ*YkA&U8z<46Gt!chYTh3*F8hjmx%O?!H>&um-1 zs3||;dkD`qND1bR5DmbdT-nE`_E;N|I^5WQzd88mqSO}wC5dZxrl*I 20 mph, and 3) visibility < 1/2 mile. +# The use of multivariate MODE is well-suited to assess the structure and +# placement of complex high-impact events such as blizzard conditions and heavy +# snow bands. Output from this use-case consists of the MODE forecast and observation +# super objects and the MODE ASCII, NetCDF, and PostScript files. +# + +############################################################################## +# Datasets +# -------- +# +# **Forecast dataset:** 1-hour HRRR in grib2 +# +# **Observation dataset:** MRMS and HRRR analysis in grib2 +# +# The forecast and observation fields are only a subset of the full domain in +# order for a faster run-time of Multivariate MODE. An example command using +# wgrib2 to create the HRRR subdomain is:: +# +# wgrib2 infile.grib2 -new_grid_winds earth -new_grid lambert:262.5:38.5:38.5:38.5 -83.0:400:3000 37.0:400:3000 outfile.grib2 +# +# **Location:** All of the input data required for this use case can be found +# in the *short_range* sample data tarball. +# Navigate to `METplus Releases `_ +# and download sample data for the appropriate release. +# +# This tarball should be unpacked into the directory that you will set the +# value of INPUT_BASE. See :ref:`running-metplus` for more information. + + +############################################################################## +# METplus Components +# ------------------ +# +# This use case runs MODE using multiple variables to output the super objects +# based on a user-defined logical expression. Currently, the initial multivariate +# MODE run only outputs the super objects and additional steps are required to +# produce the statistical output. GenVxMask is run on a field(s) of interest +# using the super objects to mask the field(s). Finally, MODE is run a second +# time on the super-object-masked field(s) to output attribute statistics for +# the field(s). +# +# **Note:** The second MODE run can also be run directly on the super objects if +# field-specific statistics, such as intensity, is not desired. +# + +############################################################################## +# METplus Workflow +# ---------------- +# +# The following tools are used for each run time: +# +# MODE(mv), GenVxMask(fcst_super), GenVxMask(obs_super), MODE(super) +# +# Where the first instance of MODE runs over multiple variables to identify +# super objects for the forecast and observation, GenVxMask masks the raw input +# field(s) using the super objects, and the second instance of MODE is run +# traditionally to compare the masked forecast and observed super objects and +# and provide statistics. +# +# This example runs a single forecast hour. +# +# | **Initialization:** 2021020100 +# | **Forecast lead:** 21 +# + +############################################################################## +# METplus Configuration +# --------------------- +# +# 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: +# parm/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf +# +# .. highlight:: bash +# .. literalinclude:: ../../../../parm/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.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:`MODE 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/MODEConfig_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/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.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 OUTPUT_BASE for the various MET tools +# and will contain the following files: +# +# **mode/2021020100/f21** +# +# Multivariate output - first instance +# +# Precipitation type = snow +# +# * 00/mode_210000L_20210201_210000V_000000A_cts.txt +# * 00/mode_210000L_20210201_210000V_000000A_obj.nc +# * 00/mode_210000L_20210201_210000V_000000A_obj.txt +# * 00/mode_210000L_20210201_210000V_000000A.ps +# +# Visibility +# +# * 01/mode_210000L_20210201_210000V_000000A_cts.txt +# * 01/mode_210000L_20210201_210000V_000000A_obj.nc +# * 01/mode_210000L_20210201_210000V_000000A_obj.txt +# * 01/mode_210000L_20210201_210000V_000000A.ps +# +# 10-m Winds +# +# * 02/mode_210000L_20210201_210000V_000000A_cts.txt +# * 02/mode_210000L_20210201_210000V_000000A_obj.nc +# * 02/mode_210000L_20210201_210000V_000000A_obj.txt +# * 02/mode_210000L_20210201_210000V_000000A.ps +# +# Super Objects +# +# * f_super.nc +# * o_super.nc +# +# MODE 10-m wind super object output - second instance +# +# * mode_HRRR_vs_ANALYSIS_WIND_super_Z10_210000L_20210201_210000V_000000A_cts.txt +# * mode_HRRR_vs_ANALYSIS_WIND_super_Z10_210000L_20210201_210000V_000000A_obj.nc +# * mode_HRRR_vs_ANALYSIS_WIND_super_Z10_210000L_20210201_210000V_000000A_obj.txt +# * mode_HRRR_vs_ANALYSIS_WIND_super_Z10_210000L_20210201_210000V_000000A.ps +# +# **gen_vx_mask/2021020100** +# +# * fcst_wind_super_2021020100_f21.nc +# * obs_wind_super_2021020121.nc + +############################################################################## +# Keywords +# -------- +# +# .. note:: +# +# * MODEToolUseCase +# * GenVxMaskToolUseCase +# * ShortRangeAppUseCase +# * GRIB2FileUseCase +# * RegriddingInToolUseCase +# * NOAAWPCOrgUseCase +# * NCAROrgUseCase +# * DiagnosticsUseCase +# +# +# Navigate to the :ref:`quick-search` page to discover other similar use cases. +# +# +# sphinx_gallery_thumbnail_path = '_static/short_range-MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.png' +# diff --git a/internal/scripts/installation/modulefiles/5.0.0.lua_wcoss2 b/internal/scripts/installation/modulefiles/5.0.0.lua_wcoss2 deleted file mode 100644 index 2f5d5cf7c5..0000000000 --- a/internal/scripts/installation/modulefiles/5.0.0.lua_wcoss2 +++ /dev/null @@ -1,26 +0,0 @@ -help([[ -]]) - -local pkgName = myModuleName() -local pkgVersion = myModuleVersion() -local pkgNameVer = myModuleFullName() - -local hierA = hierarchyA(pkgNameVer,1) -local compNameVer = hierA[1] - -conflict(pkgName) - -local opt = os.getenv("HPC_OPT") or os.getenv("OPT") or "/opt/modules" - -local base = pathJoin(opt,compNameVer,pkgName,pkgVersion) - -prepend_path("PATH", pathJoin(base,"ush")) - -setenv("METPLUS_ROOT", base) -setenv("METPLUS_VERSION", pkgVersion) -setenv("METPLUS_PATH", base) - -whatis("Name: ".. pkgName) -whatis("Version: " .. pkgVersion) -whatis("Category: application") -whatis("Description: Model Evaluation Tools Plus (METplus)") diff --git a/internal/scripts/installation/modulefiles/5.0.0_casper b/internal/scripts/installation/modulefiles/5.0.0_casper deleted file mode 100644 index ed1702f174..0000000000 --- a/internal/scripts/installation/modulefiles/5.0.0_casper +++ /dev/null @@ -1,18 +0,0 @@ -#%Module###################################################################### -## -## METplus -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus-5.0.0. - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -module use /glade/p/ral/jntp/MET/MET_releases/casper/modulefiles -module load met/11.0.0 -module load nco -module load grib-bins/1.3 -module load R - -prepend-path PATH /glade/p/ral/jntp/MET/METplus/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin -setenv METPLUS_PATH /glade/p/ral/jntp/MET/METplus/casper/METplus-5.0.0 -prepend-path PATH /glade/p/ral/jntp/MET/METplus/casper/METplus-5.0.0/ush diff --git a/internal/scripts/installation/modulefiles/5.0.0_cheyenne b/internal/scripts/installation/modulefiles/5.0.0_cheyenne deleted file mode 100644 index 6a050683f9..0000000000 --- a/internal/scripts/installation/modulefiles/5.0.0_cheyenne +++ /dev/null @@ -1,18 +0,0 @@ -#%Module###################################################################### -## -## METplus -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus-5.0. - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -module use /glade/p/ral/jntp/MET/MET_releases/modulefiles -module load met/11.0.0 -module load nco -module load grib-bins/1.3 -module load R - -setenv METPLUS_PATH /glade/p/ral/jntp/MET/METplus/METplus-5.0.0 -prepend-path PATH /glade/p/ral/jntp/MET/METplus/METplus-5.0.0/ush:/glade/p/ral/jntp/MET/METplus/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin - diff --git a/internal/scripts/installation/modulefiles/5.0.0_frontera b/internal/scripts/installation/modulefiles/5.0.0_frontera deleted file mode 100644 index d215a82532..0000000000 --- a/internal/scripts/installation/modulefiles/5.0.0_frontera +++ /dev/null @@ -1,22 +0,0 @@ -#%Module###################################################################### -## -## METplus -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus-5.0.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -module load intel/19.1.1 -module load nco/4.9.7 -module load Rstats/4.0.3 -module load met/11.0.0 -setenv METPLUS_PATH /work2/06612/tg859120/frontera/METplus/METplus-5.0.0 - -# Path to wgrib -prepend-path PATH /work2/08291/taosun/HPC-STACK/hpc-module/intel-18.0.2/grib_util/1.2.2/bin - -# Path to wgrib2 -prepend-path PATH /work2/08291/taosun/HPC-STACK/hpc-module/intel-18.0.2/wgrib2/2.0.8/bin - -prepend-path PATH /work2/06612/tg859120/frontera/METplus/METplus-5.0.0/ush:/work2/06612/tg859120/frontera/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin diff --git a/internal/scripts/installation/modulefiles/5.0.0_gaea b/internal/scripts/installation/modulefiles/5.0.0_gaea deleted file mode 100644 index fdd6fe40cd..0000000000 --- a/internal/scripts/installation/modulefiles/5.0.0_gaea +++ /dev/null @@ -1,18 +0,0 @@ -#%Module###################################################################### -## -## METplus -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus-5.0. - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -module load intel/19.0.5.281 -module use -a /usw/met/modulefiles -module load met/11.0.0 -module load nco -module load wgrib -module load wgrib2 - -setenv METPLUS_PATH /usw/met/METplus/METplus-5.0.0 -prepend-path PATH /usw/met/METplus/METplus-5.0.0/ush:/lustre/f2/dev/esrl/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin diff --git a/internal/scripts/installation/modulefiles/5.0.0_orion b/internal/scripts/installation/modulefiles/5.0.0_orion deleted file mode 100644 index 8d15f0352c..0000000000 --- a/internal/scripts/installation/modulefiles/5.0.0_orion +++ /dev/null @@ -1,17 +0,0 @@ -#%Module###################################################################### -## -## METplus -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus-5.0.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -module load contrib -module load intel/2020.2 -module load met/11.0.0 -module load nco/4.8.1 -module load wgrib/2.0.8 -prepend-path PATH /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin -setenv METPLUS_PATH /apps/contrib/MET/METplus/METplus-5.0.0 -prepend-path PATH /apps/contrib/MET/METplus/METplus-5.0.0/ush diff --git a/internal/scripts/installation/modulefiles/5.0.0_hera b/internal/scripts/installation/modulefiles/5.1.0_hera similarity index 66% rename from internal/scripts/installation/modulefiles/5.0.0_hera rename to internal/scripts/installation/modulefiles/5.1.0_hera index 3faac54eb8..ff8e845589 100644 --- a/internal/scripts/installation/modulefiles/5.0.0_hera +++ b/internal/scripts/installation/modulefiles/5.1.0_hera @@ -3,20 +3,18 @@ ## METplus ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus-5.0. + puts stderr "Sets up the paths and environment variables to use the METplus-5.1.0. *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } prereq intel -module use -a /contrib/anaconda/modulefiles -module load anaconda/latest -prepend-path PATH /scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin +prepend-path PATH /scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin module use -a /contrib/met/modulefiles -module load met/11.0.0 +module load met/11.1.0 module load nco module load wgrib module load wgrib2 module load R -setenv METPLUS_PATH /contrib/METplus/METplus-5.0.0 -prepend-path PATH /contrib/METplus/METplus-5.0.0/ush +setenv METPLUS_PATH /contrib/METplus/METplus-5.1.0 +prepend-path PATH /contrib/METplus/METplus-5.1.0/ush diff --git a/internal/scripts/installation/modulefiles/5.0.0_jet b/internal/scripts/installation/modulefiles/5.1.0_jet similarity index 61% rename from internal/scripts/installation/modulefiles/5.0.0_jet rename to internal/scripts/installation/modulefiles/5.1.0_jet index e0e1df41fc..c2db60aeb3 100644 --- a/internal/scripts/installation/modulefiles/5.0.0_jet +++ b/internal/scripts/installation/modulefiles/5.1.0_jet @@ -3,7 +3,7 @@ ## Model Evaluation Tools ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the METplus v5.0.0 + puts stderr "Sets up the paths and environment variables to use the METplus v5.1.0 *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } @@ -13,9 +13,8 @@ prereq hdf5/1.10.5 prereq nco/4.9.1 prereq wgrib/1.8.1.0b prereq wgrib2/2.0.8 -prereq R/4.0.2 -prereq met/11.0.0 - -setenv METPLUS_PATH /contrib/met/METplus/METplus-5.0.0 -prepend-path PATH /contrib/met/METplus/METplus-5.0.0/ush:/mnt/lfs1/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v5.0_py3.8/bin +prereq R/4.0.2 +prereq met/11.1.0 +setenv METPLUS_PATH /contrib/met/METplus/METplus-5.1.0 +prepend-path PATH /contrib/met/METplus/METplus-5.1.0/ush:/mnt/lfs1/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin diff --git a/internal/tests/pytests/util/config_metplus/test_config_metplus.py b/internal/tests/pytests/util/config_metplus/test_config_metplus.py index 71fe75138b..5b374fe011 100644 --- a/internal/tests/pytests/util/config_metplus/test_config_metplus.py +++ b/internal/tests/pytests/util/config_metplus/test_config_metplus.py @@ -103,18 +103,18 @@ def test_find_indices_in_config_section(metplus_config, regex, index, @pytest.mark.parametrize( 'config_var_name, expected_indices, set_met_tool', [ - ('FCST_GRID_STAT_VAR1_NAME', ['1'], True), - ('FCST_GRID_STAT_VAR2_INPUT_FIELD_NAME', ['2'], True), - ('FCST_GRID_STAT_VAR3_FIELD_NAME', ['3'], True), - ('BOTH_GRID_STAT_VAR4_NAME', ['4'], True), - ('BOTH_GRID_STAT_VAR5_INPUT_FIELD_NAME', ['5'], True), - ('BOTH_GRID_STAT_VAR6_FIELD_NAME', ['6'], True), - ('FCST_VAR7_NAME', ['7'], False), - ('FCST_VAR8_INPUT_FIELD_NAME', ['8'], False), - ('FCST_VAR9_FIELD_NAME', ['9'], False), - ('BOTH_VAR10_NAME', ['10'], False), - ('BOTH_VAR11_INPUT_FIELD_NAME', ['11'], False), - ('BOTH_VAR12_FIELD_NAME', ['12'], False), + ('FCST_GRID_STAT_VAR1_NAME', [1], True), + ('FCST_GRID_STAT_VAR2_INPUT_FIELD_NAME', [2], True), + ('FCST_GRID_STAT_VAR3_FIELD_NAME', [3], True), + ('BOTH_GRID_STAT_VAR4_NAME', [4], True), + ('BOTH_GRID_STAT_VAR5_INPUT_FIELD_NAME', [5], True), + ('BOTH_GRID_STAT_VAR6_FIELD_NAME', [6], True), + ('FCST_VAR7_NAME', [7], False), + ('FCST_VAR8_INPUT_FIELD_NAME', [8], False), + ('FCST_VAR9_FIELD_NAME', [9], False), + ('BOTH_VAR10_NAME', [10], False), + ('BOTH_VAR11_INPUT_FIELD_NAME', [11], False), + ('BOTH_VAR12_FIELD_NAME', [12], False), ] ) @pytest.mark.util @@ -126,12 +126,14 @@ def test_find_var_indices_fcst(metplus_config, data_types = ['FCST'] config.set('config', config_var_name, "NAME1") met_tool = 'grid_stat' if set_met_tool else None - var_name_indices = config_metplus._find_var_name_indices(config, - data_types=data_types, - met_tool=met_tool) + actual_indices = ( + config_metplus._find_var_name_indices(config, + data_types=data_types, + met_tool=met_tool) + ) - assert len(var_name_indices) == len(expected_indices) - for actual_index in var_name_indices: + assert len(actual_indices) == len(expected_indices) + for actual_index in actual_indices: assert actual_index in expected_indices @@ -347,13 +349,13 @@ def test_parse_var_list_obs(metplus_config, data_type, list_created): # list will be created if requesting just OBS, but it should not be created if # nothing was requested because FCST values are missing if list_created: - assert(var_list[0]['obs_name'] == "NAME1" and \ - var_list[1]['obs_name'] == "NAME1" and \ - var_list[2]['obs_name'] == "NAME2" and \ - var_list[3]['obs_name'] == "NAME2" and \ - var_list[0]['obs_level'] == "LEVELS11" and \ - var_list[1]['obs_level'] == "LEVELS12" and \ - var_list[2]['obs_level'] == "LEVELS21" and \ + assert(var_list[0]['obs_name'] == "NAME1" and + var_list[1]['obs_name'] == "NAME1" and + var_list[2]['obs_name'] == "NAME2" and + var_list[3]['obs_name'] == "NAME2" and + var_list[0]['obs_level'] == "LEVELS11" and + var_list[1]['obs_level'] == "LEVELS12" and + var_list[2]['obs_level'] == "LEVELS21" and var_list[3]['obs_level'] == "LEVELS22") else: assert not var_list @@ -382,15 +384,15 @@ def test_parse_var_list_both(metplus_config, data_type, list_created): var_list = config_metplus.parse_var_list(conf, time_info=None, data_type=data_type) print(f'var_list:{var_list}') for list_to_check in list_created.split(':'): - if not var_list[0][f'{list_to_check}_name'] == "NAME1" or \ - not var_list[1][f'{list_to_check}_name'] == "NAME1" or \ - not var_list[2][f'{list_to_check}_name'] == "NAME2" or \ - not var_list[3][f'{list_to_check}_name'] == "NAME2" or \ - not var_list[0][f'{list_to_check}_level'] == "LEVELS11" or \ - not var_list[1][f'{list_to_check}_level'] == "LEVELS12" or \ - not var_list[2][f'{list_to_check}_level'] == "LEVELS21" or \ - not var_list[3][f'{list_to_check}_level'] == "LEVELS22": - assert False + if (not var_list[0][f'{list_to_check}_name'] == "NAME1" or + not var_list[1][f'{list_to_check}_name'] == "NAME1" or + not var_list[2][f'{list_to_check}_name'] == "NAME2" or + not var_list[3][f'{list_to_check}_name'] == "NAME2" or + not var_list[0][f'{list_to_check}_level'] == "LEVELS11" or + not var_list[1][f'{list_to_check}_level'] == "LEVELS12" or + not var_list[2][f'{list_to_check}_level'] == "LEVELS21" or + not var_list[3][f'{list_to_check}_level'] == "LEVELS22"): + assert False # field info defined in both FCST_* and OBS_* variables @@ -412,21 +414,21 @@ def test_parse_var_list_fcst_and_obs(metplus_config): var_list = config_metplus.parse_var_list(conf) - assert(var_list[0]['fcst_name'] == "FNAME1" and \ - var_list[0]['obs_name'] == "ONAME1" and \ - var_list[1]['fcst_name'] == "FNAME1" and \ - var_list[1]['obs_name'] == "ONAME1" and \ - var_list[2]['fcst_name'] == "FNAME2" and \ - var_list[2]['obs_name'] == "ONAME2" and \ - var_list[3]['fcst_name'] == "FNAME2" and \ - var_list[3]['obs_name'] == "ONAME2" and \ - var_list[0]['fcst_level'] == "FLEVELS11" and \ - var_list[0]['obs_level'] == "OLEVELS11" and \ - var_list[1]['fcst_level'] == "FLEVELS12" and \ - var_list[1]['obs_level'] == "OLEVELS12" and \ - var_list[2]['fcst_level'] == "FLEVELS21" and \ - var_list[2]['obs_level'] == "OLEVELS21" and \ - var_list[3]['fcst_level'] == "FLEVELS22" and \ + assert(var_list[0]['fcst_name'] == "FNAME1" and + var_list[0]['obs_name'] == "ONAME1" and + var_list[1]['fcst_name'] == "FNAME1" and + var_list[1]['obs_name'] == "ONAME1" and + var_list[2]['fcst_name'] == "FNAME2" and + var_list[2]['obs_name'] == "ONAME2" and + var_list[3]['fcst_name'] == "FNAME2" and + var_list[3]['obs_name'] == "ONAME2" and + var_list[0]['fcst_level'] == "FLEVELS11" and + var_list[0]['obs_level'] == "OLEVELS11" and + var_list[1]['fcst_level'] == "FLEVELS12" and + var_list[1]['obs_level'] == "OLEVELS12" and + var_list[2]['fcst_level'] == "FLEVELS21" and + var_list[2]['obs_level'] == "OLEVELS21" and + var_list[3]['fcst_level'] == "FLEVELS22" and var_list[3]['obs_level'] == "OLEVELS22") @@ -520,22 +522,25 @@ def test_parse_var_list_fcst_only_options(metplus_config, data_type, list_len): @pytest.mark.parametrize( 'met_tool, indices', [ - (None, {'1': ['FCST']}), - ('GRID_STAT', {'2': ['FCST']}), - ('ENSEMBLE_STAT', {}), + (None, [1]), + ('GRID_STAT', [2]), + ('ENSEMBLE_STAT', []), ] ) @pytest.mark.util def test_find_var_indices_wrapper_specific(metplus_config, met_tool, indices): - conf = metplus_config + config = metplus_config data_type = 'FCST' - conf.set('config', f'{data_type}_VAR1_NAME', "NAME1") - conf.set('config', f'{data_type}_GRID_STAT_VAR2_NAME', "GSNAME2") + config.set('config', f'{data_type}_VAR1_NAME', "NAME1") + config.set('config', f'{data_type}_GRID_STAT_VAR2_NAME', "GSNAME2") - var_name_indices = config_metplus._find_var_name_indices(conf,data_types=[data_type], - met_tool=met_tool) + actual_indices = ( + config_metplus._find_var_name_indices(config, + data_types=[data_type], + met_tool=met_tool) + ) - assert var_name_indices == indices + assert actual_indices == indices # ensure that the field configuration used for @@ -572,28 +577,28 @@ def test_parse_var_list_ensemble(metplus_config): 'ens_phist_bin_size = 0.05;')) time_info = {} - expected_ens_list = [{'index': '1', + expected_ens_list = [{'index': 1, 'ens_name': 'APCP', 'ens_level': 'A24', 'ens_thresh': ['>0.0', '>=10.0']}, - {'index': '2', + {'index': 2, 'ens_name': 'REFC', 'ens_level': 'L0', 'ens_thresh': ['>35.0']}, - {'index': '3', + {'index': 3, 'ens_name': 'UGRD', 'ens_level': 'Z10', 'ens_thresh': ['>=5.0']}, - {'index': '4', + {'index': 4, 'ens_name': 'VGRD', 'ens_level': 'Z10', 'ens_thresh': ['>=5.0']}, - {'index': '5', + {'index': 5, 'ens_name': 'WIND', 'ens_level': 'Z10', 'ens_thresh': ['>=5.0']}, ] - expected_var_list = [{'index': '1', + expected_var_list = [{'index': 1, 'fcst_name': 'APCP', 'fcst_level': 'A24', 'fcst_thresh': ['>0.01', '>=10.0'], @@ -646,7 +651,7 @@ def test_parse_var_list_series_by(metplus_config): config.set('config', 'BOTH_SERIES_ANALYSIS_VAR2_LEVELS', 'P700') time_info = {} - expected_et_list = [{'index': '1', + expected_et_list = [{'index': 1, 'fcst_name': 'RH', 'fcst_level': 'P850', 'fcst_output_name': 'RH_850mb', @@ -654,7 +659,7 @@ def test_parse_var_list_series_by(metplus_config): 'obs_level': 'P850', 'obs_output_name': 'RH_850mb', }, - {'index': '1', + {'index': 1, 'fcst_name': 'RH', 'fcst_level': 'P700', 'fcst_output_name': 'RH_700mb', @@ -663,13 +668,13 @@ def test_parse_var_list_series_by(metplus_config): 'obs_output_name': 'RH_700mb', }, ] - expected_sa_list = [{'index': '1', + expected_sa_list = [{'index': 1, 'fcst_name': 'RH_850mb', 'fcst_level': 'P850', 'obs_name': 'RH_850mb', 'obs_level': 'P850', }, - {'index': '2', + {'index': 2, 'fcst_name': 'RH_700mb', 'fcst_level': 'P700', 'obs_name': 'RH_700mb', @@ -913,3 +918,19 @@ def test_format_var_items_options_semicolon(config_value, var_items = config_metplus._format_var_items(field_configs, time_info) result = var_items.get('extra') assert result == expected_result + + +@pytest.mark.util +def test_parse_var_list_double_digit(metplus_config): + """!This test ensures that parse_var_list returns field info in + numeric order (1,2,...,9,10,11) instead of alphabetical (1,10,11,2,3,etc) + """ + config = metplus_config + for n in range(1, 12, 1): + config.set('config', f'FCST_VAR{n}_NAME', f'fcst_name{n}') + config.set('config', f'OBS_VAR{n}_NAME', f'obs_name{n}') + + var_list = config_metplus.parse_var_list(config) + for n, var_item in enumerate(var_list, start=1): + assert var_item['fcst_name'] == f'fcst_name{n}' + assert var_item['obs_name'] == f'obs_name{n}' diff --git a/internal/tests/pytests/util/config_util/test_config_util.py b/internal/tests/pytests/util/config_util/test_config_util.py index aee78545f2..7409f62b4e 100644 --- a/internal/tests/pytests/util/config_util/test_config_util.py +++ b/internal/tests/pytests/util/config_util/test_config_util.py @@ -115,13 +115,13 @@ def test_get_process_list_instances(metplus_config, input_list, expected_list): ({'init': datetime(2019, 2, 1, 6), 'lead': 7200, }, [ - {'index': '1', + {'index': 1, 'fcst_name': 'FNAME_2019', 'fcst_level': 'Z06', 'obs_name': 'ONAME_2019', 'obs_level': 'L06', }, - {'index': '1', + {'index': 1, 'fcst_name': 'FNAME_2019', 'fcst_level': 'Z08', 'obs_name': 'ONAME_2019', @@ -131,13 +131,13 @@ def test_get_process_list_instances(metplus_config, input_list, expected_list): ({'init': datetime(2021, 4, 13, 9), 'lead': 10800, }, [ - {'index': '1', + {'index': 1, 'fcst_name': 'FNAME_2021', 'fcst_level': 'Z09', 'obs_name': 'ONAME_2021', 'obs_level': 'L09', }, - {'index': '1', + {'index': 1, 'fcst_name': 'FNAME_2021', 'fcst_level': 'Z12', 'obs_name': 'ONAME_2021', diff --git a/internal/tests/pytests/wrappers/command_builder/test_command_builder.py b/internal/tests/pytests/wrappers/command_builder/test_command_builder.py index 49526476c7..6fd2d66576 100644 --- a/internal/tests/pytests/wrappers/command_builder/test_command_builder.py +++ b/internal/tests/pytests/wrappers/command_builder/test_command_builder.py @@ -855,3 +855,60 @@ def test_get_field_info_extra(metplus_config, extra, expected_value): add_curly_braces=False )[0] assert actual_value == expected_value + + +@pytest.mark.parametrize( + 'exists, skip, is_dir, use_prefix, run', [ + (True, True, False, True, False), + (True, False, False, True, True), + (False, True, False, True, True), + (False, False, False, True, True), + (True, True, True, True, False), + (True, False, True, True, True), + (False, True, True, True, True), + (False, False, True, True, True), + (True, True, False, False, False), + (True, False, False, False, True), + (False, True, False, False, True), + (False, False, False, False, True), + (True, True, True, False, False), + (True, False, True, False, True), + (False, True, True, False, True), + (False, False, True, False, True), + ] +) +@pytest.mark.wrapper +def test_find_and_check_output_file_skip(metplus_config, exists, skip, is_dir, + use_prefix, run): + app_name = 'command_builder' + config = metplus_config + if use_prefix: + config.set('config', f'{app_name.upper()}_OUTPUT_PREFIX', 'prefix') + wrapper = CommandBuilder(config) + wrapper.app_name = app_name + prefix = f'{app_name}_prefix' if use_prefix else app_name + exist_file = f'{prefix}_120000L_20190201_000000V.stat' + non_exist_file = f'{prefix}_240000L_20190201_000000V.stat' + + # create fake file to test + create_fullpath = os.path.join(config.getdir('OUTPUT_BASE'), exist_file) + open(create_fullpath, 'a').close() + + # set time_info, output template/dir, skip if output exists flag + task_info = {'valid': datetime.datetime(2019, 2, 1, 0)} + if is_dir: + task_info['lead_hours'] = 12 if exists else 24 + + time_info = ti_calculate(task_info) + wrapper.c_dict['OUTPUT_DIR'] = wrapper.config.getdir('OUTPUT_BASE') + + wrapper.c_dict['SKIP_IF_OUTPUT_EXISTS'] = skip + if is_dir: + wrapper.c_dict['OUTPUT_TEMPLATE'] = '' + else: + wrapper.c_dict['OUTPUT_TEMPLATE'] = exist_file if exists else non_exist_file + + result = wrapper.find_and_check_output_file(time_info, is_directory=is_dir) + + # cast result to bool because None isn't equal to False + assert bool(result) == run diff --git a/internal/tests/pytests/wrappers/pb2nc/test_pb2nc_wrapper.py b/internal/tests/pytests/wrappers/pb2nc/test_pb2nc_wrapper.py index 02e35d22d4..5e612e93ce 100644 --- a/internal/tests/pytests/wrappers/pb2nc/test_pb2nc_wrapper.py +++ b/internal/tests/pytests/wrappers/pb2nc/test_pb2nc_wrapper.py @@ -23,41 +23,6 @@ def pb2nc_wrapper(metplus_config): return PB2NCWrapper(config) -@pytest.mark.parametrize( - 'exists, skip, run', [ - (True, True, False), - (True, False, True), - (False, True, True), - (False, False, True), - ] -) -@pytest.mark.wrapper -def test_find_and_check_output_file_skip(metplus_config, exists, skip, run): - pb = pb2nc_wrapper(metplus_config) - exist_file = 'wackyfilenametocreate' - non_exist_file = 'wackyfilethatdoesntexist' - - # create fake file to test - create_fullpath = os.path.join(pb.config.getdir('OUTPUT_BASE'), exist_file) - open(create_fullpath, 'a').close() - - # set time_info, output template/dir, skip if output exists flag - time_info = { 'valid' : datetime.datetime(2019, 2, 1, 0) } - pb.c_dict['OUTPUT_DIR'] = pb.config.getdir('OUTPUT_BASE') - - pb.c_dict['SKIP_IF_OUTPUT_EXISTS'] = skip - - if exists: - pb.c_dict['OUTPUT_TEMPLATE'] = exist_file - else: - pb.c_dict['OUTPUT_TEMPLATE'] = non_exist_file - - result = pb.find_and_check_output_file(time_info) - - # cast result to bool because None isn't equal to False - assert bool(result) == run - - # --------------------- # test_get_command # test that command is generated correctly diff --git a/internal/tests/use_cases/all_use_cases.txt b/internal/tests/use_cases/all_use_cases.txt index ca8f1cbc1c..eef745abc6 100644 --- a/internal/tests/use_cases/all_use_cases.txt +++ b/internal/tests/use_cases/all_use_cases.txt @@ -153,6 +153,7 @@ Category: short_range 10::UserScript_fcstFV3_fcstOnly_PhysicsTendency_Planview::model_applications/short_range/UserScript_fcstFV3_fcstOnly_PhysicsTendency_Planview.conf:: metplotpy_env 11::UserScript_fcstFV3_fcstOnly_PhysicsTendency_VerticalProfile::model_applications/short_range/UserScript_fcstFV3_fcstOnly_PhysicsTendency_VerticalProfile.conf:: metplotpy_env 12::UserScript_fcstFV3_fcstOnly_PhysicsTendency_VerticalCrossSection::model_applications/short_range/UserScript_fcstFV3_fcstOnly_PhysicsTendency_VerticalCrossSection.conf:: metplotpy_env +13::MODEMultivar_fcstHRRR_obsMRMS_HRRRanl::model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf Category: space_weather diff --git a/metplus/util/config_metplus.py b/metplus/util/config_metplus.py index e3a2dd7ead..6d0fa4295b 100644 --- a/metplus/util/config_metplus.py +++ b/metplus/util/config_metplus.py @@ -942,9 +942,9 @@ def parse_var_list(config, time_info=None, data_type=None, met_tool=None, # get indices of VAR items for data type and/or met tool indices = [] if met_tool: - indices = _find_var_name_indices(config, data_types, met_tool).keys() + indices = _find_var_name_indices(config, data_types, met_tool) if not indices: - indices = _find_var_name_indices(config, data_types).keys() + indices = _find_var_name_indices(config, data_types) # get config name prefixes for each data type to find dt_search_prefixes = {} @@ -979,7 +979,7 @@ def parse_var_list(config, time_info=None, data_type=None, met_tool=None, # check if number of levels for each field type matches n_levels = len(field_info_list[0]['levels']) if len(data_types) > 1: - if (n_levels != len(field_info_list[1]['levels'])): + if n_levels != len(field_info_list[1]['levels']): continue # if requested, put all field levels in a single item @@ -1064,7 +1064,22 @@ def parse_var_list(config, time_info=None, data_type=None, met_tool=None, ''' return sorted(var_list, key=lambda x: x['index']) + def _find_var_name_indices(config, data_types, met_tool=None): + """!Get list of indices used in _VAR_ config variables. Data type + determines prefix of variable name to find. If FCST or OBS is included + in data type list, then BOTH keyword is also searched. If specified, + wrapper-specific variables are searched, e.g. FCST_GRID_STAT_VAR_*. + Variables that end with NAME, INPUT_FIELD_NAME, or FIELD_NAME are used to + gather indices. + + @param config METplusConfig object to read + @param data_types list of prefixes of config variables that describe the + type of data e.g. FCST or OBS. + @param met_tool (optional) name of wrapper to search for wrapper-specific + variables, e.g. *_GRID_STAT_VAR_*. + @returns list of integers for all matching config variables + """ data_type_regex = f"{'|'.join(data_types)}" # if data_types includes FCST or OBS, also search for BOTH @@ -1080,10 +1095,11 @@ def _find_var_name_indices(config, data_types, met_tool=None): regex_string += r"_VAR(\d+)_(NAME|INPUT_FIELD_NAME|FIELD_NAME)" # find all _VAR_NAME keys in the conf files - return find_indices_in_config_section(regex_string, - config, - index_index=2, - id_index=1) + indices = find_indices_in_config_section(regex_string, + config, + index_index=2, + id_index=1).keys() + return [int(index) for index in indices] def _format_var_items(field_configs, time_info=None): @@ -1210,7 +1226,7 @@ def get_field_config_variables(config, index, search_prefixes): in RegridDataPlane wrapper. @param config METplusConfig object to search - @param index of field (VAR) to find + @param index integer of field (VAR) to find @param search_prefixes list of valid prefixes to search for variables in the config, i.e. FCST_VAR1_ or OBS_GRID_STAT_VAR2_ @returns dictionary containing a config variable name to be used for diff --git a/metplus/util/config_util.py b/metplus/util/config_util.py index fa835bb6cc..5baea3623c 100644 --- a/metplus/util/config_util.py +++ b/metplus/util/config_util.py @@ -163,8 +163,8 @@ def write_all_commands(all_commands, config): @returns False if no commands were provided, True otherwise """ if not all_commands: - config.logger.error("No commands were run. " - "Skip writing all_commands file") + config.logger.info("No commands were run. " + "Skip writing all_commands file") return False log_timestamp = config.getstr('config', 'LOG_TIMESTAMP') @@ -212,6 +212,8 @@ def _sub_var_info(var_info, time_info): out_value.append(do_string_sub(item, skip_missing_tags=True, **time_info)) + elif isinstance(value, int): + out_value = value else: out_value = do_string_sub(value, skip_missing_tags=True, diff --git a/metplus/util/run_util.py b/metplus/util/run_util.py index e201392f42..9a98f91098 100644 --- a/metplus/util/run_util.py +++ b/metplus/util/run_util.py @@ -147,9 +147,7 @@ def run_metplus(config): # if process list contains any wrapper that should run commands if any([item[0] not in NO_COMMAND_WRAPPERS for item in process_list]): # write out all commands and environment variables to file - if not write_all_commands(all_commands, config): - # report an error if no commands were generated - total_errors += 1 + write_all_commands(all_commands, config) # compute total number of errors that occurred and output results for process in processes: diff --git a/metplus/util/string_manip.py b/metplus/util/string_manip.py index 3ddc53e02d..da72ca9ca0 100644 --- a/metplus/util/string_manip.py +++ b/metplus/util/string_manip.py @@ -534,11 +534,9 @@ def find_indices_in_config_section(regex, config, sec='config', @param index_index 1 based number that is the regex match index for the index number (default is 1) @param id_index 1 based number that is the regex match index for the - identifier. Defaults to None which does not extract an indentifier - - number and the first match is used as an identifier + identifier. Defaults to None which does not extract an identifier @returns dictionary where keys are the index number and the value is a - list of identifiers (if noID=True) or a list containing None + list of identifiers (if id_index=None) or a list containing None """ # regex expression must have 2 () items and the 2nd item must be the index all_conf = config.keys(sec) diff --git a/metplus/wrappers/command_builder.py b/metplus/wrappers/command_builder.py index 4a9ba4131d..3595bc6b05 100755 --- a/metplus/wrappers/command_builder.py +++ b/metplus/wrappers/command_builder.py @@ -21,7 +21,7 @@ from ..util.constants import PYTHON_EMBEDDING_TYPES, COMPRESSION_EXTENSIONS from ..util import getlist, preprocess_file, loop_over_times_and_call from ..util import do_string_sub, ti_calculate, get_seconds_from_string -from ..util import get_time_from_file, shift_time_seconds +from ..util import get_time_from_file, shift_time_seconds, seconds_to_met_time from ..util import replace_config_from_section from ..util import METConfig from ..util import MISSING_DATA_VALUE @@ -917,7 +917,7 @@ def find_and_check_output_file(self, time_info=None, template @param is_directory If True, check in output directory for any files that match the pattern - {app_name}_{output_prefix}*YYYYMMDD_HHMMSSV* + {app_name}_{output_prefix}_HHMMSSL_YYYYMMDD_HHMMSSV* @param output_path_template optional filename template to use If None, build output path template from c_dict's OUTPUT_DIR and OUTPUT_TEMPLATE. Default is None @@ -955,13 +955,18 @@ def find_and_check_output_file(self, time_info=None, # get directory that the output file will exist if is_directory: parent_dir = output_path - if time_info and time_info['valid'] != '*': - valid_format = time_info['valid'].strftime('%Y%m%d_%H%M%S') - else: - valid_format = '' + valid = '*' + lead = '*' + if time_info: + if time_info['valid'] != '*': + valid = time_info['valid'].strftime('%Y%m%d_%H%M%S') + if time_info['lead'] != '*': + lead = seconds_to_met_time(time_info['lead_seconds'], + force_hms=True) prefix = self.get_output_prefix(time_info, set_env_vars=False) - search_string = f"{self.app_name}_{prefix}*{valid_format}V*" + prefix = f'{self.app_name}_{prefix}' if prefix else self.app_name + search_string = f'{prefix}_{lead}L_{valid}V*' search_path = os.path.join(output_path, search_string) if skip_if_output_exists: diff --git a/parm/use_cases/model_applications/s2s_mid_lat/UserScript_fcstGFS_obsERA_Blocking.conf b/parm/use_cases/model_applications/s2s_mid_lat/UserScript_fcstGFS_obsERA_Blocking.conf index 4bad3cef08..8fb960e2e0 100644 --- a/parm/use_cases/model_applications/s2s_mid_lat/UserScript_fcstGFS_obsERA_Blocking.conf +++ b/parm/use_cases/model_applications/s2s_mid_lat/UserScript_fcstGFS_obsERA_Blocking.conf @@ -13,6 +13,9 @@ PROCESS_LIST = UserScript(create_cbl_filelist), UserScript(script_blocking), StatAnalysis(sanal_ibls), StatAnalysis(sanal_blocks) +# use this process list if pre-processing steps are needed +# PROCESS_LIST = RegridDataPlane(regrid_fcst), RegridDataPlane(regrid_obs), PcpCombine(daily_mean_fcst), PcpCombine(daily_mean_obs), PcpCombine(running_mean_obs), PcpCombine(anomaly_obs), UserScript(create_cbl_filelist), UserScript(script_blocking) + ### # Time Info diff --git a/parm/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf b/parm/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf new file mode 100644 index 0000000000..b8361e2f90 --- /dev/null +++ b/parm/use_cases/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.conf @@ -0,0 +1,134 @@ +[config] + +# Documentation for this use-case can be found at: +# https://metplus.readthedocs.io/en/latest/generated/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl.html + +# Processes to run +PROCESS_LIST = MODE(mv),GenVxMask(fcst_super),GenVxMask(obs_super),MODE(super) + +# Time Info +LOOP_ORDER = times +LOOP_BY = INIT + +INIT_TIME_FMT = %Y%m%d%H +INIT_BEG = 2021020100 +INIT_END = 2021020100 + +LEAD_SEQ = 21 + +MODEL = HRRR +OBTYPE = ANALYSIS + +################################## +# Multivariate MODE Configurations +################################## +# Run MODE to output super objects +[mv] +MODE_MULTIVAR_LOGIC = #1 && #2 && #3 + +FCST_MODE_INPUT_DIR = {INPUT_BASE}/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl +FCST_MODE_INPUT_TEMPLATE = hrrr.t{init?fmt=%H}z.wrfprsf{lead?fmt=%H}.sub.grib2,hrrr.t{init?fmt=%H}z.wrfprsf{lead?fmt=%H}.sub.grib2,hrrr.t{init?fmt=%H}z.wrfprsf{lead?fmt=%H}.sub.grib2 + +OBS_MODE_INPUT_DIR = {INPUT_BASE}/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl +OBS_MODE_INPUT_TEMPLATE = PrecipFlag_00.00_{valid?fmt=%Y%m%d}-{valid?fmt=%2H}0000.sub.grib2,hrrr.t{valid?fmt=%H}z.wrfprsf00.sub.grib2,hrrr.t{valid?fmt=%H}z.wrfprsf00.sub.grib2 + +MODE_OUTPUT_DIR = {OUTPUT_BASE}/mode +MODE_OUTPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/f{lead?fmt=%2H} + +FCST_VAR1_NAME = CSNOW +FCST_VAR1_LEVELS = L0 +FCST_VAR1_OPTIONS = conv_radius = 0; conv_thresh = ==1 + +OBS_VAR1_NAME = PrecipFlag +OBS_VAR1_LEVELS = L0 +OBS_VAR1_OPTIONS = conv_radius = 0; conv_thresh = ==3 + +FCST_VAR2_NAME = VIS +FCST_VAR2_LEVELS = L0 +FCST_VAR2_OPTIONS = conv_radius = 5; conv_thresh = <=804.672; merge_thresh = <=1207.008; merge_flag = THRESH + +OBS_VAR2_NAME = VIS +OBS_VAR2_LEVELS = L0 +OBS_VAR2_OPTIONS = conv_radius = 5; conv_thresh = <=804.672; merge_thresh = <=1207.008; merge_flag = THRESH + +FCST_VAR3_NAME = WIND +FCST_VAR3_LEVELS = Z10 +FCST_VAR3_OPTIONS = conv_radius = 5; conv_thresh = >=8.9408; merge_thresh = >=6.7056; merge_flag = THRESH + +OBS_VAR3_NAME = WIND +OBS_VAR3_LEVELS = Z10 +OBS_VAR3_OPTIONS = conv_radius = 5; conv_thresh = >=8.9408; merge_thresh = >=6.7056; merge_flag = THRESH + +MODE_FCST_FILTER_ATTR_NAME = AREA +MODE_FCST_FILTER_ATTR_THRESH = >=25 +MODE_OBS_FILTER_ATTR_NAME = AREA +MODE_OBS_FILTER_ATTR_THRESH = >=25 + +MODE_MATCH_FLAG = MERGE_BOTH + +MODE_REGRID_TO_GRID = FCST +MODE_REGRID_METHOD = NEAREST +MODE_REGRID_WIDTH = 1 +MODE_REGRID_VLD_THRESH = 0.5 + +########################## +# GenVxMask configurations +########################## +# Mask fcst field with the fcst super object field +[fcst_super] +GEN_VX_MASK_INPUT_DIR = {INPUT_BASE}/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl +GEN_VX_MASK_INPUT_TEMPLATE = hrrr.t{init?fmt=%H}z.wrfprsf{lead?fmt=%H}.sub.grib2 +GEN_VX_MASK_INPUT_MASK_DIR = {OUTPUT_BASE}/mode +GEN_VX_MASK_INPUT_MASK_TEMPLATE = {init?fmt=%Y%m%d%H}/f{lead?fmt=%2H}/f_super.nc +GEN_VX_MASK_OPTIONS = -type data -input_field 'name="WIND";level="Z10";' -mask_field 'name="super";level="L0";' -thresh 'eq0' -value -9999 -name 'WIND_super' +GEN_VX_MASK_OUTPUT_DIR = {OUTPUT_BASE}/gen_vx_mask +GEN_VX_MASK_OUTPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/fcst_wind_super_{init?fmt=%Y%m%d%H}_f{lead?fmt=%2H}.nc + +# Mask obs field with the obs super objects +[obs_super] +GEN_VX_MASK_INPUT_DIR = {INPUT_BASE}/model_applications/short_range/MODEMultivar_fcstHRRR_obsMRMS_HRRRanl +GEN_VX_MASK_INPUT_TEMPLATE = hrrr.t{valid?fmt=%H}z.wrfprsf00.sub.grib2 +GEN_VX_MASK_INPUT_MASK_DIR = {OUTPUT_BASE}/mode +GEN_VX_MASK_INPUT_MASK_TEMPLATE = {init?fmt=%Y%m%d%H}/f{lead?fmt=%2H}/o_super.nc +GEN_VX_MASK_OPTIONS = -type data -input_field 'name="WIND";level="Z10";' -mask_field 'name="super";level="L0";' -thresh 'eq0' -value -9999 -name 'WIND_super' +GEN_VX_MASK_OUTPUT_DIR = {OUTPUT_BASE}/gen_vx_mask +GEN_VX_MASK_OUTPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/obs_wind_super_{valid?fmt=%Y%m%d%H}.nc + +####################### +# MODE on precip supers +####################### +[super] +FCST_VAR1_NAME = WIND_super +FCST_VAR1_LEVELS = Z10 + +OBS_VAR1_NAME = WIND_super +OBS_VAR1_LEVELS = Z10 + +MODE_CONV_RADIUS = 0 +MODE_CONV_THRESH = ne-9999 +MODE_MERGE_FLAG = NONE + +MODE_OUTPUT_PREFIX = {MODEL}_vs_{OBTYPE}_{CURRENT_OBS_NAME}_{CURRENT_OBS_LEVEL} + +MODE_GRID_RES = 3 + +MODE_NC_PAIRS_FLAG_LATLON = TRUE +MODE_NC_PAIRS_FLAG_RAW = TRUE +MODE_NC_PAIRS_FLAG_OBJECT_RAW = TRUE +MODE_NC_PAIRS_FLAG_OBJECT_ID = TRUE +MODE_NC_PAIRS_FLAG_CLUSTER_ID = TRUE +MODE_NC_PAIRS_FLAG_POLYLINES = TRUE + +MODE_QUILT = True + +MODE_PS_PLOT_FLAG = TRUE +MODE_CT_STATS_FLAG = TRUE + +FCST_MODE_INPUT_DIR = {OUTPUT_BASE}/gen_vx_mask +FCST_MODE_INPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/fcst_wind_super_{init?fmt=%Y%m%d%H}_f{lead?fmt=%2H}.nc + +OBS_MODE_INPUT_DIR = {OUTPUT_BASE}/gen_vx_mask +OBS_MODE_INPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/obs_wind_super_{valid?fmt=%Y%m%d%H}.nc + +MODE_OUTPUT_DIR = {OUTPUT_BASE}/mode +MODE_OUTPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/f{lead?fmt=%2H}