From e1abb7b4fecc09efc43de6be31dd11d611cfd3da Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 1 Oct 2025 11:22:31 -0600 Subject: [PATCH 01/45] Feature dtcenter/metplus-internal#64 develop (#3251) * Per dtcenter/metplus-internal#64, initial attempt * Per dtcenter/metplus-internal#63, update syntax * Per dtcenter/metplus-internal#63, update syntax * Per dtcenter/metplus-internal#63, update syntax * Per dtcenter/metplus-internal#63, update syntax * Per dtcenter/metplus-internal#63, update syntax * Per dtcenter/metplus-internal#63, update syntax * Add continuous integration docs * Fix docs --- .github/workflows/release-docker-images.yml | 32 ++++++++++++---- .../continuous_integration.rst | 37 +++++++++++++++---- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index fbcad91168..e2a840bb41 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -9,12 +9,12 @@ on: workflow_dispatch: inputs: release_version: - description: 'Comma-separated list of versions to build, e.g. "v12.0.3","v12.1.0"' - default: '"v12.1.0"' + description: 'Comma-separated list of versions to build, e.g. v12.0,v12.1' + default: 'v12.1' required: true type: string update_latest: - description: 'For "vX.Y.Z" versions, update the corresponding "X.Y-latest" images.' + description: 'Update "X.Y-latest" images.' default: false required: true type: boolean @@ -33,21 +33,39 @@ jobs: outputs: matrix: ${{ steps.get-versions.outputs.matrix }} update_latest: ${{ steps.get-versions.outputs.update_latest }} + steps: + - uses: actions/checkout@v4 + with: + repository: 'dtcenter/metplus' + ref: 'develop' + sparse-checkout: metplus/component_versions.py + sparse-checkout-cone-mode: false + - name: Get versions to build id: get-versions run: | if [[ ${{ github.event_name }} == 'schedule' ]]; then - version_list="\"v12.0.3\",\"v12.1.0\"" + version_string="v12.0,v12.1" update_latest="true" elif [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then - version_list=${{ toJSON(inputs.release_version) }} + version_string=${{ toJSON(inputs.release_version) }} update_latest=${{ toJSON(inputs.update_latest) }} else - version_list=\"${{ toJSON(github.ref_name) }}\" + version_string=${{ toJSON(github.ref_name) }} update_latest="true" fi - echo "matrix={\"version\": [ ${version_list} ]}" >> $GITHUB_OUTPUT + IFS=',' read -r -a version_array <<< "${version_string}" + matrix="{\"version\": [" + for version in "${version_array[@]}"; do + if [[ ${version} =~ ^v[0-9]+.[0-9]+$ ]]; then + matrix+=\"$(${GITHUB_WORKSPACE}/metplus/component_versions.py -v ${version} -i MET -o MET)\", + else + matrix+=\"${version}\", + fi + done + matrix+="]}" + echo "matrix=${matrix}" >> $GITHUB_OUTPUT echo "update_latest=${update_latest}" >> $GITHUB_OUTPUT build_scan_and_push: diff --git a/docs/Contributors_Guide/continuous_integration.rst b/docs/Contributors_Guide/continuous_integration.rst index f50a822450..65bf17b4d1 100644 --- a/docs/Contributors_Guide/continuous_integration.rst +++ b/docs/Contributors_Guide/continuous_integration.rst @@ -2,16 +2,39 @@ Continuous Integration ********************** -Coming Soon! +MET utilizes GitHub Actions to run processes automatically when changes +are pushed to GitHub. -Overview -======== +GitHub Actions Workflows +======================== +GitHub Actions runs workflows defined by files in the :code:`.github/workflows` +directory of a GitHub repository. Workflows that are run by multiple METplus +components are documented in the `METplus Contributor's Guide +`_. +These common workflows include: -Keywords -======== +- `Testing (testing.yml) `_ to perform regression testing. +- `Documentation (documentation.yml) `_ to check for problems building the documentation. +- `SonarQube (sonarqube.yml) `_ to perform static code analysis. +- `Build Docker Image and Trigger METplus Workflow (build_docker_and_trigger_metplus.yml) `_ to confirm that changes to METplus components do not break existing METplus use cases. +- `Release Checksum (release-checksum.yml) `_ to create and attach checksum file assets to software releases. +- `Release Docker Images (release-docker-images.yml) `_ to routinely recreate Docker images for recent software releases to minimize vulnerabilities. +- `Update Truth (update_truth.yml) `_ to update the reference truth data used by the testing workflow. +.. _cg-ci-compilation_options: -Upstream Testing -================ +Compilation Options (compilation_options.yml) +--------------------------------------------- +MET supports multiple compile-time options which are specified as arguments to the +"configure" script. The Compilation Options workflow compiles MET multiple times to +confirm that each configuration results in a successful build. These configurations +include compiling MET with: + +- All options enabled +- All options disabled +- Each individual option enabled by itself + +This workflow confirms that MET compiles successfully with a variety of configurations +but does not run any unit tests or compare output against a truth dataset. From 48c679140bf92ba980fb6979932b8cb73fea64e4 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 14 Oct 2025 11:00:20 -0600 Subject: [PATCH 02/45] Feature #3253 SQ Reliability (#3256) (#3259) * Per #3253, address 4 medium severity SonarQube reliability issues. * Per #3253, make ConcatString compile. * Per #3253, address TCPolyArray Reliability SQ issue. * Per #3253, switch conv_data from dynamically allocated memory to an STL vector. * Per #3253, switch from dynamically allocated CTSInfo and VL1L2Info arrays to using vectors to address SQ reliability findings. * Per #3253, update TrackPairInfoArray to switch from dynamically allocated memory to using an STL vector. * Per #3253, correct PCTInfo memory leak. * Per #3253, update ColorTable class to switch from dynamically allocated memory to STL vectors. * Per #3253, update crr_array.h to switch from dynamically allocated memory to using an STL vector. * Per #3253, delete crr_array.h and replace it's use in engine.h/.cc with STL vectors. * Per #3253, more SonarQube cleanup. * Per #2353, fix const auto to const auto & references to solve SQ issues. * Per #3253, try to solve my_config_scanner.cc issue. * Per #3253, attempt to fix idstack.cc SQ issue. * Saving verison that compiles and runs well. * Per #3253, simplify structure of idstack.h/.cc to operate on vectors of strings rather than using the unnecessary Identifier class. * Couple more tweaks. * Update idstack.cc * Per #3253, fix several for loops to iterate over references to the actual elements rather than copies of them. * Per #3253, correct ColorTable::clear() function which failed to call Entry.clear(). --- scripts/python/met/mprbase.py | 4 +- scripts/python/met/point.py | 2 +- src/basic/vx_config/idstack.cc | 373 ++---------------- src/basic/vx_config/idstack.h | 88 +---- src/basic/vx_config/my_config_scanner.cc | 2 + src/basic/vx_log/concat_string.cc | 3 + src/basic/vx_util/Makefile.am | 1 - src/basic/vx_util/Makefile.in | 31 +- src/basic/vx_util/crr_array.h | 412 -------------------- src/libcode/vx_color/color.h | 21 +- src/libcode/vx_color/color_table.cc | 340 ++++++---------- src/libcode/vx_shapedata/engine.cc | 85 ++-- src/libcode/vx_shapedata/engine.h | 37 +- src/libcode/vx_tc_util/track_pair_info.cc | 88 ++--- src/libcode/vx_tc_util/track_pair_info.h | 6 +- src/tools/core/mode/mode_ps_file.cc | 2 +- src/tools/core/point_stat/point_stat.cc | 72 ++-- src/tools/other/mode_time_domain/3d_conv.cc | 17 +- src/tools/tc_utils/tc_dland/tc_poly.cc | 67 +--- src/tools/tc_utils/tc_dland/tc_poly.h | 9 +- 20 files changed, 327 insertions(+), 1333 deletions(-) delete mode 100644 src/basic/vx_util/crr_array.h diff --git a/scripts/python/met/mprbase.py b/scripts/python/met/mprbase.py index a1eca1ff8f..fc27e1fa83 100644 --- a/scripts/python/met/mprbase.py +++ b/scripts/python/met/mprbase.py @@ -14,7 +14,7 @@ def read_mpr(input_file, col_start=0, col_last=0, header=None, if col_last == 0: maj_vrs = pd.read_csv(input_file, header=header, sep=sep, skiprows=skiprows, usecols=range(0, 1), - dtype=dtype, nrows=1).values[0][0] + dtype=dtype, nrows=1).to_numpy()[0][0] # The number of MPR columns vary by MET version if int(maj_vrs.strip("V").split(".")[0]) < 12: @@ -26,7 +26,7 @@ def read_mpr(input_file, col_start=0, col_last=0, header=None, keep_default_na=keep_default_na, skiprows=skiprows, usecols=range(col_start,col_last+1), - dtype=dtype).values.tolist() + dtype=dtype).to_numpy().tolist() return mpr_data diff --git a/scripts/python/met/point.py b/scripts/python/met/point.py index c361672e62..25ba9f7f1d 100644 --- a/scripts/python/met/point.py +++ b/scripts/python/met/point.py @@ -755,7 +755,7 @@ def read_text_point_obs(input_file, header=None, sep=sep, keep_default_na=keep_default_na, names=['typ', 'sid', 'vld', 'lat', 'lon', 'elv', 'var', 'lvl', 'hgt', 'qc', 'obs'], - dtype={'typ':'string', 'sid':'string', 'vld':'string', 'var':'string', 'qc':'string'}).values.tolist() + dtype={'typ':'string', 'sid':'string', 'vld':'string', 'var':'string', 'qc':'string'}).to_numpy().tolist() return ascii_point_data diff --git a/src/basic/vx_config/idstack.cc b/src/basic/vx_config/idstack.cc index 0af77c63f2..8c91e4fc5b 100644 --- a/src/basic/vx_config/idstack.cc +++ b/src/basic/vx_config/idstack.cc @@ -1,8 +1,4 @@ - - //////////////////////////////////////////////////////////////////////// - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2025 // ** University Corporation for Atmospheric Research (UCAR) @@ -10,11 +6,8 @@ // ** Research Applications Lab (RAL) // ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - - //////////////////////////////////////////////////////////////////////// - #include #include #include @@ -23,161 +16,18 @@ #include "idstack.h" - using namespace std; - //////////////////////////////////////////////////////////////////////// - static const int id_array_jump = 30; - -//////////////////////////////////////////////////////////////////////// - - - // - // Code for class Identifier - // - - -//////////////////////////////////////////////////////////////////////// - - -Identifier::Identifier() - -{ - -init_from_scratch(); - -} - - -//////////////////////////////////////////////////////////////////////// - - -Identifier::~Identifier() - -{ - -} - - -//////////////////////////////////////////////////////////////////////// - - -Identifier::Identifier(const Identifier & i) - -{ - -init_from_scratch(); - -assign(i); - -} - - -//////////////////////////////////////////////////////////////////////// - - -Identifier & Identifier::operator=(const Identifier & i) - -{ - -if ( this == &i ) return *this; - -assign(i); - -return *this; - -} - - //////////////////////////////////////////////////////////////////////// - - -void Identifier::init_from_scratch() - -{ - -clear(); - -} - - -//////////////////////////////////////////////////////////////////////// - - -void Identifier::assign(const Identifier & i) - -{ - -clear(); - -name = i.name; - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -void Identifier::clear() - -{ - -name.clear(); - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -void Identifier::set(const char * text) - -{ - -clear(); - -name.assign(text); - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -void Identifier::dump(ostream & out, int indent_depth) const - -{ - -Indent prefix(indent_depth); - -out << prefix << "\"" << name << "\"\n"; - -return; - -} - - +// +// Code for class IdentifierQueue +// //////////////////////////////////////////////////////////////////////// - - // - // Code for class IdentifierQueue - // - - -//////////////////////////////////////////////////////////////////////// - - IdentifierQueue::IdentifierQueue() { @@ -186,10 +36,8 @@ init_from_scratch(); } - //////////////////////////////////////////////////////////////////////// - IdentifierQueue::~IdentifierQueue() { @@ -198,10 +46,8 @@ clear(); } - //////////////////////////////////////////////////////////////////////// - IdentifierQueue::IdentifierQueue(const IdentifierQueue & iq) { @@ -212,10 +58,8 @@ assign(iq); } - //////////////////////////////////////////////////////////////////////// - IdentifierQueue & IdentifierQueue::operator=(const IdentifierQueue & iq) { @@ -228,37 +72,23 @@ return *this; } - //////////////////////////////////////////////////////////////////////// - void IdentifierQueue::init_from_scratch() { -memset(i, 0, sizeof(i)); - -Nelements = 0; - return; } - //////////////////////////////////////////////////////////////////////// - void IdentifierQueue::clear() { -for (int j=0; j= max_id_queue_size ) { - - cerr << "\n\n void IdentifierQueue::push(const Identifier &) -> queue full!\n\n"; - - exit ( 1 ); - -} - -i[Nelements] = new Identifier; - -*(i[Nelements]) = id; - -++Nelements; +i.emplace_back(id); return; @@ -322,33 +126,24 @@ return; //////////////////////////////////////////////////////////////////////// -Identifier IdentifierQueue::pop() +string IdentifierQueue::pop() { -if ( Nelements == 0 ) { +if ( i.empty() ) { - cerr << "\n\n IdentifierQueue::pop() -> queue empty!\n\n"; + cerr << "\nIdentifierQueue::pop() -> " + << "queue empty!\n\n"; exit ( 1 ); } -Identifier id; - -id = *(i[0]); - -for (int j=1; j Nalloc) extend(a.Nelements); - -Nelements = a.Nelements; - -for (int j=0; j n ) return; - -int k; -Identifier * inew = (Identifier *) nullptr; - - -k = n/id_array_jump; +int k = n/id_array_jump; if ( n%id_array_jump ) ++k; k *= id_array_jump; -inew = new Identifier [k]; - -if ( !inew ) { - - cerr << "\n\n void IdentifierArray::extend(int) -> memory allocation error\n\n"; - - exit ( 1 ); - -} - -for (int j=0; j= Nelements) ) { +if ( (k < 0) || (k >= i.size()) ) { - cerr << "\n\n IdentifierArray::operator[](int) -> range check error!\n\n"; + cerr << "\nIdentifierArray::operator[](int) -> " + << "range check error!\n\n"; exit ( 1 ); } - return i[k]; } - //////////////////////////////////////////////////////////////////////// - -void IdentifierArray::add(const Identifier & id) +void IdentifierArray::add(const string & s) { -extend(Nelements + 1); +extend((int) i.size() + 1); -i[Nelements++] = id; +i.emplace_back(s); return; } - //////////////////////////////////////////////////////////////////////// - void IdentifierArray::dump(ostream & out, int indent_depth) const { Indent prefix(indent_depth); +Indent prefix2(indent_depth + 1); -out << prefix << "Nelements = " << Nelements << "\n"; +out << prefix << "Nelements = " << i.size() << "\n"; -for (int j=0; j identifier \"" - << text << "\" is already in the array\n\n"; + cerr << "\nIdentifierArray::add(const char *) -> " + << "identifier \"" << text + << "\" is already in the array\n\n"; exit ( 1 ); } -extend(Nelements + 1); - -i[Nelements++].set(text); +extend((int) i.size() + 1); +i.emplace_back(text); // // done @@ -661,26 +390,4 @@ return; } - //////////////////////////////////////////////////////////////////////// - - - // - // Code for misc functions - // - - -//////////////////////////////////////////////////////////////////////// - - - - -//////////////////////////////////////////////////////////////////////// - - - - - - - - diff --git a/src/basic/vx_config/idstack.h b/src/basic/vx_config/idstack.h index f0c7ca2537..63145169cc 100644 --- a/src/basic/vx_config/idstack.h +++ b/src/basic/vx_config/idstack.h @@ -1,6 +1,4 @@ //////////////////////////////////////////////////////////////////////// - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2025 // ** University Corporation for Atmospheric Research (UCAR) @@ -8,66 +6,20 @@ // ** Research Applications Lab (RAL) // ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - - //////////////////////////////////////////////////////////////////////// - #ifndef __ID_STACK_H__ #define __ID_STACK_H__ - //////////////////////////////////////////////////////////////////////// - #include +#include #include "indent.h" //////////////////////////////////////////////////////////////////////// - -static const int max_id_size = 128; - - -//////////////////////////////////////////////////////////////////////// - - -class Identifier { - - private: - - void init_from_scratch(); - - void assign(const Identifier &); - - public: - - Identifier(); - ~Identifier(); - Identifier(const Identifier &); - Identifier & operator=(const Identifier &); - - std::string name; - - void clear(); - - void set(const char *); - - void dump(std::ostream &, int depth = 0) const; - -}; - - -//////////////////////////////////////////////////////////////////////// - - -static const int max_id_queue_size = 30; - - -//////////////////////////////////////////////////////////////////////// - - class IdentifierQueue { private: @@ -76,9 +28,7 @@ class IdentifierQueue { void assign(const IdentifierQueue &); - int Nelements; - - Identifier * i[max_id_queue_size]; + std::vector i; public: @@ -87,9 +37,9 @@ class IdentifierQueue { IdentifierQueue(const IdentifierQueue &); IdentifierQueue & operator=(const IdentifierQueue &); - void push(const Identifier &); + void push(const std::string &); - Identifier pop(); + std::string pop(); int n_elements() const; @@ -97,32 +47,23 @@ class IdentifierQueue { }; - //////////////////////////////////////////////////////////////////////// - -inline int IdentifierQueue::n_elements() const { return Nelements; } - +inline int IdentifierQueue::n_elements() const { return (int) i.size(); } //////////////////////////////////////////////////////////////////////// - class IdentifierArray { private: - void init_from_scratch(); + void init_from_scratch(); void assign(const IdentifierArray &); void extend(int); - - int Nelements; - - int Nalloc; - - Identifier * i; + std::vector i; public: @@ -137,9 +78,9 @@ class IdentifierArray { void add(const char *); - const Identifier & operator[](int) const; + const std::string & operator[](int) const; - void add(const Identifier &); + void add(const std::string &); void dump(std::ostream &, int depth = 0) const; @@ -149,22 +90,13 @@ class IdentifierArray { }; - //////////////////////////////////////////////////////////////////////// - -inline int IdentifierArray::n_elements() const { return Nelements; } - +inline int IdentifierArray::n_elements() const { return (int) i.size(); } //////////////////////////////////////////////////////////////////////// - #endif /* __ID_STACK_H__ */ - //////////////////////////////////////////////////////////////////////// - - - - diff --git a/src/basic/vx_config/my_config_scanner.cc b/src/basic/vx_config/my_config_scanner.cc index 25a5cec234..0ca174e2b0 100644 --- a/src/basic/vx_config/my_config_scanner.cc +++ b/src/basic/vx_config/my_config_scanner.cc @@ -437,6 +437,8 @@ bool char_ok(int c) { +if ( c < 0 || c > 255 ) return false; + const int k = char_class[c]; if ( k == char_class_digit ) return true; diff --git a/src/basic/vx_log/concat_string.cc b/src/basic/vx_log/concat_string.cc index b8f129da46..3c4530ca8d 100644 --- a/src/basic/vx_log/concat_string.cc +++ b/src/basic/vx_log/concat_string.cc @@ -155,6 +155,9 @@ ConcatString & ConcatString::operator=(const char c) void ConcatString::init_from_scratch() { + // MET #3253 Initialize to fix SonarQube reliability issue + Precision = 0; + set_precision(concat_string_default_precision); } diff --git a/src/basic/vx_util/Makefile.am b/src/basic/vx_util/Makefile.am index 23f667083c..365e0e5ffc 100644 --- a/src/basic/vx_util/Makefile.am +++ b/src/basic/vx_util/Makefile.am @@ -29,7 +29,6 @@ libvx_util_a_SOURCES = ascii_table.cc ascii_table.h \ grib_constants.cc grib_constants.h \ is_number.cc is_number.h \ crc_array.h \ - crr_array.h \ ncrr_array.h \ int_array.h \ two_d_array.h \ diff --git a/src/basic/vx_util/Makefile.in b/src/basic/vx_util/Makefile.in index ac4237bdbd..d4b631edf0 100644 --- a/src/basic/vx_util/Makefile.in +++ b/src/basic/vx_util/Makefile.in @@ -115,21 +115,21 @@ am__libvx_util_a_SOURCES_DIST = ascii_table.cc ascii_table.h \ comma_string.cc comma_string.h conversions.cc conversions.h \ data_line.cc data_line.h field_type.h grib_constants.cc \ grib_constants.h is_number.cc is_number.h crc_array.h \ - crr_array.h ncrr_array.h int_array.h two_d_array.h \ - long_array.cc long_array.h num_array.cc num_array.h \ - thresh_array.cc thresh_array.h main.cc main.h make_path.cc \ - make_path.h memory.cc memory.h normalize.cc normalize.h \ - ordinal.cc ordinal.h roman_numeral.cc roman_numeral.h \ - string_fxns.cc string_fxns.h substring.cc substring.h \ - fix_float.cc fix_float.h command_line.cc command_line.h \ - file_size.cc file_size.h file_exists.cc file_exists.h \ - file_linecount.cc file_linecount.h filename_suffix.cc \ - filename_suffix.h data_plane.cc data_plane.h data_cube.cc \ - data_cube.h data_plane_util.cc data_plane_util.h \ - interp_mthd.cc interp_mthd.h interp_util.cc interp_util.h \ - two_to_one.cc two_to_one.h get_filenames.cc get_filenames.h \ - util_constants.h bool_to_string.h empty_string.h polyline.h \ - polyline.cc mask_poly.h mask_poly.cc mask_sid.h mask_sid.cc \ + ncrr_array.h int_array.h two_d_array.h long_array.cc \ + long_array.h num_array.cc num_array.h thresh_array.cc \ + thresh_array.h main.cc main.h make_path.cc make_path.h \ + memory.cc memory.h normalize.cc normalize.h ordinal.cc \ + ordinal.h roman_numeral.cc roman_numeral.h string_fxns.cc \ + string_fxns.h substring.cc substring.h fix_float.cc \ + fix_float.h command_line.cc command_line.h file_size.cc \ + file_size.h file_exists.cc file_exists.h file_linecount.cc \ + file_linecount.h filename_suffix.cc filename_suffix.h \ + data_plane.cc data_plane.h data_cube.cc data_cube.h \ + data_plane_util.cc data_plane_util.h interp_mthd.cc \ + interp_mthd.h interp_util.cc interp_util.h two_to_one.cc \ + two_to_one.h get_filenames.cc get_filenames.h util_constants.h \ + bool_to_string.h empty_string.h polyline.h polyline.cc \ + mask_poly.h mask_poly.cc mask_sid.h mask_sid.cc \ read_fortran_binary.h read_fortran_binary.cc met_buffer.h \ met_buffer.cc smart_buffer.h smart_buffer.cc vx_util.h \ CircularTemplate.h CircularTemplate.cc GridTemplate.h \ @@ -479,7 +479,6 @@ libvx_util_a_SOURCES = ascii_table.cc ascii_table.h \ grib_constants.cc grib_constants.h \ is_number.cc is_number.h \ crc_array.h \ - crr_array.h \ ncrr_array.h \ int_array.h \ two_d_array.h \ diff --git a/src/basic/vx_util/crr_array.h b/src/basic/vx_util/crr_array.h deleted file mode 100644 index 220495445f..0000000000 --- a/src/basic/vx_util/crr_array.h +++ /dev/null @@ -1,412 +0,0 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2025 -// ** University Corporation for Atmospheric Research (UCAR) -// ** National Center for Atmospheric Research (NCAR) -// ** Research Applications Lab (RAL) -// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - - -//////////////////////////////////////////////////////////////////////// - - -#ifndef __CONTIGUOUS_RETURN_REFERENCE_ARRAY_H__ -#define __CONTIGUOUS_RETURN_REFERENCE_ARRAY_H__ - - -//////////////////////////////////////////////////////////////////////// - - -#include - -#include "vx_util.h" - - -//////////////////////////////////////////////////////////////////////// - - -template - -class CRR_Array { - - private: - - void init_from_scratch(); - - void assign(const CRR_Array &); - - - int Nelements; - - int Nalloc; - - int AllocInc; - - T * e; - - public: - - CRR_Array() { init_from_scratch(); } - - ~CRR_Array() { clear(); } - - CRR_Array(const CRR_Array & _a) { init_from_scratch(); assign(_a); } - - CRR_Array & operator=(const CRR_Array & _a) { - - if ( this == &_a ) return ( * this ); - - assign(_a); - - return ( * this ); - - } - - - void clear(); - - void dump(std::ostream &, int = 0) const; - - // - // set stuff - // - - void set_alloc_inc(int = 20); - - void set_all(const T); - - - // - // get stuff - // - - int n() const { return ( Nelements ); } - - // - // do stuff - // - - void add(const T &); - - void add(const CRR_Array &); - - T & operator[](int) const; - - void extend(int, bool exact = true); - - void extend(int, const T); - - void set_size(int); - -}; - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::init_from_scratch() - -{ - -e = (T *) nullptr; - -AllocInc = 25; // default value - -clear(); - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::clear() - -{ - -if ( e ) { delete [] e; e = (T *) nullptr; } - - - -Nelements = 0; - -Nalloc = 0; - -// AllocInc = 25; // don't reset AllocInc - - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::assign(const CRR_Array & a) - -{ - -clear(); - -if ( a.n() == 0 ) return; - -add(a); - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::extend(int N, bool exact) - -{ - -if ( N <= Nalloc ) return; - -if ( ! exact ) { - - N = AllocInc*( (N + AllocInc - 1)/AllocInc ); - -} - -int j; -T * u = new T [N]; - -if ( !u ) { - - mlog << Error << "\nCRR_Array::extend(int, bool) -> " - << "memory allocation error\n\n"; - - exit ( 1 ); - -} - -for(j=0; j - -void CRR_Array::extend(int N, const T _value) - -{ - -if ( N <= Nalloc ) return; - -const int n_old = Nalloc; - -extend(N); - -int j; - -for (j=n_old; j - -void CRR_Array::set_all(const T _value) - -{ - -int j; - -for (j=0; j - -void CRR_Array::set_size(int N) - -{ - -extend(N); - -if ( N > Nelements ) Nelements = N; - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::dump(std::ostream & out, int depth) const - -{ - -Indent prefix(depth); - -out << prefix << "Nelements = " << Nelements << "\n"; -out << prefix << "Nalloc = " << Nalloc << "\n"; -out << prefix << "AllocInc = " << AllocInc << "\n"; - - -int j; - -for(j=0; j - -void CRR_Array::set_alloc_inc(int N) - -{ - -if ( N < 0 ) { - - mlog << Error << "\nCRR_Array::set_alloc_int(int) -> " - << "bad value ... " << N << "\n\n"; - - exit ( 1 ); - -} - -if ( N == 0 ) AllocInc = 25; // default value -else AllocInc = N; - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::add(const T & a) - -{ - -extend(Nelements + 1, false); - -e[Nelements++] = a; - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -void CRR_Array::add(const CRR_Array & a) - -{ - -int j; - -extend(Nelements + a.n()); - -for (j=0; j<(a.n()); ++j) { - - add(a[j]); - -} - -return; - -} - - -//////////////////////////////////////////////////////////////////////// - - -template - -T & CRR_Array::operator[](int N) const - -{ - -if ( (N < 0) || (N >= Nelements) ) { - - mlog << Error << "\nCRR_Array::operator[](int) -> " - << "range check error ... " << N << "\n\n"; - - exit ( 1 ); -} - -return ( e[N] ); - -} - - -//////////////////////////////////////////////////////////////////////// - - -#endif /* __CONTIGUOUS_RETURN_REFERENCE_ARRAY_H__ */ - - -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/libcode/vx_color/color.h b/src/libcode/vx_color/color.h index a3999849bc..1411352d6f 100644 --- a/src/libcode/vx_color/color.h +++ b/src/libcode/vx_color/color.h @@ -218,27 +218,21 @@ class ColorTable { void extend(int); - - CtableEntry * Entry; - - int Nentries; - - int Nalloc; + std::vector Entry; double Gamma; unsigned char fudge[fudge_size]; + bool RescaleFlag; public: - ColorTable(); ~ColorTable(); ColorTable(const ColorTable &); ColorTable & operator=(const ColorTable &); - void clear(); int read(const char *); @@ -255,7 +249,6 @@ class ColorTable { void sort(); // sort in increasing order of data value - Color nearest(double) const; Color interp(double) const; @@ -264,6 +257,8 @@ class ColorTable { double gamma() const; + bool rescale_flag() const; + void dump(std::ostream &, int depth = 0) const; CtableEntry operator[](int) const; @@ -274,17 +269,17 @@ class ColorTable { double data_max(double) const; void rescale(double, double, double); - - int rescale_flag; }; //////////////////////////////////////////////////////////////////////// -inline int ColorTable::n_entries() const { return Nentries; } +inline int ColorTable::n_entries() const { return (int) Entry.size(); } + +inline double ColorTable::gamma() const { return Gamma; } -inline double ColorTable::gamma() const { return Gamma; } +inline bool ColorTable::rescale_flag() const { return RescaleFlag; } //////////////////////////////////////////////////////////////////////// diff --git a/src/libcode/vx_color/color_table.cc b/src/libcode/vx_color/color_table.cc index b4df10d33a..fb6c58c162 100644 --- a/src/libcode/vx_color/color_table.cc +++ b/src/libcode/vx_color/color_table.cc @@ -308,8 +308,6 @@ void ColorTable::init_from_scratch() { -Entry = (CtableEntry *) nullptr; - clear(); return; @@ -324,23 +322,17 @@ void ColorTable::clear() { -if ( Entry ) { delete [] Entry; Entry = (CtableEntry *) nullptr; } - -Nentries = 0; +Entry.clear(); -Nalloc = 0; - -int j; +Gamma = 1.0; -for (j=0; j= Entry[Nentries - 1].value_high() ) return Entry[Nentries - 1].color(); +if ( t >= Entry.back().value_high() ) return Entry.back().color(); -int j; -double vlo, vhi; -double d1, d2, dist, min_dist; - - -min_dist = fabs(t - Entry[0].value_low()); +double min_dist = fabs(t - Entry[0].value_low()); color = Entry[0].color(); +for (const auto &e : Entry) { -for (j=0; j= vlo) && (t <= vhi) ) { // direct hit - color = Entry[j].color(); + color = e.color(); fudge_color(color); @@ -426,14 +403,14 @@ for (j=0; j= Entry[Nentries - 1].value_high() ) return Entry[Nentries - 1].color(); - - -int j, k; -double vlo, vhi; -double t; - +if ( z >= Entry.back().value_high() ) return Entry.back().color(); // // check for direct hits // -for (j=0; j= vlo) && (z <= vhi) ) { // direct hit - color = Entry[j].color(); + color = e.color(); fudge_color(color); @@ -506,16 +475,16 @@ for (j=0; j= vlo) && (z <= vhi) ) { - t = (z - vlo)/(vhi - vlo); + double t = (z - vlo)/(vhi - vlo); color = blend_colors(Entry[j].color(), Entry[k].color(), t); @@ -628,17 +597,10 @@ if ( !out ) { } - -for (j=0; j bad gamma value ... " - << g << "\n\n"; + mlog << Error << "\nvoid ColorTable::set_gamma(double) -> " + << "bad gamma value ... " << g << "\n\n"; exit ( 1 ); @@ -684,24 +643,19 @@ if ( g <= 0.0 ) { Gamma = g; const double exponent = 1.0/Gamma; -int j, k; -double x, y; -for (j=0; j= n ) return; +if ( Entry.capacity() >= n ) return; -int j; -CtableEntry * u = (CtableEntry *) nullptr; - -j = n/ctable_alloc_inc; +int j = n/ctable_alloc_inc; if ( n%ctable_alloc_inc ) ++j; n = j*ctable_alloc_inc; -u = new CtableEntry [n]; - -if ( !u ) { - - mlog << Error << "\nColorTable::extend(int) -> memory allocation error\n\n"; - - exit ( 1 ); - -} - -if ( Entry ) { - - for (j=0; j Entry[k].value_low() ) { - ce = Entry[j]; + CtableEntry ce = Entry[j]; Entry[j] = Entry[k]; @@ -899,8 +801,6 @@ for (j=0; j<(Nentries - 1); ++j) { } // for j - - return; } @@ -913,9 +813,10 @@ CtableEntry ColorTable::operator[](int n) const { -if ( (n < 0) || (n >= Nentries) ) { +if ( (n < 0) || (n >= Entry.size()) ) { - mlog << Error << "\nCtableEntry ColorTable::operator[](int) const -> range check error\n\n"; + mlog << Error << "\nCtableEntry ColorTable::operator[](int) const -> " + << "range check error\n\n"; exit ( 1 ); @@ -933,13 +834,9 @@ double ColorTable::data_min() const { -if ( Nentries == 0 ) return 0.0; - -double v; +if ( Entry.empty() == 0 ) return 0.0; -v = Entry[0].value_low(); - -return v; +return Entry[0].value_low(); } @@ -956,18 +853,15 @@ double ColorTable::data_min(double bad_data_value) const { -if ( Nentries == 0 ) return 0.0; - -double v_low; -int i; +if ( Entry.empty() ) return 0.0; -v_low = 1.0e30; +double v_low = 1.0e30; -for(i=0; i v_high && - !is_eq(Entry[i].value_high(), bad_data_value)) - v_high = Entry[i].value_high(); + if(e.value_high() > v_high && + !is_eq(e.value_high(), bad_data_value)) + v_high = e.value_high(); } return v_high; @@ -1036,11 +923,7 @@ void ColorTable::rescale(double new_min, double new_max, double bad_data_value) { -int i; -double old_m, old_b, new_m, new_b; -double v_lo, v_hi, old_v_lo, old_v_hi, new_v_lo, new_v_hi; - -if(Nentries <= 0) { +if(Entry.size() <= 0) { mlog << Error << "\nCtableEntry ColorTable::rescale(double, double, double) -> " << "the colortable must be non-empty to call rescale.\n\n"; @@ -1049,49 +932,50 @@ if(Nentries <= 0) { } -old_b = data_min(bad_data_value); -old_m = data_max(bad_data_value) - data_min(bad_data_value); - -new_b = new_min; -new_m = new_max - new_min; +double old_b = data_min(bad_data_value); +double old_m = data_max(bad_data_value) - data_min(bad_data_value); -for(i=0; i ColorArray; - -typedef CRR_Array InterestInfoArray; - -typedef CRR_Array SingleFeatureArray; - -typedef CRR_Array PairFeatureArray; - - /////////////////////////////////////////////////////////////////////////////// // // Constants used to format the output text files @@ -348,23 +331,23 @@ class ModeFuzzyEngine { int n_valid; // # of data points where both fcst and obs have valid data - SingleFeatureArray fcst_single; - SingleFeatureArray obs_single; + std::vector fcst_single; + std::vector obs_single; - PairFeatureArray pair_single; + std::vector pair_single; - SingleFeatureArray fcst_cluster; - SingleFeatureArray obs_cluster; + std::vector fcst_cluster; + std::vector obs_cluster; - PairFeatureArray pair_cluster; + std::vector pair_cluster; - ColorArray fcst_color; - ColorArray obs_color; + std::vector fcst_color; + std::vector obs_color; ColorTable ctable; - InterestInfoArray info_singles; - InterestInfoArray info_clus; + std::vector info_singles; + std::vector info_clus; int get_info_index(int) const; diff --git a/src/libcode/vx_tc_util/track_pair_info.cc b/src/libcode/vx_tc_util/track_pair_info.cc index fd2e658d42..8b879d4b7c 100644 --- a/src/libcode/vx_tc_util/track_pair_info.cc +++ b/src/libcode/vx_tc_util/track_pair_info.cc @@ -932,8 +932,6 @@ TrackPairInfoArray & TrackPairInfoArray::operator=(const TrackPairInfoArray & t) void TrackPairInfoArray::init_from_scratch() { - Pair = (TrackPairInfo *) nullptr; - clear(); return; @@ -943,8 +941,7 @@ void TrackPairInfoArray::init_from_scratch() { void TrackPairInfoArray::clear() { - if(Pair) { delete [] Pair; Pair = (TrackPairInfo *) nullptr; } - NPairs = NAlloc = 0; + Pair.clear(); return; } @@ -953,12 +950,10 @@ void TrackPairInfoArray::clear() { void TrackPairInfoArray::dump(ostream &out, int indent_depth) const { Indent prefix(indent_depth); - int i; - out << prefix << "NPairs = " << NPairs << "\n"; - out << prefix << "NAlloc = " << NAlloc << "\n"; + out << prefix << "NPairs = " << Pair.size() << "\n"; - for(i=0; i= n) return; + // Check if enough memory is already reserved + if(Pair.capacity() >= n) return; // Compute the allocation size if(!exact) { - k = n/TrackPairInfoAllocInc; + int k = n/TrackPairInfoAllocInc; if(n%TrackPairInfoAllocInc) k++; n = k*TrackPairInfoAllocInc; } - // Allocate a new TrackPairInfo array of the required length - new_info = new TrackPairInfo [n]; - - if(!new_info) { - mlog << Error << "\nTrackPairInfoArray::extend(int, bool) -> " - << "memory allocation error\n\n"; - exit(1); - } - - // Copy the array contents and delete the old one - if(Pair) { - for(j=0; j= NPairs)) { + if((n < 0) || (n >= Pair.size())) { mlog << Error << "\nTrackPairInfoArray::operator[](int) -> " << "range check error for index value " << n << "\n\n"; exit(1); @@ -1074,9 +1043,9 @@ const TrackPairInfo & TrackPairInfoArray::operator[](int n) const { //////////////////////////////////////////////////////////////////////// int TrackPairInfoArray::n_points() const { - int i, n; - for(i=0,n=0; i n) n = Pair[i].adeck().n_diag(); + int n = 0; + for(const auto &p : Pair) { + if(p.adeck().n_diag() > n) n = p.adeck().n_diag(); } return n; @@ -1097,8 +1066,8 @@ int TrackPairInfoArray::max_n_diag() const { void TrackPairInfoArray::add(const TrackPairInfo &p) { - extend(NPairs + 1, false); - Pair[NPairs++] = p; + extend((int) Pair.size() + 1, false); + Pair.emplace_back(p); return; } @@ -1108,10 +1077,8 @@ void TrackPairInfoArray::add(const TrackPairInfo &p) { void TrackPairInfoArray::add_watch_warn(const ConcatString &ww_sid, WatchWarnType ww_type, unixtime ww_ut) { - int i; - // Loop through the track pairs - for(i=0; i Pair; public: @@ -225,7 +223,7 @@ class TrackPairInfoArray { //////////////////////////////////////////////////////////////////////// -inline int TrackPairInfoArray::n_pairs() const { return(NPairs); } +inline int TrackPairInfoArray::n_pairs() const { return (int) Pair.size(); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/mode/mode_ps_file.cc b/src/tools/core/mode/mode_ps_file.cc index 1e8948a80e..c6ef6d828f 100644 --- a/src/tools/core/mode/mode_ps_file.cc +++ b/src/tools/core/mode/mode_ps_file.cc @@ -981,7 +981,7 @@ void ModePsFile::draw_colorbar(bool fcst) // has been rescaled // - if ( ctable.rescale_flag ) snprintf(label, sizeof(label), "%.2f", ctable[i].value_low()); + if ( ctable.rescale_flag() ) snprintf(label, sizeof(label), "%.2f", ctable[i].value_low()); else snprintf(label, sizeof(label), "%g", ctable[i].value_low()); write_centered_text(2, 1, x_ll + bar_width + 2.0, y_ll, 0.0, 0.5, label); diff --git a/src/tools/core/point_stat/point_stat.cc b/src/tools/core/point_stat/point_stat.cc index 5d190ef13b..df3f52b77c 100644 --- a/src/tools/core/point_stat/point_stat.cc +++ b/src/tools/core/point_stat/point_stat.cc @@ -166,13 +166,13 @@ static void process_fcst_climo_files(); static void process_obs_file(int); static void process_scores(); -static void do_cts (CTSInfo *&, int, const PairDataPoint *); -static void do_mcts (MCTSInfo &, int, const PairDataPoint *); -static void do_cnt_sl1l2 (const PointStatVxOpt &, const PairDataPoint *); -static void do_vl1l2 (VL1L2Info *&, int, const PairDataPoint *, const PairDataPoint *); -static void do_pct (const PointStatVxOpt &, const PairDataPoint *); -static void do_hira_ens ( int, const PairDataPoint *); -static void do_hira_prob ( int, const PairDataPoint *); +static void do_cts (vector &, int, const PairDataPoint *); +static void do_mcts (MCTSInfo &, int, const PairDataPoint *); +static void do_cnt_sl1l2 (const PointStatVxOpt &, const PairDataPoint *); +static void do_vl1l2 (vector &, int, const PairDataPoint *, const PairDataPoint *); +static void do_pct (const PointStatVxOpt &, const PairDataPoint *); +static void do_hira_ens ( int, const PairDataPoint *); +static void do_hira_prob ( int, const PairDataPoint *); static void finish_txt_files(); @@ -990,10 +990,8 @@ static void process_scores() { ConcatString cs; // Initialize pointers - MCTSInfo mcts_info; - auto pd_ptr = (PairDataPoint *) nullptr; - auto cts_info = (CTSInfo *) nullptr; - auto vl1l2_info = (VL1L2Info *) nullptr; + MCTSInfo mcts_info; + auto pd_ptr = (PairDataPoint *) nullptr; mlog << Debug(2) << "\n" << sep_str << "\n\n"; @@ -1005,9 +1003,9 @@ static void process_scores() { int n_cat = conf_info.get_max_n_cat_thresh(); int n_wind = conf_info.get_max_n_wind_thresh(); - // Allocate space for output statistics types - cts_info = new CTSInfo [n_cat]; - vl1l2_info = new VL1L2Info [n_wind]; + // Allocate storage + vector cts_info(n_cat); + vector vl1l2_info(n_wind); // Compute scores for each PairData object and write output for(int i_vx=0; i_vxuv_index(); @@ -1397,16 +1395,13 @@ static void process_scores() { } // end for i_vx - // Deallocate memory - if(cts_info) { delete [] cts_info; cts_info = (CTSInfo *) nullptr; } - if(vl1l2_info) { delete [] vl1l2_info; vl1l2_info = (VL1L2Info *) nullptr; } - return; } //////////////////////////////////////////////////////////////////////// -static void do_cts(CTSInfo *&cts_info, int i_vx, const PairDataPoint *pd_ptr) { +static void do_cts(vector &cts_info, int i_vx, + const PairDataPoint *pd_ptr) { int n_cat; mlog << Debug(2) @@ -1436,10 +1431,11 @@ static void do_cts(CTSInfo *&cts_info, int i_vx, const PairDataPoint *pd_ptr) { // Compute the stats, normal confidence intervals, and bootstrap // bootstrap confidence intervals // + CTSInfo *cts_info_ptr = cts_info.data(); if(conf_info.vx_opt[i_vx].boot_info.interval == BootIntervalType::BCA) { compute_cts_stats_ci_bca(rng_ptr, *pd_ptr, conf_info.vx_opt[i_vx].boot_info.n_rep, - cts_info, n_cat, + cts_info_ptr, n_cat, conf_info.vx_opt[i_vx].output_flag[i_cts] != STATOutputType::None, conf_info.vx_opt[i_vx].rank_corr_flag, conf_info.tmp_dir.c_str()); @@ -1448,7 +1444,7 @@ static void do_cts(CTSInfo *&cts_info, int i_vx, const PairDataPoint *pd_ptr) { compute_cts_stats_ci_perc(rng_ptr, *pd_ptr, conf_info.vx_opt[i_vx].boot_info.n_rep, conf_info.vx_opt[i_vx].boot_info.rep_prop, - cts_info, n_cat, + cts_info_ptr, n_cat, conf_info.vx_opt[i_vx].output_flag[i_cts] != STATOutputType::None, conf_info.vx_opt[i_vx].rank_corr_flag, conf_info.tmp_dir.c_str()); @@ -1513,8 +1509,6 @@ static void do_cnt_sl1l2(const PointStatVxOpt &vx_opt, const PairDataPoint *pd_p int n_bin; PairDataPoint pd; PairDataPoint pd_thr; - auto sl1l2_info = (SL1L2Info *) nullptr; - auto cnt_info = (CNTInfo *) nullptr; mlog << Debug(2) << "Computing Scalar Partial Sums and Continuous Statistics.\n"; @@ -1536,9 +1530,9 @@ static void do_cnt_sl1l2(const PointStatVxOpt &vx_opt, const PairDataPoint *pd_p bool precip_flag = (vx_opt.vx_pd.fcst_info->is_precipitation() && vx_opt.vx_pd.obs_info->is_precipitation()); - // Allocate memory - cnt_info = new CNTInfo [n_bin]; - sl1l2_info = new SL1L2Info [n_bin]; + // Create storage + vector cnt_info(n_bin); + vector sl1l2_info(n_bin); // Process each continuous filtering threshold for(int i=0; i 0) { @@ -1691,17 +1685,14 @@ static void do_cnt_sl1l2(const PointStatVxOpt &vx_opt, const PairDataPoint *pd_p } // end for i (fcnt_ta) - // Dealloate memory - if(sl1l2_info) { delete [] sl1l2_info; sl1l2_info = (SL1L2Info *) nullptr; } - if(cnt_info) { delete [] cnt_info; cnt_info = (CNTInfo *) nullptr; } - return; } //////////////////////////////////////////////////////////////////////// -static void do_vl1l2(VL1L2Info *&v_info, int i_vx, - const PairDataPoint *pd_u_ptr, const PairDataPoint *pd_v_ptr) { +static void do_vl1l2(vector &v_info, int i_vx, + const PairDataPoint *pd_u_ptr, + const PairDataPoint *pd_v_ptr) { mlog << Debug(2) << "Computing Vector Partial Sums and Continuous Vector Statistics.\n"; @@ -1764,8 +1755,8 @@ static void do_pct(const PointStatVxOpt &vx_opt, const PairDataPoint *pd_ptr) { << "Applying " << n_bin << " climatology bins.\n"; } - // Allocate memory - auto pct_info = new PCTInfo [n_bin]; + // Allocate storage + vector pct_info(n_bin); // Process each probabilistic observation threshold for(int i=0; i 1) { PCTInfo pct_mean; - compute_pct_mean(pct_info, n_bin, pct_mean); + compute_pct_mean(pct_info.data(), n_bin, pct_mean); // Write out PSTD if(vx_opt.output_flag[i_pstd] != STATOutputType::None) { @@ -1859,9 +1850,6 @@ static void do_pct(const PointStatVxOpt &vx_opt, const PairDataPoint *pd_ptr) { } // end for i (ocnt_ta) - // Dealloate memory - if(pct_info) { delete [] pct_info; pct_info = (PCTInfo *) nullptr; } - return; } diff --git a/src/tools/other/mode_time_domain/3d_conv.cc b/src/tools/other/mode_time_domain/3d_conv.cc index 012054b34f..b6b76cdf5a 100644 --- a/src/tools/other/mode_time_domain/3d_conv.cc +++ b/src/tools/other/mode_time_domain/3d_conv.cc @@ -225,7 +225,6 @@ double value; MtdFloatFile out; double min_conv_value; double max_conv_value; -auto conv_data = (double *) nullptr; DataHandle handle; const int time_radius = time_end - time_beg + 1; @@ -252,17 +251,7 @@ ok_sum_plane_buf = new bool [Nxy]; handle.set_size(Nx, Ny, time_radius); -conv_data = new double [Nxyz]; -for (int k=0; k " - << "memory allocation error\n\n"; - - exit ( 1 ); - -} +vector conv_data(Nxyz, bad_data_double); // // get the min/max convolved data values @@ -277,7 +266,7 @@ for (int t=0; t= n) return; if(!exact) { int k = n/tc_poly_array_alloc_inc; @@ -224,24 +215,7 @@ void TCPolyArray::extend(int n, bool exact) { n = k*tc_poly_array_alloc_inc; } - TCPoly * p = (TCPoly *) nullptr; - - p = new TCPoly [n]; - - if(!p) { - mlog << Error << "\nvoid TCPolyArray::extend(int, bool) -> " - << "memory allocation error\n\n"; - exit(1); - } - - if(Poly) { - for(i=0; i= NPolys) { + if(n < 0 || n >= Poly.size()) { mlog << Error << "\nTCPolyArray::operator[](int) const -> " << "range check error\n\n"; exit(1); @@ -263,9 +237,9 @@ TCPoly TCPolyArray::operator[](int n) const { void TCPolyArray::add(const TCPoly & p) { - extend(NPolys + 1, false); - - Poly[NPolys++] = p; + extend((int) Poly.size() + 1, false); + + Poly.emplace_back(p); return; } @@ -275,8 +249,7 @@ void TCPolyArray::add(const TCPoly & p) { bool TCPolyArray::add_file(const char *filename) { ifstream in; TCPoly p; - int n = 0; - + // Open the input file in.open(filename); @@ -288,6 +261,7 @@ bool TCPolyArray::add_file(const char *filename) { } // Parse the TC Polylines + int n = 0; while(in >> p) { add(p); n++; } mlog << Debug(3) @@ -300,14 +274,14 @@ bool TCPolyArray::add_file(const char *filename) { //////////////////////////////////////////////////////////////////////// void TCPolyArray::set_check_dist() { - int i; - NumArray dsp, dnp; + NumArray dnp; + NumArray dsp; // Compute the distance from the polyline centroid to the north // and south poles. - for(i=0; i CheckDist) continue; } // Get the minimum distance to the current polyline - dcur = Poly[i].min_dist(lat, lon); + double dcur = Poly[i].min_dist(lat, lon); // Keep track of the array minimum if(is_bad_data(dmin)) { dmin = dcur; imin = i; } diff --git a/src/tools/tc_utils/tc_dland/tc_poly.h b/src/tools/tc_utils/tc_dland/tc_poly.h index b2bd28d78c..6651c9acdf 100644 --- a/src/tools/tc_utils/tc_dland/tc_poly.h +++ b/src/tools/tc_utils/tc_dland/tc_poly.h @@ -83,10 +83,9 @@ class TCPolyArray { void extend(int, bool exact = true); - TCPoly * Poly; - int NPolys; - int NAlloc; - double CheckDist; + std::vector Poly; + + double CheckDist; public: @@ -110,7 +109,7 @@ class TCPolyArray { //////////////////////////////////////////////////////////////////////// -inline int TCPolyArray::n_polys() const { return NPolys; } +inline int TCPolyArray::n_polys() const { return (int) Poly.size(); } //////////////////////////////////////////////////////////////////////// From ace8b95d57ffbe0a9e15b05ac22fc3cd6ddd4984 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 14 Oct 2025 14:49:21 -0600 Subject: [PATCH 03/45] Feature #3258 main_v12.2 lapse_rate (#3260) * Per #3258, provide default lapse rate values in ConfigConstants as the average enviromental lapse rate rather than adiabatic lapse rates. By default, set lapse_rate_correction.value = NA and prompt the user to specify an appropriate setting. * Per #3258, add error check to ensure that the lapse rate correction value has been specified well, when needed. * Per #3258, update Point-Stat and Ensemble-Stat config files to explicitly specify the lapse rate values when verifying TMP/Z2 and DPT/Z2. * Per #3258, make log messages more transparent and clear. * Per #3258, update lapse_rate_correction documentation * Per #3258, remove verifying DPT from the Ensemble-Stat unit test since the input ensemble data does not contain DPT/Z2. * Update docs/Users_Guide/config_options.rst Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> --------- Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> --- data/config/ConfigConstants | 6 ++---- data/config/EnsembleStatConfig_default | 2 +- data/config/PointStatConfig_default | 2 +- docs/Users_Guide/config_options.rst | 19 ++++++++++++------ .../config/EnsembleStatConfig_LAND_TOPO_MASK | 2 +- .../EnsembleStatConfig_LAPSE_RATE_MSL_AGL | 6 +++--- .../config/PointStatConfig_LAND_TOPO_MASK | 20 +++++++++++++++++++ .../config/PointStatConfig_LAPSE_RATE_MSL_AGL | 17 +++++++++++++--- .../config/PointStatConfig_range_azimuth | 20 ------------------- scripts/config/EnsembleStatConfig | 2 +- scripts/config/PointStatConfig | 2 +- src/basic/vx_config/config_util.cc | 13 ++++++++++++ src/libcode/vx_statistics/pair_base.cc | 10 +++++++--- 13 files changed, 77 insertions(+), 44 deletions(-) diff --git a/data/config/ConfigConstants b/data/config/ConfigConstants index 62939718f6..acf34b788a 100644 --- a/data/config/ConfigConstants +++ b/data/config/ConfigConstants @@ -56,10 +56,8 @@ MB_to_PA(p) = HPA_to_PA(p); // //////////////////////////////////////////////////////////////////////////////// -DRY_LAPSE_RATE_K_per_M = 0.0098; -DRY_LAPSE_RATE_K_per_FT = DRY_LAPSE_RATE_K_per_M / M_to_FT(1); -MOIST_LAPSE_RATE_K_per_M = 0.0055; -MOIST_LAPSE_RATE_K_per_FT = MOIST_LAPSE_RATE_K_per_M / M_to_FT(1); +WMO_TMP2M_LAPSE_RATE_K_per_M = 0.0065; +WMO_DPT2M_LAPSE_RATE_K_per_M = 0.0012; //////////////////////////////////////////////////////////////////////////////// // diff --git a/data/config/EnsembleStatConfig_default b/data/config/EnsembleStatConfig_default index 89f8ba242c..f2f0bbd09f 100644 --- a/data/config/EnsembleStatConfig_default +++ b/data/config/EnsembleStatConfig_default @@ -207,7 +207,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/data/config/PointStatConfig_default b/data/config/PointStatConfig_default index b55d021808..1406050447 100644 --- a/data/config/PointStatConfig_default +++ b/data/config/PointStatConfig_default @@ -195,7 +195,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/docs/Users_Guide/config_options.rst b/docs/Users_Guide/config_options.rst index f058e24042..007cdf850d 100644 --- a/docs/Users_Guide/config_options.rst +++ b/docs/Users_Guide/config_options.rst @@ -2329,11 +2329,18 @@ When enabled, the "message_type_group_map" dictionary must contain an entry for message type appears in the "SURFACE" entry. The "value" entry is a constant number that defines the lapse rate for correcting temperatures based on the difference of the model topography height and station -elevation. -Note that the lapse rate value depends on the units temperature and elevation and -the user is responsibile for defining it appropriately. -The default dry lapse rate value, for temperature in kelvin and height in meters, is -defined in "ConfigConstants." +elevation. By default, "value" is set to bad data and must be explicitly defined +when "apply_to" is not set to NONE. +The environmental lapse rate values for 2-meter temperature and dewpoint temperature +used by the World Meteorological Organization (WMO) can be found in "ConfigConstants". + +.. code-block:: none + + WMO_TMP2M_LAPSE_RATE_K_per_M = 0.0065; + WMO_DPT2M_LAPSE_RATE_K_per_M = 0.0012; + +Note that the lapse rate value depends on the units of temperature and elevation +and the user is responsibile for defining it appropriately. All "lapse_rate_correction" entries can be set separately in each "obs.field" entry. @@ -2341,7 +2348,7 @@ All "lapse_rate_correction" entries can be set separately in each "obs.field" en lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } msl_agl_conversion diff --git a/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK b/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK index 6664bc3157..93e2fbd83d 100644 --- a/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK +++ b/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK @@ -194,7 +194,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL b/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL index 1769cfce8d..21611781c5 100644 --- a/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL +++ b/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL @@ -78,11 +78,11 @@ fcst = { { name = "TMP"; level = "Z2"; message_type = "ADPSFC"; desc = "LAPSE_RATE_APPLY_TO_FCST"; - lapse_rate_correction = { apply_to = FCST; }; }, + lapse_rate_correction = { apply_to = FCST; value = WMO_TMP2M_LAPSE_RATE_K_per_M; }; }, { name = "TMP"; level = "Z2"; message_type = "ADPSFC"; desc = "LAPSE_RATE_APPLY_TO_OBS"; - lapse_rate_correction = { apply_to = OBS; }; }, + lapse_rate_correction = { apply_to = OBS; value = WMO_TMP2M_LAPSE_RATE_K_per_M; }; }, { name = "HGT"; level = "P500"; message_type = "ADPUPA"; desc = "MSL_TO_AGL_APPLY_FROM_NONE_TO_NONE"; }, @@ -207,7 +207,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK b/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK index d6ec9d44dd..15dd62b9cf 100644 --- a/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK +++ b/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK @@ -116,6 +116,26 @@ topo_mask = { interp_fcst_thresh = ge-50&&le50; } +// +// Lapse rate correction for surface temperature +// May be set separately in each "obs.field" entry +// +lapse_rate_correction = { + apply_to = NONE; + value = NA; +} + +// +// MSL/AGL conversion for height +// May be set separately in each "obs.field" entry +// +msl_agl_conversion = { + apply_to = NONE; + apply_from = OBS; + thresh = NA; + msl_to_agl = TRUE; +} + //////////////////////////////////////////////////////////////////////////////// mask = { diff --git a/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL b/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL index 4f4cad28e5..2e418ba137 100644 --- a/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL +++ b/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL @@ -51,11 +51,22 @@ fcst = { { name = "TMP"; level = "Z2"; message_type = "ADPSFC"; desc = "LAPSE_RATE_APPLY_TO_FCST"; - lapse_rate_correction = { apply_to = FCST; }; }, + lapse_rate_correction = { apply_to = FCST; value = WMO_TMP2M_LAPSE_RATE_K_per_M; }; }, { name = "TMP"; level = "Z2"; message_type = "ADPSFC"; desc = "LAPSE_RATE_APPLY_TO_OBS"; - lapse_rate_correction = { apply_to = OBS; }; }, + lapse_rate_correction = { apply_to = OBS; value = WMO_TMP2M_LAPSE_RATE_K_per_M; }; }, + + { name = "DPT"; level = "Z2"; message_type = "ADPSFC"; + desc = "LAPSE_RATE_APPLY_TO_NONE"; }, + + { name = "DPT"; level = "Z2"; message_type = "ADPSFC"; + desc = "LAPSE_RATE_APPLY_TO_FCST"; + lapse_rate_correction = { apply_to = FCST; value = WMO_DPT2M_LAPSE_RATE_K_per_M; }; }, + + { name = "DPT"; level = "Z2"; message_type = "ADPSFC"; + desc = "LAPSE_RATE_APPLY_TO_OBS"; + lapse_rate_correction = { apply_to = OBS; value = WMO_DPT2M_LAPSE_RATE_K_per_M; }; }, { name = "HGT"; level = "P500"; message_type = "ADPUPA"; desc = "MSL_TO_AGL_APPLY_FROM_NONE_TO_NONE"; }, @@ -137,7 +148,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/internal/test_unit/config/PointStatConfig_range_azimuth b/internal/test_unit/config/PointStatConfig_range_azimuth index 9dbc9b1f52..e9283fb230 100644 --- a/internal/test_unit/config/PointStatConfig_range_azimuth +++ b/internal/test_unit/config/PointStatConfig_range_azimuth @@ -163,26 +163,6 @@ topo_mask = { interp_fcst_thresh = ge-50&&le50; } -// -// Lapse rate correction for surface temperature -// May be set separately in each "obs.field" entry -// -lapse_rate_correction = { - apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; -} - -// -// MSL/AGL conversion for height -// May be set separately in each "obs.field" entry -// -msl_agl_conversion = { - apply_to = NONE; - apply_from = OBS; - thresh = NA; - msl_to_agl = TRUE; -} - //////////////////////////////////////////////////////////////////////////////// // diff --git a/scripts/config/EnsembleStatConfig b/scripts/config/EnsembleStatConfig index be3a7099b2..9e6d17e335 100644 --- a/scripts/config/EnsembleStatConfig +++ b/scripts/config/EnsembleStatConfig @@ -205,7 +205,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/scripts/config/PointStatConfig b/scripts/config/PointStatConfig index 44bb76fa0a..bc49f32b32 100644 --- a/scripts/config/PointStatConfig +++ b/scripts/config/PointStatConfig @@ -139,7 +139,7 @@ topo_mask = { // lapse_rate_correction = { apply_to = NONE; - value = DRY_LAPSE_RATE_K_per_M; + value = NA; } // diff --git a/src/basic/vx_config/config_util.cc b/src/basic/vx_config/config_util.cc index e487a2dae6..630917f211 100644 --- a/src/basic/vx_config/config_util.cc +++ b/src/basic/vx_config/config_util.cc @@ -2578,6 +2578,19 @@ SurfaceInfo parse_conf_surface_info(Dictionary *dict) { // Conf: lapse_rate_correction.value sfc_info.lapse_rate_correction_value = dict->lookup_double(conf_key_lapse_rate_correction_value); + + // Check for a valid lapse rate value + if(sfc_info.lapse_rate_correction_apply_to != FieldType::None && + is_bad_data(sfc_info.lapse_rate_correction_value)) { + ConcatString config_const(replace_path(config_const_filename)); + mlog << Error << "\n" << method_name + << "when \"" << conf_key_lapse_rate_correction_apply_to + << " = " << fieldtype_to_string(sfc_info.lapse_rate_correction_apply_to) + << "\", \"" << conf_key_lapse_rate_correction_value + << "\" must be set to a valid lapse rate value.\n" + << "See recommended values in: " << config_const << "\n\n"; + exit(1); + } // Conf: msl_agl_conversion.apply_to sfc_info.msl_agl_conversion_apply_to = int_to_fieldtype(dict->lookup_int(conf_key_msl_agl_conversion_apply_to)); diff --git a/src/libcode/vx_statistics/pair_base.cc b/src/libcode/vx_statistics/pair_base.cc index 9504fe22e6..becd00cf0a 100644 --- a/src/libcode/vx_statistics/pair_base.cc +++ b/src/libcode/vx_statistics/pair_base.cc @@ -2185,7 +2185,8 @@ void VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, // Log the lapse rate correction if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { mlog << Debug(CORRECTION_DEBUG_LEVEL) - << "Correcting the " + << "For " << fcst_info->magic_str() << " versus " + << obs_info->magic_str() << ", correcting the " << fieldtype_to_string(sfc_info.lapse_rate_correction_apply_to) << " temperature from " << orig_v << " to " << corr_v << " for forecast (" << fcst_elv << ") minus observation (" @@ -2243,7 +2244,9 @@ void VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, if(is_bad_data(fcst_v) || is_bad_data(obs_v) || is_bad_data(corr_f) || is_bad_data(corr_o)) { mlog << Warning << "\n" << method_name - << "skipping msl/agl conversion due to bad " + << "For " << fcst_info->magic_str() << " versus " + << obs_info->magic_str() + << ", skipping msl/agl conversion due to bad " << "(fcst, obs) elevation (" << fcst_elv << ", " << obs_elv << ") or data (" << fcst_v << ", " << obs_v << ") values.\n\n"; @@ -2264,7 +2267,8 @@ void VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, // Log the MSL/AGL conversion if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { mlog << Debug(CORRECTION_DEBUG_LEVEL) - << "Converting " + << "For " << fcst_info->magic_str() << " versus " + << obs_info->magic_str() << ", converting " << (sfc_info.msl_agl_conversion_msl_to_agl ? "MSL to AGL" : "AGL to MSL") << " using " From 76ca4d829e826086b313c2c07c138a3ec1e0388a Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 15 Oct 2025 21:49:41 -0600 Subject: [PATCH 04/45] Bugfix #3255 main_v12.2 shift_right (#3261) * Per #3255, update the shift_right logic to only shift the grid after reading data and processing any set_attr_grid setting first. * Per #3255, add GridShifted to Met2dDataFile to make ensure that we only shift the grid definition to the right one time. Without tracking that, multiple calls to data_plane() could shift the grid multiple times. * Per #3255, check for null pointer to fix SonarQube reliability issue. * Update data_class.cc to fix SonarQube reliability issue. * Per #3255, reduce a few more SonarQube maintainability issues. * Per #3255, revert changes in mode_exec.cc that are not required to solve this issue. --- src/libcode/vx_data2d/data_class.cc | 57 ++++++++++++++++++----------- src/libcode/vx_data2d/data_class.h | 14 +++---- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/libcode/vx_data2d/data_class.cc b/src/libcode/vx_data2d/data_class.cc index 12220ef9fc..c1b3df7dd3 100644 --- a/src/libcode/vx_data2d/data_class.cc +++ b/src/libcode/vx_data2d/data_class.cc @@ -110,7 +110,8 @@ void Met2dDataFile::mtddf_init_from_scratch() Raw_Grid = (Grid *) nullptr; Dest_Grid = (Grid *) nullptr; -ShiftRight = 0; +ShiftRight = 0; +GridShifted = false; return; @@ -129,7 +130,8 @@ if ( Dest_Grid ) { delete Dest_Grid; Dest_Grid = (Grid *) nullptr; } Filename.clear(); -ShiftRight = 0; +ShiftRight = 0; +GridShifted = false; return; @@ -172,6 +174,7 @@ if ( Dest_Grid ) { } else out << "(nul)\n"; out << prefix << "ShiftRight = " << ShiftRight << '\n'; +out << prefix << "GridShifted = " << bool_to_string(GridShifted) << '\n'; // // done @@ -235,8 +238,6 @@ void Met2dDataFile::set_shift_right(int N) ShiftRight = N; -if ( Dest_Grid ) Dest_Grid->shift_right(ShiftRight); - return; } @@ -368,33 +369,27 @@ bool Met2dDataFile::process_data_plane(VarInfo *vinfo, DataPlane &dp) if ( ! vinfo ) return false; // - // Check for no valid input data + // Apply conversion logic // -if ( dp.is_all_bad_data() ) { - - mlog << Warning << "\nThe field \"" << vinfo->magic_str() - << "\" contains no valid data!\n\n"; - -} +dp.convert(vinfo->ConvertFx); // - // Apply shift to the right logic + // Apply censor logic // -if ( ShiftRight != 0 ) dp.shift_right(ShiftRight); +dp.censor(vinfo->censor_thresh(), vinfo->censor_val()); // - // Apply conversion logic + // Check for no valid input data // -dp.convert(vinfo->ConvertFx); +if ( dp.is_all_bad_data() ) { - // - // Apply censor logic - // + mlog << Warning << "\nThe field \"" << vinfo->magic_str() + << "\" contains no valid data!\n\n"; -dp.censor(vinfo->censor_thresh(), vinfo->censor_val()); +} // // Update the metadata, if requested @@ -410,6 +405,25 @@ if ( vinfo->grid_attr().nxy() > 0 ) { set_grid(vinfo->grid_attr()); +} + + // + // Apply shift to the right logic + // + +if ( ShiftRight != 0 ) { + + // Shift the grid, but only once + if ( Dest_Grid && !GridShifted ) { + + Dest_Grid->shift_right(ShiftRight); + GridShifted = true; + + } + + // Shift the data + dp.shift_right(ShiftRight); + } // @@ -420,9 +434,10 @@ if ( mlog.verbosity_level() >= 4 ) { mlog << Debug(4) << "\n" << "Grid information:\n " - << Dest_Grid->serialize("\n ") << "\n"; + << (Dest_Grid ? Dest_Grid->serialize("\n ") : "(nul)") << "\n"; - double min_v, max_v; + double min_v; + double max_v; dp.data_range(min_v, max_v); mlog << Debug(4) << "\n" << "Data plane information:\n" diff --git a/src/libcode/vx_data2d/data_class.h b/src/libcode/vx_data2d/data_class.h index 556bfd873c..ce4ceaae43 100644 --- a/src/libcode/vx_data2d/data_class.h +++ b/src/libcode/vx_data2d/data_class.h @@ -41,8 +41,6 @@ class Met2dData { void mtdd_init_from_scratch(); - // void assign(const Met2dData &); // don't allow this - public: Met2dData(); @@ -85,7 +83,7 @@ class Met2dDataFile : public Met2dData { void mtddf_init_from_scratch(); - // void assign(const Met2dDataFile &); // don't allow this + bool GridShifted; protected: @@ -101,11 +99,11 @@ class Met2dDataFile : public Met2dData { public: Met2dDataFile(); - virtual ~Met2dDataFile(); + ~Met2dDataFile() override; void mtddf_clear(); - virtual void dump(std::ostream &, int depth = 0) const = 0; // dump grid and filename, etc., not data + void dump(std::ostream &, int depth = 0) const override = 0; // dump grid and filename, etc., not data // // set stuff @@ -120,11 +118,11 @@ class Met2dDataFile : public Met2dData { virtual const char * filename() const; - virtual const Grid & grid () const; + const Grid & grid() const override; virtual const Grid & raw_grid () const; - virtual int nx() const; - virtual int ny() const; + int nx() const override; + int ny() const override; virtual int raw_nx() const; virtual int raw_ny() const; From 408b8117835406a870e622411889ebd36f4a4a18 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 17 Oct 2025 16:28:34 -0600 Subject: [PATCH 05/45] Bugfix #3266 main_v12.2 empty_ascii2nc_input (#3267) * Per #3266, update logic in iabp_handler.cc and ismn_handler.cc to avoid infinite loops when reading attempting to read a header line from empty input files. * Per #3266, add a new test in unit_ascii2nc.xml to check that running with an empty input file fails with a bad return value of 1. --- internal/test_unit/xml/unit_ascii2nc.xml | 50 +++++++++++++++--------- src/tools/other/ascii2nc/ascii2nc.cc | 2 + src/tools/other/ascii2nc/iabp_handler.cc | 4 +- src/tools/other/ascii2nc/ismn_handler.cc | 8 +++- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/internal/test_unit/xml/unit_ascii2nc.xml b/internal/test_unit/xml/unit_ascii2nc.xml index d1d77da7b6..8b5fbf8021 100644 --- a/internal/test_unit/xml/unit_ascii2nc.xml +++ b/internal/test_unit/xml/unit_ascii2nc.xml @@ -56,7 +56,7 @@ - + &MET_BIN;/ascii2nc 1 \ @@ -177,10 +177,10 @@ &MET_BIN;/ascii2nc \ - -format ndbc_standard \ - -inputrx '.txt$' \ - &DATA_DIR_OBS;/ndbc \ - &OUTPUT_DIR;/ascii2nc/ndbc.nc + -format ndbc_standard \ + -inputrx '.txt$' \ + &DATA_DIR_OBS;/ndbc \ + &OUTPUT_DIR;/ascii2nc/ndbc.nc &OUTPUT_DIR;/ascii2nc/ndbc.nc @@ -190,10 +190,10 @@ &MET_BIN;/ascii2nc \ - -format ismn \ - -inputrx '.stm$' \ - &DATA_DIR_OBS;/ismn/SNOTEL \ - &OUTPUT_DIR;/ascii2nc/ismn_SNOTEL_20220924_20220927.nc + -format ismn \ + -inputrx '.stm$' \ + &DATA_DIR_OBS;/ismn/SNOTEL \ + &OUTPUT_DIR;/ascii2nc/ismn_SNOTEL_20220924_20220927.nc &OUTPUT_DIR;/ascii2nc/ismn_SNOTEL_20220924_20220927.nc @@ -203,12 +203,12 @@ &MET_BIN;/ascii2nc \ - -format iabp \ - -valid_beg 20140101 -valid_end 20140201 \ - &DATA_DIR_OBS;/iabp/090629.dat \ - &DATA_DIR_OBS;/iabp/109320.dat \ - &DATA_DIR_OBS;/iabp/109499.dat \ - &OUTPUT_DIR;/ascii2nc/iabp_20140101_20140201.nc + -format iabp \ + -valid_beg 20140101 -valid_end 20140201 \ + &DATA_DIR_OBS;/iabp/090629.dat \ + &DATA_DIR_OBS;/iabp/109320.dat \ + &DATA_DIR_OBS;/iabp/109499.dat \ + &OUTPUT_DIR;/ascii2nc/iabp_20140101_20140201.nc &OUTPUT_DIR;/ascii2nc/iabp_20140101_20140201.nc @@ -227,14 +227,26 @@ > &OUTPUT_DIR;/ascii2nc/USCRN_Boulder_file_list; \ &MET_BIN;/ascii2nc \ - -format uscrn \ - -valid_beg 20240801 -valid_end 20240801 \ - &OUTPUT_DIR;/ascii2nc/USCRN_Boulder_file_list \ - &OUTPUT_DIR;/ascii2nc/USCRN_Boulder_20240801.nc + -format uscrn \ + -valid_beg 20240801 -valid_end 20240801 \ + &OUTPUT_DIR;/ascii2nc/USCRN_Boulder_file_list \ + &OUTPUT_DIR;/ascii2nc/USCRN_Boulder_20240801.nc &OUTPUT_DIR;/ascii2nc/USCRN_Boulder_20240801.nc + + touch &OUTPUT_DIR;/ascii2nc/empty.txt; \ + &MET_BIN;/ascii2nc + 1 + \ + &OUTPUT_DIR;/ascii2nc/empty.txt \ + &OUTPUT_DIR;/ascii2nc/empty.nc + + + + + diff --git a/src/tools/other/ascii2nc/ascii2nc.cc b/src/tools/other/ascii2nc/ascii2nc.cc index ae0218f89f..b54eaeafb5 100644 --- a/src/tools/other/ascii2nc/ascii2nc.cc +++ b/src/tools/other/ascii2nc/ascii2nc.cc @@ -52,6 +52,8 @@ // 023 11/28/23 Halley Gotway MET #2701 Add ISMN soil moisture data // 024 01/06/25 Halley Gotway MET #1019 Add USCRN quality controlled data // 025 06/23/25 Halley Gotway MET #3148 Search input directories +// 026 10/17/25 Halley Gotway MET #3266 Fix IABP/ISMN infinite loops +// for empty input files // //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/ascii2nc/iabp_handler.cc b/src/tools/other/ascii2nc/iabp_handler.cc index b57a96acd3..945280ebe0 100644 --- a/src/tools/other/ascii2nc/iabp_handler.cc +++ b/src/tools/other/ascii2nc/iabp_handler.cc @@ -62,7 +62,9 @@ bool IabpHandler::isFileType(LineDataFile &ascii_file) const { // Read the header line DataLine dl; - while(dl.n_items() == 0) ascii_file >> dl; + while(ascii_file >> dl) { + if(dl.n_items() > 0) break; + } // Check the minimum number of header columns if(dl.n_items() < MIN_NUM_HDR_COLS) { diff --git a/src/tools/other/ascii2nc/ismn_handler.cc b/src/tools/other/ascii2nc/ismn_handler.cc index fa3bee183b..d9980b653f 100644 --- a/src/tools/other/ascii2nc/ismn_handler.cc +++ b/src/tools/other/ascii2nc/ismn_handler.cc @@ -77,7 +77,9 @@ bool IsmnHandler::isFileType(LineDataFile &ascii_file) const { // Read the header line DataLine dl; - while(dl.n_items() == 0) ascii_file >> dl; + while(ascii_file >> dl) { + if(dl.n_items() > 0) break; + } // Check the minimum number of header columns if(dl.n_items() < MIN_NUM_HDR_COLS) is_file_type = false; @@ -224,7 +226,9 @@ bool IsmnHandler::_readHeaderInfo(LineDataFile &ascii_file) { // Read the header line DataLine dl; - while(dl.n_items() == 0) ascii_file >> dl; + while(ascii_file >> dl) { + if(dl.n_items() > 0) break; + } // Check the minimum number of header columns if(dl.n_items() < MIN_NUM_HDR_COLS) { From 8ee0e279210b03a1bf03d2cd2546b121418b3fb1 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 21 Oct 2025 15:18:17 -0600 Subject: [PATCH 06/45] Feature #3270 main_v12.2 missing_topo (#3274) * Per #3258, provide default lapse rate values in ConfigConstants as the average enviromental lapse rate rather than adiabatic lapse rates. By default, set lapse_rate_correction.value = NA and prompt the user to specify an appropriate setting. * Per #3258, add error check to ensure that the lapse rate correction value has been specified well, when needed. * Per #3258, update Point-Stat and Ensemble-Stat config files to explicitly specify the lapse rate values when verifying TMP/Z2 and DPT/Z2. * Per #3258, make log messages more transparent and clear. * Per #3258, update lapse_rate_correction documentation * Per #3258, remove verifying DPT from the Ensemble-Stat unit test since the input ensemble data does not contain DPT/Z2. * Update docs/Users_Guide/config_options.rst Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> * Per #3258, add skip_missing entry to the lapse_rate_correction and msl_agl_conversion dictionaries in the Point-Stat and Ensemble-Stat config files to skip pairs with bad topography or observation elevations. * Per #3258, update the vx_config and vx_util libraries to parse the new skip_missing config options. * Tweak user's guide wording. * Per #3270, delete accidental commits. * Per #3270, update VxPairBase::correct_lapse_rate(...) and convert_msl_agl(...) to return booleans to alert the caller about problems applying the correction or conversion. * Per #3270, update VxPairDataPoint::add_point_obs(...) to check the updated return status and skip_missing configuration option. * Per #3270, remove the skip_missing configuration option. * Per #3270, updates * Per #3270, update the Ensemble-Stat unit test to demonstrate a point observation with bad elevation values. * Per #3270, minor changes to fix easy SonarQube maintainabiliy issues in pair_data_point.h/.cc and pair_data_ensemble.h/.cc. * Per #3270, fix initialization order * Initialize n_pair member variable. --------- Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> Co-authored-by: MET Tools Test Account --- docs/Users_Guide/config_options.rst | 13 ++ .../EnsembleStatConfig_LAPSE_RATE_MSL_AGL | 5 +- .../config/PointStatConfig_LAPSE_RATE_MSL_AGL | 2 +- internal/test_unit/xml/unit_ensemble_stat.xml | 2 + src/libcode/vx_statistics/pair_base.cc | 50 ++--- src/libcode/vx_statistics/pair_base.h | 14 +- .../vx_statistics/pair_data_ensemble.cc | 175 ++++++++++-------- .../vx_statistics/pair_data_ensemble.h | 20 +- src/libcode/vx_statistics/pair_data_point.cc | 78 ++++---- src/libcode/vx_statistics/pair_data_point.h | 22 +-- 10 files changed, 216 insertions(+), 165 deletions(-) diff --git a/docs/Users_Guide/config_options.rst b/docs/Users_Guide/config_options.rst index 007cdf850d..3e32599875 100644 --- a/docs/Users_Guide/config_options.rst +++ b/docs/Users_Guide/config_options.rst @@ -2331,6 +2331,10 @@ The "value" entry is a constant number that defines the lapse rate for correctin temperatures based on the difference of the model topography height and station elevation. By default, "value" is set to bad data and must be explicitly defined when "apply_to" is not set to NONE. +The lapse rate correction fails when the model topography or observation height +values are bad data and that matched pair is excluded from the computation of +statistics. + The environmental lapse rate values for 2-meter temperature and dewpoint temperature used by the World Meteorological Organization (WMO) can be found in "ConfigConstants". @@ -2351,6 +2355,9 @@ All "lapse_rate_correction" entries can be set separately in each "obs.field" en value = NA; } +Run with verbosity level 8 or higher (:code:`-v 8`) to see detailed log messages +about lapse rate corrections. + msl_agl_conversion ------------------ @@ -2374,6 +2381,9 @@ which may indicate clear sky. The "msl_to_agl" entry is a boolean. When "TRUE", the elevation correction is subtracted from the height value to convert from MSL to AGL. When "FALSE", the elevation correction is added to the height value to convert from AGL to MSL. +The MSL/AGL conversion fails when the model topography or observation height +values are bad data and that matched pair is excluded from the computation of +statistics. All "msl_agl_conversion" entries can be set separately in each "obs.field" entry. @@ -2386,6 +2396,9 @@ All "msl_agl_conversion" entries can be set separately in each "obs.field" entry msl_to_agl = TRUE; } +Run with verbosity level 8 or higher (:code:`-v 8`) to see detailed log messages +about MSL/AGL conversions. + hira ---- diff --git a/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL b/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL index 21611781c5..b25cb8143d 100644 --- a/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL +++ b/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL @@ -113,8 +113,9 @@ obs = fcst; // May be set separately in each "obs.field" entry // message_type = []; -sid_inc = [ "K9L2", "KAAT", "KACV", "KAJO", "KAPC", - "72293", "72388", "72393", "72489", "72493" ]; +sid_inc = [ "K9L2", "KAAT", "KACV", "KAJO", "KAPC", + "72293", "72388", "72393", "72489", "72493", + "KMUO_BAD_ELEVATION" ]; sid_exc = []; obs_thresh = [ NA ]; obs_quality_inc = []; diff --git a/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL b/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL index 2e418ba137..b8333021a9 100644 --- a/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL +++ b/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL @@ -167,7 +167,7 @@ msl_agl_conversion = { mask = { grid = []; poly = []; - sid = [ "SID_LIST:71109,71203,71600,71603,71815" ]; + sid = [ "SID_LIST:71109,71203,71600,71603,71815,CYKO" ]; llpnt = []; } diff --git a/internal/test_unit/xml/unit_ensemble_stat.xml b/internal/test_unit/xml/unit_ensemble_stat.xml index 6cc4823c4e..06017abc2e 100644 --- a/internal/test_unit/xml/unit_ensemble_stat.xml +++ b/internal/test_unit/xml/unit_ensemble_stat.xml @@ -1,5 +1,6 @@ @@ -395,6 +396,7 @@ &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040900_F012.grib \ &CONFIG_DIR;/EnsembleStatConfig_LAPSE_RATE_MSL_AGL \ -point_obs &OUTPUT_DIR;/pb2nc/gdas1.20120409.t12z.prepbufr.nc \ + -point_obs 'PYTHON_NUMPY=&MET_BASE;/python/examples/read_ascii_point.py &DATA_DIR_OBS;/ascii/sample_ascii_KMUO_BAD_ELEVATION.txt' \ -outdir &OUTPUT_DIR;/ensemble_stat -v 2 diff --git a/src/libcode/vx_statistics/pair_base.cc b/src/libcode/vx_statistics/pair_base.cc index becd00cf0a..effaa1d611 100644 --- a/src/libcode/vx_statistics/pair_base.cc +++ b/src/libcode/vx_statistics/pair_base.cc @@ -2147,25 +2147,30 @@ double VxPairBase::compute_fcst_value( //////////////////////////////////////////////////////////////////////// -void VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, +bool VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, double &fcst_v, double &obs_v) const { const char *method_name = "PairBase::correct_lapse_rate() -> "; // Check for no work to be done if(sfc_info.lapse_rate_correction_apply_to != FieldType::Fcst && - sfc_info.lapse_rate_correction_apply_to != FieldType::Obs) return; + sfc_info.lapse_rate_correction_apply_to != FieldType::Obs) return true; // Check for valid data if(is_bad_data(fcst_elv) || is_bad_data(obs_elv) || is_bad_data(fcst_v) || is_bad_data(obs_v) || is_bad_data(sfc_info.lapse_rate_correction_value)) { - mlog << Warning << "\n" << method_name - << "skipping lapse rate correction due to bad " - << "(fcst, obs) elevation (" << fcst_elv << ", " - << obs_elv << "), data (" << fcst_v << ", " - << obs_v << "), or lapse rate (" - << sfc_info.lapse_rate_correction_value << ") values.\n\n"; - return; + + if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { + mlog << Debug(CORRECTION_DEBUG_LEVEL) + << "For " << fcst_info->magic_str() << " versus " + << obs_info->magic_str() << ", skipping lapse rate correction " + << "due to bad (fcst, obs) elevation (" << fcst_elv << ", " + << obs_elv << "), data (" << fcst_v << ", " + << obs_v << "), or lapse rate (" + << sfc_info.lapse_rate_correction_value << ") values.\n"; + } + + return false; } // Apply correction @@ -2195,19 +2200,19 @@ void VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, << sfc_info.lapse_rate_correction_value << ".\n"; } - return; + return true; } //////////////////////////////////////////////////////////////////////// -void VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, +bool VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, double &fcst_v, double &obs_v, bool update_obs) const { const char *method_name = "PairBase::convert_msl_agl() -> "; // Check for no work to be done if(sfc_info.msl_agl_conversion_apply_to == FieldType::None || - sfc_info.msl_agl_conversion_apply_from == FieldType::None) return; + sfc_info.msl_agl_conversion_apply_from == FieldType::None) return true; // Apply forecast conversion double orig_f = fcst_v; @@ -2243,14 +2248,17 @@ void VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, // Check for valid data if(is_bad_data(fcst_v) || is_bad_data(obs_v) || is_bad_data(corr_f) || is_bad_data(corr_o)) { - mlog << Warning << "\n" << method_name - << "For " << fcst_info->magic_str() << " versus " - << obs_info->magic_str() - << ", skipping msl/agl conversion due to bad " - << "(fcst, obs) elevation (" << fcst_elv << ", " - << obs_elv << ") or data (" << fcst_v << ", " - << obs_v << ") values.\n\n"; - return; + + if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { + mlog << Debug(CORRECTION_DEBUG_LEVEL) + << "For " << fcst_info->magic_str() << " versus " + << obs_info->magic_str() << ", skipping msl/agl conversion " + << "due to bad (fcst, obs) elevation (" << fcst_elv << ", " + << obs_elv << ") or data (" << fcst_v << ", " + << obs_v << ") values.\n"; + } + + return false; } // Convert MSL to AGL @@ -2282,7 +2290,7 @@ void VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, << sfc_info.msl_agl_conversion_thresh.get_str() << ".\n"; } - return; + return true; } //////////////////////////////////////////////////////////////////////// diff --git a/src/libcode/vx_statistics/pair_base.h b/src/libcode/vx_statistics/pair_base.h index cd44133b89..06db360319 100644 --- a/src/libcode/vx_statistics/pair_base.h +++ b/src/libcode/vx_statistics/pair_base.h @@ -150,10 +150,10 @@ class PairBase { ////////////////////////////////////////////////////////////////// - void clear(); - void erase(); + virtual void clear(); + virtual void erase(); - void extend(int); // Allocate memory for expected size + virtual void extend(int); // Allocate memory for expected size bool is_point_vx() const; @@ -343,7 +343,7 @@ class VxPairBase { ////////////////////////////////////////////////////////////////// - void clear(); + virtual void clear(); int three_to_one(int, int, int) const; @@ -373,7 +373,7 @@ class VxPairBase { void set_obs_qty_exc_filt(const StringArray &); // Call set_size before set_msg_typ, set_mask_area, and set_interp - void set_size(int, int, int); + virtual void set_size(int, int, int); void set_msg_typ(int, const char *); void set_msg_typ_vals(int, const StringArray &); @@ -437,9 +437,9 @@ class VxPairBase { double, double, double, const ClimoPntInfo &) const; - void correct_lapse_rate(double, double, double &, double &) const; + bool correct_lapse_rate(double, double, double &, double &) const; - void convert_msl_agl(double, double, double &, double &, + bool convert_msl_agl(double, double, double &, double &, bool update_obs = true) const; // Retrieve climo data for this point diff --git a/src/libcode/vx_statistics/pair_data_ensemble.cc b/src/libcode/vx_statistics/pair_data_ensemble.cc index 241f81a6f3..93a8457c62 100644 --- a/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -83,14 +83,13 @@ void PairDataEnsemble::init_from_scratch() { //////////////////////////////////////////////////////////////////////// void PairDataEnsemble::clear() { - int i; PairBase::clear(); obs_error_entry.clear(); obs_error_flag = false; - for(i=0; i i && !is_bad_data(e_na[j][i])) { @@ -474,21 +480,22 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { else { // Compute the variance of the unperturbed ensemble members - var_unperturbed = compute_variance(esum_na[i], esumsq_na[i], esumn_na[i]); + var_unperturbed = compute_variance(esum_na[i], esumsq_na[i], nint(esumn_na[i])); var_na.add(var_unperturbed); // Process the observation error information - ObsErrorEntry * e = (has_obs_error() ? obs_error_entry[i] : 0); + const ObsErrorEntry * e = (has_obs_error() ? obs_error_entry[i] : 0); if(e) { // Get observation error variance double oerr_var = e->variance(); // Compute the observation error log scores - double v_conv, v_corr; + double v_conv; + double v_corr; compute_obs_error_log_scores( - compute_mean(esum_na[i], esumn_na[i]), - compute_stdev(esum_na[i], esumsq_na[i], esumn_na[i]), + compute_mean(esum_na[i], nint(esumn_na[i])), + compute_stdev(esum_na[i], esumsq_na[i], nint(esumn_na[i])), o_na[i], oerr_var, v_conv, v_corr); ign_conv_oerr_na.add(v_conv); @@ -528,7 +535,7 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { // Initialize dest_na.clear(); src_na.clear(); - for(k=n_bel+1; k<=n_bel+n_tie+1; k++) src_na.add(k); + for(int k=n_bel+1; k<=n_bel+n_tie+1; k++) src_na.add(k); // Randomly choose one of the ranks ran_choose(rng_ptr, src_na, dest_na, 1); @@ -561,8 +568,10 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { pit_na.add(compute_ens_pit(o_na[i], mean, stdev)); // Compute the Bias Ratio terms - int n_ge_obs, n_lt_obs; - double me_ge_obs, me_lt_obs; + int n_ge_obs; + int n_lt_obs; + double me_ge_obs; + double me_lt_obs; compute_bias_ratio_terms( o_na[i], cur_ens, n_ge_obs, me_ge_obs, @@ -594,20 +603,19 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { //////////////////////////////////////////////////////////////////////// void PairDataEnsemble::compute_rhist() { - int i, rank; // Clear the ranked histogram rhist_na.clear(); // Initialize the histogram counts to 0 - for(i=0; i<=n_ens; i++) rhist_na.add(0); + for(int i=0; i<=n_ens; i++) rhist_na.add(0); // The compute_pair_vals() routine should have already been called. // Loop through the ranks and populate the histogram. - for(i=0; i sorted_bins; - for(auto &x : bins) sorted_bins.insert(x.first); + for(const auto &x : bins) sorted_bins.insert(x.first); // Report the number of bins built - int n_bin = sorted_bins.size(); + auto n_bin = (int) sorted_bins.size(); mlog << Debug(4) << "PairDataEnsemble::compute_ssvar() - " << "Built " << n_bin << " variance spread/skill bins from " << o_na.n() << " observations\n"; @@ -801,12 +809,17 @@ void PairDataEnsemble::compute_ssvar() { // Build a list of SSVARInfo objects ssvar_bins = new SSVARInfo[n_bin]; i=0; - for( set::iterator set_it = sorted_bins.begin(); - set_it != sorted_bins.end(); set_it++, i++ ){ + for(auto set_it = sorted_bins.begin(); + set_it != sorted_bins.end(); set_it++, i++){ ssvar_pt_list* pts = &( bins[*set_it] ); var = 0; - double f = 0, o = 0, fo = 0, ff = 0, oo = 0, w = 0; + double f = 0.0; + double o = 0.0; + double fo = 0.0; + double ff = 0.0; + double oo = 0.0; + double w = 0.0; for(j=0; j < (int)pts->size(); j++){ var += (*pts)[j].w * (*pts)[j].var; @@ -820,13 +833,13 @@ void PairDataEnsemble::compute_ssvar() { ssvar_bins[i].n_bin = n_bin; ssvar_bins[i].bin_i = i; - ssvar_bins[i].bin_n = pts->size(); + ssvar_bins[i].bin_n = (int) pts->size(); ssvar_bins[i].var_min = atof( (*set_it).data() ); ssvar_bins[i].var_max = ssvar_bins[i].var_min + ssvar_bin_size; ssvar_bins[i].var_mean = var / w; - ssvar_bins[i].sl1l2_info.scount = pts->size(); + ssvar_bins[i].sl1l2_info.scount = (int) pts->size(); ssvar_bins[i].sl1l2_info.fbar = f / w; ssvar_bins[i].sl1l2_info.obar = o / w; ssvar_bins[i].sl1l2_info.fobar = fo / w; @@ -865,7 +878,6 @@ PairDataEnsemble PairDataEnsemble::subset_pairs_obs_thresh(const SingleThresh &o // Check for no work to be done if(ot.get_type() == thresh_na) return *this; - int i, j; PairDataEnsemble pd; // Set the ensemble size and allocate memory @@ -884,7 +896,7 @@ PairDataEnsemble PairDataEnsemble::subset_pairs_obs_thresh(const SingleThresh &o bool wgt_flag = set_climo_flag(o_na, wgt_na); // Loop over the pairs - for(i=0; iinterp_mthd == InterpMthd::HiRA) { GridTemplateFactory gtf; - GridTemplate* gt = gtf.buildGT(it->interp_shape, - it->interp_wdth, - false); + const GridTemplate* gt = gtf.buildGT(it->interp_shape, + it->interp_wdth, + false); it->set_ens_size(n*gt->size()); } else { @@ -1166,12 +1177,15 @@ void VxPairDataEnsemble::set_skip_const(bool tf) { //////////////////////////////////////////////////////////////////////// -void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, +void VxPairDataEnsemble::add_point_obs(const float *hdr_arr, + const int *hdr_typ_arr, const char *hdr_typ_str, const char *hdr_sid_str, unixtime hdr_ut, - const char *obs_qty, float *obs_arr, - const Grid &gr, const char *var_name) { + const char *obs_qty, + const float *obs_arr, + const Grid &gr, + const char *var_name) { // Check the observation VarInfo file type if(obs_info->file_type() != FileType_Gb1) { @@ -1181,9 +1195,6 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, exit(1); } - // Create VarInfoGrib pointer - VarInfoGrib *obs_info_grib = (VarInfoGrib *) obs_info; - // Increment the number of tries count n_try++; @@ -1213,7 +1224,8 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, // Check location double hdr_lat = hdr_arr[0]; double hdr_lon = hdr_arr[1]; - double obs_x, obs_y; + double obs_x; + double obs_y; if(!is_keeper_grd(pnt_obs_str.c_str(), gr, hdr_lat, hdr_lon, obs_x, obs_y)) return; // Check topo @@ -1235,12 +1247,8 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, obs_lvl = bad_data_double; } - // Set flags - bool spfh_flag = fcst_info->is_specific_humidity() && - obs_info->is_specific_humidity(); - // Store pointer to ObsErrorEntry - ObsErrorEntry *oerr_ptr = (ObsErrorEntry *) nullptr; + ObsErrorEntry *oerr_ptr = nullptr; if(obs_error_info->flag) { // Use config file setting, if specified @@ -1334,7 +1342,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, //////////////////////////////////////////////////////////////////////// -void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { +void VxPairDataEnsemble::add_ens(int member, bool mn, const Grid &gr) { // Set flag for specific humidity bool spfh_flag = fcst_info->is_specific_humidity() && @@ -1365,7 +1373,8 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { // Interpolate using the observation pressure level or height double to_lvl = (fcst_info->level().type() == LevelType_Pres ? it->lvl_na[i_obs] : it->hgt_na[i_obs]); - int lvl_blw, lvl_abv; + int lvl_blw; + int lvl_abv; // For a single forecast field if(fcst_dpa.n_planes() == 1) { @@ -1434,14 +1443,22 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { double obs_v = it->o_na[i_obs]; // MET #3174 Apply lapse rate surface temperature correction - if(sfc_info.lapse_rate_correction_apply_to != FieldType::None) { - correct_lapse_rate(topo_elv, it->elv_na[i_obs], fcst_v, obs_v); + if(sfc_info.lapse_rate_correction_apply_to != FieldType::None && + msg_typ_sfc.reg_exp_match(it->typ_sa[i_obs].c_str()) && + !correct_lapse_rate(topo_elv, it->elv_na[i_obs], fcst_v, obs_v)) { + + // Skip by resetting to bad data + fcst_v = bad_data_double; + obs_v = bad_data_double; } // MET #3174 Apply MSL/AGL height conversion - if(sfc_info.msl_agl_conversion_apply_to != FieldType::None) { - convert_msl_agl(topo_elv, it->elv_na[i_obs], fcst_v, obs_v, - member == 0); + if(sfc_info.msl_agl_conversion_apply_to != FieldType::None && + !convert_msl_agl(topo_elv, it->elv_na[i_obs], fcst_v, obs_v, member == 0)) { + + // Skip by resetting to bad data + fcst_v = bad_data_double; + obs_v = bad_data_double; } // Store the modified observation, but only for the first member @@ -1550,13 +1567,13 @@ double compute_crps_emp(double obs, const NumArray &ens_na) { //////////////////////////////////////////////////////////////////////// double compute_crps_gaus(double obs, double m, double s) { - double v, z; + double v; if(is_bad_data(m) || is_bad_data(s) || is_eq(s, 0.0)) { v = bad_data_double; } else { - z = (obs - m)/s; + double z = (obs - m)/s; v = s*(z*(2.0*znorm(z) - 1) + 2.0*dnorm(z) - 1.0/sqrt(pi)); } diff --git a/src/libcode/vx_statistics/pair_data_ensemble.h b/src/libcode/vx_statistics/pair_data_ensemble.h index c7232e9aaf..0b1d2caac4 100644 --- a/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/src/libcode/vx_statistics/pair_data_ensemble.h @@ -65,13 +65,13 @@ class PairDataEnsemble : public PairBase { public: PairDataEnsemble(); - ~PairDataEnsemble(); + ~PairDataEnsemble() override; PairDataEnsemble(const PairDataEnsemble &); PairDataEnsemble & operator=(const PairDataEnsemble &); ////////////////////////////////////////////////////////////////// - // ObsErrorEntry points [n_obs] + // Observation error entries [n_obs] ObsErrorEntryPtrArray obs_error_entry; bool obs_error_flag; @@ -140,9 +140,9 @@ class PairDataEnsemble : public PairBase { ////////////////////////////////////////////////////////////////// - void clear(); + void clear() override; - void extend(int); + void extend(int) override; bool has_obs_error() const; @@ -202,10 +202,10 @@ class VxPairDataEnsemble : public VxPairBase { ////////////////////////////////////////////////////////////////// - void clear(); + void clear() override; void set_ens_info(const EnsVarInfo *); - void set_size(int, int, int); + void set_size(int, int, int) override; // Call set_ens_size before add_ens void set_ens_size(int n); @@ -215,10 +215,10 @@ class VxPairDataEnsemble : public VxPairBase { void set_ctrl_index(int); void set_skip_const(bool); - void add_point_obs(float *, int *, const char *, const char *, - unixtime, const char *, float *, const Grid &, - const char *); - void add_ens(int, bool mn, Grid &); + void add_point_obs(const float *, const int *, const char *, + const char *, unixtime, const char *, + const float *, const Grid &, const char *); + void add_ens(int, bool mn, const Grid &); }; //////////////////////////////////////////////////////////////////////// diff --git a/src/libcode/vx_statistics/pair_data_point.cc b/src/libcode/vx_statistics/pair_data_point.cc index 93bfbb2f7a..2f2c939bf9 100644 --- a/src/libcode/vx_statistics/pair_data_point.cc +++ b/src/libcode/vx_statistics/pair_data_point.cc @@ -122,7 +122,7 @@ void PairDataPoint::extend(int n) { f_na.extend(n); f_lead_na.extend(n); - for (int idx=seeps_mpr.size(); idxis_specific_humidity() && - obs_info->is_specific_humidity(); bool precip_flag = fcst_info->is_precipitation() && obs_info->is_precipitation(); int precip_interval = fcst_dpa[0].accum(); - bool has_seeps = false; SeepsScore *seeps = nullptr; // When verifying a vertical level forecast against a surface message @@ -617,14 +622,18 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, cpi, fcst_v)) continue; // MET #3174 Apply lapse rate surface temperature correction - if(sfc_info.lapse_rate_correction_apply_to != FieldType::None || - msg_typ_sfc.reg_exp_match(hdr_typ_str)) { - correct_lapse_rate(topo_elv, hdr_elv, fcst_v, obs_v); + if(sfc_info.lapse_rate_correction_apply_to != FieldType::None && + msg_typ_sfc.reg_exp_match(hdr_typ_str) && + !correct_lapse_rate(topo_elv, hdr_elv, fcst_v, obs_v)) { + inc_count(rej_mpr, i_msg_typ, i_mask, i_interp); + continue; } // MET #3174 Apply MSL/AGL height conversion - if(sfc_info.msl_agl_conversion_apply_to != FieldType::None) { - convert_msl_agl(topo_elv, hdr_elv, fcst_v, obs_v); + if(sfc_info.msl_agl_conversion_apply_to != FieldType::None && + !convert_msl_agl(topo_elv, hdr_elv, fcst_v, obs_v)) { + inc_count(rej_mpr, i_msg_typ, i_mask, i_interp); + continue; } // Check matched pair filtering options @@ -776,13 +785,14 @@ bool check_mpr_thresh(double f, double o, const ClimoPntInfo &cpi, if(reason_ptr) reason_ptr->erase(); // Check arrays - if(m.size() == 0) return true; + if(m.empty()) return true; bool keep = true; bool absv = false; StringArray sa; ConcatString cs; - double v, v_cur; + double v; + double v_cur; // Loop over all the map entries for(const auto &col : m) { @@ -877,7 +887,7 @@ void apply_mpr_thresh_mask(DataPlane &fcst_dp, DataPlane &obs_dp, const map &m) { // Check for no work to be done - if(m.size() == 0) return; + if(m.empty()) return; int nxy = fcst_dp.nx() * fcst_dp.ny(); int n_skip = 0; @@ -949,8 +959,9 @@ void subset_wind_pairs(const PairDataPoint &pd_u, const PairDataPoint &pd_v, return; } - int i; - double fcst_wind, obs_wind, wgt; + double fcst_wind; + double obs_wind; + double wgt; // Initialize and allocate memory for output pairs out_pd_u.erase(); @@ -971,7 +982,7 @@ void subset_wind_pairs(const PairDataPoint &pd_u, const PairDataPoint &pd_v, bool wgt_flag = set_climo_flag(pd_u.f_na, pd_u.wgt_na); // Loop over the pairs - for(i=0; i &, - ConcatString * = 0); + ConcatString * = nullptr); extern double get_mpr_column_value(double, double, const ClimoPntInfo &, const char *); @@ -155,7 +155,7 @@ extern void apply_mpr_thresh_mask(DataPlane &, DataPlane &, extern bool check_seeps_thresh(double, double, const StringArray &, const ThreshArray &, - ConcatString * = 0); + ConcatString * = nullptr); extern double get_seeps_column_value(double, double, const char *); From 76cf76f1cbb23c3f097fce135433c64a19996b06 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 23 Oct 2025 09:41:34 -0600 Subject: [PATCH 07/45] Feature #3278 main_v12.2 exit_codes (#3279) * Per #3278, update all MET usage statements to support an integer exit_code argument. Update the CommandLine class to check for the -help/--help options and run usage with exit_code = 0. Otherwise, default to exit_code = 1. Note that CommandLine also exits with 0 on -version/--version. Had to update usage statement logic in MODE and add usage of the CommandLine class to a couple of utilities. * Per #3278, add ascii2nc unit tests to demonstrate bad status when run with no arguments and good status when run with -help. * Per #3278, fix up call to gen_climo_bin usage statement. * Per #3278, need to call CommandLine::allow_unrecognized_switches() after the set function. * Per #3278, update Note to include details about the return status. * Per #3278, consistently use __attribute__((noreturn)) and static in the definition of the usage() statement in all the MET application code to drive down the number of SonarQube maintainability issues. * Add static attribute to usage functions * Change static functions to global in mode_usage.cc --------- Co-authored-by: MET Tools Test Account --- docs/Users_Guide/overview.rst | 3 +- internal/test_unit/xml/unit_ascii2nc.xml | 25 +++++++++- .../basic/vx_config/test_user_func.cc | 9 ++-- .../test_util/basic/vx_log/test_reg_exp.cc | 8 ++-- .../basic/vx_util/test_ascii_header.cc | 8 ++-- .../basic/vx_util/test_command_line.cc | 8 ++-- src/basic/vx_util/command_line.cc | 14 ++++-- src/basic/vx_util/command_line.h | 2 +- src/tools/core/ensemble_stat/ensemble_stat.cc | 6 +-- src/tools/core/grid_stat/grid_stat.cc | 6 +-- src/tools/core/mode/mode.cc | 9 ++++ src/tools/core/mode/mode_usage.cc | 46 ++++++++++++++++--- src/tools/core/mode/mode_usage.h | 6 +-- src/tools/core/mode_analysis/mode_analysis.cc | 6 +-- src/tools/core/pair_stat/pair_stat.cc | 6 +-- src/tools/core/pcp_combine/pcp_combine.cc | 6 +-- src/tools/core/point_stat/point_stat.cc | 6 +-- .../core/series_analysis/series_analysis.cc | 6 +-- src/tools/core/stat_analysis/stat_analysis.cc | 6 +-- src/tools/core/wavelet_stat/wavelet_stat.cc | 6 +-- src/tools/dev_utils/chk4copyright.cc | 6 +-- src/tools/dev_utils/gen_climo_bin.cc | 6 +-- src/tools/dev_utils/nceptab_to_flat.cc | 6 +-- .../dev_utils/shapefiles/make_mapfiles.cc | 6 +-- src/tools/dev_utils/swinging_door.cc | 6 +-- src/tools/other/ascii2nc/ascii2nc.cc | 9 ++-- src/tools/other/gen_ens_prod/gen_ens_prod.cc | 6 +-- src/tools/other/gen_vx_mask/gen_vx_mask.cc | 4 +- src/tools/other/gen_vx_mask/gen_vx_mask.h | 2 +- src/tools/other/gis_utils/gis_dump_dbf.cc | 19 ++++++-- src/tools/other/gis_utils/gis_dump_shp.cc | 6 +-- src/tools/other/gis_utils/gis_dump_shx.cc | 19 ++++++-- src/tools/other/grid_diag/grid_diag.cc | 6 +-- src/tools/other/gsi_tools/gsid2mpr.cc | 6 +-- src/tools/other/gsi_tools/gsidens2orank.cc | 6 +-- src/tools/other/ioda2nc/ioda2nc.cc | 6 +-- src/tools/other/lidar2nc/lidar2nc.cc | 6 +-- src/tools/other/madis2nc/madis2nc.cc | 6 +-- .../other/mode_graphics/plot_mode_field.cc | 6 +-- src/tools/other/mode_time_domain/mtd.cc | 6 +-- src/tools/other/modis_regrid/modis_regrid.cc | 6 +-- src/tools/other/pb2nc/pb2nc.cc | 6 +-- .../other/plot_data_plane/plot_data_plane.cc | 6 +-- .../other/plot_point_obs/plot_point_obs.cc | 6 +-- src/tools/other/point2grid/point2grid.cc | 6 +-- .../regrid_data_plane/regrid_data_plane.cc | 6 +-- .../shift_data_plane/shift_data_plane.cc | 6 +-- src/tools/other/wwmca_tool/wwmca_plot.cc | 6 +-- src/tools/other/wwmca_tool/wwmca_regrid.cc | 6 +-- .../tc_utils/rmw_analysis/rmw_analysis.cc | 6 +-- src/tools/tc_utils/tc_diag/tc_diag.cc | 6 +-- src/tools/tc_utils/tc_dland/tc_dland.cc | 6 +-- src/tools/tc_utils/tc_gen/tc_gen.cc | 6 +-- src/tools/tc_utils/tc_pairs/tc_pairs.cc | 6 +-- src/tools/tc_utils/tc_rmw/tc_rmw.cc | 6 +-- src/tools/tc_utils/tc_stat/tc_stat.cc | 6 +-- 56 files changed, 258 insertions(+), 173 deletions(-) diff --git a/docs/Users_Guide/overview.rst b/docs/Users_Guide/overview.rst index 1168e0c7c5..685ee7104d 100644 --- a/docs/Users_Guide/overview.rst +++ b/docs/Users_Guide/overview.rst @@ -88,7 +88,8 @@ MET is the statistical component of the larger METplus system for which user sup .. note:: - **-help** and **-version** command line options are available for all of the MET tools. Typing the name of the tool with no command line options also produces the usage statement. + **-help** and **-version** command line options are available for all of the MET tools, and the command returns a good status of 0. + Typing the name of the tool with no command line options also produces the usage statement, although the command returns a non-zero status of 1. Fortify and SonarQube ===================== diff --git a/internal/test_unit/xml/unit_ascii2nc.xml b/internal/test_unit/xml/unit_ascii2nc.xml index 8b5fbf8021..a445082396 100644 --- a/internal/test_unit/xml/unit_ascii2nc.xml +++ b/internal/test_unit/xml/unit_ascii2nc.xml @@ -20,6 +20,29 @@ &TEST_DIR; true + + + + &MET_BIN;/ascii2nc + 1 + + + + + + + + + + &MET_BIN;/ascii2nc + 0 + \ + -help + + + + + &MET_BIN;/ascii2nc \ @@ -247,6 +270,6 @@ - + diff --git a/internal/test_util/basic/vx_config/test_user_func.cc b/internal/test_util/basic/vx_config/test_user_func.cc index 8c04da4470..1d35794a23 100644 --- a/internal/test_util/basic/vx_config/test_user_func.cc +++ b/internal/test_util/basic/vx_config/test_user_func.cc @@ -51,7 +51,7 @@ static CommandLine cline; static void set_do_dump(const StringArray &); -static void usage(); +static void usage(int exit_code=1); //////////////////////////////////////////////////////////////////////// @@ -198,16 +198,13 @@ return; //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) void usage(int exit_code) { cerr << "\n\n usage: " << program_name << " config_file [ config_file2 ... ] : function_name arg1 [arg2 ...]\n\n"; -exit ( 1 ); - - -return; +exit ( exit_code ); } diff --git a/internal/test_util/basic/vx_log/test_reg_exp.cc b/internal/test_util/basic/vx_log/test_reg_exp.cc index c7a0dd5bab..a07b16d72c 100644 --- a/internal/test_util/basic/vx_log/test_reg_exp.cc +++ b/internal/test_util/basic/vx_log/test_reg_exp.cc @@ -24,7 +24,7 @@ using namespace std; static void set_regex (const StringArray &); static void set_test (const StringArray &); -static void usage(); +static void usage(int exit_code=1); static ConcatString RegexCS; static ConcatString TestCS; @@ -77,13 +77,11 @@ void set_test(const StringArray & a) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) void usage(int exit_code) { mlog << Error << "\nusage: " << program_name << " -regex string -test string\n\n"; - exit(1); - - return; + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/internal/test_util/basic/vx_util/test_ascii_header.cc b/internal/test_util/basic/vx_util/test_ascii_header.cc index 4c5e241537..33f8db36ac 100644 --- a/internal/test_util/basic/vx_util/test_ascii_header.cc +++ b/internal/test_util/basic/vx_util/test_ascii_header.cc @@ -20,7 +20,7 @@ using namespace std; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); //////////////////////////////////////////////////////////////////////// @@ -87,7 +87,7 @@ int main(int argc, char * argv []) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) void usage(int exit_code) { mlog << Error << "\nUsage: " << program_name << "\n" @@ -97,9 +97,7 @@ void usage() { << "\t[-dim n]\n" << "\t[-name str]\n" << "\t[-offset beg [end]]\n\n"; - exit(1); - - return; + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/internal/test_util/basic/vx_util/test_command_line.cc b/internal/test_util/basic/vx_util/test_command_line.cc index d11183dcd5..13a5b50460 100644 --- a/internal/test_util/basic/vx_util/test_command_line.cc +++ b/internal/test_util/basic/vx_util/test_command_line.cc @@ -27,7 +27,7 @@ using namespace std; static void set_xyz (const StringArray &); static void set_verbose (const StringArray &); -static void usage(); +static void usage(int exit_code=1); //////////////////////////////////////////////////////////////////////// @@ -129,15 +129,13 @@ return; //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { mlog << Error << "\nusage: " << program_name << " [ -xyz x y z ] [ -verbose ] file_list\n\n"; -exit ( 1 ); - -return; +exit ( exit_code ); } diff --git a/src/basic/vx_util/command_line.cc b/src/basic/vx_util/command_line.cc index 6251e49e5e..8104d4b949 100644 --- a/src/basic/vx_util/command_line.cc +++ b/src/basic/vx_util/command_line.cc @@ -839,7 +839,11 @@ void CommandLine::do_help() const { -if ( Usage ) Usage(); + // + // MET #3278 print usage with good exit status + // + +if ( Usage ) Usage(0); else { mlog << Error << "\n" << ProgramName @@ -888,7 +892,11 @@ version_file = replace_path("MET_BASE/version.txt"); cout << "\n"; -exit ( 1 ); + // + // MET #3278 print version with good exit status + // + +exit(0); } @@ -984,7 +992,7 @@ while ( (j = next_option(index)) >= 0 ) { mlog << Error << "\n" << ProgramName << ": unrecognized command-line switch: \"" << args[j] << "\"\n\n"; - if ( Usage ) Usage(); + if ( Usage ) Usage(1); exit ( 1 ); diff --git a/src/basic/vx_util/command_line.h b/src/basic/vx_util/command_line.h index d11753061e..4f5340f685 100644 --- a/src/basic/vx_util/command_line.h +++ b/src/basic/vx_util/command_line.h @@ -34,7 +34,7 @@ static const char log_option [] = "-log"; typedef void (*CLSetFunction)(const StringArray &); // command-line set function -typedef void (*UsageFunction)(); // usage function +typedef void (*UsageFunction)(int); // usage function //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/ensemble_stat/ensemble_stat.cc b/src/tools/core/ensemble_stat/ensemble_stat.cc index d67e55c51f..aad96f9c1d 100644 --- a/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -176,7 +176,7 @@ static void add_var_att_local(VarInfo *, NcVar *, bool is_int, static void finish_txt_files(); static void clean_up(); -static void usage(); +static void usage(int exit_code=1); static void set_grid_obs(const StringArray &); static void set_point_obs(const StringArray &); @@ -2897,7 +2897,7 @@ static void clean_up() { //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -2956,7 +2956,7 @@ static void usage() { << "\t\t\"-compress level\" overrides the compression level of NetCDF variable (" << conf_info.get_compression_level() << ") (optional).\n\n" << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/grid_stat/grid_stat.cc b/src/tools/core/grid_stat/grid_stat.cc index fed90addfe..a3e18bfd5f 100644 --- a/src/tools/core/grid_stat/grid_stat.cc +++ b/src/tools/core/grid_stat/grid_stat.cc @@ -195,7 +195,7 @@ static void finish_txt_files(); static void clean_up(); -static void usage(); +static void usage(int exit_code=1); static void set_outdir(const StringArray &); static void set_compress(const StringArray &); static bool read_data_plane(VarInfo *info, DataPlane &dp, Met2dDataFile *mtddf, @@ -3278,7 +3278,7 @@ void clean_up() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -3321,7 +3321,7 @@ void usage() { << "\t\t\"-compress level\" overrides the compression level of NetCDF variable (" << conf_info.get_compression_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/mode/mode.cc b/src/tools/core/mode/mode.cc index 95b6ab0580..284a5205ca 100644 --- a/src/tools/core/mode/mode.cc +++ b/src/tools/core/mode/mode.cc @@ -133,6 +133,15 @@ int met_main(int argc, char * argv []) string s; const char * user_config_filename = 0; + // + // MET #3278 parse global command line options + // + CommandLine cline; + cline.set(argc, argv); + cline.set_usage(both_usage); + cline.allow_unrecognized_switches(); + cline.parse(); + for (j=0,n=0; j &, int, int); static void clean_up(); -static void usage(); +static void usage(int exit_code=1); static void set_fcst_files(const StringArray &); static void set_obs_files(const StringArray &); static void set_both_files(const StringArray &); @@ -2617,7 +2617,7 @@ static void clean_up() { //////////////////////////////////////////////////////////////////////// -__attribute__((noreturn)) static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -2683,7 +2683,7 @@ __attribute__((noreturn)) static void usage() { << R"("-compress level" overrides the compression level of NetCDF variable ()" << conf_info.get_compression_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/stat_analysis/stat_analysis.cc b/src/tools/core/stat_analysis/stat_analysis.cc index 3002092e69..667767eda2 100644 --- a/src/tools/core/stat_analysis/stat_analysis.cc +++ b/src/tools/core/stat_analysis/stat_analysis.cc @@ -86,7 +86,7 @@ static const char * python_target_string = "python"; static void parse_command_line(int &argc, char **argv); static void sanity_check(); -static void usage(); +static void usage(int exit_code=1); static void set_lookin_path(const StringArray &); static void set_out_filename(const StringArray &); static void set_tmp_dir(const StringArray &); @@ -746,7 +746,7 @@ void clean_up() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -787,7 +787,7 @@ void usage() { << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/wavelet_stat/wavelet_stat.cc b/src/tools/core/wavelet_stat/wavelet_stat.cc index 756b55600b..e9a0c0d301 100644 --- a/src/tools/core/wavelet_stat/wavelet_stat.cc +++ b/src/tools/core/wavelet_stat/wavelet_stat.cc @@ -133,7 +133,7 @@ static void draw_tiles(PSfile *, const Box &, int, int, int); static void render_image(PSfile *, const DataPlane &, const Box &, int); static void render_tile(PSfile *, const double *, int, int, const Box &); -static void usage(); +static void usage(int exit_code=1); static void set_outdir(const StringArray &); static void set_compress(const StringArray &); @@ -2982,7 +2982,7 @@ static void render_tile(PSfile *p, const double *data, int n, //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -3017,7 +3017,7 @@ static void usage() { << "\t\t\"-compress level\" overrides the compression level of NetCDF variable (" << conf_info.get_compression_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/dev_utils/chk4copyright.cc b/src/tools/dev_utils/chk4copyright.cc index d0977ab87d..dce0298f4c 100644 --- a/src/tools/dev_utils/chk4copyright.cc +++ b/src/tools/dev_utils/chk4copyright.cc @@ -63,7 +63,7 @@ static bool output_info = true; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_top_dir(const StringArray &); static void set_copyright_notice_filename(const StringArray &); @@ -164,13 +164,13 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { mlog << Error << "\nUsage: " << program_name << "\n" << " -dir DirectoryPath\n" << " [-notice CopyrightNoticeFilename ]\n" << " [-quiet ]\n\n"; - exit (1); + exit (exit_code); } diff --git a/src/tools/dev_utils/gen_climo_bin.cc b/src/tools/dev_utils/gen_climo_bin.cc index 19b1faa869..934e1d7f0f 100644 --- a/src/tools/dev_utils/gen_climo_bin.cc +++ b/src/tools/dev_utils/gen_climo_bin.cc @@ -87,7 +87,7 @@ static void set_field_str(const StringArray & a); static void set_var_name(const StringArray & a); static void my_memcpy(void * to, unsigned char * & from, int n_bytes); -static void usage(); +static void usage(int exit_code=1); //////////////////////////////////////////////////////////////////////// @@ -441,7 +441,7 @@ void set_var_name (const StringArray & a) { var_name = a[0]; return; } //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -471,7 +471,7 @@ void usage() { << "\tNOTE: Either \"-bin\" or \"-mean\", \"-stdev\", and \"-field\" must be specified.\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/dev_utils/nceptab_to_flat.cc b/src/tools/dev_utils/nceptab_to_flat.cc index 3e01063b98..a790bd7217 100644 --- a/src/tools/dev_utils/nceptab_to_flat.cc +++ b/src/tools/dev_utils/nceptab_to_flat.cc @@ -55,7 +55,7 @@ static int table_number = 0; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_table_number(const StringArray &); @@ -113,13 +113,13 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { cerr << "\n\n usage: " << program_name << " nceptab_source_file.c [ more such files ...]\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/dev_utils/shapefiles/make_mapfiles.cc b/src/tools/dev_utils/shapefiles/make_mapfiles.cc index 452e2d3635..061294f47a 100644 --- a/src/tools/dev_utils/shapefiles/make_mapfiles.cc +++ b/src/tools/dev_utils/shapefiles/make_mapfiles.cc @@ -84,7 +84,7 @@ static const char sq = '\''; // single quote //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_outdir (const StringArray &); static void set_separate_files (const StringArray &); @@ -196,7 +196,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { @@ -204,7 +204,7 @@ cerr << "\nusage: " << program_name << ' ' << "[-outdir path] [-separate_files] " << "shp_file shx_file dbf_file country_field admin_field\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/dev_utils/swinging_door.cc b/src/tools/dev_utils/swinging_door.cc index 340f315e1a..cf2e3486e5 100644 --- a/src/tools/dev_utils/swinging_door.cc +++ b/src/tools/dev_utils/swinging_door.cc @@ -68,7 +68,7 @@ static string station_id_arg; static bool process_file(); static bool run_algorithm(const vector< SDObservation > &obs, vector< SDObservation > &compressed_obs); -static void usage(); +static void usage(int exit_code=1); static bool write_observations(const vector< SDObservation > &observations, const string &file_path); static bool write_ramps(const vector< SDObservation > &observations, @@ -190,7 +190,7 @@ bool run_algorithm(const vector< SDObservation > &observations, //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\nUsage: " << program_name << "\n" @@ -217,7 +217,7 @@ void usage() << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/ascii2nc/ascii2nc.cc b/src/tools/other/ascii2nc/ascii2nc.cc index b54eaeafb5..1f76e2aefe 100644 --- a/src/tools/other/ascii2nc/ascii2nc.cc +++ b/src/tools/other/ascii2nc/ascii2nc.cc @@ -161,7 +161,7 @@ static FileHandler *create_file_handler(const ASCIIFormat, static FileHandler *determine_ascii_format(const ConcatString &, ConcatString &); -static void usage(); +static void usage(int exit_code=1); static void set_inputrx(const StringArray &); static void set_format(const StringArray &); static void set_config(const StringArray &); @@ -182,7 +182,7 @@ int met_main(int argc, char *argv[]) { // // Check for zero arguments // - if(argc == 1) { usage(); return 0; } + if(argc == 1) usage(); // Initialize time range valid_beg_ut = valid_end_ut = (unixtime) 0; @@ -219,7 +219,7 @@ int met_main(int argc, char *argv[]) { // Check for error. There should be at least two arguments left: // the ascii input filenames and the netCDF output filename // - if(cline.n() < 2) { usage(); return 0; } + if(cline.n() < 2) usage(); // // Store the input ASCII file names @@ -619,7 +619,7 @@ static FileHandler *determine_ascii_format(const ConcatString &ascii_filename, //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\nUsage: " << program_name << "\n" @@ -721,6 +721,7 @@ static void usage() { << flush; + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 0f87c1403d..c9d1d8b613 100644 --- a/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -84,7 +84,7 @@ static void add_var_att_local(GenEnsProdVarInfo *, NcVar *, bool is_int, const DataPlane &, const char *, const char *); static void clean_up(); -static void usage(); +static void usage(int exit_code=1); static void set_ens_files (const StringArray &); static void set_out_file (const StringArray &); @@ -1297,7 +1297,7 @@ static void clean_up() { //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -1331,7 +1331,7 @@ static void usage() { << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n"; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/gen_vx_mask/gen_vx_mask.cc b/src/tools/other/gen_vx_mask/gen_vx_mask.cc index 0258664517..6971623343 100644 --- a/src/tools/other/gen_vx_mask/gen_vx_mask.cc +++ b/src/tools/other/gen_vx_mask/gen_vx_mask.cc @@ -1772,7 +1772,7 @@ const char * masktype_to_description(const MaskType t) { //////////////////////////////////////////////////////////////////////// -__attribute__((noreturn)) static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -1892,7 +1892,7 @@ __attribute__((noreturn)) static void usage() { << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/gen_vx_mask/gen_vx_mask.h b/src/tools/other/gen_vx_mask/gen_vx_mask.h index 022dafdc4f..f54e68f376 100644 --- a/src/tools/other/gen_vx_mask/gen_vx_mask.h +++ b/src/tools/other/gen_vx_mask/gen_vx_mask.h @@ -157,7 +157,7 @@ static void apply_lat_lon_mask(DataPlane &dp); static DataPlane combine(const DataPlane &dp_data, const DataPlane &dp_mask, SetLogic); static void write_netcdf(const DataPlane &dp); -static void usage(); +static void usage(int exit_code=1); static void set_type(const StringArray &); static void set_input_field(const StringArray &); static void set_mask_field(const StringArray &); diff --git a/src/tools/other/gis_utils/gis_dump_dbf.cc b/src/tools/other/gis_utils/gis_dump_dbf.cc index abf39865d9..a09f10b09a 100644 --- a/src/tools/other/gis_utils/gis_dump_dbf.cc +++ b/src/tools/other/gis_utils/gis_dump_dbf.cc @@ -43,7 +43,7 @@ static unsigned char buf[buf_size]; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); //////////////////////////////////////////////////////////////////////// @@ -55,12 +55,21 @@ int met_main(int argc, char * argv []) program_name = get_short_name(argv[0]); -if ( argc != 2 ) usage(); +CommandLine cline; + +cline.set(argc, argv); + +cline.set_usage(usage); + +cline.parse(); + +if ( cline.n() != 1 ) usage(); + +ConcatString input_filename = (string)cline[0]; int fd = -1; int j; size_t n_read, bytes; -ConcatString input_filename = (string)argv[1]; DbfHeader h; DbfSubRecord sr; @@ -168,14 +177,14 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { mlog << Error << "\n\n usage: " << program_name << " dbf_filename\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/other/gis_utils/gis_dump_shp.cc b/src/tools/other/gis_utils/gis_dump_shp.cc index b097b44983..c0e4fcaaea 100644 --- a/src/tools/other/gis_utils/gis_dump_shp.cc +++ b/src/tools/other/gis_utils/gis_dump_shp.cc @@ -61,7 +61,7 @@ static CommandLine cline; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_header_only(const StringArray &); @@ -164,14 +164,14 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { mlog << Error << "\n\n usage: " << program_name << " [ -h ] shp_filename\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/other/gis_utils/gis_dump_shx.cc b/src/tools/other/gis_utils/gis_dump_shx.cc index 64bcc51ff3..182da6508d 100644 --- a/src/tools/other/gis_utils/gis_dump_shx.cc +++ b/src/tools/other/gis_utils/gis_dump_shx.cc @@ -43,7 +43,7 @@ static unsigned char buf[buf_size]; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); //////////////////////////////////////////////////////////////////////// @@ -55,12 +55,21 @@ int met_main(int argc, char * argv []) program_name = get_short_name(argv[0]); -if ( argc != 2 ) usage(); +CommandLine cline; + +cline.set(argc, argv); + +cline.set_usage(usage); + +cline.parse(); + +if ( cline.n() != 1 ) usage(); + +ConcatString input_filename = (string)cline[0]; int fd = -1; int n_read, bytes; int count; -ConcatString input_filename = (string)argv[1]; ShxFileHeader h; ShxRecord r; @@ -142,14 +151,14 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { mlog << Error << "\n\n usage: " << program_name << " shx_filename\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/other/grid_diag/grid_diag.cc b/src/tools/other/grid_diag/grid_diag.cc index af992e1725..45d45cbebf 100644 --- a/src/tools/other/grid_diag/grid_diag.cc +++ b/src/tools/other/grid_diag/grid_diag.cc @@ -70,7 +70,7 @@ static void clean_up(); static Met2dDataFile *get_mtddf(const StringArray &, const int); -static void usage(); +static void usage(int exit_code=1); static void set_data_files(const StringArray &); static void set_out_file(const StringArray &); static void set_config_file(const StringArray &); @@ -821,7 +821,7 @@ void clean_up() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -858,7 +858,7 @@ void usage() { << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/gsi_tools/gsid2mpr.cc b/src/tools/other/gsi_tools/gsid2mpr.cc index 6ca6d2ab88..06b6c6897d 100644 --- a/src/tools/other/gsi_tools/gsid2mpr.cc +++ b/src/tools/other/gsi_tools/gsid2mpr.cc @@ -57,7 +57,7 @@ static void write_mpr_row_rad (AsciiTable &at, int row, const RadData &d); static bool is_dup(const char *); -static void usage(); +static void usage(int exit_code=1); static void set_swap(const StringArray &); static void set_no_check_dup(const StringArray &); static void set_channel(const StringArray &); @@ -523,7 +523,7 @@ bool is_dup(const char *key) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -559,7 +559,7 @@ void usage() { << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/gsi_tools/gsidens2orank.cc b/src/tools/other/gsi_tools/gsidens2orank.cc index d375cddb20..cd751147e6 100644 --- a/src/tools/other/gsi_tools/gsidens2orank.cc +++ b/src/tools/other/gsi_tools/gsidens2orank.cc @@ -66,7 +66,7 @@ static bool has_key(const ConcatString &key, int & index); static void check_int(int i1, int i2, const char *col, const ConcatString &key); static void check_dbl(double d1, double d2, const char *col, const ConcatString &key); -static void usage(); +static void usage(int exit_code=1); static void set_out(const StringArray &); static void set_ens_mean(const StringArray &); static void set_swap(const StringArray &); @@ -834,7 +834,7 @@ void check_dbl(double d1, double d2, const char *col, const ConcatString &key) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -876,7 +876,7 @@ void usage() { << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/ioda2nc/ioda2nc.cc b/src/tools/other/ioda2nc/ioda2nc.cc index 97ea652c7c..8abc415b1a 100644 --- a/src/tools/other/ioda2nc/ioda2nc.cc +++ b/src/tools/other/ioda2nc/ioda2nc.cc @@ -146,7 +146,7 @@ static bool keep_message_type(const char *); static bool keep_station_id(const char *); static bool keep_valid_time(const unixtime, const unixtime, const unixtime); -static void usage(); +static void usage(int exit_code=1); static void set_compress(const StringArray &); static void set_config(const StringArray &); static void set_ioda_files(const StringArray &); @@ -1053,7 +1053,7 @@ static bool get_obs_data_double(NcFile *f_in, const ConcatString &var_name, //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -1108,7 +1108,7 @@ static void usage() { << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/lidar2nc/lidar2nc.cc b/src/tools/other/lidar2nc/lidar2nc.cc index 94c62256a1..50e9a1a563 100644 --- a/src/tools/other/lidar2nc/lidar2nc.cc +++ b/src/tools/other/lidar2nc/lidar2nc.cc @@ -90,7 +90,7 @@ static int compress_level = -1; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_outfile (const StringArray &); static void set_compress (const StringArray &); @@ -161,7 +161,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\nUsage: " << program_name << "\n" @@ -187,7 +187,7 @@ cout << "\nUsage: " << flush; -exit (1); +exit (exit_code); } diff --git a/src/tools/other/madis2nc/madis2nc.cc b/src/tools/other/madis2nc/madis2nc.cc index 2ea8ba22a7..59f672833b 100644 --- a/src/tools/other/madis2nc/madis2nc.cc +++ b/src/tools/other/madis2nc/madis2nc.cc @@ -124,7 +124,7 @@ static void process_madis_maritime(NcFile *&f_in); static void process_madis_mesonet(NcFile *&f_in); static void process_madis_acarsProfiles(NcFile *&f_in); -static void usage(); +static void usage(int exit_code=1); static void set_type(const StringArray &); static void set_qc_dd(const StringArray &); static void set_lvl_dim(const StringArray &); @@ -3554,7 +3554,7 @@ void process_madis_acarsProfiles(NcFile *&f_in) { //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\nUsage: " << program_name << "\n" @@ -3621,7 +3621,7 @@ static void usage() { << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/mode_graphics/plot_mode_field.cc b/src/tools/other/mode_graphics/plot_mode_field.cc index fe8862acc7..2d3d045535 100644 --- a/src/tools/other/mode_graphics/plot_mode_field.cc +++ b/src/tools/other/mode_graphics/plot_mode_field.cc @@ -157,7 +157,7 @@ static ConcatString config_filename; // no default ... must be set on command //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_config (const StringArray &); @@ -597,7 +597,7 @@ return; //////////////////////////////////////////////////////////////////////// -static void usage() +__attribute__((noreturn)) static void usage(int exit_code) { @@ -630,7 +630,7 @@ cout << "\n*** Model Evaluation Tools (MET" << met_version << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit (1); + exit (exit_code); } diff --git a/src/tools/other/mode_time_domain/mtd.cc b/src/tools/other/mode_time_domain/mtd.cc index 4cff82a842..8cb016653a 100644 --- a/src/tools/other/mode_time_domain/mtd.cc +++ b/src/tools/other/mode_time_domain/mtd.cc @@ -83,7 +83,7 @@ static ConcatString local_config_filename; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_fcst (const StringArray &); static void set_obs (const StringArray &); @@ -891,7 +891,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { @@ -939,7 +939,7 @@ cout << "\n*** Model Evaluation Tools (MET" << met_version << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n" << flush; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/other/modis_regrid/modis_regrid.cc b/src/tools/other/modis_regrid/modis_regrid.cc index a37a7bca55..4bdd79baa5 100644 --- a/src/tools/other/modis_regrid/modis_regrid.cc +++ b/src/tools/other/modis_regrid/modis_regrid.cc @@ -73,7 +73,7 @@ static void set_offset (const StringArray &); static void set_fillvalue (const StringArray &); static void set_compress (const StringArray &); -static void usage(); +static void usage(int exit_code=1); static void get_grid(); @@ -223,7 +223,7 @@ return; //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { @@ -255,7 +255,7 @@ cout << "\n" << "\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/other/pb2nc/pb2nc.cc b/src/tools/other/pb2nc/pb2nc.cc index ab855b3aff..02940214f8 100644 --- a/src/tools/other/pb2nc/pb2nc.cc +++ b/src/tools/other/pb2nc/pb2nc.cc @@ -428,7 +428,7 @@ static void merge_records(float *first_pqtzuv, map pqtzuv_map_p map pqtzuv_map_aux, map &pqtzuv_map_merged); -static void usage(); +static void usage(int exit_code=1); static void set_pbfile(const StringArray &); static void set_valid_beg_time(const StringArray &); static void set_valid_end_time(const StringArray &); @@ -3574,7 +3574,7 @@ void log_pbl_input(int pbl_level, const char *method_name) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -3639,7 +3639,7 @@ void usage() { << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/plot_data_plane/plot_data_plane.cc b/src/tools/other/plot_data_plane/plot_data_plane.cc index 307f3a97f3..8236aab781 100644 --- a/src/tools/other/plot_data_plane/plot_data_plane.cc +++ b/src/tools/other/plot_data_plane/plot_data_plane.cc @@ -81,7 +81,7 @@ static double PlotRangeMax = 0.0; //////////////////////////////////////////////////////////////////////// static void process_command_line(int, char **); -static void usage(); +static void usage(int exit_code=1); static void set_colortable_name(const StringArray &); static void set_plot_range(const StringArray &); static void set_title_string(const StringArray &); @@ -287,7 +287,7 @@ void process_command_line(int argc, char **argv) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -328,7 +328,7 @@ void usage() { << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } diff --git a/src/tools/other/plot_point_obs/plot_point_obs.cc b/src/tools/other/plot_point_obs/plot_point_obs.cc index 3353800549..0624f072c8 100644 --- a/src/tools/other/plot_point_obs/plot_point_obs.cc +++ b/src/tools/other/plot_point_obs/plot_point_obs.cc @@ -57,7 +57,7 @@ using namespace std; //////////////////////////////////////////////////////////////////////// -[[noreturn]] static void usage(); +static void usage(int exit_code=1); static void process_point_obs(const char *); static void create_plot(); static void add_colorbar(PSfile &, const Box &, const ColorTable &); @@ -613,7 +613,7 @@ static void add_colorbar(PSfile &plot, const Box &box, const ColorTable &ct) { //////////////////////////////////////////////////////////////////////// -[[noreturn]] static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\nUsage: " << program_name << "\n" << "\tnc_file\n" @@ -656,7 +656,7 @@ static void add_colorbar(PSfile &plot, const Box &box, const ColorTable &ct) { << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/point2grid/point2grid.cc b/src/tools/other/point2grid/point2grid.cc index 737935f94a..1cf578e37b 100644 --- a/src/tools/other/point2grid/point2grid.cc +++ b/src/tools/other/point2grid/point2grid.cc @@ -162,7 +162,7 @@ static void write_nc(const DataPlane &dp, const Grid &grid, static void write_nc_int(const DataPlane &dp, const Grid &grid, const VarInfo *vinfo, const char *vname); static void close_nc(); -static void usage(); +static void usage(int exit_code=1); static void set_field(const StringArray &); static void set_method(const StringArray &); static void set_prob_cat_thresh(const StringArray &); @@ -2927,7 +2927,7 @@ static bool has_lat_lon_vars(const NcFile *nc) { //////////////////////////////////////////////////////////////////////// -__attribute__((noreturn)) static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -3004,7 +3004,7 @@ __attribute__((noreturn)) static void usage() { << "\t\t\"-compress level\" overrides the compression level of NetCDF variable (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/regrid_data_plane/regrid_data_plane.cc b/src/tools/other/regrid_data_plane/regrid_data_plane.cc index b87323a7c8..d5ea9ff797 100644 --- a/src/tools/other/regrid_data_plane/regrid_data_plane.cc +++ b/src/tools/other/regrid_data_plane/regrid_data_plane.cc @@ -92,7 +92,7 @@ static void open_nc(const Grid &grid, const ConcatString run_cs); static void write_nc(const DataPlane &dp, const Grid &grid, const VarInfo *vinfo, const char *vname); static void close_nc(); -static void usage(); +static void usage(int exit_code=1); static void set_field(const StringArray &); static void set_method(const StringArray &); static void set_shape(const StringArray &); @@ -431,7 +431,7 @@ void close_nc() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { GridTemplateFactory gtf; cout << "\n*** Model Evaluation Tools (MET" << met_version @@ -515,7 +515,7 @@ void usage() { << "\t\t\"-compress level\" overrides the compression level of " << "NetCDF variable (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/shift_data_plane/shift_data_plane.cc b/src/tools/other/shift_data_plane/shift_data_plane.cc index 76ef1bca6c..072ddbff70 100644 --- a/src/tools/other/shift_data_plane/shift_data_plane.cc +++ b/src/tools/other/shift_data_plane/shift_data_plane.cc @@ -87,7 +87,7 @@ static void process_command_line(int, char **); static void process_data_file(); static void write_netcdf(const DataPlane &dp, const Grid &grid, const VarInfo *vinfo, const GrdFileType& ftype); -static void usage(); +static void usage(int exit_code=1); static void set_from(const StringArray &); static void set_to(const StringArray &); static void set_method(const StringArray &); @@ -366,7 +366,7 @@ void write_netcdf(const DataPlane &dp, const Grid &grid, //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -418,7 +418,7 @@ void usage() { << "\t\t\"-compress level\" overrides the compression level of NetCDF variable (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/wwmca_tool/wwmca_plot.cc b/src/tools/other/wwmca_tool/wwmca_plot.cc index ddbb48ac26..3179705628 100644 --- a/src/tools/other/wwmca_tool/wwmca_plot.cc +++ b/src/tools/other/wwmca_tool/wwmca_plot.cc @@ -90,7 +90,7 @@ static double scale; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_outdir(const StringArray &); @@ -178,7 +178,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { @@ -199,7 +199,7 @@ cout << "\nUsage: " << program_name << "\n" << "\t\t\"wwmca_cloud_pct_file_list\" is a list of one or " << "more wwmca cloud percent files to plot.\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/other/wwmca_tool/wwmca_regrid.cc b/src/tools/other/wwmca_tool/wwmca_regrid.cc index ad136e72a3..8fb7b09619 100644 --- a/src/tools/other/wwmca_tool/wwmca_regrid.cc +++ b/src/tools/other/wwmca_tool/wwmca_regrid.cc @@ -66,7 +66,7 @@ static ConcatString config_filename; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void set_nh_filename (const StringArray &); static void set_sh_filename (const StringArray &); @@ -181,7 +181,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() +__attribute__((noreturn)) static void usage(int exit_code) { @@ -210,7 +210,7 @@ cout << "\nUsage: " << program_name << "\n" << "\t\t\"-compress level\" overrides the compression level of NetCDF variable (optional).\n\n"; -exit ( 1 ); +exit ( exit_code ); } diff --git a/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc b/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc index 934ad9f649..82e3f963c3 100644 --- a/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc +++ b/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc @@ -32,7 +32,7 @@ using namespace netCDF; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void process_command_line(int, char**); static void set_data_files(const StringArray&); static void set_config(const StringArray&); @@ -76,7 +76,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -static void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -103,7 +103,7 @@ static void usage() { << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/tc_utils/tc_diag/tc_diag.cc b/src/tools/tc_utils/tc_diag/tc_diag.cc index 43a113eb4e..d3d9184583 100644 --- a/src/tools/tc_utils/tc_diag/tc_diag.cc +++ b/src/tools/tc_utils/tc_diag/tc_diag.cc @@ -57,7 +57,7 @@ using namespace netCDF; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void process_command_line(int, char**); static void get_file_type(); @@ -142,7 +142,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -176,7 +176,7 @@ void usage() { << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/tc_utils/tc_dland/tc_dland.cc b/src/tools/tc_utils/tc_dland/tc_dland.cc index e6d6952b59..57fe8fc555 100644 --- a/src/tools/tc_utils/tc_dland/tc_dland.cc +++ b/src/tools/tc_utils/tc_dland/tc_dland.cc @@ -95,7 +95,7 @@ static int compress_level = -1; static void process_command_line(int, char **); static void process_land_data(); static void process_distances(); -static void usage(); +static void usage(int exit_code=1); static void set_grid(const StringArray &); static void set_noll(const StringArray &); static void set_land(const StringArray &); @@ -307,7 +307,7 @@ void process_distances() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -345,7 +345,7 @@ void usage() { << flush; - exit (1); + exit (exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/tc_utils/tc_gen/tc_gen.cc b/src/tools/tc_utils/tc_gen/tc_gen.cc index 901e1a3f29..f413fdd8dd 100644 --- a/src/tools/tc_utils/tc_gen/tc_gen.cc +++ b/src/tools/tc_utils/tc_gen/tc_gen.cc @@ -148,7 +148,7 @@ static void finish_txt_files (); static ConcatString string_to_basin_abbr(ConcatString); -static void usage (); +static void usage (int exit_code=1); static void set_source (const StringArray &, const char *, StringArray &, StringArray &); static void set_genesis (const StringArray &); @@ -2570,7 +2570,7 @@ ConcatString string_to_basin_abbr(ConcatString cs) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -2619,7 +2619,7 @@ void usage() { << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n"; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/tc_utils/tc_pairs/tc_pairs.cc b/src/tools/tc_utils/tc_pairs/tc_pairs.cc index 2f61e30e01..beabfa48ec 100644 --- a/src/tools/tc_utils/tc_pairs/tc_pairs.cc +++ b/src/tools/tc_utils/tc_pairs/tc_pairs.cc @@ -156,7 +156,7 @@ static void process_watch_warn (TrackPairInfoArray &); static void write_tracks (const TrackPairInfoArray &); static void write_prob_rirw (const ProbRIRWPairInfoArray &); static void setup_table (AsciiTable &); -static void usage (); +static void usage (int exit_code=1); static void set_adeck (const StringArray &); static void set_edeck (const StringArray &); static void set_bdeck (const StringArray &); @@ -2227,7 +2227,7 @@ void setup_table(AsciiTable &at) { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -2279,7 +2279,7 @@ void usage() { << "may include \"suffix=string\" to modify the model names " << "from that path.\n\n"; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/tc_utils/tc_rmw/tc_rmw.cc b/src/tools/tc_utils/tc_rmw/tc_rmw.cc index 1ea016d482..e14421d786 100644 --- a/src/tools/tc_utils/tc_rmw/tc_rmw.cc +++ b/src/tools/tc_utils/tc_rmw/tc_rmw.cc @@ -58,7 +58,7 @@ using namespace netCDF; //////////////////////////////////////////////////////////////////////// -static void usage(); +static void usage(int exit_code=1); static void process_command_line(int, char**); static GrdFileType get_file_type(const StringArray &, const GrdFileType); @@ -111,7 +111,7 @@ const string get_tool_name() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -142,7 +142,7 @@ void usage() { << "\t\t\"-v level\" overrides the default level of logging (" << mlog.verbosity_level() << ") (optional).\n\n" << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/tc_utils/tc_stat/tc_stat.cc b/src/tools/tc_utils/tc_stat/tc_stat.cc index 194d87e004..0f41af0688 100644 --- a/src/tools/tc_utils/tc_stat/tc_stat.cc +++ b/src/tools/tc_utils/tc_stat/tc_stat.cc @@ -56,7 +56,7 @@ using namespace std; static void process_command_line(int, char **); static void process_search_dirs (); static void process_jobs (); -static void usage (); +static void usage (int exit_code=1); static void set_lookin (const StringArray &); static void set_out (const StringArray &); static void set_config (const StringArray &); @@ -315,7 +315,7 @@ void close_out_file() { //////////////////////////////////////////////////////////////////////// -void usage() { +__attribute__((noreturn)) static void usage(int exit_code) { cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n" @@ -352,7 +352,7 @@ void usage() { << flush; - exit(1); + exit(exit_code); } //////////////////////////////////////////////////////////////////////// From 8899d4b7c3e52bcce28cc7348c6bc049cb192ae2 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 28 Oct 2025 14:27:22 -0600 Subject: [PATCH 08/45] Feature #3270 main_v12.2 message_type_group_map (#3280) * Per #3072, add constants and logic to process the message_typ_group_map entries for LAPSERT and MSLAGL to specify the message types for which the lase_rate_correction and msl_agl_conversion should apply. * Per #3072, update PairDataPoint and PairDataEnsemble to check the new msg_typ_lapsert and msg_typ_mslagl settings. * Per #3072, update Point-Stat and Ensemble-Stat to use common functionality in PairBase to parse the specialized msg_typ_group_map entries. Since the common library code uses default values, we do not need to error out if the expected entries are missing. * Per #3270, update the message_type_group_map dictionary in Point-Stat and Ensemble-Stat config file to include entries for LAPSERT and MSLAGL. * Per #3270, update documentation. * Per #3270, fix typo and accessor function. * Per #3270, fix pair_data_ensemble.cc logic. * Per #3270, tweak docs. * Per #3270, clarify docs further. * Update config_options.rst Adding a word --------- Co-authored-by: j-opatz <59586397+j-opatz@users.noreply.github.com> --- data/config/EnsembleStatConfig_default | 6 +- data/config/PointStatConfig_default | 4 +- docs/Users_Guide/config_options.rst | 117 ++++++++++++++---- .../config/EnsembleStatConfig_LAND_TOPO_MASK | 4 +- .../EnsembleStatConfig_LAPSE_RATE_MSL_AGL | 7 +- .../config/EnsembleStatConfig_python | 7 +- .../EnsembleStatConfig_single_file_grib | 7 +- .../config/EnsembleStatConfig_single_file_nc | 6 +- .../config/PointStatConfig_LAND_TOPO_MASK | 4 +- .../config/PointStatConfig_LAPSE_RATE_MSL_AGL | 4 +- .../config/PointStatConfig_MPR_OBTYPE | 4 +- .../test_unit/config/PointStatConfig_WINDS | 2 + .../test_unit/config/PointStatConfig_airnow | 4 +- .../config/PointStatConfig_range_azimuth | 4 +- scripts/config/EnsembleStatConfig | 7 +- src/basic/vx_util/util_constants.h | 4 + src/libcode/vx_statistics/pair_base.cc | 48 ++++--- src/libcode/vx_statistics/pair_base.h | 14 +-- .../vx_statistics/pair_data_ensemble.cc | 5 +- src/libcode/vx_statistics/pair_data_point.cc | 5 +- .../ensemble_stat/ensemble_stat_conf_info.cc | 33 +---- .../core/point_stat/point_stat_conf_info.cc | 53 +------- 22 files changed, 201 insertions(+), 148 deletions(-) diff --git a/data/config/EnsembleStatConfig_default b/data/config/EnsembleStatConfig_default index f2f0bbd09f..d84fe088e8 100644 --- a/data/config/EnsembleStatConfig_default +++ b/data/config/EnsembleStatConfig_default @@ -117,7 +117,11 @@ message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/data/config/PointStatConfig_default b/data/config/PointStatConfig_default index 1406050447..3bc6a821a7 100644 --- a/data/config/PointStatConfig_default +++ b/data/config/PointStatConfig_default @@ -112,7 +112,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/docs/Users_Guide/config_options.rst b/docs/Users_Guide/config_options.rst index 3e32599875..5d9697c197 100644 --- a/docs/Users_Guide/config_options.rst +++ b/docs/Users_Guide/config_options.rst @@ -667,11 +667,27 @@ message_type_group_map The "message_type_group_map" entry is an array of dictionaries, each containing a "key" string and "val" string. This defines a mapping of message type group names to a comma-separated list of values. This map is -defined in the config files for PB2NC, Point-Stat, or Ensemble-Stat. Modify -this map to define sets of message types that should be processed together as -a group. The "SURFACE" entry defines message types for which surface verification -logic should be applied. If not defined, the default values listed below are -used. +defined in the config files for PB2NC, IODA2NC, Point-Stat, and Ensemble-Stat. +Modify this map to define sets of message types that should be processed +together as a group. + +Beyond defining groups of message types, the following entries have special meaning: + + * The "SURFACE" entry defines message types for which surface verification + logic should be applied. + + * The "LANDSF" and "WATERSF" entries differentiate between point observations + over land and water, as described in "land_mask" below. + + * The "LAPSERT" entry defines the message types for which surface temperature + lapse rate correction logic should be applied, as described in + "lapse_rate_correction" below. + + * The "MSLAGL" entry defines the message types for which MSL/AGL height + conversion logic should be applied, as described in "msl_agl_conversion" + below. + +If not defined, the default values listed below are used. .. code-block:: none @@ -679,7 +695,11 @@ used. { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag @@ -2258,17 +2278,31 @@ land_mask The "land_mask" dictionary defines the land/sea mask field used when verifying at the surface. The "flag" entry enables/disables this logic. -When enabled, the "message_type_group_map" dictionary must contain entries -for "LANDSF" and "WATERSF". For point observations whose message type -appears in the "LANDSF" entry, only use forecast grid points where land = -TRUE. For point observations whose message type appears in the "WATERSF" -entry, only use forecast grid points where land = FALSE. If the "file_name" -entry is left empty, the land/sea is assumed to exist in the input forecast -file. Otherwise, the specified file(s) are searched for the data specified -in the "field" entry. The "regrid" settings specify how this field should be -regridded to the verification domain. Lastly, the "thresh" entry is the -threshold which defines land (threshold is true) and water (threshold is false). +If the "file_name" entry is empty, the land/sea mask field is assumed +to exist in the input forecast file. Otherwise, the specified file(s) +are searched for the data specified in the "field" entry. +The "regrid" settings specify how this field should be regridded to the +verification domain. Lastly, the "thresh" entry is the threshold which +defines land (threshold is true) and water (threshold is false). + +The "message_type_group_map" dictionary entries for "LANDSF" and "WATERSF" specify +comma-separated lists of message types whose observations exist on land or water, +respectively. For point observations whose message type appears in the "LANDSF" +entry, only interpolate using forecast grid points where land = TRUE. For point +observations whose message type appears in the "WATERSF" entry, only interpolate +using forecast grids points where land = FALSE. By default, "ADPSFC" and "MSONET" +message types exist over land while the "SFCSHP" message type exists over water. +.. code-block:: none + + message_type_group_map = [ + ... + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + ... + ]; + +The "topo_mask.flag", "topo_mask.use_obs_thresh", and "topo_mask.interp_fcst_thresh" The "land_mask.flag" entry may be set separately in each "obs.field" entry. .. code-block:: none @@ -2286,11 +2320,9 @@ topo_mask The "topo_mask" dictionary defines the model topography field used when verifying at the surface. The flag entry enables/disables this logic. -When enabled, the "message_type_group_map" dictionary must contain an entry -for "SURFACE". This logic is applied to point observations whose message type -appears in the "SURFACE" entry. Only use point observations where the -topo minus station elevation difference meets the "use_obs_thresh" threshold -entry. For the observations kept, when interpolating forecast data to the +Only use point observations where the model topography minus station elevation +elevation difference meets the "use_obs_thresh" threshold entry. +For the observations kept, when interpolating forecast data to the observation location, only use forecast grid points where the topo minus station difference meets the "interp_fcst_thresh" threshold entry. If the "file_name" is left empty, the topography data is assumed to exist in the input forecast file(s). @@ -2299,6 +2331,20 @@ entry. The "regrid" settings specify how this field should be regridded to the verification domain. The "interp" settings specify how this field should be interpolated to point observation locations. +The "message_type_group_map" dictionary entry for "SURFACE" specifies a comma-separated +list of message types whose observations exist at the surface. The topography filtering +logic is only applied to observations whose message type appears in this list. +By default, the topography filtering logic is applied to observations for message types +"ADPSFC", "SFCSHP", and "MSONET". + +.. code-block:: none + + message_type_group_map = [ + ... + { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, + ... + ]; + The "topo_mask.flag", "topo_mask.use_obs_thresh", and "topo_mask.interp_fcst_thresh" entries can be set separately in each "obs.field" entry. @@ -2324,9 +2370,6 @@ for this correction. The "apply_to" option can be set to "NONE" (default) to disable this correction logic, "FCST" to correct the forecast value, or "OBS" to correct the observation value, but not "BOTH". -When enabled, the "message_type_group_map" dictionary must contain an entry for -"SURFACE". This correction is only applied when the verifying point observation -message type appears in the "SURFACE" entry. The "value" entry is a constant number that defines the lapse rate for correcting temperatures based on the difference of the model topography height and station elevation. By default, "value" is set to bad data and must be explicitly defined @@ -2335,6 +2378,19 @@ The lapse rate correction fails when the model topography or observation height values are bad data and that matched pair is excluded from the computation of statistics. +The "message_type_group_map" dictionary entry for "LAPSERT" specifies a comma-separated +list of message types for which this correction should be applied. By default, the +correction logic is applied to observations for message types "ADPSFC" and "MSONET". +If set to an empty list, the correction would be applied for all message types. + +.. code-block:: none + + message_type_group_map = [ + ... + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + ... + ]; + The environmental lapse rate values for 2-meter temperature and dewpoint temperature used by the World Meteorological Organization (WMO) can be found in "ConfigConstants". @@ -2385,6 +2441,19 @@ The MSL/AGL conversion fails when the model topography or observation height values are bad data and that matched pair is excluded from the computation of statistics. +The "message_type_group_map" dictionary entry for "MSLAGL" specifies a comma-separated +list of message types for which this conversion should be applied. By default, the +conversion logic is applied to observations for all message types since it is set to an +empty list. + +.. code-block:: none + + message_type_group_map = [ + ... + { key = "MSLAGL"; val = ""; }, + ... + ]; + All "msl_agl_conversion" entries can be set separately in each "obs.field" entry. .. code-block:: none diff --git a/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK b/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK index 93e2fbd83d..32859b6f8b 100644 --- a/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK +++ b/internal/test_unit/config/EnsembleStatConfig_LAND_TOPO_MASK @@ -135,7 +135,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL b/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL index b25cb8143d..6cba1da80f 100644 --- a/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL +++ b/internal/test_unit/config/EnsembleStatConfig_LAPSE_RATE_MSL_AGL @@ -149,7 +149,12 @@ message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/EnsembleStatConfig_python b/internal/test_unit/config/EnsembleStatConfig_python index d7a633ffe4..0b6446c04a 100644 --- a/internal/test_unit/config/EnsembleStatConfig_python +++ b/internal/test_unit/config/EnsembleStatConfig_python @@ -116,7 +116,12 @@ message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/EnsembleStatConfig_single_file_grib b/internal/test_unit/config/EnsembleStatConfig_single_file_grib index 6217e12c44..de35f96d56 100644 --- a/internal/test_unit/config/EnsembleStatConfig_single_file_grib +++ b/internal/test_unit/config/EnsembleStatConfig_single_file_grib @@ -128,7 +128,12 @@ message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/EnsembleStatConfig_single_file_nc b/internal/test_unit/config/EnsembleStatConfig_single_file_nc index 89f16090fa..f6f379824e 100644 --- a/internal/test_unit/config/EnsembleStatConfig_single_file_nc +++ b/internal/test_unit/config/EnsembleStatConfig_single_file_nc @@ -134,7 +134,11 @@ message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK b/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK index 15dd62b9cf..6bea691a4d 100644 --- a/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK +++ b/internal/test_unit/config/PointStatConfig_LAND_TOPO_MASK @@ -78,7 +78,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL b/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL index b8333021a9..e0fc19558c 100644 --- a/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL +++ b/internal/test_unit/config/PointStatConfig_LAPSE_RATE_MSL_AGL @@ -101,7 +101,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/PointStatConfig_MPR_OBTYPE b/internal/test_unit/config/PointStatConfig_MPR_OBTYPE index 1726987df1..53e7a5feab 100644 --- a/internal/test_unit/config/PointStatConfig_MPR_OBTYPE +++ b/internal/test_unit/config/PointStatConfig_MPR_OBTYPE @@ -48,7 +48,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = TRUE; diff --git a/internal/test_unit/config/PointStatConfig_WINDS b/internal/test_unit/config/PointStatConfig_WINDS index 79abb8a477..8442e76735 100644 --- a/internal/test_unit/config/PointStatConfig_WINDS +++ b/internal/test_unit/config/PointStatConfig_WINDS @@ -49,6 +49,8 @@ message_type_group_map = [ { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; }, { key = "USERSF"; val = "ADPSFC,SFCSHP"; } ]; diff --git a/internal/test_unit/config/PointStatConfig_airnow b/internal/test_unit/config/PointStatConfig_airnow index 1f765d7353..96bf46ac81 100644 --- a/internal/test_unit/config/PointStatConfig_airnow +++ b/internal/test_unit/config/PointStatConfig_airnow @@ -89,7 +89,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/internal/test_unit/config/PointStatConfig_range_azimuth b/internal/test_unit/config/PointStatConfig_range_azimuth index e9283fb230..57f1343305 100644 --- a/internal/test_unit/config/PointStatConfig_range_azimuth +++ b/internal/test_unit/config/PointStatConfig_range_azimuth @@ -87,7 +87,9 @@ message_type_group_map = [ { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, { key = "LANDSF"; val = "ADPSFC,MSONET"; }, - { key = "WATERSF"; val = "SFCSHP"; } + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/scripts/config/EnsembleStatConfig b/scripts/config/EnsembleStatConfig index 9e6d17e335..5067f1b8d4 100644 --- a/scripts/config/EnsembleStatConfig +++ b/scripts/config/EnsembleStatConfig @@ -121,7 +121,12 @@ message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, { key = "ANYAIR"; val = "AIRCAR,AIRCFT"; }, { key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; }, - { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }, + { key = "LANDSF"; val = "ADPSFC,MSONET"; }, + { key = "WATERSF"; val = "SFCSHP"; }, + { key = "LAPSERT"; val = "ADPSFC,MSONET"; }, + { key = "MSLAGL"; val = ""; } ]; obtype_as_group_val_flag = FALSE; diff --git a/src/basic/vx_util/util_constants.h b/src/basic/vx_util/util_constants.h index ebf1a3bf4b..c42dde0e0f 100644 --- a/src/basic/vx_util/util_constants.h +++ b/src/basic/vx_util/util_constants.h @@ -85,11 +85,15 @@ static const int n_vld_msg_typ = static const char surface_msg_typ_group_str [] = "SURFACE"; // Surface message type group static const char landsf_msg_typ_group_str [] = "LANDSF"; // Surface land message type group static const char watersf_msg_typ_group_str [] = "WATERSF"; // Surface water message type group +static const char lapsert_msg_typ_group_str [] = "LAPSERT"; // Lapse rate correction message type group +static const char mslagl_msg_typ_group_str [] = "MSLAGL"; // MSL/AGL conversion message type groupe // Default message type group values static const char default_msg_typ_group_surface [] = "ADPSFC,SFCSHP,MSONET"; static const char default_msg_typ_group_landsf [] = "ADPSFC,MSONET"; static const char default_msg_typ_group_watersf [] = "SFCSHP"; +static const char default_msg_typ_group_lapsert [] = "ADPSFC,MSONET"; +static const char default_msg_typ_group_mslagl [] = ""; // Convert all types // Commonly used regular expressions static const char yyyymmdd_hhmmss_reg_exp[] = diff --git a/src/libcode/vx_statistics/pair_base.cc b/src/libcode/vx_statistics/pair_base.cc index effaa1d611..e188a34e8a 100644 --- a/src/libcode/vx_statistics/pair_base.cc +++ b/src/libcode/vx_statistics/pair_base.cc @@ -982,6 +982,8 @@ void VxPairBase::clear() { msg_typ_sfc.clear(); msg_typ_lnd.clear(); msg_typ_wtr.clear(); + msg_typ_lapsert.clear(); + msg_typ_mslagl.clear(); sfc_info.clear(); @@ -1048,9 +1050,11 @@ void VxPairBase::assign(const VxPairBase &vx_pb) { mpr_str_inc_map = vx_pb.mpr_str_inc_map; mpr_str_exc_map = vx_pb.mpr_str_exc_map; - msg_typ_sfc = vx_pb.msg_typ_sfc; - msg_typ_lnd = vx_pb.msg_typ_lnd; - msg_typ_wtr = vx_pb.msg_typ_wtr; + msg_typ_sfc = vx_pb.msg_typ_sfc; + msg_typ_lnd = vx_pb.msg_typ_lnd; + msg_typ_wtr = vx_pb.msg_typ_wtr; + msg_typ_lapsert = vx_pb.msg_typ_lapsert; + msg_typ_mslagl = vx_pb.msg_typ_mslagl; sfc_info = vx_pb.sfc_info; @@ -1454,27 +1458,33 @@ void VxPairBase::set_climo_cdf_info_ptr(const ClimoCDFInfo *info) { //////////////////////////////////////////////////////////////////////// -void VxPairBase::set_msg_typ_sfc(const StringArray &sa) { +void VxPairBase::set_msg_typ_groups(const map &m) { + ConcatString cs; - msg_typ_sfc = sa; + // Surface message types + cs = surface_msg_typ_group_str; + if(m.count(cs) > 0) msg_typ_sfc = m.at(cs); + else msg_typ_sfc.parse_css(default_msg_typ_group_surface); - return; -} - -//////////////////////////////////////////////////////////////////////// - -void VxPairBase::set_msg_typ_lnd(const StringArray &sa) { + // Land surface message types + cs = landsf_msg_typ_group_str; + if(m.count(cs) > 0) msg_typ_lnd = m.at(cs); + else msg_typ_lnd.parse_css(default_msg_typ_group_landsf); - msg_typ_lnd = sa; - - return; -} - -//////////////////////////////////////////////////////////////////////// + // Water surface message types + cs = watersf_msg_typ_group_str; + if(m.count(cs) > 0) msg_typ_wtr = m.at(cs); + else msg_typ_wtr.parse_css(default_msg_typ_group_watersf); -void VxPairBase::set_msg_typ_wtr(const StringArray &sa) { + // Lapse rate correction message types + cs = lapsert_msg_typ_group_str; + if(m.count(cs) > 0) msg_typ_lapsert = m.at(cs); + else msg_typ_lapsert.parse_css(default_msg_typ_group_lapsert); - msg_typ_wtr = sa; + // MSL/AGL conversion message types + cs = mslagl_msg_typ_group_str; + if(m.count(cs) > 0) msg_typ_mslagl = m.at(cs); + else msg_typ_mslagl.parse_css(default_msg_typ_group_mslagl); return; } diff --git a/src/libcode/vx_statistics/pair_base.h b/src/libcode/vx_statistics/pair_base.h index 06db360319..4517c11489 100644 --- a/src/libcode/vx_statistics/pair_base.h +++ b/src/libcode/vx_statistics/pair_base.h @@ -299,11 +299,13 @@ class VxPairBase { ////////////////////////////////////////////////////////////////// - StringArray msg_typ_sfc; // List of surface message types - StringArray msg_typ_lnd; // List of surface land message types - StringArray msg_typ_wtr; // List of surface water message types + StringArray msg_typ_sfc; // Surface message types + StringArray msg_typ_lnd; // Surface land message types + StringArray msg_typ_wtr; // Surface water message types + StringArray msg_typ_lapsert; // Lapse rate correction message types + StringArray msg_typ_mslagl; // MSL/AGL conversion message types - SurfaceInfo sfc_info; // Land/sea mask and topography info + SurfaceInfo sfc_info; // Land/sea mask and topography info ////////////////////////////////////////////////////////////////// @@ -392,9 +394,7 @@ class VxPairBase { void set_climo_cdf_info_ptr(const ClimoCDFInfo *); - void set_msg_typ_sfc(const StringArray &); - void set_msg_typ_lnd(const StringArray &); - void set_msg_typ_wtr(const StringArray &); + void set_msg_typ_groups(const std::map &); int get_n_pair() const; diff --git a/src/libcode/vx_statistics/pair_data_ensemble.cc b/src/libcode/vx_statistics/pair_data_ensemble.cc index 93a8457c62..3f6edb92bd 100644 --- a/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -1444,7 +1444,8 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, const Grid &gr) { // MET #3174 Apply lapse rate surface temperature correction if(sfc_info.lapse_rate_correction_apply_to != FieldType::None && - msg_typ_sfc.reg_exp_match(it->typ_sa[i_obs].c_str()) && + (msg_typ_lapsert.all_empty() || + msg_typ_lapsert.reg_exp_match(it->typ_sa[i_obs].c_str())) && !correct_lapse_rate(topo_elv, it->elv_na[i_obs], fcst_v, obs_v)) { // Skip by resetting to bad data @@ -1454,6 +1455,8 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, const Grid &gr) { // MET #3174 Apply MSL/AGL height conversion if(sfc_info.msl_agl_conversion_apply_to != FieldType::None && + (msg_typ_mslagl.all_empty() || + msg_typ_mslagl.reg_exp_match(it->typ_sa[i_obs].c_str())) && !convert_msl_agl(topo_elv, it->elv_na[i_obs], fcst_v, obs_v, member == 0)) { // Skip by resetting to bad data diff --git a/src/libcode/vx_statistics/pair_data_point.cc b/src/libcode/vx_statistics/pair_data_point.cc index 2f2c939bf9..9426d63755 100644 --- a/src/libcode/vx_statistics/pair_data_point.cc +++ b/src/libcode/vx_statistics/pair_data_point.cc @@ -623,7 +623,8 @@ void VxPairDataPoint::add_point_obs(const float *hdr_arr, // MET #3174 Apply lapse rate surface temperature correction if(sfc_info.lapse_rate_correction_apply_to != FieldType::None && - msg_typ_sfc.reg_exp_match(hdr_typ_str) && + (msg_typ_lapsert.all_empty() || + msg_typ_lapsert.reg_exp_match(hdr_typ_str)) && !correct_lapse_rate(topo_elv, hdr_elv, fcst_v, obs_v)) { inc_count(rej_mpr, i_msg_typ, i_mask, i_interp); continue; @@ -631,6 +632,8 @@ void VxPairDataPoint::add_point_obs(const float *hdr_arr, // MET #3174 Apply MSL/AGL height conversion if(sfc_info.msl_agl_conversion_apply_to != FieldType::None && + (msg_typ_mslagl.all_empty() || + msg_typ_mslagl.reg_exp_match(hdr_typ_str)) && !convert_msl_agl(topo_elv, hdr_elv, fcst_v, obs_v)) { inc_count(rej_mpr, i_msg_typ, i_mask, i_interp); continue; diff --git a/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index 515496cab8..64a0c57de5 100644 --- a/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -167,15 +167,6 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, // Conf: message_type_group_map msg_typ_group_map = parse_conf_message_type_group_map(&conf); - // Conf: message_type_group_map(SURFACE) - ConcatString cs = surface_msg_typ_group_str; - if(msg_typ_group_map.count(cs) > 0) { - msg_typ_sfc = msg_typ_group_map[cs]; - } - else { - msg_typ_sfc.parse_css(default_msg_typ_group_surface); - } - // Conf: obtype_as_group_val_flag obtype_as_group_val_flag = conf.lookup_bool(conf_key_obtype_as_group_val_flag); @@ -524,18 +515,6 @@ void EnsembleStatConfInfo::process_geog(const Grid &grid, DataPlane geog_dp(parse_geog_data(dict, grid, input_files)); geog_dp.threshold(dict->lookup_thresh(conf_key_thresh)); land_mask = geog_dp.mask_plane(); - - // Conf: message_type_group_map for LANDSF and WATERSF - if(msg_typ_group_map.count((string)landsf_msg_typ_group_str) == 0 || - msg_typ_group_map.count((string)watersf_msg_typ_group_str) == 0 ) { - mlog << Error << "\n" << method_name - << "when \"" << conf_key_land_mask_flag << "\" is true, \"" - << conf_key_message_type_group_map - << "\" must contain entries for \"" - << landsf_msg_typ_group_str << "\" and \"" - << watersf_msg_typ_group_str << "\".\n\n"; - exit(1); - } } // Store pointer to the land mask data @@ -549,16 +528,6 @@ void EnsembleStatConfInfo::process_geog(const Grid &grid, if(topo_dp.is_empty()) { Dictionary *dict = conf.lookup_dictionary(conf_key_topo_mask); topo_dp = parse_geog_data(dict, grid, input_files); - - // Conf: message_type_group_map for SURFACE - if(msg_typ_group_map.count((string)surface_msg_typ_group_str) == 0) { - mlog << Error << "\n" << method_name - << "when \"" << conf_key_topo_mask_flag << "\" is true, \"" - << conf_key_message_type_group_map - << "\" must contain an entry for \"" - << surface_msg_typ_group_str << "\".\n\n"; - exit(1); - } } // Store pointer to the topo data @@ -1069,7 +1038,7 @@ void EnsembleStatVxOpt::set_vx_pd(EnsembleStatConfInfo *conf_info, int ctrl_inde vx_pd.set_climo_cdf_info_ptr(&cdf_info); // Store the list of surface message types - vx_pd.set_msg_typ_sfc(conf_info->msg_typ_sfc); + vx_pd.set_msg_typ_groups(conf_info->msg_typ_group_map); // Define the verifying message type name and values for(int i=0; ilookup_thresh(conf_key_thresh)); land_mask = geog_dp.mask_plane(); - - // Conf: message_type_group_map for LANDSF and WATERSF - if(msg_typ_group_map.count((string)landsf_msg_typ_group_str) == 0 || - msg_typ_group_map.count((string)watersf_msg_typ_group_str) == 0 ) { - mlog << Error << "\n" << method_name - << "when \"" << conf_key_land_mask_flag << "\" is true, \"" - << conf_key_message_type_group_map - << "\" must contain entries for \"" - << landsf_msg_typ_group_str << "\" and \"" - << watersf_msg_typ_group_str << "\".\n\n"; - exit(1); - } } // Store pointer to the land mask data @@ -544,16 +532,6 @@ void PointStatConfInfo::process_geog(const Grid &grid, if(topo_dp.is_empty()) { Dictionary *dict = conf.lookup_dictionary(conf_key_topo_mask); topo_dp = parse_geog_data(dict, grid, input_files); - - // Conf: message_type_group_map for SURFACE - if(msg_typ_group_map.count((string)surface_msg_typ_group_str) == 0) { - mlog << Error << "\n" << method_name - << "when \"" << conf_key_topo_mask_flag << "\" is true, \"" - << conf_key_message_type_group_map - << "\" must contain an entry for \"" - << surface_msg_typ_group_str << "\".\n\n"; - exit(1); - } } // Store pointer to the topo data @@ -1145,35 +1123,8 @@ void PointStatVxOpt::set_vx_pd(PointStatConfInfo *conf_info) { // Store the climo CDF info vx_pd.set_climo_cdf_info_ptr(&cdf_info); - // Store the surface message type group - cs = surface_msg_typ_group_str; - if(conf_info->msg_typ_group_map.count(cs) > 0) { - vx_pd.set_msg_typ_sfc(conf_info->msg_typ_group_map[cs]); - } - else { - sa.parse_css(default_msg_typ_group_surface); - vx_pd.set_msg_typ_sfc(sa); - } - - // Store the surface land message type group - cs = landsf_msg_typ_group_str; - if(conf_info->msg_typ_group_map.count(cs) > 0) { - vx_pd.set_msg_typ_lnd(conf_info->msg_typ_group_map[cs]); - } - else { - sa.parse_css(default_msg_typ_group_landsf); - vx_pd.set_msg_typ_lnd(sa); - } - - // Store the surface water message type group - cs = watersf_msg_typ_group_str; - if(conf_info->msg_typ_group_map.count(cs) > 0) { - vx_pd.set_msg_typ_wtr(conf_info->msg_typ_group_map[cs]); - } - else { - sa.parse_css(default_msg_typ_group_watersf); - vx_pd.set_msg_typ_wtr(sa); - } + // Store message type groups + vx_pd.set_msg_typ_groups(conf_info->msg_typ_group_map); // Define the verifying message type name and values for(int i=0; i Date: Tue, 28 Oct 2025 16:30:52 -0600 Subject: [PATCH 09/45] Feature #3275 v12.2.0-rc2 (#3283) * Per #3275, update the release notes for v12.2.0-rc2. * Per #3275, tweak formatting. --------- Co-authored-by: MET Tools Test Account --- docs/Users_Guide/release-notes.rst | 26 ++++++++++++++++++++++++++ docs/conf.py | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/Users_Guide/release-notes.rst b/docs/Users_Guide/release-notes.rst index 600fbc8552..fd99f5fc54 100644 --- a/docs/Users_Guide/release-notes.rst +++ b/docs/Users_Guide/release-notes.rst @@ -9,6 +9,32 @@ When applicable, release notes are followed by the GitHub issue number which des enhancement, or new feature (`MET GitHub issues `_). Important issues are listed **in bold** for emphasis. +MET Version 12.2.0-rc2 Release Notes (20251029) +----------------------------------------------- + + .. dropdown:: Enhancements + + * Refine default lapse rates for orographic corrections + (`#3258 `_). + * Refine handling of missing data for orographic corrections + (`#3270 `_). + * Enhance the MET tools to return consistent exit codes + (`#3278 `_). + + .. dropdown:: Bugfixes + + * Update the logic to apply "set_attr_grid" before "ShiftRight" + (`#3255 `_). + * Fix ASCII2NC hang when run with an empty input file + (`#3266 `_). + + .. dropdown:: Repository, build, and test + + * Confirm that the METplus difference logic handles MTD output file + (`#977 `_). + * Enhance the "Create Release Docker Images" METplus workflows to determine and build the most recent bugfix versions + (`METplus-Internal#64 `_). + MET Version 12.2.0-rc1 Release Notes (20250926) ----------------------------------------------- diff --git a/docs/conf.py b/docs/conf.py index dca00b74d2..2f281598e0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,11 +20,11 @@ project = 'MET' author = 'UCAR/NCAR, NOAA, CSU/CIRA, and CU/CIRES' author_list = 'Soh, H., L. Goodrich, B. Brown, R. Bullock, J. Halley Gotway, K. Newman, J. Opatz, T. Jensen, J. Prestopnik' -version = '12.2.0-rc1' +version = '12.2.0-rc2' verinfo = version release = f'{version}' release_year = '2025' -release_date = f'{release_year}-09-26' +release_date = f'{release_year}-10-29' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- From 563d3e556b17218be788292012f7c66555d9cab5 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 6 Nov 2025 13:31:12 -0700 Subject: [PATCH 10/45] Feature #3270 main_v12.2 duplicate_corrections (#3284) * Per #3207, update convert_msl_agl() and correct_lapse_rate() functions to include the station name and point observation summary string as arguments to enhance the log messages. * Per #3207, update calls to convert_msl_agl() and correct_lapse_rate() in PairDataPoint and PairDataEnsemble. In PairDataPoint, operate on a copy of the obs value rather than the original input one to avoid applying the same operation multiple times. * Per #3072, update the criteria in pair_data_ensemble.cc to refine when correct_lapse_rate() and convert_msll_agl() are called. There is not a problem with the output, but the current logic produces confusing and unexpected log messages. * Per #3270, revise logging and logic for Ensemble-Stat. --------- Co-authored-by: MET Tools Test Account --- src/libcode/vx_statistics/pair_base.cc | 34 ++++++++++++------- src/libcode/vx_statistics/pair_base.h | 8 +++-- .../vx_statistics/pair_data_ensemble.cc | 7 ++-- src/libcode/vx_statistics/pair_data_point.cc | 13 ++++--- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/libcode/vx_statistics/pair_base.cc b/src/libcode/vx_statistics/pair_base.cc index e188a34e8a..9fc918a11f 100644 --- a/src/libcode/vx_statistics/pair_base.cc +++ b/src/libcode/vx_statistics/pair_base.cc @@ -2157,7 +2157,9 @@ double VxPairBase::compute_fcst_value( //////////////////////////////////////////////////////////////////////// -bool VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, +bool VxPairBase::correct_lapse_rate(const char *pnt_obs_str, + const char *obs_sid_str, + double fcst_elv, double obs_elv, double &fcst_v, double &obs_v) const { const char *method_name = "PairBase::correct_lapse_rate() -> "; @@ -2170,14 +2172,17 @@ bool VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, is_bad_data(fcst_v) || is_bad_data(obs_v) || is_bad_data(sfc_info.lapse_rate_correction_value)) { - if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { - mlog << Debug(CORRECTION_DEBUG_LEVEL) + if(mlog.verbosity_level() >= REJECT_DEBUG_LEVEL) { + ConcatString cs; + if(pnt_obs_str) cs << ":\n" << pnt_obs_str << "\n"; + else cs << ".\n"; + mlog << Debug(REJECT_DEBUG_LEVEL) << "For " << fcst_info->magic_str() << " versus " << obs_info->magic_str() << ", skipping lapse rate correction " << "due to bad (fcst, obs) elevation (" << fcst_elv << ", " << obs_elv << "), data (" << fcst_v << ", " << obs_v << "), or lapse rate (" - << sfc_info.lapse_rate_correction_value << ") values.\n"; + << sfc_info.lapse_rate_correction_value << ") values" << cs; } return false; @@ -2200,8 +2205,8 @@ bool VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, // Log the lapse rate correction if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { mlog << Debug(CORRECTION_DEBUG_LEVEL) - << "For " << fcst_info->magic_str() << " versus " - << obs_info->magic_str() << ", correcting the " + << "For station " << obs_sid_str << ", " << fcst_info->magic_str() + << " versus " << obs_info->magic_str() << ", correcting the " << fieldtype_to_string(sfc_info.lapse_rate_correction_apply_to) << " temperature from " << orig_v << " to " << corr_v << " for forecast (" << fcst_elv << ") minus observation (" @@ -2215,7 +2220,9 @@ bool VxPairBase::correct_lapse_rate(double fcst_elv, double obs_elv, //////////////////////////////////////////////////////////////////////// -bool VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, +bool VxPairBase::convert_msl_agl(const char *pnt_obs_str, + const char *obs_sid_str, + double fcst_elv, double obs_elv, double &fcst_v, double &obs_v, bool update_obs) const { const char *method_name = "PairBase::convert_msl_agl() -> "; @@ -2259,13 +2266,16 @@ bool VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, if(is_bad_data(fcst_v) || is_bad_data(obs_v) || is_bad_data(corr_f) || is_bad_data(corr_o)) { - if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { - mlog << Debug(CORRECTION_DEBUG_LEVEL) + if(mlog.verbosity_level() >= REJECT_DEBUG_LEVEL) { + ConcatString cs; + if(pnt_obs_str) cs << ":\n" << pnt_obs_str << "\n"; + else cs << ".\n"; + mlog << Debug(REJECT_DEBUG_LEVEL) << "For " << fcst_info->magic_str() << " versus " << obs_info->magic_str() << ", skipping msl/agl conversion " << "due to bad (fcst, obs) elevation (" << fcst_elv << ", " << obs_elv << ") or data (" << fcst_v << ", " - << obs_v << ") values.\n"; + << obs_v << ") values" << cs; } return false; @@ -2285,8 +2295,8 @@ bool VxPairBase::convert_msl_agl(double fcst_elv, double obs_elv, // Log the MSL/AGL conversion if(mlog.verbosity_level() >= CORRECTION_DEBUG_LEVEL) { mlog << Debug(CORRECTION_DEBUG_LEVEL) - << "For " << fcst_info->magic_str() << " versus " - << obs_info->magic_str() << ", converting " + << "For station " << obs_sid_str << ", " << fcst_info->magic_str() + << " versus " << obs_info->magic_str() << ", converting " << (sfc_info.msl_agl_conversion_msl_to_agl ? "MSL to AGL" : "AGL to MSL") << " using " diff --git a/src/libcode/vx_statistics/pair_base.h b/src/libcode/vx_statistics/pair_base.h index 4517c11489..a00b7598d8 100644 --- a/src/libcode/vx_statistics/pair_base.h +++ b/src/libcode/vx_statistics/pair_base.h @@ -437,9 +437,13 @@ class VxPairBase { double, double, double, const ClimoPntInfo &) const; - bool correct_lapse_rate(double, double, double &, double &) const; + bool correct_lapse_rate(const char *, const char *, + double, double, + double &, double &) const; - bool convert_msl_agl(double, double, double &, double &, + bool convert_msl_agl(const char *, const char *, + double, double, + double &, double &, bool update_obs = true) const; // Retrieve climo data for this point diff --git a/src/libcode/vx_statistics/pair_data_ensemble.cc b/src/libcode/vx_statistics/pair_data_ensemble.cc index 3f6edb92bd..51bae372c9 100644 --- a/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -1446,7 +1446,8 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, const Grid &gr) { if(sfc_info.lapse_rate_correction_apply_to != FieldType::None && (msg_typ_lapsert.all_empty() || msg_typ_lapsert.reg_exp_match(it->typ_sa[i_obs].c_str())) && - !correct_lapse_rate(topo_elv, it->elv_na[i_obs], fcst_v, obs_v)) { + !correct_lapse_rate(nullptr, it->sid_sa[i_obs].c_str(), + topo_elv, it->elv_na[i_obs], fcst_v, obs_v)) { // Skip by resetting to bad data fcst_v = bad_data_double; @@ -1457,7 +1458,9 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, const Grid &gr) { if(sfc_info.msl_agl_conversion_apply_to != FieldType::None && (msg_typ_mslagl.all_empty() || msg_typ_mslagl.reg_exp_match(it->typ_sa[i_obs].c_str())) && - !convert_msl_agl(topo_elv, it->elv_na[i_obs], fcst_v, obs_v, member == 0)) { + !convert_msl_agl(nullptr, it->sid_sa[i_obs].c_str(), + topo_elv, it->elv_na[i_obs], fcst_v, obs_v, + member == 0)) { // Skip by resetting to bad data fcst_v = bad_data_double; diff --git a/src/libcode/vx_statistics/pair_data_point.cc b/src/libcode/vx_statistics/pair_data_point.cc index 9426d63755..f8193508a9 100644 --- a/src/libcode/vx_statistics/pair_data_point.cc +++ b/src/libcode/vx_statistics/pair_data_point.cc @@ -550,8 +550,8 @@ void VxPairDataPoint::add_point_obs(const float *hdr_arr, if(!is_keeper_vld(pnt_obs_str.c_str(), hdr_ut)) return; // Check observation value - double obs_v = obs_arr[4]; - if(!is_keeper_obs(pnt_obs_str.c_str(), obs_v)) return; + double orig_obs_v = obs_arr[4]; + if(!is_keeper_obs(pnt_obs_str.c_str(), orig_obs_v)) return; // Check location double hdr_lat = hdr_arr[0]; @@ -605,6 +605,9 @@ void VxPairDataPoint::add_point_obs(const float *hdr_arr, // Loop through the interpolation methods for(int i_interp=0; i_interp Date: Thu, 13 Nov 2025 09:04:11 -0700 Subject: [PATCH 11/45] Feature #3287 v12.2.0 (#3289) * Per #3287, update log message to indicate that the observation height is printed rather than the station elevation. * Per #3287, update versio info in MET User's Guide. * Per #3287, update version numbers in MET config files. * Per #3287, add 12.2 to list of versions to be build by the release docker images workflow. * Per #3287, update 12.2.0 release notes. --- .github/workflows/release-docker-images.yml | 6 +-- data/config/Ascii2NcConfig_default | 2 +- data/config/EnsembleStatConfig_default | 2 +- data/config/GenEnsProdConfig_default | 2 +- data/config/GridDiagConfig_default | 2 +- data/config/GridStatConfig_default | 2 +- data/config/IODA2NCConfig_default | 2 +- data/config/MODEAnalysisConfig_default | 2 +- data/config/MODEConfig_default | 2 +- data/config/MODEMultivarConfig_default | 2 +- data/config/MTDConfig_default | 2 +- data/config/Madis2NcConfig_default | 2 +- data/config/PB2NCConfig_default | 2 +- data/config/PlotPointObsConfig_default | 2 +- data/config/Point2GridConfig_default | 2 +- data/config/PointStatConfig_default | 2 +- data/config/RMWAnalysisConfig_default | 2 +- data/config/STATAnalysisConfig_CBS_Index | 2 +- data/config/STATAnalysisConfig_GO_Index | 2 +- data/config/STATAnalysisConfig_default | 2 +- data/config/SeriesAnalysisConfig_default | 2 +- data/config/TCDiagConfig_default | 2 +- data/config/TCGenConfig_default | 2 +- data/config/TCPairsConfig_default | 2 +- data/config/TCRMWConfig_default | 2 +- data/config/TCStatConfig_default | 2 +- data/config/UGridConfig_lfric | 2 +- data/config/UGridConfig_lfric_pressure_levels | 2 +- data/config/UGridConfig_mpas | 2 +- data/config/WaveletStatConfig_default | 2 +- docs/Users_Guide/installation.rst | 38 ++++++++-------- docs/Users_Guide/release-notes.rst | 44 +++++++------------ docs/conf.py | 4 +- scripts/config/EnsembleStatConfig | 2 +- scripts/config/GenEnsProdConfig | 2 +- scripts/config/GridStatConfig_APCP_12 | 2 +- scripts/config/GridStatConfig_APCP_24 | 2 +- scripts/config/GridStatConfig_POP_12 | 2 +- scripts/config/GridStatConfig_all | 2 +- scripts/config/MODEAnalysisConfig | 2 +- scripts/config/MODEConfig_APCP_12 | 2 +- scripts/config/MODEConfig_APCP_24 | 2 +- scripts/config/MODEConfig_RH | 2 +- scripts/config/PB2NCConfig_G212 | 2 +- scripts/config/PointStatConfig | 2 +- scripts/config/STATAnalysisConfig | 2 +- scripts/config/WaveletStatConfig_APCP_12 | 2 +- scripts/config/WaveletStatConfig_APCP_12_NC | 2 +- src/libcode/vx_statistics/pair_base.cc | 2 +- 49 files changed, 85 insertions(+), 97 deletions(-) diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index e2a840bb41..879da0a90a 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -9,8 +9,8 @@ on: workflow_dispatch: inputs: release_version: - description: 'Comma-separated list of versions to build, e.g. v12.0,v12.1' - default: 'v12.1' + description: 'Comma-separated list of versions to build, e.g. v12.0,v12.1,v12.2' + default: 'v12.2' required: true type: string update_latest: @@ -46,7 +46,7 @@ jobs: id: get-versions run: | if [[ ${{ github.event_name }} == 'schedule' ]]; then - version_string="v12.0,v12.1" + version_string="v12.0,v12.1,v12.2" update_latest="true" elif [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then version_string=${{ toJSON(inputs.release_version) }} diff --git a/data/config/Ascii2NcConfig_default b/data/config/Ascii2NcConfig_default index 9c424f1fea..ff8b8b09e8 100644 --- a/data/config/Ascii2NcConfig_default +++ b/data/config/Ascii2NcConfig_default @@ -52,4 +52,4 @@ message_type_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V12.1.0"; +version = "V12.2.0"; diff --git a/data/config/EnsembleStatConfig_default b/data/config/EnsembleStatConfig_default index d84fe088e8..f75c7523f6 100644 --- a/data/config/EnsembleStatConfig_default +++ b/data/config/EnsembleStatConfig_default @@ -325,6 +325,6 @@ grid_weight_flag = NONE; point_weight_flag = NONE; output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/GenEnsProdConfig_default b/data/config/GenEnsProdConfig_default index ce430d874e..e18a2327e7 100644 --- a/data/config/GenEnsProdConfig_default +++ b/data/config/GenEnsProdConfig_default @@ -146,6 +146,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/GridDiagConfig_default b/data/config/GridDiagConfig_default index 21e299ff58..2c9649424f 100644 --- a/data/config/GridDiagConfig_default +++ b/data/config/GridDiagConfig_default @@ -61,6 +61,6 @@ mask = { //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/GridStatConfig_default b/data/config/GridStatConfig_default index fb20547b59..3a8b6e558d 100644 --- a/data/config/GridStatConfig_default +++ b/data/config/GridStatConfig_default @@ -274,6 +274,6 @@ grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/IODA2NCConfig_default b/data/config/IODA2NCConfig_default index d53b0d9b0d..92324a7a43 100644 --- a/data/config/IODA2NCConfig_default +++ b/data/config/IODA2NCConfig_default @@ -135,6 +135,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/MODEAnalysisConfig_default b/data/config/MODEAnalysisConfig_default index 5f0a49afca..b16ae8218c 100644 --- a/data/config/MODEAnalysisConfig_default +++ b/data/config/MODEAnalysisConfig_default @@ -188,6 +188,6 @@ unmatched = FALSE; //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/MODEConfig_default b/data/config/MODEConfig_default index 28cd09806b..a1cbc04dc1 100644 --- a/data/config/MODEConfig_default +++ b/data/config/MODEConfig_default @@ -243,6 +243,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/MODEMultivarConfig_default b/data/config/MODEMultivarConfig_default index bd50ef6372..96aef72242 100644 --- a/data/config/MODEMultivarConfig_default +++ b/data/config/MODEMultivarConfig_default @@ -263,6 +263,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/MTDConfig_default b/data/config/MTDConfig_default index 62a180c283..9a62940a87 100644 --- a/data/config/MTDConfig_default +++ b/data/config/MTDConfig_default @@ -232,6 +232,6 @@ txt_output = { output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/Madis2NcConfig_default b/data/config/Madis2NcConfig_default index b795fc6999..dd5d1190fe 100644 --- a/data/config/Madis2NcConfig_default +++ b/data/config/Madis2NcConfig_default @@ -63,4 +63,4 @@ time_summary = { // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V12.1.0"; +version = "V12.2.0"; diff --git a/data/config/PB2NCConfig_default b/data/config/PB2NCConfig_default index 06eac3b594..f820afffae 100644 --- a/data/config/PB2NCConfig_default +++ b/data/config/PB2NCConfig_default @@ -156,6 +156,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/PlotPointObsConfig_default b/data/config/PlotPointObsConfig_default index 4d0458fee7..371ad76f95 100644 --- a/data/config/PlotPointObsConfig_default +++ b/data/config/PlotPointObsConfig_default @@ -79,6 +79,6 @@ point_data = [ //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/Point2GridConfig_default b/data/config/Point2GridConfig_default index 71bee261e6..0ea11d3afb 100644 --- a/data/config/Point2GridConfig_default +++ b/data/config/Point2GridConfig_default @@ -74,6 +74,6 @@ var_name_map = [ //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/PointStatConfig_default b/data/config/PointStatConfig_default index 3bc6a821a7..5d8d366d1a 100644 --- a/data/config/PointStatConfig_default +++ b/data/config/PointStatConfig_default @@ -328,6 +328,6 @@ point_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/RMWAnalysisConfig_default b/data/config/RMWAnalysisConfig_default index c70f42d205..ecc1bbfe86 100644 --- a/data/config/RMWAnalysisConfig_default +++ b/data/config/RMWAnalysisConfig_default @@ -92,7 +92,7 @@ init_thresh_val = []; //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/STATAnalysisConfig_CBS_Index b/data/config/STATAnalysisConfig_CBS_Index index 4617b63751..28c82e17c1 100644 --- a/data/config/STATAnalysisConfig_CBS_Index +++ b/data/config/STATAnalysisConfig_CBS_Index @@ -140,6 +140,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/STATAnalysisConfig_GO_Index b/data/config/STATAnalysisConfig_GO_Index index dab4254d45..ccfc5db09a 100644 --- a/data/config/STATAnalysisConfig_GO_Index +++ b/data/config/STATAnalysisConfig_GO_Index @@ -148,6 +148,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/STATAnalysisConfig_default b/data/config/STATAnalysisConfig_default index 69539b5f3e..63b3eb218f 100644 --- a/data/config/STATAnalysisConfig_default +++ b/data/config/STATAnalysisConfig_default @@ -118,6 +118,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/SeriesAnalysisConfig_default b/data/config/SeriesAnalysisConfig_default index 0b1c2314f8..fb02ba1642 100644 --- a/data/config/SeriesAnalysisConfig_default +++ b/data/config/SeriesAnalysisConfig_default @@ -176,6 +176,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/TCDiagConfig_default b/data/config/TCDiagConfig_default index 82331d4f50..31065923b9 100644 --- a/data/config/TCDiagConfig_default +++ b/data/config/TCDiagConfig_default @@ -151,6 +151,6 @@ output_base_format = "s{storm_id}_{technique}_doper_{init_ymdh}"; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/TCGenConfig_default b/data/config/TCGenConfig_default index 8d95b08fec..5032f79421 100644 --- a/data/config/TCGenConfig_default +++ b/data/config/TCGenConfig_default @@ -291,4 +291,4 @@ nc_pairs_grid = "G003"; // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V12.1.0"; +version = "V12.2.0"; diff --git a/data/config/TCPairsConfig_default b/data/config/TCPairsConfig_default index 38b6765b42..593f215748 100644 --- a/data/config/TCPairsConfig_default +++ b/data/config/TCPairsConfig_default @@ -214,4 +214,4 @@ basin_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V12.1.0"; +version = "V12.2.0"; diff --git a/data/config/TCRMWConfig_default b/data/config/TCRMWConfig_default index 07d895a402..c02684c97e 100644 --- a/data/config/TCRMWConfig_default +++ b/data/config/TCRMWConfig_default @@ -114,6 +114,6 @@ radial_velocity_long_field_name = "Radial Velocity"; //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/TCStatConfig_default b/data/config/TCStatConfig_default index 480386b6eb..4d6bacd851 100644 --- a/data/config/TCStatConfig_default +++ b/data/config/TCStatConfig_default @@ -216,4 +216,4 @@ jobs = []; // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V12.1.0"; +version = "V12.2.0"; diff --git a/data/config/UGridConfig_lfric b/data/config/UGridConfig_lfric index a8bef18b7c..5b21e053c5 100644 --- a/data/config/UGridConfig_lfric +++ b/data/config/UGridConfig_lfric @@ -23,6 +23,6 @@ ugrid_metadata_map = [ //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/UGridConfig_lfric_pressure_levels b/data/config/UGridConfig_lfric_pressure_levels index 5f62792106..dd207e25e5 100644 --- a/data/config/UGridConfig_lfric_pressure_levels +++ b/data/config/UGridConfig_lfric_pressure_levels @@ -32,6 +32,6 @@ ugrid_max_distance_km = 30; //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/UGridConfig_mpas b/data/config/UGridConfig_mpas index 927f6b8719..d8cb8d9aca 100644 --- a/data/config/UGridConfig_mpas +++ b/data/config/UGridConfig_mpas @@ -23,6 +23,6 @@ ugrid_metadata_map = [ //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/WaveletStatConfig_default b/data/config/WaveletStatConfig_default index 9e42617bcf..68ee5df3fe 100644 --- a/data/config/WaveletStatConfig_default +++ b/data/config/WaveletStatConfig_default @@ -138,6 +138,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/docs/Users_Guide/installation.rst b/docs/Users_Guide/installation.rst index 05232de1d1..6b785f0b65 100644 --- a/docs/Users_Guide/installation.rst +++ b/docs/Users_Guide/installation.rst @@ -110,9 +110,9 @@ format from GitHub, which the script will then install. To begin, create and change to a directory where the latest version of MET will be installed. Assuming that the following guidance uses “/d1” as the parent directory, a suggested format is a path to a “met” directory, followed by the version number -subdirectory (e.g. */d1/met/12.0.0*). +subdirectory (e.g. /d1/met/12.2.0). Next, download the -`compile_MET_all.sh `_ +`compile_MET_all.sh `_ script and `tar_files.tgz `_ file and place both of these files in the @@ -122,7 +122,7 @@ the terminal while in the directory MET will be installed in: .. code-block:: ini - wget https://raw.githubusercontent.com/dtcenter/MET/main_v12.0/internal/scripts/installation/compile_MET_all.sh + wget https://raw.githubusercontent.com/dtcenter/MET/main_v12.2/internal/scripts/installation/compile_MET_all.sh wget https://dtcenter.ucar.edu/dfiles/code/METplus/MET/installation/tar_files.tgz The tar files will need to be extracted in the MET installation directory: @@ -144,7 +144,7 @@ Now change directories to the one that was created from expanding the tar files: cd tar_files The next step will be to identify and download the latest MET release as a -tar file (e.g. **v12.0.0.tar.gz**) and place it in +tar file (e.g. v12.2.0.tar.gz) and place it in the *tar_files* directory. The file is available from the MET line under the “RECOMMENDED - COMPONENTS” section on the `METplus website `_ or @@ -152,7 +152,7 @@ by using a wget command while in the *tar_files* directory: .. code-block:: ini - wget https://github.com/dtcenter/MET/archive/refs/tags/v12.0.0.tar.gz + wget https://github.com/dtcenter/MET/archive/refs/tags/v12.2.0.tar.gz .. _Install_Required-libraries-and: @@ -174,7 +174,7 @@ environment variables is in an environment configuration file configuration file to start with (**install_met_env.generic_gnu**), as well as the environment configuration files used on HPCs at NCAR and NOAA, can be found in the `MET GitHub repository `_ in the -`scripts/installation/config `_ +`scripts/installation/config `_ directory. .. note:: Starting with MET-12.0.0, C++17 is the default C++ standard for MET due to the requirements of its dependent libraries. However, MET itself only makes use of C++11 features. @@ -195,7 +195,7 @@ Environment Variable Descriptions .. dropdown:: REQUIRED - **TEST_BASE** – Format is */d1/met/12.0.0*. This is the MET + **TEST_BASE** – Format is */d1/met/12.2.0*. This is the MET installation directory that was created the beginning of, :numref:`compile_script_install` and contains the **compile_MET_all.sh** script, **tar_files.tgz**, @@ -210,11 +210,11 @@ Environment Variable Descriptions provided for the PGI family of compilers through “pgi”. However, this compiler option is no longer actively tested. - **MET_SUBDIR** – Format is */d1/met/12.0.0*. This is the location where the top-level MET + **MET_SUBDIR** – Format is */d1/met/12.2.0*. This is the location where the top-level MET subdirectory will be installed and is often set equivalent to **TEST_BASE** (e.g. ${TEST_BASE}). - **MET_TARBALL** – Format is *v12.0.0.tar.gz*. This is the name of the downloaded MET tarball. + **MET_TARBALL** – Format is *v12.2.0.tar.gz*. This is the name of the downloaded MET tarball. **USE_MODULES** – Format is *TRUE* or *FALSE*. Set to FALSE if using a machine that does not use modulefiles; set to TRUE if using a machine that does use modulefiles. For more information on @@ -424,10 +424,10 @@ this step on the machine ‘hera’. .. code-block:: ini - /contrib/met/12.0.0$ ls + /contrib/met/12.2.0$ ls compile_MET_all.sh install_met_env.hera tar_files - /contrib/met/12.0.0$ ls tar_files + /contrib/met/12.2.0$ ls tar_files HDF-EOS2.16v1.00.tar.Z eckit-1.24.4.tar.gz netcdf-4.7.4.tar.gz HDF4.2r3.tar.gz freetype-2.11.0.tar.gz netcdf-cxx4-4.3.1.tar.gz atlas-0.30.0.tar.gz g2clib-1.6.4.tar.gz pixman-0.40.0.tar.gz @@ -448,14 +448,14 @@ The screenshot below shows the contents of the installation directory after inst .. code-block:: ini - /contrib/met/12.0.0$ ls - MET-12.0.0 bin compile_MET_all.sh external_libs install_met_env.hera share tar_files + /contrib/met/12.2.0$ ls + MET-12.2.0 bin compile_MET_all.sh external_libs install_met_env.hera share tar_files To confirm that MET was installed successfully, run the following command from the installation directory to check for errors in the test file: .. code-block:: ini - grep -i error MET-12.0.0/met.make_test.log + grep -i error MET-12.2.0/met.make_test.log If no errors are returned, the installation was successful. Due to the highly variable nature of hardware systems, users may encounter issues during @@ -513,7 +513,7 @@ MET version number, for example: .. code-block:: ini - docker pull dtcenter/met:12.0.0 + docker pull dtcenter/met:12.2.0 Omitting the version number will result in an error due to Docker’s behavior @@ -539,7 +539,7 @@ the same way the latest image of MET was pulled: .. code-block:: ini - docker run -it --rm dtcenter/met:12.0.0 /bin/bash + docker run -it --rm dtcenter/met:12.2.0 /bin/bash If the usage MET via Docker images was successful, it is highly recommended to move on @@ -588,7 +588,7 @@ to make the container: .. code-block:: ini - singularity build met-12.0.0.sif docker://dtcenter/met:12.0.0 + singularity build met-12.2.0.sif docker://dtcenter/met:12.2.0 Running the MET Container ------------------------- @@ -599,7 +599,7 @@ MET command line usage: .. code-block:: ini - singularity exec met-12.0.0.sif plot_data_plane /home/data/fcst_006.grb2 image_output.ps ‘name=”TMP”; level=”Z0”;’ + singularity exec met-12.2.0.sif plot_data_plane /home/data/fcst_006.grb2 image_output.ps ‘name=”TMP”; level=”Z0”;’ Stopping the Apptainer Instance ------------------------------- @@ -610,7 +610,7 @@ be used otherwise the instance will continue to run in the background: .. code-block:: ini - singularity instance stop /path/to/container/met-12.0.0.sif met-12.0.0 + singularity instance stop /path/to/container/met-12.2.0.sif met-12.2.0 Now that MET is successfully installed, it is highly recommended to next install the METplus wrappers to take full advantage of diff --git a/docs/Users_Guide/release-notes.rst b/docs/Users_Guide/release-notes.rst index fd99f5fc54..287fd2a477 100644 --- a/docs/Users_Guide/release-notes.rst +++ b/docs/Users_Guide/release-notes.rst @@ -9,34 +9,8 @@ When applicable, release notes are followed by the GitHub issue number which des enhancement, or new feature (`MET GitHub issues `_). Important issues are listed **in bold** for emphasis. -MET Version 12.2.0-rc2 Release Notes (20251029) ------------------------------------------------ - - .. dropdown:: Enhancements - - * Refine default lapse rates for orographic corrections - (`#3258 `_). - * Refine handling of missing data for orographic corrections - (`#3270 `_). - * Enhance the MET tools to return consistent exit codes - (`#3278 `_). - - .. dropdown:: Bugfixes - - * Update the logic to apply "set_attr_grid" before "ShiftRight" - (`#3255 `_). - * Fix ASCII2NC hang when run with an empty input file - (`#3266 `_). - - .. dropdown:: Repository, build, and test - - * Confirm that the METplus difference logic handles MTD output file - (`#977 `_). - * Enhance the "Create Release Docker Images" METplus workflows to determine and build the most recent bugfix versions - (`METplus-Internal#64 `_). - -MET Version 12.2.0-rc1 Release Notes (20250926) ------------------------------------------------ +MET Version 12.2.0 Release Notes (20251113) +------------------------------------------- .. dropdown:: Enhancements @@ -58,6 +32,12 @@ MET Version 12.2.0-rc1 Release Notes (20250926) (`#3226 `_). * Add new pre-defined grid definitions to support the computation of CBS scores (`#3232 `_). + * Refine default lapse rates for orographic corrections + (`#3258 `_). + * Refine handling of missing data for orographic corrections + (`#3270 `_). + * Enhance the MET tools to return consistent exit codes + (`#3278 `_). .. dropdown:: Bugfixes @@ -71,9 +51,15 @@ MET Version 12.2.0-rc1 Release Notes (20250926) (`#3219 `_). * Bugfix: Fix segfault when reading climatological data from a CF-compliant NetCDF file fails (`#3235 `_). + * Update the logic to apply "set_attr_grid" before "ShiftRight" + (`#3255 `_). + * Fix ASCII2NC hang when run with an empty input file + (`#3266 `_). .. dropdown:: Repository, build, and test + * Confirm that the METplus difference logic handles MTD output file + (`#977 `_). * Switch MET's R-based differencing logic over to using the Python-based METplus implementation (`#2718 `_). @@ -85,6 +71,8 @@ MET Version 12.2.0-rc1 Release Notes (20250926) (`METbaseimage#33 `_). * METbaseimage: Address Critical CVEs from Grype scans of the Docker images (`METplus-Internal#61 `_). + * Enhance the "Create Release Docker Images" METplus workflows to determine and build the most recent bugfix versions + (`METplus-Internal#64 `_). MET Upgrade Instructions ======================== diff --git a/docs/conf.py b/docs/conf.py index 2f281598e0..c1220f61ca 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,11 +20,11 @@ project = 'MET' author = 'UCAR/NCAR, NOAA, CSU/CIRA, and CU/CIRES' author_list = 'Soh, H., L. Goodrich, B. Brown, R. Bullock, J. Halley Gotway, K. Newman, J. Opatz, T. Jensen, J. Prestopnik' -version = '12.2.0-rc2' +version = '12.2.0' verinfo = version release = f'{version}' release_year = '2025' -release_date = f'{release_year}-10-29' +release_date = f'{release_year}-11-13' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- diff --git a/scripts/config/EnsembleStatConfig b/scripts/config/EnsembleStatConfig index 5067f1b8d4..6e1fc1c8bc 100644 --- a/scripts/config/EnsembleStatConfig +++ b/scripts/config/EnsembleStatConfig @@ -332,6 +332,6 @@ grid_weight_flag = NONE; point_weight_flag = NONE; output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/GenEnsProdConfig b/scripts/config/GenEnsProdConfig index d61eb1dbe4..29d3342ae6 100644 --- a/scripts/config/GenEnsProdConfig +++ b/scripts/config/GenEnsProdConfig @@ -157,6 +157,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/GridStatConfig_APCP_12 b/scripts/config/GridStatConfig_APCP_12 index c38d7b8ab3..28b934ec27 100644 --- a/scripts/config/GridStatConfig_APCP_12 +++ b/scripts/config/GridStatConfig_APCP_12 @@ -220,6 +220,6 @@ grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "APCP_12"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/GridStatConfig_APCP_24 b/scripts/config/GridStatConfig_APCP_24 index b7d980d85e..7ee54a0202 100644 --- a/scripts/config/GridStatConfig_APCP_24 +++ b/scripts/config/GridStatConfig_APCP_24 @@ -230,6 +230,6 @@ grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "APCP_24"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/GridStatConfig_POP_12 b/scripts/config/GridStatConfig_POP_12 index f0719b57fc..e6d77c04ee 100644 --- a/scripts/config/GridStatConfig_POP_12 +++ b/scripts/config/GridStatConfig_POP_12 @@ -229,6 +229,6 @@ grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "POP_12"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/GridStatConfig_all b/scripts/config/GridStatConfig_all index 9e1ca021d5..f1b5cc74e5 100644 --- a/scripts/config/GridStatConfig_all +++ b/scripts/config/GridStatConfig_all @@ -260,6 +260,6 @@ grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/MODEAnalysisConfig b/scripts/config/MODEAnalysisConfig index 894a9ee1c7..8aa4b30a08 100644 --- a/scripts/config/MODEAnalysisConfig +++ b/scripts/config/MODEAnalysisConfig @@ -186,6 +186,6 @@ simple = TRUE; //////////////////////////////////////////////////////////////////////////////// -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/MODEConfig_APCP_12 b/scripts/config/MODEConfig_APCP_12 index 76dc5f6f9a..3f2faeb98b 100644 --- a/scripts/config/MODEConfig_APCP_12 +++ b/scripts/config/MODEConfig_APCP_12 @@ -240,6 +240,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/MODEConfig_APCP_24 b/scripts/config/MODEConfig_APCP_24 index 15c85227a0..dc49072657 100644 --- a/scripts/config/MODEConfig_APCP_24 +++ b/scripts/config/MODEConfig_APCP_24 @@ -246,6 +246,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/MODEConfig_RH b/scripts/config/MODEConfig_RH index bb98b530ea..117e3eb253 100644 --- a/scripts/config/MODEConfig_RH +++ b/scripts/config/MODEConfig_RH @@ -242,6 +242,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/PB2NCConfig_G212 b/scripts/config/PB2NCConfig_G212 index 1e44fcd4ff..394bd2613a 100644 --- a/scripts/config/PB2NCConfig_G212 +++ b/scripts/config/PB2NCConfig_G212 @@ -94,6 +94,6 @@ event_stack_flag = TOP; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/PointStatConfig b/scripts/config/PointStatConfig index bc49f32b32..bcbaef932f 100644 --- a/scripts/config/PointStatConfig +++ b/scripts/config/PointStatConfig @@ -270,6 +270,6 @@ point_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/STATAnalysisConfig b/scripts/config/STATAnalysisConfig index 9fcb9da02d..59adc01223 100644 --- a/scripts/config/STATAnalysisConfig +++ b/scripts/config/STATAnalysisConfig @@ -109,6 +109,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/WaveletStatConfig_APCP_12 b/scripts/config/WaveletStatConfig_APCP_12 index a0491ef2b8..8349dfcbe1 100644 --- a/scripts/config/WaveletStatConfig_APCP_12 +++ b/scripts/config/WaveletStatConfig_APCP_12 @@ -144,6 +144,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/config/WaveletStatConfig_APCP_12_NC b/scripts/config/WaveletStatConfig_APCP_12_NC index cd1d5458d8..5cc82dcde7 100644 --- a/scripts/config/WaveletStatConfig_APCP_12_NC +++ b/scripts/config/WaveletStatConfig_APCP_12_NC @@ -136,6 +136,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V12.1.0"; +version = "V12.2.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libcode/vx_statistics/pair_base.cc b/src/libcode/vx_statistics/pair_base.cc index 9fc918a11f..60f96b60f8 100644 --- a/src/libcode/vx_statistics/pair_base.cc +++ b/src/libcode/vx_statistics/pair_base.cc @@ -683,7 +683,7 @@ void PairBase::print_obs_summary() const { << "Computed " << obssummary_to_string(obs_summary, obs_perc_value) << " of " << (int) svt.obs.size() << " observations = " << svt.summary_val - << " for [lat:lon:level:elevation] = [" + << " for [lat:lon:level:height] = [" << map_key[i] << "]\n"; // parse and print the point obs information for the current key From 20635cd724254b32b0248890e1ff9c172f90bf08 Mon Sep 17 00:00:00 2001 From: jprestop Date: Wed, 3 Dec 2025 15:34:20 -0700 Subject: [PATCH 12/45] Updating files to refer to 12.2 instead of 12.1 --- internal/scripts/installation/config/install_met_env.acorn | 2 +- internal/scripts/installation/config/install_met_env.cactus | 4 ++-- internal/scripts/installation/config/install_met_env.casper | 4 ++-- internal/scripts/installation/config/install_met_env.derecho | 4 ++-- internal/scripts/installation/config/install_met_env.frontera | 4 ++-- internal/scripts/installation/config/install_met_env.gaea | 4 ++-- .../scripts/installation/config/install_met_env.generic_gnu | 2 +- .../config/install_met_env.generic_intel_non-oneapi | 2 +- .../installation/config/install_met_env.generic_intel_oneapi | 2 +- internal/scripts/installation/config/install_met_env.hera | 4 ++-- internal/scripts/installation/config/install_met_env.hercules | 4 ++-- internal/scripts/installation/config/install_met_env.jet | 4 ++-- internal/scripts/installation/config/install_met_env.narya | 2 +- internal/scripts/installation/config/install_met_env.orion | 4 ++-- .../installation/config/install_met_env.seneca_intel_oneapi | 4 ++-- internal/scripts/installation/config/install_met_env.wcoss2 | 2 +- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.acorn b/internal/scripts/installation/config/install_met_env.acorn index 27ca382783..e67acff76a 100644 --- a/internal/scripts/installation/config/install_met_env.acorn +++ b/internal/scripts/installation/config/install_met_env.acorn @@ -26,7 +26,7 @@ export LIB_DIR=${TEST_BASE}/external_libs export BIN_DIR_PATH=${TEST_BASE}/bin export COMPILER=intel_19.1.3.304 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0-rc1.tar.gz +export MET_TARBALL=v12.2.0-rc1.tar.gz export USE_MODULES=TRUE export ADDTL_DIR=/apps/spack/gettext/0.21/intel/19.1.3.304/at2kdo4edvuhyzrt5g6zhwrdb7bdui4s/lib64 export PYTHON_MODULE=python_3.12.0 diff --git a/internal/scripts/installation/config/install_met_env.cactus b/internal/scripts/installation/config/install_met_env.cactus index b16e81ff93..075d698ddd 100644 --- a/internal/scripts/installation/config/install_met_env.cactus +++ b/internal/scripts/installation/config/install_met_env.cactus @@ -21,11 +21,11 @@ export F77=ifort export F90=ifort export CC=icc export CXX=icpc -export TEST_BASE=/lfs/h2/users/julie.prestopnik/12.1.0 +export TEST_BASE=/lfs/h2/users/julie.prestopnik/12.2.0 export LIB_DIR=${TEST_BASE}/external_libs export COMPILER=intel_19.1.3.304 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export ADDTL_DIR=/apps/spack/gettext/0.21/intel/19.1.3.304/at2kdo4edvuhyzrt5g6zhwrdb7bdui4s/lib64/ export PYTHON_MODULE=python_3.10.4 diff --git a/internal/scripts/installation/config/install_met_env.casper b/internal/scripts/installation/config/install_met_env.casper index 68768b0d7d..a29e4658f7 100644 --- a/internal/scripts/installation/config/install_met_env.casper +++ b/internal/scripts/installation/config/install_met_env.casper @@ -8,10 +8,10 @@ export CXX=`which icpx` export FC=`which ifx` export F77=`which ifx` export F90=`which ifx` -export TEST_BASE=/glade/work/dtcrt/METplus/casper/components/MET/installations/12.1.0 +export TEST_BASE=/glade/work/dtcrt/METplus/casper/components/MET/installations/12.2.0 export COMPILER=intel-oneapi_2024.2.1 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/glade/work/dtcrt/METplus/casper/miniconda/miniconda3/envs/metplus_v6.1_py3.12 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 diff --git a/internal/scripts/installation/config/install_met_env.derecho b/internal/scripts/installation/config/install_met_env.derecho index ace77a1c42..30538b2a7d 100644 --- a/internal/scripts/installation/config/install_met_env.derecho +++ b/internal/scripts/installation/config/install_met_env.derecho @@ -8,10 +8,10 @@ export FC=ifx export F77=ifx export F90=ifx -export TEST_BASE=/glade/work/dtcrt/METplus/derecho/components/MET/installations/12.1.0 +export TEST_BASE=/glade/work/dtcrt/METplus/derecho/components/MET/installations/12.2.0 export COMPILER=intel_2023.2.1 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/glade/work/dtcrt/METplus/derecho/miniconda/miniconda3/envs/metplus_v5.1_py3.10 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 diff --git a/internal/scripts/installation/config/install_met_env.frontera b/internal/scripts/installation/config/install_met_env.frontera index 1c5bc6910b..7b373827e2 100644 --- a/internal/scripts/installation/config/install_met_env.frontera +++ b/internal/scripts/installation/config/install_met_env.frontera @@ -6,10 +6,10 @@ export F90=ifx export CC=icx export CXX=icpx -export TEST_BASE=/work2/06612/tg859120/frontera/MET/12.1.0 +export TEST_BASE=/work2/06612/tg859120/frontera/MET/12.2.0 export COMPILER=intel_23.1.0 export MET_SUBDIR=${TEST_BASE}/ -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/work2/06612/tg859120/frontera/miniconda/miniconda3/envs/metplus_v5.1_py3.10 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 diff --git a/internal/scripts/installation/config/install_met_env.gaea b/internal/scripts/installation/config/install_met_env.gaea index a39125b40b..13755c21f4 100644 --- a/internal/scripts/installation/config/install_met_env.gaea +++ b/internal/scripts/installation/config/install_met_env.gaea @@ -14,10 +14,10 @@ export F90=ifort export CC=icc export CXX=icpc -export TEST_BASE=/usw/met/12.1.0 +export TEST_BASE=/usw/met/12.2.0 export COMPILER=intel_2023.2.0 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/ export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 diff --git a/internal/scripts/installation/config/install_met_env.generic_gnu b/internal/scripts/installation/config/install_met_env.generic_gnu index 0821d2d98c..9df96bd078 100644 --- a/internal/scripts/installation/config/install_met_env.generic_gnu +++ b/internal/scripts/installation/config/install_met_env.generic_gnu @@ -18,7 +18,7 @@ export MET_SUBDIR=${TEST_BASE} # Required # The name of the met tarbal usually downloaded with version from dtcenter.org and includes a version # example - v11.1.0.tar.gz -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz # Required # Specify if machine useds modules for loading software diff --git a/internal/scripts/installation/config/install_met_env.generic_intel_non-oneapi b/internal/scripts/installation/config/install_met_env.generic_intel_non-oneapi index c8b44a3673..481ce121ab 100644 --- a/internal/scripts/installation/config/install_met_env.generic_intel_non-oneapi +++ b/internal/scripts/installation/config/install_met_env.generic_intel_non-oneapi @@ -25,7 +25,7 @@ export MET_SUBDIR=${TEST_BASE} # Required # The name of the met tarbal usually downloaded with version from dtcenter.org and includes a version # example - v11.1.0.tar.gz -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz # Required # Specify if machine useds modules for loading software diff --git a/internal/scripts/installation/config/install_met_env.generic_intel_oneapi b/internal/scripts/installation/config/install_met_env.generic_intel_oneapi index 024c057e57..db9c096981 100644 --- a/internal/scripts/installation/config/install_met_env.generic_intel_oneapi +++ b/internal/scripts/installation/config/install_met_env.generic_intel_oneapi @@ -25,7 +25,7 @@ export MET_SUBDIR=${TEST_BASE} # Required # The name of the met tarbal usually downloaded with version from dtcenter.org and includes a version # example - v12.0.0.tar.gz -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz # Required # Specify if machine useds modules for loading software diff --git a/internal/scripts/installation/config/install_met_env.hera b/internal/scripts/installation/config/install_met_env.hera index 50bb58da47..c8c3aa75df 100644 --- a/internal/scripts/installation/config/install_met_env.hera +++ b/internal/scripts/installation/config/install_met_env.hera @@ -7,10 +7,10 @@ export F90=ifx export CC=icx export CXX=icpx export PATH=/scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin:${PATH} -export TEST_BASE=/contrib/met/12.1.0 +export TEST_BASE=/contrib/met/12.2.0 export COMPILER=intel_2024.2.1 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 diff --git a/internal/scripts/installation/config/install_met_env.hercules b/internal/scripts/installation/config/install_met_env.hercules index e9fcb8f2bc..b0c1fc97c8 100644 --- a/internal/scripts/installation/config/install_met_env.hercules +++ b/internal/scripts/installation/config/install_met_env.hercules @@ -7,10 +7,10 @@ export FC=ifx export F77=ifx export F90=ifx -export TEST_BASE=/apps/contrib/MET/12.1.0 +export TEST_BASE=/apps/contrib/MET/12.2.0 export COMPILER=intel-oneapi-compilers_2022.2.1 export MET_SUBDIR=${TEST_BASE}/ -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 diff --git a/internal/scripts/installation/config/install_met_env.jet b/internal/scripts/installation/config/install_met_env.jet index 3e375fd194..f8aae9bcca 100644 --- a/internal/scripts/installation/config/install_met_env.jet +++ b/internal/scripts/installation/config/install_met_env.jet @@ -6,10 +6,10 @@ export F77=ifx export F90=ifx export CC=icx export CXX=icpx -export TEST_BASE=/contrib/met/12.1.0 +export TEST_BASE=/contrib/met/12.2.0 export COMPILER=intel_2022.1.2 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/mnt/lfs6/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 diff --git a/internal/scripts/installation/config/install_met_env.narya b/internal/scripts/installation/config/install_met_env.narya index 5b86d81e9b..e66b4b2ddc 100644 --- a/internal/scripts/installation/config/install_met_env.narya +++ b/internal/scripts/installation/config/install_met_env.narya @@ -1,7 +1,7 @@ export TEST_BASE=/Volumes/d1/jpresto/projects/MET/MET_installation/11.1.0 export COMPILER=gnu_12.3.0 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=FALSE export MET_PYTHON=/opt/local export MET_PYTHON_CC=-I${MET_PYTHON}/Library/Frameworks/Python.framework/Versions/3.10/include/python3.10 diff --git a/internal/scripts/installation/config/install_met_env.orion b/internal/scripts/installation/config/install_met_env.orion index c1924e420a..daaff64886 100644 --- a/internal/scripts/installation/config/install_met_env.orion +++ b/internal/scripts/installation/config/install_met_env.orion @@ -7,10 +7,10 @@ export FC=ifx export F77=ifx export F90=ifx -export TEST_BASE=/apps/contrib/MET/12.1.0 +export TEST_BASE=/apps/contrib/MET/12.2.0 export COMPILER=intel-oneapi-compilers_2024.1.0 export MET_SUBDIR=${TEST_BASE}/ -export MET_TARBALL=v12.1.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.12 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 diff --git a/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi b/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi index c1a1a1803c..4997af8125 100644 --- a/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi +++ b/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi @@ -27,8 +27,8 @@ export MET_SUBDIR=${TEST_BASE} # Required # The name of the met tarbal usually downloaded with version from dtcenter.org and includes a version -# example - v12.1.0.tar.gz -export MET_TARBALL=v12.1.0.tar.gz +# example - v12.2.0.tar.gz +export MET_TARBALL=v12.2.0.tar.gz # Required # Specify if machine useds modules for loading software diff --git a/internal/scripts/installation/config/install_met_env.wcoss2 b/internal/scripts/installation/config/install_met_env.wcoss2 index 27ca382783..e67acff76a 100644 --- a/internal/scripts/installation/config/install_met_env.wcoss2 +++ b/internal/scripts/installation/config/install_met_env.wcoss2 @@ -26,7 +26,7 @@ export LIB_DIR=${TEST_BASE}/external_libs export BIN_DIR_PATH=${TEST_BASE}/bin export COMPILER=intel_19.1.3.304 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.1.0-rc1.tar.gz +export MET_TARBALL=v12.2.0-rc1.tar.gz export USE_MODULES=TRUE export ADDTL_DIR=/apps/spack/gettext/0.21/intel/19.1.3.304/at2kdo4edvuhyzrt5g6zhwrdb7bdui4s/lib64 export PYTHON_MODULE=python_3.12.0 From 7b90f2f7c2445b3e25bebeb7dd83a74809fba1b0 Mon Sep 17 00:00:00 2001 From: jprestop Date: Wed, 3 Dec 2025 15:37:04 -0700 Subject: [PATCH 13/45] Updating files to refer to 12.2 instead of 12.1 --- .../modulefiles/12.2.0.lua_wcoss2 | 27 +++++++++++++ .../installation/modulefiles/12.2.0_acorn | 38 +++++++++++++++++++ .../installation/modulefiles/12.2.0_casper | 26 +++++++++++++ .../installation/modulefiles/12.2.0_gaea | 20 ++++++++++ .../installation/modulefiles/12.2.0_hera | 21 ++++++++++ .../installation/modulefiles/12.2.0_hercules | 20 ++++++++++ .../installation/modulefiles/12.2.0_jet | 20 ++++++++++ .../installation/modulefiles/12.2.0_orion | 19 ++++++++++ 8 files changed, 191 insertions(+) create mode 100644 internal/scripts/installation/modulefiles/12.2.0.lua_wcoss2 create mode 100644 internal/scripts/installation/modulefiles/12.2.0_acorn create mode 100644 internal/scripts/installation/modulefiles/12.2.0_casper create mode 100644 internal/scripts/installation/modulefiles/12.2.0_gaea create mode 100644 internal/scripts/installation/modulefiles/12.2.0_hera create mode 100644 internal/scripts/installation/modulefiles/12.2.0_hercules create mode 100644 internal/scripts/installation/modulefiles/12.2.0_jet create mode 100644 internal/scripts/installation/modulefiles/12.2.0_orion diff --git a/internal/scripts/installation/modulefiles/12.2.0.lua_wcoss2 b/internal/scripts/installation/modulefiles/12.2.0.lua_wcoss2 new file mode 100644 index 0000000000..f6f41f3289 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0.lua_wcoss2 @@ -0,0 +1,27 @@ +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,"bin")) + +setenv("MET_ROOT", base) +setenv("MET_BASE", pathJoin(base, "share", "met")) +setenv("MET_VERSION", pkgVersion) + +whatis("Name: ".. pkgName) +whatis("Version: " .. pkgVersion) +whatis("Category: applications") +whatis("Description: Model Evaluation Tools (MET)") + diff --git a/internal/scripts/installation/modulefiles/12.2.0_acorn b/internal/scripts/installation/modulefiles/12.2.0_acorn new file mode 100644 index 0000000000..edbdb5e9eb --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_acorn @@ -0,0 +1,38 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +# The intel compiler is required to run MET + +module use /apps/ops/para/libs/modulefiles/compiler/intel/19.1.3.304/ +module load intel +module use /apps/dev/modulefiles/ +module load ve/evs/2.0_py312 +module load netcdf/4.7.4 +module load hdf5/1.10.6 +module load bufr/11.6.0 +module load zlib/1.2.11 +module load jasper/2.0.25 +module load libpng/1.6.37 +module load gsl/2.7 +module load g2c/1.6.4 +module load proj/7.1.0 +module use /apps/dev/lmodules/intel/19.1.3.304/ +module load atlas/0.35.0 +module load eckit/1.24.4 + +set base /apps/sw_review/emc/MET/12.2.0 +set ver 12.2.0 +set share $base/share/met +set lib_base $base + +prepend-path PATH $base/bin + +setenv METversion V$ver +setenv MET_ROOT $base +#setenv MET_PYTHON_EXE /apps/dev/ve/evs/2.0/bin/python diff --git a/internal/scripts/installation/modulefiles/12.2.0_casper b/internal/scripts/installation/modulefiles/12.2.0_casper new file mode 100644 index 0000000000..a2d7798a50 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_casper @@ -0,0 +1,26 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + + +# The intel compiler is required to run MET + +module load ncarenv/24.12 +module load intel/2024.2.1 +module load cmake/3.31.0 +module load proj/9.2.1 + +set base /glade/work/dtcrt/METplus/casper/components/MET/installations/12.2.0 +set ver 12.2.0 +set share $base/share/met + +prepend-path PATH $base/bin:/glade/work/dtcrt/METplus/casper/components/MET/installations/12.2.0/external_libs/bin:/glade/work/dtcrt/METplus/casper/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin + +setenv METversion V$ver + + diff --git a/internal/scripts/installation/modulefiles/12.2.0_gaea b/internal/scripts/installation/modulefiles/12.2.0_gaea new file mode 100644 index 0000000000..cff8bb11f9 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_gaea @@ -0,0 +1,20 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +module unload cray-libsci/24.07.0 +module load intel/2023.2.0 + +set base /usw/met +set ver 12.2.0 +set share $base/$ver/share/met +set lib_base $base/12.2.0 + +prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin + +setenv MET_PYTHON_EXE /gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python diff --git a/internal/scripts/installation/modulefiles/12.2.0_hera b/internal/scripts/installation/modulefiles/12.2.0_hera new file mode 100644 index 0000000000..255011f841 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_hera @@ -0,0 +1,21 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +# The intel compiler is required to run MET +prereq intel/2024.2.1 + +set base /contrib/met +set ver 12.2.0 +set share $base/$ver/share/met +set lib_base $base/12.2.0 +setenv MET_ROOT $base/$ver + +prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin + +setenv MET_PYTHON_EXE /scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python diff --git a/internal/scripts/installation/modulefiles/12.2.0_hercules b/internal/scripts/installation/modulefiles/12.2.0_hercules new file mode 100644 index 0000000000..fec78413e4 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_hercules @@ -0,0 +1,20 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +prereq intel-oneapi-compilers/2022.2.1 + +set base /apps/contrib/MET +set ver 12.2.0 +set share $base/$ver/share/met +set lib_base $base/12.2.0 +setenv MET_ROOT $base/$ver/MET-12.2.0 + +prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin + +setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python diff --git a/internal/scripts/installation/modulefiles/12.2.0_jet b/internal/scripts/installation/modulefiles/12.2.0_jet new file mode 100644 index 0000000000..d8318ef7d5 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_jet @@ -0,0 +1,20 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +prereq intel/2024.2.1 + +set base /contrib/met/12.2.0 +set ver 12.2.0 +set share $base/share/met +setenv MET_ROOT $base/$ver/MET-12.2.0 + +prepend-path PATH $base/bin:$base/external_libs/bin:/mnt/lfs6/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin + +setenv MET_PYTHON_EXE /mnt/lfs5/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python + diff --git a/internal/scripts/installation/modulefiles/12.2.0_orion b/internal/scripts/installation/modulefiles/12.2.0_orion new file mode 100644 index 0000000000..b432ee6cd8 --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_orion @@ -0,0 +1,19 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +prereq intel-oneapi-compilers/2024.1.0 + +set base /apps/contrib/MET +set ver 12.2.0 +set share $base/$ver/share/met +setenv MET_ROOT $base/$ver + +prepend-path PATH $base/$ver/bin:$base/$ver/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin + +setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python From a3915d37c7d77d59b8ae90c092ad28a231abca3e Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Thu, 4 Dec 2025 09:46:06 -0700 Subject: [PATCH 14/45] Update Python environment variables for METplus v6.2 --- .../scripts/installation/config/install_met_env.hercules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.hercules b/internal/scripts/installation/config/install_met_env.hercules index b0c1fc97c8..ec7c3d7e29 100644 --- a/internal/scripts/installation/config/install_met_env.hercules +++ b/internal/scripts/installation/config/install_met_env.hercules @@ -12,9 +12,9 @@ export COMPILER=intel-oneapi-compilers_2022.2.1 export MET_SUBDIR=${TEST_BASE}/ export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE -export MET_PYTHON=/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10 -export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 -export MET_PYTHON_LD=-L${MET_PYTHON}/lib/python3.10/config-3.10-x86_64-linux-gnu\ -L${MET_PYTHON}/lib\ -lpython3.10\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm\ -lm +export MET_PYTHON=/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12 +export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 +export MET_PYTHON_LD=-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gnu\ -L${MET_PYTHON}/lib\ -lpython3.12\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm\ -lm export EXTERNAL_LIBS=${TEST_BASE}/external_libs COMPILE_ATLAS=1 COMPILE_ECKIT=1 From a405a7747f7ef8b3b0623d259728d0d5a198afd5 Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Thu, 4 Dec 2025 11:26:43 -0700 Subject: [PATCH 15/45] Update Python environment paths for MET 12.2.0 --- internal/scripts/installation/modulefiles/12.2.0_hercules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/scripts/installation/modulefiles/12.2.0_hercules b/internal/scripts/installation/modulefiles/12.2.0_hercules index fec78413e4..08486d708f 100644 --- a/internal/scripts/installation/modulefiles/12.2.0_hercules +++ b/internal/scripts/installation/modulefiles/12.2.0_hercules @@ -15,6 +15,6 @@ set share $base/$ver/share/met set lib_base $base/12.2.0 setenv MET_ROOT $base/$ver/MET-12.2.0 -prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin +prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin -setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python +#setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python From 189692cf5f9c092c7e0eff48188488fe7ad5b628 Mon Sep 17 00:00:00 2001 From: jprestop Date: Fri, 5 Dec 2025 19:19:31 -0700 Subject: [PATCH 16/45] Update typo in Python conda env --- .../installation/config/install_met_env.orion | 2 +- .../modulefiles/12.1.0.lua_wcoss2 | 27 ------------- .../installation/modulefiles/12.1.0_acorn | 38 ------------------- .../installation/modulefiles/12.1.0_casper | 26 ------------- .../installation/modulefiles/12.1.0_derecho | 22 ----------- .../installation/modulefiles/12.1.0_gaea | 20 ---------- .../installation/modulefiles/12.1.0_hera | 21 ---------- .../installation/modulefiles/12.1.0_hercules | 20 ---------- .../installation/modulefiles/12.1.0_jet | 20 ---------- .../installation/modulefiles/12.1.0_orion | 19 ---------- 10 files changed, 1 insertion(+), 214 deletions(-) delete mode 100644 internal/scripts/installation/modulefiles/12.1.0.lua_wcoss2 delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_acorn delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_casper delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_derecho delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_gaea delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_hera delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_hercules delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_jet delete mode 100644 internal/scripts/installation/modulefiles/12.1.0_orion diff --git a/internal/scripts/installation/config/install_met_env.orion b/internal/scripts/installation/config/install_met_env.orion index daaff64886..95482bc3a6 100644 --- a/internal/scripts/installation/config/install_met_env.orion +++ b/internal/scripts/installation/config/install_met_env.orion @@ -12,7 +12,7 @@ export COMPILER=intel-oneapi-compilers_2024.1.0 export MET_SUBDIR=${TEST_BASE}/ export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE -export MET_PYTHON=/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.12 +export MET_PYTHON=/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 export MET_PYTHON_LD=-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gnu\ -L${MET_PYTHON}/lib\ -lpython3.12\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm\ -lm #export ADDTL_DIR=/usr/lib64 diff --git a/internal/scripts/installation/modulefiles/12.1.0.lua_wcoss2 b/internal/scripts/installation/modulefiles/12.1.0.lua_wcoss2 deleted file mode 100644 index f6f41f3289..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0.lua_wcoss2 +++ /dev/null @@ -1,27 +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,"bin")) - -setenv("MET_ROOT", base) -setenv("MET_BASE", pathJoin(base, "share", "met")) -setenv("MET_VERSION", pkgVersion) - -whatis("Name: ".. pkgName) -whatis("Version: " .. pkgVersion) -whatis("Category: applications") -whatis("Description: Model Evaluation Tools (MET)") - diff --git a/internal/scripts/installation/modulefiles/12.1.0_acorn b/internal/scripts/installation/modulefiles/12.1.0_acorn deleted file mode 100644 index b1a99bdb35..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_acorn +++ /dev/null @@ -1,38 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -# The intel compiler is required to run MET - -module use /apps/ops/para/libs/modulefiles/compiler/intel/19.1.3.304/ -module load intel -module use /apps/dev/modulefiles/ -module load ve/evs/2.0_py312 -module load netcdf/4.7.4 -module load hdf5/1.10.6 -module load bufr/11.6.0 -module load zlib/1.2.11 -module load jasper/2.0.25 -module load libpng/1.6.37 -module load gsl/2.7 -module load g2c/1.6.4 -module load proj/7.1.0 -module use /apps/dev/lmodules/intel/19.1.3.304/ -module load atlas/0.35.0 -module load eckit/1.24.4 - -set base /apps/sw_review/emc/MET/12.1.0 -set ver 12.1.0 -set share $base/share/met -set lib_base $base - -prepend-path PATH $base/bin - -setenv METversion V$ver -setenv MET_ROOT $base -#setenv MET_PYTHON_EXE /apps/dev/ve/evs/2.0/bin/python diff --git a/internal/scripts/installation/modulefiles/12.1.0_casper b/internal/scripts/installation/modulefiles/12.1.0_casper deleted file mode 100644 index e15d843217..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_casper +++ /dev/null @@ -1,26 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - - -# The intel compiler is required to run MET - -module load ncarenv/24.12 -module load intel/2024.2.1 -module load cmake/3.31.0 -module load proj/9.2.1 - -set base /glade/work/dtcrt/METplus/casper/components/MET/installations/12.1.0 -set ver 12.1.0 -set share $base/share/met - -prepend-path PATH $base/bin:/glade/work/dtcrt/METplus/casper/components/MET/installations/12.1.0/external_libs/bin:/glade/work/dtcrt/METplus/casper/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin - -setenv METversion V$ver - - diff --git a/internal/scripts/installation/modulefiles/12.1.0_derecho b/internal/scripts/installation/modulefiles/12.1.0_derecho deleted file mode 100644 index 9d0e5beb7b..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_derecho +++ /dev/null @@ -1,22 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -# The intel compiler is required to run MET - -module load ncarenv/23.09 -module load intel/2023.2.1 - -set base /glade/work/dtcrt/METplus/derecho/components/MET/installations/12.1.0 -set ver 12.1.0 -set share $base/share/met - -prepend-path PATH $base/bin:/glade/work/dtcrt/METplus/derecho/components/MET/installations/12.1.0/external_libs/bin:/glade/work/dtcrt/METplus/derecho/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin - -setenv METversion V$ver -setenv MET_PYTHON_EXE /glade/work/dtcrt/METplus/derecho/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python3 diff --git a/internal/scripts/installation/modulefiles/12.1.0_gaea b/internal/scripts/installation/modulefiles/12.1.0_gaea deleted file mode 100644 index 43eeb5c533..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_gaea +++ /dev/null @@ -1,20 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -module unload cray-libsci/24.07.0 -module load intel/2023.2.0 - -set base /usw/met -set ver 12.1.0 -set share $base/$ver/share/met -set lib_base $base/12.1.0 - -prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin - -setenv MET_PYTHON_EXE /gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python diff --git a/internal/scripts/installation/modulefiles/12.1.0_hera b/internal/scripts/installation/modulefiles/12.1.0_hera deleted file mode 100644 index aac70e28c7..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_hera +++ /dev/null @@ -1,21 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -# The intel compiler is required to run MET -prereq intel/2024.2.1 - -set base /contrib/met -set ver 12.1.0 -set share $base/$ver/share/met -set lib_base $base/12.1.0 -setenv MET_ROOT $base/$ver - -prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin - -setenv MET_PYTHON_EXE /scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python diff --git a/internal/scripts/installation/modulefiles/12.1.0_hercules b/internal/scripts/installation/modulefiles/12.1.0_hercules deleted file mode 100644 index 01c55b751f..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_hercules +++ /dev/null @@ -1,20 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -prereq intel-oneapi-compilers/2022.2.1 - -set base /apps/contrib/MET -set ver 12.1.0 -set share $base/$ver/share/met -set lib_base $base/12.1.0 -setenv MET_ROOT $base/$ver/MET-12.1.0 - -prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin - -setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python diff --git a/internal/scripts/installation/modulefiles/12.1.0_jet b/internal/scripts/installation/modulefiles/12.1.0_jet deleted file mode 100644 index c9dc902104..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_jet +++ /dev/null @@ -1,20 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -prereq intel/2024.2.1 - -set base /contrib/met/12.1.0 -set ver 12.1.0 -set share $base/share/met -setenv MET_ROOT $base/$ver/MET-12.1.0 - -prepend-path PATH $base/bin:$base/external_libs/bin:/mnt/lfs6/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin - -setenv MET_PYTHON_EXE /mnt/lfs5/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python - diff --git a/internal/scripts/installation/modulefiles/12.1.0_orion b/internal/scripts/installation/modulefiles/12.1.0_orion deleted file mode 100644 index 6ed25eaab3..0000000000 --- a/internal/scripts/installation/modulefiles/12.1.0_orion +++ /dev/null @@ -1,19 +0,0 @@ -#%Module###################################################################### -## -## Model Evaluation Tools -## -proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.1.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -prereq intel-oneapi-compilers/2024.1.0 - -set base /apps/contrib/MET -set ver 12.1.0 -set share $base/$ver/share/met -setenv MET_ROOT $base/$ver - -prepend-path PATH $base/$ver/bin:$base/$ver/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin - -setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python From 17d5991978b509299f1950beeee4e93248fefdff Mon Sep 17 00:00:00 2001 From: jprestop Date: Fri, 5 Dec 2025 19:20:00 -0700 Subject: [PATCH 17/45] Updates to hera and ursa files --- .../installation/config/install_met_env.hera | 4 +-- .../installation/config/install_met_env.ursa | 34 +++++++++---------- .../installation/modulefiles/12.2.0_hera | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.hera b/internal/scripts/installation/config/install_met_env.hera index c8c3aa75df..b17be00815 100644 --- a/internal/scripts/installation/config/install_met_env.hera +++ b/internal/scripts/installation/config/install_met_env.hera @@ -18,8 +18,8 @@ export MET_PYTHON_LD="-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gn export SET_D64BIT=FALSE export ADDTL_DIR=/usr/lib64 export EXTERNAL_LIBS=${TEST_BASE}/external_libs/ -export COMPILE_ECKIT=1 -export COMPILE_ATLAS=1 +#export COMPILE_ECKIT=1 +#export COMPILE_ATLAS=1 #export MET_PROJ=${EXTERNAL_LIBS} #export MET_NETCDF=${EXTERNAL_LIBS} #export MET_GSL=${EXTERNAL_LIBS} diff --git a/internal/scripts/installation/config/install_met_env.ursa b/internal/scripts/installation/config/install_met_env.ursa index 6901cf26c7..099e4d9436 100644 --- a/internal/scripts/installation/config/install_met_env.ursa +++ b/internal/scripts/installation/config/install_met_env.ursa @@ -20,22 +20,22 @@ export ADDTL_DIR=/usr/lib64 export EXTERNAL_LIBS=${TEST_BASE}/external_libs/ #export COMPILE_ECKIT=1 #export COMPILE_ATLAS=1 -export MET_PROJ=${EXTERNAL_LIBS} -export MET_NETCDF=${EXTERNAL_LIBS} -export MET_GSL=${EXTERNAL_LIBS} -export MET_BUFRLIB=${EXTERNAL_LIBS} -export BUFRLIB_NAME=-lbufr_4 -export MET_HDF5=${EXTERNAL_LIBS} -export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib -export MET_GRIB2CINC=${EXTERNAL_LIBS}/include -export GRIB2CLIB_NAME=-lg2c -export LIB_JASPER=${EXTERNAL_LIBS}/lib -export LIB_LIBPNG=${EXTERNAL_LIBS}/lib -export LIB_Z=${EXTERNAL_LIBS}/lib -export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include -export TIFF_LIB_DIR=${EXTERNAL_LIBS}/lib -export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include -export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib -export MAKE_ARGS="-j 5" +#export MET_PROJ=${EXTERNAL_LIBS} +#export MET_NETCDF=${EXTERNAL_LIBS} +#export MET_GSL=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export BUFRLIB_NAME=-lbufr_4 +#export MET_HDF5=${EXTERNAL_LIBS} +#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +#export MET_GRIB2CINC=${EXTERNAL_LIBS}/include +#export GRIB2CLIB_NAME=-lg2c +#export LIB_JASPER=${EXTERNAL_LIBS}/lib +#export LIB_LIBPNG=${EXTERNAL_LIBS}/lib +#export LIB_Z=${EXTERNAL_LIBS}/lib +#export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include +#export TIFF_LIB_DIR=${EXTERNAL_LIBS}/lib +#export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include +#export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib +#export MAKE_ARGS="-j 5" #export SKIP_MET=true diff --git a/internal/scripts/installation/modulefiles/12.2.0_hera b/internal/scripts/installation/modulefiles/12.2.0_hera index 255011f841..aef489e603 100644 --- a/internal/scripts/installation/modulefiles/12.2.0_hera +++ b/internal/scripts/installation/modulefiles/12.2.0_hera @@ -18,4 +18,4 @@ setenv MET_ROOT $base/$ver prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin -setenv MET_PYTHON_EXE /scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python +#setenv MET_PYTHON_EXE /scratch1/BMC/dtc/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python From 75dadc6b8cb843e51e099efa3abb9b43688022e4 Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 8 Dec 2025 13:41:13 -0700 Subject: [PATCH 18/45] Update to Python 3.12 in seneca file --- .../config/install_met_env.seneca_intel_oneapi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi b/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi index 4997af8125..fc047f1b02 100644 --- a/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi +++ b/internal/scripts/installation/config/install_met_env.seneca_intel_oneapi @@ -36,15 +36,15 @@ export USE_MODULES=FALSE # Root directory of your python install, containing the bin, include, lib, and share directories export MET_DST=/nrit/ral -export MET_PYTHON=${MET_DST}/met-python3 +export MET_PYTHON=${MET_DST}/met-python3.12 # Python ldflags created using python3-config -export MET_PYTHON_LD="-L${MET_PYTHON}/lib -lpython3.10 -lcrypt -lpthread -ldl -lutil -lm" +export MET_PYTHON_LD="-L${MET_PYTHON}/lib -lpython3.12 -lcrypt -lpthread -ldl -lutil -lm" # Python cflags created using python3-config -export MET_PYTHON_CC="-I${MET_PYTHON}/include/python3.10" +export MET_PYTHON_CC="-I${MET_PYTHON}/include/python3.12" -export MET_PYTHON_BIN_EXE=${MET_PYTHON}/bin/python3.10 +export MET_PYTHON_BIN_EXE=${MET_PYTHON}/bin/python3.12 # Use MAKE_ARGS to sped up the compilation of the external libaries and/or MET # MAKE_ARGS can be set "-j #" where # is replaced with the number of From 4d2c5e582eb4fd65a05acda23b196e693af46dd9 Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 8 Dec 2025 13:43:13 -0700 Subject: [PATCH 19/45] Update to Python 3.12 in gaea file --- internal/scripts/installation/config/install_met_env.gaea | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.gaea b/internal/scripts/installation/config/install_met_env.gaea index 13755c21f4..60a1c257ac 100644 --- a/internal/scripts/installation/config/install_met_env.gaea +++ b/internal/scripts/installation/config/install_met_env.gaea @@ -19,9 +19,9 @@ export COMPILER=intel_2023.2.0 export MET_SUBDIR=${TEST_BASE} export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE -export MET_PYTHON=/gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/ -export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 -export MET_PYTHON_LD=-L${MET_PYTHON}/lib/python3.10/config-3.10-x86_64-linux-gnu\ -L${MET_PYTHON}/lib\ -lpython3.10\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lm +export MET_PYTHON=/gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v6.1_py3.12/ +export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 +export MET_PYTHON_LD=-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gnu\ -L${MET_PYTHON}/lib\ -lpython3.12\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lm export EXTERNAL_LIBS=${TEST_BASE}/external_libs COMPILE_ATLAS=1 COMPILE_ECKIT=1 From 7923518649c299eb23c4f69427074451d4617c5c Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 8 Dec 2025 13:43:37 -0700 Subject: [PATCH 20/45] Remove install_met_env.derecho --- .../config/install_met_env.derecho | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 internal/scripts/installation/config/install_met_env.derecho diff --git a/internal/scripts/installation/config/install_met_env.derecho b/internal/scripts/installation/config/install_met_env.derecho deleted file mode 100644 index 30538b2a7d..0000000000 --- a/internal/scripts/installation/config/install_met_env.derecho +++ /dev/null @@ -1,44 +0,0 @@ -module load ncarenv/23.09 -module load intel/2023.2.1 -module load cmake/3.26.3 - -export CC=icx -export CXX=icpx -export FC=ifx -export F77=ifx -export F90=ifx - -export TEST_BASE=/glade/work/dtcrt/METplus/derecho/components/MET/installations/12.2.0 -export COMPILER=intel_2023.2.1 -export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=v12.2.0.tar.gz -export USE_MODULES=TRUE -export MET_PYTHON=/glade/work/dtcrt/METplus/derecho/miniconda/miniconda3/envs/metplus_v5.1_py3.10 -export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 -export MET_PYTHON_LD=`${MET_PYTHON}/bin/python3-config --ldflags --embed` -export EXTERNAL_LIBS=${TEST_BASE}/external_libs -export COMPILE_ECKIT=1 -export COMPILE_ATLAS=1 -#export MET_PROJ=${EXTERNAL_LIBS} -#export MET_ECKIT=${EXTERNAL_LIBS} -#export MET_ATLAS=${EXTERNAL_LIBS} -#export MET_GSL=${EXTERNAL_LIBS} -#export MET_BUFRLIB=${EXTERNAL_LIBS} -#export BUFRLIB_NAME=-lbufr_4 -#export MET_NETCDF=${EXTERNAL_LIBS} -#export MET_HDF5=${EXTERNAL_LIBS} -#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib64 -#export MET_GRIB2CINC=${EXTERNAL_LIBS}/include -#export GRIB2CLIB_NAME=-lg2c -#export LIB_JASPER=${EXTERNAL_LIBS}/lib64 -#export LIB_LIBPNG=${EXTERNAL_LIBS}/lib -#export LIB_Z=${EXTERNAL_LIBS}/lib -#export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include -#export TIFF_LIB_DIR=${EXTERNAL_LIBS}/lib -#export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include -#export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib -export MAKE_ARGS=-j -#export CFLAGS="-Wall -g" -#export CXXFLAGS="-Wall -g" -#export CXXFLAGS="-std=c++11" - From e16b4fe63deb5984ea0043e226023c7ca1907be3 Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 8 Dec 2025 13:45:24 -0700 Subject: [PATCH 21/45] Update to Python 3.12 in frontera file --- .../scripts/installation/config/install_met_env.frontera | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.frontera b/internal/scripts/installation/config/install_met_env.frontera index 7b373827e2..1c965fe2b3 100644 --- a/internal/scripts/installation/config/install_met_env.frontera +++ b/internal/scripts/installation/config/install_met_env.frontera @@ -11,9 +11,9 @@ export COMPILER=intel_23.1.0 export MET_SUBDIR=${TEST_BASE}/ export MET_TARBALL=v12.2.0.tar.gz export USE_MODULES=TRUE -export MET_PYTHON=/work2/06612/tg859120/frontera/miniconda/miniconda3/envs/metplus_v5.1_py3.10 -export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.10 -export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.10\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lm +export MET_PYTHON=/work2/06612/tg859120/frontera/miniconda/miniconda3/envs/metplus_v6.1_py3.12 +export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 +export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.12\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lm #export MET_HDF5=/opt/apps/intel19/hdf5/1.12.0/x86_64/ #export MET_NETCDF=/opt/apps/intel19/netcdf/4.7.4/x86_64/ export EXTERNAL_LIBS=${TEST_BASE}/external_libs From a1c63dcb9e929c32000f6743cc601061083a6813 Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 8 Dec 2025 14:12:07 -0700 Subject: [PATCH 22/45] Update commented out lines in files --- .../config/install_met_env.frontera | 28 +++++++++---------- .../installation/config/install_met_env.hera | 4 +-- .../installation/config/install_met_env.ursa | 4 +-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.frontera b/internal/scripts/installation/config/install_met_env.frontera index 1c965fe2b3..d3c9eccbe2 100644 --- a/internal/scripts/installation/config/install_met_env.frontera +++ b/internal/scripts/installation/config/install_met_env.frontera @@ -17,25 +17,25 @@ export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.12\ -lcrypt\ -lpthread\ -ldl #export MET_HDF5=/opt/apps/intel19/hdf5/1.12.0/x86_64/ #export MET_NETCDF=/opt/apps/intel19/netcdf/4.7.4/x86_64/ export EXTERNAL_LIBS=${TEST_BASE}/external_libs -#COMPILE_ATLAS=1 -#COMPILE_ECKIT=1 -export MET_PROJ=${EXTERNAL_LIBS} -export MET_NETCDF=${EXTERNAL_LIBS} -export MET_HDF5=${EXTERNAL_LIBS} -export MET_ATLAS=${EXTERNAL_LIBS} -export MET_ECKIT=${EXTERNAL_LIBS} -export MET_GSL=${EXTERNAL_LIBS} -export MET_BUFRLIB=${EXTERNAL_LIBS} -export BUFRLIB_NAME=-lbufr_4 +COMPILE_ATLAS=1 +COMPILE_ECKIT=1 +#export MET_PROJ=${EXTERNAL_LIBS} +#export MET_NETCDF=${EXTERNAL_LIBS} +#export MET_HDF5=${EXTERNAL_LIBS} +#export MET_ATLAS=${EXTERNAL_LIBS} +#export MET_ECKIT=${EXTERNAL_LIBS} +#export MET_GSL=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export BUFRLIB_NAME=-lbufr_4 #export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib #export MET_GRIB2CINC=${EXTERNAL_LIBS}/include #export GRIB2CLIB_NAME=-lg2c #export LIB_JASPER=${EXTERNAL_LIBS}/lib #export LIB_LIBPNG=${EXTERNAL_LIBS}/lib #export LIB_Z=${EXTERNAL_LIBS}/lib -export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include -export TIFF_LIB_DIR=${EXTERNAL_LIBS}/lib -export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include -export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib +#export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include +#export TIFF_LIB_DIR=${EXTERNAL_LIBS}/lib +#export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include +#export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib export MAKE_ARGS="-j 5" diff --git a/internal/scripts/installation/config/install_met_env.hera b/internal/scripts/installation/config/install_met_env.hera index b17be00815..c8c3aa75df 100644 --- a/internal/scripts/installation/config/install_met_env.hera +++ b/internal/scripts/installation/config/install_met_env.hera @@ -18,8 +18,8 @@ export MET_PYTHON_LD="-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gn export SET_D64BIT=FALSE export ADDTL_DIR=/usr/lib64 export EXTERNAL_LIBS=${TEST_BASE}/external_libs/ -#export COMPILE_ECKIT=1 -#export COMPILE_ATLAS=1 +export COMPILE_ECKIT=1 +export COMPILE_ATLAS=1 #export MET_PROJ=${EXTERNAL_LIBS} #export MET_NETCDF=${EXTERNAL_LIBS} #export MET_GSL=${EXTERNAL_LIBS} diff --git a/internal/scripts/installation/config/install_met_env.ursa b/internal/scripts/installation/config/install_met_env.ursa index 099e4d9436..9339d20fdd 100644 --- a/internal/scripts/installation/config/install_met_env.ursa +++ b/internal/scripts/installation/config/install_met_env.ursa @@ -18,8 +18,8 @@ export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 export MET_PYTHON_LD="-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gnu -L${MET_PYTHON}/lib -lpython3.12 -lpthread -ldl -lutil -lm" export ADDTL_DIR=/usr/lib64 export EXTERNAL_LIBS=${TEST_BASE}/external_libs/ -#export COMPILE_ECKIT=1 -#export COMPILE_ATLAS=1 +export COMPILE_ECKIT=1 +export COMPILE_ATLAS=1 #export MET_PROJ=${EXTERNAL_LIBS} #export MET_NETCDF=${EXTERNAL_LIBS} #export MET_GSL=${EXTERNAL_LIBS} From 244e3e3812a105bd6c61623043b38c06d2681ecd Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 8 Dec 2025 14:19:10 -0700 Subject: [PATCH 23/45] Updated files to comment out MET_PYTHON_EXE --- internal/scripts/installation/modulefiles/12.2.0_gaea | 4 ++-- internal/scripts/installation/modulefiles/12.2.0_jet | 2 +- internal/scripts/installation/modulefiles/12.2.0_orion | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/scripts/installation/modulefiles/12.2.0_gaea b/internal/scripts/installation/modulefiles/12.2.0_gaea index cff8bb11f9..708af20c09 100644 --- a/internal/scripts/installation/modulefiles/12.2.0_gaea +++ b/internal/scripts/installation/modulefiles/12.2.0_gaea @@ -15,6 +15,6 @@ set ver 12.2.0 set share $base/$ver/share/met set lib_base $base/12.2.0 -prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin +prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/ncrc/proj/nggps_psd/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin -setenv MET_PYTHON_EXE /gpfs/f5/esrl/proj-shared/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v5.1_py3.10/bin/python +#setenv MET_PYTHON_EXE /ncrc/proj/nggps_psd/Julie.Prestopnik/projects/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python diff --git a/internal/scripts/installation/modulefiles/12.2.0_jet b/internal/scripts/installation/modulefiles/12.2.0_jet index d8318ef7d5..8b5bcd09f2 100644 --- a/internal/scripts/installation/modulefiles/12.2.0_jet +++ b/internal/scripts/installation/modulefiles/12.2.0_jet @@ -16,5 +16,5 @@ setenv MET_ROOT $base/$ver/MET-12.2.0 prepend-path PATH $base/bin:$base/external_libs/bin:/mnt/lfs6/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin -setenv MET_PYTHON_EXE /mnt/lfs5/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python +#setenv MET_PYTHON_EXE /mnt/lfs5/HFIP/dtc-hurr/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python diff --git a/internal/scripts/installation/modulefiles/12.2.0_orion b/internal/scripts/installation/modulefiles/12.2.0_orion index b432ee6cd8..d509a2a4a9 100644 --- a/internal/scripts/installation/modulefiles/12.2.0_orion +++ b/internal/scripts/installation/modulefiles/12.2.0_orion @@ -16,4 +16,4 @@ setenv MET_ROOT $base/$ver prepend-path PATH $base/$ver/bin:$base/$ver/external_libs/bin:/work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin -setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python +#setenv MET_PYTHON_EXE /work/noaa/ovp/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin/python From 13e81438b904dbe8181f1553b64e974a4d27bdcd Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Mon, 15 Dec 2025 19:59:10 -0700 Subject: [PATCH 24/45] Add installation configuration for MET environment on smac-c5 --- .../config/install_met_env.smac-c5 | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 internal/scripts/installation/config/install_met_env.smac-c5 diff --git a/internal/scripts/installation/config/install_met_env.smac-c5 b/internal/scripts/installation/config/install_met_env.smac-c5 new file mode 100644 index 0000000000..2cfd2e1053 --- /dev/null +++ b/internal/scripts/installation/config/install_met_env.smac-c5 @@ -0,0 +1,44 @@ +module purge +module load compiler-rt/2024.0.1 +module load tbb/2021.11 +module load oclfpga/2024.0.0 +module load compiler/2024.0.1 +module load mkl/2024.0 +module load mpi/2021.11 + +export FC=ifx +export F77=ifx +export F90=ifx +export CC=icx +export CXX=icpx +export PATH=/atec/opt/atectest/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin:${PATH} +export TEST_BASE=/atec/opt/atectest/MET/12.2.0 +export COMPILER=intel_2024.0.1 +export MET_SUBDIR=${TEST_BASE} +export MET_TARBALL=v12.2.0.tar.gz +export USE_MODULES=TRUE +export MET_PYTHON=/atec/opt/atectest/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12 +export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 +export MET_PYTHON_LD="-L${MET_PYTHON}/lib/python3.12/config-3.12-x86_64-linux-gnu -L${MET_PYTHON}/lib -lpython3.12 -lpthread -ldl -lutil -lm" +export SET_D64BIT=FALSE +#export ADDTL_DIR=/usr/lib64 +export EXTERNAL_LIBS=${TEST_BASE}/external_libs/ +export COMPILE_ECKIT=1 +export COMPILE_ATLAS=1 +#export MET_PROJ=${EXTERNAL_LIBS} +#export MET_NETCDF=${EXTERNAL_LIBS} +#export MET_GSL=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export BUFRLIB_NAME=-lbufr_4 +#export MET_HDF5=${EXTERNAL_LIBS} +#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +#export MET_GRIB2CINC=${EXTERNAL_LIBS}/include +#export GRIB2CLIB_NAME=-lg2c +#export LIB_JASPER=${EXTERNAL_LIBS}/lib +#export LIB_LIBPNG=${EXTERNAL_LIBS}/lib +#export LIB_Z=${EXTERNAL_LIBS}/lib +#export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include +#export TIFF_LIB_DIR=${EXTERNAL_LIBS}/lib +#export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include +#export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib +export MAKE_ARGS="-j 5" From acb206d017e4ad1bddd3babe3e744f1a2460404f Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Mon, 15 Dec 2025 20:16:50 -0700 Subject: [PATCH 25/45] Add modulefile for smac-c5 --- .../installation/modulefiles/12.2.0_smac-c5 | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 internal/scripts/installation/modulefiles/12.2.0_smac-c5 diff --git a/internal/scripts/installation/modulefiles/12.2.0_smac-c5 b/internal/scripts/installation/modulefiles/12.2.0_smac-c5 new file mode 100644 index 0000000000..2d2a2cbbbc --- /dev/null +++ b/internal/scripts/installation/modulefiles/12.2.0_smac-c5 @@ -0,0 +1,23 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v12.2.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +module load compiler-rt/2024.0.1 +module load tbb/2021.11 +module load oclfpga/2024.0.0 +module load compiler/2024.0.1 +module load mkl/2024.0 +module load mpi/2021.11 + +set base /atec/opt/atectest/MET +set ver 12.2.0 +set share $base/$ver/share/met +set lib_base $base/12.2.0 +setenv MET_ROOT $base/$ver + +prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin:/atec/opt/atectest/METplus/miniconda/miniconda3/envs/metplus_v6.1_py3.12/bin From 50a6ef772874c7cf41754103bb1403dfaa3031ed Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 16 Dec 2025 11:45:24 -0700 Subject: [PATCH 26/45] Per dtcenter/METplus#3175 discussion, update the description of Python embedding for Stat-Analysis. --- docs/Users_Guide/appendixF.rst | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/Users_Guide/appendixF.rst b/docs/Users_Guide/appendixF.rst index eb98bc06f3..46b3864620 100644 --- a/docs/Users_Guide/appendixF.rst +++ b/docs/Users_Guide/appendixF.rst @@ -90,9 +90,9 @@ Python embedding with MET tools offers support for three different types of data 1. Two-dimensional (2D) gridded dataplanes -2. Point data conforming to the :ref:`MET 11-column format` +2. Point observation data conforming to the :ref:`MET 11-column format` -3. Matched-pair data conforming to the :ref:`MET MPR Line Type` +3. Statistics data, including matched-pair data conforming to the :ref:`MET MPR Line Type` Details for each of these data structures are provided below. @@ -559,25 +559,25 @@ Examples of Python Embedding for Point Observations .. _pyembed-mpr-data: -Python Embedding for MPR Data ------------------------------ +Python Embedding for STAT Data (MPR) +------------------------------------ -The MET Stat-Analysis tool also supports Python embedding. By using the command line option **-lookin python**, Stat-Analysis can read matched pair (MPR) data formatted in the MET MPR line-type format via Python. +The MET Stat-Analysis tool also supports Python embedding. By using the command line option **-lookin python**, Stat-Analysis can read statistics data generated by the MET statistics tools. This is particularly useful for reading matched pair (MPR) data formatted in the MET MPR line-type format via Python. -The MET Pair-Stat tool also supports Python embedding of matched pair (MPR) data using the **-format python** command line option. Similar to the Stat-Analysis tool, this functionality expects data formatted in the MET MPR format within Python prior to passing to Pair-Stat. +The MET Pair-Stat tool also supports Python embedding of matched pair (MPR) data using the **-format python** command line option. This functionality expects data formatted in the MET MPR format within Python prior to passing to Pair-Stat. .. note:: - This functionality assumes you are passing only the MPR line type information, and not other statistical line types. Sometimes users configure MET tools to write the MPR line type to the STAT file (along with all other line types). The example below will not work for those files, but rather only files from MET tools containing just the MPR line type information, or optionally, data in another format that the user adapts to the MPR line type format. + While Stat-Analysis can read all STAT line types through Python embedding, Pair-Stat only reads the MPR line type. Note that the MET statistics tools write all output line types to a STAT file, but can also be configured to write each line type to separate text (TXT) files. The example below reads data from an MPR text file generated by Point-Stat where each line has the same number of columns. It will not work for STAT files, in general, where the number of columns vary by line type. Python Script Requirements for MPR Data ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1. The data must be stored in a variable with the name **mpr_data** +1. The data must be stored in a variable with the name **mpr_data**, although Stat-Analysis actually supports any STAT line type 2. The **mpr_data** variable must be a Python list representation of a NumPy N-D Array created from a Pandas DataFrame -3. The **met_data** variable must have data in **exactly** 36 columns, corresponding to the summation of the :ref:`common STAT output` and the :ref:`MPR line type output`. +3. The **met_data** variable must have data in **exactly** 36 columns for MPR data, corresponding to the summation of the :ref:`common STAT output` and the :ref:`MPR line type output`. If a user does not have an existing MPR line type file created by the MET tools, they will need to map their data into the 36 columns expected by Stat-Analysis for the MPR line type data. If a user already has MPR line type files, the most direct way for a user to read MPR line type data is to model their Python script after the sample **read_ascii_mpr.py** script. Sample code is included here for convenience: @@ -596,6 +596,10 @@ If a user does not have an existing MPR line type file created by the MET tools, # Convert to the variable MET expects mpr_data = mpr_dataframe.values.tolist() +.. note:: + + If reading non-MPR STAT line types as input, the example above should be modified based on the number of columns for the input line type. + Running Python Embedding for MPR Data ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 053dd4de0e329ca62bd2ec801c29872db4349820 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 16 Dec 2025 12:31:56 -0700 Subject: [PATCH 27/45] Tweak wording --- docs/Users_Guide/appendixF.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Users_Guide/appendixF.rst b/docs/Users_Guide/appendixF.rst index 46b3864620..62221f84d1 100644 --- a/docs/Users_Guide/appendixF.rst +++ b/docs/Users_Guide/appendixF.rst @@ -559,8 +559,8 @@ Examples of Python Embedding for Point Observations .. _pyembed-mpr-data: -Python Embedding for STAT Data (MPR) ------------------------------------- +Python Embedding for STAT Data +------------------------------ The MET Stat-Analysis tool also supports Python embedding. By using the command line option **-lookin python**, Stat-Analysis can read statistics data generated by the MET statistics tools. This is particularly useful for reading matched pair (MPR) data formatted in the MET MPR line-type format via Python. From 77cfaa8fc4d933674b0cfaa20035da7252a0084b Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 5 Jan 2026 13:35:15 -0700 Subject: [PATCH 28/45] Hotfix to the develop branch to call metplus-action-free-disk-space after the release-docker-images.yml workflow failed after running out of disk space. --- .github/workflows/release-docker-images.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index 879da0a90a..1528c73f70 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -77,6 +77,9 @@ jobs: matrix: ${{ fromJSON(needs.define-matrix.outputs.matrix) }} steps: + - name: Free Disk Space + uses: dtcenter/metplus-action-free-disk-space@v1 + - uses: actions/checkout@v4 - uses: actions/checkout@v4 From 7f176a60ec104c26ad4747e3772690c036514ea6 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:22:23 -0700 Subject: [PATCH 29/45] Do not fail security scan if critical CVEs are found. Upload build log artifacts so that they are available even if the scan fails --- .github/workflows/release-docker-images.yml | 29 ++++++++++----------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index 1528c73f70..9278ce6f1d 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -105,6 +105,19 @@ jobs: SOURCE_BRANCH: ${{ matrix.version }} MET_CONFIG_OPTS: '--enable-all' + - name: Copy build log files into logs directory + if: always() + run: | + cp ${GITHUB_WORKSPACE}/*.log ${RUNNER_WORKSPACE}/logs/ + + - name: Upload build logs as artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: build_logs_${{ matrix.version }} + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + - name: Get DockerHub tag id: get-dockerhub-tag run: | @@ -123,7 +136,7 @@ jobs: [ "${{ steps.get-dockerhub-tag.outputs.DOCKERHUB_TAG }}" ] - fail-on-critical: "true" + fail-on-critical: "false" log-artifact-name: 'security-scan-logs_${{ matrix.version }}' - name: Push Docker Image @@ -134,17 +147,3 @@ jobs: UPDATE_LATEST: ${{ fromJSON(needs.define-matrix.outputs.update_latest) }} DOCKER_USERNAME: ${{ vars.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_TOKEN }} - - - name: Copy build log files into logs directory - if: always() - run: | - cp ${GITHUB_WORKSPACE}/*.log ${RUNNER_WORKSPACE}/logs/ - - - name: Upload build logs as artifact - if: always() - uses: actions/upload-artifact@v4 - with: - name: build_logs_${{ matrix.version }} - path: ${{ runner.workspace }}/logs - if-no-files-found: ignore - From b7552604c6211e88d0450a633c3225ec0c33d958 Mon Sep 17 00:00:00 2001 From: METplus Bot <97135045+metplus-bot@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:49:57 -0700 Subject: [PATCH 30/45] Update schedule as metplus-bot so that user receives weekly emails --- .github/workflows/release-docker-images.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index 9278ce6f1d..8969e9d344 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -20,7 +20,7 @@ on: type: boolean schedule: - - cron: "30 03 * * 0" + - cron: "35 03 * * 0" env: DOCKERHUB_REPO: dtcenter/met From 065b73a54590e75440ca71be73c91130ee92416d Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Fri, 16 Jan 2026 12:59:25 -0700 Subject: [PATCH 31/45] Modify library export paths in install_met_env.smac-c5 Updated library paths to point to lib64 directory. --- .../installation/config/install_met_env.smac-c5 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/internal/scripts/installation/config/install_met_env.smac-c5 b/internal/scripts/installation/config/install_met_env.smac-c5 index 2cfd2e1053..9a0319f143 100644 --- a/internal/scripts/installation/config/install_met_env.smac-c5 +++ b/internal/scripts/installation/config/install_met_env.smac-c5 @@ -25,16 +25,21 @@ export SET_D64BIT=FALSE export EXTERNAL_LIBS=${TEST_BASE}/external_libs/ export COMPILE_ECKIT=1 export COMPILE_ATLAS=1 -#export MET_PROJ=${EXTERNAL_LIBS} +#export MET_ECKITINC=${EXTERNAL_LIBS}/include +#export MET_ECKITLIB=${EXTERNAL_LIBS}/lib64 +#export MET_ATLASINC=${EXTERNAL_LIBS}/include +#export MET_ATLASLIB=${EXTERNAL_LIBS}/lib64 +#export MET_PROJINC=${EXTERNAL_LIBS}/include +#export MET_PROJLIB=${EXTERNAL_LIBS}/lib64 #export MET_NETCDF=${EXTERNAL_LIBS} #export MET_GSL=${EXTERNAL_LIBS} -#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS}/lib64 #export BUFRLIB_NAME=-lbufr_4 #export MET_HDF5=${EXTERNAL_LIBS} -#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib64 #export MET_GRIB2CINC=${EXTERNAL_LIBS}/include #export GRIB2CLIB_NAME=-lg2c -#export LIB_JASPER=${EXTERNAL_LIBS}/lib +#export LIB_JASPER=${EXTERNAL_LIBS}/lib64 #export LIB_LIBPNG=${EXTERNAL_LIBS}/lib #export LIB_Z=${EXTERNAL_LIBS}/lib #export TIFF_INCLUDE_DIR=${EXTERNAL_LIBS}/include @@ -42,3 +47,4 @@ export COMPILE_ATLAS=1 #export SQLITE_INCLUDE_DIR=${EXTERNAL_LIBS}/include #export SQLITE_LIB_DIR=${EXTERNAL_LIBS}/lib export MAKE_ARGS="-j 5" + From 82c074b33577ce656cc0410630e9255842642aba Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:48:33 -0700 Subject: [PATCH 32/45] remove support for v12.0 rebuilds --- .github/workflows/release-docker-images.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index 8969e9d344..2d2f13e06a 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -9,8 +9,8 @@ on: workflow_dispatch: inputs: release_version: - description: 'Comma-separated list of versions to build, e.g. v12.0,v12.1,v12.2' - default: 'v12.2' + description: 'Comma-separated list of versions to build, e.g. v12.1,v12.2' + default: 'v12.1,v12.2' required: true type: string update_latest: @@ -46,7 +46,7 @@ jobs: id: get-versions run: | if [[ ${{ github.event_name }} == 'schedule' ]]; then - version_string="v12.0,v12.1,v12.2" + version_string="v12.1,v12.2" update_latest="true" elif [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then version_string=${{ toJSON(inputs.release_version) }} From aa41106e376e6f8bd9bef87f0e55d3aae7f61898 Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Thu, 22 Jan 2026 11:23:57 -0700 Subject: [PATCH 33/45] Per #3317, resolve bugs as describe in the issue (#3318) --- .../scripts/installation/compile_MET_all.sh | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/internal/scripts/installation/compile_MET_all.sh b/internal/scripts/installation/compile_MET_all.sh index d013e3954d..bff2bc9909 100755 --- a/internal/scripts/installation/compile_MET_all.sh +++ b/internal/scripts/installation/compile_MET_all.sh @@ -184,18 +184,19 @@ else fi # Constants +# Read compile options from config file (with defaults if not set) +COMPILE_ZLIB=${COMPILE_ZLIB:-0} +COMPILE_LIBPNG=${COMPILE_LIBPNG:-0} +COMPILE_JASPER=${COMPILE_JASPER:-0} +COMPILE_JPEG=${COMPILE_JPEG:-0} +COMPILE_G2CLIB=${COMPILE_G2CLIB:-0} + if [[ -z ${MET_GRIB2CLIB} ]] && [[ -z ${MET_GRIB2C} ]]; then COMPILE_ZLIB=1 COMPILE_LIBPNG=1 COMPILE_JASPER=1 COMPILE_JPEG=1 COMPILE_G2CLIB=1 -else - COMPILE_ZLIB=0 - COMPILE_LIBPNG=0 - COMPILE_JASPER=0 - COMPILE_JPEG=0 - COMPILE_G2CLIB=0 fi if [ -z ${MET_BUFRLIB} ]; then COMPILE_BUFRLIB=1; else COMPILE_BUFRLIB=0; fi @@ -716,7 +717,7 @@ if [ $COMPILE_ATLAS -eq 1 ]; then cd ${LIB_DIR}/atlas/atlas* echo "cd `pwd`" run_cmd "mkdir build; cd build" - run_cmd "cmake ../ -DCMAKE_INSTALL_PREFIX=${LIB_DIR} -DCMAKE_PREFIX_PATH=${LIB_DIR} > $(pwd)/atlas.cmake.log 2>&1" + run_cmd "cmake ../ -DCMAKE_INSTALL_PREFIX=${LIB_DIR} -DCMAKE_PREFIX_PATH=${LIB_DIR} -DENABLE_TESSELATION=OFF > $(pwd)/atlas.cmake.log 2>&1" run_cmd "make ${MAKE_ARGS} > $(pwd)/atlas.make.log 2>&1" run_cmd "make ${MAKE_ARGS} install > $(pwd)/atlas.make_install.log 2>&1" @@ -969,11 +970,17 @@ if [[ ! -z ${MET_FREETYPEINC} && ! -z ${MET_FREETYPELIB} && \ configure_cmd="${configure_cmd} --enable-mode_graphics" fi -if [[ ! -z $MET_ECKIT && ! -z $MET_ATLAS ]]; then +if [[ ( ! -z $MET_ECKIT && ! -z $MET_ATLAS ) || \ + ( ! -z $MET_ATLASINC && ! -z $MET_ATLASLIB && ! -z $MET_ECKIT ) || \ + ( ! -z $MET_ECKITINC && ! -z $MET_ECKITLIB && ! -z $MET_ATLAS ) || \ + ( ! -z $MET_ATLASINC && ! -z $MET_ATLASLIB && ! -z $MET_ECKITINC && ! -z $MET_ECKITLIB ) ]]; then configure_cmd="${configure_cmd} --enable-ugrid" fi -if [[ ! -z $MET_HDF && ! -z $MET_HDFEOS ]]; then +if [[ ( ! -z $MET_HDF && ! -z $MET_HDFEOS ) || \ + ( ! -z $MET_HDFEOSINC && ! -z $MET_HDFEOSLIB && ! -z $MET_HDF ) || \ + ( ! -z $MET_HDFINC && ! -z $MET_HDFLIB && ! -z $MET_HDFEOS ) || \ + ( ! -z $MET_HDFEOSINC && ! -z $MET_HDFEOSLIB && ! -z $MET_HDFINC && ! -z $MET_HDFLIB ) ]]; then configure_cmd="${configure_cmd} --enable-modis --enable-lidar2nc" fi From 9ad83d329f747852c56bb0c44a6b0045204a5350 Mon Sep 17 00:00:00 2001 From: Julie Prestopnik Date: Fri, 23 Jan 2026 17:11:00 -0700 Subject: [PATCH 34/45] Update MET_PYTHON_CC to use python sysconfig --- internal/scripts/installation/config/install_met_env.acorn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/scripts/installation/config/install_met_env.acorn b/internal/scripts/installation/config/install_met_env.acorn index e67acff76a..96c60f5fdd 100644 --- a/internal/scripts/installation/config/install_met_env.acorn +++ b/internal/scripts/installation/config/install_met_env.acorn @@ -32,7 +32,7 @@ export ADDTL_DIR=/apps/spack/gettext/0.21/intel/19.1.3.304/at2kdo4edvuhyzrt5g6zh export PYTHON_MODULE=python_3.12.0 export MET_PYTHON=/apps/spack/python/3.12.0/intel/19.1.3.304/r7ia355o3tnbbmfexnp3bcsyl2r4ai47 export MET_PYTHON_LIB=${MET_PYTHON}/lib -export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.12 +export MET_PYTHON_CC=-I$(python -c "import sysconfig; print(sysconfig.get_path('include'))") export MET_PYTHON_LD=-L${MET_PYTHON_LIB}\ -lpython3.12\ -lcrypt\ -lintl\ -ldl\ -lutil\ -lm\ -lm export MET_NETCDF=/apps/prod/hpc-stack/intel-19.1.3.304/netcdf/4.7.4 # JY export MET_HDF5=/apps/prod/hpc-stack/intel-19.1.3.304/hdf5/1.10.6 From ba2c7af0cd0ba88c033e34b1282c9576dd222a8c Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 29 Jan 2026 13:43:10 -0700 Subject: [PATCH 35/45] Per #3293, update logic grid_stat, wavelet_stat, and regrid_data_plane so that the user-specified set_attr_grid setting takes effect. (#3300) --- .../vx_data2d_factory/data2d_factory_utils.cc | 33 +++++++++++++++++++ .../vx_data2d_factory/data2d_factory_utils.h | 2 ++ src/tools/core/grid_stat/grid_stat.cc | 29 +++------------- src/tools/core/wavelet_stat/wavelet_stat.cc | 23 +++---------- .../regrid_data_plane/regrid_data_plane.cc | 19 ++++------- 5 files changed, 49 insertions(+), 57 deletions(-) diff --git a/src/libcode/vx_data2d_factory/data2d_factory_utils.cc b/src/libcode/vx_data2d_factory/data2d_factory_utils.cc index fac721e936..be6e0b4cd0 100644 --- a/src/libcode/vx_data2d_factory/data2d_factory_utils.cc +++ b/src/libcode/vx_data2d_factory/data2d_factory_utils.cc @@ -181,3 +181,36 @@ return FileType_None; //////////////////////////////////////////////////////////////////////// +void update_mtddf_grid(Met2dDataFile *mtddf, VarInfo *vinfo) + +{ + + // + // Read the requested data to define the grid for Python and + // range/azimuth inputs and when set_attr_grid is specified + // + +if ( is_python_grdfiletype(mtddf->file_type()) || + mtddf->grid().info().ra || + vinfo->grid_attr().is_set() ) { + + DataPlane dp; + + if( !mtddf->data_plane(*vinfo, dp) ) { + + mlog << Error << "\nupdate_mtddf_grid() -> " + << "Trouble reading \"" << vinfo->magic_str() + << " \"data from input file \"" + << mtddf->filename() << "\"\n\n"; + exit(1); + + } + +} + +return; + +} + + +//////////////////////////////////////////////////////////////////////// diff --git a/src/libcode/vx_data2d_factory/data2d_factory_utils.h b/src/libcode/vx_data2d_factory/data2d_factory_utils.h index 6c94f62202..b79119403d 100644 --- a/src/libcode/vx_data2d_factory/data2d_factory_utils.h +++ b/src/libcode/vx_data2d_factory/data2d_factory_utils.h @@ -25,6 +25,8 @@ extern GrdFileType grd_file_type(const char * filename); +extern void update_mtddf_grid(Met2dDataFile *, VarInfo *); + /////////////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/grid_stat/grid_stat.cc b/src/tools/core/grid_stat/grid_stat.cc index a3e18bfd5f..161f5bd306 100644 --- a/src/tools/core/grid_stat/grid_stat.cc +++ b/src/tools/core/grid_stat/grid_stat.cc @@ -116,6 +116,7 @@ // 058 10/03/24 Halley Gotway MET #2887 Compute weighted contingency tables. // 059 11/15/24 Halley Gotway MET #3020 SEEPS NetCDF output. // 060 05/05/24 Halley Gotway MET #3145 Add OpenMP. +// 061 12/08/25 Halley Gotway MET #3293 Fix set_attr_grid. // //////////////////////////////////////////////////////////////////////// @@ -147,14 +148,8 @@ using namespace std; using namespace netCDF; - //////////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////////// - - static void process_command_line(int, char **); static void setup_first_pass (const DataPlane &); @@ -233,7 +228,6 @@ void process_command_line(int argc, char **argv) { CommandLine cline; GrdFileType ftype, otype; ConcatString default_config_file; - DataPlane dp; const char *method_name = "process_command_line() -> "; // Set the default output directory @@ -349,24 +343,9 @@ void process_command_line(int argc, char **argv) { #endif } - // For python types and range/azimuth grids, read the first field to set the grid - if(is_python_grdfiletype(ftype) || - fcst_mtddf->grid().info().ra) { - if(!fcst_mtddf->data_plane(*conf_info.vx_opt[0].fcst_info, dp)) { - mlog << Error << "\nTrouble reading data from forecast file \"" - << fcst_file << "\"\n\n"; - exit(1); - } - } - - if(is_python_grdfiletype(otype) || - obs_mtddf->grid().info().ra) { - if(!obs_mtddf->data_plane(*conf_info.vx_opt[0].obs_info, dp)) { - mlog << Error << "\nTrouble reading data from observation file \"" - << obs_file << "\"\n\n"; - exit(1); - } - } + // Update the input grid, if needed + update_mtddf_grid(fcst_mtddf, conf_info.vx_opt[0].fcst_info); + update_mtddf_grid(obs_mtddf, conf_info.vx_opt[0].obs_info); // Determine the verification grid grid = parse_vx_grid(conf_info.vx_opt[0].fcst_info->regrid(), diff --git a/src/tools/core/wavelet_stat/wavelet_stat.cc b/src/tools/core/wavelet_stat/wavelet_stat.cc index e9a0c0d301..4ec5ec5d17 100644 --- a/src/tools/core/wavelet_stat/wavelet_stat.cc +++ b/src/tools/core/wavelet_stat/wavelet_stat.cc @@ -41,6 +41,7 @@ // 016 10/03/22 Prestopnik MET #2227 Remove using namespace netCDF from header files // 017 01/29/24 Halley Gotway MET #2801 Configure time difference warnings // 018 05/07/25 Halley Gotway MET #3145 Add OpenMP +// 019 12/08/25 Halley Gotway MET #3293 Fix set_attr_grid. // //////////////////////////////////////////////////////////////////////// @@ -165,7 +166,6 @@ static void process_command_line(int argc, char **argv) { CommandLine cline; GrdFileType ftype, otype; ConcatString default_config_file; - DataPlane dp; // Set the default output directory out_dir = replace_path(default_out_dir); @@ -231,24 +231,9 @@ static void process_command_line(int argc, char **argv) { // Process the configuration conf_info.process_config(ftype, otype); - // For python types and range/azimuth grids, read the first field to set the grid - if(is_python_grdfiletype(ftype) || - fcst_mtddf->grid().info().ra) { - if(!fcst_mtddf->data_plane(*conf_info.fcst_info[0], dp)) { - mlog << Error << "\nTrouble reading data from forecast file \"" - << fcst_file << "\"\n\n"; - exit(1); - } - } - - if(is_python_grdfiletype(otype) || - obs_mtddf->grid().info().ra) { - if(!obs_mtddf->data_plane(*conf_info.obs_info[0], dp)) { - mlog << Error << "\nTrouble reading data from observation file \"" - << obs_file << "\"\n\n"; - exit(1); - } - } + // Update the input grid, if needed + update_mtddf_grid(fcst_mtddf, conf_info.fcst_info[0]); + update_mtddf_grid(obs_mtddf, conf_info.obs_info[0]); // Determine the verification grid grid = parse_vx_grid(conf_info.fcst_info[0]->regrid(), diff --git a/src/tools/other/regrid_data_plane/regrid_data_plane.cc b/src/tools/other/regrid_data_plane/regrid_data_plane.cc index d5ea9ff797..0bd83382e1 100644 --- a/src/tools/other/regrid_data_plane/regrid_data_plane.cc +++ b/src/tools/other/regrid_data_plane/regrid_data_plane.cc @@ -25,6 +25,7 @@ // 005 04-09-20 Halley Gotway Add convert and censor options. // 006 07-06-22 Howard Soh METplus-Internal #19 Rename main to met_main // 007 09-29-22 Prestopnik MET #2227 Remove namespace std and netCDF from header files +// 008 12-08-25 Halley Gotway MET #3293 Fix set_attr_grid. // //////////////////////////////////////////////////////////////////////// @@ -254,8 +255,7 @@ void process_data_file() { // Setup the VarInfo request object VarInfoFactory v_factory; - VarInfo *vinfo; - vinfo = v_factory.new_var_info(ftype); + VarInfo *vinfo = v_factory.new_var_info(ftype); if(!vinfo) { mlog << Error << "\nprocess_data_file() -> " @@ -263,18 +263,11 @@ void process_data_file() { << "\"\n\n"; exit(1); } + config.read_string(FieldSA[0].c_str()); + vinfo->set_dict(config); - // For python types and range/azimuth grids, read the first field to set the grid - if(is_python_grdfiletype(ftype) || - fr_mtddf->grid().info().ra) { - config.read_string(FieldSA[0].c_str()); - vinfo->set_dict(config); - if(!fr_mtddf->data_plane(*vinfo, fr_dp)) { - mlog << Error << "\nTrouble reading data from file \"" - << InputFilename << "\"\n\n"; - exit(1); - } - } + // Update the input grid, if needed + update_mtddf_grid(fr_mtddf, vinfo); fr_grid = fr_mtddf->grid(); mlog << Debug(2) << "Input grid: " << fr_grid.serialize() << "\n"; From 3227dd9e75f4033ed302c45457394dd8be9695ca Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 24 Feb 2026 10:57:39 -0700 Subject: [PATCH 36/45] Bugfix #3342 main_v12.2 ndbc bad data (#3344) * Per #3342, switch to using a regular expression for finding bad data. * Per #3342, update default ugrid_max_distance and corresponding documentation. * Per #3342, need to change default ugrid_max_distance_km setting from 30 to NA to avoid differences caused in the unit test output. --- data/config/UGridConfig_lfric | 5 +++++ data/config/UGridConfig_lfric_pressure_levels | 3 +++ data/config/UGridConfig_mpas | 5 +++++ docs/Users_Guide/appendixH.rst | 2 +- src/tools/other/ascii2nc/ascii2nc.cc | 1 + src/tools/other/ascii2nc/ndbc_handler.cc | 21 +++++++------------ 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/data/config/UGridConfig_lfric b/data/config/UGridConfig_lfric index 5b21e053c5..b0ba8ec396 100644 --- a/data/config/UGridConfig_lfric +++ b/data/config/UGridConfig_lfric @@ -21,6 +21,11 @@ ugrid_metadata_map = [ { key = "time"; val = "time_instant"; } ]; +// +// Unstructured grid maximum search distance +// +ugrid_max_distance_km = NA; + //////////////////////////////////////////////////////////////////////////////// version = "V12.2.0"; diff --git a/data/config/UGridConfig_lfric_pressure_levels b/data/config/UGridConfig_lfric_pressure_levels index dd207e25e5..3ce0299b60 100644 --- a/data/config/UGridConfig_lfric_pressure_levels +++ b/data/config/UGridConfig_lfric_pressure_levels @@ -28,6 +28,9 @@ ugrid_metadata_map = [ { key = "time"; val = "time_instant"; } ]; +// +// Unstructured grid maximum search distance +// ugrid_max_distance_km = 30; //////////////////////////////////////////////////////////////////////////////// diff --git a/data/config/UGridConfig_mpas b/data/config/UGridConfig_mpas index d8cb8d9aca..b4ffe96174 100644 --- a/data/config/UGridConfig_mpas +++ b/data/config/UGridConfig_mpas @@ -21,6 +21,11 @@ ugrid_metadata_map = [ { key = "time"; val = "xtime"; } ]; +// +// Unstructured grid maximum search distance +// +ugrid_max_distance_km = NA; + //////////////////////////////////////////////////////////////////////////////// version = "V12.2.0"; diff --git a/docs/Users_Guide/appendixH.rst b/docs/Users_Guide/appendixH.rst index 6597cc02f4..49669c5bad 100644 --- a/docs/Users_Guide/appendixH.rst +++ b/docs/Users_Guide/appendixH.rst @@ -63,7 +63,7 @@ If the UGRID dataset is supported by MET, then this item is set to the string id ugrid_max_distance_km --------------------- -For PointStat, this is the distance from each UGRID cell center that PointStat will search outward to collect observations to use for verification. The default is 0 km, which by default will use the closest observation to the UGRID cell for verification. For GridStat, this is the distance from each forecast grid point to search for observation grid cells to include when interpolating to the forecast grid point locations. Currently, only the nearest point observation or gridded observation cell is used. See `Unstructured Grid Limitations`_ for additional details about interpolation when using GridStat. +For PointStat, this is the maximum allowable distance in kilometers for a point observation to be matched to the nearest UGRID cell center. If left unspecified, each point observation will be matched to the closest UGRID cell, regardless of how far apart they are. If no UGRID cells are within the specified distance, the observation will be not used for verification. For GridStat, this is the distance from each forecast grid point to search for observation grid cells to include when interpolating to the forecast grid point locations. Currently, only the nearest point observation or gridded observation cell is used. See `Unstructured Grid Limitations`_ for additional details about interpolation when using GridStat. ugrid_coordinates_file ---------------------- diff --git a/src/tools/other/ascii2nc/ascii2nc.cc b/src/tools/other/ascii2nc/ascii2nc.cc index 1f76e2aefe..0a9cf28e69 100644 --- a/src/tools/other/ascii2nc/ascii2nc.cc +++ b/src/tools/other/ascii2nc/ascii2nc.cc @@ -54,6 +54,7 @@ // 025 06/23/25 Halley Gotway MET #3148 Search input directories // 026 10/17/25 Halley Gotway MET #3266 Fix IABP/ISMN infinite loops // for empty input files +// 027 02/18/26 Halley Gotway MET #3342 Fix NDBC bad data // //////////////////////////////////////////////////////////////////////// diff --git a/src/tools/other/ascii2nc/ndbc_handler.cc b/src/tools/other/ascii2nc/ndbc_handler.cc index 3c82e77642..6774e8a757 100644 --- a/src/tools/other/ascii2nc/ndbc_handler.cc +++ b/src/tools/other/ascii2nc/ndbc_handler.cc @@ -11,6 +11,7 @@ #include +#include #include #include #include @@ -494,22 +495,16 @@ double NdbcHandler::_extractDouble(const DataLine &data_line, int ptr) const // should be missing, based on documentation here: // https://www.ndbc.noaa.gov/measdes.shtml // which suggests 'anything with only 9s is missing data' + + // MET #3342 Use a regular expression to match a wider variety of + // missing data values if (c == "MM" || - c == "99" || c == "99.0" || - c == "999" || c == "999.0" || - c == "9999" || c == "9999.0" || - c == "99999" || c == "99999.0" || - c == "999999" || c == "999999.0" || - c == "9999999" ||c == "9999999.0" || - c == "-99" || c == "-99.0" || - c == "-999" || c == "-999.0" || - c == "-9999" || c == "-9999.0" || - c == "-99999" || c == "-99999.0" || - c == "-999999" || c == "-999999.0" || - c == "-9999999" ||c == "-9999999.0") { + regex_match(c, regex("^[-]*99[9]*$|^[-]*99[9]*\\.[0]*$"))) { return bad_data_double; } - double value = atof(c.c_str()); + double value = stod(c); return value; } + +//////////////////////////////////////////////////////////////////////// From aed2118b2a947985ce41df88c3bdd75c39a693ad Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 27 Feb 2026 09:44:36 -0700 Subject: [PATCH 37/45] Feature #3348 v12.2.1 (#3352) * Per #3348, update MET_PYTHON settings, update to version 12.2.1, and add release notes. * Per #3348, MET_PYTHON is not actually required by build_met_docker.sh * Per #3342, parse and apply the file_type option from the -field string when searching for input files to sum. * Revert "Per #3342, parse and apply the file_type option from the -field string when searching for input files to sum." This reverts commit 141660d57d64420ad2041c5320c23967e49a126f. --- docs/Users_Guide/release-notes.rst | 22 +++++++++++++++++++ docs/conf.py | 6 ++--- internal/scripts/docker/build_met_docker.sh | 17 ++++++++++++++ .../scripts/environment/development.docker | 6 ++--- src/basic/vx_util/util_constants.h | 3 ++- 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/docs/Users_Guide/release-notes.rst b/docs/Users_Guide/release-notes.rst index 287fd2a477..32cea4c890 100644 --- a/docs/Users_Guide/release-notes.rst +++ b/docs/Users_Guide/release-notes.rst @@ -9,6 +9,28 @@ When applicable, release notes are followed by the GitHub issue number which des enhancement, or new feature (`MET GitHub issues `_). Important issues are listed **in bold** for emphasis. +MET Version 12.2.1 Release Notes (20260227) +------------------------------------------- + + .. dropdown:: Bugfixes + + * Fix support for the "set_attr_grid" config option when defining the verification domain + (`#3293 `_). + * Fix dependency checks and compile flag defaults in "compile_MET_all.sh" + (`#3317 `_). + * Fix ASCII2NC to handle a wider range of NDBC bad data values + (`#3342 `_). + + .. dropdown:: METbaseimage testing environment + + * Update METbaseimage to Python 3.14 + (`METbaseimage#61 `_). + + .. note:: MET version 12.2.1 is built upon METbaseimage version 3.4.9 in which the + Python version was upgraded from 3.12 to 3.14. This change only impacts + MET's Docker development and testing environment. MET version 12.1.2 should + continue working well with Python version 3.12. + MET Version 12.2.0 Release Notes (20251113) ------------------------------------------- diff --git a/docs/conf.py b/docs/conf.py index c1220f61ca..59dca642c7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,11 +20,11 @@ project = 'MET' author = 'UCAR/NCAR, NOAA, CSU/CIRA, and CU/CIRES' author_list = 'Soh, H., L. Goodrich, B. Brown, R. Bullock, J. Halley Gotway, K. Newman, J. Opatz, T. Jensen, J. Prestopnik' -version = '12.2.0' +version = '12.2.1' verinfo = version release = f'{version}' -release_year = '2025' -release_date = f'{release_year}-11-13' +release_year = '2026' +release_date = f'{release_year}-02-27' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- diff --git a/internal/scripts/docker/build_met_docker.sh b/internal/scripts/docker/build_met_docker.sh index f1b7536e70..5864a0952b 100755 --- a/internal/scripts/docker/build_met_docker.sh +++ b/internal/scripts/docker/build_met_docker.sh @@ -16,6 +16,23 @@ if [ -z ${MET_CONFIG_OPTS+x} ]; then echo "Setting MET_CONFIG_OPTS=${MET_CONFIG_OPTS} to compile all available options." fi +# Check that required MET_PYTHON environment variables +# have been set by METbaseimage +if [[ -z "${MET_PYTHON_BIN_EXE}" || + -z "${MET_PYTHON_CC}" || + -z "${MET_PYTHON_LD}" ]]; then + echo + echo "ERROR: Required Python environment variable(s) unset:" + echo "ERROR: \${MET_PYTHON_BIN_EXE}, \${MET_PYTHON_CC}, \${MET_PYTHON_LD}" + echo + exit 1 +else + echo "Using Python environment:" + echo "MET_PYTHON_BIN_EXE=${MET_PYTHON_BIN_EXE}" + echo "MET_PYTHON_CC=${MET_PYTHON_CC}" + echo "MET_PYTHON_LD=${MET_PYTHON_LD}" +fi + # Create log directory mkdir -p /met/logs diff --git a/internal/scripts/environment/development.docker b/internal/scripts/environment/development.docker index ebf9b03bec..a66771eeb3 100644 --- a/internal/scripts/environment/development.docker +++ b/internal/scripts/environment/development.docker @@ -6,10 +6,8 @@ MET_PROJ_DIR=`ls -1d /met/MET*` # Variables required to build MET export MET_DEVELOPMENT=true -export MET_PYTHON=/usr/local -export MET_PYTHON_BIN_EXE=${MET_PYTHON}/bin/python3 -export MET_PYTHON_CC="-I${MET_PYTHON}/include/python3.12" -export MET_PYTHON_LD="-L${MET_PYTHON}/lib -lpython3.12 -lcrypt -lpthread -ldl -lutil -lm" +# MET_PYTHON environment settings are defined +# in METbaseimage, as of MET version 12.2.1 export CFLAGS="-DUNDERSCORE -fPIC" export CXXFLAGS=${CFLAGS} diff --git a/src/basic/vx_util/util_constants.h b/src/basic/vx_util/util_constants.h index c42dde0e0f..e46e73919f 100644 --- a/src/basic/vx_util/util_constants.h +++ b/src/basic/vx_util/util_constants.h @@ -18,6 +18,7 @@ //////////////////////////////////////////////////////////////////////// // Released versions of MET +static const char met_version_12_2_1[] = "V12.2.1"; static const char met_version_12_2_0[] = "V12.2.0"; static const char met_version_12_1_0[] = "V12.1.0"; static const char met_version_12_0_0[] = "V12.0.0"; @@ -45,7 +46,7 @@ static const char met_version_1_1[] = "V1.1"; //////////////////////////////////////////////////////////////////////// -static const char * const met_version = met_version_12_2_0; +static const char * const met_version = met_version_12_2_1; static const char default_met_data_dir[] = "MET_BASE"; static const char txt_file_ext[] = ".txt"; static const char stat_file_ext[] = ".stat"; From 5ad7c57806a51c081074a2b1802b110b742da555 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 27 Feb 2026 15:41:10 -0700 Subject: [PATCH 38/45] Bugfix #3353 main_v12.2 sum file type (#3354) * Per #3348, update MET_PYTHON settings, update to version 12.2.1, and add release notes. * Per #3348, MET_PYTHON is not actually required by build_met_docker.sh * Per #3342, parse and apply the file_type option from the -field string when searching for input files to sum. * Revert "Per #3342, parse and apply the file_type option from the -field string when searching for input files to sum." This reverts commit 141660d57d64420ad2041c5320c23967e49a126f. * Per #3342, parse and apply the file_type option from the -field string when searching for input files to sum. * Per #3353, add this issue the v12.2.1 release notes. * Per #3353, fix issue number in comments. --- docs/Users_Guide/release-notes.rst | 2 ++ src/tools/core/pcp_combine/pcp_combine.cc | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/Users_Guide/release-notes.rst b/docs/Users_Guide/release-notes.rst index 32cea4c890..315ad0f58f 100644 --- a/docs/Users_Guide/release-notes.rst +++ b/docs/Users_Guide/release-notes.rst @@ -20,6 +20,8 @@ MET Version 12.2.1 Release Notes (20260227) (`#3317 `_). * Fix ASCII2NC to handle a wider range of NDBC bad data values (`#3342 `_). + * Fix support for the "file_type" option in the PCP-Combine "sum" command + (`#3353 `_). .. dropdown:: METbaseimage testing environment diff --git a/src/tools/core/pcp_combine/pcp_combine.cc b/src/tools/core/pcp_combine/pcp_combine.cc index 1288075749..d86ce89471 100644 --- a/src/tools/core/pcp_combine/pcp_combine.cc +++ b/src/tools/core/pcp_combine/pcp_combine.cc @@ -80,6 +80,7 @@ // 026 01/29/24 Halley Gotway MET #2801 Configure time difference warnings. // 027 05/09/24 Halley Gotway MET #2883 Allow missing input files. // 028 04/30/25 Prestopnik MET #3120 Add OpenMP +// 029 02/26/26 Halley Gotway MET #3353 Support file_type for sum // //////////////////////////////////////////////////////////////////////// @@ -782,10 +783,19 @@ static int search_pcp_dir(const char *cur_dir, const unixtime cur_ut, VarInfoFactory var_fac; VarInfo * cur_var; + // + // MET #3353: Parse the file type from the field string, if present. + // + GrdFileType ftype = FileType_None; + if(field_string.nonempty()) { + config.read_string(field_string.c_str()); + ftype = parse_conf_file_type(&config); + } + // // Create a data file object. // - mtddf = factory.new_met_2d_data_file(cur_file.c_str()); + mtddf = factory.new_met_2d_data_file(cur_file.c_str(), ftype); if(!mtddf) { mlog << Warning << "search_pcp_dir() -> " << "can't open data file \"" << cur_file << "\"\n"; From e22a3428189732588a9e6a57f531a7fc3cd95225 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 6 Mar 2026 14:32:16 -0700 Subject: [PATCH 39/45] Patch the Series-Analysis docs to match the default mask setting. --- docs/Users_Guide/series-analysis.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Users_Guide/series-analysis.rst b/docs/Users_Guide/series-analysis.rst index f623613ef5..5804263ff6 100644 --- a/docs/Users_Guide/series-analysis.rst +++ b/docs/Users_Guide/series-analysis.rst @@ -115,7 +115,7 @@ ____________________ ci_alpha = [ 0.05 ]; boot = { interval = PCTILE; rep_prop = 1.0; n_rep = 1000; rng = "mt19937"; seed = ""; } - mask = { grid = [ "FULL" ]; poly = []; } + mask = { grid = ""; poly = ""; } gradient = { dx = [ 1 ]; dy = [ 1 ]; } hss_ec_value = NA; rank_corr_flag = TRUE; From 2ea7a2f964c1d63332ca96a80f6630aa79731d3c Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 9 Mar 2026 13:43:18 -0600 Subject: [PATCH 40/45] Bugfix #3359 main_v12.2 gnu_8.5.0 (#3360) * Per #3359, update the OpenMP shared statements to remove constant variables which were causing compilation errors. With these changes, MET version 12.2.1 does compile and run on the CCS AWS instance. * Per #3359, for GNU 8.5.0 I removed the constant variables from the OpenMP shared list. But with default(none), that causes a compilation error for GNU 12.2.0. Switching default(none) to default(shared) should satisfy both GNU 8.5.0 and 12.2.0. --- src/basic/vx_util/data_cube.cc | 14 ++++---- src/basic/vx_util/data_plane.cc | 18 +++++----- src/basic/vx_util/data_plane_util.cc | 16 ++++----- src/libcode/vx_data2d/data2d_utils.cc | 16 ++++----- src/libcode/vx_regrid/vx_regrid.cc | 3 +- src/libcode/vx_regrid/vx_regrid_budget.cc | 1 - src/libcode/vx_shapedata/shapedata.cc | 34 +++++++++---------- src/libcode/vx_statistics/apply_mask.cc | 4 +-- src/libcode/vx_statistics/pair_data_point.cc | 7 ++-- src/tools/core/grid_stat/grid_stat.cc | 4 +-- src/tools/core/mode/combine_boolplanes.cc | 4 +-- src/tools/core/mode/mode_exec.cc | 2 +- src/tools/core/mode/mode_ps_file.cc | 4 +-- src/tools/core/mode/mode_superobject.cc | 3 +- src/tools/core/mode/multivar_data.cc | 4 +-- src/tools/core/mode/objects_from_netcdf.cc | 4 +-- src/tools/core/pcp_combine/pcp_combine.cc | 6 ++-- src/tools/other/gen_ens_prod/gen_ens_prod.cc | 5 ++- .../shift_data_plane/shift_data_plane.cc | 2 +- src/tools/tc_utils/tc_dland/tc_dland.cc | 2 +- 20 files changed, 74 insertions(+), 79 deletions(-) diff --git a/src/basic/vx_util/data_cube.cc b/src/basic/vx_util/data_cube.cc index 1fe9043346..fb4ed362ab 100644 --- a/src/basic/vx_util/data_cube.cc +++ b/src/basic/vx_util/data_cube.cc @@ -198,7 +198,7 @@ void DataCube::add_assign(const DataCube& other) { this->check_shape_equal(other); #pragma omp parallel default(none) \ - shared(Data, Nxyz, other, bad_data_double) + shared(Data, Nxyz, other) { #pragma omp for schedule(static) @@ -222,7 +222,7 @@ void DataCube::subtract_assign(const DataCube& other) { this->check_shape_equal(other); #pragma omp parallel default(none) \ - shared(Data, Nxyz, other, bad_data_double) + shared(Data, Nxyz, other) { #pragma omp for schedule(static) @@ -246,7 +246,7 @@ void DataCube::multiply_assign(const DataCube& other) { this->check_shape_equal(other); #pragma omp parallel default(none) \ - shared(Data, Nxyz, other, bad_data_double) + shared(Data, Nxyz, other) { #pragma omp for schedule(static) @@ -268,7 +268,7 @@ void DataCube::multiply_assign(const DataCube& other) { void DataCube::divide_assign(int denom) { #pragma omp parallel default(none) \ - shared(Data, Nxyz, denom, bad_data_double) + shared(Data, Nxyz, denom) { #pragma omp for schedule(static) @@ -292,7 +292,7 @@ void DataCube::divide_assign(const DataCube& other) { this->check_shape_equal(other); #pragma omp parallel default(none) \ - shared(Data, Nxyz, other, bad_data_double) + shared(Data, Nxyz, other) { #pragma omp for schedule(static) @@ -317,7 +317,7 @@ void DataCube::min_assign(const DataCube& other) { this->check_shape_equal(other); #pragma omp parallel default(none) \ - shared(Data, Nxyz, other, bad_data_double) + shared(Data, Nxyz, other) { #pragma omp for schedule(static) @@ -341,7 +341,7 @@ void DataCube::max_assign(const DataCube& other) { this->check_shape_equal(other); #pragma omp parallel default(none) \ - shared(Data, Nxyz, other, bad_data_double) + shared(Data, Nxyz, other) { #pragma omp for schedule(static) diff --git a/src/basic/vx_util/data_plane.cc b/src/basic/vx_util/data_plane.cc index 72ae3bcb03..86fdb12448 100644 --- a/src/basic/vx_util/data_plane.cc +++ b/src/basic/vx_util/data_plane.cc @@ -466,7 +466,7 @@ int DataPlane::n_good_data() const { int n = 0; #pragma omp parallel default(none) \ - shared(Data, n) + shared(n) { // Count number of good data values @@ -652,8 +652,8 @@ void DataPlane::standard_anomaly(const DataPlane &mn, void DataPlane::replace_bad_data(const double value) { -#pragma omp parallel default(none) \ - shared(Data, Nxy, value) +#pragma omp parallel default(shared) \ + shared(Data, Nxy) { #pragma omp for schedule(static) @@ -757,7 +757,7 @@ void DataPlane::data_range(double & data_min, double & data_max) const { data_max = -1.0e30; #pragma omp parallel default(none) \ - shared(Data, Nxy, data_min, data_max) + shared(data_min, data_max) { #pragma omp for schedule(static) \ @@ -791,7 +791,7 @@ MaskPlane DataPlane::mask_plane() const { mp.set_size(Nx, Ny); #pragma omp parallel default(none) \ - shared(Data, Nxy, mp) + shared(mp) { #pragma omp for schedule(static) @@ -964,8 +964,8 @@ bool DataPlane::fitwav_1d(const int start_wave, const int end_wave) { vector C(Nx); vector S(Nx); -#pragma omp parallel default(none) \ -shared(Nx, Ny, mnw, start_wave, end_wave, C, S) +#pragma omp parallel default(shared) \ +shared(Nx, Ny, C, S) { #pragma omp for schedule(static) @@ -1095,8 +1095,8 @@ DataPlaneArray & DataPlaneArray::operator+=(const DataPlaneArray &d) { DataPlaneArray & DataPlaneArray::operator/=(const double v) { -#pragma omp parallel default(none) \ - shared(Nplanes, Plane, v) +#pragma omp parallel default(shared) \ + shared(Nplanes, Plane) { #pragma omp for schedule(static) diff --git a/src/basic/vx_util/data_plane_util.cc b/src/basic/vx_util/data_plane_util.cc index 2c74f932dc..7596abe1f8 100644 --- a/src/basic/vx_util/data_plane_util.cc +++ b/src/basic/vx_util/data_plane_util.cc @@ -114,9 +114,9 @@ void smooth_field(const DataPlane &dp, DataPlane &smooth_dp, // For nearest neighbor, no work to do. if(width == 1 && mthd == InterpMthd::Nearest) return; -#pragma omp parallel default(none) \ +#pragma omp parallel default(shared) \ shared(mlog, Error, dp, smooth_dp) \ - shared(mthd, width, shape, wrap_lon, t, gaussian) \ + shared(mthd, width, wrap_lon, t, gaussian) \ private(v) { @@ -446,7 +446,7 @@ void apply_mask(DataPlane &in, const MaskPlane &mask) { int Nxy = mask.nx() * mask.ny(); #pragma omp parallel default(none) \ - shared(in, mask, Nxy, bad_data_double) + shared(in, mask, Nxy) { #pragma omp for schedule(static) @@ -563,7 +563,7 @@ DataPlane subtract(const DataPlane &dp1, const DataPlane &dp2) { } #pragma omp parallel default(none) \ - shared(dp1, dp2, diff, bad_data_double) + shared(dp1, dp2, diff) { #pragma omp for schedule(static) \ @@ -597,7 +597,7 @@ DataPlane normal_cdf(const DataPlane &dp, const DataPlane &mn, } #pragma omp parallel default(none) \ - shared(dp, mn, sd, cdf, bad_data_double) + shared(dp, mn, sd, cdf) { // Compute the normal CDF for each grid point @@ -643,8 +643,8 @@ DataPlane normal_cdf_inv(const double area, const DataPlane &mn, exit(1); } -#pragma omp parallel default(none) \ - shared(area, mn, sd, cdf_inv, bad_data_double) +#pragma omp parallel default(shared) \ + shared(mn, sd, cdf_inv) { // Compute the inverse of the normal CDF for each grid point @@ -683,7 +683,7 @@ DataPlane gradient(const DataPlane &dp, int dim, int delta) { grad_dp.set_constant(bad_data_double); #pragma omp parallel default(none) \ - shared(dp, dim, delta, grad_dp, bad_data_double) + shared(dp, dim, delta, grad_dp) { // Compute the gradient for each grid point diff --git a/src/libcode/vx_data2d/data2d_utils.cc b/src/libcode/vx_data2d/data2d_utils.cc index f13eaadac2..32739925ac 100644 --- a/src/libcode/vx_data2d/data2d_utils.cc +++ b/src/libcode/vx_data2d/data2d_utils.cc @@ -97,8 +97,8 @@ bool derive_wdir(const DataPlane &u2d, const DataPlane &v2d, wdir2d = u2d; wdir2d.set_constant(bad_data_double); -#pragma omp parallel default(none) \ - shared(nx, ny, u2d, v2d, wdir2d) +#pragma omp parallel default(shared) \ + shared(u2d, v2d, wdir2d) { // @@ -163,8 +163,8 @@ bool derive_wind(const DataPlane &u2d, const DataPlane &v2d, wind2d = u2d; wind2d.set_constant(bad_data_double); -#pragma omp parallel default(none) \ - shared(nx, ny, u2d, v2d, wind2d) +#pragma omp parallel default(shared) \ + shared(u2d, v2d, wind2d) { // @@ -218,8 +218,8 @@ void rotate_wdir_grid_to_earth(const DataPlane &wdir2d, const Grid &g, wdir2d_rot = wdir2d; wdir2d_rot.set_constant(bad_data_double); -#pragma omp parallel default(none) \ - shared(nx, ny, wdir2d, g, wdir2d_rot) +#pragma omp parallel default(shared) \ + shared(wdir2d, g, wdir2d_rot) { // @@ -291,8 +291,8 @@ bool rotate_uv_grid_to_earth(const DataPlane &u2d, const DataPlane &v2d, u2d_rot.set_constant(bad_data_double); v2d_rot.set_constant(bad_data_double); -#pragma omp parallel default(none) \ - shared(nx, ny, u2d, v2d, g, u2d_rot, v2d_rot) +#pragma omp parallel default(shared) \ + shared(u2d, v2d, g, u2d_rot, v2d_rot) { // diff --git a/src/libcode/vx_regrid/vx_regrid.cc b/src/libcode/vx_regrid/vx_regrid.cc index fb3e0dabbc..75309256a9 100644 --- a/src/libcode/vx_regrid/vx_regrid.cc +++ b/src/libcode/vx_regrid/vx_regrid.cc @@ -170,8 +170,7 @@ DataPlane met_regrid_area_weighted(const DataPlane & from_data, #pragma omp parallel default(none) \ shared(from_data, from_grid, to_grid, info, to_data) \ - shared(to_data_sum, wt_data_sum) \ - shared(bad_data_double) + shared(to_data_sum, wt_data_sum) { #pragma omp single diff --git a/src/libcode/vx_regrid/vx_regrid_budget.cc b/src/libcode/vx_regrid/vx_regrid_budget.cc index 2282e094cc..4cf389de32 100644 --- a/src/libcode/vx_regrid/vx_regrid_budget.cc +++ b/src/libcode/vx_regrid/vx_regrid_budget.cc @@ -33,7 +33,6 @@ DataPlane met_regrid_budget(const DataPlane & from_data, #pragma omp parallel default(none) \ shared(from_data, from_grid, to_grid, info, to_data) \ - shared(Radius, N, NN, delta) \ private(count, value, sum) { diff --git a/src/libcode/vx_shapedata/shapedata.cc b/src/libcode/vx_shapedata/shapedata.cc index 6195d07ee0..8ee5d04a4c 100644 --- a/src/libcode/vx_shapedata/shapedata.cc +++ b/src/libcode/vx_shapedata/shapedata.cc @@ -263,8 +263,8 @@ double ShapeData::area_thresh(const ShapeData *raw_ptr, const int nxy = data.nxy(); // Number of points inside the object that meet the threshold criteria -#pragma omp parallel default(none) \ - shared(raw_ptr, obj_thresh, nxy, data, cur_area) +#pragma omp parallel default(shared) \ + shared(raw_ptr, obj_thresh, cur_area) { #pragma omp for schedule(static) \ @@ -1293,7 +1293,7 @@ void apply_mask(ShapeData &f, const ShapeData &mask) { } #pragma omp parallel default(none) \ - shared(f, mask, bad_data_float) + shared(f, mask) { // @@ -1332,8 +1332,8 @@ void ShapeData::threshold(SingleThresh t) { // const int nxy = data.nxy(); -#pragma omp parallel default(none) \ - shared(t, data, nxy) +#pragma omp parallel default(shared) \ + shared(t, data) { #pragma omp for schedule(static) @@ -1354,8 +1354,8 @@ void ShapeData::set_to_1_or_0() { const int nxy = data.nxy(); -#pragma omp parallel default(none) \ - shared(data, nxy) +#pragma omp parallel default(shared) \ + shared(data) { #pragma omp for schedule(static) @@ -1421,8 +1421,8 @@ void ShapeData::threshold_attr(const map &attr_map, // Zero out discarded shapes const int nxy = data.nxy(); -#pragma omp parallel default(none) \ - shared(keep_object, sd_split, data, nxy) +#pragma omp parallel default(shared) \ + shared(keep_object, sd_split, data) { #pragma omp for schedule(static) @@ -1459,8 +1459,8 @@ void ShapeData::threshold_area(SingleThresh t) { // const int nxy = data.nxy(); -#pragma omp parallel default(none) \ - shared(t, area_object, sd_split, data, nxy) +#pragma omp parallel default(shared) \ + shared(t, area_object, sd_split, data) { #pragma omp for schedule(static) @@ -1543,8 +1543,8 @@ void ShapeData::threshold_intensity(const ShapeData *sd_ptr, int perc, // const int nxy = data.nxy(); -#pragma omp parallel default(none) \ - shared(t, inten_object, sd_split, data, nxy) +#pragma omp parallel default(shared) \ + shared(t, inten_object, sd_split, data) { #pragma omp for schedule(static) @@ -1714,8 +1714,8 @@ ShapeData select(const ShapeData &id, int n) { ShapeData d(id); const int nxy = id.data.nxy(); -#pragma omp parallel default(none) \ - shared(id, d, n, nxy) +#pragma omp parallel default(shared) \ + shared(id, d, n) { #pragma omp for schedule(static) @@ -1737,8 +1737,8 @@ void ShapeData::filter(SingleThresh t) { const int nxy = data.nxy(); -#pragma omp parallel default(none) \ - shared(t, data, nxy) +#pragma omp parallel default(shared) \ + shared(t, data) { #pragma omp for schedule(static) diff --git a/src/libcode/vx_statistics/apply_mask.cc b/src/libcode/vx_statistics/apply_mask.cc index 7ff07063ef..97d9929705 100644 --- a/src/libcode/vx_statistics/apply_mask.cc +++ b/src/libcode/vx_statistics/apply_mask.cc @@ -124,8 +124,8 @@ void parse_grid_weight(const Grid &grid, const GridWeightType t, wgt_dp.clear(); wgt_dp.set_size(grid.nx(), grid.ny()); -#pragma omp parallel default(none) \ - shared(grid, t, wgt_dp) +#pragma omp parallel default(shared) \ + shared(grid, wgt_dp) { // Compute weight for each grid point diff --git a/src/libcode/vx_statistics/pair_data_point.cc b/src/libcode/vx_statistics/pair_data_point.cc index f8193508a9..53ea1a823c 100644 --- a/src/libcode/vx_statistics/pair_data_point.cc +++ b/src/libcode/vx_statistics/pair_data_point.cc @@ -904,10 +904,9 @@ void apply_mpr_thresh_mask(DataPlane &fcst_dp, DataPlane &obs_dp, bool ocmn_flag = !(ocmn_dp.is_empty()); bool ocsd_flag = !(ocsd_dp.is_empty()); -#pragma omp parallel default(none) \ - shared(fcst_dp, obs_dp, fcmn_dp, fcsd_dp, ocmn_dp, ocsd_dp, m) \ - shared(nxy, n_skip, fcmn_flag, fcsd_flag, ocmn_flag, ocsd_flag) \ - shared(bad_data_double) +#pragma omp parallel default(shared) \ + shared(fcst_dp, obs_dp, fcmn_dp, fcsd_dp, ocmn_dp, ocsd_dp, m) \ + shared(nxy, n_skip, fcmn_flag, fcsd_flag, ocmn_flag, ocsd_flag) { // Loop over the pairs diff --git a/src/tools/core/grid_stat/grid_stat.cc b/src/tools/core/grid_stat/grid_stat.cc index 161f5bd306..7ab0f071ad 100644 --- a/src/tools/core/grid_stat/grid_stat.cc +++ b/src/tools/core/grid_stat/grid_stat.cc @@ -2977,7 +2977,7 @@ void write_nc(const ConcatString &field_name, const DataPlane &dp, &conf_info.mask_map[conf_info.vx_opt[i_vx].mask_name[i]]; #pragma omp parallel default(none) \ - shared(grid, DefaultTO, apply_mask, mask_ptr, data, dp, bad_data_float) + shared(grid, DefaultTO, apply_mask, mask_ptr, data, dp) { // Store the data @@ -3139,7 +3139,7 @@ void write_nbrhd_nc(const DataPlane &fcst_dp, const DataPlane &obs_dp, #pragma omp parallel default(none) \ shared(grid, DefaultTO, apply_mask, mask_ptr) \ - shared(fcst_data, obs_data, fcst_dp, obs_dp, bad_data_float) + shared(fcst_data, obs_data, fcst_dp, obs_dp) { // Store the forecast and observation values diff --git a/src/tools/core/mode/combine_boolplanes.cc b/src/tools/core/mode/combine_boolplanes.cc index 34bffe6a34..08a55be47c 100644 --- a/src/tools/core/mode/combine_boolplanes.cc +++ b/src/tools/core/mode/combine_boolplanes.cc @@ -59,8 +59,8 @@ void boolplane_to_pgm(const BoolPlane & in, Pgm & out) { out.set_size_xy(in.nx(), in.ny()); out.all_white(); -#pragma omp parallel default(none) \ - shared(out, in, black, white) +#pragma omp parallel default(shared) \ + shared(out, in) { #pragma omp for schedule(static) \ diff --git a/src/tools/core/mode/mode_exec.cc b/src/tools/core/mode/mode_exec.cc index 98d51a7a7f..5a0a4997c0 100644 --- a/src/tools/core/mode/mode_exec.cc +++ b/src/tools/core/mode/mode_exec.cc @@ -1963,7 +1963,7 @@ void ModeExecutive::write_obj_netcdf(const ModeNcOutInfo & info) } #pragma omp parallel default(none) \ - shared(grid, info, DefaultTO, unmatched_id, bad_data_int) \ + shared(grid, info, DefaultTO) \ shared(fcst_raw_data, obs_raw_data) \ shared(fcst_obj_raw_data, fcst_obj_data) \ shared(obs_obj_raw_data, obs_obj_data) \ diff --git a/src/tools/core/mode/mode_ps_file.cc b/src/tools/core/mode/mode_ps_file.cc index c6ef6d828f..bddefd8a6b 100644 --- a/src/tools/core/mode/mode_ps_file.cc +++ b/src/tools/core/mode/mode_ps_file.cc @@ -1313,8 +1313,8 @@ Box valid_xy_bb(const ShapeData * wd_ptr, const Grid & grid) const int data_nx = wd_ptr->data.nx(); const int data_ny = wd_ptr->data.ny(); -#pragma omp parallel default(none) \ - shared(data_nx, data_ny, wd_ptr) \ +#pragma omp parallel default(shared) \ + shared(wd_ptr) \ shared(L, B, R, T) { diff --git a/src/tools/core/mode/mode_superobject.cc b/src/tools/core/mode/mode_superobject.cc index 05eeff09c4..1d2ecd78b0 100644 --- a/src/tools/core/mode/mode_superobject.cc +++ b/src/tools/core/mode/mode_superobject.cc @@ -185,8 +185,7 @@ ModeSuperObject::ModeSuperObject(bool isFcst, int n_files, bool do_clusters, _simple_sd = ShapeData(*(mvd[0]->_simple->_sd)); auto merge_sd = ShapeData(*(mvd[0]->_simple->_sd)); -#pragma omp parallel default(none) \ - shared(nx, ny, bad_data_double) \ +#pragma omp parallel default(shared) \ shared(_simple_result, _simple_sd) \ shared(merge_result, merge_sd) { diff --git a/src/tools/core/mode/multivar_data.cc b/src/tools/core/mode/multivar_data.cc index 9564243628..bfb811d1c2 100644 --- a/src/tools/core/mode/multivar_data.cc +++ b/src/tools/core/mode/multivar_data.cc @@ -333,8 +333,8 @@ static void populate_bool_plane(const string &name, const int * buf, int nyes=0; -#pragma omp parallel default(none) \ - shared(nx, ny, buf, nyes, bp_out) +#pragma omp parallel default(shared) \ + shared(buf, nyes, bp_out) { #pragma omp for schedule(static) \ diff --git a/src/tools/core/mode/objects_from_netcdf.cc b/src/tools/core/mode/objects_from_netcdf.cc index 03dfcba97b..f99a65504e 100644 --- a/src/tools/core/mode/objects_from_netcdf.cc +++ b/src/tools/core/mode/objects_from_netcdf.cc @@ -141,8 +141,8 @@ static void populate_bool_plane(const int * buf, const int nx, const int ny, Boo int nyes = 0.0; -#pragma omp parallel default(none) \ - shared(nx, ny, buf, nyes, bp_out) +#pragma omp parallel default(shared) \ + shared(buf, nyes, bp_out) { #pragma omp for schedule(static) \ diff --git a/src/tools/core/pcp_combine/pcp_combine.cc b/src/tools/core/pcp_combine/pcp_combine.cc index d86ce89471..f078e7e299 100644 --- a/src/tools/core/pcp_combine/pcp_combine.cc +++ b/src/tools/core/pcp_combine/pcp_combine.cc @@ -1209,7 +1209,7 @@ static void do_derive_command() { der_dp = max_dp; #pragma omp parallel default(none) \ - shared(nxy, max_dp, min_dp, bad_data_double, der_dp) + shared(nxy, max_dp, min_dp, der_dp) { #pragma omp for schedule(static) @@ -1231,7 +1231,7 @@ static void do_derive_command() { der_dp = sum_dp; #pragma omp parallel default(none) \ - shared(nxy, sum_dp, vld_dp, bad_data_double, der_dp) + shared(nxy, sum_dp, vld_dp, der_dp) { #pragma omp for schedule(static) @@ -1254,7 +1254,7 @@ static void do_derive_command() { der_dp = sum_dp; #pragma omp parallel default(none) \ - shared(nxy, sum_dp, sum_sq_dp, vld_dp, bad_data_double, der_dp) \ + shared(nxy, sum_dp, sum_sq_dp, vld_dp, der_dp) \ private(v) { diff --git a/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/src/tools/other/gen_ens_prod/gen_ens_prod.cc index c9d1d8b613..c31d63043c 100644 --- a/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -620,8 +620,7 @@ static void get_ens_mean_stdev(GenEnsProdVarInfo *ens_info, #pragma omp parallel default(none) \ shared(nxy, emn_dp, esd_dp) \ shared(emn_cnt, emn_sum) \ - shared(esd_cnt, esd_sum, esd_ssq) \ - shared(bad_data_double) + shared(esd_cnt, esd_sum, esd_ssq) { #pragma omp for schedule(static) @@ -861,7 +860,7 @@ static void write_ens_nc(GenEnsProdVarInfo *ens_info, int n_ens_vld, double t = conf_info.vld_data_thresh; #pragma omp parallel default(none) \ - shared(ens_vld, n_ens_vld, t, bad_data_float) \ + shared(ens_vld, n_ens_vld, t) \ shared(ens_mean, ens_stdev, ens_minus, ens_plus, ens_min, ens_max, ens_range) \ shared(sum_na, cnt_na, min_na, max_na, stdev_sum_na, stdev_ssq_na, stdev_cnt_na) { diff --git a/src/tools/other/shift_data_plane/shift_data_plane.cc b/src/tools/other/shift_data_plane/shift_data_plane.cc index 072ddbff70..a5f63921fc 100644 --- a/src/tools/other/shift_data_plane/shift_data_plane.cc +++ b/src/tools/other/shift_data_plane/shift_data_plane.cc @@ -264,7 +264,7 @@ void process_data_file() { #pragma omp parallel default(none) \ shared(dp_shift, dp_in, dx, dy, grid) \ - shared(Method, Width, Shape, bad_data_double) + shared(Method, Width, Shape) { // Shift the data diff --git a/src/tools/tc_utils/tc_dland/tc_dland.cc b/src/tools/tc_utils/tc_dland/tc_dland.cc index 57fe8fc555..ab155d3406 100644 --- a/src/tools/tc_utils/tc_dland/tc_dland.cc +++ b/src/tools/tc_utils/tc_dland/tc_dland.cc @@ -256,7 +256,7 @@ void process_distances() { << " points in grid (" << grid.serialize() << ")...\n"; #pragma omp parallel default(none) \ - shared(DefaultTO, grid, dland, land_array, nautical_miles_per_km) + shared(DefaultTO, grid, dland, land_array) { // Loop over the grid and compute the distance to land for each point From a8005dccf623358c8ab1da1e804d93529db7e75e Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 24 Mar 2026 11:45:22 -0700 Subject: [PATCH 41/45] Bugfix #3362 main_v12.2 seeps_pairs_nc (#3363) * Per #3362, update compute_aggregated_seeps_grid() to store the forecast timing info in the SEEPS output fields. * hotfix: fix broken copy of diff files needed after changes to diff_util output * Per #3362, update version of actions to get passed Node.js 20 warnings from GHA. * Per #3362, do still need to use upload-artifact/merge@7 * Update Docker image scanning action to version 2 --------- Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> Co-authored-by: MET Tools Test Account --- .../build_docker_and_trigger_metplus.yml | 4 +- .github/workflows/compilation_options.yml | 8 +-- .github/workflows/documentation.yml | 8 +-- .github/workflows/release-docker-images.yml | 12 ++-- .github/workflows/sonarqube.yml | 4 +- .github/workflows/testing.yml | 66 +++++++++---------- .github/workflows/update_truth.yml | 2 +- internal/test_unit/python/comp_dir.py | 2 +- src/libcode/vx_statistics/compute_stats.cc | 8 ++- 9 files changed, 58 insertions(+), 56 deletions(-) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 1b1b12752d..4b76478869 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -19,14 +19,14 @@ jobs: name: Handle Docker Image runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Get branch name id: get_branch_name run: echo branch_name=${GITHUB_REF#refs/heads/} >> $GITHUB_OUTPUT - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} diff --git a/.github/workflows/compilation_options.yml b/.github/workflows/compilation_options.yml index 0cf00302ae..b36a94b0a3 100644 --- a/.github/workflows/compilation_options.yml +++ b/.github/workflows/compilation_options.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set job controls id: job_status run: .github/jobs/set_job_controls.sh @@ -73,13 +73,13 @@ jobs: config: '--disable-openmp' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Create directories to store output run: mkdir -p ${RUNNER_WORKSPACE}/logs - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -98,7 +98,7 @@ jobs: - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 9f061df17b..87a07cc5ab 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -18,8 +18,8 @@ jobs: name: Build Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: python-version: '3.8' - name: Install dependencies @@ -29,12 +29,12 @@ jobs: python -m pip install -r docs/requirements.txt - name: Build docs run: ./.github/jobs/build_documentation.sh - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: always() with: name: documentation path: artifact/documentation - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: failure() with: name: documentation_warnings.log diff --git a/.github/workflows/release-docker-images.yml b/.github/workflows/release-docker-images.yml index 2d2f13e06a..f4dfd654f7 100644 --- a/.github/workflows/release-docker-images.yml +++ b/.github/workflows/release-docker-images.yml @@ -35,7 +35,7 @@ jobs: update_latest: ${{ steps.get-versions.outputs.update_latest }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: repository: 'dtcenter/metplus' ref: 'develop' @@ -80,9 +80,9 @@ jobs: - name: Free Disk Space uses: dtcenter/metplus-action-free-disk-space@v1 - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: ref: ${{ matrix.version }} path: ${{ matrix.version }} @@ -93,7 +93,7 @@ jobs: run: mkdir -p ${RUNNER_WORKSPACE}/logs - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -112,7 +112,7 @@ jobs: - name: Upload build logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: build_logs_${{ matrix.version }} path: ${{ runner.workspace }}/logs @@ -130,7 +130,7 @@ jobs: - name: Scan Docker Images id: security-scan continue-on-error: false - uses: dtcenter/metplus-action-scan-docker-images@v1 + uses: dtcenter/metplus-action-scan-docker-images@v2 with: images: | [ diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index 8e37fc9e65..97e013bd85 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -45,7 +45,7 @@ jobs: steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: # Disable shallow clones for better analysis fetch-depth: 0 @@ -84,7 +84,7 @@ jobs: - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_sonarqube path: ${{ runner.workspace }}/logs diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 6ea54ddc99..173de503c4 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -50,7 +50,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set job controls id: job_status run: .github/jobs/set_job_controls.sh @@ -76,13 +76,13 @@ jobs: needs: job_control if: ${{ needs.job_control.outputs.run_compile == 'true' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Create directories to store output run: mkdir -p ${RUNNER_WORKSPACE}/logs - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -109,7 +109,7 @@ jobs: - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_compile path: ${{ runner.workspace }}/logs @@ -122,7 +122,7 @@ jobs: if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} steps: - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ vars.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} @@ -151,7 +151,7 @@ jobs: tests: 'pb2nc madis2nc pcp_combine gen_ens_prod regrid' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 @@ -164,14 +164,14 @@ jobs: INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_1a_${{ matrix.jobid }} path: ${{ runner.workspace }}/output - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_unit_1a_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs @@ -191,7 +191,7 @@ jobs: tests: 'met_test_scripts mode_multivar mode_graphics mtd airnow gsi_tools netcdf modis series_analysis wwmca_regrid gen_vx_mask interp_shape grid_diag grib_tables lidar2nc shift_data_plane trmm2nc aeronet wwmca_plot ioda2nc gaussian' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 @@ -204,14 +204,14 @@ jobs: INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_1b_${{ matrix.jobid }} path: ${{ runner.workspace }}/output - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_unit_1b_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs @@ -233,7 +233,7 @@ jobs: tests: 'ref_config_lead_36' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 @@ -246,14 +246,14 @@ jobs: INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_1c_${{ matrix.jobid }} path: ${{ runner.workspace }}/output - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_rc_leads_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs @@ -271,13 +271,13 @@ jobs: tests: 'ref_config' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 - name: Download ref_config_leads output from artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: path: ${{ runner.workspace }}/output pattern: unit_1c_job* @@ -291,14 +291,14 @@ jobs: INPUT_DATA_VERSION: 'none' - name: Upload output as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_2c_${{ matrix.jobid }} path: ${{ runner.workspace }}/output - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_unit_2c_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs @@ -326,13 +326,13 @@ jobs: tests: 'grid_weight point_weight' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 - name: Download 1a output from artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: path: ${{ runner.workspace }}/output pattern: unit_1a_job* @@ -346,14 +346,14 @@ jobs: INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_2a_${{ matrix.jobid }} path: ${{ runner.workspace }}/output - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_unit_2a_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs @@ -379,13 +379,13 @@ jobs: tests: 'python point2grid plot_data_plane mode mode_analysis perc_thresh hira plot_point_obs quality_filter obs_summary duplicate_flag' fail-fast: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 - name: Download 1a output from artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: path: ${{ runner.workspace }}/output pattern: unit_1a_job* @@ -399,14 +399,14 @@ jobs: INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_2b_${{ matrix.jobid }} path: ${{ runner.workspace }}/output - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_unit_2b_${{ matrix.jobid }} path: ${{ runner.workspace }}/logs @@ -419,14 +419,14 @@ jobs: if: ${{ needs.job_control.outputs.run_diff == 'true' }} steps: - name: Download data from previous jobs - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 - name: Copy test output into single directory run: | mkdir ${RUNNER_WORKSPACE}/output cp -r unit_*/* ${RUNNER_WORKSPACE}/output/ - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Run Diff Tests in Docker run: .github/jobs/run_diff_docker.sh @@ -437,7 +437,7 @@ jobs: - name: Upload diff files as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: diff path: ${{ runner.workspace }}/diff @@ -445,7 +445,7 @@ jobs: - name: Upload logs as artifact if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: logs_diff path: ${{ runner.workspace }}/logs @@ -458,7 +458,7 @@ jobs: if: ${{ always() }} steps: - name: Upload merged logs as artifact - uses: actions/upload-artifact/merge@v4 + uses: actions/upload-artifact/merge@v7 with: name: logs pattern: logs_* @@ -470,13 +470,13 @@ jobs: needs: [job_control, unit_1b, unit_2a, unit_2b, unit_2c] if: ${{ needs.job_control.outputs.run_update_truth == 'true' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Free disk space uses: dtcenter/metplus-action-free-disk-space@v1 - name: Download data from previous jobs - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 - name: Copy test output into single directory run: | diff --git a/.github/workflows/update_truth.yml b/.github/workflows/update_truth.yml index a5ce785489..8074dc42f7 100644 --- a/.github/workflows/update_truth.yml +++ b/.github/workflows/update_truth.yml @@ -26,7 +26,7 @@ jobs: fi echo ERROR: Branch is $branch_name - must be develop or match main_vX.Y exit 1 - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 name: Checkout repository with: fetch-depth: 0 diff --git a/internal/test_unit/python/comp_dir.py b/internal/test_unit/python/comp_dir.py index e547022d7c..3f6bc6cf64 100755 --- a/internal/test_unit/python/comp_dir.py +++ b/internal/test_unit/python/comp_dir.py @@ -83,7 +83,7 @@ def copy_diff_files(diff_files, truth_dir, output_dir, diff_dir=''): if not diff_dir: diff_dir = os.path.join(output_dir, 'diff') - for n, (truth_file, out_file, _, diff_file) in enumerate(diff_files): + for n, (truth_file, out_file, _, diff_file, _) in enumerate(diff_files): print(f"\n[{n+1}]", end="") if truth_file: copy_to_diff_dir( diff --git a/src/libcode/vx_statistics/compute_stats.cc b/src/libcode/vx_statistics/compute_stats.cc index edaa470cdd..c94b20dcc5 100644 --- a/src/libcode/vx_statistics/compute_stats.cc +++ b/src/libcode/vx_statistics/compute_stats.cc @@ -1699,9 +1699,11 @@ void compute_aggregated_seeps_grid(const DataPlane &fcst_dp, const DataPlane &ob double obs_sum = 0.0; double fcst_sum = 0.0; - seeps_dp.set_size(nx, ny); - seeps_dp_fcat.set_size(nx, ny); - seeps_dp_ocat.set_size(nx, ny); + // MET #3362: Initialize dimensions and timing info + seeps_dp = fcst_dp; + seeps_dp.set_constant(0.0); + seeps_dp_fcat = seeps_dp; + seeps_dp_ocat = seeps_dp; seeps_agg->clear(); mlog << Debug(9) << method_name From ea53f07a8e552c82b6a350bde025df4cf45acbf0 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 29 Apr 2026 11:52:28 -0700 Subject: [PATCH 42/45] Bugfix #3374 main_v12.2 false_easting_northing (#3376) * Per #3374, update nc_cf_file.cc to apply false_easting and false_northing offsets. Also include an OpenMP patch when compiling on casper. * Per #3374, update comp_dir.py to ignore a small recurring difference in the ALAL2010_stat.out file. --------- Co-authored-by: MET Tools Test Account --- internal/test_unit/python/comp_dir.py | 12 ++++++++---- src/libcode/vx_data2d_nc_cf/nc_cf_file.cc | 21 ++++++++++++++++++--- src/libcode/vx_regrid/vx_regrid_budget.cc | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/internal/test_unit/python/comp_dir.py b/internal/test_unit/python/comp_dir.py index 3f6bc6cf64..cc9aa5e6c3 100755 --- a/internal/test_unit/python/comp_dir.py +++ b/internal/test_unit/python/comp_dir.py @@ -14,7 +14,7 @@ raise e sys.path.append(metplus_util_path) -from diff_util import compare_dir +import diff_util as du def comp_dir(truth_dir, output_dir, debug=True, save_diff=True): @@ -43,11 +43,15 @@ def comp_dir(truth_dir, output_dir, debug=True, save_diff=True): """ start_time = dt.datetime.now() + + # Custom rounding overrides for MET unit test output + du.ROUNDING_OVERRIDES['ALAL2010_stat.out'] = 4 + print('******************************') print("Comparing output to truth data") - diff_files = compare_dir(truth_dir, output_dir, - debug=debug, - save_diff=save_diff) + diff_files = du.compare_dir(truth_dir, output_dir, + debug=debug, + save_diff=save_diff) end_time = dt.datetime.now() runtime = end_time - start_time diff --git a/src/libcode/vx_data2d_nc_cf/nc_cf_file.cc b/src/libcode/vx_data2d_nc_cf/nc_cf_file.cc index 00dc6f8fba..2505f074d0 100644 --- a/src/libcode/vx_data2d_nc_cf/nc_cf_file.cc +++ b/src/libcode/vx_data2d_nc_cf/nc_cf_file.cc @@ -1912,6 +1912,20 @@ void NcCfFile::get_grid_mapping_lambert_conformal_conic(const NcVar *grid_mappin return; } + // false_easting, optional + + double false_east = get_nc_var_att_double( + grid_mapping_var, "false_easting", false); + + if(is_bad_data(false_east)) false_east = 0.0; + + // false_northing, optional + + double false_north = get_nc_var_att_double( + grid_mapping_var, "false_northing", false); + + if(is_bad_data(false_north)) false_north = 0.0; + // Look for the x/y dimensions and x/y coordinate variables find_xy_vars(method_name); @@ -1987,10 +2001,11 @@ void NcCfFile::get_grid_mapping_lambert_conformal_conic(const NcVar *grid_mappin get_nc_data(_yCoordVar, y_values.data()); - // Unit conversion + // MET #3374 Support false easting and northing offsets + // Unit conversion and false northing and easting offsets - for (int i = 0; i Date: Thu, 7 May 2026 09:13:03 -0600 Subject: [PATCH 43/45] Bugfix #3370 main_v12.2 tc_rmw BEST tracks (#3371) * Per #3370, update tc_rmw to check for analysis track when parse ATCF input files. * Per #3370, update tc_rmw.cc to hard-code the expected BEST track name. --- src/tools/tc_utils/tc_rmw/tc_rmw.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tools/tc_utils/tc_rmw/tc_rmw.cc b/src/tools/tc_utils/tc_rmw/tc_rmw.cc index e14421d786..9872d44415 100644 --- a/src/tools/tc_utils/tc_rmw/tc_rmw.cc +++ b/src/tools/tc_utils/tc_rmw/tc_rmw.cc @@ -20,6 +20,7 @@ // 003 09/28/22 Prestopnik MET #2227 Remove namspace std and netCDF from header files // 004 04/26/23 Halley Gotway MET #2523 Reorder NetCDF dimensions // 005 03/11/24 Halley Gotway MET #2833 range/azimuth grid +// 006 04/13/26 Halley Gotway MET #3370 check for analysis tracks // //////////////////////////////////////////////////////////////////////// @@ -340,6 +341,12 @@ void process_track_files(const StringArray& files, // Initialize counts tot_read = tot_add = 0; + // Set metadata pointer + StringArray BestTechnique; + BestTechnique.add("BEST"); + BestTechnique.set_ignore_case(true); + line.set_best_technique(&BestTechnique); + // Process input ATCF files for(int i = 0; i < files.n(); i++) { @@ -372,7 +379,8 @@ void process_track_files(const StringArray& files, if(!is_keeper(&line)) continue; // Attempt to add current line to TrackInfoArray - if(tracks.add(line, true, false)) { + // MET #3370 check for analysis tracks + if(tracks.add(line, true, true)) { cur_add++; tot_add++; } From 803e30b6e80ca8f1940c6aa23f3578b33d9bda5f Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 15 Jul 2026 14:14:55 -0600 Subject: [PATCH 44/45] Bugfix #3381 Added radian_to_degree (#3414) * #3381 Added radian_to_degree * #3381 Corrected typo --------- Co-authored-by: Howard Soh --- src/libcode/vx_data2d_ugrid/ugrid_file.cc | 41 +++++++++++++++++++++-- src/libcode/vx_data2d_ugrid/ugrid_file.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/libcode/vx_data2d_ugrid/ugrid_file.cc b/src/libcode/vx_data2d_ugrid/ugrid_file.cc index 9024cdfd01..cbcc84a219 100644 --- a/src/libcode/vx_data2d_ugrid/ugrid_file.cc +++ b/src/libcode/vx_data2d_ugrid/ugrid_file.cc @@ -38,6 +38,7 @@ using namespace netCDF; static const char *def_user_config = "UGridConfig_user"; static const char *def_config_prefix = "UGridConfig_"; static const char *def_config_prefix2 = "MET_BASE/config/UGridConfig_"; +constexpr double lat_epsilon = 0.00001; array DIM_KEYS = { "dim_face", "dim_node", "dim_edge", "dim_time", "dim_vert" @@ -890,6 +891,40 @@ void UGridFile::read_config(ConcatString config_filename) { } +//////////////////////////////////////////////////////////////////////// + +void UGridFile::radian_to_degree(vector &lat_values, const int lat_count) const { + const char *method_name = "UGridFile::radian_to_degree() -> "; + int lat_adjusted = 0; + int lat_adjusted_total = 0; + for (int idx=0; idx 90.0) { + if (!is_eq(lat_values[idx], 90.0, lat_epsilon)) { + mlog << Warning << "\n" << method_name << "adjusted " << lat_values[idx] + << " (delta: " << (lat_values[idx] - 90.0) << ") to 90.0\n\n"; + lat_adjusted++; + } + lat_values[idx] = 90.0; + lat_adjusted_total++; + } + else if (lat_values[idx] < -90.0) { + if (!is_eq(lat_values[idx], -90.0, lat_epsilon)) { + mlog << Warning << "\n" << method_name << "adjusted " << lat_values[idx] + << " (delta: " << (lat_values[idx] + 90.0) << ") to -90.0\n\n"; + lat_adjusted++; + } + lat_values[idx] = -90.0; + lat_adjusted_total++; + } + } + if (lat_adjusted_total > 0) { + mlog << Debug(4) << method_name << "adjusted " << lat_adjusted << " (" + << lat_adjusted_total << ") latitudes\n"; + } +} + + //////////////////////////////////////////////////////////////////////// @@ -927,13 +962,13 @@ void UGridFile::read_netcdf_grid() if (get_var_units(_latVar, units_value)) { if (units_value == "rad" || units_value == "radian") { - mlog << Debug(6) << method_name << "convert " << units_value << " to degree for lat\n"; - for (int idx=0; idx &lat_values, const int lat_count) const; void read_config(ConcatString config_filename); void read_netcdf_grid(); From 8afca761c4f9276a40deb985bd0f168954471248 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 21 Jul 2026 18:36:17 -0600 Subject: [PATCH 45/45] Bugfix 3406 negative value with at main v12.2 (#3419) * #3406 Update pointer if negative sign * #3406 Added get_index_at_nc_data * #3406 Separedt get_real_dimension * #3406 Corrected offset for negative sign * #3406 Support negative value ranges --------- Co-authored-by: Howard Soh --- src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc | 17 +++- src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.cc | 76 +++++++++++++---- src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.h | 2 + .../vx_data2d_nc_wrf/var_info_nc_wrf.cc | 20 ++++- src/libcode/vx_nc_util/nc_utils.cc | 83 ++++++++++++++++++- src/libcode/vx_nc_util/nc_utils.h | 3 +- 6 files changed, 179 insertions(+), 22 deletions(-) diff --git a/src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc b/src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc index 408edf31f7..710e45555d 100644 --- a/src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc +++ b/src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc @@ -208,8 +208,23 @@ void VarInfoNcCF::set_magic(const ConcatString &nstr, const ConcatString &lstr) as_offset = (*ptr2 != '@'); if (!as_offset) ptr2++; + ptr3 = strchr(ptr2, '-'); + //skip negative sign of the negative value to check the range + if (ptr3 != nullptr && ptr3 == ptr2) ptr3 = strchr((ptr2+1), '-'); + // Check for a range of levels - if ((ptr3 = strchr(ptr2, '-')) != nullptr) { + if (ptr3 != nullptr && ptr3 != ptr2) { + *ptr3 = 0; + ptr3++; + if (*ptr3 == '@') { + if (as_offset) { + mlog << Error << "\n" << method_name + << "Can not mix an offset and a value for NetCDF variable \"" + << MagicStr << "\".\n\n"; + exit(1); + } + ptr3++; // to support @vlevel_lower-@vlevel_upper + } // Check if a range has already been supplied if (Dimension.has(range_flag)) { diff --git a/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.cc b/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.cc index 58b586b186..7d53df269f 100644 --- a/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.cc +++ b/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.cc @@ -121,33 +121,75 @@ void MetNcWrfDataFile::dump(ostream & out, int depth) const { //////////////////////////////////////////////////////////////////////// +bool MetNcWrfDataFile::get_real_dimension(const VarInfoNcWrf *vinfo_nc, + const NcVarInfo *info, LongArray &dimension) const { + static const string method_name + = "MetNcWrfDataFile::get_real_dimension() ->"; + int dim_count = dimension.n_elements(); + for (int k=0; klevel().is_offset()) { + dimension[k] = nint(vinfo_nc->level().lower()); + continue; + } + + if (dimension[k] != vx_data2d_dim_by_value && dimension[k] != range_flag) continue; + + string dim_name = GET_NC_NAME(get_nc_dim(info->var, k)); + NcVarInfo *var_info = find_var_info_by_dim_name(WrfNc->Var, dim_name, + WrfNc->Nvars); + if (var_info == nullptr) continue; + + if (dimension[k] == vx_data2d_dim_by_value) { + long new_offset = get_index_at_nc_data(var_info->var, + vinfo_nc->dim_value(k), + dim_name, (k == info->t_slot)); + if (new_offset != bad_data_int) dimension[k] = new_offset; + else { + mlog << Warning << "\n" << method_name + << "for \"" << vinfo_nc->req_name() + << "\" variable, the dimension value " + << vinfo_nc->dim_value(k) << " for " << dim_name + << " does not exist\n\n"; + return false; + } + } + else if (dimension[k] == range_flag) { + double lower = vinfo_nc->level().lower(); + double upper = vinfo_nc->level().upper(); + long new_offset = get_index_at_nc_data(var_info->var, lower, upper, + dim_name, (k == info->t_slot)); + if (new_offset != bad_data_int) dimension[k] = new_offset; + else { + mlog << Warning << "\n" << method_name + << "for \"" << vinfo_nc->req_name() + << "\" variable, the dimension value between " + << lower << " and " << upper << " for " << dim_name + << " does not exist\n\n"; + return false; + } + } + } + return true; + } + +//////////////////////////////////////////////////////////////////////// + bool MetNcWrfDataFile::data_plane(VarInfo &vinfo, DataPlane &plane) { bool status = false; double pressure; ConcatString level_str; - VarInfoNcWrf * vinfo_nc = (VarInfoNcWrf *) &vinfo; - NcVarInfo *info = (NcVarInfo *) nullptr; + auto vinfo_nc = (VarInfoNcWrf *) &vinfo; + auto info = (NcVarInfo *) nullptr; // Initialize the data plane plane.clear(); // Read the data WrfNc->get_nc_var_info(vinfo_nc->req_name().c_str(), info); + LongArray dimension = vinfo_nc->dimension(); - int dim_count = dimension.n_elements(); - for (int k=0; kvar, k)); - NcVarInfo *var_info = find_var_info_by_dim_name(WrfNc->Var, dim_name, - WrfNc->Nvars); - if (var_info) { - long new_offset = get_index_at_nc_data(var_info->var, - vinfo_nc->dim_value(k), - dim_name, (k == info->t_slot)); - if (new_offset != bad_data_int) dimension[k] = new_offset; - } - } - } + if (! get_real_dimension(vinfo_nc, info, dimension)) + return false; status = WrfNc->data(vinfo_nc->req_name().c_str(), dimension, plane, pressure, info); @@ -198,7 +240,7 @@ bool MetNcWrfDataFile::data_plane(VarInfo &vinfo, DataPlane &plane) { //////////////////////////////////////////////////////////////////////// int MetNcWrfDataFile::data_plane_array(VarInfo &vinfo, - DataPlaneArray &plane_array) { + DataPlaneArray &plane_array) { int i, i_dim, n_level, status, lower, upper; ConcatString level_str; double pressure, min_level, max_level; diff --git a/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.h b/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.h index ac29854595..11fc9963b5 100644 --- a/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.h +++ b/src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.h @@ -34,6 +34,8 @@ class MetNcWrfDataFile : public Met2dDataFile { private: void nc_wrf_init_from_scratch(); + bool get_real_dimension(const VarInfoNcWrf *vinfo_nc, const NcVarInfo *info, + LongArray &dimension) const; MetNcWrfDataFile(const MetNcWrfDataFile &); MetNcWrfDataFile & operator=(const MetNcWrfDataFile &); diff --git a/src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc b/src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc index 10c04ca65e..aa23560f55 100644 --- a/src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc +++ b/src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc @@ -209,8 +209,23 @@ void VarInfoNcWrf::set_magic(const ConcatString &nstr, const ConcatString &lstr) as_offset = (*ptr2 != '@'); if (!as_offset) ptr2++; + ptr3 = strchr(ptr2, '-'); + //skip negative sign of the negative value to check the range + if (ptr3 != nullptr && ptr3 == ptr2) ptr3 = strchr((ptr2+1), '-'); + // Check for a range of levels - if((ptr3 = strchr(ptr2, '-')) != nullptr) { + if (ptr3 != nullptr && ptr3 != ptr2) { + *ptr3 = 0; + ptr3++; + if (*ptr3 == '@') { + if (as_offset) { + mlog << Error << "\n" << method_name + << "Can not mix an offset and a value for NetCDF variable \"" + << MagicStr << "\".\n\n"; + exit(1); + } + ptr3++; // to support @vlevel_lower-@vlevel_upper + } // Check if a range has already been supplied if(Dimension.has(range_flag)) { @@ -223,10 +238,11 @@ void VarInfoNcWrf::set_magic(const ConcatString &nstr, const ConcatString &lstr) else { add_dimension(range_flag); Level.set_lower(atoi(ptr2)); - Level.set_upper(atoi(++ptr3)); + Level.set_upper(atoi(ptr3)); // Assume pressure level type for a range of levels Level.set_type(LevelType_Pres); + Level.set_is_offset(as_offset); } } // Single level diff --git a/src/libcode/vx_nc_util/nc_utils.cc b/src/libcode/vx_nc_util/nc_utils.cc index e6f77db56d..c95efc1129 100644 --- a/src/libcode/vx_nc_util/nc_utils.cc +++ b/src/libcode/vx_nc_util/nc_utils.cc @@ -1888,10 +1888,19 @@ bool get_nc_data(NcVar *var, ncbyte *data, const LongArray &dims, const LongArra return return_status; } +//////////////////////////////////////////////////////////////////////// + +ConcatString get_value_string(double value, bool is_time) { + ConcatString value_str; + if (is_time && (value > 10000000.)) value_str << unix_to_yyyymmdd_hhmmss(value); + else value_str << value; + return value_str; +} + //////////////////////////////////////////////////////////////////////// // returns matching offset or bad_data_int if not found -int get_index_at_nc_data(NcVar *var, double value, const string dim_name, bool is_time) { +int get_index_at_nc_data(NcVar *var, double value, const string &dim_name, bool is_time) { int offset = bad_data_int; static const char *method_name = "get_index_at_nc_data() -> "; if (IS_VALID_NC_P(var)) { @@ -1948,6 +1957,78 @@ int get_index_at_nc_data(NcVar *var, double value, const string dim_name, bool i return offset; } +//////////////////////////////////////////////////////////////////////// +// returns matching offset or bad_data_int if not found + +int get_index_at_nc_data(NcVar *var, double value_min, double value_max, + const string &dim_name, bool is_time) { + int offset = bad_data_int; + static const char *method_name = "get_index_at_nc_data(min,max) -> "; + if (IS_VALID_NC_P(var)) { + int data_size = get_data_size(var); + vector values(data_size); + + if (get_nc_data(var, values.data())) { + unixtime ut; + int sec_per_unit; + bool no_leap_year = get_att_no_leap_year(var); + ut = sec_per_unit = 0; + if (is_time) { + ConcatString units; + bool has_attr = get_var_units(var, units); + if (has_attr && (!units.empty())) + parse_cf_time_string(units.c_str(), ut, sec_per_unit); + else { + mlog << Warning << "\n" << method_name + << "the time variable \"" << GET_NC_NAME_P(var) + << "\" must contain a \"" + << units_att_name << "\" attribute.\n\n"; + } + } + bool found = false; + // Select the first offset between value_min and value_max + for (int idx=0; idx= value_min && values[idx] <= value_max)) { + found = true; + } + if (!found && is_time) { + unixtime time_value = add_to_unixtime(ut, sec_per_unit, + values[idx], no_leap_year); + if (is_eq(time_value, value_min) + || is_eq(time_value, value_max) + || (time_value >= value_min && time_value <= value_max)) { + found = true; + } + } + if (found) { + offset = idx; + break; + } + } + } + + ConcatString value_max_str = get_value_string(value_max, is_time); + ConcatString value_min_str = get_value_string(value_min, is_time); + if (offset == bad_data_int) + mlog << Debug(7) << method_name << "Not found value between " << value_min_str + << " and " << value_max_str << " at " << GET_NC_NAME_P(var) + << " by dimension name \"" << dim_name << "\"\n"; + else { + ConcatString value_str = get_value_string(values[offset], is_time); + mlog << Debug(7) << method_name << "Found value " << value_str + << " (index=" << offset << ") at " << GET_NC_NAME_P(var) + << " by dimension name \"" << dim_name << "\"\n"; + } + } + else { + mlog << Debug(7) << method_name << "Not found a dimension variable for \"" + << dim_name << "\"\n"; + } + return offset; +} + //////////////////////////////////////////////////////////////////////// bool get_nc_data_to_array(NcVar *var, StringArray *array_buf) { diff --git a/src/libcode/vx_nc_util/nc_utils.h b/src/libcode/vx_nc_util/nc_utils.h index ddf57055d6..0002c955fe 100644 --- a/src/libcode/vx_nc_util/nc_utils.h +++ b/src/libcode/vx_nc_util/nc_utils.h @@ -335,7 +335,8 @@ extern bool get_dim_names(const netCDF::NcFile *nc, StringArray *dimNames); extern netCDF::NcVar get_nc_var_lat(const netCDF::NcFile *nc); extern netCDF::NcVar get_nc_var_lon(const netCDF::NcFile *nc); extern netCDF::NcVar get_nc_var_time(const netCDF::NcFile *nc); -extern int get_index_at_nc_data(netCDF::NcVar *var, double value, const std::string dim_name, bool is_time=false); +extern int get_index_at_nc_data(netCDF::NcVar *var, double value, const std::string &dim_name, bool is_time=false); +extern int get_index_at_nc_data(netCDF::NcVar *var, double value_min, double value_max, const std::string &dim_name, bool is_time=false); extern netCDF::NcFile* open_ncfile(const char * nc_name, bool write = false); // Moved from nc_cf_file.cc