diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b85706f034..a475d51459 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,7 +4,9 @@ - [ ] Recommend testing for the reviewer(s) to perform, including the location of input datasets, and any additional instructions:
-- [ ] Do these changes include sufficient documentation and testing updates? **[Yes or No]** +- [ ] Do these changes include sufficient documentation updates, ensuring that no errors or warnings exist in the build of the documentation? **[Yes or No]** + +- [ ] Do these changes include sufficient testing updates? **[Yes or No]** - [ ] Will this PR result in changes to the test suite? **[Yes or No]**
If **yes**, describe the new output and/or changes to the existing output:
diff --git a/met/data/config/README b/met/data/config/README index e09413030b..55c0c77edd 100644 --- a/met/data/config/README +++ b/met/data/config/README @@ -53,7 +53,7 @@ The configuration file language supports the following data types: - In the Gen-Vx-Mask "-thresh" command line option. - The following percentile threshold types are supported: - "SFP" for a percentile of the sample forecast values. - e.g. ">SFP50" means greater than the 50-th forecast percentile. + e.g. ">SFP33.3" means greater than the 33.3-rd forecast percentile. - "SOP" for a percentile of the sample observation values. e.g. ">SOP75" means greater than the 75-th observation percentile. - "SCP" for a percentile of the sample climatology values. diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index fdec4f86a3..d48b784656 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -5,8 +5,15 @@ When applicable, release notes are followed by the GitHub issue number which describes the bugfix, enhancement, or new feature: https://github.com/dtcenter/MET/issues +Version 9.1.3 release notes (20210319) +-------------------------------------- + +- See complete list of `GitHub Issues `_. +- Fix PB2NC segfault when deriving PBL (`#1715 `_). +- Fix parsing error for floating point percentile thresholds, like >SFP33.3 (`#1716 `_). + Version 9.1.2 release notes (20210310) ------------------------------------------------- +-------------------------------------- - See complete list of `GitHub Issues `_. - Enable the MET documentation to be published via `Read the Docs `_. @@ -17,7 +24,7 @@ Version 9.1.2 release notes (20210310) - The 1D histograms reported by Grid-Diag are incorrect when reading the same variable name from multiple data sources (`#1694 `_). Version 9.1.1 release notes (20201118) ------------------------------------------------- +-------------------------------------- - See complete list of `GitHub Issues `_. - Fix Grid-Diag to correctly ignore missing data values (`#1562 `_). diff --git a/met/docs/conf.py b/met/docs/conf.py index bec11592ac..2934883cdc 100644 --- a/met/docs/conf.py +++ b/met/docs/conf.py @@ -20,11 +20,11 @@ project = 'MET' author = 'UCAR/NCAR, NOAA, CSU/CIRA, and CU/CIRES' author_list = 'Brown, B., Bullock, R., Fowler, T., Halley Gotway, J., Newman, K., Jensen, T.' -version = '9.1.2' +version = '9.1.3' verinfo = version release = f'{version}' release_year = '2021' -release_date = f'{release_year}0310' +release_date = f'{release_year}0319' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- diff --git a/met/src/basic/vx_config/my_config_scanner.cc b/met/src/basic/vx_config/my_config_scanner.cc index 57246913cf..1acae0582b 100644 --- a/met/src/basic/vx_config/my_config_scanner.cc +++ b/met/src/basic/vx_config/my_config_scanner.cc @@ -169,6 +169,8 @@ static bool replace_env(ConcatString &); static bool is_fort_thresh_no_spaces(); +static bool is_simple_perc_thresh(); + static int do_simple_perc_thresh(); @@ -370,6 +372,8 @@ if ( is_float_v2() ) { if ( do_float() ) return ( token(FLOAT) ); } if ( is_fort_thresh_no_spaces() ) { return ( do_fort_thresh() ); } +if ( is_simple_perc_thresh() ) { return ( do_simple_perc_thresh() ); } + int t; if ( is_id() ) { t = do_id(); return ( token(t) ); } @@ -533,7 +537,6 @@ if ( is_lhs ) { strncpy(configlval.text, configtext, max_id_length); return ( if ( strcmp(configtext, "print" ) == 0 ) { return ( PRINT ); } - // // boolean? // @@ -554,17 +557,13 @@ for (j=0; jlookup(configtext); if ( e && (e->is_number()) && (! is_lhs) ) { - // cout << "=================== id = \"" << configtext << "\" is_lhs = " << (is_lhs ? "true" : "false") << "\n"; - - // cout << "do_id() -> \n"; - // e->dump(cout); - if ( e->type() == IntegerType ) { set_int(configlval.nval, e->i_value()); @@ -613,28 +607,20 @@ if ( e && (! is_lhs) && (e->type() == UserFunctionType) ) { } - /////////////////////////////////////////////////////////////////////// - - - - // // fortran threshold without spaces? (example: "le150") // -if ( (strncmp(configtext, "lt", 2) == 0) && is_number(configtext + 2, max_id_length - 2) ) { return ( do_fort_thresh() ); } - for (j=0; j " @@ -1482,11 +1493,8 @@ if ( index < 0 ) { } - configlval.pc_info.perc_index = index; -// configlval.pc_info.is_simple = true; -configlval.pc_info.value = value; -// configlval.pc_info.value2 = bad_data_double;; +configlval.pc_info.value = value; return ( SIMPLE_PERC_THRESH ); @@ -1495,9 +1503,3 @@ return ( SIMPLE_PERC_THRESH ); //////////////////////////////////////////////////////////////////////// - - - - - - diff --git a/met/src/basic/vx_util/util_constants.h b/met/src/basic/vx_util/util_constants.h index fb4e650c54..79dac2964b 100644 --- a/met/src/basic/vx_util/util_constants.h +++ b/met/src/basic/vx_util/util_constants.h @@ -18,6 +18,7 @@ //////////////////////////////////////////////////////////////////////// // Released versions of MET +static const char met_version_9_1_3[] = "V9.1.3"; static const char met_version_9_1_2[] = "V9.1.2"; static const char met_version_9_1_1[] = "V9.1.1"; static const char met_version_9_1[] = "V9.1"; @@ -40,7 +41,7 @@ static const char met_version_1_1[] = "V1.1"; //////////////////////////////////////////////////////////////////////// -static const char * const met_version = met_version_9_1_2; +static const char * const met_version = met_version_9_1_3; static const char default_met_data_dir[] = "MET_BASE"; static const char txt_file_ext[] = ".txt"; static const char stat_file_ext[] = ".stat"; diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index fa497ae3fa..09d36f8f02 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -2437,7 +2437,7 @@ void write_netcdf_hdr_data() { // Check for no messages retained if(dim_count <= 0) { - mlog << Error << method_name << " -> " + mlog << Error << "\n" << method_name << " -> " << "No PrepBufr messages retained. Nothing to write.\n\n"; // Delete the NetCDF file remove_temp_file(ncfile); @@ -2930,16 +2930,27 @@ int combine_tqz_and_uv(map pqtzuv_map_tq, float *pqtzuv_tq, *pqtzuv_uv; float *pqtzuv_merged = (float *) 0; float *next_pqtzuv, *prev_pqtzuv; + float tq_pres_max, tq_pres_min, uv_pres_max, uv_pres_min; std::map::iterator it, it_tq, it_uv; // Gets pressure levels for TQZ records - for (it=pqtzuv_map_tq.begin(); it!=pqtzuv_map_tq.end(); ++it) { - tq_levels.add(int(it->first)); + it = pqtzuv_map_tq.begin(); + tq_pres_min = tq_pres_max = it->first; + for (; it!=pqtzuv_map_tq.end(); ++it) { + float pres_v = it->first; + if (tq_pres_min > pres_v) tq_pres_min = pres_v; + if (tq_pres_max < pres_v) tq_pres_max = pres_v; + tq_levels.add(nint(pres_v)); } // Gets pressure levels for common records - for (it=pqtzuv_map_uv.begin(); it!=pqtzuv_map_uv.end(); ++it) { - if (tq_levels.has(int(it->first))) { - common_levels.add(int(it->first)); + it = pqtzuv_map_uv.begin(); + uv_pres_min = uv_pres_max = it->first; + for (; it!=pqtzuv_map_uv.end(); ++it) { + float pres_v = it->first; + if (uv_pres_min > pres_v) uv_pres_min = pres_v; + if (uv_pres_max < pres_v) uv_pres_max = pres_v; + if (tq_levels.has(nint(pres_v))) { + common_levels.add(nint(pres_v)); } } @@ -2947,22 +2958,36 @@ int combine_tqz_and_uv(map pqtzuv_map_tq, log_tqz_and_uv(pqtzuv_map_tq, pqtzuv_map_uv, method_name); } + bool no_overlap = (tq_pres_max < uv_pres_min) || (tq_pres_min > uv_pres_max); + mlog << Debug(6) << method_name << "TQZ pressures: " << tq_pres_max + << " to " << tq_pres_min << " UV pressures: " << uv_pres_max + << " to " << uv_pres_min << (no_overlap ? " no overlap!" : " overlapping") << "\n"; + if( no_overlap ) { + mlog << Warning << "\n" << method_name + << "Can not combine TQ and UV records because of no overlapping" + << " TQZ count: " << tq_count << ", UV count: " << uv_count + << " common_levels: " << common_levels.n() << "\n\n"; + return pqtzuv_map_merged.size(); + } + // Select first record by 1) merging two records with the same pressure // level or 2) interpolate + int tq_pres, uv_pres; next_pqtzuv = (float *)0; it_tq = pqtzuv_map_tq.begin(); it_uv = pqtzuv_map_uv.begin(); pqtzuv_tq = (float *)it_tq->second; pqtzuv_uv = (float *)it_uv->second;; pqtzuv_merged = new float[mxr8vt]; - if (common_levels.has(int(it_tq->first)) - || common_levels.has(int(it_uv->first))) { + tq_pres = nint(it_tq->first); + uv_pres = nint(it_uv->first); + if (common_levels.has(tq_pres) || common_levels.has(uv_pres)) { // Found the records with the same precsure level - if (it_tq->first != it_uv->first) { - if (common_levels.has(int(it_uv->first))) { + if (tq_pres != uv_pres) { + if (common_levels.has(uv_pres)) { pqtzuv_uv = pqtzuv_map_uv[it_uv->first]; } - else if (common_levels.has(int(it_tq->first))) { + else if (common_levels.has(tq_pres)) { pqtzuv_tq = pqtzuv_map_tq[it_tq->first]; } } @@ -2978,7 +3003,7 @@ int combine_tqz_and_uv(map pqtzuv_map_tq, prev_pqtzuv = (float *)it_uv->second; ++it_uv; } - next_pqtzuv = it_uv->second; + next_pqtzuv = (float *)it_uv->second; } else { //Interpolate TQZ into UV @@ -2988,8 +3013,9 @@ int combine_tqz_and_uv(map pqtzuv_map_tq, prev_pqtzuv = (float *)it_tq->second; ++it_tq; } - next_pqtzuv = it_tq->second; + next_pqtzuv = (float *)it_tq->second; } + // Interpolate TQZ and UV as the first pressure level interpolate_pqtzuv(prev_pqtzuv, pqtzuv_merged, next_pqtzuv); } float first_pres = (pqtzuv_merged == 0 ? bad_data_float : pqtzuv_merged[0]); @@ -3006,6 +3032,7 @@ int combine_tqz_and_uv(map pqtzuv_map_tq, if(mlog.verbosity_level() >= PBL_DEBUG_LEVEL) { log_merged_tqz_uv(pqtzuv_map_tq, pqtzuv_map_uv, pqtzuv_map_merged, method_name); } + delete [] pqtzuv_merged; } return pqtzuv_map_merged.size(); @@ -3044,7 +3071,7 @@ float compute_pbl(map pqtzuv_map_tq, hgt_cnt = spfh_cnt = 0; for (it=pqtzuv_map_merged.begin(); it!=pqtzuv_map_merged.end(); ++it) { if (index < 0) { - mlog << Error << method_name << "negative index: " << index << "\n"; + mlog << Error << "\n" << method_name << "negative index: " << index << "\n\n"; break; } @@ -3058,13 +3085,13 @@ float compute_pbl(map pqtzuv_map_tq, pbl_data_vgrd[index] = pqtzuv[5]; if (!is_eq(pbl_data_spfh[index], bad_data_float)) spfh_cnt++; if (!is_eq(pbl_data_hgt[index], bad_data_float)) hgt_cnt++; - selected_levels.add(int(it->first)); + selected_levels.add(nint(it->first)); } index--; } if (index != -1) { - mlog << Error << method_name << "Missing some levels (" << index << ")\n"; + mlog << Error << "\n" << method_name << "Missing some levels (" << index << ")\n\n"; } if (pbl_level > MAX_PBL_LEVEL) { @@ -3080,7 +3107,7 @@ float compute_pbl(map pqtzuv_map_tq, if (!is_eq(highest_pressure, bad_data_float)) { index = MAX_PBL_LEVEL - 1; for (; it!=pqtzuv_map_tq.end(); ++it) { - int pres_level = int(it->first); + int pres_level = nint(it->first); if (selected_levels.has(pres_level)) break; float *pqtzuv = pqtzuv_map_merged[it->first]; @@ -3149,10 +3176,10 @@ void insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, hdr_info << unix_to_yyyymmdd_hhmmss(hdr_vld_ut) << " " << hdr_typ << " " << hdr_sid; if (is_eq(pbl_value, bad_data_float)) { - mlog << Warning << "Failed to compute PBL " << hdr_info << "\n\n"; + mlog << Warning << "\nFailed to compute PBL " << hdr_info << "\n\n"; } else if (pbl_value < hdr_elv) { - mlog << Warning << "Not saved because the computed PBL (" << pbl_value + mlog << Warning << "\nNot saved because the computed PBL (" << pbl_value << ") is less than the station elevation (" << hdr_elv << "). " << hdr_info << "\n\n"; obs_arr[4] = 0; @@ -3166,7 +3193,7 @@ void insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, << " lat: " << hdr_lat << ", lon: " << hdr_lon << ", elv: " << hdr_elv << " " << hdr_info << "\n\n"; if (obs_arr[4] > MAX_PBL) { - mlog << Warning << " Computed PBL (" << obs_arr[4] << " from " + mlog << Warning << "\nComputed PBL (" << obs_arr[4] << " from " << pbl_value << ") is too high, Reset to " << MAX_PBL << " " << hdr_info<< "\n\n"; obs_arr[4] = MAX_PBL; @@ -3202,9 +3229,14 @@ int interpolate_by_pressure(int length, float *pres_data, float *var_data) { << var_data[idx_start] << " and " << var_data[idx_end] << "\n"; float data_diff = var_data[idx_end] - var_data[idx_start]; for (idx2 = idx_start+1; idx2 pqtzuv_map_pivot, if (first_pres < it_pivot->first) break; } mlog << Debug(8) << method_name << "pivot->first: " << it_pivot->first - << " aux->first " << it_aux->first << " first_pres: " << first_pres - << " prev_pqtzuv[0]" << prev_pqtzuv[0] << "\n"; + << " aux->first: " << it_aux->first << " first_pres: " << first_pres + << " prev_pqtzuv[0]: " << prev_pqtzuv[0] << "\n"; // Find next UV level for (; it_aux!=pqtzuv_map_aux.end(); ++it_aux) { // Skip the records below the first mathcing/interpolated level