From 94374473eed96f0472558247dedfb7c321d8cba0 Mon Sep 17 00:00:00 2001 From: jprestop Date: Tue, 26 Oct 2021 13:08:20 -0600 Subject: [PATCH 001/172] Per #1906, modify code to pass entire path to make_temp_file_name instead of only the filename so that the function can tell whether or not the file exists. (#1952) Co-authored-by: Julie Prestopnik --- met/src/basic/vx_config/config_file.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/met/src/basic/vx_config/config_file.cc b/met/src/basic/vx_config/config_file.cc index 8b289a7487..a7b1377405 100644 --- a/met/src/basic/vx_config/config_file.cc +++ b/met/src/basic/vx_config/config_file.cc @@ -312,9 +312,10 @@ if ( empty(name) ) { DictionaryStack DS(*this); ConcatString temp_filename = get_tmp_dir(); - -temp_filename << "/" << make_temp_file_name("met_config", 0); - + +temp_filename << "/" << "met_config"; +temp_filename = make_temp_file_name(temp_filename.c_str(), 0); + recursive_envs(name, temp_filename.c_str()); bison_input_filename = (const char *) temp_filename.c_str(); @@ -422,9 +423,10 @@ if ( empty(s) ) { ofstream out; ConcatString temp_filename = get_tmp_dir(); -temp_filename << "/" << make_temp_file_name("config", ".temp"); - - out.open(temp_filename.c_str()); +temp_filename << "/" << "met_config"; +temp_filename = make_temp_file_name(temp_filename.c_str(), 0); + +out.open(temp_filename.c_str()); if ( ! out ) { From 8c446ffd61fb79224c753060ada2fa355c678018 Mon Sep 17 00:00:00 2001 From: Seth Linden Date: Wed, 3 Nov 2021 09:36:55 -0600 Subject: [PATCH 002/172] Feature 1761 percent thresh (#1956) * Per issue #1761 in set_perc() adding code to get FBIAS numeric value, like 1.0 or 0.9, etc. SL * Per issue #1761: in set_perc(), modified actual percentile calculation at end to use the extracted FBIAS numeric value (float). SL * Per issue #1761: modified the check on the perc_thresh_freq_bias, just has to be > 0 now. SL * Per issue #1761: cleaned up code in set_perc(). SL * Per #1761, updates to Simple_Node::set_perc() to handle variable frequency bias amounts. Changes include: - Reverting the formatting of this back to how it originally was in the develop branch. In general, just match the formatting of the existing file, so as the minimize the number of difference lines. - Add logic to adjust the percentile to be found based on the requested FBIAS value. Multiplying or dividing the percentile by the FBIAS value depends on the inequality type and whether we're bias adjusting the forecast or observation data. - Adjust the log messages slightly. Please be aware that I'm not totally confident in these changes. They warrant much more testing. This logic is very, very confusing. * Per #1761, call compute_percentile() when double-checking the percentile values. * Per #1761, remove unused variable. * Per #1761, add warning for percentiles > 100. * Per #1761. In set_perc(), after testing cleaned up code. SL * Per issue #1761: adding new config file for testing dynamic FBIAS values. SL * Per issue #1761: added new unit test for dynamic FBIAS values when running grid_stat. SL * Per issue #1761, modified FBIAS section to indicated that the user can use dynamic values that are not 1.0. SL * Update met/docs/Users_Guide/config_options.rst Co-authored-by: johnhg * Update met/docs/Users_Guide/config_options.rst Co-authored-by: johnhg * Update met/docs/Users_Guide/config_options.rst Co-authored-by: johnhg * Update test/config/GridStatConfig_fbias_perc_thresh Co-authored-by: johnhg * Update test/config/GridStatConfig_fbias_perc_thresh Co-authored-by: johnhg * Update test/config/GridStatConfig_fbias_perc_thresh Co-authored-by: johnhg * Update test/config/GridStatConfig_fbias_perc_thresh Co-authored-by: johnhg * Per issue #1761, set nc_pairs_flag = FALSE. SL Co-authored-by: Seth Linden Co-authored-by: John Halley Gotway --- met/docs/Users_Guide/config_options.rst | 16 +- met/src/basic/vx_config/config.tab.yy | 2 +- met/src/basic/vx_config/threshold.cc | 99 ++++++--- test/config/GridStatConfig_fbias_perc_thresh | 204 +++++++++++++++++++ test/xml/unit_perc_thresh.xml | 24 +++ 5 files changed, 314 insertions(+), 31 deletions(-) create mode 100644 test/config/GridStatConfig_fbias_perc_thresh diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index 23f67fecda..e6d2349cc4 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -93,12 +93,14 @@ The configuration file language supports the following data types: e.g. "5.0" and - "fcst.cat_thresh = ==FBIAS1;", MET applies the >5.0 threshold to the - observations and then chooses a forecast threshold which results in a - frequency bias of 1. + * "==FBIAS" for a user-specified frequency bias value. + e.g. "==FBIAS1" to automatically de-bias the data, "==FBIAS0.9" to select a low-bias threshold, or "==FBIAS1.1" to select a high-bias threshold. + This option must be used in + conjunction with a simple threshold in the other field. For example, + when "obs.cat_thresh = >5.0" and "fcst.cat_thresh = ==FBIAS1;", + MET applies the >5.0 threshold to the observations and then chooses a + forecast threshold which results in a frequency bias of 1. + The frequency bias can be any float value > 0.0. * "CDP" for climatological distribution percentile thresholds. These thresholds require that the climatological mean and standard @@ -119,7 +121,7 @@ The configuration file language supports the following data types: For example, "==CDP25" is automatically expanded to 4 percentile bins: >=CDP0&&=CDP25&&=CDP50&&=CDP75&&<=CDP100 - * When sample percentile thresholds of type SFP, SOP, SCP, or FBIAS1 are + * When sample percentile thresholds of type SFP, SOP, SCP, or FBIAS are requested, MET recomputes the actual percentile that the threshold represents. If the requested percentile and actual percentile differ by more than 5%, a warning message is printed. This may occur when the diff --git a/met/src/basic/vx_config/config.tab.yy b/met/src/basic/vx_config/config.tab.yy index d19715eb35..a89d87c6e8 100644 --- a/met/src/basic/vx_config/config.tab.yy +++ b/met/src/basic/vx_config/config.tab.yy @@ -1661,7 +1661,7 @@ if ( s->PT < 0 || s->PT > 100 ) { } -if ( s->Ptype == perc_thresh_freq_bias && !is_eq(s->PT, 1.0) ) { +if ( s->Ptype == perc_thresh_freq_bias && s->PT <= 0 ) { mlog << Error << "\ndo_simple_perc_thresh() -> " << "unsupported frequency bias percentile threshold!\n\n"; diff --git a/met/src/basic/vx_config/threshold.cc b/met/src/basic/vx_config/threshold.cc index cf3e9dd26a..bf317733ff 100644 --- a/met/src/basic/vx_config/threshold.cc +++ b/met/src/basic/vx_config/threshold.cc @@ -934,10 +934,11 @@ void Simple_Node::set_perc(const NumArray *fptr, const NumArray *optr, const Num { -int i, count; +int i; double ptile, diff; NumArray data; const NumArray * ptr = 0; +bool fbias_fcst = false; // // handle sample percentile types @@ -972,14 +973,16 @@ else if ( Ptype == perc_thresh_freq_bias ) { fthr->get_ptype() == no_perc_thresh_type && fthr->get_type() != thresh_complex ) { + fbias_fcst = false; + ptr = optr; op = fthr->get_type(); PT = fptr->compute_percentile(fthr->get_value(), is_inclusive(fthr->get_type())); mlog << Debug(3) - << "The forecast threshold \"" << fthr->get_str() - << "\" includes " << PT * 100.0 << "% of the data.\n"; + << "The forecast threshold value \"" << fthr->get_str() + << "\" represents the " << PT * 100.0 << "-th percentile.\n"; } @@ -991,14 +994,16 @@ else if ( Ptype == perc_thresh_freq_bias ) { othr->get_ptype() == no_perc_thresh_type && othr->get_type() != thresh_complex ) { + fbias_fcst = true; + ptr = fptr; op = othr->get_type(); PT = optr->compute_percentile(othr->get_value(), is_inclusive(othr->get_type())); mlog << Debug(3) - << "The observation threshold \"" << othr->get_str() - << "\" includes " << PT * 100.0 << "% of the data.\n"; + << "The observation threshold value \"" << othr->get_str() + << "\" represents the " << PT * 100.0 << "-th percentile.\n"; } @@ -1029,7 +1034,8 @@ else if ( Ptype == perc_thresh_freq_bias ) { PT *= 100.0; -} +} // end else if PT == perc_thresh_freq_bias + // // nothing to do // @@ -1082,7 +1088,7 @@ if ( data.n() == 0 ) { << " threshold \"" << s << "\" because no valid data was provided.\n\n"; - exit ( 1 ); + exit ( 1 ); } else { @@ -1094,6 +1100,64 @@ else { s.strip_paren(); abbr_s.strip_paren(); + // + // parse the frequency bias value from the threshold string + // + + if ( Ptype == perc_thresh_freq_bias ) { + + ConcatString fs = s; + + fs.replace("==FBIAS", " ", false); + + double fbias_val = atof(fs.c_str()); + + // + // range check requested bias value + // + + if ( fbias_val <= 0.0 ) { + + mlog << Error << "\nSimple_Node::set_perc() -> " + << "the requested frequency bias value (" << fbias_val + << ") must be > 0 in threshold \"" << s << "\".\n\n"; + + } + + // + // adjust PT by the requested frequency bias amount + // + + double PT_new; + + if ( fbias_fcst ) { + if ( op == thresh_le || op == thresh_lt ) PT_new = PT * fbias_val; + else if ( op == thresh_ge || op == thresh_gt ) PT_new = PT / fbias_val; + } + else { + if ( op == thresh_le || op == thresh_lt ) PT_new = PT / fbias_val; + else if ( op == thresh_ge || op == thresh_gt ) PT_new = PT * fbias_val; + } + + if ( PT_new > 100.0 ) { + mlog << Warning << "\nSimple_Node::set_perc() -> " + << "For " << (fbias_fcst ? "forecast" : "observation" ) + << " threshold \"" << s << "\" the required percentile of " + << PT_new << " exceeds the maximum possible value. " + << "Resetting to 100.\n\n"; + + PT_new = 100.0; + } + + mlog << Debug(3) + << "For " << (fbias_fcst ? "forecast" : "observation" ) + << " threshold \"" << s << "\" with type \"" << thresh_type_str[op] + << "\" update the requested percentile from " << PT << " to " + << PT_new << ".\n"; + + PT = PT_new; + } + // // compute the percentile and update the strings // @@ -1117,27 +1181,16 @@ else { // compute the actual percentile and check tolerance // - if ( op == thresh_le || op == thresh_ge || op == thresh_eq ) { - - for ( i=count=0; i " << "the requested percentile (" << PT - << "%) for threshold \"" << s + << ") for threshold \"" << s << "\" differs from the actual percentile (" - << ptile * 100.0 << ") by " << diff * 100.0 << "%.\n" + << ptile * 100.0 << ") by " << diff * 100.0 << ".\n" << "This is common for small samples or data that contains " << "ties.\n\n"; @@ -1146,8 +1199,8 @@ else { mlog << Debug(3) << "The requested percentile (" << PT - << "%) for threshold threshold \"" << s - << "\" includes " << ptile * 100.0 << "% of the data.\n"; + << ") for threshold \"" << s << "\" includes " + << ptile * 100.0 << "% of the data.\n"; } diff --git a/test/config/GridStatConfig_fbias_perc_thresh b/test/config/GridStatConfig_fbias_perc_thresh new file mode 100644 index 0000000000..1072db748a --- /dev/null +++ b/test/config/GridStatConfig_fbias_perc_thresh @@ -0,0 +1,204 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Grid-Stat configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "GFS"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "NA"; + +// +// Output observation type to be written +// +obtype = "ANALYS"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +mpr_column = []; +mpr_thresh = []; +cat_thresh = []; +cnt_thresh = [ NA ]; +cnt_logic = UNION; +wind_thresh = [ NA ]; +wind_logic = UNION; +eclv_points = 0.05; +nc_pairs_var_name = ""; +nc_pairs_var_suffix = ""; +hss_ec_value = NA; +rank_corr_flag = FALSE; + +// +// Forecast and observation fields to be verified +// +fcst = { + + field = [ + { name = "TMP"; level = [ "P500" ]; cat_thresh = [ ==FBIAS0.9, ==FBIAS1.0, ==FBIAS1.1, ==FBIAS0.9, ==FBIAS1.0, ==FBIAS1.1, <243, <243, <243, >253, >253, >253 ]; } + ]; + +} +obs = { + + field = [ + { name = "TMP"; level = [ "P500" ]; cat_thresh = [ <243, <243, <243, >253, >253, >253, ==FBIAS0.9, ==FBIAS1.0, ==FBIAS1.1, ==FBIAS0.9, ==FBIAS1.0, ==FBIAS1.1 ]; } + ]; + +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification masking regions +// +mask = { + grid = [ "FULL" ]; + poly = [ ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +boot = { + interval = PCTILE; + rep_prop = 1.0; + n_rep = 0; + rng = "mt19937"; + seed = "1"; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Data smoothing methods +// +interp = { + field = FCST; + vld_thresh = 1.0; + shape = SQUARE; + + type = [ + { method = NEAREST; width = 1; } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood methods +// +nbrhd = { + width = [ 3, 5 ]; + cov_thresh = [ >=0.5 ]; + vld_thresh = 1.0; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Fourier decomposition +// +fourier = { + wave_1d_beg = []; + wave_1d_end = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Gradient statistics +// May be set separately in each "obs.field" entry +// +gradient = { + dx = [ 1 ]; + dy = [ 1 ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Distance Map statistics +// May be set separately in each "obs.field" entry +// +distance_map = { + baddeley_p = 2; + baddeley_max_dist = NA; + fom_alpha = 0.1; + zhu_weight = 0.5; + beta_value(n) = n * n / 2.0; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Statistical output types +// +output_flag = { + fho = NONE; + ctc = BOTH; + cts = BOTH; + mctc = NONE; + mcts = NONE; + cnt = NONE; + sl1l2 = NONE; + sal1l2 = NONE; + vl1l2 = NONE; + val1l2 = NONE; + vcnt = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; + nbrctc = NONE; + nbrcts = NONE; + nbrcnt = NONE; + grad = NONE; + dmap = NONE; +} + +// +// NetCDF matched pairs output file +// +nc_pairs_flag = FALSE; + +//////////////////////////////////////////////////////////////////////////////// + +grid_weight_flag = NONE; +tmp_dir = "/tmp"; +output_prefix = "${OUTPUT_PREFIX}"; +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/xml/unit_perc_thresh.xml b/test/xml/unit_perc_thresh.xml index bc2ef52a83..23e1c83aea 100644 --- a/test/xml/unit_perc_thresh.xml +++ b/test/xml/unit_perc_thresh.xml @@ -84,6 +84,30 @@ + + + + + + &MET_BIN;/grid_stat + + OUTPUT_PREFIX PERC_THRESH_FBIAS + + \ + &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F024.grib2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0000_000.grb2 \ + &CONFIG_DIR;/GridStatConfig_fbias_perc_thresh \ + -outdir &OUTPUT_DIR;/perc_thresh -v 3 + + + &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V.stat + &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_cts.txt + &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_cnt.txt + &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_sl1l2.txt + &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_pairs.nc + + + From d60924c9524ad034a7c6c785b0adbb11ab864feb Mon Sep 17 00:00:00 2001 From: johnhg Date: Wed, 3 Nov 2021 10:58:38 -0600 Subject: [PATCH 003/172] Feature 1905 ens_ctrl (#1955) Co-authored-by: j-opatz <59586397+j-opatz@users.noreply.github.com> --- met/docs/Users_Guide/ensemble-stat.rst | 19 +- met/docs/Users_Guide/reformat_grid.rst | 2 +- met/src/basic/vx_util/num_array.cc | 53 ++ met/src/basic/vx_util/num_array.h | 4 + .../vx_statistics/pair_data_ensemble.cc | 60 ++- .../vx_statistics/pair_data_ensemble.h | 4 + .../tools/core/ensemble_stat/ensemble_stat.cc | 463 +++++++++--------- .../tools/core/ensemble_stat/ensemble_stat.h | 18 +- .../ensemble_stat/ensemble_stat_conf_info.cc | 7 +- .../ensemble_stat/ensemble_stat_conf_info.h | 4 +- .../tools/other/gen_ens_prod/gen_ens_prod.cc | 3 +- test/config/EnsembleStatConfig_MASK_SID | 2 +- test/xml/unit_ensemble_stat.xml | 28 ++ 13 files changed, 394 insertions(+), 273 deletions(-) diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index a39424d289..1c131a9580 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -69,6 +69,7 @@ The usage statement for the Ensemble Stat tool is shown below: [-grid_obs file] [-point_obs file] [-ens_mean file] + [-ctrl file] [-obs_valid_beg time] [-obs_valid_end time] [-outdir path] @@ -92,23 +93,23 @@ Optional arguments for ensemble_stat 4. To produce ensemble statistics using gridded observations, use the **-grid_obs file** option to specify a gridded observation file. This option may be used multiple times if your observations are in several files. +5. To produce ensemble statistics using point observations, use the **-point_obs file** option to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. -5. To produce ensemble statistics using point observations, use the **-point_obs file** to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. +6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** option specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** option from earlier versions of MET. +7. The **-ctrl file** option specifies an ensemble control member data file. The control member is included in the computation of the ensemble mean but excluded from the spread. -6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** from earlier versions of MET. +8. To filter point observations by time, use **-obs_valid_beg time** in YYYYMMDD[_HH[MMSS]] format to set the beginning of the matching observation time window. -7. To filter point observations by time, use **-obs_valid_beg time** in YYYYMMDD[_HH[MMSS]] format to set the beginning of the matching observation time window. +9. As above, use **-obs_valid_end time** in YYYYMMDD[_HH[MMSS]] format to set the end of the matching observation time window. -8. As above, use **-obs_valid_end time** in YYYYMMDD[_HH[MMSS]] format to set the end of the matching observation time window. +10. Specify the **-outdir path** option to override the default output directory (./). -9. Specify the **-outdir path** option to override the default output directory (./). +11. The **-log** file outputs log messages to the specified file. -10. The **-log** file outputs log messages to the specified file. +12. The **-v level** option indicates the desired level of verbosity. The value of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity will increase the amount of logging. -11. The **-v level** option indicates the desired level of verbosity. The value of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity will increase the amount of logging. - -12. The **-compress level** option indicates the desired level of compression (deflate level) for NetCDF variables. The valid level is between 0 and 9. The value of "level" will override the default setting of 0 from the configuration file or the environment variable MET_NC_COMPRESS. Setting the compression level to 0 will make no compression for the NetCDF output. Lower number is for fast compression and higher number is for better compression. +13. The **-compress level** option indicates the desired level of compression (deflate level) for NetCDF variables. The valid level is between 0 and 9. The value of "level" will override the default setting of 0 from the configuration file or the environment variable MET_NC_COMPRESS. Setting the compression level to 0 will make no compression for the NetCDF output. Lower number is for fast compression and higher number is for better compression. An example of the ensemble_stat calling sequence is shown below: diff --git a/met/docs/Users_Guide/reformat_grid.rst b/met/docs/Users_Guide/reformat_grid.rst index 191ef4e1a4..3f67a377a7 100644 --- a/met/docs/Users_Guide/reformat_grid.rst +++ b/met/docs/Users_Guide/reformat_grid.rst @@ -74,7 +74,7 @@ Required arguments for the pcp_combine Optional arguments for pcp_combine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -3. The **-field string** option defines the data to be extracted from the input files. Use this option when processing fields other than **APCP** or non-GRIB files. This option may be used multiple times and output will be created for each. +3. The **-field string** option defines the data to be extracted from the input files. Use this option when processing fields other than **APCP** or non-GRIB files. It can be used multiple times and output will be created for each. In general, the field string should include the **name** and **level** of the requested data and be enclosed in single quotes. It is processed as an inline configuration file and may also include data filtering, censoring, and conversion options. For example, use **-field ‘name=”ACPCP”; level=”A6”; convert(x)=x/25.4;’** to read 6-hourly accumulated convective precipitation from a GRIB file and convert from millimeters to inches. 4. The **-name list** option is a comma-separated list of output variable names which override the default choices. If specified, the number of names must match the number of variables to be written to the output file. diff --git a/met/src/basic/vx_util/num_array.cc b/met/src/basic/vx_util/num_array.cc index b681b901ee..446bf29034 100644 --- a/met/src/basic/vx_util/num_array.cc +++ b/met/src/basic/vx_util/num_array.cc @@ -1157,6 +1157,59 @@ double NumArray::wmean_fisher(const NumArray &wgt) const } + +//////////////////////////////////////////////////////////////////////// + + +double NumArray::variance(int skip_index) const + +{ + + if(n() == 0) return ( bad_data_double ); + + int j, count; + double s, s_sq, var; + + s = s_sq = 0.0; + count = 0; + + for(j=0; j 1) { + var = (s_sq - s*s/(double) count)/((double) (count - 1)); + if(is_eq(var, 0.0)) var = 0.0; + } + else { + var = bad_data_double; + } + + return(var); + +} + + +//////////////////////////////////////////////////////////////////////// + + +double NumArray::stdev(int skip_index) const + +{ + + double v = variance(skip_index); + + if ( !is_bad_data(v) ) v = sqrt(v); + + return(v); + +} + + //////////////////////////////////////////////////////////////////////// // diff --git a/met/src/basic/vx_util/num_array.h b/met/src/basic/vx_util/num_array.h index 207b512acd..623f7e39c8 100644 --- a/met/src/basic/vx_util/num_array.h +++ b/met/src/basic/vx_util/num_array.h @@ -21,6 +21,7 @@ #include #include "concat_string.h" +#include "is_bad_data.h" //////////////////////////////////////////////////////////////////////// @@ -107,6 +108,9 @@ class NumArray { double mean_sqrt() const; double mean_fisher() const; + double variance(int skip_index = bad_data_int) const; + double stdev(int skip_index = bad_data_int) const; + double wmean(const NumArray &) const; double wmean_sqrt(const NumArray &) const; double wmean_fisher(const NumArray &) const; diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 5782cf6a0d..4811f66147 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -108,6 +108,7 @@ void PairDataEnsemble::clear() { n_ens = 0; n_pair = 0; + ctrl_index = bad_data_int; skip_const = false; skip_ba.clear(); @@ -121,6 +122,7 @@ void PairDataEnsemble::clear() { esum_na.clear(); esumsq_na.clear(); + esumn_na.clear(); mn_na.clear(); mn_oerr_na.clear(); @@ -170,6 +172,7 @@ void PairDataEnsemble::extend(int n) { var_plus_oerr_na.extend (n); esum_na.extend (n); esumsq_na.extend (n); + esumn_na.extend (n); mn_na.extend (n); mn_oerr_na.extend (n); @@ -222,6 +225,7 @@ void PairDataEnsemble::assign(const PairDataEnsemble &pd) { ign_na = pd.ign_na; pit_na = pd.pit_na; n_pair = pd.n_pair; + ctrl_index = pd.ctrl_index; skip_const = pd.skip_const; skip_ba = pd.skip_ba; @@ -231,6 +235,7 @@ void PairDataEnsemble::assign(const PairDataEnsemble &pd) { esum_na = pd.esum_na; esumsq_na = pd.esumsq_na; + esumn_na = pd.esumn_na; mn_na = pd.mn_na; mn_oerr_na = pd.mn_oerr_na; @@ -290,12 +295,14 @@ void PairDataEnsemble::add_ens_var_sums(int i_obs, double v) { if(i_obs >= esum_na.n()) { esum_na.add(0.0); esumsq_na.add(0.0); + esumn_na.add(0.0); } // Track sums of the raw ensemble member values if(!is_bad_data(v)) { esum_na.inc(i_obs, v); esumsq_na.inc(i_obs, v*v); + esumn_na.inc(i_obs, 1); } return; @@ -416,17 +423,17 @@ 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], v_na[i]); + var_unperturbed = compute_variance(esum_na[i], esumsq_na[i], esumn_na[i]); var_na.add(var_unperturbed); // Process the observation error information. ObsErrorEntry * e = (has_obs_error() ? obs_error_entry[i] : 0); if(e) { - // Compute perturbed ensemble mean and variance - cur_ens.compute_mean_variance(mean, var_perturbed); - mn_oerr_na.add(mean); - var_oerr_na.add(var_perturbed); + // Compute perturbed ensemble mean and variance + // Exclude the control member from the variance + mn_oerr_na.add(cur_ens.mean()); + var_oerr_na.add(cur_ens.variance(ctrl_index)); // Compute the variance plus observation error variance. var_plus_oerr_na.add(var_unperturbed + @@ -467,8 +474,12 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { crps_emp_na.add(compute_crps_emp(o_na[i], cur_ens)); crpscl_emp_na.add(compute_crps_emp(o_na[i], cur_clm)); + // Ensemble mean and standard deviation + // Exclude the control member from the standard deviation + mean = cur_ens.mean(); + stdev = cur_ens.stdev(ctrl_index); + // Store Gaussian CRPS stats - cur_ens.compute_mean_stdev(mean, stdev); crps_gaus_na.add(compute_crps_gaus(o_na[i], mean, stdev)); crpscl_gaus_na.add(compute_crps_gaus(o_na[i], cmn_na[i], csd_na[i])); ign_na.add(compute_ens_ign(o_na[i], mean, stdev)); @@ -613,7 +624,7 @@ struct ssvar_bin_comp { void PairDataEnsemble::compute_ssvar() { int i, j; - double mn, var; + double var; ssvar_bin_map bins; NumArray cur; @@ -644,21 +655,22 @@ void PairDataEnsemble::compute_ssvar() { if(skip_ba[i]) continue; // Store ensemble values for the current observation - for(j=0, cur.erase(); jflag) { @@ -1781,6 +1796,21 @@ void VxPairDataEnsemble::calc_obs_summary() { //////////////////////////////////////////////////////////////////////// +void VxPairDataEnsemble::set_ctrl_index(int index) { + + for(int i=0; i < n_msg_typ; i++){ + for(int j=0; j < n_mask; j++){ + for(int k=0; k < n_interp; k++){ + pd[i][j][k].ctrl_index = index; + } + } + } + + return; +} + +//////////////////////////////////////////////////////////////////////// + void VxPairDataEnsemble::set_skip_const(bool tf) { for(int i=0; i < n_msg_typ; i++){ diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index e9c2417e49..bee6b11838 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -90,6 +90,7 @@ class PairDataEnsemble : public PairBase { int n_ens; // Number of ensemble members int n_pair; // Number of valid pairs, n_obs - sum(skip_ba) + int ctrl_index; // Index of the control member bool skip_const; // Skip cases where the observation and // all ensemble members are constant BoolArray skip_ba; // Flag for each observation [n_obs] @@ -106,6 +107,7 @@ class PairDataEnsemble : public PairBase { NumArray esum_na; // Sum of unperturbed ensemble values [n_obs] NumArray esumsq_na; // Sum of unperturbed ensemble squared values [n_obs] + NumArray esumn_na; // Count of ensemble values [n_obs] NumArray mn_na; // Ensemble mean value [n_obs] NumArray mn_oerr_na; // Mean of perturbed members [n_obs] @@ -293,6 +295,8 @@ class VxPairDataEnsemble { void calc_obs_summary(); + void set_ctrl_index(int); + void set_skip_const(bool); }; diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 6dfc98dee3..783691945b 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -61,6 +61,7 @@ // statistics in the ECNT line type. // 031 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. +// 032 10/07/21 Halley Gotway MET #1905 Add -ctrl option. // //////////////////////////////////////////////////////////////////////// @@ -124,7 +125,7 @@ static void do_rps (const EnsembleStatVxOpt &, const PairDataEnsemble *); static void clear_counts(); -static void track_counts(int, const DataPlane &); +static void track_counts(int, const DataPlane &, bool); static ConcatString get_ens_mn_var_name(int); @@ -135,10 +136,12 @@ static void setup_table (AsciiTable &); static void build_outfile_name(unixtime, const char *, ConcatString &); static void write_ens_nc(int, DataPlane &); -static void write_ens_var_float(int, float *, DataPlane &, +static void write_ens_var_float(int, float *, const DataPlane &, const char *, const char *); -static void write_ens_var_int(int, int *, DataPlane &, +static void write_ens_var_int(int, int *, const DataPlane &, const char *, const char *); +static void write_ens_data_plane(int, const DataPlane &, const DataPlane &, + const char *, const char *); static void write_orank_nc(PairDataEnsemble &, DataPlane &, int, int, int); static void write_orank_var_float(int, int, int, float *, DataPlane &, @@ -146,8 +149,8 @@ static void write_orank_var_float(int, int, int, float *, DataPlane &, static void write_orank_var_int(int, int, int, int *, DataPlane &, const char *, const char *); -static void add_var_att_local(VarInfo *, NcVar *, bool is_int, DataPlane &, - const char *, const char *); +static void add_var_att_local(VarInfo *, NcVar *, bool is_int, + const DataPlane &, const char *, const char *); static void finish_txt_files(); static void clean_up(); @@ -157,6 +160,7 @@ static void usage(); static void set_grid_obs(const StringArray &); static void set_point_obs(const StringArray &); static void set_ens_mean(const StringArray & a); +static void set_ctrl_file(const StringArray &); static void set_obs_valid_beg(const StringArray &); static void set_obs_valid_end(const StringArray &); static void set_outdir(const StringArray &); @@ -215,20 +219,18 @@ void process_command_line(int argc, char **argv) { cline.set_usage(usage); // - // add the options function calls + // add the option function calls + // quietly support deprecated -ssvar_mean option // - cline.add(set_grid_obs, "-grid_obs", 1); - cline.add(set_point_obs, "-point_obs", 1); - cline.add(set_ens_mean, "-ens_mean", 1); + cline.add(set_grid_obs, "-grid_obs", 1); + cline.add(set_point_obs, "-point_obs", 1); + cline.add(set_ens_mean, "-ens_mean", 1); + cline.add(set_ctrl_file, "-ctrl", 1); cline.add(set_obs_valid_beg, "-obs_valid_beg", 1); cline.add(set_obs_valid_end, "-obs_valid_end", 1); - cline.add(set_outdir, "-outdir", 1); - cline.add(set_compress, "-compress", 1); - - // - // quietly support deprecated -ssvar_mean option - // - cline.add(set_ens_mean, "-ssvar_mean", 1); + cline.add(set_outdir, "-outdir", 1); + cline.add(set_compress, "-compress", 1); + cline.add(set_ens_mean, "-ssvar_mean", 1); // // parse the command line @@ -291,6 +293,13 @@ void process_command_line(int argc, char **argv) { exit(1); } + // Prepend the control member, if specified + if(ctrl_file.nonempty()) { + ctrl_index = 0; + ens_file_list.insert(ctrl_index, ctrl_file.c_str()); + n_ens++; + } + // Check that the end_ut >= beg_ut if(obs_valid_beg_ut != (unixtime) 0 && obs_valid_end_ut != (unixtime) 0 && @@ -370,18 +379,19 @@ void process_command_line(int argc, char **argv) { shc.set_model(conf_info.model.c_str()); // Allocate arrays to store threshold counts - thresh_count_na = new NumArray [conf_info.get_max_n_thresh()]; - thresh_nbrhd_count_na = new NumArray * [conf_info.get_max_n_thresh()]; + thresh_cnt_na = new NumArray [conf_info.get_max_n_thresh()]; + thresh_nbrhd_cnt_na = new NumArray * [conf_info.get_max_n_thresh()]; for(i=0; i " + << "the control member file is not valid.\n\n"; + exit(1); + } + + // Otherwise, continue + continue; + } // Read the current field if(!get_data_plane(ens_file_list[j].c_str(), etype, - conf_info.ens_info[i], ens_dp, true)) continue; + conf_info.ens_info[i], ens_dp, true)) { + + // Error out if the control member data cannot be read + if(j==ctrl_index) { + mlog << Error << "\nprocess_ensemble() -> " + << "can't find \"" << conf_info.ens_info[i]->magic_str() + << "\" data in the control member file.\n\n"; + exit(1); + } + + // Otherwise, continue + continue; + } // Create a NetCDF file to store the ensemble output if(nc_out == (NcFile *) 0) { @@ -788,7 +821,7 @@ void process_ensemble() { } // Apply current data to the running sums and counts - track_counts(i, ens_dp); + track_counts(i, ens_dp, j == ctrl_index); // Keep track of the maximum initialization time if(is_bad_data(max_init_ut) || ens_dp.init() > max_init_ut) { @@ -802,8 +835,7 @@ void process_ensemble() { write_ens_nc(i, ens_dp); // Store the ensemble mean output file - ens_mean_file = - out_nc_file_list[out_nc_file_list.n() - 1]; + ens_mean_file = out_nc_file_list[out_nc_file_list.n() - 1]; } // end for i @@ -825,7 +857,7 @@ void process_vx() { if(point_obs_file_list.n() == 0 && grid_obs_file_list.n() == 0) { mlog << Error << "\nprocess_vx() -> " - << " when \"fcst.field\" is non-empty, you must use " + << "when \"fcst.field\" is non-empty, you must use " << "\"-point_obs\" and/or \"-grid_obs\" to specify the " << "verifying observations.\n\n"; exit(1); @@ -835,7 +867,7 @@ void process_vx() { conf_info.process_masks(grid); // Setup the PairDataEnsemble objects - conf_info.set_vx_pd(n_vx_vld); + conf_info.set_vx_pd(n_vx_vld, ctrl_index); // Process the point observations if(point_obs_flag) process_point_vx(); @@ -1080,7 +1112,8 @@ int process_point_ens(int i_ens, int &n_miss) { ens_mean_file : ens_mean_user); mlog << Debug(2) << "\n" << sep_str << "\n\n" - << "Processing " << file_type << " file: " << ens_file << "\n"; + << "Processing " << file_type << " file: " << ens_file + << (i_ens == ctrl_index ? " (control)\n" : "\n"); // Loop through each of the fields to be verified and extract // the forecast fields for verification @@ -1651,6 +1684,7 @@ void process_grid_vx() { pd_all.clear(); pd_all.set_ens_size(n_vx_vld[i]); pd_all.set_climo_cdf_info(conf_info.vx_opt[i].cdf_info); + pd_all.ctrl_index = conf_info.vx_opt[i].vx_pd.pd[0][0][0].ctrl_index; pd_all.skip_const = conf_info.vx_opt[i].vx_pd.pd[0][0][0].skip_const; // Apply the current mask to the fields and compute the pairs @@ -1813,7 +1847,7 @@ void process_grid_scores(int i_vx, ObsErrorEntry *e = (ObsErrorEntry *) 0; // Allocate memory in one big chunk based on grid size - pd.extend(grid.nx()*grid.ny()); + pd.extend(nxy); // Climatology flags bool emn_flag = (emn_dp.nx() == obs_dp.nx() && @@ -1880,7 +1914,8 @@ void process_grid_scores(int i_vx, pd.add_ens(j-n_miss, fcst_dp[j](x, y)); // Store the unperturbed ensemble value - pd.add_ens_var_sums(i, fraw_dp[j](x, y)); + // Exclude the control member from the variance + if(j != ctrl_index) pd.add_ens_var_sums(i, fraw_dp[j](x, y)); } } // end for j } // end for i @@ -1955,46 +1990,21 @@ void do_rps(const EnsembleStatVxOpt &vx_opt, //////////////////////////////////////////////////////////////////////// void clear_counts() { - int i, j, k; + int i, j; - // Allocate memory in one big chunk based on grid size, if needed - count_na.extend(nxy); - min_na.extend(nxy); - max_na.extend(nxy); - sum_na.extend(nxy); - sum_sq_na.extend(nxy); - for(i=0; i= MaxBuf[i] || is_bad_data(MaxBuf[i])) MaxBuf[i] = v; + // Ensemble sum + sum_na.buf()[i] += v; - SumBuf[i] += v; - SumSqBuf[i] += v*v; + // Ensemble min and max + if(v <= min_na.buf()[i] || is_bad_data(min_na.buf()[i])) min_na.buf()[i] = v; + if(v >= max_na.buf()[i] || is_bad_data(max_na.buf()[i])) max_na.buf()[i] = v; - for(j=0; j 0 @@ -2051,23 +2062,21 @@ void track_counts(int i_vx, const DataPlane &dp) { DataPlane frac_dp; // Loop over thresholds - for(i=0; i 0) thresh_nbrhd_count_na[i][j].inc(k, 1); + if(frac_dp.data()[k] > 0) thresh_nbrhd_cnt_na[i][j].inc(k, 1); } // end for k } // end for j @@ -2332,45 +2341,33 @@ void build_outfile_name(unixtime ut, const char *suffix, ConcatString &str) { //////////////////////////////////////////////////////////////////////// -void write_ens_nc(int i_ens, DataPlane &dp) { +void write_ens_nc(int i_var, DataPlane &ens_dp) { int i, j, k, l; double t, v; char type_str[max_str_len]; - DataPlane prob_dp, smooth_dp; - - // Arrays for storing ensemble data - float *ens_mean = (float *) 0; - float *ens_stdev = (float *) 0; - float *ens_minus = (float *) 0; - float *ens_plus = (float *) 0; - float *ens_min = (float *) 0; - float *ens_max = (float *) 0; - float *ens_range = (float *) 0; - int *ens_vld = (int *) 0; - float *ens_prob = (float *) 0; + DataPlane prob_dp, nbrhd_dp; // Allocate memory for storing ensemble data - ens_mean = new float [grid.nx()*grid.ny()]; - ens_stdev = new float [grid.nx()*grid.ny()]; - ens_minus = new float [grid.nx()*grid.ny()]; - ens_plus = new float [grid.nx()*grid.ny()]; - ens_min = new float [grid.nx()*grid.ny()]; - ens_max = new float [grid.nx()*grid.ny()]; - ens_range = new float [grid.nx()*grid.ny()]; - ens_vld = new int [grid.nx()*grid.ny()]; - ens_prob = new float [grid.nx()*grid.ny()]; + float * ens_mean = new float [nxy]; + float * ens_stdev = new float [nxy]; + float * ens_minus = new float [nxy]; + float * ens_plus = new float [nxy]; + float * ens_min = new float [nxy]; + float * ens_max = new float [nxy]; + float * ens_range = new float [nxy]; + int * ens_vld = new int [nxy]; // Store the threshold for the ratio of valid data points t = conf_info.vld_data_thresh; // Store the data - for(i=0; i 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" - << conf_info.ens_info[i_ens]->level_attr() + << conf_info.ens_info[i_var]->name_attr() << "_" + << conf_info.ens_info[i_var]->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -2625,16 +2590,16 @@ void write_ens_var_float(int i_ens, float *ens_data, DataPlane &dp, // if(strcmp(type_str, "ENS_MEAN") == 0) { name_str << cs_erase - << conf_info.ens_info[i_ens]->name_attr(); + << conf_info.ens_info[i_var]->name_attr(); } else { name_str << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" + << conf_info.ens_info[i_var]->name_attr() << "_" << type_str; } // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_ens], &ens_var, false, dp, + add_var_att_local(conf_info.ens_info[i_var], &ens_var, false, dp, name_str.c_str(), long_name_str); // Write the data @@ -2650,20 +2615,20 @@ void write_ens_var_float(int i_ens, float *ens_data, DataPlane &dp, //////////////////////////////////////////////////////////////////////// -void write_ens_var_int(int i_ens, int *ens_data, DataPlane &dp, +void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; // Append nc_pairs_var_str config file entry - cs = conf_info.ens_var_str[i_ens]; + cs = conf_info.ens_var_str[i_var]; if(cs.length() > 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" - << conf_info.ens_info[i_ens]->level_attr() + << conf_info.ens_info[i_var]->name_attr() << "_" + << conf_info.ens_info[i_var]->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -2678,11 +2643,11 @@ void write_ens_var_int(int i_ens, int *ens_data, DataPlane &dp, // Construct the variable name attribute name_str << cs_erase - << conf_info.ens_info[i_ens]->name_attr() << "_" + << conf_info.ens_info[i_var]->name_attr() << "_" << type_str; // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_ens], &ens_var, true, dp, + add_var_att_local(conf_info.ens_info[i_var], &ens_var, true, dp, name_str.c_str(), long_name_str); // Write the data @@ -2698,6 +2663,26 @@ void write_ens_var_int(int i_ens, int *ens_data, DataPlane &dp, //////////////////////////////////////////////////////////////////////// +void write_ens_data_plane(int i_var, const DataPlane &ens_dp, const DataPlane &dp, + const char *type_str, const char *long_name_str) { + + // Allocate memory for this data + float *ens_data = new float [nxy]; + + // Store the data in an array of floats + for(int i=0; i + + &MET_BIN;/ensemble_stat + + CENSOR_THRESH + CENSOR_VAL + SKIP_CONST FALSE + OUTPUT_PREFIX MASK_SID_CTRL + CONFIG_DIR &CONFIG_DIR; + + \ + 5 \ + &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib \ + &CONFIG_DIR;/EnsembleStatConfig_MASK_SID \ + -ctrl &DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ + -point_obs &OUTPUT_DIR;/ascii2nc/gauge_2012041012_24hr.nc \ + -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + + + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_MASK_SID_CTRL_20120410_120000V.stat + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_MASK_SID_CTRL_20120410_120000V_orank.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_MASK_SID_CTRL_20120410_120000V_ens.nc + + + &MET_BIN;/ensemble_stat From 3b13ce102db384e8c8b05d5092f2e28c8dd2f9cd Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 3 Nov 2021 13:42:36 -0600 Subject: [PATCH 004/172] Hotfix after merging changing for #1761. Updating the list of expected output files. --- test/xml/unit_perc_thresh.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/xml/unit_perc_thresh.xml b/test/xml/unit_perc_thresh.xml index 23e1c83aea..893dedf3cf 100644 --- a/test/xml/unit_perc_thresh.xml +++ b/test/xml/unit_perc_thresh.xml @@ -101,10 +101,8 @@ &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V.stat + &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_ctc.txt &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_cts.txt - &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_cnt.txt - &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_sl1l2.txt - &OUTPUT_DIR;/perc_thresh/grid_stat_PERC_THRESH_FBIAS_240000L_20120410_000000V_pairs.nc From 5131042053ffdc94c6c5fe6ed9a64ccd70775e96 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 3 Nov 2021 15:54:06 -0600 Subject: [PATCH 005/172] Per #1905, committing a hotfix directly to the develop branch. Reverting the logic for computing the ensemble range back to what it was previously. The new version produced very slight differences in the 6-th or 7-th decimal place when compared to previous results. There's not good reason for these changes which were caused by the order of operations in casting from doubles to floats. Reverting back to the old logic prevents diffs for anyone else downstream and is the prudent choice. --- met/src/tools/core/ensemble_stat/ensemble_stat.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 783691945b..d712c96abd 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -2387,8 +2387,8 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { ens_min[i] = (float) min_na[i]; ens_max[i] = (float) max_na[i]; v = max_na[i] - min_na[i]; - ens_range[i] = (is_eq(max_na[i], min_na[i]) ? - 0.0 : (float) max_na[i] - min_na[i]); + if(is_eq(v, 0.0)) v = 0; + ens_range[i] = (float) v; } } // end for i From 4ff28d192d07fb61c3271cea4d62b8b59b84ef6b Mon Sep 17 00:00:00 2001 From: johnhg Date: Thu, 4 Nov 2021 08:53:32 -0600 Subject: [PATCH 006/172] Feature 1957 ascii2nc_python (#1958) --- met/src/tools/other/ascii2nc/ascii2nc.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/met/src/tools/other/ascii2nc/ascii2nc.cc b/met/src/tools/other/ascii2nc/ascii2nc.cc index a8f74f9daf..4d876793b8 100644 --- a/met/src/tools/other/ascii2nc/ascii2nc.cc +++ b/met/src/tools/other/ascii2nc/ascii2nc.cc @@ -116,7 +116,7 @@ static ASCIIFormat ascii_format = ASCIIFormat_None; //////////////////////////////////////////////////////////////////////// // Variables for command line arguments -static vector< ConcatString > asfile_list; +static vector asfile_list; static ConcatString ncfile; static ConcatString config_filename(replace_path(DEFAULT_CONFIG_FILENAME)); @@ -234,10 +234,13 @@ int main(int argc, char *argv[]) { file_handler->setMessageTypeMap(config_info.getMessageTypeMap()); // - // Process the files. If a configuration file was specified, do any - // extra processing specified. + // Read the input files // - file_handler->readAsciiFiles(asfile_list); + if(!file_handler->readAsciiFiles(asfile_list)) { + mlog << Error << "\n" << program_name << "-> " + << "encountered an error while reading input files!\n\n"; + exit(1); + } // // Summarize the observations, if directed. We need to use a different From aee6269263380bcf1e0b1c91f44e9435c299f24e Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Mon, 15 Nov 2021 09:01:58 -0700 Subject: [PATCH 007/172] Feature 1949 cf netcdf documentaton (#1951) * #1949 Added CF compliant NetCDF into data IO * #1949 Added commas * #1948 Some corrections for typo and added the links for CF attributes * #1948 Added Performance with NetCDF input data * #1949 Corrected tyoe and applied Juloie's suggestions Co-authored-by: Howard Soh --- met/docs/Users_Guide/data_io.rst | 112 +++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/met/docs/Users_Guide/data_io.rst b/met/docs/Users_Guide/data_io.rst index 8b6d41ea95..dcca8763f9 100644 --- a/met/docs/Users_Guide/data_io.rst +++ b/met/docs/Users_Guide/data_io.rst @@ -18,6 +18,118 @@ Input point observation files in PrepBUFR format are available through NCEP. The Tropical cyclone forecasts and observations are typically provided in a specific ATCF (Automated Tropical Cyclone Forecasting) ASCII format, in A-deck, B-deck, and E-deck files. +Requirements for CF Compliant NetCDF +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The MET tools use following attributes and variables for input CF Compliant NetCDF data. + +1. The global attribute "Conventions". + +2. The "`standard_name `_" and "`units `_" attributes for coordinate variables. The "`axis `_" attribute ("T" or "time") must exist as the time variable if the "standard_name" attribute does not exist. + +3. The "`coordinates `_" attribute for the data variables. It contains the coordinate variable names. + +4. The "`grid_mapping `_" attribute for the data variables for projections and the matching grid mapping variable (optional for the latitude_longitude projection). + +5. The gridded data should be evenly spaced horizontally and vertically. + +6. (Optional) the "`forecast_reference_time `_" variable for init_time. + +MET processes the CF-Compliant gridded NetCDF files with the projection information. The CF-Compliant NetCDF is defined by the global attribute "Conventions" whose value begins with "CF-" ("CF-"). The global attribute "Conventions" is mandatory. MET accepts the variation of this attribute ("conventions" and "CONVENTIONS"). The value should be started with "CF-" and followed by the version number. MET accepts the attribute value that begins with "CF " ("CF" and a space instead of a hyphen) or "COARDS". + +The grid mapping variable contains the projection information. The grid mapping variable can be found by looking at the variable attribute "grid_mapping" from the data variables. The "standard_name" attribute is used to filter out the coordinate variables like time, latitude, and longitude variables. The value of the "grid_mapping" attribute is the name of the grid mapping variable. Four projections are supported with grid mapping variables: latitude_longitude, lambert_conformal_conic, polar_stereographic, and geostationary. In case of the latitude_longitude projection, the latitude and longitude variable names should be the same as the dimension names and the "units" attribute should be valid. + +Here are examples for the grid mapping variable ("edr" is the data variable): + +**Example 1: grid mapping for latitude_longitude projection** + +.. code-block:: none + + float edr(time, z, lat, lon) ; + edr:units = "m^(2/3) s^-1" ; + edr:long_name = "Median eddy dissipation rate" ; + edr:coordinates = "lat lon" ; + edr:_FillValue = -9999.f ; + edr:grid_mapping = "grid_mapping" ; + int grid_mapping ; + grid_mapping:grid_mapping_name = "latitude_longitude" ; + grid_mapping:semi_major_axis = 6371000. ; + grid_mapping:inverse_flattening = 0 ; + + +**Example 2: grid mapping for lambert_conformal_conic projection** + +.. code-block:: none + + float edr(time, z, y, x) ; + edr:units = "m^(2/3) s^-1" ; + edr:long_name = "Eddy dissipation rate" ; + edr:coordinates = "lat lon" ; + edr:_FillValue = -9999.f ; + edr:grid_mapping = "grid_mapping" ; + int grid_mapping ; + grid_mapping:grid_mapping_name = "lambert_conformal_conic" ; + grid_mapping:standard_parallel = 25. ; + grid_mapping:longitude_of_central_meridian = -95. ; + grid_mapping:latitude_of_projection_origin = 25. ; + grid_mapping:false_easting = 0 ; + grid_mapping:false_northing = 0 ; + grid_mapping:GRIB_earth_shape = "spherical" ; + grid_mapping:GRIB_earth_shape_code = 0 ; + +When the grid mapping variable is not available, MET detects the latitude_longitude projection in following order: + +1. the lat/lon projection from the dimensions + +2. the lat/lon projection from the "coordinates" attribute from the data variable + +3. the lat/lon projection from the latitude and longitude variables by the "standard_name" attribute + +MET is looking for variables with the same name as the dimension and checking the "units" attribute to find the latitude and longitude variables. The valid "units" strings are listed in the table below. MET accepts the variable "tlat" and "tlon" if the dimension names are "nlat" and "nlon”. + +If there are no latitude and longitude variables from dimensions, MET gets coordinate variable names from the "coordinates" attribute. The matching coordinate variables should have the proper "units" attribute. + +MET gets the time, latitude, and longitude variables by looking at the standard name: "time", "latitude", and "longitude" as the last option. + +MET gets the valid time from the time variable and the "forecast_reference_time" variable for the init_time. If the time variable does not exist, it can come from the file name. MET supports only two cases: + +1. TRMM_3B42_3hourly_filename (3B42...7.G3.nc) + +2. TRMM_3B42_daily_filename (3B42_daily...
.7.G3.nc) + +.. list-table:: Valid strings for the "units" attribute. + :widths: auto + :header-rows: 1 + + * - time + - latitude + - longitude + * - "seconds since YYYY-MM-DD HH:MM:SS", + "minutes since YYYY-MM-DD HH:MM:SS", + "hours since YYYY-MM-DD HH:MM:SS", + "days since YYYY-MM-DD HH:MM:SS", + Accepts "Y", "YY", "YYY", "M", "D", "HH", and "HH:MM". + "HH:MM:SS" is optional + - "degrees_north", + "degree_north", + "degree_N", + "degrees_N", + "degreeN", + "degreesN" + - "degrees_east", + "degree_east", + "degree_E", + "degrees_E", + "degreeE", + "degreesE" + +Performance with NetCDF input data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There is no limitation on the NetCDF file size. The size of the data variables matters more than the file size. The NetCDF API loads the metadata first upon opening the NetCDF file. It's similar for accessing data variables. There are two API calls: getting the metadata and getting the actual data. The memory is allocated and consumed at the second API call (getting the actual data). + +The dimensions of the data variables matter. MET requests the NetCDF data needs based on: 1) loading and processing a data plane, and 2) loading and processing the next data plane. This means an extra step for slicing with one more dimension in the NetCDF input data. The performance is quite different if the compression is enabled with high resolution data. NetCDF does compression per variable. The variables can have different compression levels (0 to 9). A value of 0 means no compression, and 9 is the highest level of compression possible. The number for decompression is the same between one more and one less dimension NetCDF input files (combined VS separated). The difference is the amount of data to be decompressed which requires more memory. For example, let's assume the time dimension is 30. NetCDF data with one less dimension (no time dimension) does decompression 30 times for nx by ny dataset. NetCDF with one more dimension does compression 30 times for 30 by nx by ny dataset and slicing for target time offset. So it's better to have multiple NetCDF files with one less dimension than a big file with bigger variable data if compressed. If the compression is not enabled, the file size will be much bigger requiring more disk space. + .. _Intermediate data formats: Intermediate data formats From 867360f7fc52c62a752873bf69775973e7936a8a Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 15 Nov 2021 14:41:55 -0700 Subject: [PATCH 008/172] Feature 1968 ens_ctrl (#1969) --- met/docs/Users_Guide/ensemble-stat.rst | 2 +- met/docs/Users_Guide/gen-ens-prod.rst | 2 +- met/src/tools/core/ensemble_stat/ensemble_stat.cc | 9 +++++++++ met/src/tools/other/gen_ens_prod/gen_ens_prod.cc | 15 ++++++++++++--- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index 1c131a9580..266519da4f 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -97,7 +97,7 @@ Optional arguments for ensemble_stat 6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** option specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** option from earlier versions of MET. -7. The **-ctrl file** option specifies an ensemble control member data file. The control member is included in the computation of the ensemble mean but excluded from the spread. +7. The **-ctrl file** option specifies an ensemble control member data file. The control member is included in the computation of the ensemble mean but excluded from the spread. The control file should not appear in the list of ensemble member files. 8. To filter point observations by time, use **-obs_valid_beg time** in YYYYMMDD[_HH[MMSS]] format to set the beginning of the matching observation time window. diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index 69cf1d3c73..029d256ad2 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -67,7 +67,7 @@ Required arguments gen_ens_prod Optional arguments for gen_ens_prod ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -4. The **-ctrl file** option specifies the input file for the ensemble control member. Data for this member is included in the computation of the ensemble mean, but excluded from the spread. +4. The **-ctrl file** option specifies the input file for the ensemble control member. Data for this member is included in the computation of the ensemble mean, but excluded from the spread. The control file should not appear in the **-ens** list of ensemble member files. 5. The **-log** file outputs log messages to the specified file. diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index d712c96abd..fe5d160157 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -62,6 +62,7 @@ // 031 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. // 032 10/07/21 Halley Gotway MET #1905 Add -ctrl option. +// 032 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. // //////////////////////////////////////////////////////////////////////// @@ -295,6 +296,14 @@ void process_command_line(int argc, char **argv) { // Prepend the control member, if specified if(ctrl_file.nonempty()) { + + if(ens_file_list.has(ctrl_file)) { + mlog << Error << "\nprocess_command_line() -> " + << "the ensemble control file should not appear in the list " + << "of ensemble member files:\n" << ctrl_file << "\n\n"; + exit(1); + } + ctrl_index = 0; ens_file_list.insert(ctrl_index, ctrl_file.c_str()); n_ens++; diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 4fc7491c86..c7b48a7331 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -12,9 +12,10 @@ // // Description: // -// Mod# Date Name Description -// ---- ---- ---- ----------- -// 000 09/10/21 Halley Gotway Initial version (MET #1904). +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 09/10/21 Halley Gotway MET #1904 Initial version. +// 001 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. // //////////////////////////////////////////////////////////////////////// @@ -201,6 +202,14 @@ void process_command_line(int argc, char **argv) { mlog << Debug(1) << "Ensemble Control: " << (ctrl_file.empty() ? "None" : ctrl_file.c_str()) << "\n"; + // Check for control in the list of ensemble files + if(ctrl_file.nonempty() && ens_files.has(ctrl_file)) { + mlog << Error << "\nprocess_command_line() -> " + << "the ensemble control file should not appear in the list " + << "of ensemble member files:\n" << ctrl_file << "\n\n"; + exit(1); + } + // Check for missing non-python ensemble files for(i=0; i Date: Tue, 16 Nov 2021 11:14:18 -0700 Subject: [PATCH 009/172] Feature 1809 gen prob (#1967) --- met/data/config/TCGenConfig_default | 11 +- .../table_files/met_header_columns_V10.1.txt | 2 +- met/docs/Users_Guide/tc-gen.rst | 143 ++- .../libcode/vx_tc_util/Makefile.am | 2 + .../libcode/vx_tc_util/test_read_prob.cc | 2 +- met/src/basic/vx_config/config_constants.h | 1 + met/src/basic/vx_util/stat_column_defs.h | 1 + met/src/libcode/vx_statistics/met_stats.cc | 21 + met/src/libcode/vx_statistics/met_stats.h | 1 + met/src/libcode/vx_tc_util/Makefile.am | 1 + met/src/libcode/vx_tc_util/atcf_offsets.h | 15 +- met/src/libcode/vx_tc_util/atcf_prob_line.cc | 6 +- met/src/libcode/vx_tc_util/prob_gen_info.cc | 241 +++++ met/src/libcode/vx_tc_util/prob_gen_info.h | 98 ++ met/src/libcode/vx_tc_util/prob_info_array.cc | 168 ++- met/src/libcode/vx_tc_util/prob_info_array.h | 18 +- met/src/libcode/vx_tc_util/prob_info_base.cc | 21 +- met/src/libcode/vx_tc_util/prob_info_base.h | 7 +- met/src/libcode/vx_tc_util/prob_rirw_info.cc | 15 +- met/src/libcode/vx_tc_util/prob_rirw_info.h | 4 +- met/src/tools/tc_utils/tc_gen/tc_gen.cc | 976 +++++++++++++++--- met/src/tools/tc_utils/tc_gen/tc_gen.h | 20 +- .../tools/tc_utils/tc_gen/tc_gen_conf_info.cc | 197 +++- .../tools/tc_utils/tc_gen/tc_gen_conf_info.h | 63 +- met/src/tools/tc_utils/tc_pairs/Makefile.am | 1 + met/src/tools/tc_utils/tc_pairs/tc_pairs.cc | 40 +- test/config/TCGenConfig_prob | 288 ++++++ test/hdr/met_10_1.hdr | 2 +- test/xml/unit_tc_gen.xml | 28 +- 29 files changed, 2103 insertions(+), 290 deletions(-) create mode 100644 met/src/libcode/vx_tc_util/prob_gen_info.cc create mode 100644 met/src/libcode/vx_tc_util/prob_gen_info.h create mode 100644 test/config/TCGenConfig_prob diff --git a/met/data/config/TCGenConfig_default b/met/data/config/TCGenConfig_default index 9ed75cc2c2..839d8bd21d 100644 --- a/met/data/config/TCGenConfig_default +++ b/met/data/config/TCGenConfig_default @@ -212,6 +212,11 @@ ops_method_flag = TRUE; // //////////////////////////////////////////////////////////////////////////////// +// +// Probability of genesis thresholds +// +prob_genesis_thresh = ==0.25; + // // Confidence interval alpha value // @@ -222,8 +227,12 @@ ci_alpha = 0.05; // output_flag = { fho = NONE; - ctc = BOTH; + ctc = BOTH; cts = BOTH; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; genmpr = NONE; } diff --git a/met/data/table_files/met_header_columns_V10.1.txt b/met/data/table_files/met_header_columns_V10.1.txt index c0218275ec..1dbd3c2849 100644 --- a/met/data/table_files/met_header_columns_V10.1.txt +++ b/met/data/table_files/met_header_columns_V10.1.txt @@ -28,7 +28,7 @@ V10.1 : STAT : SSVAR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID V10.1 : STAT : VAL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFABAR VFABAR UOABAR VOABAR UVFOABAR UVFFABAR UVOOABAR V10.1 : STAT : VL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFBAR VFBAR UOBAR VOBAR UVFOBAR UVFFBAR UVOOBAR F_SPEED_BAR O_SPEED_BAR V10.1 : STAT : VCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR FBAR_BCL FBAR_BCU OBAR OBAR_BCL OBAR_BCU FS_RMS FS_RMS_BCL FS_RMS_BCU OS_RMS OS_RMS_BCL OS_RMS_BCU MSVE MSVE_BCL MSVE_BCU RMSVE RMSVE_BCL RMSVE_BCU FSTDEV FSTDEV_BCL FSTDEV_BCU OSTDEV OSTDEV_BCL OSTDEV_BCU FDIR FDIR_BCL FDIR_BCU ODIR ODIR_BCL ODIR_BCU FBAR_SPEED FBAR_SPEED_BCL FBAR_SPEED_BCU OBAR_SPEED OBAR_SPEED_BCL OBAR_SPEED_BCU VDIFF_SPEED VDIFF_SPEED_BCL VDIFF_SPEED_BCU VDIFF_DIR VDIFF_DIR_BCL VDIFF_DIR_BCU SPEED_ERR SPEED_ERR_BCL SPEED_ERR_BCU SPEED_ABSERR SPEED_ABSERR_BCL SPEED_ABSERR_BCU DIR_ERR DIR_ERR_BCL DIR_ERR_BCU DIR_ABSERR DIR_ABSERR_BCL DIR_ABSERR_BCU -V10.1 : STAT : GENMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX STORM_ID AGEN_INIT AGEN_FHR AGEN_LAT AGEN_LON AGEN_DLAND BGEN_LAT BGEN_LON BGEN_DLAND GEN_DIST GEN_TDIFF INIT_TDIFF DEV_CAT OPS_CAT +V10.1 : STAT : GENMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX STORM_ID PROB_LEAD PROB_VAL AGEN_INIT AGEN_FHR AGEN_LAT AGEN_LON AGEN_DLAND BGEN_LAT BGEN_LON BGEN_DLAND GEN_DIST GEN_TDIFF INIT_TDIFF DEV_CAT OPS_CAT V10.1 : STAT : SSIDX : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE FCST_MODEL REF_MODEL N_INIT N_TERM N_VLD SS_INDEX V10.1 : MODE : OBJ : VERSION MODEL N_VALID GRID_RES DESC FCST_LEAD FCST_VALID FCST_ACCUM OBS_LEAD OBS_VALID OBS_ACCUM FCST_RAD FCST_THR OBS_RAD OBS_THR FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE OBJECT_ID OBJECT_CAT CENTROID_X CENTROID_Y CENTROID_LAT CENTROID_LON AXIS_ANG LENGTH WIDTH AREA AREA_THRESH CURVATURE CURVATURE_X CURVATURE_Y COMPLEXITY INTENSITY_10 INTENSITY_25 INTENSITY_50 INTENSITY_75 INTENSITY_90 INTENSITY_USER INTENSITY_SUM CENTROID_DIST BOUNDARY_DIST CONVEX_HULL_DIST ANGLE_DIFF ASPECT_DIFF AREA_RATIO INTERSECTION_AREA UNION_AREA SYMMETRIC_DIFF INTERSECTION_OVER_AREA CURVATURE_RATIO COMPLEXITY_RATIO PERCENTILE_INTENSITY_RATIO INTEREST diff --git a/met/docs/Users_Guide/tc-gen.rst b/met/docs/Users_Guide/tc-gen.rst index 61209566dc..b67f1a26b9 100644 --- a/met/docs/Users_Guide/tc-gen.rst +++ b/met/docs/Users_Guide/tc-gen.rst @@ -6,14 +6,18 @@ TC-Gen Tool Introduction ____________ -The TC-Gen tool provides verification of tropical cyclone genesis forecasts in ATCF file format. Producing reliable tropical cyclone genesis forecasts is an important metric for global numerical weather prediction models. This tool ingests deterministic model output post-processed by a genesis tracking software (e.g. GFDL vortex tracker) and ATCF format reference dataset(s) (e.g. Best Track analysis and CARQ operational tracks) and outputs categorical counts and statistics. The capability to modify the spatial and temporal tolerances that define a "hit" forecast is included to give users the ability to condition the criteria based on model performance and/or conduct sensitivity analyses. Statistical aspects are outlined in :numref:`tc-gen_stat_aspects` and practical aspects of the TC-Gen tool are described in :numref:`tc-gen_practical_info`. +The TC-Gen tool provides verification of deterministic and probabilistic tropical cyclone genesis forecasts in the ATCF file format. Producing reliable tropical cyclone genesis forecasts is an important metric for global numerical weather prediction models. This tool ingests deterministic model output post-processed by a genesis tracking software (e.g. GFDL vortex tracker), ATCF edeck files containing probability of genesis forecasts, and ATCF reference track dataset(s) (e.g. Best Track analysis and CARQ operational tracks). It writes categorical counts and statistics. The capability to modify the spatial and temporal tolerances when matching forecasts to reference genesis events, as well as scoring those matched pairs, gives users the ability to condition the criteria based on model performance and/or conduct sensitivity analyses. Statistical aspects are outlined in :numref:`tc-gen_stat_aspects` and practical aspects of the TC-Gen tool are described in :numref:`tc-gen_practical_info`. .. _tc-gen_stat_aspects: Statistical aspects ___________________ -The TC-Gen tool populates a contingency tables with hits, misses, and false alarms. As with other extreme events (where the event occurs much less frequently than the non-event), the correct negative category is not computed the non-events would dominate the contingency table. Therefore, only statistics that do not include correct negatives should be considered for this tool. The following CTS statistics are relevant: Base rate (BASER), Mean forecast (FMEAN), Frequency Bias (FBIAS), Probability of Detection (PODY), False Alarm Ratio (FAR), Critical Success Index (CSI), Gilbert Skill Score (GSS), Extreme Dependency Score (EDS), Symmetric Extreme Dependency Score (SEDS), Bias Adjusted Gilbert Skill Score (BAGSS). +The TC-Gen tool processes both deterministic and probabilistic forecasts. For deterministic forecasts specified using the **-track** command line option, it identifies genesis events in both the forecasts and reference datasets, typically Best tracks. It applies user-specified configuration options to pair up the forecast and reference genesis events and categorize each pair as a hit, miss, or false alarm. + +As with other extreme events (where the event occurs much less frequently than the non-event), the correct negative category is not computed since the non-events would dominate the contingency table. Therefore, only statistics that do not include correct negatives should be considered for this tool. The following CTS statistics are relevant: Base rate (BASER), Mean forecast (FMEAN), Frequency Bias (FBIAS), Probability of Detection (PODY), False Alarm Ratio (FAR), Critical Success Index (CSI), Gilbert Skill Score (GSS), Extreme Dependency Score (EDS), Symmetric Extreme Dependency Score (SEDS), Bias Adjusted Gilbert Skill Score (BAGSS). + +For probabilistic forecasts specified using the **-edeck** command line option, it identifies genesis events in the reference dataset. It applies user-specified configuration options to pair the forecast probabilities to the reference genesis events. These pairs are added to an Nx2 probabilistic contingency table. If the reference genesis event occurs within in the predicted time window, the pair is counted in the observation-yes column. Otherwise, it is added to the observation-no column. Other considerations for interpreting the output of the TC-Gen tool involve the size of the contingency table output. The size of the contingency table will change depending on the number of matches. Additionally, the number of misses is based on the forecast duration and interval (specified in the configuration file). This change is due to the number of model opportunities to forecast the event, which is determined by the specified duration/interval. @@ -34,8 +38,8 @@ The usage statement for tc_gen is shown below: .. code-block:: none Usage: tc_gen - -genesis path - -track path + -genesis source and/or -edeck source + -track source -config file [-out base] [-log file] @@ -46,50 +50,76 @@ TC-Gen has three required arguments and accepts optional ones. Required arguments for tc_gen ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1. The **-genesis path** argument is the path to one or more ATCF or fort.66 (see documentation listed below) files generated by the Geophysical Fluid Dynamics Laboratory (GFDL) Vortex Tracker when run in tcgen mode or an ASCII file list or a top-level directory containing them. The **-genesis** option must be used at least once. The required file format is described in the "Output formats" section of the `GFDL Vortex Tracker users guide. `_ +1. The **-genesis source** argument is the path to one or more ATCF or fort.66 (see documentation listed below) files generated by the Geophysical Fluid Dynamics Laboratory (GFDL) Vortex Tracker when run in tcgen mode or an ASCII file list or a top-level directory containing them. The required file format is described in the "Output formats" section of the `GFDL Vortex Tracker users guide. `_ + +2. The **-edeck source** argument is the path to one or more ATCF edeck files, an ASCII file list containing them, or a top-level directory with files matching the regular expression ".dat". The probability of genesis are read from each edeck input file and verified against at the **-track** data. The **-genesis** or **-edeck** option must be used at least once. -2. The **-track path** argument is one or more ATCF reference track files or an ASCII file list or top-level directory containing them, with files ending in ".dat". This tool processes either Best track data from bdeck files, or operational track data (e.g. CARQ) from adeck files, or both. Providing both bdeck and adeck files will result in a richer dataset to match with the **-genesis** files. Both adeck and bdeck data should be provided using the **-track** option. The **-track** option must be used at least once. +3. The **-track source** argument is one or more ATCF reference track files or an ASCII file list or top-level directory containing them, with files ending in ".dat". This tool processes either Best track data from bdeck files, or operational track data (e.g. CARQ) from adeck files, or both. Providing both bdeck and adeck files will result in a richer dataset to match with the **-genesis** files. Both adeck and bdeck data should be provided using the **-track** option. The **-track** option must be used at least once. -3. The **-config** file argument indicates the name of the configuration file to be used. The contents of the configuration file are discussed below. +4. The **-config** file argument indicates the name of the configuration file to be used. The contents of the configuration file are discussed below. Optional arguments for tc_gen ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -4. The **-out base** argument indicates the path of the output file base. This argument overrides the default output file base (./tc_gen) +5. The **-out base** argument indicates the path of the output file base. This argument overrides the default output file base (./tc_gen) -5. The **-log file** option directs output and errors to the specified log file. All messages will be written to that file as well as standard out and error. Thus, users can save the messages without having to redirect the output on the command line. The default behavior is no log file. +6. The **-log file** option directs output and errors to the specified log file. All messages will be written to that file as well as standard out and error. Thus, users can save the messages without having to redirect the output on the command line. The default behavior is no log file. -6. The **-v level** option indicates the desired level of verbosity. The contents of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity above 1 will increase the amount of logging. +7. The **-v level** option indicates the desired level of verbosity. The contents of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity above 1 will increase the amount of logging. -The TC-Gen tool implements the following logic: +Scoring Logic +^^^^^^^^^^^^^ -* Parse the forecast genesis data and identify forecast genesis events separately for each model present. +The TC-Gen tool implements the following logic: * Parse the Best and operational track data, and identify Best track genesis events. Note that Best tracks with a cyclone number greater than 50 are automatically discarded from the analysis. Large cyclone numbers are used for pre-season testing or to track invests prior to a storm actually forming. Running this tool at verbosity level 6 (-v 6) prints details about which tracks are discarded. -* Loop over the filters defined in the configuration file and apply the following logic for each. +* For **-track** inputs: + + * Parse the forecast genesis data and identify forecast genesis events separately for each model present. - * For each Best track genesis event meeting the filter critera, determine the initialization and lead times for which the model had an opportunity to forecast that genesis event. Store an unmatched genesis pair for each case. + * Loop over the filters defined in the configuration file and apply the following logic for each. + + * For each Best track genesis event meeting the filter critera, determine the initialization and lead times for which the model had an opportunity to forecast that genesis event. Store an unmatched genesis pair for each case. - * For each forecast genesis event, search for a matching Best track. A configurable boolean option controls whether all Best track points are considered for a match or only the single Best track genesis point. A match occurs if the Best track point valid time is within a configurable window around the forecast genesis time and the Best track point location is within a configurable radius of the forecast genesis location. If a Best track match is found, store the storm ID. + * For each forecast genesis event, search for a matching Best track. A configurable boolean option controls whether all Best track points are considered for a match or only the single Best track genesis point. A match occurs if the Best track point valid time is within a configurable window around the forecast genesis time and the Best track point location is within a configurable radius of the forecast genesis location. If a Best track match is found, store the storm ID. - * In no Best track match is found, apply the same logic to search the operational track points with lead time of 0 hours. If an operational match is found, store the storm ID. + * If no Best track match is found, apply the same logic to search the operational track points with lead time of 0 hours. If an operational match is found, store the storm ID. - * If a matching storm ID is found, match the forecast genesis event to the Best track genesis event for that storm ID. + * If a matching storm ID is found, match the forecast genesis event to the Best track genesis event for that storm ID. - * If no matching storm ID is found, store an unmatched pair for the genesis forecast. + * If no matching storm ID is found, store an unmatched pair for the genesis forecast. - * Loop through the genesis pairs and populate contingency tables using two methods, the developement (dev) and operational (ops) methods. For each pair, if the forecast genesis event is unmatched, score it as a dev and ops FALSE ALARM. If the Best track genesis event is unmatched, score it as a dev and ops MISS. Score each matched genesis pair as follows: + * Loop through the genesis pairs and populate contingency tables using two methods, the development (dev) and operational (ops) methods. For each pair, if the forecast genesis event is unmatched, score it as a dev and ops FALSE ALARM. If the Best track genesis event is unmatched, score it as a dev and ops MISS. Score each matched genesis pair as follows: - * If the forecast initialization time is at or after the Best track genesis event, DISCARD this case and exclude it from the statistics. + * If the forecast initialization time is at or after the Best track genesis event, DISCARD this case and exclude it from the statistics. - * Compute the difference between the forecast and Best track genesis events in time and space. If they are both within the configurable tolerance, score it as a dev HIT. If not, score it as a dev FALSE ALARM. + * Compute the difference between the forecast and Best track genesis events in time and space. If they are both within the configurable tolerance, score it as a dev HIT. If not, score it as a dev FALSE ALARM. - * Compute the difference between the Best track genesis time and model initialization time. If it is within the configurable tolerance, score it as an ops HIT. If not, score it as an ops FALSE ALARM. + * Compute the difference between the Best track genesis time and model initialization time. If it is within the configurable tolerance, score it as an ops HIT. If not, score it as an ops FALSE ALARM. + + * Do not count any CORRECT NEGATIVES. + + * Report the contingency table hits, misses, and false alarms separately for each forecast model and configuration file filter. The development (dev) scoring method is indicated in the output as *GENESIS_DEV* while the operational (ops) scoring method is indicated as *GENESIS_OPS*. + +* For **-edeck** inputs: + + * Parse the ATCF edeck files. Ignore any lines not containing "GN" and "genFcst", which indicate a genesis probability forecast. Also, ignore any lines which do not contain a predicted genesis location (latitude and longitude) or genesis time. + + * Loop over the filters defined in the configuration file and apply the following logic for each. - * Do not count any CORRECT NEGATIVES. + * Subset the genesis probability forecasts based on the current filter criteria. Typically, genesis probability forecast are provided for multiple lead times. Create separate Nx2 probabilistic contingency tables for each unique combination of predicted lead time and model name. + + * For each genesis probability forecast, search for a matching Best track. A configurable boolean option controls whether all Best track points are considered for a match or only the single Best track genesis point. A match occurs if the Best track point valid time is within a configurable window around the forecast genesis time and the Best track point location is within a configurable radius of the forecast genesis location. If a Best track match is found, store the storm ID. + + * If no Best track match is found, apply the same logic to search the operational track points with lead time of 0 hours. If an operational match is found, store the storm ID. + + * If no matching storm ID is found, add the unmatched forecast to the observation-no column of the Nx2 probabilistic contingency table. + + * If a matching storm ID is found, check whether that storm's genesis occurred within the predicted time window: between the forecast initialization time and the predicted lead time. If so, add the matched forecast to the observation-yes column. If not, add it to observation-no column. + + * Report the Nx2 probabilistic contingency table counts and statistics for each forecast model, lead time, and configuration file filter. These counts and statistics are identified in the output files as *PROB_GENESIS*. -* Report the contingency table hits, misses, and false alarms separately for each forecast model and configuration file filter. The development (dev) scoring method is indicated in the output as *GENESIS_DEV* while the operational (ops) scoring method is indicated as *GENESIS_OPS*. tc_gen configuration file ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -381,18 +411,31 @@ The **nc_pairs_grid** entry is a string which defines the grid to be used for th ______________________ +.. code-block:: none + + prob_genesis_thresh = ==0.25; + +The **prob_genesis_thresh** entry defines the probability thresholds used to create the output Nx2 contingency table when verifying edeck probability of genesis forecasts. The default is probability bins of width 0.25. These probabilities may be specified as a list (>0.00,>0.25,>0.50,>0.75,>1.00) or using shorthand notation (==0.25) for bins of equal width. + +______________________ + .. code-block:: none ci_alpha = 0.05; output_flag = { - fho = BOTH; - ctc = BOTH; - cts = BOTH; + fho = BOTH; + ctc = BOTH; + cts = BOTH; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + genmpr = NONE; } dland_file = "MET_BASE/tc_data/dland_global_tenth_degree.nc"; version = "VN.N"; -The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. Note that TC-Gen writes output for 2x2 contingency tables to the **FHO, CTC**, and **CTS** line types. +The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. TC-Gen writes output for 2x2 contingency tables to the **FHO**, **CTC**, and **CTS** line types when verifying deterministic genesis forecasts specified using the **-track** command line option. TC-Gen writes output for Nx2 probabilistic contingency tables to the **PCT**, **PSTD**, **PJC**, and **PRC** line types when verifying the probability of genesis forecasts specified using the **-edeck** command line option. Note that the **genmpr** line type is specific to TC-Gen and describes individual genesis matched pairs. tc_gen output ~~~~~~~~~~~~~ @@ -440,7 +483,7 @@ TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The AS - Maximum Best track valid time in YYYYMMDD_HHMMSS format * - 10 - FCST_VAR - - Genesis methodology + - Genesis methodology (GENESIS_DEV, GENESIS_OPS, or PROB_GENESIS) * - 11 - FCST_UNITS - Does not apply and is set to NA @@ -449,7 +492,7 @@ TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The AS - Does not apply and is set to NA * - 13 - OBS_VAR - - Genesis methodology + - Genesis methodology (GENESIS_DEV, GENESIS_OPS, or PROB_GENESIS) * - 14 - OBS_UNITS - Does not apply and is set to NA @@ -515,44 +558,50 @@ TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The AS - STORM_ID - BBCCYYYY designation of storm (basin, cyclone number, and year) * - 28 + - PROB_LEAD + - Lead time in HHH format for the predicted probability of genesis (only for **-edeck** inputs) + * - 29 + - PROB_VAL + - Predicted probability of genesis (only for **-edeck** inputs) + * - 30 - AGEN_INIT - Forecast initialization time - * - 29 + * - 31 - AGEN_FHR - Forecast hour of genesis event - * - 30 + * - 32 - AGEN_LAT - Latitude position of the forecast genesis event - * - 31 + * - 33 - AGEN_LON - Longitude position of the forecast genesis event - * - 32 + * - 34 - AGEN_DLAND - Forecast genesis event distance to land (nm) - * - 33 + * - 35 - BGEN_LAT - Latitude position of the verifying Best track genesis event - * - 34 + * - 36 - BGEN_LON - Longitude position of the verifying Best track genesis event - * - 35 + * - 37 - BGEN_DLAND - Best track genesis event distance to land (nm) - * - 36 + * - 38 - GEN_DIST - - Distance between the forecast and Best track genesis events (km) - * - 37 + - Distance between the forecast and Best track genesis events (km) (only for **-track** inputs) + * - 39 - GEN_TDIFF - - Forecast minus Best track genesis time in HHMMSS format - * - 38 + - Forecast minus Best track genesis time in HHMMSS format (only for **-track** inputs) + * - 40 - INIT_TDIFF - - Best track genesis minus forecast initialization time in HHMMSS format - * - 39 + - Best track genesis minus forecast initialization time in HHMMSS format (only for **-track** inputs) + * - 41 - DEV_CAT - - Development methodology category (FYOY, FYON, FNOY, or DISCARD) - * - 40 + - Category for the development methodology (FYOY, FYON, FNOY, or DISCARD) (only for **-track** inputs) + * - 42 - OPS_CAT - - Operational methodology category (FYOY, FYON, FNOY, or DISCARD) + - Category for the operational methodology (FYOY, FYON, FNOY, or DISCARD for **-track** inputs and FYOY or FYON for **-edeck** inputs) .. _table_TG_var_NetCDF_matched_pair_out: diff --git a/met/internal_tests/libcode/vx_tc_util/Makefile.am b/met/internal_tests/libcode/vx_tc_util/Makefile.am index a5fc96c5d0..a1d0fed6c5 100644 --- a/met/internal_tests/libcode/vx_tc_util/Makefile.am +++ b/met/internal_tests/libcode/vx_tc_util/Makefile.am @@ -43,6 +43,7 @@ test_read_LDADD = -lvx_stat_out \ -lvx_config \ -lvx_gsl_prob \ -lvx_cal \ + -lvx_nav \ -lvx_util \ -lvx_math \ -lvx_color \ @@ -75,6 +76,7 @@ test_read_prob_LDADD = -lvx_stat_out \ -lvx_config \ -lvx_gsl_prob \ -lvx_cal \ + -lvx_nav \ -lvx_util \ -lvx_math \ -lvx_color \ diff --git a/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc b/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc index 402876f47c..eea9a30e2d 100644 --- a/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc +++ b/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc @@ -53,7 +53,7 @@ int main(int argc, char *argv[]) { while(f >> p_line) { // Add the current line to the array of probs - probs.add(p_line); + probs.add(p_line, bad_data_double, false); // Increment the line count count++; diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index a46559ca02..01c598bd72 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -1097,6 +1097,7 @@ static const char conf_key_ops_hit_window[] = "ops_hit_window"; static const char conf_key_discard_init_post_genesis_flag[] = "discard_init_post_genesis_flag"; static const char conf_key_dev_method_flag[] = "dev_method_flag"; static const char conf_key_ops_method_flag[] = "ops_method_flag"; +static const char conf_key_prob_genesis_thresh[] = "prob_genesis_thresh"; static const char conf_key_fcst_fy_oy[] = "fcst_fy_oy"; static const char conf_key_fcst_fy_on[] = "fcst_fy_on"; static const char conf_key_fcst_tracks[] = "fcst_tracks"; diff --git a/met/src/basic/vx_util/stat_column_defs.h b/met/src/basic/vx_util/stat_column_defs.h index b8ddc583bc..9b21762513 100644 --- a/met/src/basic/vx_util/stat_column_defs.h +++ b/met/src/basic/vx_util/stat_column_defs.h @@ -320,6 +320,7 @@ static const char * ssidx_columns [] = { static const char * genmpr_columns [] = { "TOTAL", "INDEX", "STORM_ID", + "PROB_LEAD", "PROB_VAL", "AGEN_INIT", "AGEN_FHR", "AGEN_LAT", "AGEN_LON", "AGEN_DLAND", "BGEN_LAT", "BGEN_LON", "BGEN_DLAND", diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 2975b03432..3880ab204a 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2424,6 +2424,27 @@ void PCTInfo::allocate_n_alpha(int i) { //////////////////////////////////////////////////////////////////////// +void PCTInfo::set_fthresh(const ThreshArray &ta) { + + // Expand the probability thresholds, as needed + fthresh = string_to_prob_thresh(ta.get_str().c_str()); + + // Validate the threshold settings + check_prob_thresh(fthresh, true); + + // Store the values in an array + NumArray prob_vals; + for(int i=0; i " << "skipping ATCF line type (" << atcflinetype_to_string(Type) << ")\n"; diff --git a/met/src/libcode/vx_tc_util/prob_gen_info.cc b/met/src/libcode/vx_tc_util/prob_gen_info.cc new file mode 100644 index 0000000000..c0db7ce9fb --- /dev/null +++ b/met/src/libcode/vx_tc_util/prob_gen_info.cc @@ -0,0 +1,241 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +//////////////////////////////////////////////////////////////////////// + +using namespace std; + +#include +#include +#include +#include +#include +#include + +#include "nav.h" + +#include "prob_gen_info.h" +#include "atcf_offsets.h" + +//////////////////////////////////////////////////////////////////////// +// +// Code for class ProbGenInfo +// +//////////////////////////////////////////////////////////////////////// + +ProbGenInfo::ProbGenInfo() { + + init_from_scratch(); +} + +//////////////////////////////////////////////////////////////////////// + +ProbGenInfo::~ProbGenInfo() { + + clear(); +} + +//////////////////////////////////////////////////////////////////////// + +ProbGenInfo::ProbGenInfo(const ProbGenInfo & t) { + + init_from_scratch(); + + assign(t); +} + +//////////////////////////////////////////////////////////////////////// + +ProbGenInfo & ProbGenInfo::operator=(const ProbGenInfo & t) { + + if(this == &t) return(*this); + + assign(t); + + return(*this); +} + +//////////////////////////////////////////////////////////////////////// + +void ProbGenInfo::init_from_scratch() { + + clear(); + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void ProbGenInfo::clear() { + + ProbInfoBase::clear(); + + Initials.clear(); + GenOrDis.clear(); + GenesisTime = (unixtime) 0; + GenesisLead = 0; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void ProbGenInfo::dump(ostream &out, int indent_depth) const { + Indent prefix(indent_depth); + + ProbInfoBase::dump(out, indent_depth); + + out << prefix << "Initials = \"" << Initials.contents() << "\"\n"; + out << prefix << "GenOrDis = \"" << GenOrDis.contents() << "\"\n"; + out << prefix << "GenesisTime = " << unix_to_yyyymmdd_hhmmss(GenesisTime) << "\n"; + out << prefix << "GenesisLead = " << sec_to_hhmmss(GenesisLead) << "\n"; + + out << flush; + + return; + +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString ProbGenInfo::serialize() const { + ConcatString s; + + s << ProbInfoBase::serialize() + << ", ProbGenInfo: " + << "Initials = \"" << Initials << "\"" + << ", GenOrDis = \"" << GenOrDis << "\"" + << ", GenesisTime = " << unix_to_yyyymmdd_hhmmss(GenesisTime) + << ", GenesisLead = " << sec_to_hhmmss(GenesisLead) << "\n"; + + return(s); +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString ProbGenInfo::serialize_r(int n, int indent_depth) const { + ConcatString s; + + s << ProbInfoBase::serialize_r(n, indent_depth); + + return(s); +} + +//////////////////////////////////////////////////////////////////////// + +void ProbGenInfo::assign(const ProbGenInfo &p) { + + clear(); + + ProbInfoBase::assign(p); + + Initials = p.Initials; + GenOrDis = p.GenOrDis; + GenesisTime = p.GenesisTime; + GenesisLead = p.GenesisLead; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +int ProbGenInfo::genesis_fhr() const { + return(is_bad_data(GenesisLead) ? + bad_data_int : + nint((double) GenesisLead/sec_per_hour)); +} + +//////////////////////////////////////////////////////////////////////// + +void ProbGenInfo::initialize(const ATCFProbLine &l, double dland) { + + clear(); + + ProbInfoBase::initialize(l, dland); + + Initials = l.get_item(ProbGenInitialsOffset); + GenOrDis = l.get_item(ProbGenOrDisOffset); + + // Store an empty string as unixtime 0 + GenesisTime = (l.get_item(ProbGenTimeOffset).empty() ? + (unixtime) 0 : + parse_time(l.get_item(ProbGenTimeOffset).c_str())); + GenesisLead = (GenesisTime == 0 ? bad_data_int : + GenesisTime - InitTime); + + return; +} + +//////////////////////////////////////////////////////////////////////// + +bool ProbGenInfo::is_match(const ATCFProbLine &l) const { + + if(!ProbInfoBase::is_match(l)) return(false); + + unixtime gen_ut = (l.get_item(ProbGenTimeOffset).empty() ? + (unixtime) 0 : + parse_time(l.get_item(ProbGenTimeOffset).c_str())); + + return(GenesisTime == gen_ut); +} + +//////////////////////////////////////////////////////////////////////// + +bool ProbGenInfo::add(const ATCFProbLine &l, double dland, bool check_dup) { + + // Check for duplicates + if(check_dup) { + if(has(l)) { + mlog << Warning + << "\nProbGenInfo::add(const ATCFProbLine &l, bool check_dup) -> " + << "skipping duplicate ATCF line:\n" + << l.get_line() << "\n\n"; + return(false); + } + } + + // Initialize the header information, if necessary + if(Type == NoATCFLineType) initialize(l, dland); + + // Check for matching header information + if(!is_match(l)) return(false); + + // Add probability information + NProb++; + Prob.add(l.prob()); + ProbItem.add(l.prob_item()); + + // Store the ATCFProbLine that was just added + if(check_dup) ProbLines.add(l.get_line()); + + return(true); +} + +//////////////////////////////////////////////////////////////////////// + +bool ProbGenInfo::is_match(const TrackPoint &p, const double rad, + const int beg, const int end) const { + + // Check for matching in time and space + return(p.valid() >= (GenesisTime + beg) && + p.valid() <= (GenesisTime + end) && + gc_dist(Lat, Lon, p.lat(), p.lon()) <= rad); +} + +//////////////////////////////////////////////////////////////////////// + +bool ProbGenInfo::is_match(const GenesisInfo &gi, const double rad, + const int beg, const int end) const { + + // Input genesis point + const TrackPoint *p = gi.genesis(); + + return(p ? is_match(*p, rad, beg, end) : false); +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_tc_util/prob_gen_info.h b/met/src/libcode/vx_tc_util/prob_gen_info.h new file mode 100644 index 0000000000..af97bb03fa --- /dev/null +++ b/met/src/libcode/vx_tc_util/prob_gen_info.h @@ -0,0 +1,98 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 __VX_PROB_GEN_INFO_H__ +#define __VX_PROB_GEN_INFO_H__ + +//////////////////////////////////////////////////////////////////////// + +#include + +#include "prob_info_base.h" +#include "genesis_info.h" + +#include "vx_util.h" + +//////////////////////////////////////////////////////////////////////// +// +// ProbGenInfo class stores probability of rapid intensification. +// +//////////////////////////////////////////////////////////////////////// + +class ProbGenInfo : public ProbInfoBase { + + private: + + void init_from_scratch(); + void assign(const ProbGenInfo &); + + // Probability of Genesis specific values + ConcatString Initials; + ConcatString GenOrDis; + unixtime GenesisTime; + int GenesisLead; + + public: + + ProbGenInfo(); + ~ProbGenInfo(); + ProbGenInfo(const ProbGenInfo &); + ProbGenInfo & operator=(const ProbGenInfo &); + + void clear(); + + void dump(ostream &, int = 0) const; + ConcatString serialize() const; + ConcatString serialize_r(int, int = 0) const; + + // + // set stuff + // + + void set_best_gen(const GenesisInfo *); + + // + // get stuff + // + + const ConcatString & initials() const; + const ConcatString & gen_or_dis() const; + unixtime genesis_time() const; + int genesis_lead() const; + int genesis_fhr() const; + const GenesisInfo * best_gen() const; + + // + // do stuff + // + + void initialize(const ATCFProbLine &, double); + bool is_match (const ATCFProbLine &) const; + bool add (const ATCFProbLine &, double, bool check_dup = false); + + bool is_match (const TrackPoint &, + const double, const int, const int) const; + bool is_match (const GenesisInfo &, + const double, const int, const int) const; + +}; + +//////////////////////////////////////////////////////////////////////// + +inline const ConcatString & ProbGenInfo::initials() const { return(Initials); } +inline const ConcatString & ProbGenInfo::gen_or_dis() const { return(GenOrDis); } +inline unixtime ProbGenInfo::genesis_time() const { return(GenesisTime); } +inline int ProbGenInfo::genesis_lead() const { return(GenesisLead); } + +//////////////////////////////////////////////////////////////////////// + +#endif /* __VX_PROB_GEN_INFO_H__ */ + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_tc_util/prob_info_array.cc b/met/src/libcode/vx_tc_util/prob_info_array.cc index 5a8e91844b..64809049ec 100644 --- a/met/src/libcode/vx_tc_util/prob_info_array.cc +++ b/met/src/libcode/vx_tc_util/prob_info_array.cc @@ -72,8 +72,9 @@ void ProbInfoArray::init_from_scratch() { void ProbInfoArray::clear() { - // Erase the entire vector + // Erase the entire vectors ProbRIRW.erase(ProbRIRW.begin(), ProbRIRW.end()); + ProbGen.erase(ProbGen.begin(), ProbGen.end()); return; } @@ -82,15 +83,23 @@ void ProbInfoArray::clear() { void ProbInfoArray::dump(ostream &out, int indent_depth) const { Indent prefix(indent_depth); + int i; out << prefix << "ProbInfoArray:\n" - << prefix << "NProbRIRW = " << n_prob_rirw() << "\n"; + << prefix << "NProbRIRW = " << n_prob_rirw() << "\n"; - for(unsigned int i=0; i 0 ) { + s << prefix << serialize() << ", ProbRIRW:\n"; + } + for(i=0; i 0 ) { + s << prefix << serialize() << ", ProbGen:\n"; + } + + for(i=0; i= n_probs())) { - mlog << Error - << "\nProbInfoBase * ProbInfoArray::operator[] -> " + mlog << Error << "\nProbInfoBase * ProbInfoArray::operator[] -> " << "range check error for index value " << n << "\n\n"; exit(1); } - // Return a base pointer to the n-th probability - // Need to revise for each new probability vector + // Get a base pointer to the n-th probability + const ProbInfoBase *ptr; + + if(ProbRIRW.size() > 0 && n < ProbRIRW.size()) { + ptr = &ProbRIRW[n]; + } + else { + n -= ProbRIRW.size(); + ptr = &ProbGen[n]; + } - return(&ProbRIRW[n]); + return(ptr); } //////////////////////////////////////////////////////////////////////// -const ProbRIRWInfo & ProbInfoArray::prob_rirw(int n) const { +ProbRIRWInfo & ProbInfoArray::prob_rirw(int n) { // Check range if((n < 0) || (n >= (int) ProbRIRW.size())) { - mlog << Error - << "\nProbRIRWInfo & ProbInfoArray::prob_rirw(int) -> " + mlog << Error << "\nProbRIRWInfo & ProbInfoArray::prob_rirw(int) -> " << "range check error for index value " << n << "\n\n"; exit(1); } @@ -171,14 +195,49 @@ const ProbRIRWInfo & ProbInfoArray::prob_rirw(int n) const { //////////////////////////////////////////////////////////////////////// -bool ProbInfoArray::add(const ATCFProbLine &l, bool check_dup) { +ProbGenInfo & ProbInfoArray::prob_gen(int n) { + + // Check range + if((n < 0) || (n >= (int) ProbGen.size())) { + mlog << Error << "\nProbGenInfo & ProbInfoArray::prob_gen(int) -> " + << "range check error for index value " << n << "\n\n"; + exit(1); + } + + return(ProbGen[n]); +} + +//////////////////////////////////////////////////////////////////////// + +int ProbInfoArray::n_technique() const { + StringArray sa; + + // Count the number of unique technique names + for(int i=0; i 100) { - mlog << Debug(4) - << "\nbool ProbInfoArray::add() -> " + mlog << Debug(4) + << "bool ProbInfoArray::add() -> " << "skipping probability value (" << l.prob() - << ") outside of range (0, 100).\n\n"; + << ") outside of range (0, 100).\n"; return(false); } @@ -187,27 +246,61 @@ bool ProbInfoArray::add(const ATCFProbLine &l, bool check_dup) { case(ATCFLineType_ProbRI): - // Check for no entries or a mismatch with the latest entry - if( ProbRIRW.size() == 0 || - (ProbRIRW.size() > 0 && - !ProbRIRW[ProbRIRW.size()-1].add(l, check_dup))) { - - // Store new entry + // Add line to an existing entry + if(ProbRIRW.size() > 0 && + ProbRIRW[ProbRIRW.size()-1].add(l, dland, check_dup)) { + status = true; + } + // Add a new entry + else { ProbRIRWInfo ri; - ri.add(l, check_dup); + ri.add(l, dland, check_dup); ProbRIRW.push_back(ri); + status = true; + } + break; + + case(ATCFLineType_ProbGN): + + // Add line to an existing entry + if(ProbGen.size() > 0 && + ProbGen[ProbGen.size()-1].add(l, dland, check_dup)) { + status = true; + } + // Add a new entry + else { + ProbGenInfo gi; + gi.add(l, dland, check_dup); + + // Check for the expected genesis type and predicted location + if(gi.gen_or_dis() != "genFcst") { + mlog << Debug(4) + << "bool ProbInfoArray::add() -> " + << "skipping ATCF " << atcflinetype_to_string(ATCFLineType_ProbGN) + << " line with non-genesis probability type (" + << gi.gen_or_dis() << " != genFcst).\n"; + } + else if(is_bad_data(gi.lat()) || is_bad_data(gi.lon())) { + mlog << Debug(4) + << "bool ProbInfoArray::add() -> " + << "skipping ATCF " << atcflinetype_to_string(ATCFLineType_ProbGN) + << " line with no predicted genesis location.\n"; + } + else { + ProbGen.push_back(gi); + status = true; + } } break; default: - mlog << Warning - << "\nbool ProbInfoArray::add() -> " + mlog << Warning << "\nbool ProbInfoArray::add() -> " << "unexpected ATCF line type (" << atcflinetype_to_string(l.type()) << ")\n\n"; - return(false); + status = false; } - return(true); + return(status); } //////////////////////////////////////////////////////////////////////// @@ -218,3 +311,10 @@ void ProbInfoArray::add(const ProbRIRWInfo &rirw) { } //////////////////////////////////////////////////////////////////////// + +void ProbInfoArray::add(const ProbGenInfo &gi) { + ProbGen.push_back(gi); + return; +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_tc_util/prob_info_array.h b/met/src/libcode/vx_tc_util/prob_info_array.h index 1228b91880..881cf3dcfb 100644 --- a/met/src/libcode/vx_tc_util/prob_info_array.h +++ b/met/src/libcode/vx_tc_util/prob_info_array.h @@ -19,6 +19,7 @@ #include "atcf_prob_line.h" #include "prob_info_base.h" #include "prob_rirw_info.h" +#include "prob_gen_info.h" #include "vx_util.h" @@ -36,6 +37,7 @@ class ProbInfoArray { void assign(const ProbInfoArray &); vector ProbRIRW; + vector ProbGen; public: @@ -58,21 +60,27 @@ class ProbInfoArray { const ProbInfoBase * operator[](int) const; int n_prob_rirw() const; - const ProbRIRWInfo & prob_rirw(int) const; + ProbRIRWInfo & prob_rirw(int); + + int n_prob_gen() const; + ProbGenInfo & prob_gen(int); + + int n_technique() const; // // do stuff // - bool add(const ATCFProbLine &, bool check_dup = false); + bool add(const ATCFProbLine &, double dland, bool check_dup = false); void add(const ProbRIRWInfo &); - + void add(const ProbGenInfo &); }; //////////////////////////////////////////////////////////////////////// -inline int ProbInfoArray::n_probs() const { return(ProbRIRW.size()); } -inline int ProbInfoArray::n_prob_rirw() const { return(ProbRIRW.size()); } +inline int ProbInfoArray::n_probs() const { return(ProbRIRW.size() + ProbGen.size()); } +inline int ProbInfoArray::n_prob_rirw() const { return(ProbRIRW.size()); } +inline int ProbInfoArray::n_prob_gen() const { return(ProbGen.size()); } //////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_tc_util/prob_info_base.cc b/met/src/libcode/vx_tc_util/prob_info_base.cc index f8d3bb791e..fb4147226c 100644 --- a/met/src/libcode/vx_tc_util/prob_info_base.cc +++ b/met/src/libcode/vx_tc_util/prob_info_base.cc @@ -79,6 +79,7 @@ void ProbInfoBase::clear() { ValidTime = (unixtime) 0; Lat = bad_data_double; Lon = bad_data_double; + DLand = bad_data_double; NProb = 0; Prob.clear(); ProbItem.clear(); @@ -101,6 +102,7 @@ void ProbInfoBase::dump(ostream &out, int indent_depth) const { out << prefix << "ValidTime = \"" << (ValidTime > 0 ? unix_to_yyyymmdd_hhmmss(ValidTime).text() : na_str) << "\"\n"; out << prefix << "Lat = " << Lat << "\n"; out << prefix << "Lon = " << Lon << "\n"; + out << prefix << "DLand = " << DLand << "\n"; out << prefix << "NProb = " << NProb << "\n"; out << prefix << "Prob:" << "\n"; Prob.dump(out, indent_depth+1); @@ -130,6 +132,7 @@ ConcatString ProbInfoBase::serialize() const { << ", ValidTime = \"" << (ValidTime > 0 ? unix_to_yyyymmdd_hhmmss(ValidTime).text() : na_str) << "\"" << ", Lat = " << Lat << ", Lon = " << Lon + << ", DLand = " << DLand << ", NProb = " << NProb; return(s); @@ -155,6 +158,14 @@ ConcatString ProbInfoBase::serialize_r(int n, int indent_depth) const { //////////////////////////////////////////////////////////////////////// +void ProbInfoBase::set_dland(double d) { + DLand = d; + + return; +} + +//////////////////////////////////////////////////////////////////////// + void ProbInfoBase::assign(const ProbInfoBase &t) { clear(); @@ -168,6 +179,7 @@ void ProbInfoBase::assign(const ProbInfoBase &t) { ValidTime = t.ValidTime; Lat = t.Lat; Lon = t.Lon; + DLand = t.DLand; NProb = t.NProb; Prob = t.Prob; ProbItem = t.ProbItem; @@ -178,7 +190,7 @@ void ProbInfoBase::assign(const ProbInfoBase &t) { //////////////////////////////////////////////////////////////////////// -void ProbInfoBase::initialize(const ATCFProbLine &l) { +void ProbInfoBase::initialize(const ATCFProbLine &l, double dland) { clear(); @@ -192,6 +204,7 @@ void ProbInfoBase::initialize(const ATCFProbLine &l) { ValidTime = l.valid(); Lat = l.lat(); Lon = l.lon(); + DLand = dland; return; } @@ -206,7 +219,6 @@ bool ProbInfoBase::is_match(const ATCFProbLine &l) const { Cyclone == l.cyclone_number() && Technique == l.technique() && InitTime == l.warning_time() && - ValidTime == l.valid() && Lat == l.lat() && Lon == l.lon()); } @@ -239,7 +251,7 @@ bool ProbInfoBase::is_match(const TrackInfo &t) const { //////////////////////////////////////////////////////////////////////// -bool ProbInfoBase::add(const ATCFProbLine &l, bool check_dup) { +bool ProbInfoBase::add(const ATCFProbLine &l, double dland, bool check_dup) { // Check for duplicates if(check_dup) { @@ -253,7 +265,7 @@ bool ProbInfoBase::add(const ATCFProbLine &l, bool check_dup) { } // Initialize the header information, if necessary - if(Type == NoATCFLineType) initialize(l); + if(Type == NoATCFLineType) initialize(l, dland); // Check for matching header information if(!is_match(l)) return(false); @@ -297,6 +309,7 @@ void ProbInfoBase::set(const TCStatLine &l) { ValidTime = l.valid(); Lat = atof(l.get_item("ALAT")); Lon = atof(l.get_item("ALON")); + DLand = atof(l.get_item("ADLAND")); NProb = atoi(l.get_item("N_THRESH")); for(int i=1; i<=NProb; i++) { cs << cs_erase << "PROB_" << i; diff --git a/met/src/libcode/vx_tc_util/prob_info_base.h b/met/src/libcode/vx_tc_util/prob_info_base.h index 4f416db319..fff06def24 100644 --- a/met/src/libcode/vx_tc_util/prob_info_base.h +++ b/met/src/libcode/vx_tc_util/prob_info_base.h @@ -50,6 +50,7 @@ class ProbInfoBase { // Location information double Lat; double Lon; + double DLand; // Probability information int NProb; @@ -93,6 +94,7 @@ class ProbInfoBase { int valid_hour() const; double lat() const; double lon() const; + double dland() const; int n_prob() const; double prob(int i) const; double prob_item(int i) const; @@ -101,11 +103,11 @@ class ProbInfoBase { // do stuff // - virtual void initialize(const ATCFProbLine &); + virtual void initialize(const ATCFProbLine &, double); virtual bool is_match (const ATCFProbLine &) const; bool is_match (const TrackInfo &) const; bool has (const ATCFProbLine &) const; - virtual bool add (const ATCFProbLine &, bool check_dup = false); + virtual bool add (const ATCFProbLine &, double, bool check_dup = false); virtual void set (const TCStatLine &); }; @@ -123,6 +125,7 @@ inline unixtime ProbInfoBase::valid() const { return(ValidT inline int ProbInfoBase::valid_hour() const { return(unix_to_sec_of_day(ValidTime)); } inline double ProbInfoBase::lat() const { return(Lat); } inline double ProbInfoBase::lon() const { return(Lon); } +inline double ProbInfoBase::dland() const { return(DLand); } inline int ProbInfoBase::n_prob() const { return(NProb); } inline double ProbInfoBase::prob(int i) const { return(Prob[i]); } inline double ProbInfoBase::prob_item(int i) const { return(ProbItem[i]); } diff --git a/met/src/libcode/vx_tc_util/prob_rirw_info.cc b/met/src/libcode/vx_tc_util/prob_rirw_info.cc index edbd318334..7799e591d3 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_info.cc +++ b/met/src/libcode/vx_tc_util/prob_rirw_info.cc @@ -149,11 +149,11 @@ int ProbRIRWInfo::rirw_window() const { //////////////////////////////////////////////////////////////////////// -void ProbRIRWInfo::initialize(const ATCFProbLine &l) { +void ProbRIRWInfo::initialize(const ATCFProbLine &l, double dland) { clear(); - ProbInfoBase::initialize(l); + ProbInfoBase::initialize(l, dland); Value = parse_int(l.get_item(ProbRIRWValueOffset).c_str()); Initials = l.get_item(ProbRIRWInitialsOffset); @@ -169,14 +169,15 @@ bool ProbRIRWInfo::is_match(const ATCFProbLine &l) const { if(!ProbInfoBase::is_match(l)) return(false); - return(Value == parse_int(l.get_item(ProbRIRWValueOffset).c_str()) && - RIRWBeg == parse_int(l.get_item(ProbRIRWBegOffset).c_str()) && - RIRWEnd == parse_int(l.get_item(ProbRIRWEndOffset).c_str())); + return(ValidTime == l.valid() && + Value == parse_int(l.get_item(ProbRIRWValueOffset).c_str()) && + RIRWBeg == parse_int(l.get_item(ProbRIRWBegOffset).c_str()) && + RIRWEnd == parse_int(l.get_item(ProbRIRWEndOffset).c_str())); } //////////////////////////////////////////////////////////////////////// -bool ProbRIRWInfo::add(const ATCFProbLine &l, bool check_dup) { +bool ProbRIRWInfo::add(const ATCFProbLine &l, double dland, bool check_dup) { // Check for duplicates if(check_dup) { @@ -190,7 +191,7 @@ bool ProbRIRWInfo::add(const ATCFProbLine &l, bool check_dup) { } // Initialize the header information, if necessary - if(Type == NoATCFLineType) initialize(l); + if(Type == NoATCFLineType) initialize(l, dland); // Check for matching header information if(!is_match(l)) return(false); diff --git a/met/src/libcode/vx_tc_util/prob_rirw_info.h b/met/src/libcode/vx_tc_util/prob_rirw_info.h index 9f47615dbf..2f04fc4baf 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_info.h +++ b/met/src/libcode/vx_tc_util/prob_rirw_info.h @@ -69,9 +69,9 @@ class ProbRIRWInfo : public ProbInfoBase { // do stuff // - void initialize(const ATCFProbLine &); + void initialize(const ATCFProbLine &, double); bool is_match (const ATCFProbLine &) const; - bool add (const ATCFProbLine &, bool check_dup = false); + bool add (const ATCFProbLine &, double, bool check_dup = false); void set (const TCStatLine &); }; diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen.cc b/met/src/tools/tc_utils/tc_gen/tc_gen.cc index bfb3960226..fb05b4c743 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen.cc +++ b/met/src/tools/tc_utils/tc_gen/tc_gen.cc @@ -20,6 +20,7 @@ // 003 12/31/20 Halley Gotway Add NetCDF output for MET #1430 // 004 01/14/21 Halley Gotway Add GENMPR output for MET #1597 // 005 04/02/21 Halley Gotway Refinements for MET #1714 +// 006 11/04/21 Halley Gotway Add -edeck for MET #1809 // //////////////////////////////////////////////////////////////////////// @@ -56,19 +57,24 @@ using namespace std; //////////////////////////////////////////////////////////////////////// static void process_command_line (int, char **); -static void process_genesis (); +static void score_track_genesis (const GenesisInfoArray &, + const TrackInfoArray &); +static void score_genesis_prob (const GenesisInfoArray &, + const TrackInfoArray &); static void get_atcf_files (const StringArray &, const StringArray &, const char *, StringArray &, StringArray &); -static void process_fcst_tracks (const StringArray &, +static void process_genesis (const StringArray &, const StringArray &, GenesisInfoArray &); -static void process_best_tracks (const StringArray &, +static void process_tracks (const StringArray &, const StringArray &, GenesisInfoArray &, TrackInfoArray &); - +static void process_edecks (const StringArray &, + const StringArray &, + ProbInfoArray &); static void get_genesis_pairs (const TCGenVxOpt &, const ConcatString &, const GenesisInfoArray &, @@ -79,25 +85,44 @@ static void get_genesis_pairs (const TCGenVxOpt &, static void do_genesis_ctc (const TCGenVxOpt &, PairDataGenesis &, GenCTCInfo &); +static void do_probgen_pct (const TCGenVxOpt &, + ProbInfoArray &, + const GenesisInfoArray &, + const TrackInfoArray &, + ProbGenPCTInfo &); static int find_genesis_match (const GenesisInfo &, const GenesisInfoArray &, const TrackInfoArray &, bool, double, int, int); +static int find_probgen_match (const ProbGenInfo &, + const GenesisInfoArray &, + const TrackInfoArray &, + bool, double, int, int); -static void setup_txt_files (int, int); +static void setup_txt_files (int, int, int); static void setup_table (AsciiTable &); static void setup_nc_file (); -static void write_stats (const PairDataGenesis &, +static void write_ctc_stats (const PairDataGenesis &, GenCTCInfo &); -static void write_genmpr_row (StatHdrColumns &, +static void write_ctc_genmpr_row (StatHdrColumns &, const PairDataGenesis &, STATOutputType, AsciiTable &, int &, AsciiTable &, int &); -static void write_genmpr_cols (const PairDataGenesis &, int, +static void write_ctc_genmpr_cols(const PairDataGenesis &, int, AsciiTable &, int, int); + +static void write_pct_stats (ProbGenPCTInfo &); +static void write_pct_genmpr_row (StatHdrColumns &, + ProbGenPCTInfo &, int, + STATOutputType, + AsciiTable &, int &, + AsciiTable &, int &); +static void write_pct_genmpr_cols(ProbGenPCTInfo &, int, int, + AsciiTable &, int, int); + static void write_nc (GenCTCInfo &); static void finish_txt_files (); @@ -105,6 +130,7 @@ static void usage (); static void set_source (const StringArray &, const char *, StringArray &, StringArray &); static void set_genesis (const StringArray &); +static void set_edeck (const StringArray &); static void set_track (const StringArray &); static void set_config (const StringArray &); static void set_out (const StringArray &); @@ -119,8 +145,43 @@ int main(int argc, char *argv[]) { // Process the command line arguments process_command_line(argc, argv); - // Identify and process genesis events and write output - process_genesis(); + // Process the verifying BEST and operational tracks + StringArray track_files, track_files_model_suffix; + GenesisInfoArray best_ga; + TrackInfoArray oper_ta; + + // Get the list of verifing track files + get_atcf_files(track_source, track_model_suffix, atcf_reg_exp, + track_files, track_files_model_suffix); + + mlog << Debug(2) + << "Processing " << track_files.n() + << " verifying track files.\n"; + process_tracks(track_files, track_files_model_suffix, + best_ga, oper_ta); + + // Score genesis events and write output + if(genesis_source.n() > 0) { + score_track_genesis(best_ga, oper_ta); + } + + // Score EDECK genesis probabilities and write output + if(edeck_source.n() > 0) { + score_genesis_prob(best_ga, oper_ta); + } + + // Finish output files + finish_txt_files(); + + // Close the NetCDF output file + if(nc_out) { + + // List the NetCDF file after it is finished + mlog << Debug(1) << "Output file: " << out_nc_file << "\n"; + + delete nc_out; + nc_out = (NcFile *) 0; + } return(0); } @@ -143,6 +204,7 @@ void process_command_line(int argc, char **argv) { // Add function calls for the arguments cline.add(set_genesis, "-genesis", -1); + cline.add(set_edeck, "-edeck", -1); cline.add(set_track, "-track", -1); cline.add(set_config, "-config", 1); cline.add(set_out, "-out", 1); @@ -154,21 +216,29 @@ void process_command_line(int argc, char **argv) { for(i=genesis_model_suffix.n(); i " - << "the \"-genesis\", \"-track\", and \"-config\" command " + if(genesis_source.n() == 0 && edeck_source.n() == 0) { + mlog << Error << "\nprocess_command_line(int argc, char **argv) -> " + << "at least one of the \"-genesis\" or \"-edeck\" command " << "line options are required\n\n"; usage(); } + // Check for the minimum number of arguments + if(track_source.n() == 0 || config_file.length() == 0) { + mlog << Error << "\nprocess_command_line(int argc, char **argv) -> " + << "the \"-track\" and \"-config\" command line options " + << "are required\n\n"; + usage(); + } + // List the input genesis track files for(i=0; i model_ga_map; map::iterator it; PairDataGenesis pairs; - GenCTCInfo ctc_info; + GenCTCInfo genesis_ctc; // Get the list of genesis track files get_atcf_files(genesis_source, genesis_model_suffix, atcf_gen_reg_exp, @@ -221,25 +298,15 @@ void process_genesis() { mlog << Debug(2) << "Processing " << genesis_files.n() << " forecast genesis track files.\n"; - process_fcst_tracks(genesis_files, genesis_files_model_suffix, - fcst_ga); - - // Get the list of verifing track files - get_atcf_files(track_source, track_model_suffix, atcf_reg_exp, - track_files, track_files_model_suffix); - - mlog << Debug(2) - << "Processing " << track_files.n() - << " verifying track files.\n"; - process_best_tracks(track_files, track_files_model_suffix, - best_ga, oper_ta); + process_genesis(genesis_files, genesis_files_model_suffix, + fcst_ga); // Setup output files based on the number of techniques present // and possible pairs. int n_time = (conf_info.FcstSecEnd - conf_info.FcstSecBeg) / (conf_info.InitFreqHr*sec_per_hour) + 1; int n_pair = best_ga.n() * n_time + fcst_ga.n(); - setup_txt_files(fcst_ga.n_technique(), n_pair); + setup_txt_files(fcst_ga.n_technique(), 1, n_pair); // If requested, setup the NetCDF output file if(!conf_info.NcInfo.all_false()) setup_nc_file(); @@ -272,16 +339,16 @@ void process_genesis() { // Store the current genesis event model_ga_map[model].add(fcst_ga[j]); - } // end j + } // end for j - // Process the genesis events for each model. + // Process the genesis events for each model for(j=0,it=model_ga_map.begin(); it!=model_ga_map.end(); it++,j++) { // Initialize - ctc_info.clear(); - ctc_info.Model = it->first; - ctc_info.set_vx_opt(&conf_info.VxOpt[i], - &conf_info.NcOutGrid); + genesis_ctc.clear(); + genesis_ctc.Model = it->first; + genesis_ctc.set_vx_opt(&conf_info.VxOpt[i], + &conf_info.NcOutGrid); mlog << Debug(2) << "[Filter " << i+1 << " (" << conf_info.VxOpt[i].Desc @@ -297,33 +364,107 @@ void process_genesis() { best_ga, oper_ta, pairs); // Do the categorical verification - do_genesis_ctc(conf_info.VxOpt[i], pairs, ctc_info); + do_genesis_ctc(conf_info.VxOpt[i], pairs, genesis_ctc); // Write the statistics output - write_stats(pairs, ctc_info); + write_ctc_stats(pairs, genesis_ctc); // Write NetCDF output fields if(!conf_info.VxOpt[i].NcInfo.all_false()) { - write_nc(ctc_info); + write_nc(genesis_ctc); } } // end for j } // end for i n_vx - // Finish output files - finish_txt_files(); + return; +} - // Close the NetCDF output file - if(nc_out) { +//////////////////////////////////////////////////////////////////////// - // List the NetCDF file after it is finished - mlog << Debug(1) << "Output file: " << out_nc_file << "\n"; +void score_genesis_prob(const GenesisInfoArray &best_ga, + const TrackInfoArray &oper_ta) { + int i, j, n, max_n_prob, n_pair; + StringArray edeck_files, edeck_files_model_suffix; + ProbInfoArray fcst_pa, empty_pa; + ConcatString model; + map model_pa_map; + map::iterator it; + ProbGenPCTInfo probgen_pct; - delete nc_out; - nc_out = (NcFile *) 0; + // Get the list of EDECK files + get_atcf_files(edeck_source, edeck_model_suffix, atcf_reg_exp, + edeck_files, edeck_files_model_suffix); + + mlog << Debug(2) + << "Processing " << edeck_files.n() + << " forecast EDECK files.\n"; + process_edecks(edeck_files, edeck_files_model_suffix, + fcst_pa); + + // Count up the total number of probabilities + for(i=0,max_n_prob=0,n_pair=0; i max_n_prob) max_n_prob = n; + n_pair += n; } + // Setup output files based on the number of techniques + setup_txt_files(fcst_pa.n_technique(), max_n_prob, n_pair); + + // Process each verification filter + for(i=0; i 0 && + !conf_info.VxOpt[i].Model.has(model)) continue; + + // Add a new map entry, if necessary + if(model_pa_map.count(model) == 0) { + empty_pa.clear(); + model_pa_map[model] = empty_pa; + } + + // Store the current genesis event + model_pa_map[model].add(fcst_pa.prob_gen(j)); + + } // end for j + + // Process the genesis probabilities for each model + for(j=0,it=model_pa_map.begin(); it!=model_pa_map.end(); it++,j++) { + + mlog << Debug(2) + << "[Filter " << i+1 << " (" << conf_info.VxOpt[i].Desc + << ") " << ": Model " << j+1 << "] " << "For " << it->first + << " model, comparing " << it->second.n_prob_gen() + << " probability of genesis forecasts to " << best_ga.n() << " " + << conf_info.BestEventInfo.Technique << " and " + << oper_ta.n() << " " << conf_info.OperTechnique + << " tracks.\n"; + + // Do the probabilistic verification + do_probgen_pct(conf_info.VxOpt[i], it->second, + best_ga, oper_ta, probgen_pct); + + // Write the statistics output + write_pct_stats(probgen_pct); + + } // end for j + } // end for i return; } @@ -598,9 +739,63 @@ void do_genesis_ctc(const TCGenVxOpt &vx_opt, //////////////////////////////////////////////////////////////////////// -int find_genesis_match(const GenesisInfo &fcst_gi, +void do_probgen_pct(const TCGenVxOpt &vx_opt, + ProbInfoArray &model_pa, + const GenesisInfoArray &best_ga, + const TrackInfoArray &oper_ta, + ProbGenPCTInfo &pgi) { + int i, i_bga, j, time_diff; + bool is_event; + const GenesisInfo *bgi; + + // Initialize + pgi.clear(); + pgi.set_vx_opt(&vx_opt); + + // Score each of the probability forecasts + for(i=0; igenesis_time() - + model_pa.prob_gen(i).init(); + is_event = time_diff >= 0 && + time_diff <= (model_pa.prob_gen(i).prob_item(j) * sec_per_hour); + } + else { + is_event = false; + } + + // Store pair info + pgi.add(model_pa.prob_gen(i), j, bgi, is_event); + + } // end for j + } // end for i + + return; +} + + +//////////////////////////////////////////////////////////////////////// + +int find_genesis_match(const GenesisInfo &fcst_gi, const GenesisInfoArray &bga, - const TrackInfoArray &ota, + const TrackInfoArray &ota, bool point2track, double rad, int beg, int end) { int i, j, i_best, i_oper; @@ -684,6 +879,94 @@ int find_genesis_match(const GenesisInfo &fcst_gi, return(i_best); } +//////////////////////////////////////////////////////////////////////// + +int find_probgen_match(const ProbGenInfo &prob_gi, + const GenesisInfoArray &bga, + const TrackInfoArray &ota, + bool point2track, double rad, + int beg, int end) { + int i, j, i_best, i_oper; + + ConcatString case_cs; + case_cs << prob_gi.technique() << " " + << unix_to_yyyymmdd_hhmmss(prob_gi.init()) + << " initialization, " + << unix_to_yyyymmdd_hhmmss(prob_gi.genesis_time()) + << " forecast genesis at (" << prob_gi.lat() << ", " + << prob_gi.lon() << ")"; + + // Search for a BEST track genesis match + for(i=0, i_best=bad_data_int; + i " + mlog << Error << "\nprocess_genesis() -> " << "unable to open file \"" << files[i] << "\"\n\n"; exit(1); } @@ -842,10 +1125,10 @@ void process_fcst_tracks(const StringArray &files, //////////////////////////////////////////////////////////////////////// -void process_best_tracks(const StringArray &files, - const StringArray &model_suffix, - GenesisInfoArray &best_ga, - TrackInfoArray &oper_ta) { +void process_tracks(const StringArray &files, + const StringArray &model_suffix, + GenesisInfoArray &best_ga, + TrackInfoArray &oper_ta) { int i, i_bga, n_lines; ConcatString suffix, gen_basin, case_cs, storm_id; StringArray best_tech, oper_tech; @@ -871,8 +1154,7 @@ void process_best_tracks(const StringArray &files, // Open the current file if(!f.open(files[i].c_str())) { - mlog << Error - << "\nprocess_best_tracks() -> " + mlog << Error << "\nprocess_tracks() -> " << "unable to open file \"" << files[i] << "\"\n\n"; exit(1); } @@ -976,7 +1258,7 @@ void process_best_tracks(const StringArray &files, i--; } else { - mlog << Warning << "\nprocess_best_tracks() -> " + mlog << Warning << "\nprocess_tracks() -> " << case_cs << "neither " << best_ga[i_bga].storm_id() << " nor " << best_gi.storm_id() << " matches the basin!\n\n"; @@ -997,6 +1279,82 @@ void process_best_tracks(const StringArray &files, mlog << Debug(2) << "Found " << best_ga.n() << " BEST genesis events.\n"; + // Dump out very verbose output + if(mlog.verbosity_level() > 6) { + mlog << Debug(6) << best_ga.serialize_r() << "\n"; + } + // Dump out track info + else { + for(i=0; i " + << "unable to open file \"" << files[i] << "\"\n\n"; + exit(1); + } + + // Set metadata pointer + suffix = model_suffix[i]; + line.set_tech_suffix(&suffix); + + // Process the input track lines + while(f >> line) { + + // Skip off-hour track points + if((line.valid_hour() % valid_freq_sec) != 0) continue; + + // Only process genesis probability lines + if(line.type() == ATCFLineType_ProbGN) { + dland = conf_info.compute_dland(line.lat(), -1.0*line.lon()); + if(probs.add(line, dland, false)) n_lines++; + } + } + + // Close the current file + f.close(); + + } // end for i + + // Dump out the total number of lines + mlog << Debug(3) + << "Read a total of " << n_lines << " " + << atcflinetype_to_string(ATCFLineType_ProbGN) + << " lines from " << files.n() << " input files.\n"; + + // Dump out very verbose output + if(mlog.verbosity_level() >= 6) { + mlog << Debug(6) << probs.serialize_r() << "\n"; + } + return; } @@ -1006,70 +1364,153 @@ void process_best_tracks(const StringArray &files, // //////////////////////////////////////////////////////////////////////// -void setup_txt_files(int n_model, int n_pair) { - int i, n_rows, n_cols; +void setup_txt_files(int n_model, int max_n_prob, int n_pair) { + int i, n_rows, n_cols, stat_rows, stat_cols, n_prob; - // Check to see if the text files have already been set up - if(stat_at.nrows() > 0 || stat_at.ncols() > 0) return; + // Check to see if the stat file stream has already been setup + bool init_from_scratch = (stat_out == (ofstream *) 0); - // Initialize file stream - stat_out = (ofstream *) 0; + // Get the maximum number of probability thresholds + n_prob = conf_info.get_max_n_prob_thresh(); - // Build the file name - stat_file << out_base << stat_file_ext; + // Compute the number of rows/cols needs for each file type + for(i=0, stat_rows=0, stat_cols=0; iOutputMap.at(stat_fho), + gci.VxOpt->output_map(stat_fho), stat_at, i_stat_row, txt_at[i_fho], i_txt_row[i_fho]); } @@ -1172,7 +1613,7 @@ void write_stats(const PairDataGenesis &gpd, shc.set_fcst_var(genesis_ops_name); shc.set_obs_var (genesis_ops_name); write_fho_row(shc, gci.CTSOps, - gci.VxOpt->OutputMap.at(stat_fho), + gci.VxOpt->output_map(stat_fho), stat_at, i_stat_row, txt_at[i_fho], i_txt_row[i_fho]); } @@ -1185,7 +1626,7 @@ void write_stats(const PairDataGenesis &gpd, shc.set_fcst_var(genesis_dev_name); shc.set_obs_var (genesis_dev_name); write_ctc_row(shc, gci.CTSDev, - gci.VxOpt->OutputMap.at(stat_ctc), + gci.VxOpt->output_map(stat_ctc), stat_at, i_stat_row, txt_at[i_ctc], i_txt_row[i_ctc]); } @@ -1194,7 +1635,7 @@ void write_stats(const PairDataGenesis &gpd, shc.set_fcst_var(genesis_ops_name); shc.set_obs_var (genesis_ops_name); write_ctc_row(shc, gci.CTSOps, - gci.VxOpt->OutputMap.at(stat_ctc), + gci.VxOpt->output_map(stat_ctc), stat_at, i_stat_row, txt_at[i_ctc], i_txt_row[i_ctc]); } @@ -1210,7 +1651,7 @@ void write_stats(const PairDataGenesis &gpd, shc.set_fcst_var(genesis_dev_name); shc.set_obs_var (genesis_dev_name); write_cts_row(shc, gci.CTSDev, - gci.VxOpt->OutputMap.at(stat_cts), + gci.VxOpt->output_map(stat_cts), stat_at, i_stat_row, txt_at[i_cts], i_txt_row[i_cts]); } @@ -1222,7 +1663,7 @@ void write_stats(const PairDataGenesis &gpd, shc.set_fcst_var(genesis_ops_name); shc.set_obs_var (genesis_ops_name); write_cts_row(shc, gci.CTSOps, - gci.VxOpt->OutputMap.at(stat_cts), + gci.VxOpt->output_map(stat_cts), stat_at, i_stat_row, txt_at[i_cts], i_txt_row[i_cts]); } @@ -1232,21 +1673,22 @@ void write_stats(const PairDataGenesis &gpd, if(gci.VxOpt->output_map(stat_genmpr) != STATOutputType_None) { shc.set_fcst_var(genesis_name); shc.set_obs_var (genesis_name); - write_genmpr_row(shc, gpd, - gci.VxOpt->OutputMap.at(stat_genmpr), - stat_at, i_stat_row, - txt_at[i_genmpr], i_txt_row[i_genmpr]); + write_ctc_genmpr_row(shc, gpd, + gci.VxOpt->output_map(stat_genmpr), + stat_at, i_stat_row, + txt_at[i_genmpr], i_txt_row[i_genmpr]); } return; } + //////////////////////////////////////////////////////////////////////// -void write_genmpr_row(StatHdrColumns &shc, - const PairDataGenesis &gpd, - STATOutputType out_type, - AsciiTable &stat_at, int &stat_row, - AsciiTable &txt_at, int &txt_row) { +void write_ctc_genmpr_row(StatHdrColumns &shc, + const PairDataGenesis &gpd, + STATOutputType out_type, + AsciiTable &stat_at, int &stat_row, + AsciiTable &txt_at, int &txt_row) { int i; unixtime ut; @@ -1254,6 +1696,8 @@ void write_genmpr_row(StatHdrColumns &shc, shc.set_line_type(stat_genmpr_str); // Not Applicable + shc.set_fcst_thresh(na_str); + shc.set_obs_thresh(na_str); shc.set_alpha(bad_data_double); // Write a line for each matched pair @@ -1262,7 +1706,7 @@ void write_genmpr_row(StatHdrColumns &shc, // Pointers for current case const GenesisInfo* fgi = gpd.fcst_gen(i); const GenesisInfo* bgi = gpd.best_gen(i); - + // Store timing info shc.set_fcst_lead_sec(gpd.lead_time(i)); ut = (fgi ? fgi->genesis_time() : bgi->genesis_time()); @@ -1277,7 +1721,7 @@ void write_genmpr_row(StatHdrColumns &shc, write_header_cols(shc, stat_at, stat_row); // Write the data columns - write_genmpr_cols(gpd, i, stat_at, stat_row, n_header_columns); + write_ctc_genmpr_cols(gpd, i, stat_at, stat_row, n_header_columns); // If requested, copy row to the text file if(out_type == STATOutputType_Both) { @@ -1296,16 +1740,17 @@ void write_genmpr_row(StatHdrColumns &shc, //////////////////////////////////////////////////////////////////////// - void write_genmpr_cols(const PairDataGenesis &gpd, int i, - AsciiTable &at, int r, int c) { + void write_ctc_genmpr_cols(const PairDataGenesis &gpd, int i, + AsciiTable &at, int r, int c) { // Pointers for current case const GenesisInfo* fgi = gpd.fcst_gen(i); const GenesisInfo* bgi = gpd.best_gen(i); - + // // Genesis Matched Pairs (GENMPR): // TOTAL, INDEX, STORM_ID, + // PROB_LEAD, PROB_VAL, // AGEN_INIT, AGEN_FHR, // AGEN_LAT, AGEN_LON, AGEN_DLAND, // BGEN_LAT, BGEN_LON, BGEN_DLAND, @@ -1322,43 +1767,49 @@ void write_genmpr_row(StatHdrColumns &shc, at.set_entry(r, c+2, // Best track Storm ID gpd.best_storm_id(i)); - at.set_entry(r, c+3, // Fcst genesis initialization time + at.set_entry(r, c+3, // Probability lead time + na_str); + + at.set_entry(r, c+4, // Probability value + na_str); + + at.set_entry(r, c+5, // Fcst genesis initialization time fgi ? unix_to_yyyymmdd_hhmmss(fgi->init()) : na_str); - at.set_entry(r, c+4, // Fcst genesis hour + at.set_entry(r, c+6, // Fcst genesis hour fgi ? fgi->genesis_fhr() : bad_data_int); - at.set_entry(r, c+5, // Fcst track latitude + at.set_entry(r, c+7, // Fcst track latitude fgi ? fgi->lat() : bad_data_double); - at.set_entry(r, c+6, // Fcst track longitude + at.set_entry(r, c+8, // Fcst track longitude fgi ? fgi->lon() : bad_data_double); - at.set_entry(r, c+7, // Fcst track distance to land + at.set_entry(r, c+9, // Fcst track distance to land fgi ? fgi->dland() : bad_data_double); - at.set_entry(r, c+8, // Best track latitude + at.set_entry(r, c+10, // Best track latitude bgi ? bgi->lat() : bad_data_double); - at.set_entry(r, c+9, // Best track longitude + at.set_entry(r, c+11, // Best track longitude bgi ? bgi->lon() : bad_data_double); - at.set_entry(r, c+10, // Best track distance to land + at.set_entry(r, c+12, // Best track distance to land bgi ? bgi->dland() : bad_data_double); - at.set_entry(r, c+11, // Genesis distance + at.set_entry(r, c+13, // Genesis distance gpd.gen_diff(i).DevDist); - at.set_entry(r, c+12, // Genesis time difference + at.set_entry(r, c+14, // Genesis time difference sec_to_hhmmss(gpd.gen_diff(i).DevDSec)); - at.set_entry(r, c+13, // Genesis - Init time + at.set_entry(r, c+15, // Genesis - Init time sec_to_hhmmss(gpd.gen_diff(i).OpsDSec)); - at.set_entry(r, c+14, // Development category + at.set_entry(r, c+16, // Development category genesispaircategory_to_string(gpd.gen_diff(i).DevCategory)); - at.set_entry(r, c+15, // Operational category + at.set_entry(r, c+17, // Operational category genesispaircategory_to_string(gpd.gen_diff(i).OpsCategory)); return; @@ -1366,6 +1817,222 @@ void write_genmpr_row(StatHdrColumns &shc, //////////////////////////////////////////////////////////////////////// +void write_pct_stats(ProbGenPCTInfo &pgi) { + int i, lead_hr, lead_sec; + + // Setup header columns + shc.set_model(pgi.Model.c_str()); + shc.set_desc(pgi.VxOpt->Desc.c_str()); + shc.set_obtype(conf_info.BestEventInfo.Technique.c_str()); + shc.set_mask(pgi.VxOpt->VxMaskName.empty() ? + na_str : pgi.VxOpt->VxMaskName.c_str()); + shc.set_fcst_var(prob_genesis_name); + shc.set_obs_var (prob_genesis_name); + + // Write results for each lead time + for(i=0; ioutput_map(stat_pct) != STATOutputType_None) { + write_pct_row(shc, pgi.PCTMap[lead_hr], + pgi.VxOpt->output_map(stat_pct), + 1, 1, stat_at, i_stat_row, + txt_at[i_pct], i_txt_row[i_pct]); + } + + // Write PSTD output + if(pgi.VxOpt->output_map(stat_pstd) != STATOutputType_None) { + pgi.PCTMap[lead_hr].compute_stats(); + pgi.PCTMap[lead_hr].compute_ci(); + write_pstd_row(shc, pgi.PCTMap[lead_hr], + pgi.VxOpt->output_map(stat_pstd), + 1, 1, stat_at, i_stat_row, + txt_at[i_pstd], i_txt_row[i_pstd]); + } + + // Write PJC output + if(pgi.VxOpt->output_map(stat_pjc) != STATOutputType_None) { + write_pct_row(shc, pgi.PCTMap[lead_hr], + pgi.VxOpt->output_map(stat_pjc), + 1, 1, stat_at, i_stat_row, + txt_at[i_pjc], i_txt_row[i_pjc]); + } + + // Write PRC output + if(pgi.VxOpt->output_map(stat_pjc) != STATOutputType_None) { + write_pct_row(shc, pgi.PCTMap[lead_hr], + pgi.VxOpt->output_map(stat_pjc), + 1, 1, stat_at, i_stat_row, + txt_at[i_prc], i_txt_row[i_prc]); + } + + // Write out GENMPR + if(pgi.VxOpt->output_map(stat_genmpr) != STATOutputType_None) { + shc.set_fcst_var(prob_genesis_name); + shc.set_obs_var (prob_genesis_name); + write_pct_genmpr_row(shc, pgi, lead_hr, + pgi.VxOpt->output_map(stat_genmpr), + stat_at, i_stat_row, + txt_at[i_genmpr], i_txt_row[i_genmpr]); + } + + } // end for i + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void write_pct_genmpr_row(StatHdrColumns &shc, + ProbGenPCTInfo &pgi, + int lead_hr, + STATOutputType out_type, + AsciiTable &stat_at, int &stat_row, + AsciiTable &txt_at, int &txt_row) { + int i; + unixtime ut; + + // GENMPR line type + shc.set_line_type(stat_genmpr_str); + + // Not Applicable + shc.set_fcst_thresh(na_str); + shc.set_obs_thresh(na_str); + shc.set_alpha(bad_data_double); + + // Write a line for each matched pair + for(i=0; igenesis_lead()); + ut = fgi->genesis_time(); + shc.set_fcst_valid_beg(ut); + shc.set_fcst_valid_end(ut); + shc.set_obs_lead_sec(bad_data_int); + ut = (bgi ? bgi->genesis_time() : ut); + shc.set_obs_valid_beg(ut); + shc.set_obs_valid_end(ut); + + // Write the header columns + write_header_cols(shc, stat_at, stat_row); + + // Write the data columns + write_pct_genmpr_cols(pgi, lead_hr, i, + stat_at, stat_row, n_header_columns); + + // If requested, copy row to the text file + if(out_type == STATOutputType_Both) { + copy_ascii_table_row(stat_at, stat_row, txt_at, txt_row); + + // Increment the text row counter + txt_row++; + } + + // Increment the STAT row counter + stat_row++; + + } + + return; +} + +//////////////////////////////////////////////////////////////////////// + + void write_pct_genmpr_cols(ProbGenPCTInfo &pgi, + int lead_hr, int index, + AsciiTable &at, int r, int c) { + + // Pointers for current case + const ProbGenInfo *fgi = pgi.FcstGenMap[lead_hr][index]; + const GenesisInfo *bgi = pgi.BestGenMap[lead_hr][index]; + + int i_prob = pgi.FcstIdxMap[lead_hr][index]; + + // + // Genesis Matched Pairs (GENMPR): + // TOTAL, INDEX, STORM_ID, + // PROB_LEAD, PROB_VAL, + // AGEN_INIT, AGEN_FHR, + // AGEN_LAT, AGEN_LON, AGEN_DLAND, + // BGEN_LAT, BGEN_LON, BGEN_DLAND, + // GEN_DIST, GEN_TDIFF, INIT_TDIFF, + // DEV_CAT, OPS_CAT + // + + at.set_entry(r, c+0, // Total number of pairs + (int) pgi.FcstGenMap[lead_hr].size()); + + at.set_entry(r, c+1, // Index of current pair + index+1); + + at.set_entry(r, c+2, // Best track Storm ID + (bgi ? bgi->storm_id() : na_str)); + + at.set_entry(r, c+3, // Probability lead time + fgi->prob_item(i_prob)); + + at.set_entry(r, c+4, // Probability value + fgi->prob(i_prob)); + + at.set_entry(r, c+5, // Fcst genesis initialization time + unix_to_yyyymmdd_hhmmss(fgi->init())); + + at.set_entry(r, c+6, // Fcst genesis hour + fgi->genesis_fhr()); + + at.set_entry(r, c+7, // Fcst genesis latitude + fgi->lat()); + + at.set_entry(r, c+8, // Fcst genesis longitude + fgi->lon()); + + at.set_entry(r, c+9, // Fcst genesis distance to land + fgi->dland()); + + at.set_entry(r, c+10, // Best track latitude + bgi ? bgi->lat() : bad_data_double); + + at.set_entry(r, c+11, // Best track longitude + bgi ? bgi->lon() : bad_data_double); + + at.set_entry(r, c+12, // Best track distance to land + bgi ? bgi->dland() : bad_data_double); + + at.set_entry(r, c+13, // Genesis distance + na_str); + + at.set_entry(r, c+14, // Genesis time difference + na_str); + + at.set_entry(r, c+15, // Genesis - Init time + na_str); + + at.set_entry(r, c+16, // Development category + na_str); + + at.set_entry(r, c+17, // Operational category + (pgi.BestEvtMap[lead_hr][index] ? "FYOY" : "FYON" )); + + return; + } + +//////////////////////////////////////////////////////////////////////// + void write_nc(GenCTCInfo &gci) { int i; ConcatString var_name, long_name; @@ -1547,19 +2214,24 @@ void usage() { << ") ***\n\n" << "Usage: " << program_name << "\n" - << "\t-genesis path\n" - << "\t-track path\n" + << "\t-genesis source and/or -edeck source\n" + << "\t-track source\n" << "\t-config file\n" << "\t[-out base]\n" << "\t[-log file]\n" << "\t[-v level]\n\n" - << "\twhere\t\"-genesis path\" is one or more ATCF genesis " + << "\twhere\t\"-genesis source\" is one or more ATCF genesis " << "files, an ASCII file list containing them, or a top-level " << "directory with files matching the regular expression \"" - << atcf_gen_reg_exp << "\" (required).\n" + << atcf_gen_reg_exp << "\" (required if no -edeck).\n" - << "\t\t\"-track path\" is one or more ATCF track " + << "\t\t\"-edeck source\" is one or more ensemble model output " + << "files, an ASCII file list containing them, or a top-level " + << "directory with files matching the regular expression \"" + << atcf_reg_exp << "\" (required if no -genesis).\n" + + << "\t\t\"-track source\" is one or more ATCF track " << "files, an ASCII file list containing them, or a top-level " << "directory with files matching the regular expression \"" << atcf_reg_exp << "\" for the verifying BEST and operational " @@ -1648,6 +2320,12 @@ void set_genesis(const StringArray & a) { //////////////////////////////////////////////////////////////////////// +void set_edeck(const StringArray & a) { + set_source(a, "edeck", edeck_source, edeck_model_suffix); +} + +//////////////////////////////////////////////////////////////////////// + void set_track(const StringArray & a) { set_source(a, "track", track_source, track_model_suffix); } diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen.h b/met/src/tools/tc_utils/tc_gen/tc_gen.h index a531652c32..19461c5941 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen.h +++ b/met/src/tools/tc_utils/tc_gen/tc_gen.h @@ -60,22 +60,27 @@ static const char * default_config_filename = // Header columns static const char **txt_columns[n_txt] = { - fho_columns, ctc_columns, cts_columns, genmpr_columns + fho_columns, ctc_columns, cts_columns, + pct_columns, pstd_columns, pjc_columns, + prc_columns, genmpr_columns }; // Length of header columns static const int n_txt_columns[n_txt] = { - n_fho_columns, n_ctc_columns, n_cts_columns, n_genmpr_columns + n_fho_columns, n_ctc_columns, n_cts_columns, + n_pct_columns, n_pstd_columns, n_pjc_columns, + n_prc_columns, n_genmpr_columns }; // Text file abbreviations static const char *txt_file_abbr[n_txt] = { - "fho", "ctc", "cts", "genmpr" + "fho", "ctc", "cts", "pct", "pstd", "pjc", "prc", "genmpr" }; -const ConcatString genesis_name ("GENESIS"); -const ConcatString genesis_dev_name("GENESIS_DEV"); -const ConcatString genesis_ops_name("GENESIS_OPS"); +const ConcatString genesis_name ("GENESIS"); +const ConcatString genesis_dev_name ("GENESIS_DEV"); +const ConcatString genesis_ops_name ("GENESIS_OPS"); +const ConcatString prob_genesis_name("PROB_GENESIS"); // Maximum Best track cyclone number to be processed // Cyclone numbers > 50 are for testing or invests @@ -89,7 +94,8 @@ static const int max_best_cyclone_number = 50; // Input files static StringArray genesis_source, genesis_model_suffix; -static StringArray track_source, track_model_suffix; +static StringArray edeck_source, edeck_model_suffix; +static StringArray track_source, track_model_suffix; static ConcatString config_file; static TCGenConfInfo conf_info; diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc index 02f75d16d7..0592c667b4 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc @@ -164,6 +164,7 @@ void TCGenVxOpt::clear() { OpsHitBeg = OpsHitEnd = bad_data_int; DiscardFlag = false; DevFlag = OpsFlag = false; + ProbGenThresh.clear(); CIAlpha = bad_data_double; OutputMap.clear(); NcInfo.clear(); @@ -288,7 +289,12 @@ void TCGenVxOpt::process_config(Dictionary &dict) { << " must be set to true!\n\n"; exit(1); } - + + // Conf: prob_genesis_thresh + ProbGenThresh = dict.lookup_thresh_array(conf_key_prob_genesis_thresh); + ProbGenThresh = string_to_prob_thresh(ProbGenThresh.get_str().c_str()); + check_prob_thresh(ProbGenThresh); + // Conf: ci_alpha CIAlpha = dict.lookup_double(conf_key_ci_alpha); @@ -508,6 +514,62 @@ bool TCGenVxOpt::is_keeper(const GenesisInfo &gi) const { //////////////////////////////////////////////////////////////////////// +bool TCGenVxOpt::is_keeper(const ProbGenInfo &gi) const { + bool keep = true; + + // ATCF ID processed elsewhere + + // Check storm id + if(StormId.n() > 0 && + !has_storm_id(StormId, gi.basin(), gi.cyclone(), gi.init())) + keep = false; + + // Check storm name: no included in genesis probabilities + + // Initialization time + if((InitBeg > 0 && InitBeg > gi.init()) || + (InitEnd > 0 && InitEnd < gi.init()) || + (InitInc.n() > 0 && !InitInc.has(gi.init())) || + (InitExc.n() > 0 && InitExc.has(gi.init()))) + keep = false; + + // Initialization hours + if(InitHour.n() > 0 && !InitHour.has(gi.init_hour())) + keep = false; + + // Lead and valid times: + // ProbGenInfo objects can contain multiple lead/valid times. + // Do not filter by them here. + + // Poly masking + if(VxPolyMask.n_points() > 0 && + !VxPolyMask.latlon_is_inside(gi.lat(), gi.lon())) + keep = false; + + // Area masking + if(!VxAreaMask.is_empty()) { + double x, y; + VxGridMask.latlon_to_xy(gi.lat(), -1.0*gi.lon(), x, y); + if(x < 0 || x >= VxGridMask.nx() || + y < 0 || y >= VxGridMask.ny()) { + keep = false; + } + else { + keep = VxAreaMask(nint(x), nint(y)); + } + } + + // Distance to land + if((DLandThresh.get_type() != no_thresh_type) && + (is_bad_data(gi.dland()) || !DLandThresh.check(gi.dland()))) + keep = false; + + // Return the keep status + return(keep); +} + +//////////////////////////////////////////////////////////////////////// + STATOutputType TCGenVxOpt::output_map(STATLineType t) const { return(OutputMap.at(t)); } @@ -823,6 +885,18 @@ STATOutputType TCGenConfInfo::output_map(STATLineType t) const { return(OutputMap.at(t)); } +//////////////////////////////////////////////////////////////////////// + +int TCGenConfInfo::get_max_n_prob_thresh() const { + int i, n; + + for(i=0,n=0; iProbGenThresh); + DefaultPCT.allocate_n_alpha(1); + DefaultPCT.alpha[0] = VxOpt->CIAlpha; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void ProbGenPCTInfo::add(const ProbGenInfo &fgi, int index, + const GenesisInfo *bgi, bool is_event) { + int i; + unixtime ut; + + // Store the model name + if(Model.empty()) Model = fgi.technique(); + + // Track the range of forecast initalization times + ut = fgi.init(); + if(InitBeg == 0 || InitBeg > ut) InitBeg = ut; + if(InitEnd == 0 || InitEnd < ut) InitEnd = ut; + + // Track the range of verifying BEST genesis events + if(bgi) { + ut = bgi->genesis_time(); + if(BestBeg == 0 || BestBeg > ut) BestBeg = ut; + if(BestEnd == 0 || BestEnd < ut) BestEnd = ut; + } + + // Current lead time and probability value + int lead_hr = nint(fgi.prob_item(index)); + double prob = fgi.prob(index) / 100.0; + + // Add new map entries, if needed + if(!LeadTimes.has(lead_hr)) { + + LeadTimes.add(lead_hr); + vector empty_fgi; + vector empty_idx; + vector empty_bgi; + vector empty_evt; + + PCTMap [lead_hr] = DefaultPCT; + FcstGenMap[lead_hr] = empty_fgi; + FcstIdxMap[lead_hr] = empty_idx; + BestGenMap[lead_hr] = empty_bgi; + BestEvtMap[lead_hr] = empty_evt; + } + + // Update map entries + FcstGenMap[lead_hr].push_back(&fgi); + FcstIdxMap[lead_hr].push_back(index); + BestGenMap[lead_hr].push_back(bgi); + BestEvtMap[lead_hr].push_back(is_event); + + // Increment counts + if(is_event) PCTMap[lead_hr].pct.inc_event (prob); + else PCTMap[lead_hr].pct.inc_nonevent(prob); + + return; +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h index a02a62e562..fe1b3c3f57 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h @@ -29,16 +29,24 @@ static const int i_fho = 0; static const int i_ctc = 1; static const int i_cts = 2; -static const int i_genmpr = 3; +static const int i_pct = 3; +static const int i_pstd = 4; +static const int i_pjc = 5; +static const int i_prc = 6; +static const int i_genmpr = 7; -static const int n_txt = 4; +static const int n_txt = 8; // Text file type static const STATLineType txt_file_type[n_txt] = { stat_fho, // 0 stat_ctc, // 1 stat_cts, // 2 - stat_genmpr // 3 + stat_pct, // 3 + stat_pstd, // 4 + stat_pjc, // 5 + stat_prc, // 6 + stat_genmpr // 7 }; // Names for output data plane types @@ -78,7 +86,6 @@ struct TCGenNcOutInfo { bool do_best_fy_oy; bool do_best_fn_oy; - ////////////////////////////////////////////////////////////////// TCGenNcOutInfo(); @@ -145,6 +152,7 @@ class TCGenVxOpt { bool DiscardFlag, DevFlag, OpsFlag; // Output file options + ThreshArray ProbGenThresh; double CIAlpha; map OutputMap; TCGenNcOutInfo NcInfo; @@ -161,6 +169,7 @@ class TCGenVxOpt { void parse_nc_info(Dictionary &); bool is_keeper(const GenesisInfo &) const; + bool is_keeper(const ProbGenInfo &) const; STATOutputType output_map(STATLineType) const; }; @@ -242,6 +251,9 @@ class TCGenConfInfo { int compression_level(); STATOutputType output_map(STATLineType) const; + + // Maximum across all verification tasks + int get_max_n_prob_thresh() const; }; //////////////////////////////////////////////////////////////////////// @@ -303,6 +315,49 @@ class GenCTCInfo { //////////////////////////////////////////////////////////////////////// +class ProbGenPCTInfo { + + private: + + void init_from_scratch(); + + PCTInfo DefaultPCT; + + public: + + ProbGenPCTInfo(); + ~ProbGenPCTInfo(); + + ////////////////////////////////////////////////////////////////// + + ConcatString Model; + unixtime InitBeg, InitEnd; + unixtime BestBeg, BestEnd; + const TCGenVxOpt* VxOpt; + IntArray LeadTimes; + + // Map of lead times to PCT tables + map PCTMap; + + // Map of lead times to vectors of pair info + map> FcstGenMap; + map> FcstIdxMap; + map> BestGenMap; + map> BestEvtMap; + + ////////////////////////////////////////////////////////////////// + + void clear(); + + void set_vx_opt(const TCGenVxOpt *); + + void add(const ProbGenInfo &, int, + const GenesisInfo *, bool); + +}; + +//////////////////////////////////////////////////////////////////////// + #endif /* __TC_GEN_CONF_INFO_H__ */ //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/tc_utils/tc_pairs/Makefile.am b/met/src/tools/tc_utils/tc_pairs/Makefile.am index d5d4436698..1dd9e1275f 100644 --- a/met/src/tools/tc_utils/tc_pairs/Makefile.am +++ b/met/src/tools/tc_utils/tc_pairs/Makefile.am @@ -38,6 +38,7 @@ tc_pairs_LDADD = -lvx_stat_out \ -lvx_gsl_prob \ -lvx_pb_util \ -lvx_cal \ + -lvx_nav \ -lvx_util \ -lvx_math \ -lvx_color \ diff --git a/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc b/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc index 7a70c0736a..5bf073959e 100644 --- a/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc +++ b/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc @@ -437,7 +437,7 @@ void process_edecks(const TrackInfoArray &bdeck_tracks) { // Filter the EDECK tracks using the config file information mlog << Debug(2) - << "Filtering " << edeck_probs.n_probs() + << "Filtering " << edeck_probs.n_prob_rirw() << " probabilities based on config file settings.\n"; filter_probs(edeck_probs); @@ -446,11 +446,11 @@ void process_edecks(const TrackInfoArray &bdeck_tracks) { // mlog << Debug(2) - << "Matching " << edeck_probs.n_probs() + << "Matching " << edeck_probs.n_prob_rirw() << " EDECK probabilities to " << bdeck_tracks.n() << " BDECK tracks.\n"; - for(i=0; idland()); + cur_ri.set_bdland(compute_dland(cur_ri.blat(), -1.0*cur_ri.blon())); // Store the current pair prob_rirw_pairs.add(cur_ri); @@ -640,6 +640,7 @@ void process_prob_files(const StringArray &files, const StringArray &model_suffix, ProbInfoArray &probs) { int i, cur_read, cur_add, tot_read, tot_add; + double dland; LineDataFile f; ConcatString suffix; ATCFProbLine line; @@ -683,10 +684,13 @@ void process_prob_files(const StringArray &files, // Check the keep status if(!is_keeper(&line)) continue; - // Attempt to add the current line to ProbInfoArray - if(probs.add(line, conf_info.CheckDup)) { - cur_add++; - tot_add++; + // Only process probability of RI lines + if(line.type() == ATCFLineType_ProbRI) { + dland = compute_dland(line.lat(), -1.0*line.lon()); + if(probs.add(line, dland, conf_info.CheckDup)) { + cur_add++; + tot_add++; + } } } @@ -708,7 +712,7 @@ void process_prob_files(const StringArray &files, // Dump out the track information mlog << Debug(3) - << "Identified " << probs.n_probs() << " probabilities.\n"; + << "Identified " << probs.n_prob_rirw() << " probabilities.\n"; // Dump out very verbose output if(mlog.verbosity_level() >= 5) { @@ -717,9 +721,9 @@ void process_prob_files(const StringArray &files, } // Dump out track info else { - for(i=0; iserialize() << "\n"; } } @@ -928,7 +932,7 @@ void filter_probs(ProbInfoArray &probs) { // Loop through the pairs and determine which should be retained // The is_keeper() function has already filtered by model, storm id, // basin, cyclone, initialization time, and initialization hour. - for(i=0; i 0 && @@ -977,11 +981,11 @@ void filter_probs(ProbInfoArray &probs) { // Print summary filtering info mlog << Debug(3) - << "Total probabilities read = " << p.n_probs() << "\n" - << "Total probabilities kept = " << probs.n_probs() << "\n" - << "Rejected for valid time = " << n_vld << "\n" - << "Rejected for init mask = " << n_mask_init << "\n" - << "Rejected for valid mask = " << n_mask_vld << "\n"; + << "Total probabilities read = " << p.n_prob_rirw() << "\n" + << "Total probabilities kept = " << probs.n_prob_rirw() << "\n" + << "Rejected for valid time = " << n_vld << "\n" + << "Rejected for init mask = " << n_mask_init << "\n" + << "Rejected for valid mask = " << n_mask_vld << "\n"; return; } diff --git a/test/config/TCGenConfig_prob b/test/config/TCGenConfig_prob new file mode 100644 index 0000000000..db075b4479 --- /dev/null +++ b/test/config/TCGenConfig_prob @@ -0,0 +1,288 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// TC-Gen configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// ATCF file format reference: +// http://www.nrlmry.navy.mil/atcf_web/docs/database/new/abrdeck.html +// + +//////////////////////////////////////////////////////////////////////////////// +// +// Genesis event definition criteria +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Model initialization frequency in hours, starting at 0 +// +init_freq = 6; + +// +// Valid hour frequency to be analyzed in hours, starting at 0 +// +valid_freq = 6; + +// +// Forecast hours to be searched for genesis events +// +fcst_hr_window = { + beg = 6; + end = 120; +} + +// +// Minimum track duration for genesis event in hours +// +min_duration = 12; + +// +// Forecast genesis event criteria. Defined as tracks reaching the specified +// intensity category, maximum wind speed threshold, and minimum sea-level +// pressure threshold. The forecast genesis time is the valid time of the first +// track point where all of these criteria are met. +// +fcst_genesis = { + vmax_thresh = NA; + mslp_thresh = NA; +} + +// +// BEST track genesis event criteria. Defined as tracks reaching the specified +// intensity category, maximum wind speed threshold, and minimum sea-level +// pressure threshold. The BEST track genesis time is the valid time of the +// first track point where all of these criteria are met. +// +best_genesis = { + technique = "BEST"; + category = [ "TD", "TS" ]; + vmax_thresh = NA; + mslp_thresh = NA; +} + +// +// Operational track technique name +// +oper_technique = "CARQ"; + +//////////////////////////////////////////////////////////////////////////////// +// +// Track filtering options +// May be specified separately in each filter array entry. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Array of dictionaries containing the track filtering options +// If empty, a single filter is defined using the top-level settings. +// +filter = [ + { + desc = "ALL"; + } +]; + +// +// Description written to output DESC column +// +desc = "ALL"; + +// +// Forecast ATCF ID's +// If empty, all ATCF ID's found will be processed. +// Statistics will be generated separately for each ATCF ID. +// +model = []; + +// +// BEST and operational track storm identifiers +// +storm_id = []; + +// +// BEST and operational track storm names +// +storm_name = []; + +// +// Forecast and operational initialization times to include or exclude +// +init_beg = ""; +init_end = ""; +init_inc = []; +init_exc = []; + +// +// Forecast, BEST, and operational valid time window +// +valid_beg = ""; +valid_end = ""; + +// +// Forecast and operational initialization hours +// +init_hour = []; + +// +// Forecast and operational lead times in hours +// +lead = []; + +// +// Spatial masking region (path to gridded data file or polyline file) +// +vx_mask = ""; + +// +// Spatial masking of hurricane basin names from the basin_file +// +basin_mask = []; + +// +// Distance to land threshold +// +dland_thresh = NA; + +//////////////////////////////////////////////////////////////////////////////// +// +// Matching and scoring options +// May be specified separately in each filter array entry. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Genesis matching logic. Compare the forecast genesis point to all points in +// the Best track (TRUE) or the single Best track genesis point (FALSE). +// +genesis_match_point_to_track = FALSE; + +// +// Radius in km to search for a matching genesis event +// +genesis_match_radius = 500; + +// +// Time window in hours, relative to the model genesis time, to search for a +// matching Best track point +// +genesis_match_window = { + beg = -6; + end = 6; +} + +// +// Radius in km for a development scoring method hit +// +dev_hit_radius = 500; + +// +// Time window in hours, relative to the model genesis time, for a development +// scoring method hit +// +dev_hit_window = { + beg = -24; + end = 24; +} + +// +// Time window in hours for the Best track genesis minus model initialization +// time difference for an operational scoring method hit +// +ops_hit_window = { + beg = 0; + end = 48; +} + +// +// Discard genesis forecasts for initializations at or after the matching +// BEST track genesis time +// +discard_init_post_genesis_flag = TRUE; + +// +// Scoring methods to be applied +// +dev_method_flag = TRUE; +ops_method_flag = TRUE; + +//////////////////////////////////////////////////////////////////////////////// +// +// Output options +// May be specified separately in each filter array entry. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Probability of genesis thresholds +// +prob_genesis_thresh = ==0.25; + +// +// Confidence interval alpha value +// +ci_alpha = 0.05; + +// +// Statistical output types +// +output_flag = { + fho = NONE; + ctc = NONE; + cts = NONE; + pct = BOTH; + pstd = BOTH; + pjc = BOTH; + prc = BOTH; + genmpr = BOTH; +} + +// +// NetCDF genesis pair counts +// +nc_pairs_flag = FALSE; + +// +// Specify which track points should be counted by thresholding the track point +// valid time minus genesis time difference. +// +valid_minus_genesis_diff_thresh = NA; + +// +// Count unique BEST track genesis event locations (TRUE) versus counting the +// location for all pairs (FALSE). +// +best_unique_flag = TRUE; + +//////////////////////////////////////////////////////////////////////////////// +// +// Global settings +// May only be specified once. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Specify the NetCDF output of the gen_dland tool containing a gridded +// representation of the minimum distance to land. +// +dland_file = "MET_BASE/tc_data/dland_global_tenth_degree.nc"; + +// +// Specify the NetCDF file containing a gridded representation of the +// global basins. +// +basin_file = "MET_BASE/tc_data/basin_global_tenth_degree.nc"; + +// +// NetCDF genesis pairs grid +// +nc_pairs_grid = "G003"; + +// +// Indicate a version number for the contents of this configuration file. +// The value should generally not be modified. +// +version = "V10.1.0"; diff --git a/test/hdr/met_10_1.hdr b/test/hdr/met_10_1.hdr index 641ac25813..84f5b5a950 100644 --- a/test/hdr/met_10_1.hdr +++ b/test/hdr/met_10_1.hdr @@ -28,7 +28,7 @@ SSVAR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_L VL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFBAR VFBAR UOBAR VOBAR UVFOBAR UVFFBAR UVOOBAR F_SPEED_BAR O_SPEED_BAR VAL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFABAR VFABAR UOABAR VOABAR UVFOABAR UVFFABAR UVOOABAR VCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR FBAR_BCL FBAR_BCU OBAR OBAR_BCL OBAR_BCU FS_RMS FS_RMS_BCL FS_RMS_BCU OS_RMS OS_RMS_BCL OS_RMS_BCU MSVE MSVE_BCL MSVE_BCU RMSVE RMSVE_BCL RMSVE_BCU FSTDEV FSTDEV_BCL FSTDEV_BCU OSTDEV OSTDEV_BCL OSTDEV_BCU FDIR FDIR_BCL FDIR_BCU ODIR ODIR_BCL ODIR_BCU FBAR_SPEED FBAR_SPEED_BCL FBAR_SPEED_BCU OBAR_SPEED OBAR_SPEED_BCL OBAR_SPEED_BCU VDIFF_SPEED VDIFF_SPEED_BCL VDIFF_SPEED_BCU VDIFF_DIR VDIFF_DIR_BCL VDIFF_DIR_BCU SPEED_ERR SPEED_ERR_BCL SPEED_ERR_BCU SPEED_ABSERR SPEED_ABSERR_BCL SPEED_ABSERR_BCU DIR_ERR DIR_ERR_BCL DIR_ERR_BCU DIR_ABSERR DIR_ABSERR_BCL DIR_ABSERR_BCU -GENMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX STORM_ID AGEN_INIT AGEN_FHR AGEN_LAT AGEN_LON AGEN_DLAND BGEN_LAT BGEN_LON BGEN_DLAND GEN_DIST GEN_TDIFF INIT_TDIFF DEV_CAT OPS_CAT +GENMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX STORM_ID PROB_LEAD PROB_VAL AGEN_INIT AGEN_FHR AGEN_LAT AGEN_LON AGEN_DLAND BGEN_LAT BGEN_LON BGEN_DLAND GEN_DIST GEN_TDIFF INIT_TDIFF DEV_CAT OPS_CAT SSIDX : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE FCST_MODEL REF_MODEL N_INIT N_TERM N_VLD SS_INDEX MODE_SOA : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE N_VALID GRID_RES OBJECT_ID OBJECT_CAT CENTROID_X CENTROID_Y CENTROID_LAT CENTROID_LON AXIS_ANG LENGTH WIDTH AREA AREA_THRESH CURVATURE CURVATURE_X CURVATURE_Y COMPLEXITY INTENSITY_10 INTENSITY_25 INTENSITY_50 INTENSITY_75 INTENSITY_90 INTENSITY_50 INTENSITY_SUM MODE_POA : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE N_VALID GRID_RES OBJECT_ID OBJECT_CAT CENTROID_DIST BOUNDARY_DIST CONVEX_HULL_DIST ANGLE_DIFF ASPECT_DIFF AREA_RATIO INTERSECTION_AREA UNION_AREA SYMMETRIC_DIFF INTERSECTION_OVER_AREA CURVATURE_RATIO COMPLEXITY_RATIO PERCENTILE_INTENSITY_RATIO INTEREST diff --git a/test/xml/unit_tc_gen.xml b/test/xml/unit_tc_gen.xml index d1aa664166..86245745d8 100644 --- a/test/xml/unit_tc_gen.xml +++ b/test/xml/unit_tc_gen.xml @@ -6,7 +6,7 @@ - + ]> @@ -17,8 +17,8 @@ &MET_BIN;/tc_gen \ - -genesis &DATA_DIR;/suite1/2016*/genesis*2016* \ - -track &DATA_DIR;/atcf/2016 \ + -genesis &DATA_DIR;/genesis/suite1/2016*/genesis*2016* \ + -track &DATA_DIR;/genesis/atcf/2016 \ -config &CONFIG_DIR;/TCGenConfig_2016 \ -out &OUTPUT_DIR;/tc_gen/tc_gen_2016 \ -log &OUTPUT_DIR;/tc_gen/tc_gen_2016.log \ @@ -31,4 +31,26 @@ + + + + &MET_BIN;/tc_gen + \ + -edeck &DATA_DIR;/edeck/eal152020*dat \ + -track &DATA_DIR;/bdeck/bal152020.dat \ + -config &CONFIG_DIR;/TCGenConfig_prob \ + -out &OUTPUT_DIR;/tc_gen/tc_gen_prob \ + -log &OUTPUT_DIR;/tc_gen/tc_gen_prob.log \ + -v 4 + + + &OUTPUT_DIR;/tc_gen/tc_gen_prob.stat + &OUTPUT_DIR;/tc_gen/tc_gen_prob_pct.txt + &OUTPUT_DIR;/tc_gen/tc_gen_prob_pstd.txt + &OUTPUT_DIR;/tc_gen/tc_gen_prob_pjc.txt + &OUTPUT_DIR;/tc_gen/tc_gen_prob_prc.txt + &OUTPUT_DIR;/tc_gen/tc_gen_prob_genmpr.txt + + + From 13996c21d45e92b12483a70f074bf3e2ec0eb441 Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 16 Nov 2021 14:57:47 -0700 Subject: [PATCH 010/172] Feature 1970 v10.1.0-beta4 (#1973) --- met/docs/Users_Guide/release-notes.rst | 25 +++++++++++++++++++++++-- met/docs/conf.py | 4 ++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index af9fb5168b..68524d323b 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -5,8 +5,29 @@ When applicable, release notes are followed by the GitHub issue number which describes the bugfix, enhancement, or new feature: `MET GitHub issues. `_ -MET Version 10.1.0-beta3 release notes (|release_date|) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +MET Version 10.1.0-beta4 release notes (20211116) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Enhancements: + + * **Add logic to Ensemble-Stat to handle an ensemble control member** (`#1905 `_). + * Enhance Ensemble-Stat and Gen-Ens-Prod to error out if the control member also appears in the list of ensemble members (`#1968 `_). + * **Enhance TC-Gen to verify genesis probabilities from ATCF e-deck files** (`#1809 `_). + * Modify the STAT-Analysis GO Index configuration file (`#1945 `_). + * **Support percentile thresholds for frequency bias not equal to 1 (e.g. ==FBIAS0.9)** (`#1761 `_). + * Reimplement the NumArray class based on an STL template (`#1899 `_). + +* Bugfixes: + + * Fix bug with the incrementing of numbers in temporary file names (`#1906 `_). + * Fix ascii2nc to check the return status when reading ASCII input files (`#1957 `_). + +* Documentation: + + * Enhance the documentation with meta-data that is expected by MET for netCDF (`#1949 `_). + +MET Version 10.1.0-beta3 release notes (20211006) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * New tools: diff --git a/met/docs/conf.py b/met/docs/conf.py index 7a625f0c9e..b06f98568c 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 = 'Halley Gotway, J., K. Newman, H. Soh, J. Opatz, T. Jensen, J. Prestopnik, L. Goodrich, D. Fillmore, B. Brown, R. Bullock, T. Fowler' -version = '10.1.0-beta3' +version = '10.1.0-beta4' verinfo = version release = f'{version}' release_year = '2021' -release_date = f'{release_year}-10-06' +release_date = f'{release_year}-11-16' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- From dae9db7a95acae2d8faa130733fcc39eedddb83e Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 17 Nov 2021 11:34:04 -0700 Subject: [PATCH 011/172] Fix tiny typo in plot_data_plane usage statement. --- met/src/tools/other/plot_data_plane/plot_data_plane.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/other/plot_data_plane/plot_data_plane.cc b/met/src/tools/other/plot_data_plane/plot_data_plane.cc index 80251a7ccf..101eb51c0e 100644 --- a/met/src/tools/other/plot_data_plane/plot_data_plane.cc +++ b/met/src/tools/other/plot_data_plane/plot_data_plane.cc @@ -289,7 +289,7 @@ void usage() { << "\t[-v level]\n\n" << "\twhere\t\"input_filename\" is the name of a " - << " gridded data file to be plotted (required).\n" + << "gridded data file to be plotted (required).\n" << "\t\t\"output_filename\" is the name of the output " << "PostScript file to be written (required).\n" From 9bd9946d5e5c2be1b64ffeb7daf9ca30e65f2faf Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 17 Nov 2021 16:02:31 -0700 Subject: [PATCH 012/172] Hotfix for the develop branch to get met-10.1.0-beta4 compiling on WCOSS. The intel compiler does not allow adjacent >> characters when defining maps. --- met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h index fe1b3c3f57..b3512c0d8c 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h @@ -340,10 +340,10 @@ class ProbGenPCTInfo { map PCTMap; // Map of lead times to vectors of pair info - map> FcstGenMap; - map> FcstIdxMap; - map> BestGenMap; - map> BestEvtMap; + map > FcstGenMap; + map > FcstIdxMap; + map > BestGenMap; + map > BestEvtMap; ////////////////////////////////////////////////////////////////// From e0b659dc5bab88c3263c6f95046ae37a67119443 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 17 Nov 2021 16:16:23 -0700 Subject: [PATCH 013/172] Updating the beta4 release date from 11/16 to 11/17 since the beta4 release needs to be recreated. --- met/docs/Users_Guide/release-notes.rst | 2 +- met/docs/conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index 68524d323b..eebd4f9e28 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -5,7 +5,7 @@ When applicable, release notes are followed by the GitHub issue number which describes the bugfix, enhancement, or new feature: `MET GitHub issues. `_ -MET Version 10.1.0-beta4 release notes (20211116) +MET Version 10.1.0-beta4 release notes (20211117) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Enhancements: diff --git a/met/docs/conf.py b/met/docs/conf.py index b06f98568c..c04f0ceeb3 100644 --- a/met/docs/conf.py +++ b/met/docs/conf.py @@ -24,7 +24,7 @@ verinfo = version release = f'{version}' release_year = '2021' -release_date = f'{release_year}-11-16' +release_date = f'{release_year}-11-17' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- From 817d9db840f7e8434ab6c9dde14cd4aab414fe6c Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 19 Nov 2021 15:26:31 -0700 Subject: [PATCH 014/172] Update the MET PR template to list expected changes up front. --- .github/pull_request_template.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 450355440e..c2984bffdf 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,3 +1,11 @@ +## Expected Differences ## + +- [ ] Do these changes introduce new tools, command line arguments, or configuration file options? **[Yes or No]**
+If **yes**, please describe:
+ +- [ ] Do these changes modify the structure of existing or add new output data types (e.g. statistic line types or NetCDF variables)? **[Yes or No]**
+If **yes**, please describe:
+ ## Pull Request Testing ## - [ ] Describe testing already performed for these changes:
From 4e28ae7f11b90e0cac989e53ee7357ab63d2c6c9 Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 22 Nov 2021 12:40:28 -0700 Subject: [PATCH 015/172] Bugfix 1976 develop cdist (#1979) --- .../tools/other/mode_time_domain/3d_att.cc | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/met/src/tools/other/mode_time_domain/3d_att.cc b/met/src/tools/other/mode_time_domain/3d_att.cc index 0fc640ff05..6c10fadfda 100644 --- a/met/src/tools/other/mode_time_domain/3d_att.cc +++ b/met/src/tools/other/mode_time_domain/3d_att.cc @@ -1261,7 +1261,8 @@ moments = mask.calc_3d_moments(); if ( moments.N == 0 ) { - mlog << Error << "\n\n calc_3d_single_atts() -> empty object!\n\n"; + mlog << Error << "\n\ncalc_3d_single_atts() -> " + << "empty object!\n\n"; exit ( 1 ); @@ -1322,16 +1323,22 @@ for (j=0,x_old=0,y_old=0; j 0 ) { - } else { - dist += calc_2d_dist(xbar_2d, ybar_2d, x_old, y_old, *grid); - } // else + } + + // + // update old (x, y) with current + // + + x_old = xbar_2d; + y_old = ybar_2d; } @@ -1347,7 +1354,8 @@ values = new float [Vol]; if ( !values ) { - mlog << Error << "\n\n calc_3d_single_atts() -> memory allocation error\n\n"; + mlog << Error << "\n\ncalc_3d_single_atts() -> " + << "memory allocation error\n\n"; exit ( 1 ); @@ -1390,8 +1398,6 @@ a.Ptile_User = percentile_f(values, n, (double) (a.Ptile_Value/100.0)); if ( values ) { delete [] values; values = 0; } -// a.dump(cout); - return ( a ); } From 39a5233d324a735410036a30aa7edc7360e2a2af Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 29 Nov 2021 13:47:45 -0700 Subject: [PATCH 016/172] #1936 Excludes precip3hr, precip6hr, precip12hr, and precip10min from required variables for MESONET --- met/src/tools/other/madis2nc/madis2nc.cc | 26 +++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/met/src/tools/other/madis2nc/madis2nc.cc b/met/src/tools/other/madis2nc/madis2nc.cc index b1192f566f..6f48a30ccc 100644 --- a/met/src/tools/other/madis2nc/madis2nc.cc +++ b/met/src/tools/other/madis2nc/madis2nc.cc @@ -84,7 +84,7 @@ static void clean_up(); static void setup_netcdf_out(int nhdr); static bool get_filtered_nc_data(NcVar var, float *data, const long dim, - const long cur, const char *var_name); + const long cur, const char *var_name, bool required=true); static bool get_filtered_nc_data_2d(NcVar var, int *data, const long *dim, const long *cur, const char *var_name, bool count_bad=false); static bool get_filtered_nc_data_2d(NcVar var, float *data, const long *dim, @@ -415,7 +415,7 @@ void setup_netcdf_out(int nhdr) { static bool get_filtered_nc_data(NcVar var, float *data, const long dim, const long cur, - const char *var_name) { + const char *var_name, bool required) { bool status = false; float in_fill_value; @@ -439,15 +439,13 @@ static bool get_filtered_nc_data(NcVar var, float *data, << "Fail to read data [" << var_name << "].\n\n"; } } - else { + else if (required) { mlog << Error << "\n" << method_name << "Can not read a NetCDF data because the variable [" << var_name << "] is missing.\n\n"; } - if (!status) { - for (int idx=0; idx Date: Wed, 1 Dec 2021 12:42:39 -0700 Subject: [PATCH 017/172] Per #1985, correcting typo found while creating V10.0.1 in the develop branch as well. --- met/docs/Users_Guide/point-stat.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index 926ad1f0c5..311332574f 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -745,7 +745,7 @@ The first set of header columns are common to all of the output files generated .. _table_PS_format_info_CNT: -.. list-table:: Format information for CNT(Continuous Statistics) output line type. +.. list-table:: Format information for CNT (Continuous Statistics) output line type. :widths: auto :header-rows: 2 @@ -804,7 +804,7 @@ The first set of header columns are common to all of the output files generated .. _table_PS_format_info_CNT_cont: -.. list-table:: Format information for CNT(Continuous Statistics) output line type continued from above table +.. list-table:: Format information for CNT (Continuous Statistics) output line type continued from above table :widths: auto :header-rows: 2 @@ -1299,7 +1299,7 @@ The first set of header columns are common to all of the output files generated .. _table_PS_format_info_VCNT: -.. list-table:: Format information for VAL1L2 (Vector Anomaly Partial Sums) output line type. Note that each statistic (except TOTAL) is followed by two columns giving bootstrap confidence intervals. These confidence intervals are not currently calculated for this release of MET, but will be in future releases. +.. list-table:: Format information for VCNT (Vector Continuous Statistics) output line type. Note that each statistic (except TOTAL) is followed by two columns giving bootstrap confidence intervals. These confidence intervals are not currently calculated for this release of MET, but will be in future releases. :widths: auto :header-rows: 2 From 84f8c7fb311fe632a89870274bf6ce74d1cc40a7 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 1 Dec 2021 12:54:12 -0700 Subject: [PATCH 018/172] Per #1985, VERY minor change to fix alignment of titles in Point-Stat... updating the develop branch. --- met/docs/Users_Guide/point-stat.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index 311332574f..e9cc3fdca8 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -698,7 +698,7 @@ The first set of header columns are common to all of the output files generated .. _table_PS_format_info_CTS_cont: -.. list-table:: Format information for CTS (Contingency Table Statistics) output line type, continued from above +.. list-table:: Format information for CTS (Contingency Table Statistics) output line type, continued from above :widths: auto :header-rows: 2 @@ -804,7 +804,7 @@ The first set of header columns are common to all of the output files generated .. _table_PS_format_info_CNT_cont: -.. list-table:: Format information for CNT (Continuous Statistics) output line type continued from above table +.. list-table:: Format information for CNT (Continuous Statistics) output line type continued from above table :widths: auto :header-rows: 2 From d35190e8c1ad5b3d60b7e5a2863ece30bc0d15c0 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 1 Dec 2021 13:50:10 -0700 Subject: [PATCH 019/172] #1936 Added an unit test for newer MESONET file --- test/xml/unit_madis2nc.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/xml/unit_madis2nc.xml b/test/xml/unit_madis2nc.xml index 0b0020e8ba..802eebc3c7 100644 --- a/test/xml/unit_madis2nc.xml +++ b/test/xml/unit_madis2nc.xml @@ -130,6 +130,18 @@ + + &MET_BIN;/madis2nc + \ + &DATA_DIR_OBS;/madis/mesonet/mesonet_20170101_0000.nc \ + &OUTPUT_DIR;/madis2nc/mesonet_20170101_0000_F000.nc \ + -type mesonet -mask_grid G207 -v 2 + + + &OUTPUT_DIR;/madis2nc/mesonet_20170101_0000_F000.nc + + + &MET_BIN;/madis2nc \ From 8c29f09d21ea73ce755027e18192b638d1a591bc Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 13 Dec 2021 11:08:49 -0700 Subject: [PATCH 020/172] Feature 1989 sort (#1990) --- met/data/table_files/Makefile.am | 2 +- .../{grib2_af_gpp.txt => grib2_gpp_af.txt} | 0 met/src/basic/vx_util/get_filenames.cc | 12 +++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) rename met/data/table_files/{grib2_af_gpp.txt => grib2_gpp_af.txt} (100%) diff --git a/met/data/table_files/Makefile.am b/met/data/table_files/Makefile.am index 354ba05876..ab8a87b130 100644 --- a/met/data/table_files/Makefile.am +++ b/met/data/table_files/Makefile.am @@ -87,9 +87,9 @@ tablefiles_DATA = \ grib1_ncep_141_7.txt \ grib1_ncep_2_7.txt \ grib1_lidar2nc.txt \ - grib2_af_gpp.txt \ grib2_all.txt \ grib2_bom.txt \ + grib2_gpp_af.txt \ grib2_mrms.txt \ grib2_ndfd.txt diff --git a/met/data/table_files/grib2_af_gpp.txt b/met/data/table_files/grib2_gpp_af.txt similarity index 100% rename from met/data/table_files/grib2_af_gpp.txt rename to met/data/table_files/grib2_gpp_af.txt diff --git a/met/src/basic/vx_util/get_filenames.cc b/met/src/basic/vx_util/get_filenames.cc index d0067fa437..f52d31ae7e 100644 --- a/met/src/basic/vx_util/get_filenames.cc +++ b/met/src/basic/vx_util/get_filenames.cc @@ -112,11 +112,14 @@ struct stat sbuf; if ( S_ISDIR(sbuf.st_mode) ) { // - // process directory + // get filenames from the directory and sort them + // to make the order consistent across platforms // b = get_filenames_from_dir(search_dir.c_str(), prefix, suffix); + b.sort(); + a.add(b); b.clear(); @@ -198,10 +201,17 @@ while ( (entry = readdir(directory)) != NULL ) { } + // + // get filenames from the directory and sort them + // to make the order consistent across platforms + // + if ( S_ISDIR(sbuf.st_mode) ) { b = get_filenames_from_dir(entry_path, prefix, suffix); + b.sort(); + a.add(b); b.clear(); From b93f4eae10e5061cd78a07b6307f36b26191b20a Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 13 Dec 2021 12:08:56 -0700 Subject: [PATCH 021/172] Feature 1991 VCNT (#1992) --- met/src/tools/core/grid_stat/grid_stat.cc | 30 ++++++++++++--------- met/src/tools/core/point_stat/point_stat.cc | 10 +++---- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 380df877b5..9b2447818a 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -85,8 +85,7 @@ // output line types. // 034 05/10/16 Halley Gotway Add grid weighting. // 035 05/20/16 Prestopnik J Removed -version (now in command_line.cc) -// 036 02/14/17 Win MET-621 enhancement support- additional -// nc_pairs_flag 'apply_mask' +// 036 02/14/17 Win MET#621 Add nc_pairs_flag.apply_mask // 037 05/15/17 Prestopnik P Add shape for regrid, nbrhd and interp // 038 06/26/17 Halley Gotway Add ECLV line type. // 039 08/18/17 Halley Gotway Add fourier decomposition. @@ -109,6 +108,7 @@ // 051 03/28/21 Halley Gotway Add mpr_column and mpr_thresh // filtering options. // 052 05/28/21 Halley Gotway Add MCTS HSS_EC output. +// 053 12/11/21 Halley Gotway MET #1991 Fix VCNT output. // //////////////////////////////////////////////////////////////////////// @@ -930,12 +930,13 @@ void process_scores() { do_cnt_sl1l2(conf_info.vx_opt[i], &pd); } - // Compute VL1L2 and VAL1L2 partial sums for UGRD,VGRD + // Compute VL1L2 and VAL1L2 partial sums for UGRD and VGRD if(!conf_info.vx_opt[i].fcst_info->is_prob() && conf_info.vx_opt[i].fcst_info->is_v_wind() && conf_info.vx_opt[i].fcst_info->uv_index() >= 0 && (conf_info.vx_opt[i].output_flag[i_vl1l2] != STATOutputType_None || - conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None) ) { + conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None || + conf_info.vx_opt[i].output_flag[i_vcnt] != STATOutputType_None)) { // Store the forecast variable name shc.set_fcst_var(ugrd_vgrd_abbr_str); @@ -1006,7 +1007,6 @@ void process_scores() { // Write out VL1L2 if(conf_info.vx_opt[i].output_flag[i_vl1l2] != STATOutputType_None && vl1l2_info[m].vcount > 0) { - write_vl1l2_row(shc, vl1l2_info[m], conf_info.vx_opt[i].output_flag[i_vl1l2], stat_at, i_stat_row, @@ -1016,18 +1016,15 @@ void process_scores() { // Write out VAL1L2 if(conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None && vl1l2_info[m].vacount > 0) { - write_val1l2_row(shc, vl1l2_info[m], conf_info.vx_opt[i].output_flag[i_val1l2], stat_at, i_stat_row, txt_at[i_val1l2], i_txt_row[i_val1l2]); } - // Write out VCNT if(conf_info.vx_opt[i].output_flag[i_vcnt] != STATOutputType_None && vl1l2_info[m].vcount > 0) { - write_vcnt_row(shc, vl1l2_info[m], conf_info.vx_opt[i].output_flag[i_vcnt], stat_at, i_stat_row, @@ -1677,12 +1674,13 @@ void process_scores() { do_cnt_sl1l2(conf_info.vx_opt[i], &pd); } - // Compute VL1L2 and VAL1L2 partial sums for UGRD,VGRD + // Compute VL1L2 and VAL1L2 partial sums for UGRD and VGRD if(!conf_info.vx_opt[i].fcst_info->is_prob() && conf_info.vx_opt[i].fcst_info->is_v_wind() && conf_info.vx_opt[i].fcst_info->uv_index() >= 0 && (conf_info.vx_opt[i].output_flag[i_vl1l2] != STATOutputType_None || - conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None) ) { + conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None || + conf_info.vx_opt[i].output_flag[i_vcnt] != STATOutputType_None)) { // Store the forecast variable name shc.set_fcst_var(ugrd_vgrd_abbr_str); @@ -1754,7 +1752,6 @@ void process_scores() { // Write out VL1L2 if(conf_info.vx_opt[i].output_flag[i_vl1l2] != STATOutputType_None && vl1l2_info[m].vcount > 0) { - write_vl1l2_row(shc, vl1l2_info[m], conf_info.vx_opt[i].output_flag[i_vl1l2], stat_at, i_stat_row, @@ -1764,12 +1761,21 @@ void process_scores() { // Write out VAL1L2 if(conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None && vl1l2_info[m].vacount > 0) { - write_val1l2_row(shc, vl1l2_info[m], conf_info.vx_opt[i].output_flag[i_val1l2], stat_at, i_stat_row, txt_at[i_val1l2], i_txt_row[i_val1l2]); } + + // Write out VCNT + if(conf_info.vx_opt[i].output_flag[i_vcnt] != STATOutputType_None && + vl1l2_info[m].vcount > 0) { + write_vcnt_row(shc, vl1l2_info[m], + conf_info.vx_opt[i].output_flag[i_vcnt], + stat_at, i_stat_row, + txt_at[i_vcnt], i_txt_row[i_vcnt]); + } + } // end for m // Reset the forecast variable name diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 549e6fce9f..7e78611c59 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -98,6 +98,7 @@ // 047 08/23/21 Seth Linden Add ORANK line type for HiRA. // 048 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. +// 049 12/11/21 Halley Gotway MET#1991 Fix VCNT output. // //////////////////////////////////////////////////////////////////////// @@ -1055,12 +1056,13 @@ void process_scores() { do_cnt_sl1l2(conf_info.vx_opt[i], pd_ptr); } - // Compute VL1L2 and VAL1L2 partial sums for UGRD,VGRD + // Compute VL1L2 and VAL1L2 partial sums for UGRD and VGRD if(!conf_info.vx_opt[i].vx_pd.fcst_info->is_prob() && conf_info.vx_opt[i].vx_pd.fcst_info->is_v_wind() && conf_info.vx_opt[i].vx_pd.fcst_info->uv_index() >= 0 && (conf_info.vx_opt[i].output_flag[i_vl1l2] != STATOutputType_None || - conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None) ) { + conf_info.vx_opt[i].output_flag[i_val1l2] != STATOutputType_None || + conf_info.vx_opt[i].output_flag[i_vcnt] != STATOutputType_None)) { // Store the forecast variable name shc.set_fcst_var(ugrd_vgrd_abbr_str); @@ -1117,8 +1119,7 @@ void process_scores() { txt_at[i_val1l2], i_txt_row[i_val1l2]); } - - // Write out VCNT + // Write out VCNT if(conf_info.vx_opt[i].output_flag[i_vcnt] != STATOutputType_None && vl1l2_info[m].vcount > 0) { write_vcnt_row(shc, vl1l2_info[m], @@ -1127,7 +1128,6 @@ void process_scores() { txt_at[i_vcnt], i_txt_row[i_vcnt]); } - } // end for m // Reset the forecast variable name From 49fb555e1523ed7e9b61772ca05789977b7b90e1 Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 13 Dec 2021 13:37:38 -0700 Subject: [PATCH 022/172] Feature 1993 grid_mask (#1994) --- .../tools/other/gen_vx_mask/gen_vx_mask.cc | 52 +++++++++++++++---- test/xml/unit_gen_vx_mask.xml | 35 +++++++++++++ 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc b/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc index 3b220f8e75..1fd7bb9bc2 100644 --- a/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc +++ b/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc @@ -25,7 +25,8 @@ // 007 04/08/19 Halley Gotway Add percentile thresholds. // 008 04/06/20 Halley Gotway Generalize input_grid option. // 009 06/01/21 Seth Linden Change -type from optional to required. -// 010 08/30/21 Halley Gotway MET #1891 fix input and mask fields. +// 010 08/30/21 Halley Gotway MET#1891 Fix input and mask fields. +// 011 12/13/21 Halley Gotway MET#1993 Fix -type grid. // //////////////////////////////////////////////////////////////////////// @@ -163,26 +164,26 @@ void process_command_line(int argc, char **argv) { void process_input_grid(DataPlane &dp) { - // Parse info.name as a white-space separated string + // Parse the input grid as a white-space separated string StringArray sa; sa.parse_wsss(input_gridname); // Search for a named grid if(sa.n() == 1 && find_grid_by_name(sa[0].c_str(), grid)) { mlog << Debug(3) - << "Use the grid named \"" << input_gridname << "\".\n"; + << "Use input grid named \"" << input_gridname << "\".\n"; } // Parse grid definition else if(sa.n() > 1 && parse_grid_def(sa, grid)) { mlog << Debug(3) - << "Use the grid defined by string \"" << input_gridname + << "Use input grid defined by string \"" << input_gridname << "\".\n"; } // Extract the grid from a gridded data file else { mlog << Debug(3) - << "Use the grid defined by file \"" << input_gridname + << "Use input grid defined by file \"" << input_gridname << "\".\n"; // Read the input grid and data plane, if requested @@ -249,13 +250,44 @@ void process_mask_file(DataPlane &dp) { mask_type == MaskType_Lon) { } - // Otherwise, process the mask file as a gridded data file + // Otherwise, process the mask file as a named grid, grid specification + // string or gridded data file else { - // Read the mask grid and data plane, if requested - get_data_plane(mask_filename, mask_field_str, - mask_type == MaskType_Data, - dp, grid_mask); + // For the grid mask type, support named grids and grid + // specification strings + if(mask_type == MaskType_Grid) { + + // Parse the mask file as a white-space separated string + StringArray sa; + sa.parse_wsss(mask_filename); + + // Search for a named grid + if(sa.n() == 1 && find_grid_by_name(sa[0].c_str(), grid_mask)) { + mlog << Debug(3) + << "Use mask grid named \"" << mask_filename << "\".\n"; + } + // Parse grid definition + else if(sa.n() > 1 && parse_grid_def(sa, grid_mask)) { + mlog << Debug(3) + << "Use mask grid defined by string \"" << mask_filename + << "\".\n"; + } + } + + // Parse as a gridded data file if not already set + if(grid_mask.nxy() == 0) { + + // Extract the grid from a gridded data file + mlog << Debug(3) + << "Use mask grid defined by file \"" << mask_filename + << "\".\n"; + + // Read the mask grid and data plane, if requested + get_data_plane(mask_filename, mask_field_str, + mask_type == MaskType_Data, + dp, grid_mask); + } mlog << Debug(2) << "Parsed Mask Grid:\t" << grid_mask.name() diff --git a/test/xml/unit_gen_vx_mask.xml b/test/xml/unit_gen_vx_mask.xml index 8ada4b6649..6416d0a048 100644 --- a/test/xml/unit_gen_vx_mask.xml +++ b/test/xml/unit_gen_vx_mask.xml @@ -125,6 +125,41 @@ + + + + + + &MET_BIN;/gen_vx_mask + \ + G004 G130 \ + &OUTPUT_DIR;/gen_vx_mask/GRID_NAMED_GRIDS_mask.nc \ + -type grid -name G130_grid \ + -v 1 + + + &OUTPUT_DIR;/gen_vx_mask/GRID_NAMED_GRIDS_mask.nc + + + + + + + + + &MET_BIN;/gen_vx_mask + \ + "latlon 720 361 -90 0 0.5 0.5" \ + "latlon 200 100 -40 -50 0.5 0.5" \ + &OUTPUT_DIR;/gen_vx_mask/GRID_SPEC_STRINGS_mask.nc \ + -type grid -name grid_spec \ + -v 1 + + + &OUTPUT_DIR;/gen_vx_mask/GRID_SPEC_STRINGS_mask.nc + + + From dd0a68b22bc3a9b2d899c1446dc939c8a3b67653 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:28:37 -0700 Subject: [PATCH 023/172] #1844 Added vx_pointdata_python --- met/Make-include | 2 ++ 1 file changed, 2 insertions(+) diff --git a/met/Make-include b/met/Make-include index dfa6bd5faa..42f1d5f3b3 100644 --- a/met/Make-include +++ b/met/Make-include @@ -25,6 +25,7 @@ MET_CPPFLAGS = -I${top_builddir}/src/basic/vx_cal \ -I${top_builddir}/src/libcode/vx_nc_util \ -I${top_builddir}/src/libcode/vx_pb_util \ -I${top_builddir}/src/libcode/vx_plot_util \ + -I${top_builddir}/src/libcode/vx_pointdata_python \ -I${top_builddir}/src/libcode/vx_ps \ -I${top_builddir}/src/libcode/vx_pxm \ -I${top_builddir}/src/libcode/vx_render \ @@ -67,6 +68,7 @@ MET_LDFLAGS = -L${top_builddir}/src/basic/vx_cal \ -L${top_builddir}/src/libcode/vx_nc_util \ -L${top_builddir}/src/libcode/vx_pb_util \ -L${top_builddir}/src/libcode/vx_plot_util \ + -L${top_builddir}/src/libcode/vx_pointdata_python \ -L${top_builddir}/src/libcode/vx_ps \ -L${top_builddir}/src/libcode/vx_pxm \ -L${top_builddir}/src/libcode/vx_render \ From 2b61506d5e6e75162ebf13dcd5bbc99bf3afcf27 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:31:27 -0700 Subject: [PATCH 024/172] #1844 Added vx_pointdata_python to PYTHON_LIBS & make file for vx_pointdata_python --- met/configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/met/configure.ac b/met/configure.ac index 2fc599e47a..a20d682eff 100644 --- a/met/configure.ac +++ b/met/configure.ac @@ -1036,7 +1036,7 @@ if test "x$ENABLE_PYTHON" = "xyes"; then AC_DEFINE([ENABLE_PYTHON], [], ["build python embedding"]) AC_MSG_NOTICE([python embedding will be compiled]) CPPFLAGS="${CPPFLAGS} -DWITH_PYTHON" - PYTHON_LIBS="-lvx_data2d_python -lvx_python3_utils ${MET_PYTHON_LD}" + PYTHON_LIBS="-lvx_data2d_python -lvx_pointdata_python -lvx_python3_utils ${MET_PYTHON_LD}" else AC_MSG_NOTICE([python embedding will not be compiled]) PYTHON_LIBS= @@ -1233,6 +1233,7 @@ AC_CONFIG_FILES([Makefile src/libcode/vx_summary/Makefile src/libcode/vx_python3_utils/Makefile src/libcode/vx_data2d_python/Makefile + src/libcode/vx_pointdata_python/Makefile src/tools/Makefile src/tools/core/Makefile src/tools/core/ensemble_stat/Makefile From b4a4e18d509ee39458e8af8adc3f018e485a2a14 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:32:05 -0700 Subject: [PATCH 025/172] #1844 Added vx_pointdata_python to SUBDIRS --- met/src/libcode/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/met/src/libcode/Makefile.am b/met/src/libcode/Makefile.am index 76817f7749..8ed5d82c73 100644 --- a/met/src/libcode/Makefile.am +++ b/met/src/libcode/Makefile.am @@ -27,6 +27,7 @@ SUBDIRS = vx_grid \ if ENABLE_PYTHON SUBDIRS += vx_python3_utils SUBDIRS += vx_data2d_python + SUBDIRS += vx_pointdata_python endif From ba9f81e22fe63c0a4cc7621f0db2f818f453ca49 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:33:59 -0700 Subject: [PATCH 026/172] #1844 Initial release --- met/src/libcode/vx_nc_obs/met_point_data.cc | 437 ++++++++++++++++++++ met/src/libcode/vx_nc_obs/met_point_data.h | 179 ++++++++ 2 files changed, 616 insertions(+) create mode 100644 met/src/libcode/vx_nc_obs/met_point_data.cc create mode 100644 met/src/libcode/vx_nc_obs/met_point_data.h diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc new file mode 100644 index 0000000000..6cc15a7e81 --- /dev/null +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -0,0 +1,437 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include +#include + +#include "vx_log.h" +#include "is_bad_data.h" + +#include "met_point_data.h" +//#include "nc_point_obs.h" + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class MetPointData + // + + +//////////////////////////////////////////////////////////////////////// + +MetPointData::MetPointData() { + // Derived class should set obs_data + init_from_scratch(); +} + +//////////////////////////////////////////////////////////////////////// + +MetPointData::~MetPointData() { + clear(); +} + +//////////////////////////////////////////////////////////////////////// + +void MetPointData::init_from_scratch() { + nobs = 0; + nhdr = 0; + qty_length = 0; + + use_var_id = false; + use_arr_vars = false; +} + + +//////////////////////////////////////////////////////////////////////// + +//void MetPointData::allocate() { +// obs_data.allocate(); +//} + +//////////////////////////////////////////////////////////////////////// + +void MetPointData::clear() { + if (obs_data) obs_data->clear(); + header_data.clear(); +} + +//////////////////////////////////////////////////////////////////////// + +bool MetPointData::get_header(int header_offset, float hdr_arr[HDR_ARRAY_LEN], + ConcatString &hdr_typ_str, ConcatString &hdr_sid_str, + ConcatString &hdr_vld_str) { + int hdr_idx; + + // Read the corresponding header array for this observation + + hdr_arr[0] = header_data.lat_array[header_offset]; + hdr_arr[1] = header_data.lon_array[header_offset]; + hdr_arr[2] = header_data.elv_array[header_offset]; + + // Read the corresponding header type for this observation + hdr_idx = use_arr_vars ? header_offset : header_data.typ_idx_array[header_offset]; + hdr_typ_str = header_data.typ_array[hdr_idx]; + + // Read the corresponding header Station ID for this observation + hdr_idx = use_arr_vars ? header_offset : header_data.sid_idx_array[header_offset]; + hdr_sid_str = header_data.sid_array[hdr_idx]; + + // Read the corresponding valid time for this observation + hdr_idx = use_arr_vars ? header_offset : header_data.vld_idx_array[header_offset]; + hdr_vld_str = header_data.vld_array[hdr_idx]; + + return true; +} + +//////////////////////////////////////////////////////////////////////// + +bool MetPointData::get_header_type(int header_offset, int hdr_typ_arr[HDR_TYPE_ARR_LEN]) { + int hdr_idx; + // Read the header integer types + hdr_typ_arr[0] = (header_data.prpt_typ_array.n() > header_offset ? + header_data.prpt_typ_array[header_offset] : bad_data_int); + hdr_typ_arr[1] = (header_data.irpt_typ_array.n() > header_offset ? + header_data.irpt_typ_array[header_offset] : bad_data_int); + hdr_typ_arr[2] = (header_data.inst_typ_array.n() > header_offset ? + header_data.inst_typ_array[header_offset] : bad_data_int); + + return true; +} + +//////////////////////////////////////////////////////////////////////// + +bool MetPointData::get_lats(float *hdr_lats) { + for (int idx=0; idxobs_cnt = obs_cnt; +} + + + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class MetPointDataPython + // + + +//////////////////////////////////////////////////////////////////////// + +MetPointDataPython::MetPointDataPython() { + obs_data = new MetPointObsData(); + init_from_scratch(); +} + +//////////////////////////////////////////////////////////////////////// + +MetPointDataPython::MetPointDataPython(MetPointDataPython &d) { + init_from_scratch(); + //obs_data = d.get_point_obs_data(); + //header_data = d.get_header_data(); + obs_data->assign(*d.get_point_obs_data()); + header_data.assign(*d.get_header_data()); +cout << " DEBUG HS MetPointData(MetPointData &d) is called \n"; +cout << " DEBUG HS MetPointData(MetPointData &d) &header_data.lat_array=" << &(header_data.lat_array) << "\n"; +cout << " DEBUG HS MetPointData(MetPointData &d) header_data.lat_array.n()=" << header_data.lat_array.n() << "\n"; +cout << " DEBUG HS MetPointData(MetPointData &d) header_data.lon_array.n()=" << header_data.lon_array.n() << "\n"; +cout << " DEBUG HS MetPointData(MetPointData &d) header_data.elv_array.n()=" << header_data.elv_array.n() << "\n"; +cout << " DEBUG HS MetPointData(MetPointData &d) header_data.typ_idx_array.n()=" << header_data.typ_idx_array.n() << "\n"; +cout << " DEBUG HS MetPointData(MetPointData &d) header_data.sid_idx_array.n()=" << header_data.sid_idx_array.n() << "\n"; +cout << " DEBUG HS MetPointData(MetPointData &d) header_data.vld_idx_array.n()=" << header_data.vld_idx_array.n() << "\n"; +} + + +//////////////////////////////////////////////////////////////////////// + +MetPointDataPython::~MetPointDataPython() { + clear(); +} + +//////////////////////////////////////////////////////////////////////// + +//void MetPointDataPython::init_from_scratch() { +// nobs = 0; +// nhdr = 0; +// qty_length = 0; +// +// use_var_id = false; +// use_arr_vars = false; +//} + + +//////////////////////////////////////////////////////////////////////// + +void MetPointDataPython::allocate(int obs_cnt) { + set_obs_cnt(obs_cnt); + obs_data->allocate(); +} + +//////////////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////////////////////// +// struct MetPointObsData + +MetPointObsData::MetPointObsData(): + obs_cnt(0), + obs_ids((int *)0), + obs_hids((int *)0), + obs_qids((int *)0), + obs_lvls((float *)0), + obs_hgts((float *)0), + obs_vals((float *)0), + obs_arr((float *)0), + is_obs_array(false) +{ +} + + +/////////////////////////////////////////////////////////////////////////////// + +void MetPointObsData::allocate() { + if (is_obs_array) obs_arr = new float[obs_cnt*OBS_ARRAY_LEN]; // nobs * 5 + else { + obs_ids = new int[obs_cnt]; // grib_code or var_id + obs_hids = new int[obs_cnt]; + obs_qids = new int[obs_cnt]; + obs_lvls = new float[obs_cnt]; + obs_hgts = new float[obs_cnt]; + obs_vals = new float[obs_cnt]; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void MetPointObsData::assign(MetPointObsData &o) { + obs_cnt = o.obs_cnt; + is_obs_array = o.is_obs_array; + + clear(); + allocate(); + if (is_obs_array) + for (int idx=0; idx + +#include "nc_utils.h" + + +//////////////////////////////////////////////////////////////////////// + +struct MetPointHeader { + int typ_len; + int sid_len; + int vld_len; + int strl_len; + int strll_len; + int min_vld_time; + int max_vld_time; + int hdr_count; + int hdr_type_count; + + StringArray typ_array; + StringArray sid_array; + StringArray vld_array; // string array for valid time + IntArray vld_num_array; // number array for valid time + IntArray typ_idx_array; + IntArray sid_idx_array; + IntArray vld_idx_array; // index to vld_array/vld_num_array + NumArray lat_array; + NumArray lon_array; + NumArray elv_array; + IntArray prpt_typ_array; + IntArray irpt_typ_array; + IntArray inst_typ_array; + + MetPointHeader(); + void assign(MetPointHeader &h); + void clear(); + void reset_counters(); +}; + +//////////////////////////////////////////////////////////////////////// + +struct MetPointObsData { + int obs_cnt; + bool is_obs_array; + + int *obs_ids; // grib_code or var_id + int *obs_hids; + int *obs_qids; + float *obs_lvls; + float *obs_hgts; + float *obs_vals; + float *obs_arr; // nobs * 5 + StringArray var_names; + StringArray qty_names; + + MetPointObsData(); + void allocate(); + void assign(MetPointObsData &d); + void clear(); + void clear_numbers(); + void clear_strings(); + bool fill_obs_buf(int buf_size, int offset, float *obs_arr, int *qty_idx_arr); + float get_obs_val(int index); +}; + + +class MetPointData { + + protected: + + int nobs; + int nhdr; + int qty_length; + bool use_var_id; + bool use_arr_vars; + + MetPointHeader header_data; + MetPointObsData *obs_data = 0; + + void init_from_scratch(); + + public: + + MetPointData(); + ~MetPointData(); + + //void close(); + void clear(); + + int get_buf_size(); + int get_hdr_cnt(); + int get_grib_code_or_var_index(const float obs_arr[OBS_ARRAY_LEN]); + MetPointHeader *get_header_data(); + bool get_header(int header_offset, float hdr_arr[HDR_ARRAY_LEN], + ConcatString &hdr_typ_str, ConcatString &hdr_sid_str, + ConcatString &hdr_vld_str); + int get_header_offset(const float obs_arr[OBS_ARRAY_LEN]); + bool get_header_type(int header_offset, int hdr_typ_arr[HDR_TYPE_ARR_LEN]); + bool get_lats(float *hdr_lats); + bool get_lons(float *hdr_lons); + int get_obs_cnt(); + MetPointObsData *get_point_obs_data(); + StringArray get_qty_data(); + StringArray get_var_names(); + + bool is_same_obs_values(const float obs_arr1[OBS_ARRAY_LEN], const float obs_arr2[OBS_ARRAY_LEN]); + bool is_using_var_id(); + + void set_grib_code_or_var_index(float obs_arr[OBS_ARRAY_LEN], int grib_code); + void set_hdr_cnt(int hdr_cnt); + void set_obs_cnt(int obs_cnt); + // variables + + // data + +}; // MetPointDataBase + + + +class MetPointDataPython : public MetPointData { + + protected: + + public: + + MetPointDataPython(); + MetPointDataPython(MetPointDataPython &d); + ~MetPointDataPython(); + + void allocate(int obs_cnt); + void set_use_var_id(bool new_use_var_id); + + // variables + + // data + +}; // MetPointData + +//////////////////////////////////////////////////////////////////////// + +inline MetPointHeader *MetPointData::get_header_data() { return &header_data; } +inline int MetPointData::get_buf_size() { return OBS_BUFFER_SIZE; } +inline int MetPointData::get_grib_code_or_var_index(const float obs_arr[OBS_ARRAY_LEN]) { return obs_arr[1]; }; +inline int MetPointData::get_hdr_cnt() { return nhdr; } +inline int MetPointData::get_header_offset(const float obs_arr[OBS_ARRAY_LEN]) { return obs_arr[0]; }; +inline int MetPointData::get_obs_cnt() { return nobs; } +inline MetPointObsData *MetPointData::get_point_obs_data() { return obs_data; } +inline StringArray MetPointData::get_qty_data() { return obs_data->qty_names; } +inline StringArray MetPointData::get_var_names() { return obs_data->var_names; } +inline bool MetPointData::is_using_var_id() { return use_var_id; } +inline void MetPointData::set_grib_code_or_var_index(float obs_arr[OBS_ARRAY_LEN], int grib_code) { obs_arr[1] = grib_code; } +inline void MetPointDataPython::set_use_var_id(bool new_use_var_id) { use_var_id = new_use_var_id; } + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MET_POINT_DATA_H__ */ + + +//////////////////////////////////////////////////////////////////////// + From abef2b798c1851f0cbd8cbe42b98d3a621c60631 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:34:46 -0700 Subject: [PATCH 027/172] #1844 Added met_point_data.cc & met_point_data.h --- met/src/libcode/vx_nc_obs/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/met/src/libcode/vx_nc_obs/Makefile.am b/met/src/libcode/vx_nc_obs/Makefile.am index ba2fb8c910..22f0871fab 100644 --- a/met/src/libcode/vx_nc_obs/Makefile.am +++ b/met/src/libcode/vx_nc_obs/Makefile.am @@ -12,6 +12,7 @@ include ${top_srcdir}/Make-include noinst_LIBRARIES = libvx_nc_obs.a libvx_nc_obs_a_SOURCES = \ + met_point_data.cc met_point_data.h \ nc_obs_util.cc nc_obs_util.h \ nc_point_obs.cc nc_point_obs.h \ nc_point_obs_in.cc nc_point_obs_in.h \ From 6c36d79297baabfd741feda5236ce8442e05c85f Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:46:13 -0700 Subject: [PATCH 028/172] #1844 NcHeaderData is renamed to MetPointHeader and moved to met_point_dataq.h --- met/src/libcode/vx_nc_obs/nc_obs_util.h | 60 +++---------------------- 1 file changed, 6 insertions(+), 54 deletions(-) diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.h b/met/src/libcode/vx_nc_obs/nc_obs_util.h index 4985639c09..d3d07f3007 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.h +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.h @@ -17,6 +17,7 @@ using namespace netCDF; #include "nc_summary.h" +#include "met_point_data.h" //////////////////////////////////////////////////////////////////////// @@ -78,39 +79,6 @@ struct NcDataBuffer { //////////////////////////////////////////////////////////////////////// -struct NcHeaderData { - bool valid_point_obs; - int typ_len; - int sid_len; - int vld_len; - int strl_len; - int strll_len; - int min_vld_time; - int max_vld_time; - int hdr_count; - int hdr_type_count; - - StringArray typ_array; - StringArray sid_array; - StringArray vld_array; - IntArray vld_num_array; - IntArray typ_idx_array; - IntArray sid_idx_array; - IntArray vld_idx_array; - NumArray lat_array; - NumArray lon_array; - NumArray elv_array; - IntArray prpt_typ_array; - IntArray irpt_typ_array; - IntArray inst_typ_array; - - NcHeaderData(); - void clear(); - void reset_counters(); -}; - -//////////////////////////////////////////////////////////////////////// - struct NetcdfObsVars { bool attr_agl ; bool attr_pb2nc ; @@ -167,7 +135,7 @@ struct NetcdfObsVars { void create_hdr_vars (NcFile *f_out, const int hdr_count); void create_obs_vars (NcFile *f_out); void create_obs_name_vars (NcFile *f_out, const int var_count, const int unit_count); - void create_table_vars (NcFile *f_out, NcHeaderData &hdr_data, NcDataBuffer &data_buffer); + void create_table_vars (NcFile *f_out, MetPointHeader &hdr_data, NcDataBuffer &data_buffer); void create_pb_hdrs (NcFile *f_out, const int hdr_count); NcDim create_var_obs_var (NcFile *f_out, int var_count); @@ -175,41 +143,25 @@ struct NetcdfObsVars { int get_obs_index(); void read_dims_vars(NcFile *f_in); - void read_header_data(NcHeaderData &hdr_data); + void read_header_data(MetPointHeader &hdr_data); bool read_obs_data(int buf_size, int offset, int qty_len, float *obs_arr, int *qty_idx_arr, char *obs_qty_buf); - void read_pb_hdr_data(NcHeaderData &hdr_data); + void read_pb_hdr_data(MetPointHeader &hdr_data); void write_header_to_nc(NcDataBuffer &data_buf, const int buf_size, const bool is_pb = false); void write_obs_buffer(NcDataBuffer &data_buffer, const int buf_size); void write_obs_var_names(StringArray &obs_names); void write_obs_var_units(StringArray &units); void write_obs_var_descriptions(StringArray &descriptions); - void write_table_vars(NcHeaderData &hdr_data, NcDataBuffer &data_buffer); + void write_table_vars(MetPointHeader &hdr_data, NcDataBuffer &data_buffer); }; // NetcdfObsVars //////////////////////////////////////////////////////////////////////// -struct NcPointObsData { - int obs_cnt; - bool is_obs_array; - - int *obs_ids; // grib_code or var_id - int *obs_hids; - int *obs_qids; - float *obs_lvls; - float *obs_hgts; - float *obs_vals; - float *obs_arr; // nobs * 5 - StringArray var_names; - StringArray qty_names; +struct NcPointObsData : public MetPointObsData { NcPointObsData(); - void clear(); - void clear_numbers(); - void clear_strings(); - float get_obs_val(int index); bool read_obs_data_numbers(NetcdfObsVars obs_vars, bool stop=true); bool read_obs_data_table_lookups(NetcdfObsVars obs_vars, bool stop=true); }; From 3f0de5e7e45c47e0fe9615b2c964003b4a8fcb69 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:47:58 -0700 Subject: [PATCH 029/172] #1844 NcPointObsData is derived from MetPointObsData. Many methods are moved to the base class MetPointObsData --- met/src/libcode/vx_nc_obs/nc_obs_util.cc | 121 +---------------------- 1 file changed, 5 insertions(+), 116 deletions(-) diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.cc b/met/src/libcode/vx_nc_obs/nc_obs_util.cc index 70ea844d49..39a59266d2 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.cc +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.cc @@ -68,78 +68,12 @@ void NcDataBuffer::reset_counters() { /////////////////////////////////////////////////////////////////////////////// // struct NcPointObsData -NcPointObsData::NcPointObsData(): - obs_cnt(0), - obs_ids((int *)0), - obs_hids((int *)0), - obs_qids((int *)0), - obs_lvls((float *)0), - obs_hgts((float *)0), - obs_vals((float *)0), - obs_arr((float *)0), - is_obs_array(false) +NcPointObsData::NcPointObsData() { } /////////////////////////////////////////////////////////////////////////////// -void NcPointObsData::clear() { - obs_cnt = 0; - is_obs_array = false; - - clear_numbers(); - clear_strings(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void NcPointObsData::clear_numbers() { - if (0 != obs_ids) { - delete [] obs_ids; - obs_ids = (int *)0; - } - if (0 != obs_hids) { - delete [] obs_hids; - obs_hids = (int *)0; - } - if (0 != obs_qids) { - delete [] obs_qids; - obs_qids = (int *)0; - } - if (0 != obs_lvls) { - delete [] obs_lvls; - obs_lvls = (float *)0; - } - if (0 != obs_hgts) { - delete [] obs_hgts; - obs_hgts = (float *)0; - } - if (0 != obs_vals) { - delete [] obs_vals; - obs_vals = (float *)0; - } - if (0 != obs_arr) { - delete [] obs_arr; - obs_arr = (float *)0; - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void NcPointObsData::clear_strings() { - var_names.clear(); - qty_names.clear(); -} - -/////////////////////////////////////////////////////////////////////////////// - -float NcPointObsData::get_obs_val(int index) { - float obs_val = (is_obs_array ? obs_arr[index*obs_cnt+4] : obs_vals[index]); - return obs_val; -} - -/////////////////////////////////////////////////////////////////////////////// - bool NcPointObsData::read_obs_data_numbers(NetcdfObsVars obs_vars, bool stop) { bool succeed = true; const char* method_name = "NcPointObsData::read_obs_data_numbers()"; @@ -434,7 +368,7 @@ void NetcdfObsVars::create_pb_hdrs (NcFile *f_out, const int hdr_count) { /////////////////////////////////////////////////////////////////////////////// -void NetcdfObsVars::create_table_vars (NcFile *f_out, NcHeaderData &hdr_data, +void NetcdfObsVars::create_table_vars (NcFile *f_out, MetPointHeader &hdr_data, NcDataBuffer &data_buffer) { const string method_name = " create_table_vars()"; @@ -603,7 +537,7 @@ void NetcdfObsVars::read_dims_vars(NcFile *f_in) { //////////////////////////////////////////////////////////////////////// -void NetcdfObsVars::read_header_data(NcHeaderData &hdr_data) { +void NetcdfObsVars::read_header_data(MetPointHeader &hdr_data) { bool is_valid_obs_nc = true; long nhdr_count = get_dim_size(&hdr_dim); int strl_len = get_dim_size(&strl_dim); @@ -970,7 +904,7 @@ bool NetcdfObsVars::read_obs_data(int buf_size, int offset, //////////////////////////////////////////////////////////////////////// -void NetcdfObsVars::read_pb_hdr_data(NcHeaderData &hdr_data) { +void NetcdfObsVars::read_pb_hdr_data(MetPointHeader &hdr_data) { const char *method_name = "get_nc_pb_hdr_data() -> "; int pb_hdr_count = get_dim_size(&pb_hdr_dim); @@ -1166,7 +1100,7 @@ void NetcdfObsVars::write_header_to_nc(NcDataBuffer &data_buf, /////////////////////////////////////////////////////////////////////////////// -void NetcdfObsVars::write_table_vars (NcHeaderData &hdr_data, NcDataBuffer &data_buffer) +void NetcdfObsVars::write_table_vars (MetPointHeader &hdr_data, NcDataBuffer &data_buffer) { mlog << Debug(5) << "write_table_vars() is called. valid hdr_typ_tbl_var: " << !IS_INVALID_NC(hdr_typ_tbl_var) << "\n"; @@ -1261,51 +1195,6 @@ void NetcdfObsVars::write_obs_var_descriptions(StringArray &descriptions) { //////////////////////////////////////////////////////////////////////// // End of NetcdfObsVars -/////////////////////////////////////////////////////////////////////////////// - -// struct NcHeaderData - -NcHeaderData::NcHeaderData() -{ - reset_counters(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void NcHeaderData::clear() { - reset_counters(); - - typ_array.clear(); - sid_array.clear(); - vld_array.clear(); - vld_num_array.clear(); - typ_idx_array.clear(); - sid_idx_array.clear(); - vld_idx_array.clear(); - lat_array.clear(); - lon_array.clear(); - elv_array.clear(); - prpt_typ_array.clear(); - irpt_typ_array.clear(); - inst_typ_array.clear(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void NcHeaderData::reset_counters() { - valid_point_obs = false; - typ_len = 0; - sid_len = 0; - vld_len = 0; - strl_len = 0; - strll_len = 0; - hdr_count = 0; - - min_vld_time = -1; - max_vld_time = -1; -} - - /////////////////////////////////////////////////////////////////////////////// long count_nc_headers(vector< Observation > &observations) From 6c50d500ffb0b21f2b29221a8e12fbbcda212702 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:52:54 -0700 Subject: [PATCH 030/172] #1844 Moved varianbles and methods to the base class MetPointData --- met/src/libcode/vx_nc_obs/nc_point_obs.cc | 92 ++--------------------- met/src/libcode/vx_nc_obs/nc_point_obs.h | 42 +---------- 2 files changed, 7 insertions(+), 127 deletions(-) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs.cc b/met/src/libcode/vx_nc_obs/nc_point_obs.cc index b665e9d2e9..0869f3a31e 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs.cc +++ b/met/src/libcode/vx_nc_obs/nc_point_obs.cc @@ -36,6 +36,7 @@ using namespace std; //////////////////////////////////////////////////////////////////////// MetNcPointObs::MetNcPointObs() { + obs_data = new NcPointObsData(); init_from_scratch(); } @@ -48,104 +49,21 @@ MetNcPointObs::~MetNcPointObs() { //////////////////////////////////////////////////////////////////////// void MetNcPointObs::init_from_scratch() { - obs_nc = (NcFile *) 0; + MetPointData::init_from_scratch(); - nobs = 0; - nhdr = 0; - qty_length = 0; keep_nc = false; - use_var_id = false; - use_arr_vars = false; - - return; + obs_nc = (NcFile *) 0; } //////////////////////////////////////////////////////////////////////// void MetNcPointObs::close() { + MetPointData::clear(); + if ( !keep_nc && obs_nc ) { delete obs_nc; obs_nc = (NcFile *) 0; } - - obs_data.clear(); - header_data.clear(); - return; -} - -//////////////////////////////////////////////////////////////////////// - -int MetNcPointObs::get_qty_length() { - qty_length = get_nc_string_length(&obs_vars.obs_qty_tbl_var); - return qty_length; -} - -//////////////////////////////////////////////////////////////////////// - -bool MetNcPointObs::get_header(int header_offset, float hdr_arr[HDR_ARRAY_LEN], - ConcatString &hdr_typ_str, ConcatString &hdr_sid_str, ConcatString &hdr_vld_str) { - int hdr_idx; - - // Read the corresponding header array for this observation - hdr_arr[0] = header_data.lat_array[header_offset]; - hdr_arr[1] = header_data.lon_array[header_offset]; - hdr_arr[2] = header_data.elv_array[header_offset]; - - // Read the corresponding header type for this observation - hdr_idx = use_arr_vars ? header_offset : header_data.typ_idx_array[header_offset]; - hdr_typ_str = header_data.typ_array[hdr_idx]; - - // Read the corresponding header Station ID for this observation - hdr_idx = use_arr_vars ? header_offset : header_data.sid_idx_array[header_offset]; - hdr_sid_str = header_data.sid_array[hdr_idx]; - - // Read the corresponding valid time for this observation - hdr_idx = use_arr_vars ? header_offset : header_data.vld_idx_array[header_offset]; - hdr_vld_str = header_data.vld_array[hdr_idx]; - - return true; -} - -//////////////////////////////////////////////////////////////////////// - -bool MetNcPointObs::get_header_type(int header_offset, int hdr_typ_arr[HDR_TYPE_ARR_LEN]) { - int hdr_idx; - // Read the header integer types - hdr_typ_arr[0] = (header_data.prpt_typ_array.n() > header_offset ? - header_data.prpt_typ_array[header_offset] : bad_data_int); - hdr_typ_arr[1] = (header_data.irpt_typ_array.n() > header_offset ? - header_data.irpt_typ_array[header_offset] : bad_data_int); - hdr_typ_arr[2] = (header_data.inst_typ_array.n() > header_offset ? - header_data.inst_typ_array[header_offset] : bad_data_int); - - return true; -} - -//////////////////////////////////////////////////////////////////////// - -bool MetNcPointObs::get_lats(float *hdr_lats) { - for (int idx=0; idx Date: Tue, 28 Dec 2021 15:54:30 -0700 Subject: [PATCH 031/172] #1844 override the obs_data pointer to the derived class --- met/src/libcode/vx_nc_obs/nc_point_obs_in.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc b/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc index 3345edb5a7..3a91441deb 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc +++ b/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc @@ -94,7 +94,7 @@ bool MetNcPointObsIn::read_obs_data(int buf_size, int start, float *obs_arr_bloc bool MetNcPointObsIn::read_obs_data_numbers() { bool status = false; if( IS_VALID_NC_P(obs_nc) ) { - status = obs_data.read_obs_data_numbers(obs_vars); + status = ((NcPointObsData *)obs_data)->read_obs_data_numbers(obs_vars); } return status; } @@ -104,7 +104,7 @@ bool MetNcPointObsIn::read_obs_data_numbers() { bool MetNcPointObsIn::read_obs_data_table_lookups() { bool status = false; if( IS_VALID_NC_P(obs_nc) ) { - status = obs_data.read_obs_data_table_lookups(obs_vars); + status = ((NcPointObsData *)obs_data)->read_obs_data_table_lookups(obs_vars); } return status; } From b053f714ec4873d4a63d82930142e4393beb5744 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 15:55:59 -0700 Subject: [PATCH 032/172] #1844 Added pyobject_as_bool & pyobject_as_string_array --- .../libcode/vx_python3_utils/python3_util.cc | 36 ++++++++++++++++++- .../libcode/vx_python3_utils/python3_util.h | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/met/src/libcode/vx_python3_utils/python3_util.cc b/met/src/libcode/vx_python3_utils/python3_util.cc index fe56b6f6b2..ab17acd7b8 100644 --- a/met/src/libcode/vx_python3_utils/python3_util.cc +++ b/met/src/libcode/vx_python3_utils/python3_util.cc @@ -12,7 +12,6 @@ using namespace std; #include #include "vx_log.h" -#include "concat_string.h" #include "vx_math.h" #include "python3_util.h" @@ -125,6 +124,18 @@ return ( k ); //////////////////////////////////////////////////////////////////////// +bool pyobject_as_bool (PyObject * obj) + +{ + +return ( 1 == PyObject_IsTrue(obj) ); + +} + + +//////////////////////////////////////////////////////////////////////// + + double pyobject_as_double (PyObject * obj) { @@ -215,6 +226,29 @@ return ( s ); //////////////////////////////////////////////////////////////////////// +StringArray pyobject_as_string_array (PyObject * obj) + +{ + +StringArray a; +ConcatString s; +PyObject *item = 0; + +int size = PyList_Size (obj); +for (int idx=0; idx Date: Tue, 28 Dec 2021 16:06:28 -0700 Subject: [PATCH 033/172] #1844 Cleanup include statements and addpointdata_python.h if python is enabled --- met/src/tools/other/plot_point_obs/plot_point_obs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs.h b/met/src/tools/other/plot_point_obs/plot_point_obs.h index 7fec0e19f0..0bf33b0679 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs.h +++ b/met/src/tools/other/plot_point_obs/plot_point_obs.h @@ -43,12 +43,13 @@ using namespace netCDF; #include "plot_point_obs_conf_info.h" -#include "vx_data2d_factory.h" -#include "vx_grid.h" #include "vx_util.h" #include "vx_stat_out.h" #include "vx_gsl_prob.h" #include "nc_utils.h" +#ifdef WITH_PYTHON +#include "pointdata_python.h" +#endif //////////////////////////////////////////////////////////////////////// // From e397fa12eb11df51efb22cbcae1fb0830b0b142d Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 16:14:03 -0700 Subject: [PATCH 034/172] #18443 Support python embedding --- .../tools/core/ensemble_stat/ensemble_stat.cc | 110 ++++++-- met/src/tools/core/point_stat/point_stat.cc | 115 +++++--- .../other/plot_point_obs/plot_point_obs.cc | 143 ++++++---- met/src/tools/other/point2grid/point2grid.cc | 254 ++++++++++++++---- 4 files changed, 458 insertions(+), 164 deletions(-) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index fe5d160157..422c8d6f84 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -92,6 +92,11 @@ using namespace std; #include "nc_obs_util.h" #include "nc_point_obs_in.h" +#ifdef WITH_PYTHON +#include "data2d_nc_met.h" +#include "pointdata_python.h" +#endif + //////////////////////////////////////////////////////////////////////// static void process_command_line (int, char **); @@ -992,25 +997,59 @@ void process_point_obs(int i_nc) { << point_obs_file_list[i_nc] << "\n"; // Open the observation file as a NetCDF file. + bool status; + bool use_var_id = true; + bool use_arr_vars = false; + bool use_python = false; MetNcPointObsIn nc_point_obs; - if(!nc_point_obs.open(point_obs_file_list[i_nc].c_str())) { - nc_point_obs.close(); + MetPointData *met_point_obs = 0; +#ifdef WITH_PYTHON + MetPythonPointDataFile met_point_file; + string python_command = point_obs_file_list[i_nc]; + bool use_xarray = (0 == python_command.find(conf_val_python_xarray)); + use_python = use_xarray || (0 == python_command.find(conf_val_python_numpy)); + if (use_python) { + int offset = python_command.find("="); + if (offset == std::string::npos) { + mlog << Error << "\n" << method_name + << "trouble parsing the python command " << python_command << ".\n\n"; + exit(1); + } - mlog << Warning << "\n" << method_name - << "can't open observation netCDF file: " - << point_obs_file_list[i_nc] << "\n\n"; - return; - } + if(!met_point_file.open(python_command.substr(offset+1).c_str(), use_xarray)) { + met_point_file.close(); + mlog << Error << "\n" << method_name + << "trouble getting point observation file from python command " + << python_command << ".\n\n"; + exit(1); + } - // Read the dimensions and variables - nc_point_obs.read_dim_headers(); - nc_point_obs.check_nc(point_obs_file_list[i_nc].c_str(), method_name); // exit if missing dims/vars - nc_point_obs.read_obs_data_table_lookups(); + met_point_obs = met_point_file.get_met_point_data(); + } + else { +#endif + if(!nc_point_obs.open(point_obs_file_list[i_nc].c_str())) { + nc_point_obs.close(); + + mlog << Warning << "\n" << method_name + << "can't open observation netCDF file: " + << point_obs_file_list[i_nc] << "\n\n"; + return; + } + + // Read the dimensions and variables + nc_point_obs.read_dim_headers(); + nc_point_obs.check_nc(point_obs_file_list[i_nc].c_str(), method_name); // exit if missing dims/vars + nc_point_obs.read_obs_data_table_lookups(); + met_point_obs = (MetPointData *)&nc_point_obs; + use_var_id = nc_point_obs.is_using_var_id(); + use_arr_vars = nc_point_obs.is_using_obs_arr(); +#ifdef WITH_PYTHON + } +#endif - int hdr_count = nc_point_obs.get_hdr_cnt(); - int obs_count = nc_point_obs.get_obs_cnt(); - bool use_var_id = nc_point_obs.is_using_var_id(); - bool use_arr_vars = nc_point_obs.is_using_obs_arr(); + int hdr_count = met_point_obs->get_hdr_cnt(); + int obs_count = met_point_obs->get_obs_cnt(); mlog << Debug(2) << "Searching " << (obs_count) << " observations from " << (hdr_count) @@ -1028,17 +1067,23 @@ void process_point_obs(int i_nc) { ConcatString obs_qty_str; ConcatString var_name; StringArray var_names; - StringArray obs_qty_array = nc_point_obs.get_qty_data(); - if(use_var_id) var_names = nc_point_obs.get_var_names(); + StringArray obs_qty_array = met_point_obs->get_qty_data(); + if(use_var_id) var_names = met_point_obs->get_var_names(); for(int i_start=0; i_start DEF_NC_BUFFER_SIZE) - ? DEF_NC_BUFFER_SIZE : (obs_count-i_start); + int buf_size2 = (obs_count-i_start); + if (buf_size2 > DEF_NC_BUFFER_SIZE) buf_size2 = DEF_NC_BUFFER_SIZE; + +#ifdef WITH_PYTHON + if (use_python) + status = met_point_obs->get_point_obs_data()->fill_obs_buf( + buf_size2, i_start, (float *)obs_arr_block, obs_qty_idx_block); + else +#endif + status = nc_point_obs.read_obs_data(buf_size2, i_start, (float *)obs_arr_block, + obs_qty_idx_block, (char *)0); + if (!status) exit(1); - if (!nc_point_obs.read_obs_data(buf_size, i_start, (float *)obs_arr_block, - obs_qty_idx_block, (char *)0)) { - exit(1); - } // Process each observation in the file for(int i_offset=0; i_offsetget_header_offset(obs_arr); // Range check the header offset if(headerOffset < 0 || headerOffset >= hdr_count) { @@ -1065,16 +1110,21 @@ void process_point_obs(int i_nc) { // Read the corresponding header array for this observation // - the corresponding header type, header Station ID, and valid time - nc_point_obs.get_header(headerOffset, hdr_arr, hdr_typ_str, - hdr_sid_str, hdr_vld_str); +#ifdef WITH_PYTHON + if (use_python) + met_point_obs->get_header(headerOffset, hdr_arr, hdr_typ_str, hdr_sid_str, hdr_vld_str); + else +#endif + nc_point_obs.get_header(headerOffset, hdr_arr, hdr_typ_str, + hdr_sid_str, hdr_vld_str); // Read the header integer types - nc_point_obs.get_header_type(headerOffset, hdr_typ_arr); + met_point_obs->get_header_type(headerOffset, hdr_typ_arr); // Convert string to a unixtime hdr_ut = timestring_to_unix(hdr_vld_str.c_str()); - int grib_code = nc_point_obs.get_grib_code_or_var_index(obs_arr); + int grib_code = met_point_obs->get_grib_code_or_var_index(obs_arr); if (use_var_id && grib_code < var_names.n()) { var_name = var_names[grib_code]; } @@ -1097,6 +1147,10 @@ void process_point_obs(int i_nc) { } // end for i_start // Deallocate and clean up +#ifdef WITH_PYTHON + if (use_python) met_point_file.close(); + else +#endif nc_point_obs.close(); return; diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 549e6fce9f..4578d91a33 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -126,6 +126,11 @@ using namespace std; #include "nc_obs_util.h" #include "nc_point_obs_in.h" +#ifdef WITH_PYTHON +#include "data2d_nc_met.h" +#include "pointdata_python.h" +#endif + //////////////////////////////////////////////////////////////////////// #define BUFFER_SIZE (DEF_NC_BUFFER_SIZE/2) @@ -671,33 +676,67 @@ void process_obs_file(int i_nc) { // Open the observation file as a NetCDF file. // The observation file must be in NetCDF format as the // output of the PB2NC or ASCII2NC tool. + bool status; + bool use_var_id = true; + bool use_arr_vars = false; + bool use_python = false; MetNcPointObsIn nc_point_obs; - if( !nc_point_obs.open(obs_file[i_nc].c_str()) ) { - nc_point_obs.close(); + MetPointData *met_point_obs = 0; +#ifdef WITH_PYTHON + MetPythonPointDataFile met_point_file; + string python_command = obs_file[i_nc]; + bool use_xarray = (0 == python_command.find(conf_val_python_xarray)); + use_python = use_xarray || (0 == python_command.find(conf_val_python_numpy)); + if (use_python) { + int offset = python_command.find("="); + if (offset == std::string::npos) { + mlog << Error << "\n" << method_name + << "trouble parsing the python command " << python_command << ".\n\n"; + exit(1); + } - mlog << Warning << "\n" << method_name - << "can't open observation netCDF file: " - << obs_file[i_nc] << "\n\n"; - return; - } + if(!met_point_file.open(python_command.substr(offset+1).c_str(), use_xarray)) { + met_point_file.close(); + mlog << Error << "\n" << method_name + << "trouble getting point observation file from python command " + << python_command << ".\n\n"; + exit(1); + } - nc_point_obs.read_dim_headers(); - nc_point_obs.check_nc(obs_file[i_nc].c_str(), method_name); - nc_point_obs.read_obs_data_table_lookups(); + met_point_obs = met_point_file.get_met_point_data(); + } + else { +#endif + if( !nc_point_obs.open(obs_file[i_nc].c_str()) ) { + nc_point_obs.close(); + + mlog << Warning << "\n" << method_name + << "can't open observation netCDF file: " + << obs_file[i_nc] << "\n\n"; + return; + } + + nc_point_obs.read_dim_headers(); + nc_point_obs.check_nc(obs_file[i_nc].c_str(), method_name); + nc_point_obs.read_obs_data_table_lookups(); + met_point_obs = (MetPointData *)&nc_point_obs; + use_var_id = nc_point_obs.is_using_var_id(); + use_arr_vars = nc_point_obs.is_using_obs_arr(); +#ifdef WITH_PYTHON + } +#endif - bool use_var_id = nc_point_obs.is_using_var_id(); - int hdr_count = nc_point_obs.get_hdr_cnt(); - int obs_count = nc_point_obs.get_obs_cnt(); + int hdr_count = met_point_obs->get_hdr_cnt(); + int obs_count = met_point_obs->get_obs_cnt(); mlog << Debug(2) << "Searching " << obs_count << " observations from " << hdr_count << " messages.\n"; ConcatString var_name(""); - bool use_arr_vars = nc_point_obs.is_using_obs_arr(); StringArray var_names; - StringArray obs_qty_array = nc_point_obs.get_qty_data(); - if( use_var_id ) var_names = nc_point_obs.get_var_names(); + StringArray obs_qty_array = met_point_obs->get_qty_data(); + if( use_var_id ) var_names = met_point_obs->get_var_names(); int buf_size = ((obs_count > BUFFER_SIZE) ? BUFFER_SIZE : (obs_count)); int obs_qty_idx_block[buf_size]; @@ -706,17 +745,22 @@ void process_obs_file(int i_nc) { // Process each observation in the file int str_length, block_size; for(int i_block_start_idx=0; i_block_start_idx BUFFER_SIZE) block_size = BUFFER_SIZE; - - if (!nc_point_obs.read_obs_data(block_size, i_block_start_idx, - (float *)obs_arr_block, - obs_qty_idx_block, (char *)0)) { - exit(1); - } + int block_size2 = (obs_count - i_block_start_idx); + if (block_size2 > BUFFER_SIZE) block_size2 = BUFFER_SIZE; + +#ifdef WITH_PYTHON + if (use_python) + status = met_point_obs->get_point_obs_data()->fill_obs_buf( + block_size2, i_block_start_idx, (float *)obs_arr_block, obs_qty_idx_block); + else +#endif + status = nc_point_obs.read_obs_data(block_size2, i_block_start_idx, + (float *)obs_arr_block, + obs_qty_idx_block, (char *)0); + if (!status) exit(1); int hdr_idx; - for(int i_block_idx=0; i_block_idxget_header_offset(obs_arr); // Range check the header offset if(headerOffset < 0 || headerOffset >= hdr_count) { @@ -740,11 +784,16 @@ void process_obs_file(int i_nc) { // Read the corresponding header array for this observation // - the corresponding header type, header Station ID, and valid time - nc_point_obs.get_header(headerOffset, hdr_arr, hdr_typ_str, - hdr_sid_str, hdr_vld_str); +#ifdef WITH_PYTHON + if (use_python) + met_point_obs->get_header(headerOffset, hdr_arr, hdr_typ_str, hdr_sid_str, hdr_vld_str); + else +#endif + nc_point_obs.get_header(headerOffset, hdr_arr, hdr_typ_str, + hdr_sid_str, hdr_vld_str); // Store the variable name - int org_grib_code = nc_point_obs.get_grib_code_or_var_index(obs_arr); + int org_grib_code = met_point_obs->get_grib_code_or_var_index(obs_arr); int grib_code = org_grib_code; if (use_var_id && grib_code < var_names.n()) { var_name = var_names[grib_code]; @@ -773,7 +822,7 @@ void process_obs_file(int i_nc) { // and at the same vertical level. if(vflag && is_vgrd) { - if(!nc_point_obs.is_same_obs_values(obs_arr, prev_obs_arr)) { + if(!met_point_obs->is_same_obs_values(obs_arr, prev_obs_arr)) { mlog << Error << "\n" << method_name << "for observation index " << i_obs << ", when computing VL1L2 and/or VAL1L2 vector winds " @@ -801,12 +850,16 @@ void process_obs_file(int i_nc) { grid, var_name.c_str()); } - nc_point_obs.set_grib_code_or_var_index(obs_arr, org_grib_code); + met_point_obs->set_grib_code_or_var_index(obs_arr, org_grib_code); } } // end for i_block_start_idx // Deallocate and clean up +#ifdef WITH_PYTHON + if (use_python) met_point_file.close(); + else +#endif nc_point_obs.close(); return; diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs.cc b/met/src/tools/other/plot_point_obs/plot_point_obs.cc index 1ba1b9938b..af45a93641 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs.cc +++ b/met/src/tools/other/plot_point_obs/plot_point_obs.cc @@ -45,26 +45,11 @@ using namespace std; #include "plot_point_obs.h" -#include "nc_utils.h" -#include "vx_log.h" -#include "data_plane.h" #include "data_plane_plot.h" -#include "write_netcdf.h" -#include "vx_data2d.h" -#include "vx_data2d_factory.h" -#include "vx_data2d_grib.h" -#include "vx_data2d_nc_met.h" -#include "vx_data2d_nc_pinterp.h" -#include "vx_util.h" -#include "vx_cal.h" -#include "vx_grid.h" -#include "vx_math.h" -#include "vx_color.h" #include "vx_ps.h" #include "vx_pxm.h" #include "vx_render.h" #include "vx_plot_util.h" -#include "nc_obs_util.h" #include "nc_point_obs_in.h" //////////////////////////////////////////////////////////////////////// @@ -149,42 +134,76 @@ int main(int argc, char *argv[]) { void process_point_obs(const char *point_obs_filename) { int h, v, i_obs; - const char *method_name = "\nprocess_point_obs() -> "; - const char *method_name_s = "\nprocess_point_obs() "; + const char *method_name = "process_point_obs() -> "; + const char *method_name_s = "process_point_obs() "; // Open the netCDF point observation file mlog << Debug(1) << "Reading point observation file: " << point_obs_filename << "\n"; + bool status; + bool use_var_id = true; + bool use_obs_arr = false; + + bool use_python = false; MetNcPointObsIn nc_point_obs; - if(!nc_point_obs.open(point_obs_filename)) { - nc_point_obs.close(); + MetPointData *met_point_obs = 0; +#ifdef WITH_PYTHON + MetPythonPointDataFile met_point_file; + string python_command = point_obs_filename; + bool use_xarray = (0 == python_command.find(conf_val_python_xarray)); + use_python = use_xarray || (0 == python_command.find(conf_val_python_numpy)); + if (use_python) { + int offset = python_command.find("="); + if (offset == std::string::npos) { + mlog << Error << "\n" << method_name + << "trouble parsing the python command " << python_command << ".\n\n"; + exit(1); + } - mlog << Error << "\n" << method_name - << "trouble opening point observation file " - << point_obs_filename << ".\n\n"; + if(!met_point_file.open(python_command.substr(offset+1).c_str(), use_xarray)) { + met_point_file.close(); + mlog << Error << "\n" << method_name + << "trouble getting point observation file from python command " + << python_command << ".\n\n"; + exit(1); + } - exit(1); + met_point_obs = met_point_file.get_met_point_data(); } + else +#endif + { + if(!nc_point_obs.open(point_obs_filename)) { + nc_point_obs.close(); - // Read the dimensions and variables - nc_point_obs.read_dim_headers(); - nc_point_obs.check_nc(point_obs_filename, method_name_s); // exit if missing dims/vars - nc_point_obs.read_obs_data(); + mlog << Error << "\n" << method_name + << "trouble opening point observation file " + << point_obs_filename << ".\n\n"; - bool use_var_id = nc_point_obs.is_using_var_id(); + exit(1); + } - // Print warning about ineffective command line arguments - if(use_var_id && ivar.n() != 0) { - mlog << Warning << "\n" << method_name << "-gc option is ignored!\n\n"; - } - if(!use_var_id && svar.n() != 0) { - mlog << Warning << "\n" << method_name << "-obs_var option is ignored!\n\n"; - } + // Read the dimensions and variables + nc_point_obs.read_dim_headers(); + nc_point_obs.check_nc(point_obs_filename, method_name_s); // exit if missing dims/vars + nc_point_obs.read_obs_data(); + use_var_id = nc_point_obs.is_using_var_id(); + use_obs_arr = nc_point_obs.is_using_obs_arr(); - long nhdr_count = nc_point_obs.get_hdr_cnt(); - long nobs_count = nc_point_obs.get_obs_cnt(); + // Print warning about ineffective command line arguments + if(use_var_id && ivar.n() != 0) { + mlog << Warning << "\n" << method_name << "-gc option is ignored!\n\n"; + } + if(!use_var_id && svar.n() != 0) { + mlog << Warning << "\n" << method_name << "-obs_var option is ignored!\n\n"; + } + met_point_obs = (MetPointData *)&nc_point_obs; + } + + long nhdr_count = met_point_obs->get_hdr_cnt(); + long nobs_count = met_point_obs->get_obs_cnt(); mlog << Debug(2) << "Processing " << nobs_count << " observations at " << nhdr_count << " locations.\n"; @@ -192,8 +211,6 @@ void process_point_obs(const char *point_obs_filename) { // Get the corresponding header: // message type, staton_id, valid_time, and lat/lon/elv - bool use_obs_arr = nc_point_obs.is_using_obs_arr(); - int buf_size = (nobs_count > DEF_NC_BUFFER_SIZE) ? DEF_NC_BUFFER_SIZE : nobs_count; // Allocate space to store the data @@ -202,8 +219,17 @@ void process_point_obs(const char *point_obs_filename) { int obs_qty_block[buf_size]; float obs_arr_block[buf_size][OBS_ARRAY_LEN]; - if(use_var_id) var_list = nc_point_obs.get_var_names(); - qty_list = nc_point_obs.get_qty_data(); + if(use_var_id) var_list = met_point_obs->get_var_names(); + qty_list = met_point_obs->get_qty_data(); + + if (0 == qty_list.n()) { + mlog << Error << "\n" << method_name << "Missing quality marks\n\n"; + exit (1); + } + if (use_var_id && (0 == var_list.n())) { + mlog << Debug(1) << method_name << "Missing variable names\ns\n"; + exit (1); + } ConcatString hdr_typ_str; ConcatString hdr_sid_str; @@ -211,16 +237,21 @@ void process_point_obs(const char *point_obs_filename) { ConcatString obs_qty_str; for(int i_start=0; i_start DEF_NC_BUFFER_SIZE) ? - DEF_NC_BUFFER_SIZE : (nobs_count-i_start); - - if (!nc_point_obs.read_obs_data(buf_size, i_start, (float *)obs_arr_block, - obs_qty_block, (char *)0)) { - exit(1); - } + int buf_size2 = ((nobs_count-i_start) > DEF_NC_BUFFER_SIZE) ? + DEF_NC_BUFFER_SIZE : (nobs_count-i_start); + +#ifdef WITH_PYTHON + if (use_python) + status = met_point_obs->get_point_obs_data()->fill_obs_buf( + buf_size2, i_start, (float *)obs_arr_block, obs_qty_block); + else +#endif + status = nc_point_obs.read_obs_data(buf_size2, i_start, (float *)obs_arr_block, + obs_qty_block, (char *)0); + if (!status) exit(1); int typ_idx, sid_idx, vld_idx; - for(int i_offset=0; i_offsetget_header(h, hdr_arr, hdr_typ_str, hdr_sid_str, hdr_vld_str); + else +#endif + nc_point_obs.get_header(h, hdr_arr, hdr_typ_str, hdr_sid_str, hdr_vld_str); // Store data in an observation object Observation cur_obs( @@ -263,12 +299,15 @@ void process_point_obs(const char *point_obs_filename) { } // end for i_start // Clean up +#ifdef WITH_PYTHON + if (use_python) met_point_file.close(); + else +#endif nc_point_obs.close(); return; } - //////////////////////////////////////////////////////////////////////// void create_plot() { @@ -470,7 +509,7 @@ void create_plot() { if(use_flate) plot.end_flate(); mlog << Debug(2) - << "Finished plotting " << plot_count << " locations.\n" + << "Finished plotting " << plot_count << " locations for " << ps_file << ".\n" << "Skipped " << skip_count << " locations off the grid.\n"; plot.showpage(); diff --git a/met/src/tools/other/point2grid/point2grid.cc b/met/src/tools/other/point2grid/point2grid.cc index 7b840f08d9..f806023c11 100644 --- a/met/src/tools/other/point2grid/point2grid.cc +++ b/met/src/tools/other/point2grid/point2grid.cc @@ -43,6 +43,11 @@ using namespace std; #include "point2grid_conf_info.h" +#ifdef WITH_PYTHON +#include "data2d_nc_met.h" +#include "pointdata_python.h" +#endif + //////////////////////////////////////////////////////////////////////// static ConcatString program_name; @@ -53,6 +58,7 @@ static const int TYPE_OBS = 1; // MET Point Obs NetCDF (from xxx2nc) static const int TYPE_NCCF = 2; // CF NetCDF with time and lat/lon variables static const int TYPE_GOES = 5; static const int TYPE_GOES_ADP = 6; +static const int TYPE_PYTHON = 7; // MET Point Obs NetCDF from PYTHON static const InterpMthd DefaultInterpMthd = InterpMthd_UW_Mean; static const int DefaultInterpWdth = 2; @@ -120,14 +126,19 @@ static NcDim lon_dim ; static void process_command_line(int, char **); static void process_data_file(); static void process_point_file(NcFile *nc_in, MetConfig &config, - VarInfo *, const Grid fr_grid, const Grid to_grid); + VarInfo *, const Grid to_grid); +#ifdef WITH_PYTHON +static void process_point_python(string python_command, MetConfig &config, + VarInfo *vinfo, const Grid to_grid, bool use_xarray); +#endif static void process_point_nccf_file(NcFile *nc_in, MetConfig &config, - VarInfo *, Met2dDataFile *fr_mtddf, const Grid to_grid); + VarInfo *, Met2dDataFile *fr_mtddf, + const Grid to_grid); 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 write_nc_int(const DataPlane &dp, const Grid &grid, - const VarInfo *vinfo, const char *vname); + const VarInfo *vinfo, const char *vname); static void close_nc(); static void usage(); static void set_field(const StringArray &); @@ -265,11 +276,26 @@ void process_command_line(int argc, char **argv) { OutputFilename = cline[2]; // Check if the input file - if ( !file_exists(InputFilename.c_str()) ) { - mlog << Error << "\n" << method_name - << "file does not exist \"" << InputFilename << "\"\n\n"; - exit(1); + bool use_python = false; +#ifdef WITH_PYTHON + string python_command = InputFilename; + bool use_xarray = (0 == python_command.find(conf_val_python_xarray)); + use_python = use_xarray || (0 == python_command.find(conf_val_python_numpy)); + if (use_python) { + int offset = python_command.find("="); + if (offset == std::string::npos) { + mlog << Error << "\n" << method_name + << "trouble parsing the python command " << python_command << ".\n\n"; + exit(1); + } } + else +#endif + if ( !file_exists(InputFilename.c_str()) ) { + mlog << Error << "\n" << method_name + << "file does not exist \"" << InputFilename << "\"\n\n"; + exit(1); + } // Check for at least one configuration string if(FieldSA.n() < 1) { @@ -347,18 +373,42 @@ void process_data_file() { // Open the input file mlog << Debug(1) << "Reading data file: " << InputFilename << "\n"; - nc_in = open_ncfile(InputFilename.c_str()); - - // Get the obs type before opening NetCDF - int obs_type = get_obs_type(nc_in); - bool goes_data = (obs_type == TYPE_GOES || obs_type == TYPE_GOES_ADP); - - if (obs_type == TYPE_NCCF) setenv(nc_att_met_point_nccf, "yes", 1); - - // Read the input data file + bool goes_data = false; + bool use_python = false; + int obs_type = TYPE_UNKNOWN; Met2dDataFileFactory m_factory; Met2dDataFile *fr_mtddf = (Met2dDataFile *) 0; - fr_mtddf = m_factory.new_met_2d_data_file(InputFilename.c_str(), ftype); +#ifdef WITH_PYTHON + string python_command = InputFilename; + MetPointData *met_point_obs = 0; + bool use_xarray = (0 == python_command.find(conf_val_python_xarray)); + use_python = use_xarray || (0 == python_command.find(conf_val_python_numpy)); + if (use_python) { + int offset = python_command.find("="); + if (offset == std::string::npos) { + mlog << Error << "\n" << method_name + << "trouble parsing the python command " << python_command << ".\n\n"; + exit(1); + } + + python_command = python_command.substr(offset+1); + obs_type = TYPE_PYTHON; + fr_mtddf = new MetNcMetDataFile(); + } + else +#endif + { + nc_in = open_ncfile(InputFilename.c_str()); + + // Get the obs type before opening NetCDF + obs_type = get_obs_type(nc_in); + goes_data = (obs_type == TYPE_GOES || obs_type == TYPE_GOES_ADP); + + if (obs_type == TYPE_NCCF) setenv(nc_att_met_point_nccf, "yes", 1); + + // Read the input data file + fr_mtddf = m_factory.new_met_2d_data_file(InputFilename.c_str(), ftype); + } if(!fr_mtddf) { mlog << Error << "\n" << method_name @@ -384,7 +434,11 @@ void process_data_file() { // For python types read the first field to set the grid // Determine the "from" grid +#ifdef WITH_PYTHON + if (!use_python) fr_grid = fr_mtddf->grid(); +#else fr_grid = fr_mtddf->grid(); +#endif // Determine the "to" grid to_grid = parse_vx_grid(RGInfo, &fr_grid, &fr_grid); @@ -410,12 +464,17 @@ void process_data_file() { process_goes_file(nc_in, config, vinfo, fr_grid, to_grid); } else if (TYPE_OBS == obs_type) { - process_point_file(nc_in, config, vinfo, fr_grid, to_grid); + process_point_file(nc_in, config, vinfo, to_grid); } else if (TYPE_NCCF == obs_type) { process_point_nccf_file(nc_in, config, vinfo, fr_mtddf, to_grid); unsetenv(nc_att_met_point_nccf); } +#ifdef WITH_PYTHON + else if (TYPE_PYTHON == obs_type) { + process_point_python(python_command, config, vinfo, to_grid, use_xarray); + } +#endif else { mlog << Error << "\n" << method_name << "Please check the input file. Only supports GOES, MET point obs, " @@ -599,8 +658,8 @@ IntArray prepare_qc_array(const IntArray qc_flags, StringArray qc_tables) { //////////////////////////////////////////////////////////////////////// -void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, - const Grid fr_grid, const Grid to_grid) { +void process_point_met_data(MetPointData *met_point_obs, MetConfig &config, VarInfo *vinfo, + const Grid to_grid) { int nhdr, nobs; int nx, ny, var_count, to_count, var_count2; int idx, hdr_idx; @@ -616,8 +675,8 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, bool has_prob_thresh = !prob_cat_thresh.check(bad_data_double); unixtime requested_valid_time, valid_time; - static const char *method_name = "process_point_file() -> "; - static const char *method_name_s = "process_point_file()"; + static const char *method_name = "process_point_met_data() -> "; + static const char *method_name_s = "process_point_met_data()"; // Check for at least one configuration string if(FieldSA.n() < 1) { @@ -626,35 +685,29 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, usage(); } - MetNcPointObsIn nc_point_obs; - nc_point_obs.set_netcdf(nc_in, true); - // Read the dimensions and variables - nc_point_obs.read_dim_headers(); - nc_point_obs.check_nc(GET_NC_NAME_P(nc_in).c_str(), method_name_s); // exit if missing dims/vars - // Read all obs data to compute the cell mapping - nc_point_obs.read_obs_data(); - NcHeaderData header_data = nc_point_obs.get_header_data(); - NcPointObsData obs_data = nc_point_obs.get_point_obs_data(); +// MetNcPointObsIn nc_point_obs; + MetPointHeader *header_data = met_point_obs->get_header_data(); + MetPointObsData *obs_data = met_point_obs->get_point_obs_data(); - nhdr = nc_point_obs.get_hdr_cnt(); - nobs = nc_point_obs.get_obs_cnt(); + nhdr = met_point_obs->get_hdr_cnt(); + nobs = met_point_obs->get_obs_cnt(); bool empty_input = (nhdr == 0 && nobs == 0); - bool use_var_id = nc_point_obs.is_using_var_id(); + bool use_var_id = met_point_obs->is_using_var_id(); float *hdr_lats = new float[nhdr]; float *hdr_lons = new float[nhdr]; IntArray var_index_array; IntArray valid_time_array; - StringArray qc_tables = nc_point_obs.get_qty_data(); - StringArray var_names = nc_point_obs.get_var_names(); - StringArray hdr_valid_times = header_data.vld_array; + StringArray qc_tables = met_point_obs->get_qty_data(); + StringArray var_names = met_point_obs->get_var_names(); + StringArray hdr_valid_times = header_data->vld_array; hdr_valid_times.sort(); - nc_point_obs.get_lats(hdr_lats); - nc_point_obs.get_lons(hdr_lons); + met_point_obs->get_lats(hdr_lats); + met_point_obs->get_lons(hdr_lons); // Check the message types - prepare_message_types(header_data.typ_array); + prepare_message_types(header_data->typ_array); // Check and read obs_vid and obs_var if exists bool success_to_read = true; @@ -732,7 +785,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, else { bool not_found_grib_code = true; for (idx=0; idxobs_ids[idx]) { not_found_grib_code = false; break; } @@ -757,10 +810,10 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, log_msg << "GRIB codes: "; IntArray grib_codes; for (idx=0; idxobs_ids[idx])) { + grib_codes.add(obs_data->obs_ids[idx]); if (0 < idx) log_msg << ", "; - log_msg << obs_data.obs_ids[idx]; + log_msg << obs_data->obs_ids[idx]; } } } @@ -836,29 +889,29 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, var_count = var_count2 = to_count = 0; filtered_by_time = filtered_by_msg_type = filtered_by_qc = 0; for (idx=0; idx < nobs; idx++) { - if (var_idx_or_gc == obs_data.obs_ids[idx]) { + if (var_idx_or_gc == obs_data->obs_ids[idx]) { var_count2++; - hdr_idx = obs_data.obs_hids[idx]; + hdr_idx = obs_data->obs_hids[idx]; if (0 < valid_time_array.n() && - !valid_time_array.has(header_data.vld_idx_array[hdr_idx])) { + !valid_time_array.has(header_data->vld_idx_array[hdr_idx])) { filtered_by_time++; continue; } - if(!keep_message_type(header_data.typ_idx_array[hdr_idx])) { + if(!keep_message_type(header_data->typ_idx_array[hdr_idx])) { filtered_by_msg_type++; continue; } // Filter by QC flag - if (has_qc_flags && !qc_idx_array.has(obs_data.obs_qids[idx])) { + if (has_qc_flags && !qc_idx_array.has(obs_data->obs_qids[idx])) { filtered_by_qc++; continue; } var_index_array.add(idx); var_count++; - if (is_eq(obs_data.obs_vals[idx], 0.)) obs_count_zero_from++; + if (is_eq(obs_data->obs_vals[idx], 0.)) obs_count_zero_from++; else obs_count_non_zero_from++; } } @@ -869,7 +922,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, } cellMapping = new IntArray[nx * ny]; if( get_grid_mapping(to_grid, cellMapping, var_index_array, - obs_data.obs_hids, hdr_lats, hdr_lons) ) { + obs_data->obs_hids, hdr_lats, hdr_lons) ) { int from_index; IntArray cellArray; NumArray dataArray; @@ -905,7 +958,7 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, dataArray.extend(cellArray.n()); for (int dIdx=0; dIdxget_obs_val(from_index); if (is_bad_data(data_value)) continue; if(mlog.verbosity_level() >= 4) { @@ -1073,13 +1126,108 @@ void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, delete [] hdr_lats; delete [] hdr_lons; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void process_point_file(NcFile *nc_in, MetConfig &config, VarInfo *vinfo, + const Grid to_grid) { + int nhdr, nobs; + int nx, ny, var_count, to_count, var_count2; + int idx, hdr_idx; + int var_idx_or_gc; + int filtered_by_time, filtered_by_msg_type, filtered_by_qc; + ConcatString vname, vname_cnt, vname_mask; + DataPlane fr_dp, to_dp; + DataPlane cnt_dp, mask_dp; + DataPlane prob_dp, prob_mask_dp; + NcVar var_obs_gc, var_obs_var; + + clock_t start_clock = clock(); + bool has_prob_thresh = !prob_cat_thresh.check(bad_data_double); + + unixtime requested_valid_time, valid_time; + static const char *method_name = "process_point_file() -> "; + static const char *method_name_s = "process_point_file()"; + + // Check for at least one configuration string + if(FieldSA.n() < 1) { + mlog << Error << "\n" << method_name + << "The -field option must be used at least once!\n\n"; + usage(); + } + + MetNcPointObsIn nc_point_obs; + nc_point_obs.set_netcdf(nc_in, true); + // Read the dimensions and variables + nc_point_obs.read_dim_headers(); + nc_point_obs.check_nc(GET_NC_NAME_P(nc_in).c_str(), method_name_s); // exit if missing dims/vars + // Read all obs data to compute the cell mapping + nc_point_obs.read_obs_data(); + process_point_met_data(&nc_point_obs, config, vinfo, to_grid); + nc_point_obs.close(); mlog << Debug(LEVEL_FOR_PERFORMANCE) << method_name << "took " << (clock()-start_clock)/double(CLOCKS_PER_SEC) << " seconds\n"; +} + +//////////////////////////////////////////////////////////////////////// + +#ifdef WITH_PYTHON + +void process_point_python(string python_command, MetConfig &config, VarInfo *vinfo, + const Grid to_grid, bool use_xarray) { + int nhdr, nobs; + int nx, ny, var_count, to_count, var_count2; + int idx, hdr_idx; + int var_idx_or_gc; + int filtered_by_time, filtered_by_msg_type, filtered_by_qc; + ConcatString vname, vname_cnt, vname_mask; + DataPlane fr_dp, to_dp; + DataPlane cnt_dp, mask_dp; + DataPlane prob_dp, prob_mask_dp; + NcVar var_obs_gc, var_obs_var; + + clock_t start_clock = clock(); + bool has_prob_thresh = !prob_cat_thresh.check(bad_data_double); + + unixtime requested_valid_time, valid_time; + static const char *method_name = "process_point_python() -> "; + static const char *method_name_s = "process_point_python()"; + + // Check for at least one configuration string + if(FieldSA.n() < 1) { + mlog << Error << "\n" << method_name + << "The -field option must be used at least once!\n\n"; + usage(); + } + + MetPythonPointDataFile met_point_file; + if(!met_point_file.open(python_command.c_str(), use_xarray)) { + met_point_file.close(); + + mlog << Error << "\n" << method_name + << "trouble getting point observation file from python command " + << python_command << "\n\n"; + + exit(1); + } + + MetPointData *met_point_obs = met_point_file.get_met_point_data(); + process_point_met_data(met_point_obs, config, vinfo, to_grid); + + met_point_file.close(); + + mlog << Debug(LEVEL_FOR_PERFORMANCE) << method_name << "took " + << (clock()-start_clock)/double(CLOCKS_PER_SEC) << " seconds\n"; + return; } +#endif //////////////////////////////////////////////////////////////////////// @@ -1097,7 +1245,7 @@ void process_point_nccf_file(NcFile *nc_in, MetConfig &config, bool opt_all_attrs = false; Grid fr_grid = fr_mtddf->grid(); int from_size = fr_grid.nx() * fr_grid.ny(); - static const char *method_name = "process_point_file_with_latlon() -> "; + static const char *method_name = "process_point_nccf_file() -> "; NcVar var_lat = get_nc_var_lat(nc_in); NcVar var_lon = get_nc_var_lon(nc_in); From 315d3b433551948b99acb7e3b87eed85cef10237 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 28 Dec 2021 16:14:24 -0700 Subject: [PATCH 035/172] #1844 Initial release --- .../libcode/vx_pointdata_python/Makefile.am | 19 + .../pointdata_from_array.cc | 659 ++++++++++++++++++ .../pointdata_from_array.h | 59 ++ .../vx_pointdata_python/pointdata_python.cc | 290 ++++++++ .../vx_pointdata_python/pointdata_python.h | 112 +++ .../vx_pointdata_python/python_pointdata.cc | 588 ++++++++++++++++ .../vx_pointdata_python/python_pointdata.h | 80 +++ 7 files changed, 1807 insertions(+) create mode 100644 met/src/libcode/vx_pointdata_python/Makefile.am create mode 100644 met/src/libcode/vx_pointdata_python/pointdata_from_array.cc create mode 100644 met/src/libcode/vx_pointdata_python/pointdata_from_array.h create mode 100644 met/src/libcode/vx_pointdata_python/pointdata_python.cc create mode 100644 met/src/libcode/vx_pointdata_python/pointdata_python.h create mode 100644 met/src/libcode/vx_pointdata_python/python_pointdata.cc create mode 100644 met/src/libcode/vx_pointdata_python/python_pointdata.h diff --git a/met/src/libcode/vx_pointdata_python/Makefile.am b/met/src/libcode/vx_pointdata_python/Makefile.am new file mode 100644 index 0000000000..c48c07e2df --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/Makefile.am @@ -0,0 +1,19 @@ +## @start 1 +## Makefile.am -- Process this file with automake to produce Makefile.in +## @end 1 + +MAINTAINERCLEANFILES = Makefile.in + +# Include the project definitions + +include ${top_srcdir}/Make-include + +# The library + +noinst_LIBRARIES = libvx_pointdata_python.a +libvx_pointdata_python_a_SOURCES = \ + pointdata_python.h pointdata_python.cc \ + pointdata_from_array.h pointdata_from_array.cc \ + python_pointdata.h python_pointdata.cc +libvx_pointdata_python_a_CPPFLAGS = ${MET_CPPFLAGS} -I../vx_python2_utils ${MET_PYTHON_CC} $(MET_PYTHON_LD) + diff --git a/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc b/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc new file mode 100644 index 0000000000..b3d6cd84fe --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc @@ -0,0 +1,659 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +//////////////////////////////////////////////////////////////////////// + + +#include "string.h" + +#include "vx_python3_utils.h" +#include "vx_statistics.h" +#include "check_endian.h" + +#include "pointdata_from_array.h" + +//////////////////////////////////////////////////////////////////////// + +static const int api_delug_level = 11; + +//////////////////////////////////////////////////////////////////////// + + +template +void load_numpy (void * buf, + const int n, + const int data_endian, + void (*shuf)(void *), + float * out) +{ + +bool need_swap = (shuf != 0) && (native_endian != data_endian); + +int j, x, y, r, c; +T * u = (T *) buf; +T value; + +for (j=0; j +void load_numpy (void * buf, + const int n, + const int data_endian, + void (*shuf)(void *), + int * out) +{ + +const char *method_name = "load_numpy(int *) "; +bool need_swap = (shuf != 0) && (native_endian != data_endian); + +int j; +T * u = (T *) buf; +T value; + +for (j=0; j +void load_numpy_int (void * buf, + const int n, + const int data_endian, + void (*shuf)(void *), + IntArray *out) +{ + +const char *method_name = "load_numpy_int(IntArray *) "; +bool need_swap = (shuf != 0) && (native_endian != data_endian); + +int j; +T * u = (T *) buf; +T value; + +out->extend(n); + +for (j=0; jadd((int)value); + + mlog << Debug(api_delug_level) << method_name << " [" << j << "] value=" << value << "\n"; +} // for j + + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +template +void load_numpy_num (void * buf, + const int n, + const int data_endian, + void (*shuf)(void *), + NumArray *out) +{ + +const char *method_name = "load_numpy_num(NumArray *) "; +bool need_swap = (shuf != 0) && (native_endian != data_endian); + +int j; +T * u = (T *) buf; +T value; + +out->extend(n); + +for (j=0; jadd((float)value); + + mlog << Debug(api_delug_level) << method_name << "[" << j << "] value=" << value << "\n"; +} // for j + + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool pointdata_from_np_array(Python3_Numpy & np, float * data_out) +{ + +const char *method_name = "pointdata_from_np_array(float) -> "; + + // + // make sure it's a 1D array + // + +if ( np.n_dims() != 1 ) { + + mlog << Error << "\n" << method_name + << "data array is not 1-dimensional! ... " + << "(dim = " << (np.n_dims()) << ")\n\n"; + + exit ( 1 ); + + +} + +int n = np.dim(0); + + + // + // load the data + // + +const ConcatString dtype = np.dtype(); + + // 1 byte integers + + if ( dtype == "|i1" ) load_numpy (np.buffer(), n, little_endian, 0, data_out); +else if ( dtype == "|u1" ) load_numpy (np.buffer(), n, little_endian, 0, data_out); + + // 2 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); + +else if ( dtype == ">i2" ) load_numpy (np.buffer(), n, big_endian, shuffle_2, data_out); +else if ( dtype == ">u2" ) load_numpy (np.buffer(), n, big_endian, shuffle_2, data_out); + + // 4 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); + +else if ( dtype == ">i4" ) load_numpy (np.buffer(), n, big_endian, shuffle_4, data_out); +else if ( dtype == ">u4" ) load_numpy (np.buffer(), n, big_endian, shuffle_4, data_out); + + // 8 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); + +else if ( dtype == ">i8" ) load_numpy (np.buffer(), n, big_endian, shuffle_8, data_out); +else if ( dtype == ">u8" ) load_numpy (np.buffer(), n, big_endian, shuffle_8, data_out); + + // single precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == ">f4" ) load_numpy (np.buffer(), n, big_endian, shuffle_4, data_out); + + // double precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == ">f8" ) load_numpy (np.buffer(), n, big_endian, shuffle_8, data_out); + + // + // nope ... the only other numerical data type for numpy arrays + // is single or double precision complex numbers, and + // we're not supporting those at this time + // + +else { + + mlog << Error << "\n" << method_name + << "unsupported data type \"" << dtype << "\"\n\n"; + + exit ( 1 ); + +} + + //////////////////// + + + // + // done + // + +return ( true ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool pointdata_from_np_array(Python3_Numpy & np, int * data_out) +{ + +const char *method_name = "pointdata_from_np_array(int) -> "; + + // + // make sure it's a 1D array + // + +if ( np.n_dims() != 1 ) { + + mlog << Error << "\n" << method_name + << "data array is not 1-dimensional! ... " + << "(dim = " << (np.n_dims()) << ")\n\n"; + + exit ( 1 ); + + +} + +int n = np.dim(0); + + + // + // load the data + // + +const ConcatString dtype = np.dtype(); + + // 1 byte integers + + if ( dtype == "|i1" ) load_numpy (np.buffer(), n, little_endian, 0, data_out); +else if ( dtype == "|u1" ) load_numpy (np.buffer(), n, little_endian, 0, data_out); + + // 2 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); + +else if ( dtype == ">i2" ) load_numpy (np.buffer(), n, big_endian, shuffle_2, data_out); +else if ( dtype == ">u2" ) load_numpy (np.buffer(), n, big_endian, shuffle_2, data_out); + + // 4 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); + +else if ( dtype == ">i4" ) load_numpy (np.buffer(), n, big_endian, shuffle_4, data_out); +else if ( dtype == ">u4" ) load_numpy (np.buffer(), n, big_endian, shuffle_4, data_out); + + // 8 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); + +else if ( dtype == ">i8" ) load_numpy (np.buffer(), n, big_endian, shuffle_8, data_out); +else if ( dtype == ">u8" ) load_numpy (np.buffer(), n, big_endian, shuffle_8, data_out); + + // single precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == ">f4" ) load_numpy (np.buffer(), n, big_endian, shuffle_4, data_out); + + // double precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == ">f8" ) load_numpy (np.buffer(), n, big_endian, shuffle_8, data_out); + + // + // nope ... the only other numerical data type for numpy arrays + // is single or double precision complex numbers, and + // we're not supporting those at this time + // + +else { + + mlog << Error << "\n" << method_name + << "unsupported data type \"" << dtype << "\"\n\n"; + + exit ( 1 ); + +} + + //////////////////// + + + // + // done + // + +return ( true ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool pointdata_from_np_array(Python3_Numpy & np, IntArray *data_out) +{ + +const char *method_name = "pointdata_from_np_array(IntArray) -> "; + + // + // make sure it's a 1D array + // + +if ( np.n_dims() != 1 ) { + + mlog << Error << "\n" << method_name + << "data array is not 1-dimensional! ... " + << "(dim = " << (np.n_dims()) << ")\n\n"; + + exit ( 1 ); + + +} + +int n = np.dim(0); + + + // + // load the data + // + +IntArray data; +const ConcatString dtype = np.dtype(); + + // 1 byte integers + + if ( dtype == "|i1" ) load_numpy_int (np.buffer(), n, little_endian, 0, data_out); +else if ( dtype == "|u1" ) load_numpy_int (np.buffer(), n, little_endian, 0, data_out); + + // 2 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); + +else if ( dtype == ">i2" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_2, data_out); +else if ( dtype == ">u2" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_2, data_out); + + // 4 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); + +else if ( dtype == ">i4" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_4, data_out); +else if ( dtype == ">u4" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_4, data_out); + + // 8 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); + +else if ( dtype == ">i8" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_8, data_out); +else if ( dtype == ">u8" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_8, data_out); + + // single precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == ">f4" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_4, data_out); + + // double precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == ">f8" ) load_numpy_int (np.buffer(), n, big_endian, shuffle_8, data_out); + + // + // nope ... the only other numerical data type for numpy arrays + // is single or double precision complex numbers, and + // we're not supporting those at this time + // + +else { + + mlog << Error << "\n" << method_name + << "unsupported data type \"" << dtype << "\"\n\n"; + + exit ( 1 ); + +} + + //////////////////// + + + // + // done + // + +return ( true ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool pointdata_from_np_array(Python3_Numpy & np, NumArray *data_out) +{ + +const char *method_name = "pointdata_from_np_array(NumArray) -> "; + + // + // make sure it's a 1D array + // + +if ( np.n_dims() != 1 ) { + + mlog << Error << "\n" << method_name + << "data array is not 1-dimensional! ... " + << "(dim = " << (np.n_dims()) << ")\n\n"; + + exit ( 1 ); + + +} + +int n = np.dim(0); + + + // + // load the data + // + +NumArray data; +const ConcatString dtype = np.dtype(); + + // 1 byte integers + + if ( dtype == "|i1" ) load_numpy_num (np.buffer(), n, little_endian, 0, data_out); +else if ( dtype == "|u1" ) load_numpy_num (np.buffer(), n, little_endian, 0, data_out); + + // 2 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_2, data_out); + +else if ( dtype == ">i2" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_2, data_out); +else if ( dtype == ">u2" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_2, data_out); + + // 4 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); + +else if ( dtype == ">i4" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_4, data_out); +else if ( dtype == ">u4" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_4, data_out); + + // 8 byte integers + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); + +else if ( dtype == ">i8" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_8, data_out); +else if ( dtype == ">u8" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_8, data_out); + + // single precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_4, data_out); +else if ( dtype == ">f4" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_4, data_out); + + // double precision floats + +else if ( dtype == " (np.buffer(), n, little_endian, shuffle_8, data_out); +else if ( dtype == ">f8" ) load_numpy_num (np.buffer(), n, big_endian, shuffle_8, data_out); + + // + // nope ... the only other numerical data type for numpy arrays + // is single or double precision complex numbers, and + // we're not supporting those at this time + // + +else { + + mlog << Error << "\n" << method_name + << "unsupported data type \"" << dtype << "\"\n\n"; + + exit ( 1 ); + +} + + //////////////////// + + + // + // done + // + +return ( true ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool pointdata_from_str_array(PyObject *data_array, StringArray *data_out) +{ + +//const char *method_name = "pointdata_from_str_array(StringArray) -> "; + +StringArray a = pyobject_as_string_array(data_array); +data_out->clear(); +data_out->add(a); + + //////////////////// + + + // + // done + // + +return ( true ); + +} + + +//////////////////////////////////////////////////////////////////////// + + // + // we just grab the numpy array and the attributes dictionary + // + // from the xarray DataArray object, and then hand them + // + // off to pointdata_from_numpy_array + // + +bool pointdata_from_xarray(PyObject * data_array, float *data_out) +{ + +Python3_Numpy np; +PyObject *numpy_array = PyObject_GetAttrString(data_array, data_attr_name); + + ///////////////////// + +np.set(numpy_array); + +bool status = pointdata_from_np_array(np, data_out); + + // + // done + // + +return ( status ); + +} + + +//////////////////////////////////////////////////////////////////////// + + // + // we just grab the numpy array and the attributes dictionary + // + // from the xarray DataArray object, and then hand them + // + // off to pointdata_from_numpy_array + // + +bool pointdata_from_xarray(PyObject * data_array, int *data_out) +{ + +Python3_Numpy np; +PyObject *numpy_array = PyObject_GetAttrString(data_array, data_attr_name); + + + ///////////////////// + + +np.set(numpy_array); + +bool status = pointdata_from_np_array(np, data_out); + + // + // done + // + +return ( status ); + +} + + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_pointdata_python/pointdata_from_array.h b/met/src/libcode/vx_pointdata_python/pointdata_from_array.h new file mode 100644 index 0000000000..bec9380705 --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/pointdata_from_array.h @@ -0,0 +1,59 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 __MET_POINTDATA_FROM_ARRAY_H__ +#define __MET_POINTDATA_FROM_ARRAY_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include "met_point_data.h" + +#include "python3_dict.h" +#include "python3_numpy.h" + + +extern "C" { + +#include "Python.h" + +} + + +//////////////////////////////////////////////////////////////////////// + +static const char data_attr_name [] = "values"; + +//////////////////////////////////////////////////////////////////////// + + +extern bool pointdata_from_np_array(Python3_Numpy & np, int * data_out); +extern bool pointdata_from_np_array(Python3_Numpy & np, float * data_out); +extern bool pointdata_from_np_array(Python3_Numpy & np, IntArray *data_out); +extern bool pointdata_from_np_array(Python3_Numpy & np, NumArray *data_out); +extern bool pointdata_from_str_array(PyObject *data_array, StringArray *data_out); + + +extern bool pointdata_from_xarray(PyObject *data_array, int *data_out); +extern bool pointdata_from_xarray(PyObject *data_array, float *data_out); +extern bool pointdata_from_xarray(PyObject *data_array, IntArray &data_out); +extern bool pointdata_from_xarray(PyObject *data_array, NumArray &data_out); +extern bool pointdata_from_xarray(PyObject *data_array, StringArray &data_out); + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MET_POINTDATA_FROM_NUMPY_ARRAY_H__ */ + + +//////////////////////////////////////////////////////////////////////// + diff --git a/met/src/libcode/vx_pointdata_python/pointdata_python.cc b/met/src/libcode/vx_pointdata_python/pointdata_python.cc new file mode 100644 index 0000000000..846966a6f1 --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/pointdata_python.cc @@ -0,0 +1,290 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include + +#include "pointdata_python.h" +#include "pointdata_from_array.h" +#include "vx_python3_utils.h" + +#include "vx_math.h" +#include "vx_log.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class MetPythonPointDataFile + // + + +//////////////////////////////////////////////////////////////////////// + + +MetPythonPointDataFile::MetPythonPointDataFile() + +{ + +python_init_from_scratch(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +MetPythonPointDataFile::~MetPythonPointDataFile() + +{ + +close(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +MetPythonPointDataFile::MetPythonPointDataFile(const MetPythonPointDataFile &) + +{ + +mlog << Error << "\nMetPythonPointDataFile::MetPythonPointDataFile(const MetPythonPointDataFile &) -> " + << "should never be called!\n\n"; + +exit ( 1 ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +MetPythonPointDataFile & MetPythonPointDataFile::operator=(const MetPythonPointDataFile &) + +{ + +mlog << Error << "\nMetPythonPointDataFile::operator=(const MetPythonPointDataFile &) -> " + << "should never be called!\n\n"; + +exit ( 1 ); + +return ( * this ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void MetPythonPointDataFile::python_init_from_scratch() + +{ + +PythonCommand.clear(); +//met_data.clear(); + +close(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void MetPythonPointDataFile::close() + +{ + +met_data.clear(); + + // + // Don't reset the Type field + // Don't reset the PythonCommand + // + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + +/* +void MetPythonPointDataFile::set_type(const GrdFileType t) + +{ + +Type = t; + +return; + +} +*/ + +//////////////////////////////////////////////////////////////////////// + + +bool MetPythonPointDataFile::open(const char * cur_command, bool use_xarray) + +{ + +close(); + +ConcatString full_path, file_name; +int i, file_argc; +char **file_argv = (char **) 0; // allocated +StringArray sa; +const char *method_name = "MetPythonPointDataFile::open() "; + + // + // Store the PythonCommand that is being run + // + +PythonCommand = cur_command; + + // + // parse and store argc and argv + // + +sa = PythonCommand.split(" "); + +file_argc = sa.n_elements(); + +if ( file_argc > 0 ) { + file_argv = new char * [ file_argc ]; + char a_var_name[512+1]; + + for ( i=0; idump(out, depth + 1); + +} else { + + out << prefix << "No Grid!\n"; + +} +*/ + // + // done + // + +out.flush(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// +/* + +bool MetPythonPointDataFile::data_ok(int x, int y) const + +{ + +//const double value = get(x, y); + +//return ( !is_bad_data(value) ); +return true; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void MetPythonPointDataFile::data_minmax(double & data_min, double & data_max) const + +{ + +//Plane.data_range(data_min, data_max); + +return; + +} +*/ + +//////////////////////////////////////////////////////////////////////// + + +MetPointDataPython *MetPythonPointDataFile::get_met_point_data() + +{ + +return &met_data; + +} + + +//////////////////////////////////////////////////////////////////////// + diff --git a/met/src/libcode/vx_pointdata_python/pointdata_python.h b/met/src/libcode/vx_pointdata_python/pointdata_python.h new file mode 100644 index 0000000000..22b32c7f52 --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/pointdata_python.h @@ -0,0 +1,112 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 __MET_VX_POINTDATA_PYTHON_H__ +#define __MET_VX_POINTDATA_PYTHON_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include "data_plane.h" +#include "data_class.h" +#include "two_to_one.h" + +#include "python_pointdata.h" // the main access point +#include "pointdata_from_array.h" // takes an NumPy array or xarray DataArray + +#include "global_python.h" + + +//////////////////////////////////////////////////////////////////////// + + +//class MetPythonPointDataFile : public Met2dDataFile { +class MetPythonPointDataFile { + + private: + + void python_init_from_scratch(); + + MetPythonPointDataFile(const MetPythonPointDataFile &); + MetPythonPointDataFile & operator=(const MetPythonPointDataFile &); + + ConcatString PythonCommand; + + MetPointDataPython met_data; + + //VarInfoPython VInfo; + + //GrdFileType Type; // FileType_Python_Xarray or FileType_Python_Numpy + + public: + + MetPythonPointDataFile(); + ~MetPythonPointDataFile(); + + + // + // set stuff + // + + //void set_type(const GrdFileType); + + // + // get stuff + // + +// GrdFileType file_type() const; + +// double operator () (int x, int y) const; + + //double get (int x, int y) const; + +// bool data_ok (int x, int y) const; + +// void data_minmax (double & data_min, double & data_max) const; + + // + // do stuff + // + + bool open(const char * cur_command, bool use_xarray); + + void close(); + + + void dump (ostream &, int depth = 0) const; + + //MetPointData get_met_point_data(); + MetPointDataPython *get_met_point_data(); + + //int data_plane_array(VarInfo &, DataPlaneArray &); + + //bool met_point_data(MetPointData &); + +}; + + +//////////////////////////////////////////////////////////////////////// + + +//inline double MetPythonPointDataFile::operator () (int x, int y) const { return ( get(x, y) ); } +//inline GrdFileType MetPythonPointDataFile::file_type () const { return ( Type ); } + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MET_VX_POINTDATA_PYTHON_H__ */ + + +//////////////////////////////////////////////////////////////////////// + diff --git a/met/src/libcode/vx_pointdata_python/python_pointdata.cc b/met/src/libcode/vx_pointdata_python/python_pointdata.cc new file mode 100644 index 0000000000..0712bbb13a --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/python_pointdata.cc @@ -0,0 +1,588 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +//////////////////////////////////////////////////////////////////////// + + +#include "vx_python3_utils.h" +#include "python_pointdata.h" +#include "pointdata_from_array.h" +#include "vx_util.h" + + +#include "global_python.h" +#include "wchar_argv.h" + +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// + + +static bool straight_python_point_data(const char * script_name, + int script_argc, char ** script_argv, + const bool use_xarray, MetPointDataPython &met_pd_out); + +//////////////////////////////////////////////////////////////////////// + +template +static void set_array_from_python(PyObject *python_data, const char *python_key, T *out, bool required=true) { + const char *method_name = "set_array_from_python(T *) -> "; + PyObject *numpy_array_obj = PyDict_GetItemString (python_data, python_key); + if (numpy_array_obj) { + Python3_Numpy np; + np.set(numpy_array_obj); + pointdata_from_np_array(np, out); + mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object\n"; + } + else { + if (required) { + mlog << Error << "\n" << method_name + << "error getting the point data by the key (" << python_key << ") from python object\n\n"; + exit (1); + } + else mlog << Debug(3) << method_name + << "not exists the point data (" << python_key << ") from python object\n"; + } +} + +/* +static void set_array_from_python(PyObject *python_data, const char *python_key, int *out, bool required=true) { + const char *method_name = "set_array_from_python(T *) -> "; + PyObject *numpy_array_obj = PyDict_GetItemString (python_data, python_key); + if (numpy_array_obj) { + Python3_Numpy np; +mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object - before\n"; + np.set(numpy_array_obj); +mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object - after np.set\n"; + pointdata_from_np_array(np, out); + mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object\n"; + } + else { + if (required) { + mlog << Error << "\n" << method_name + << "error getting the point data by the key (" << python_key << ") from python object\n\n"; + exit (1); + } + else mlog << Debug(3) << method_name + << "not exists the point data (" << python_key << ") from python object\n"; + } +} +*/ + +/* +static void set_array_from_python(PyObject *python_data, const char *python_key, int *out, bool required=true) { + const char *method_name = "set_array_from_python(int *) -> "; + PyObject *numpy_array_obj = PyDict_GetItemString (python_data, python_key); + if (numpy_array_obj) { + Python3_Numpy np; + np.set(numpy_array_obj); + pointdata_from_np_array(np, out); + } + else if (required) { + mlog << Error << "\nset_array_from_python(int *) -> " + << "error getting member (" << python_key << ") from python object\"\n\n"; + exit (1); + } + else mlog << Debug(3) << method_name + << "not exists the point data (" << python_key << ") from python object\n"; +} + +//////////////////////////////////////////////////////////////////////// + +static void set_array_from_python(PyObject *python_data, const char *python_key, float *out, bool required=true) { + const char *method_name = "set_array_from_python(float *) -> "; + PyObject *numpy_array_obj = PyDict_GetItemString (python_data, python_key); + if (numpy_array_obj) { + Python3_Numpy np; + np.set(numpy_array_obj); + pointdata_from_np_array(np, out); + mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object\n"; + } + else if (required) { + mlog << Error << "\n" << method_name + << "error getting member (" << python_key << ") from python object\"\n\n"; + exit (1); + } + else mlog << Debug(3) << method_name + << "not exists the point data (" << python_key << ") from python object\n"; +} +*/ +//////////////////////////////////////////////////////////////////////// + +/* +static void set_met_array_from_python(PyObject *python_data, const char *python_key, IntArray *out, bool required=true) { + const char *method_name = "set_met_array_from_python(IntArray *) -> "; + PyObject *numpy_array_obj = PyDict_GetItemString (python_data, python_key); + if (numpy_array_obj) { + Python3_Numpy np; + np.set(numpy_array_obj); + pointdata_from_np_array(np, out); + mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object\n"; + } + else if (required) { + mlog << Error << "\n" << method_name + << "error getting member (" << python_key << ") from python object\"\n\n"; + exit (1); + } + else mlog << Debug(3) << method_name + << "not exists the point data (" << python_key << ") from python object\n"; +} +*/ +/* +//////////////////////////////////////////////////////////////////////// + +static void set_met_array_from_python(PyObject *python_data, const char *python_key, NumArray &out) { + PyObject *numpy_array_obj = PyDict_GetItemString (python_data, python_key); + if (numpy_array_obj) { + Python3_Numpy np; + np.set(numpy_array_obj); + pointdata_from_np_array(np, out); + } + else { + mlog << Error << "\nset_array_from_python(NumArray) -> " + << "error getting member (" << python_key << ") from python object\"\n\n"; + exit (1); + } +} +*/ +//////////////////////////////////////////////////////////////////////// + +static void set_str_array_from_python(PyObject *python_data, const char *python_key, StringArray *out) { + const char *method_name = "set_met_array_from_python(StringArray *) -> "; + PyObject *str_array_obj = PyDict_GetItemString (python_data, python_key); + if (str_array_obj) { + pointdata_from_str_array(str_array_obj, out); + mlog << Debug(7) << method_name + << "get the point data for " << python_key << " from python object\n"; + } + else { + mlog << Error << "\n" << method_name + << "error getting member (" << python_key << ") from python object\"\n\n"; + exit (1); + } +} + + +//////////////////////////////////////////////////////////////////////// + + +bool python_point_data(const char * script_name, int script_argc, char ** script_argv, + const bool use_xarray, MetPointDataPython &met_pd_out) + +{ + +bool status = straight_python_point_data(script_name, script_argc, script_argv, + use_xarray, met_pd_out); + +return ( status ); + +} + +//////////////////////////////////////////////////////////////////////// + + +bool straight_python_point_data(const char * script_name, int script_argc, char ** script_argv, + const bool use_xarray, MetPointDataPython &met_pd_out) +{ + +int int_value; +PyObject * module_obj = 0; +PyObject * module_dict_obj = 0; +PyObject * python_key = 0; +PyObject * python_value = 0; +PyObject * numpy_array_obj = 0; +PyObject * python_met_point_data = 0; +ConcatString cs, user_dir, user_base; +const char *method_name = "straight_python_point_data -> "; +const char *method_name_s = "straight_python_point_data()"; + +mlog << Debug(3) << "Running user's python script (" + << script_name << ").\n"; + +cs = script_name; +user_dir = cs.dirname(); +user_base = cs.basename(); + +Wchar_Argv wa; + +wa.set(script_argc, script_argv); + + // + // if the global python object has already been initialized, + // we need to reload the module + // + +bool do_reload = GP.is_initialized; + +GP.initialize(); + + // + // start up the python interpreter + // + +if ( PyErr_Occurred() ) { + + PyErr_Print(); + + mlog << Warning << "\n" << method_name + << "an error occurred initializing python\n\n"; + + return ( false ); + +} + + // + // set the arguments + // + +run_python_string("import os"); +run_python_string("import sys"); + +ConcatString command; + +command << cs_erase + << "sys.path.append(\"" + << user_dir + << "\")"; + +run_python_string(command.text()); + +if ( script_argc > 0 ) { + + PySys_SetArgv (wa.wargc(), wa.wargv()); + +} + + // + // import the python script as a module + // + +module_obj = PyImport_ImportModule (user_base.c_str()); + + // + // if needed, reload the module + // + +if ( do_reload ) { + + module_obj = PyImport_ReloadModule (module_obj); + +} + +if ( PyErr_Occurred() ) { + + PyErr_Print(); + + mlog << Warning << "\n" << method_name + << "an error occurred importing module \"" + << script_name << "\"\n\n"; + + return ( false ); + +} + +if ( ! module_obj ) { + + mlog << Warning << "\n" << method_name + << "error running python script \"" + << script_name << "\"\n\n"; + + return ( false ); + +} + + // + // get the namespace for the module (as a dictionary) + // + +module_dict_obj = PyModule_GetDict (module_obj); + + // + // get handles to the objects of interest from the module_dict + // + +python_met_point_data = PyDict_GetItemString (module_dict_obj, python_key_point_data); + +python_value = PyDict_GetItemString (python_met_point_data, python_use_var_id); + +bool use_var_id = pyobject_as_bool(python_value); +met_pd_out.set_use_var_id(use_var_id); + + +python_value = PyDict_GetItemString (python_met_point_data, python_key_nhdr); + +int_value = pyobject_as_int(python_value); +met_pd_out.set_hdr_cnt(int_value); + +python_value = PyDict_GetItemString (python_met_point_data, python_key_nobs); +int_value = pyobject_as_int(python_value); + +met_pd_out.allocate(int_value); + +MetPointObsData *obs_data = met_pd_out.get_point_obs_data(); +MetPointHeader *header_data = met_pd_out.get_header_data(); + +if ( use_xarray ) { + + PyObject * data_array_obj = 0; + + // look up the data array variable name from the dictionary + + data_array_obj = PyDict_GetItemString (python_met_point_data, numpy_array_hdr_typ); + + if ( ! data_array_obj ) { + + mlog << Warning << "\n" << method_name + << "trouble reading data from \"" + << script_name << "\"\n\n"; + + return ( false ); + } + + //pointdata_from_xarray(data_array_obj, &header_data.hdr_typ); + +} else { // numpy array & dict + + // look up the data array variable name from the dictionary + +/* + set_met_array_from_python(python_met_point_data, numpy_array_hdr_typ, header_data->typ_idx_array); + set_met_array_from_python(python_met_point_data, numpy_array_hdr_sid, header_data->sid_idx_array); + set_met_array_from_python(python_met_point_data, numpy_array_hdr_vld, header_data->vld_idx_array); + //IntArray vld_num_array; // number array for valid time + + set_met_array_from_python(python_met_point_data, numpy_array_hdr_lat, header_data->lat_array); + set_met_array_from_python(python_met_point_data, numpy_array_hdr_lon, header_data->lon_array); + set_met_array_from_python(python_met_point_data, numpy_array_hdr_elv, header_data->elv_array); +*/ + set_array_from_python(python_met_point_data, numpy_array_hdr_typ, &header_data->typ_idx_array); + set_array_from_python(python_met_point_data, numpy_array_hdr_sid, &header_data->sid_idx_array); + set_array_from_python(python_met_point_data, numpy_array_hdr_vld, &header_data->vld_idx_array); + set_array_from_python(python_met_point_data, numpy_array_hdr_lat, &header_data->lat_array); + set_array_from_python(python_met_point_data, numpy_array_hdr_lon, &header_data->lon_array); + set_array_from_python(python_met_point_data, numpy_array_hdr_elv, &header_data->elv_array); + + set_str_array_from_python(python_met_point_data, numpy_array_hdr_typ_table, &header_data->typ_array); + set_str_array_from_python(python_met_point_data, numpy_array_hdr_sid_table, &header_data->sid_array); + set_str_array_from_python(python_met_point_data, numpy_array_hdr_vld_table, &header_data->vld_array); + set_array_from_python(python_met_point_data, numpy_array_prpt_typ_table, &header_data->prpt_typ_array, false); + set_array_from_python(python_met_point_data, numpy_array_irpt_typ_table, &header_data->irpt_typ_array, false); + set_array_from_python(python_met_point_data, numpy_array_inst_typ_table, &header_data->inst_typ_array, false); + + +// if ( !numpy_array_obj ) { +// +// mlog << Warning << "\n" << method_name +// << "trouble reading data from \"" +// << script_name << "\"\n\n"; +// +//// return ( false ); +// } +/* +*/ + set_array_from_python(python_met_point_data, numpy_array_obs_qty, obs_data->obs_qids); + set_array_from_python(python_met_point_data, numpy_array_obs_hid, obs_data->obs_hids); + set_array_from_python(python_met_point_data, numpy_array_obs_vid, obs_data->obs_ids); + set_array_from_python(python_met_point_data, numpy_array_obs_lvl, obs_data->obs_lvls); + set_array_from_python(python_met_point_data, numpy_array_obs_hgt, obs_data->obs_hgts); + set_array_from_python(python_met_point_data, numpy_array_obs_val, obs_data->obs_vals); + + set_str_array_from_python(python_met_point_data, numpy_array_obs_qty_table, &obs_data->qty_names); + set_str_array_from_python(python_met_point_data, numpy_array_obs_var_table, &obs_data->var_names); + + if(mlog.verbosity_level()>=point_data_debug_level) print_met_data(obs_data, header_data, method_name_s); + +} + + // + // done + // + +return ( true ); + +} + + +//////////////////////////////////////////////////////////////////////// + +void print_met_data(MetPointObsData *obs_data, MetPointHeader *header_data, + const char *caller, int debug_level) { + int log_count, count; + const int min_count = 20; + const char *method_name = "print_met_data() "; + + mlog << Debug(debug_level) << "\n" << method_name << "by " << caller << "\n" + << " obs_data.obs_cnt = " << obs_data->obs_cnt << "\n" + << " header_data.hdr_count = " << header_data->hdr_count << " type=" + << header_data->typ_idx_array.n() << ", sid=" + << header_data->sid_idx_array.n() << ", valid=" + << header_data->vld_idx_array.n() << ", lat=" + << header_data->lat_array.n() << ", lon=" + << header_data->lon_array.n() << ", elv=" + << header_data->elv_array.n() << ", message_type=" + << header_data->typ_array.n() << ", station_id=" + << header_data->sid_array.n() << ", valid_time=" + << header_data->vld_array.n() << ", prpt=" + << header_data->prpt_typ_array.n() << ", irpt=" + << header_data->irpt_typ_array.n() << ", inst=" + << header_data->inst_typ_array.n() << " &header_data=" << header_data + << "\n"; + + log_count = (header_data->hdr_count > min_count) ? min_count : header_data->hdr_count; + mlog << Debug(debug_level) << method_name + << "header_data: message_type,station_id,time_time,lat,lon.elv\n"; + for (int idx=0; idxsid_idx_array[idx] << ", " + << header_data->vld_idx_array[idx] << ", " + << header_data->lat_array[idx] << ", " + << header_data->lon_array[idx] << ", " + << header_data->elv_array[idx] << "\n"; + } + if (header_data->hdr_count > log_count) { + log_count = header_data->hdr_count - min_count; + if (log_count < min_count) log_count = min_count; + else mlog << Debug(debug_level) + << " header_data[...] = ...\n"; + for (int idx=log_count; idxhdr_count; idx++) { + mlog << Debug(debug_level) + << " header_data[" << idx << "] = " + << header_data->typ_idx_array[idx] << ", " + << header_data->sid_idx_array[idx] << ", " + << header_data->vld_idx_array[idx] << ", " + << header_data->lat_array[idx] << ", " + << header_data->lon_array[idx] << ", " + << header_data->elv_array[idx] << "\n"; + } + } + if (header_data->typ_array.n() > 0) { + mlog << Debug(debug_level) << "\n"; + count = header_data->typ_array.n(); + for (int idx=0; idxsid_array.n() > 0) { + mlog << Debug(debug_level) << "\n"; + count = header_data->sid_array.n(); + log_count = (count > min_count) ? min_count : count; + for (int idx=0; idx log_count) { + log_count = count - min_count; + if (log_count < min_count) log_count = min_count; + else mlog << Debug(debug_level) + << " station_id[...] = ...\n"; + for (int idx=log_count; idxvld_array.n() > 0) { + mlog << Debug(debug_level) << "\n"; + count = header_data->vld_array.n(); + log_count = (count > min_count) ? min_count : count; + for (int idx=0; idx log_count) { + log_count = count - min_count; + if (log_count < min_count) log_count = min_count; + else mlog << Debug(debug_level) + << " valid time[...] = ...\n"; + for (int idx=log_count; idxprpt_typ_array.n() > 0) { + mlog << Debug(debug_level) << "\n"; + for (int idx=0; idxprpt_typ_array.n(); idx++) + mlog << Debug(debug_level) + << " prpt_type[" << idx << "] = " << header_data->prpt_typ_array[idx] << "\n"; + } + if (header_data->irpt_typ_array.n() > 0) { + mlog << Debug(debug_level) << "\n"; + for (int idx=0; idxirpt_typ_array.n(); idx++) + mlog << Debug(debug_level) + << " irpt_type[" << idx << "] = " << header_data->irpt_typ_array[idx] << "\n"; + } + if (header_data->inst_typ_array.n() > 0) { + mlog << Debug(debug_level) << "\n"; + for (int idx=0; idxinst_typ_array.n(); idx++) + mlog << Debug(debug_level) + << " inst_type[" << idx << "] = " << header_data->inst_typ_array[idx] << "\n"; + } + + log_count = (obs_data->obs_cnt > min_count) ? min_count : obs_data->obs_cnt; + mlog << Debug(debug_level) << "\n" << method_name + << "obs_data: hid,vid.level,height,value,qty\n"; + for (int idx=0; idxobs_ids[idx] << ", " + << obs_data->obs_lvls[idx] << ", " + << obs_data->obs_hgts[idx] << ", " + << obs_data->obs_vals[idx] << ", " + << obs_data->obs_qids[idx] << "\n"; + } + if (obs_data->obs_cnt > log_count) { + log_count = obs_data->obs_cnt - min_count; + if (log_count < min_count) log_count = min_count; + else mlog << Debug(debug_level) + << " obs_data[...] = ...\n"; + for (int idx=log_count; idxobs_cnt; idx++) { + mlog << Debug(debug_level) + << " obs_data[" << idx << "] = " + << obs_data->obs_hids[idx] << ", " + << obs_data->obs_ids[idx] << ", " + << obs_data->obs_lvls[idx] << ", " + << obs_data->obs_hgts[idx] << ", " + << obs_data->obs_vals[idx] << ", " + << obs_data->obs_qids[idx] << "\n"; + } + } + + if (obs_data->var_names.n() > 0) { + mlog << Debug(debug_level) << "\n"; + for (int idx=0; idxvar_names.n(); idx++) + mlog << Debug(debug_level) + << " var_names[" << idx << "] = " << obs_data->var_names[idx] << "\n"; + } + else mlog << Debug(debug_level) + << " var_names is empty!!!\n"; + if (obs_data->qty_names.n() > 0) { + mlog << Debug(debug_level) << "\n"; + for (int idx=0; idxqty_names.n(); idx++) + mlog << Debug(debug_level) + << " qty_names[" << idx << "] = " << obs_data->qty_names[idx] << "\n"; + } + else mlog << Debug(debug_level) + << " qty_names is empty!!!\n"; + + mlog << Debug(debug_level) << "Done " << method_name << "by " << caller << "\n\n"; + +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_pointdata_python/python_pointdata.h b/met/src/libcode/vx_pointdata_python/python_pointdata.h new file mode 100644 index 0000000000..5be19111f0 --- /dev/null +++ b/met/src/libcode/vx_pointdata_python/python_pointdata.h @@ -0,0 +1,80 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 __PYTHON_POINTDATA__ +#define __PYTHON_POINTDATA__ + + +//////////////////////////////////////////////////////////////////////// + + +#include "met_point_data.h" + + +extern "C" { + +#include "Python.h" + +} + + +//////////////////////////////////////////////////////////////////////// + +static const char python_key_point_data [] = "met_point_data"; + +static const char python_key_nhdr [] = "nhdr"; +//static const char python_key_npbhdr [] = "npbhdr"; +static const char python_use_var_id [] = "use_var_id"; +static const char numpy_array_hdr_typ [] = "hdr_typ"; // message type IDs +static const char numpy_array_hdr_sid [] = "hdr_sid"; // station IDs +static const char numpy_array_hdr_vld [] = "hdr_vld"; // valid time IDs +static const char numpy_array_hdr_lat [] = "hdr_lat"; +static const char numpy_array_hdr_lon [] = "hdr_lon"; +static const char numpy_array_hdr_elv [] = "hdr_elv"; +static const char numpy_array_hdr_typ_table [] = "hdr_typ_table"; // message type list +static const char numpy_array_hdr_sid_table [] = "hdr_sid_table"; // station ID list +static const char numpy_array_hdr_vld_table [] = "hdr_vld_table"; // valid time list +static const char numpy_array_prpt_typ_table[] = "prpt_typ_table"; +static const char numpy_array_irpt_typ_table[] = "irpt_typ_table"; +static const char numpy_array_inst_typ_table[] = "inst_typ_table"; + +static const char python_key_nobs [] = "nobs"; +static const char numpy_array_obs_qty [] = "obs_qty"; // quality_id +static const char numpy_array_obs_hid [] = "obs_hid"; // header id +static const char numpy_array_obs_vid [] = "obs_vid"; // variable id or grib code +static const char numpy_array_obs_lvl [] = "obs_lvl"; +static const char numpy_array_obs_hgt [] = "obs_hgt"; +static const char numpy_array_obs_val [] = "obs_val"; +static const char numpy_array_obs_qty_table [] = "obs_qty_table"; +static const char numpy_array_obs_var_table [] = "obs_var_table"; // variable names or grib codes as string + +static const int point_data_debug_level = 10; + + +//////////////////////////////////////////////////////////////////////// + + +extern bool python_point_data(const char * script_name, int script_argc, char ** script_argv, + const bool use_xarray, MetPointDataPython &met_pd_out); +//extern bool python_point_data(const char *python_command, const bool use_xarray, +// MetPointData & po_out); +extern void print_met_data(MetPointObsData *obs_data, MetPointHeader *header_data, + const char *caller, int debug_level=point_data_debug_level); + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __PYTHON_POINTDATA__ */ + + +//////////////////////////////////////////////////////////////////////// + From 95a65ed174f397d9a8005c8e84ee3b5a23b2eefd Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 29 Dec 2021 14:07:18 -0700 Subject: [PATCH 036/172] #1844 Make buf_size const --- met/src/tools/core/ensemble_stat/ensemble_stat.cc | 4 ++-- met/src/tools/core/point_stat/point_stat.cc | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 422c8d6f84..f84e557b97 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -1055,7 +1055,7 @@ void process_point_obs(int i_nc) { << " observations from " << (hdr_count) << " header messages.\n"; - int buf_size = ((obs_count > DEF_NC_BUFFER_SIZE) ? DEF_NC_BUFFER_SIZE : (obs_count)); + const int buf_size = ((obs_count > DEF_NC_BUFFER_SIZE) ? DEF_NC_BUFFER_SIZE : (obs_count)); int obs_qty_idx_block[buf_size]; float obs_arr_block[buf_size][OBS_ARRAY_LEN]; @@ -1072,7 +1072,7 @@ void process_point_obs(int i_nc) { for(int i_start=0; i_start DEF_NC_BUFFER_SIZE) buf_size2 = DEF_NC_BUFFER_SIZE; + if (buf_size2 > buf_size) buf_size2 = buf_size; #ifdef WITH_PYTHON if (use_python) diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 4578d91a33..f56a95bfe7 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -738,29 +738,29 @@ void process_obs_file(int i_nc) { StringArray obs_qty_array = met_point_obs->get_qty_data(); if( use_var_id ) var_names = met_point_obs->get_var_names(); - int buf_size = ((obs_count > BUFFER_SIZE) ? BUFFER_SIZE : (obs_count)); + const int buf_size = ((obs_count > BUFFER_SIZE) ? BUFFER_SIZE : (obs_count)); int obs_qty_idx_block[buf_size]; float obs_arr_block[buf_size][OBS_ARRAY_LEN]; // Process each observation in the file int str_length, block_size; - for(int i_block_start_idx=0; i_block_start_idx BUFFER_SIZE) block_size2 = BUFFER_SIZE; + for(int i_block_start_idx=0; i_block_start_idx buf_size) block_size = buf_size; #ifdef WITH_PYTHON if (use_python) status = met_point_obs->get_point_obs_data()->fill_obs_buf( - block_size2, i_block_start_idx, (float *)obs_arr_block, obs_qty_idx_block); + block_size, i_block_start_idx, (float *)obs_arr_block, obs_qty_idx_block); else #endif - status = nc_point_obs.read_obs_data(block_size2, i_block_start_idx, + status = nc_point_obs.read_obs_data(block_size, i_block_start_idx, (float *)obs_arr_block, obs_qty_idx_block, (char *)0); if (!status) exit(1); int hdr_idx; - for(int i_block_idx=0; i_block_idx Date: Wed, 5 Jan 2022 16:25:52 -0700 Subject: [PATCH 037/172] Add GitHub Actions workflow to trigger METplus testing workflow (#2002) --- .github/jobs/build_and_push_docker_image.sh | 40 +++++++++++++++++ .../build_docker_and_trigger_metplus.yml | 45 +++++++++++++++++++ met/.gitignore | 1 + 3 files changed, 86 insertions(+) create mode 100755 .github/jobs/build_and_push_docker_image.sh create mode 100644 .github/workflows/build_docker_and_trigger_metplus.yml diff --git a/.github/jobs/build_and_push_docker_image.sh b/.github/jobs/build_and_push_docker_image.sh new file mode 100755 index 0000000000..766b67cc41 --- /dev/null +++ b/.github/jobs/build_and_push_docker_image.sh @@ -0,0 +1,40 @@ +#! /bin/bash + +# utility function to run command get log the time it took to run +function time_command { + local start_seconds=$SECONDS + echo "RUNNING: $*" + "$@" + local error=$? + + local duration=$(( SECONDS - start_seconds )) + echo "TIMING: Command took `printf '%02d' $(($duration / 60))`:`printf '%02d' $(($duration % 60))` (MM:SS): '$*'" + if [ ${error} -ne 0 ]; then + echo "ERROR: '$*' exited with status = ${error}" + fi + return $error +} + +prefix=refs/heads/ +branch_name=${GITHUB_REF#"$prefix"} +DOCKERHUB_TAG=dtcenter/met:${branch_name} + +DOCKERFILE_DIR=${GITHUB_WORKSPACE}/scripts/docker + +echo "::group::Docker Build Command" +time_command docker build -t ${DOCKERHUB_TAG} \ + --build-arg SOURCE_BRANCH=$branch_name \ + $DOCKERFILE_DIR +echo "::endgroup::" + +# skip docker push if credentials are not set +if [ -z ${DOCKER_USERNAME+x} ] || [ -z ${DOCKER_PASSWORD+x} ]; then + echo "DockerHub credentials not set. Skipping docker push" + exit 0 +fi + +echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin + +echo "::group::Docker Push Command" +time_command docker push ${DOCKERHUB_TAG} +echo "::endgroup::" diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml new file mode 100644 index 0000000000..76a7dadb80 --- /dev/null +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -0,0 +1,45 @@ +name: Build Docker Image and Trigger METplus Workflow + +on: + push: + branches: + - develop + paths-ignore: + - 'met/docs/**' + +jobs: + build_met_docker: + name: Handle Docker Image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build and Push Docker Image + run: .github/jobs/build_and_push_docker_image.sh + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + trigger_metplus: + name: Trigger METplus testing workflow + runs-on: ubuntu-latest + needs: build_met_docker + steps: + - name: Print GitHub values for reference + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + - uses: actions/github-script@v5 + with: + github-token: ${{ secrets.METPLUS_BOT_TOKEN }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: 'dtcenter', + repo: 'METplus', + workflow_id: 'testing.yml', + ref: 'develop', + inputs: { + repo_name: '${{ github.repository }}', + docker_tag: '${{ github.ref }}', + actor: '${{ github.actor }}', + commit: '${{ github.sha }}' + }, + }); diff --git a/met/.gitignore b/met/.gitignore index 28829cf0bb..1afea10016 100644 --- a/met/.gitignore +++ b/met/.gitignore @@ -17,6 +17,7 @@ bin share Makefile Makefile.in +make.log # tilda files generated by emacs *~ From 1c981f4276dcccbf614177e02326d549b742bcea Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 5 Jan 2022 16:54:38 -0700 Subject: [PATCH 038/172] changed names of inputs to send to METplus to match changes to METplus repo --- .github/workflows/build_docker_and_trigger_metplus.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 76a7dadb80..02b6bca831 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -37,9 +37,9 @@ jobs: workflow_id: 'testing.yml', ref: 'develop', inputs: { - repo_name: '${{ github.repository }}', - docker_tag: '${{ github.ref }}', + repository: '${{ github.repository }}', + ref: '${{ github.ref }}', actor: '${{ github.actor }}', - commit: '${{ github.sha }}' + sha: '${{ github.sha }}' }, }); From 0273cf162c3ef63e2b4989382f69a4ab1be0c268 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Fri, 7 Jan 2022 10:44:38 -0700 Subject: [PATCH 039/172] #1965 Excludes the duplicated variable names from multiple input files --- met/src/tools/other/ioda2nc/ioda2nc.cc | 72 +++++++++++++++----------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index 772af80a72..79d96a6434 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -369,7 +369,8 @@ void process_ioda_file(int i_pb) { IntArray diff_file_times; int diff_file_time_count; StringArray variables_big_nlevels; - static const char *method_name = "process_ioda_file() "; + static const char *method_name = "process_ioda_file() ->"; + static const char *method_name_s = "process_ioda_file() "; bool apply_grid_mask = (conf_info.grid_mask.nx() > 0 && conf_info.grid_mask.ny() > 0); @@ -388,7 +389,7 @@ void process_ioda_file(int i_pb) { // Check for a valid file if(IS_INVALID_NC_P(f_in)) { - mlog << Error << "\n" << method_name << "-> " + mlog << Error << "\n" << method_name << "can't open input NetCDF file \"" << ioda_files[i_pb] << "\" for reading.\n\n"; delete f_in; @@ -444,7 +445,7 @@ void process_ioda_file(int i_pb) { dim_names, metadata_vars); if(!is_netcdf_ready) { - mlog << Error << "\n" << method_name << "-> " + mlog << Error << "\n" << method_name << "Please check the IODA file (required dimensions or meta variables are missing).\n\n"; delete f_in; f_in = (NcFile *) 0; @@ -460,7 +461,7 @@ void process_ioda_file(int i_pb) { if(dim_names.has("nrecs")) nrecs = get_dim_value(f_in, "nrecs", false); else { nrecs = nvars * nlocs; - mlog << Debug(3) << "\n" << method_name << "-> " + mlog << Debug(3) << "\n" << method_name << "nrecs dimension does not exist, so computed\n"; } NcVar in_hdr_vld_var = get_var(f_in, "datetime@MetaData"); @@ -472,10 +473,10 @@ void process_ioda_file(int i_pb) { else { NcDim datetime_dim = get_nc_dim(&in_hdr_vld_var, 1); ndatetime = IS_VALID_NC(datetime_dim) ? get_dim_size(&datetime_dim) : nstring; - mlog << Debug(3) << "\n" << method_name << "-> " + mlog << Debug(3) << "\n" << method_name << "ndatetime dimension does not exist!\n"; } - mlog << Debug(5) << method_name << "-> dimensions: nvars=" << nvars << ", nlocs=" << nlocs + mlog << Debug(5) << method_name << "dimensions: nvars=" << nvars << ", nlocs=" << nlocs << ", nrecs=" << nrecs << ", nstring=" << nstring << ", ndatetime=" << ndatetime << "\n"; npbmsg_total = npbmsg = nlocs; @@ -515,17 +516,17 @@ void process_ioda_file(int i_pb) { } if(!get_nc_data(&in_hdr_lat_var, hdr_lat_arr, nlocs)) { - mlog << Error << "\n" << method_name << " -> " + mlog << Error << "\n" << method_name << "trouble getting latitude\n\n"; exit(1); } if(!get_nc_data(&in_hdr_lon_var, hdr_lon_arr, nlocs)) { - mlog << Error << "\n" << method_name << " -> " + mlog << Error << "\n" << method_name << "trouble getting longitude\n\n"; exit(1); } if(!get_nc_data(&in_hdr_vld_var, hdr_vld_block, lengths, offsets)) { - mlog << Error << "\n" << method_name << " -> " + mlog << Error << "\n" << method_name << "trouble getting datetime\n\n"; exit(1); } @@ -533,7 +534,6 @@ void process_ioda_file(int i_pb) { StringArray raw_var_names; if(do_all_vars || obs_var_names.n() == 0) raw_var_names = obs_value_vars; else raw_var_names = obs_var_names; - if(obs_var_names.n() > 0) obs_var_names.clear(); NcVar obs_var, qc_var; ConcatString unit_attr; @@ -543,8 +543,8 @@ void process_ioda_file(int i_pb) { int *qc_data = new int[nlocs]; float *obs_data = new float[nlocs]; ConcatString obs_var_name = raw_var_names[idx] + "@ObsValue"; - - mlog << Debug(7) << method_name << " -> " + + mlog << Debug(7) << method_name << "processing \"" << obs_var_name << "\" variable!\n"; obs_var = get_var(f_in, obs_var_name.c_str()); v_qc_data.push_back(qc_data); @@ -556,13 +556,16 @@ void process_ioda_file(int i_pb) { get_var_units(&obs_var, unit_attr); get_att_value_string(&obs_var, "long_name", desc_attr); } - obs_var_units.add(unit_attr); - obs_var_descs.add(desc_attr); - + // Replace the input variable name to the output variable name ConcatString new_name = name_map[raw_var_names[idx]]; - if (0 < new_name.length()) obs_var_names.add(new_name); - else obs_var_names.add(raw_var_names[idx]); + if (0 >= new_name.length()) new_name = raw_var_names[idx]; + // Filter out the same variable names from multiple input files + if (!obs_var_names.has(new_name)) { + obs_var_names.add(new_name); + obs_var_units.add(unit_attr); + obs_var_descs.add(desc_attr); + } } // Initialize counts @@ -573,7 +576,7 @@ void process_ioda_file(int i_pb) { bool showed_progress = false; if(mlog.verbosity_level() >= debug_level_for_performance) { end_t = clock(); - mlog << Debug(debug_level_for_performance) << " PERF: " << method_name << " " + mlog << Debug(debug_level_for_performance) << " PERF: " << method_name_s << " " << (end_t-start_t)/double(CLOCKS_PER_SEC) << " seconds for preparing\n"; start_t = clock(); @@ -612,7 +615,7 @@ void process_ioda_file(int i_pb) { char valid_time[ndatetime+1]; m_strncpy(valid_time, (const char *)(hdr_vld_block + (i_read * ndatetime)), - ndatetime, method_name, "valid_time", true); + ndatetime, method_name_s, "valid_time", true); valid_time[ndatetime] = 0; msg_ut = yyyymmddThhmmss_to_unix(valid_time); @@ -662,7 +665,7 @@ void process_ioda_file(int i_pb) { if(has_msg_type) { int buf_len = sizeof(modified_hdr_typ); - m_strncpy(hdr_typ, hdr_msg_types+(i_read*nstring), nstring, method_name, "hdr_typ"); + m_strncpy(hdr_typ, hdr_msg_types+(i_read*nstring), nstring, method_name_s, "hdr_typ"); m_rstrip(hdr_typ, nstring); // If the message type is not listed in the configuration @@ -675,22 +678,22 @@ void process_ioda_file(int i_pb) { if(0 < message_type_map.count((string)hdr_typ)) { ConcatString mappedMessageType = message_type_map[(string)hdr_typ]; - mlog << Debug(6) << "\n" << method_name << " -> " + mlog << Debug(6) << "\n" << method_name << "Switching report type \"" << hdr_typ << "\" to message type \"" << mappedMessageType << "\".\n"; if(mappedMessageType.length() < HEADER_STR_LEN) buf_len = HEADER_STR_LEN; m_strncpy(modified_hdr_typ, mappedMessageType.c_str(), buf_len, - method_name, "modified_hdr_typ"); + method_name_s, "modified_hdr_typ"); } else { - m_strncpy(modified_hdr_typ, hdr_typ, buf_len, method_name, "modified_hdr_typ2"); + m_strncpy(modified_hdr_typ, hdr_typ, buf_len, method_name_s, "modified_hdr_typ2"); } modified_hdr_typ[buf_len-1] = 0; } if(has_station_id) { char tmp_sid[nstring+1]; - m_strncpy(tmp_sid, hdr_station_ids+(i_read*nstring), nstring, method_name, "tmp_sid"); + m_strncpy(tmp_sid, hdr_station_ids+(i_read*nstring), nstring, method_name_s, "tmp_sid"); m_rstrip(tmp_sid, nstring); hdr_sid = tmp_sid; } @@ -775,7 +778,16 @@ void process_ioda_file(int i_pb) { n_hdr_obs = 0; for(idx=0; idx= out_name.length()) out_name = raw_var_names[idx]; + if (!obs_var_names.has(out_name, var_idx)) { + mlog << Warning << "\n" << method_name + << "Skip the variable " << out_name << " (" << raw_var_names[idx] + << ") at " << ioda_files[i_pb] << "\n\n"; + continue; + } + obs_arr[1] = var_idx; obs_arr[2] = obs_pres_arr[i_read]; obs_arr[3] = obs_hght_arr[i_read]; obs_arr[4] = v_obs_data[idx][i_read]; @@ -795,8 +807,6 @@ void process_ioda_file(int i_pb) { // store the header data and increment the IODA record // counter if(n_hdr_obs > 0) { - //nc_point_obs.add_header(modified_hdr_typ, hdr_sid.c_str(), hdr_vld_ut, - // hdr_lat, hdr_lon, hdr_elv); i_msg++; } else { @@ -839,12 +849,12 @@ void process_ioda_file(int i_pb) { << n_file_obs << "\n"; if(npbmsg == rej_vld && 0 < rej_vld) { - mlog << Warning << "\n" << method_name << " -> " + mlog << Warning << "\n" << method_name << "All records were filtered out by valid time.\n" << "\tPlease adjust time range with \"-valid_beg\" and \"-valid_end\".\n" << "\tmin/max obs time from IODA file: " << min_time_str << " and " << max_time_str << ".\n" - << "\ttime range: " << start_time_str << " and " << end_time_str << ".\n"; + << "\ttime range: " << start_time_str << " and " << end_time_str << ".\n\n"; } else { mlog << Debug(1) << "Obs time between " << unix_to_yyyymmdd_hhmmss(min_msg_ut) @@ -882,13 +892,13 @@ void process_ioda_file(int i_pb) { if(mlog.verbosity_level() >= debug_level_for_performance) { method_end = clock(); - cout << " PERF: " << method_name << " " + cout << " PERF: " << method_name_s << (method_end-method_start)/double(CLOCKS_PER_SEC) << " seconds\n"; } if(i_msg <= 0) { - mlog << Warning << "\n" << method_name << " -> " + mlog << Warning << "\n" << method_name << "No IODA records retained from file: " << ioda_files[i_pb] << "\n\n"; } From ab1199b8eecec4fe14b0226e8d00ea8744c86bfb Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 11 Jan 2022 12:18:14 -0700 Subject: [PATCH 040/172] #1965 Processed with the raw variable names and update them when the output is saved. --- met/src/tools/other/ioda2nc/ioda2nc.cc | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index 79d96a6434..9c7df80b1a 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -538,7 +538,6 @@ void process_ioda_file(int i_pb) { NcVar obs_var, qc_var; ConcatString unit_attr; ConcatString desc_attr; - map name_map = conf_info.getObsVarMap(); for(idx=0; idx= new_name.length()) new_name = raw_var_names[idx]; + ConcatString raw_name = raw_var_names[idx]; // Filter out the same variable names from multiple input files - if (!obs_var_names.has(new_name)) { - obs_var_names.add(new_name); + if (!obs_var_names.has(raw_name)) { + obs_var_names.add(raw_name); obs_var_units.add(unit_attr); obs_var_descs.add(desc_attr); } @@ -779,12 +777,10 @@ void process_ioda_file(int i_pb) { n_hdr_obs = 0; for(idx=0; idx= out_name.length()) out_name = raw_var_names[idx]; - if (!obs_var_names.has(out_name, var_idx)) { + if (!obs_var_names.has(raw_var_names[idx], var_idx)) { mlog << Warning << "\n" << method_name - << "Skip the variable " << out_name << " (" << raw_var_names[idx] - << ") at " << ioda_files[i_pb] << "\n\n"; + << "Skip the variable " << raw_var_names[idx] + << " at " << ioda_files[i_pb] << "\n\n"; continue; } obs_arr[1] = var_idx; @@ -930,13 +926,14 @@ void write_netcdf_hdr_data() { StringArray nc_var_name_arr; StringArray nc_var_unit_arr; StringArray nc_var_desc_arr; - const long var_count = obs_var_names.n(); - const long units_count = obs_var_units.n(); + map name_map = conf_info.getObsVarMap(); - for(int i=0; i= new_name.length()) new_name = obs_var_names[i]; + nc_var_name_arr.add(new_name); } - for(int i=0; i Date: Tue, 11 Jan 2022 12:19:50 -0700 Subject: [PATCH 041/172] #1965 Added unit test ioda2nc_same_input --- test/xml/unit_ioda2nc.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/xml/unit_ioda2nc.xml b/test/xml/unit_ioda2nc.xml index 0006da34d8..a44463c6e1 100644 --- a/test/xml/unit_ioda2nc.xml +++ b/test/xml/unit_ioda2nc.xml @@ -100,4 +100,24 @@ + + &MET_BIN;/ioda2nc + + STATION_ID "KEKA" + MASK_GRID + MASK_POLY + MESSAGE_TYPE + + \ + &DATA_DIR_OBS;/ioda/ioda.NC001007.2020031012.nc \ + &OUTPUT_DIR;/ioda2nc/ioda.NC001007.2020031012.same_input.nc \ + -config &CONFIG_DIR;/IODA2NCConfig_mask \ + -iodafile &DATA_DIR_OBS;/ioda/ioda.NC001007.2020031012.nc \ + -v 7 + + + &OUTPUT_DIR;/ioda2nc/ioda.NC001007.2020031012.same_input.nc + + + From e48c5ff4ade259a591ebdd535a0adad3bc1170a0 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 11 Jan 2022 12:26:53 -0700 Subject: [PATCH 042/172] #1965 Processed with the raw variable names and update them when the output is saved. --- met/src/tools/other/ioda2nc/ioda2nc.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index 9c7df80b1a..1d27aa5ec1 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -926,14 +926,16 @@ void write_netcdf_hdr_data() { StringArray nc_var_name_arr; StringArray nc_var_unit_arr; StringArray nc_var_desc_arr; + const long var_count = obs_var_names.n(); + const long units_count = obs_var_units.n(); map name_map = conf_info.getObsVarMap(); - for(int i=0; i= new_name.length()) new_name = obs_var_names[i]; nc_var_name_arr.add(new_name); } - for(int i=0; i Date: Tue, 11 Jan 2022 12:28:20 -0700 Subject: [PATCH 043/172] #1965 Added unit test ioda2nc_same_input --- test/xml/unit_ioda2nc.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/xml/unit_ioda2nc.xml b/test/xml/unit_ioda2nc.xml index a44463c6e1..b519a08d4d 100644 --- a/test/xml/unit_ioda2nc.xml +++ b/test/xml/unit_ioda2nc.xml @@ -113,7 +113,7 @@ &OUTPUT_DIR;/ioda2nc/ioda.NC001007.2020031012.same_input.nc \ -config &CONFIG_DIR;/IODA2NCConfig_mask \ -iodafile &DATA_DIR_OBS;/ioda/ioda.NC001007.2020031012.nc \ - -v 7 + -v 2 &OUTPUT_DIR;/ioda2nc/ioda.NC001007.2020031012.same_input.nc From ee761439084ed3a23133f0cc9c7ffb442376dafa Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Tue, 11 Jan 2022 18:02:40 -0700 Subject: [PATCH 044/172] #1965 initialize var_idx --- met/src/tools/other/ioda2nc/ioda2nc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index 1d27aa5ec1..323cd83447 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -776,7 +776,7 @@ void process_ioda_file(int i_pb) { n_hdr_obs = 0; for(idx=0; idx Date: Wed, 12 Jan 2022 10:05:21 -0700 Subject: [PATCH 045/172] Update the development environment for seneca to add /usr/local/nco/bin and /usr/local/netcdf/bin to the path. Also define MET_TEST_RSCRIPT to point to a new enough version of RSCRIPT that has the ncdf4 package 1.17 or later. --- scripts/environment/development.seneca | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/environment/development.seneca b/scripts/environment/development.seneca index d6e13f0543..325e80ed3b 100644 --- a/scripts/environment/development.seneca +++ b/scripts/environment/development.seneca @@ -40,7 +40,13 @@ export LDFLAGS="${LDFLAGS} -L${MET_JASPER}/lib" export MET_TEST_INPUT=${MET_PROJ_DIR}/MET_test_data/unit_test export MET_FONT_DIR=${MET_TEST_INPUT}/fonts +# Define Rscript to use a version with the ncdf4 package 1.17 or later +export MET_TEST_RSCRIPT=/usr/local/R-4.1.2/bin/Rscript + # This is a cron script -- create the shell environment for this job -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:\ - /usr/bin/X11:/opt/bin:${MET_NETCDF}/bin" +# - NCO is for ncdiff +# - NetCDF is for ncdump. +export PATH="/usr/local/nco/bin:/usr/local/netcdf/bin:\ + /usr/local/sbin:/usr/local/bin:/usr/sbin:\ + /usr/bin:/sbin:/bin:/usr/bin/X11:/opt/bin" From 58988bffa134be48d9320dd3b8a681ff933201a3 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 12 Jan 2022 11:57:32 -0700 Subject: [PATCH 046/172] send email address of user who triggered event to METplus workflow as input --- .github/workflows/build_docker_and_trigger_metplus.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 02b6bca831..070fa071a6 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -40,6 +40,7 @@ jobs: repository: '${{ github.repository }}', ref: '${{ github.ref }}', actor: '${{ github.actor }}', - sha: '${{ github.sha }}' + sha: '${{ github.sha }}', + pusher_email: '${{ github.event.pusher.email }}' }, }); From b26788310d7ce3ff98d1c1063742fe898b13ac86 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 12 Jan 2022 12:41:58 -0700 Subject: [PATCH 047/172] Fixup the Rscript diffing logic to support running the nightly build on seneca. The problem here is that the ncdiff -x -v command line options that worked in version 4.7.0 NO LONGER work in 4.9.2. Added a check to skip over the time_bounds variable when processing the ncdiff output. --- test/R_test/test_util.R | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/R_test/test_util.R b/test/R_test/test_util.R index d00616209a..6dea9afd11 100644 --- a/test/R_test/test_util.R +++ b/test/R_test/test_util.R @@ -753,6 +753,11 @@ compareNc = function(nc1, nc2, verb, strict=0, delta=-1, comp_var=0){ # for each variable present in the file, check for differences for(strVar in names(ncFileD$var)){ + # Skip the time_bounds variable + # Note: Running "ncdiff -x -v time_bounds" successfully excludes that variable + # in version 4.7.0. However, it fails in version 4.9.2. + if (strVar == "time_bounds"){ next; } + # check the variable attributes for differences listAtt1 = ncatt_get(ncFile1, varid=strVar); listAtt1Nam = names(listAtt1); From 96536f54e361957670aa1e8673ad9dfe53436067 Mon Sep 17 00:00:00 2001 From: MET Tools Test Account Date: Wed, 12 Jan 2022 12:50:24 -0700 Subject: [PATCH 048/172] No real changes here. Just formatting --- test/R_test/test_util.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/R_test/test_util.R b/test/R_test/test_util.R index 6dea9afd11..d7491fa966 100644 --- a/test/R_test/test_util.R +++ b/test/R_test/test_util.R @@ -755,7 +755,7 @@ compareNc = function(nc1, nc2, verb, strict=0, delta=-1, comp_var=0){ # Skip the time_bounds variable # Note: Running "ncdiff -x -v time_bounds" successfully excludes that variable - # in version 4.7.0. However, it fails in version 4.9.2. + # in version 4.7.0. However, it fails in version 4.9.2. if (strVar == "time_bounds"){ next; } # check the variable attributes for differences From fa41760ba04ce6c20322c877dc3d4b272dccdc3a Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Wed, 12 Jan 2022 14:12:03 -0700 Subject: [PATCH 049/172] Feature 1974 message_type_group_map (#1999) Co-authored-by: Howard Soh Co-authored-by: John Halley Gotway --- met/docs/Users_Guide/point-stat.rst | 2 +- met/src/libcode/vx_statistics/pair_data_ensemble.cc | 4 ++-- met/src/libcode/vx_statistics/pair_data_point.cc | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index e9cc3fdca8..7a9966511c 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -22,7 +22,7 @@ Interpolation/matching methods This section provides information about the various methods available in MET to match gridded model output to point observations. Matching in the vertical and horizontal are completed separately using different methods. -In the vertical, if forecasts and observations are at the same vertical level, then they are paired as-is. If any discrepancy exists between the vertical levels, then the forecasts are interpolated to the level of the observation. The vertical interpolation is done in the natural log of pressure coordinates, except for specific humidity, which is interpolated using the natural log of specific humidity in the natural log of pressure coordinates. Vertical interpolation for heights above ground are done linear in height coordinates. When forecasts are for the surface, no interpolation is done. They are matched to observations with message types that are mapped to **SURFACE** in the **message_type_group_map** configuration option. By default, the surface message types include ADPSFC, SFCSHP, and MSONET. +In the vertical, if forecasts and observations are at the same vertical level, then they are paired as-is. If any discrepancy exists between the vertical levels, then the forecasts are interpolated to the level of the observation. The vertical interpolation is done in the natural log of pressure coordinates, except for specific humidity, which is interpolated using the natural log of specific humidity in the natural log of pressure coordinates. Vertical interpolation for heights above ground are done linear in height coordinates. When forecasts are for the surface, no interpolation is done. They are matched to observations with message types that are mapped to **SURFACE** in the **message_type_group_map** configuration option. By default, the surface message types include ADPSFC, SFCSHP, and MSONET. The regular expression is applied to the message type list at the message_type_group_map. The derived message types from the time summary ("ADPSFC_MIN_hhmmss" and "ADPSFC_MAX_hhmmss") are accepted as "ADPSFC". To match forecasts and observations in the horizontal plane, the user can select from a number of methods described below. Many of these methods require the user to define the width of the forecast grid W, around each observation point P, that should be considered. In addition, the user can select the interpolation shape, either a SQUARE or a CIRCLE. For example, a square of width 2 defines the 2 x 2 set of grid points enclosing P, or simply the 4 grid points closest to P. A square of width of 3 defines a 3 x 3 square consisting of 9 grid points centered on the grid point closest to P. :numref:`point_stat_fig1` provides illustration. The point P denotes the observation location where the interpolated value is calculated. The interpolation width W, shown is five. diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 4811f66147..6f6471b63a 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -1442,7 +1442,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, // falls within the requested range. else { - if(!msg_typ_sfc.has(hdr_typ_str) && + if(!msg_typ_sfc.reg_exp_match(hdr_typ_str) && (obs_hgt < obs_info_grib->level().lower() || obs_hgt > obs_info_grib->level().upper())) { return; @@ -1481,7 +1481,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, // set the observation level value to bad data so that it's not used in the // duplicate logic. if(obs_info->level().type() == LevelType_Vert && - msg_typ_sfc.has(hdr_typ_str)) { + msg_typ_sfc.reg_exp_match(hdr_typ_str)) { obs_lvl = bad_data_double; } diff --git a/met/src/libcode/vx_statistics/pair_data_point.cc b/met/src/libcode/vx_statistics/pair_data_point.cc index 6cfa81de6c..d26e6c8c89 100644 --- a/met/src/libcode/vx_statistics/pair_data_point.cc +++ b/met/src/libcode/vx_statistics/pair_data_point.cc @@ -984,7 +984,7 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, } // Check for a large topography difference - if(sfc_info.topo_ptr && msg_typ_sfc.has(hdr_typ_str)) { + if(sfc_info.topo_ptr && msg_typ_sfc.reg_exp_match(hdr_typ_str)) { // Interpolate model topography to observation location double topo = compute_horz_interp( @@ -1051,7 +1051,7 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, // falls within the requested range. else { - if(!msg_typ_sfc.has(hdr_typ_str) && + if(!msg_typ_sfc.reg_exp_match(hdr_typ_str) && (obs_hgt < obs_info->level().lower() || obs_hgt > obs_info->level().upper())) { rej_lvl++; @@ -1105,7 +1105,7 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, // type, set the observation level value to bad data so that it's not // used in the duplicate logic. if(obs_info->level().type() == LevelType_Vert && - msg_typ_sfc.has(hdr_typ_str)) { + msg_typ_sfc.reg_exp_match(hdr_typ_str)) { obs_lvl = bad_data_double; } @@ -1208,7 +1208,7 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, // For surface verification, apply land/sea and topo masks if((sfc_info.land_ptr || sfc_info.topo_ptr) && - (msg_typ_sfc.has(hdr_typ_str))) { + (msg_typ_sfc.reg_exp_match(hdr_typ_str))) { bool is_land = msg_typ_lnd.has(hdr_typ_str); From 551f92b618d21868a7f9a5e7cabb29c8827018c7 Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Wed, 12 Jan 2022 14:15:56 -0700 Subject: [PATCH 050/172] Feature 1996 uninitialized variables (#2004) Co-authored-by: Howard Soh Co-authored-by: John Halley Gotway --- met/src/basic/vx_config/threshold.cc | 2 +- met/src/basic/vx_log/concat_string.cc | 21 ------------- met/src/basic/vx_log/concat_string.h | 8 ----- met/src/basic/vx_log/string_array.cc | 1 + met/src/basic/vx_log/string_array.h | 2 -- met/src/libcode/vx_nc_util/nc_utils.cc | 9 ++++-- met/src/libcode/vx_statistics/pair_base.cc | 1 + met/src/libcode/vx_tc_util/vx_tc_nc_util.cc | 1 + met/src/tools/tc_utils/tc_stat/tc_stat.cc | 35 +++++++++++---------- 9 files changed, 30 insertions(+), 50 deletions(-) diff --git a/met/src/basic/vx_config/threshold.cc b/met/src/basic/vx_config/threshold.cc index bf317733ff..78147f1071 100644 --- a/met/src/basic/vx_config/threshold.cc +++ b/met/src/basic/vx_config/threshold.cc @@ -1128,7 +1128,7 @@ else { // adjust PT by the requested frequency bias amount // - double PT_new; + double PT_new = 0.; if ( fbias_fcst ) { if ( op == thresh_le || op == thresh_lt ) PT_new = PT * fbias_val; diff --git a/met/src/basic/vx_log/concat_string.cc b/met/src/basic/vx_log/concat_string.cc index 2f4e6550dd..198f17ff66 100644 --- a/met/src/basic/vx_log/concat_string.cc +++ b/met/src/basic/vx_log/concat_string.cc @@ -50,8 +50,6 @@ ConcatString::ConcatString() init_from_scratch(); -set_alloc_inc(default_cs_alloc_inc); - } @@ -64,8 +62,6 @@ ConcatString::ConcatString(int _alloc_inc) init_from_scratch(); -set_alloc_inc(_alloc_inc); - } @@ -237,23 +233,6 @@ void ConcatString::assign(const ConcatString & c) memcpy(FloatFormat, c.FloatFormat, sizeof(FloatFormat)); Precision = c.Precision; - AllocInc = c.AllocInc; -} - - -//////////////////////////////////////////////////////////////////////// - - -void ConcatString::set_alloc_inc(int _alloc_inc) - -{ - -if ( _alloc_inc < min_cs_alloc_inc ) _alloc_inc = min_cs_alloc_inc; - -AllocInc = _alloc_inc; - -return; - } diff --git a/met/src/basic/vx_log/concat_string.h b/met/src/basic/vx_log/concat_string.h index 29903f8e40..03424effbc 100644 --- a/met/src/basic/vx_log/concat_string.h +++ b/met/src/basic/vx_log/concat_string.h @@ -71,10 +71,6 @@ class ConcatString { void assign(const ConcatString &); - void extend(int); - - int AllocInc; - int Precision; char FloatFormat[16]; @@ -102,8 +98,6 @@ class ConcatString { // set stuff // - void set_alloc_inc(int); - void set_precision(int); // @@ -207,8 +201,6 @@ inline int ConcatString::precision() const { return ( Precision ); } inline const char * ConcatString::float_format() const { return ( FloatFormat ); } -inline int ConcatString::alloc_inc() const { return ( AllocInc ); } - inline bool ConcatString::empty() const { return ( s ? s->empty() : true ); } inline bool ConcatString::nonempty() const { return ( s ? !s->empty() : false ); } diff --git a/met/src/basic/vx_log/string_array.cc b/met/src/basic/vx_log/string_array.cc index 21419fbe6c..57f90dac49 100644 --- a/met/src/basic/vx_log/string_array.cc +++ b/met/src/basic/vx_log/string_array.cc @@ -131,6 +131,7 @@ void StringArray::init_from_scratch() { IgnoreCase = 0; +MaxLength = 0; clear(); diff --git a/met/src/basic/vx_log/string_array.h b/met/src/basic/vx_log/string_array.h index 6563f68e2e..3662719197 100644 --- a/met/src/basic/vx_log/string_array.h +++ b/met/src/basic/vx_log/string_array.h @@ -37,8 +37,6 @@ class StringArray { std::vector s; - int Nalloc; - int MaxLength; bool IgnoreCase; diff --git a/met/src/libcode/vx_nc_util/nc_utils.cc b/met/src/libcode/vx_nc_util/nc_utils.cc index 50c3ff778e..8d1505875d 100644 --- a/met/src/libcode/vx_nc_util/nc_utils.cc +++ b/met/src/libcode/vx_nc_util/nc_utils.cc @@ -129,6 +129,9 @@ bool get_att_value(const NcAtt *att, double &att_val) { int get_att_value_int(const NcAtt *att) { int value = bad_data_int; static const char *method_name = "get_att_value_int(NcAtt) -> "; + + if (IS_INVALID_NC_P(att)) return value; + switch (att->getType().getId()) { case NC_BYTE: ncbyte b_value; @@ -221,7 +224,7 @@ bool get_att_value_chars(const NcAtt *att, ConcatString &value) { long long get_att_value_llong(const NcAtt *att) { long long value = bad_data_int; - att->getValues(&value); + if (IS_VALID_NC_P(att)) att->getValues(&value); return value; } @@ -229,7 +232,7 @@ long long get_att_value_llong(const NcAtt *att) { double get_att_value_double(const NcAtt *att) { double value = bad_data_double; - att->getValues(&value); + if (IS_VALID_NC_P(att)) att->getValues(&value); return value; } @@ -1658,6 +1661,8 @@ bool get_nc_data(NcVar *var, float *data) { fill_value = get_att_value_char(att_fill_value); } + var->getVar(packed_data); + if (unsigned_value) { int value; int positive_cnt = 0; diff --git a/met/src/libcode/vx_statistics/pair_base.cc b/met/src/libcode/vx_statistics/pair_base.cc index 45bf5696a5..a8f2f2ff83 100644 --- a/met/src/libcode/vx_statistics/pair_base.cc +++ b/met/src/libcode/vx_statistics/pair_base.cc @@ -71,6 +71,7 @@ void PairBase::clear() { msg_typ.clear(); msg_typ_vals.clear(); + interp_wdth = 0; interp_mthd = InterpMthd_None; interp_shape = GridTemplateFactory::GridTemplate_None; diff --git a/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc b/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc index 7bd51ffbbe..40a6feedc1 100644 --- a/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc +++ b/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc @@ -512,6 +512,7 @@ void write_tc_azi_mean_data(NcFile* nc_out, const TcrmwGrid& grid, data_azi_mean = new double[grid.range_n()]; for(int ir = 0; ir < grid.range_n(); ir++) { + data_azi_mean[ir] = 0.; for(int ia = 0; ia < grid.azimuth_n(); ia++) { int i = ir * grid.azimuth_n() + ia; int i_rev = (grid.range_n() - ir - 1) * grid.azimuth_n() + ia; diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat.cc b/met/src/tools/tc_utils/tc_stat/tc_stat.cc index 5595e02b93..e1793ec194 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat.cc +++ b/met/src/tools/tc_utils/tc_stat/tc_stat.cc @@ -165,6 +165,7 @@ void process_jobs() { ConcatString jobstring; int i, n_jobs; TCLineCounts n; + const char *method_name = "process_jobs() -> "; // Open the output file open_out_file(); @@ -193,27 +194,29 @@ void process_jobs() { // Allocate a new job cur_job = factory.new_tc_stat_job(jobstring.c_str()); + if (cur_job) { + // Set the job output file stream + cur_job->JobOut = tc_stat_out; - // Set the job output file stream - cur_job->JobOut = tc_stat_out; + // Set the output precision + cur_job->set_precision(conf_info.Conf.output_precision()); - // Set the output precision - cur_job->set_precision(conf_info.Conf.output_precision()); + // Serialize the current job + mlog << Debug(2) + << "\nProcessing Job " << i+1 << ": " + << cur_job->serialize() << "\n"; - // Serialize the current job - mlog << Debug(2) - << "\nProcessing Job " << i+1 << ": " - << cur_job->serialize() << "\n"; + // Initialize counts + memset(&n, 0, sizeof(TCLineCounts)); - // Initialize counts - memset(&n, 0, sizeof(TCLineCounts)); + // Do the job + cur_job->do_job(tcst_files, n); - // Do the job - cur_job->do_job(tcst_files, n); - - mlog << Debug(2) - << "Job " << i+1 << " used " << n.NKeep << " out of " - << n.NRead << " lines read.\n"; + mlog << Debug(2) << method_name + << "Job " << i+1 << " used " << n.NKeep << " out of " + << n.NRead << " lines read.\n"; + } + else mlog << Debug(1) << method_name << "job is missing\n"; mlog << Debug(3) << "Total lines read = " << n.NRead << "\n" From dbc7d10ec9f82a1a8885c940d0dd5dcb8c8c41d4 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 12 Jan 2022 15:30:46 -0700 Subject: [PATCH 051/172] Feature 1695 ensemble single file (gen_ens_prod) (#2001) Co-authored-by: johnhg --- met/data/config/GenEnsProdConfig_default | 7 + met/docs/Users_Guide/gen-ens-prod.rst | 46 +++- met/src/basic/vx_config/config_constants.h | 2 + met/src/basic/vx_config/config_file.cc | 2 +- met/src/basic/vx_config/config_util.cc | 16 ++ met/src/basic/vx_config/config_util.h | 1 + met/src/basic/vx_config/dictionary.cc | 29 ++- met/src/basic/vx_config/dictionary.h | 5 +- met/src/basic/vx_log/file_fxns.h | 1 - .../ensemble_stat/ensemble_stat_conf_info.h | 1 + .../tools/other/gen_ens_prod/gen_ens_prod.cc | 212 +++++++++-------- .../tools/other/gen_ens_prod/gen_ens_prod.h | 2 +- .../gen_ens_prod/gen_ens_prod_conf_info.cc | 223 ++++++++++++++++-- .../gen_ens_prod/gen_ens_prod_conf_info.h | 48 +++- .../other/mode_graphics/plot_mode_field.cc | 2 +- scripts/environment/development.seneca | 2 +- test/config/GenEnsProdConfig | 7 + test/config/GenEnsProdConfig_single_file_grib | 149 ++++++++++++ test/config/GenEnsProdConfig_single_file_nc | 149 ++++++++++++ test/xml/unit_gen_ens_prod.xml | 56 ++++- 20 files changed, 819 insertions(+), 141 deletions(-) create mode 100644 test/config/GenEnsProdConfig_single_file_grib create mode 100644 test/config/GenEnsProdConfig_single_file_nc diff --git a/met/data/config/GenEnsProdConfig_default b/met/data/config/GenEnsProdConfig_default index fbe81a00f4..09746b626e 100644 --- a/met/data/config/GenEnsProdConfig_default +++ b/met/data/config/GenEnsProdConfig_default @@ -57,6 +57,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index 029d256ad2..459a9778f1 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -67,7 +67,7 @@ Required arguments gen_ens_prod Optional arguments for gen_ens_prod ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -4. The **-ctrl file** option specifies the input file for the ensemble control member. Data for this member is included in the computation of the ensemble mean, but excluded from the spread. The control file should not appear in the **-ens** list of ensemble member files. +4. The **-ctrl file** option specifies the input file for the ensemble control member. Data for this member is included in the computation of the ensemble mean, but excluded from the spread. The control file should not appear in the **-ens** list of ensemble member files (unless processing a single file that contains all ensemble members). 5. The **-log** file outputs log messages to the specified file. @@ -134,6 +134,50 @@ For each dictionary entry in the **field** array, give the name and vertical or _______________________ +.. code-block:: none + + ens_member_ids = []; + control_id = ""; + +The **ens_member_ids** array is only used if reading a single file that contains all ensemble members. +It should contain a list of string identifiers that are substituted into the **ens** dictionary fields +to determine which data to read from the file. +The length of the array determines how many ensemble members will be processed for a given field. +Each value in the array will replace the text **MET_ENS_MEMBER_ID**. + +**NetCDF Example:** + +.. code-block:: none + + ens = { + field = [ + { + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,0,*,*)"; + } + ]; + } + +**GRIB Example:** + +.. code-block:: none + + ens = { + field = [ + { + name = "fcst"; + level = "L0"; + GRIB_ens = "+MET_ENS_MEMBER_ID"; + } + ]; + } + +**control_id** is a string that is substituted in the same way as the **ens_member_ids** values +to read a control member. This value is only used when the **-ctrl** command line argument is +used. The value should not be found in the **ens_member_ids** array. + +_______________________ + .. code-block:: none nbrhd_prob = { diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index 01c598bd72..01f03b3840 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -632,6 +632,8 @@ static const char conf_key_eclv_points[] = "eclv_points"; static const char conf_key_var_name_map[] = "var_name_map"; static const char conf_key_metadata_map[] = "metadata_map"; static const char conf_key_missing_thresh[] = "missing_thresh"; +static const char conf_key_control_id[] = "control_id"; +static const char conf_key_ens_member_ids[] = "ens_member_ids"; // // Entries to override file metadata diff --git a/met/src/basic/vx_config/config_file.cc b/met/src/basic/vx_config/config_file.cc index a7b1377405..1e229d5aa9 100644 --- a/met/src/basic/vx_config/config_file.cc +++ b/met/src/basic/vx_config/config_file.cc @@ -252,7 +252,7 @@ ConcatString MetConfig::get_tmp_dir() // Use the MET_TMP_DIR environment variable, if set. if(!get_env("MET_TMP_DIR", tmp_dir)) { const DictionaryEntry * _e = lookup(conf_key_tmp_dir); - if ( LastLookupStatus ) tmp_dir = *(_e->string_value()); + if ( LastLookupStatus ) tmp_dir = _e->string_value(); else tmp_dir = default_tmp_dir; } diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index 934bec72b9..1218e2940d 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -2965,3 +2965,19 @@ ConcatString wavelettype_to_string(WaveletType type) { } /////////////////////////////////////////////////////////////////////////////// + +StringArray parse_conf_ens_member_ids(Dictionary *dict) { + const char *method_name = "parse_conf_ens_member_ids() -> "; + + StringArray sa = parse_conf_string_array(dict, conf_key_ens_member_ids, method_name); + + if(sa.n() > 0) { + mlog << Debug(4) << method_name + << "Ensemble Member IDs \"" << conf_key_ens_member_ids << "\" list contains " + << sa.n() << " entries.\n"; + } + + return(sa); +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_config/config_util.h b/met/src/basic/vx_config/config_util.h index 5e83b2c6aa..ff9d38e7d4 100644 --- a/met/src/basic/vx_config/config_util.h +++ b/met/src/basic/vx_config/config_util.h @@ -73,6 +73,7 @@ extern map parse_conf_filter_attr_map(Dictionary *dict); extern void parse_conf_range_int(Dictionary *dict, int &beg, int &end); extern void parse_conf_range_double(Dictionary *dict, double &beg, double &end); +extern StringArray parse_conf_ens_member_ids(Dictionary *dict); extern void check_mask_names(const StringArray &); diff --git a/met/src/basic/vx_config/dictionary.cc b/met/src/basic/vx_config/dictionary.cc index 55ef59a0ac..f090916ace 100644 --- a/met/src/basic/vx_config/dictionary.cc +++ b/met/src/basic/vx_config/dictionary.cc @@ -762,21 +762,30 @@ return ( Bval ); //////////////////////////////////////////////////////////////////////// -const ConcatString * DictionaryEntry::string_value() const +const ConcatString DictionaryEntry::string_value() const { -if ( Type != StringType ) { + if ( Type != StringType ) { - mlog << Error - << "\nDictionaryEntry::string_value() -> bad type\n\n"; + mlog << Error + << "\nDictionaryEntry::string_value() -> bad type\n\n"; - exit ( 1 ); + exit ( 1 ); -} + } + + ConcatString sub_text = ConcatString(*Text); + ConcatString cur_env_val; + if ( get_env(met_ens_member_id, cur_env_val) ) { + if(!cur_env_val.empty()) { + sub_text.replace(met_ens_member_id, cur_env_val.c_str(), false); + } + + } -return ( Text ); + return ( sub_text ); } @@ -1816,7 +1825,7 @@ if ( !Entry || !is_correct_type ) { } -return ( *(Entry->string_value()) ); +return ( Entry->string_value() ); } @@ -1874,7 +1883,7 @@ if ( !Entry || !is_correct_type ) { if ( Entry->type() == StringType ) { - array.add( *(Entry->string_value()) ); + array.add( Entry->string_value() ); return ( array ); @@ -1911,7 +1920,7 @@ if ( Dict->n_entries() > 0 ) { for (int i=0; in_entries(); i++) { - array.add(*(*Dict)[i]->string_value()); + array.add((*Dict)[i]->string_value()); } diff --git a/met/src/basic/vx_config/dictionary.h b/met/src/basic/vx_config/dictionary.h index a39949be04..3a90e047e5 100644 --- a/met/src/basic/vx_config/dictionary.h +++ b/met/src/basic/vx_config/dictionary.h @@ -40,6 +40,9 @@ class Dictionary; // forward reference //////////////////////////////////////////////////////////////////////// +static const char met_ens_member_id [] = "MET_ENS_MEMBER_ID"; + +//////////////////////////////////////////////////////////////////////// class DictionaryEntry { @@ -122,7 +125,7 @@ class DictionaryEntry { int n_args () const; - const ConcatString * string_value () const; + const ConcatString string_value () const; Dictionary * dict_value () const; diff --git a/met/src/basic/vx_log/file_fxns.h b/met/src/basic/vx_log/file_fxns.h index 4b868bbdbf..f5d571962d 100644 --- a/met/src/basic/vx_log/file_fxns.h +++ b/met/src/basic/vx_log/file_fxns.h @@ -22,7 +22,6 @@ #include #include "concat_string.h" -#include "file_fxns.h" //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h index 7148109bba..df46f8ecf7 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h @@ -95,6 +95,7 @@ class EnsembleStatVxOpt { VxPairDataEnsemble vx_pd; // Ensemble pair data ConcatString var_str; // nc_pairs_var_str string + ConcatString control_id; // Control ID int beg_ds; // Begin observation time window offset int end_ds; // End observation time window offset diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index c7b48a7331..1f634c38b2 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -53,17 +53,17 @@ static void process_ensemble(); static bool get_data_plane(const char *, GrdFileType, VarInfo *, DataPlane &); static void clear_counts(); -static void track_counts(int, const DataPlane &, bool, +static void track_counts(EnsVarInfo *, const DataPlane &, bool, const DataPlane &, const DataPlane &); static void setup_nc_file(); -static void write_ens_nc(int, int, const DataPlane &, +static void write_ens_nc(EnsVarInfo *, int, const DataPlane &, const DataPlane &, const DataPlane &); -static void write_ens_var_float(int, float *, const DataPlane &, +static void write_ens_var_float(EnsVarInfo *, float *, const DataPlane &, const char *, const char *); -static void write_ens_var_int(int, int *, const DataPlane &, +static void write_ens_var_int(EnsVarInfo *, int *, const DataPlane &, const char *, const char *); -static void write_ens_data_plane(int, const DataPlane &, const DataPlane &, +static void write_ens_data_plane(EnsVarInfo *, const DataPlane &, const DataPlane &, const char *, const char *); static void add_var_att_local(VarInfo *, NcVar *, bool is_int, @@ -136,8 +136,8 @@ void process_command_line(int argc, char **argv) { if(cline.n() != 0) usage(); // Check that the required arguments have been set - n_ens = ens_files.n(); - if(ens_files.n() == 0) { + n_ens_files = ens_files.n(); + if(n_ens_files == 0) { mlog << Error << "\nprocess_command_line() -> " << "the ensemble file list must be set using the " << "\"-ens\" option.\n\n"; @@ -181,7 +181,7 @@ void process_command_line(int argc, char **argv) { etype = ens_mtddf->file_type(); // Process the configuration - conf_info.process_config(etype); + conf_info.process_config(etype, &ens_files); // Allocate arrays to store threshold counts thresh_cnt_na = new NumArray [conf_info.get_max_n_cat()]; @@ -193,8 +193,8 @@ void process_command_line(int argc, char **argv) { // List the input ensemble files mlog << Debug(1) << "Ensemble Files[" - << ens_files.n() << "]:\n"; - for(i=0; i " << "the ensemble control file should not appear in the list " << "of ensemble member files:\n" << ctrl_file << "\n\n"; @@ -211,7 +211,7 @@ void process_command_line(int argc, char **argv) { } // Check for missing non-python ensemble files - for(i=0; i " @@ -224,6 +224,12 @@ void process_command_line(int argc, char **argv) { } } + if(conf_info.control_id.nonempty() && ctrl_file.empty()) { + mlog << Warning << "\nprocess_command_line() -> " + << "control_id is set in the config file but " + << "control file is not provided with -ctrl argument\n\n"; + } + // Deallocate memory for data files if(ens_mtddf) { delete ens_mtddf; ens_mtddf = (Met2dDataFile *) 0; } @@ -238,7 +244,7 @@ void process_grid(const Grid &fcst_grid) { // Parse regridding logic RegridInfo ri; if(conf_info.get_n_var() > 0) { - ri = conf_info.ens_info[0]->regrid(); + ri = conf_info.ens_input[0]->get_var_info()->regrid(); } else { mlog << Error << "\nprocess_grid() -> " @@ -308,33 +314,45 @@ bool get_data_plane(const char *infile, GrdFileType ftype, //////////////////////////////////////////////////////////////////////// void process_ensemble() { - int i_var, i_file, n_ens_vld; + int i_var, i_ens, n_ens_vld, n_ens_inputs; bool need_reset; DataPlane ens_dp, ctrl_dp, cmn_dp, csd_dp; unixtime max_init_ut = bad_data_ll; + VarInfo * var_info; + ConcatString ens_file; // Loop through each of the ensemble fields to be processed - for(i_var=0; i_var::const_iterator var_it = conf_info.ens_input.begin(); + for(i_var=0; var_it != conf_info.ens_input.end(); var_it++, i_var++) { + + // Need to reinitialize counts and sums for each ensemble field + need_reset = true; + var_info = (*var_it)->get_var_info(); mlog << Debug(2) << "\n" << sep_str << "\n\n" << "Processing ensemble field: " - << conf_info.ens_info[i_var]->magic_str() << "\n"; + << (*var_it)->raw_magic_str << "\n"; - // Need to reinitialize counts and sums for each ensemble field - need_reset = true; + n_ens_inputs = (*var_it)->inputs_n(); + for(i_ens=n_ens_vld=0; i_ens < n_ens_inputs; i_ens++) { - // Loop through the ensemble member files - for(i_file=0, n_ens_vld=0; i_fileget_file(i_ens); + var_info = (*var_it)->get_var_info(i_ens); // Skip bad data files - if(!ens_file_vld[i_file]) continue; + if(!ens_file_vld[(*var_it)->get_file_index(i_ens)]) continue; + + mlog << Debug(3) << "\n" + << "Reading field: " + << var_info->magic_str() << "\n"; // Read data and track the valid data count - if(!get_data_plane(ens_files[i_file].c_str(), etype, - conf_info.ens_info[i_var], ens_dp)) { + if(!get_data_plane(ens_file.c_str(), etype, + var_info, ens_dp)) { mlog << Warning << "\nprocess_ensemble() -> " - << "ensemble field \"" << conf_info.ens_info[i_var]->magic_str() - << "\" not found in file \"" << ens_files[i_file] << "\"\n\n"; + << "ensemble field \"" << var_info->magic_str() + << "\" not found in file \"" << ens_file << "\"\n\n"; continue; } else { @@ -360,19 +378,24 @@ void process_ensemble() { // Read ensemble control member data, if provided if(ctrl_file.nonempty()) { + VarInfo * ctrl_info = (*var_it)->get_ctrl(i_ens); + + mlog << Debug(3) << "\n" + << "Reading control field: " + << ctrl_info->magic_str() << "\n"; // Error out if missing if(!get_data_plane(ctrl_file.c_str(), etype, - conf_info.ens_info[i_var], ctrl_dp)) { + ctrl_info, ctrl_dp)) { mlog << Error << "\nprocess_ensemble() -> " << "control member ensemble field \"" - << conf_info.ens_info[i_var]->magic_str() + << ctrl_info->magic_str() << "\" not found in file \"" << ctrl_file << "\"\n\n"; exit(1); } // Apply current data to the running sums and counts - track_counts(i_var, ctrl_dp, true, cmn_dp, csd_dp); + track_counts(*var_it, ctrl_dp, true, cmn_dp, csd_dp); } // end if ctrl_file @@ -381,26 +404,27 @@ void process_ensemble() { << " control member, " << (cmn_dp.is_empty() ? 0 : 1) << " climatology mean, and " << (csd_dp.is_empty() ? 0 : 1) << " climatology standard deviation field(s) for \"" - << conf_info.ens_info[i_var]->magic_str() << "\".\n"; + << var_info->magic_str() << "\".\n"; } // end if need_reset // Apply current data to the running sums and counts - track_counts(i_var, ens_dp, false, cmn_dp, csd_dp); + track_counts(*var_it, ens_dp, false, cmn_dp, csd_dp); // Keep track of the maximum initialization time if(is_bad_data(max_init_ut) || ens_dp.init() > max_init_ut) { max_init_ut = ens_dp.init(); } - } // end for i_file + } // end for it // Check for too much missing data - if(((double) n_ens_vld/n_ens) < conf_info.vld_ens_thresh) { + if(((double) n_ens_vld/n_ens_inputs) < conf_info.vld_ens_thresh) { mlog << Error << "\nprocess_ensemble() -> " - << n_ens - n_ens_vld << " of " << n_ens - << " missing fields for \"" << conf_info.ens_info[i_var]->magic_str() - << "\" exceeds the maximum allowable specified by \"" + << n_ens_vld << " of " << n_ens_inputs + << " (" << (double)n_ens_vld/n_ens_inputs << ")" + << " fields found for \"" << (*var_it)->get_var_info()->magic_str() + << "\" does not meet the threshold specified by \"" << conf_key_ens_ens_thresh << "\" (" << conf_info.vld_ens_thresh << ") in the configuration file.\n\n"; exit(1); @@ -408,9 +432,9 @@ void process_ensemble() { // Write out the ensemble information to a NetCDF file ens_dp.set_init(max_init_ut); - write_ens_nc(i_var, n_ens_vld, ens_dp, cmn_dp, csd_dp); + write_ens_nc(*var_it, n_ens_vld, ens_dp, cmn_dp, csd_dp); - } // end for i_var + } // end for var_it return; } @@ -441,14 +465,14 @@ void clear_counts() { //////////////////////////////////////////////////////////////////////// -void track_counts(int i_var, const DataPlane &ens_dp, bool is_ctrl, +void track_counts(EnsVarInfo * ens_info, const DataPlane &ens_dp, bool is_ctrl, const DataPlane &cmn_dp, const DataPlane &csd_dp) { int i, j, k; double ens, cmn, csd; // Ensemble thresholds - const int n_thr = conf_info.cat_ta[i_var].n(); - SingleThresh *thr_buf = conf_info.cat_ta[i_var].buf(); + const int n_thr = ens_info->cat_ta.n(); + SingleThresh *thr_buf = ens_info->cat_ta.buf(); // Increment counts for each grid point for(i=0; i 0 - if(conf_info.nc_info[i_var].do_nmep) { + if(ens_info->nc_info.do_nmep) { DataPlane frac_dp; // Loop over thresholds @@ -543,7 +567,7 @@ void setup_nc_file() { lon_dim = add_dim(nc_out, "lon", (long) grid.nx()); // Add the lat/lon variables - if(conf_info.nc_info[0].do_latlon) { + if(conf_info.ens_input[0]->nc_info.do_latlon) { write_netcdf_latlon(nc_out, &lat_dim, &lon_dim, grid); } @@ -552,7 +576,7 @@ void setup_nc_file() { //////////////////////////////////////////////////////////////////////// -void write_ens_nc(int i_var, int n_ens_vld, +void write_ens_nc(EnsVarInfo * ens_info, int n_ens_vld, const DataPlane &ens_dp, const DataPlane &cmn_dp, const DataPlane &csd_dp) { @@ -605,69 +629,69 @@ void write_ens_nc(int i_var, int n_ens_vld, } // end for i // Add the ensemble mean, if requested - if(conf_info.nc_info[i_var].do_mean) { - write_ens_var_float(i_var, ens_mean, ens_dp, + if(ens_info->nc_info.do_mean) { + write_ens_var_float(ens_info, ens_mean, ens_dp, "ENS_MEAN", "Ensemble Mean"); } // Add the ensemble standard deviation, if requested - if(conf_info.nc_info[i_var].do_stdev) { - write_ens_var_float(i_var, ens_stdev, ens_dp, + if(ens_info->nc_info.do_stdev) { + write_ens_var_float(ens_info, ens_stdev, ens_dp, "ENS_STDEV", "Ensemble Standard Deviation"); } // Add the ensemble mean minus one standard deviation, if requested - if(conf_info.nc_info[i_var].do_minus) { - write_ens_var_float(i_var, ens_minus, ens_dp, + if(ens_info->nc_info.do_minus) { + write_ens_var_float(ens_info, ens_minus, ens_dp, "ENS_MINUS", "Ensemble Mean Minus 1 Standard Deviation"); } // Add the ensemble mean plus one standard deviation, if requested - if(conf_info.nc_info[i_var].do_plus) { - write_ens_var_float(i_var, ens_plus, ens_dp, + if(ens_info->nc_info.do_plus) { + write_ens_var_float(ens_info, ens_plus, ens_dp, "ENS_PLUS", "Ensemble Mean Plus 1 Standard Deviation"); } // Add the ensemble minimum value, if requested - if(conf_info.nc_info[i_var].do_min) { - write_ens_var_float(i_var, ens_min, ens_dp, + if(ens_info->nc_info.do_min) { + write_ens_var_float(ens_info, ens_min, ens_dp, "ENS_MIN", "Ensemble Minimum"); } // Add the ensemble maximum value, if requested - if(conf_info.nc_info[i_var].do_max) { - write_ens_var_float(i_var, ens_max, ens_dp, + if(ens_info->nc_info.do_max) { + write_ens_var_float(ens_info, ens_max, ens_dp, "ENS_MAX", "Ensemble Maximum"); } // Add the ensemble range, if requested - if(conf_info.nc_info[i_var].do_range) { - write_ens_var_float(i_var, ens_range, ens_dp, + if(ens_info->nc_info.do_range) { + write_ens_var_float(ens_info, ens_range, ens_dp, "ENS_RANGE", "Ensemble Range"); } // Add the ensemble valid data count, if requested - if(conf_info.nc_info[i_var].do_vld) { - write_ens_var_int(i_var, ens_vld, ens_dp, + if(ens_info->nc_info.do_vld) { + write_ens_var_int(ens_info, ens_vld, ens_dp, "ENS_VLD", "Ensemble Valid Data Count"); } // Add the ensemble relative frequencies and neighborhood probabilities, if requested - if(conf_info.nc_info[i_var].do_freq || - conf_info.nc_info[i_var].do_nep) { + if(ens_info->nc_info.do_freq || + ens_info->nc_info.do_nep) { prob_dp.set_size(grid.nx(), grid.ny()); // Loop through each threshold - for(i=0; icat_ta.n(); i++) { // Initialize prob_dp.erase(); @@ -680,15 +704,15 @@ void write_ens_nc(int i_var, int n_ens_vld, } // Write ensemble relative frequency - if(conf_info.nc_info[i_var].do_freq) { + if(ens_info->nc_info.do_freq) { snprintf(type_str, sizeof(type_str), "ENS_FREQ_%s", - conf_info.cat_ta[i_var][i].get_abbr_str().contents().c_str()); - write_ens_data_plane(i_var, prob_dp, ens_dp, type_str, + ens_info->cat_ta[i].get_abbr_str().contents().c_str()); + write_ens_data_plane(ens_info, prob_dp, ens_dp, type_str, "Ensemble Relative Frequency"); } // Process the neighborhood ensemble probability - if(conf_info.nc_info[i_var].do_nep) { + if(ens_info->nc_info.do_nep) { GaussianInfo info; // Loop over the neighborhoods @@ -701,10 +725,10 @@ void write_ens_nc(int i_var, int n_ens_vld, // Write neighborhood ensemble probability snprintf(type_str, sizeof(type_str), "ENS_NEP_%s_%s%i", - conf_info.cat_ta[i_var][i].get_abbr_str().contents().c_str(), + ens_info->cat_ta[i].get_abbr_str().contents().c_str(), interpmthd_to_string(InterpMthd_Nbrhd).c_str(), conf_info.nbrhd_prob.width[j]*conf_info.nbrhd_prob.width[j]); - write_ens_data_plane(i_var, nbrhd_dp, ens_dp, type_str, + write_ens_data_plane(ens_info, nbrhd_dp, ens_dp, type_str, "Neighborhood Ensemble Probability"); } // end for k } // end if do_nep @@ -712,12 +736,12 @@ void write_ens_nc(int i_var, int n_ens_vld, } // end if // Add the neighborhood maximum ensemble probabilities, if requested - if(conf_info.nc_info[i_var].do_nmep) { + if(ens_info->nc_info.do_nmep) { prob_dp.set_size(grid.nx(), grid.ny()); // Loop through each threshold - for(i=0; icat_ta.n(); i++) { // Loop through each neigbhorhood size for(j=0; jcat_ta[i].get_abbr_str().contents().c_str(), interpmthd_to_string(InterpMthd_Nbrhd).c_str(), conf_info.nbrhd_prob.width[j]*conf_info.nbrhd_prob.width[j], conf_info.nmep_smooth.method[k].c_str(), conf_info.nmep_smooth.width[k]*conf_info.nmep_smooth.width[k]); - write_ens_data_plane(i_var, nbrhd_dp, ens_dp, type_str, + write_ens_data_plane(ens_info, nbrhd_dp, ens_dp, type_str, "Neighborhood Maximum Ensemble Probability"); } // end for k } // end for j @@ -757,26 +781,26 @@ void write_ens_nc(int i_var, int n_ens_vld, } // end if do_nep // Write the climo mean field, if requested - if(conf_info.nc_info[i_var].do_climo && !cmn_dp.is_empty()) { - write_ens_data_plane(i_var, cmn_dp, ens_dp, + if(ens_info->nc_info.do_climo && !cmn_dp.is_empty()) { + write_ens_data_plane(ens_info, cmn_dp, ens_dp, "CLIMO_MEAN", "Climatology mean"); } // Write the climo stdev field, if requested - if(conf_info.nc_info[i_var].do_climo && !csd_dp.is_empty()) { - write_ens_data_plane(i_var, csd_dp, ens_dp, + if(ens_info->nc_info.do_climo && !csd_dp.is_empty()) { + write_ens_data_plane(ens_info, csd_dp, ens_dp, "CLIMO_STDEV", "Climatology standard deviation"); } // Write the climo distribution percentile thresholds, if requested - if(conf_info.nc_info[i_var].do_climo_cdp && + if(ens_info->nc_info.do_climo_cdp && !cmn_dp.is_empty() && !csd_dp.is_empty()) { DataPlane cdp_dp; vector simp; - conf_info.cat_ta[i_var].get_simple_nodes(simp); + ens_info->cat_ta.get_simple_nodes(simp); // Process all CDP thresholds except 0 and 100 for(vector::iterator it = simp.begin(); @@ -787,7 +811,7 @@ void write_ens_nc(int i_var, int n_ens_vld, snprintf(type_str, sizeof(type_str), "CLIMO_CDP%i", nint(it->pvalue())); cdp_dp = normal_cdf_inv(it->pvalue()/100.0, cmn_dp, csd_dp); - write_ens_data_plane(i_var, cdp_dp, ens_dp, + write_ens_data_plane(ens_info, cdp_dp, ens_dp, type_str, "Climatology distribution percentile"); } @@ -809,20 +833,20 @@ void write_ens_nc(int i_var, int n_ens_vld, //////////////////////////////////////////////////////////////////////// -void write_ens_var_float(int i_var, float *ens_data, const DataPlane &dp, +void write_ens_var_float(EnsVarInfo * ens_info, float *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; // Append nc_var_str config file entry - cs = conf_info.nc_var_str[i_var]; + cs = ens_info->nc_var_str; if(cs.length() > 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" - << conf_info.ens_info[i_var]->level_attr() + << ens_info->get_var_info()->name_attr() << "_" + << ens_info->get_var_info()->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -840,16 +864,16 @@ void write_ens_var_float(int i_var, float *ens_data, const DataPlane &dp, // if(strcmp(type_str, "ENS_MEAN") == 0) { name_str << cs_erase - << conf_info.ens_info[i_var]->name_attr(); + << ens_info->get_var_info()->name_attr(); } else { name_str << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" + << ens_info->get_var_info()->name_attr() << "_" << type_str; } // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_var], &ens_var, false, dp, + add_var_att_local(ens_info->get_var_info(), &ens_var, false, dp, name_str.c_str(), long_name_str); // Write the data @@ -865,20 +889,20 @@ void write_ens_var_float(int i_var, float *ens_data, const DataPlane &dp, //////////////////////////////////////////////////////////////////////// -void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, +void write_ens_var_int(EnsVarInfo * ens_info, int *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; // Append nc_var_str config file entry - cs = conf_info.nc_var_str[i_var]; + cs = ens_info->nc_var_str; if(cs.length() > 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" - << conf_info.ens_info[i_var]->level_attr() + << ens_info->get_var_info()->name_attr() << "_" + << ens_info->get_var_info()->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -892,11 +916,11 @@ void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, // Construct the variable name attribute name_str << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" + << ens_info->get_var_info()->name_attr() << "_" << type_str; // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_var], &ens_var, true, dp, + add_var_att_local(ens_info->get_var_info(), &ens_var, true, dp, name_str.c_str(), long_name_str); // Write the data @@ -912,7 +936,7 @@ void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, //////////////////////////////////////////////////////////////////////// -void write_ens_data_plane(int i_var, const DataPlane &ens_dp, const DataPlane &dp, +void write_ens_data_plane(EnsVarInfo * ens_info, const DataPlane &ens_dp, const DataPlane &dp, const char *type_str, const char *long_name_str) { // Allocate memory for this data @@ -922,7 +946,7 @@ void write_ens_data_plane(int i_var, const DataPlane &ens_dp, const DataPlane &d for(int i=0; i::const_iterator it; + vector::const_iterator var_it = ens_input.begin(); // Clear, erase, and initialize members model.clear(); desc.clear(); - for(it = ens_info.begin(); it != ens_info.end(); it++) { - if(*it) { delete *it; } + + for(; var_it != ens_input.end(); var_it++) { + + if(*var_it) { delete *var_it; } + } - ens_info.clear(); + ens_input.clear(); cdf_info.clear(); - cat_ta.clear(); - nc_var_str.clear(); nbrhd_prob.clear(); nmep_smooth.clear(); vld_ens_thresh = bad_data_double; vld_data_thresh = bad_data_double; - nc_info.clear(); version.clear(); // Reset counts @@ -100,12 +100,18 @@ void GenEnsProdConfInfo::read_config(const ConcatString default_file_name, //////////////////////////////////////////////////////////////////////// -void GenEnsProdConfInfo::process_config(GrdFileType etype) { - int i; +void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_files) { + int i, j; VarInfoFactory info_factory; Dictionary *edict = (Dictionary *) 0; Dictionary i_edict; InterpMthd mthd; + VarInfo * next_var; + + int n_ens_files = ens_files->n(); + + // Unset MET_ENS_MEMBER_ID in case it is set by the user + unsetenv(met_ens_member_id); // Dump the contents of the config file if(mlog.verbosity_level() >= 5) conf.dump(cout); @@ -122,6 +128,38 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype) { // Conf: desc desc = parse_conf_string(&conf, conf_key_desc); + // Conf: ens_member_ids + ens_member_ids = parse_conf_ens_member_ids(&conf); + + // Conf: control_id + control_id = parse_conf_string(&conf, conf_key_control_id, false); + + // Error check ens_member_ids and ensemble file list + if(ens_member_ids.n() > 1) { + + // Only a single file should be provided if using ens_member_ids + if(n_ens_files > 1) { + mlog << Error << "\nGenEnsProdConfInfo::process_config() -> " + << "The \"" << conf_key_ens_member_ids << "\" " + << "must be empty if more than " + << "one file is provided.\n\n"; + exit(1); + } + + // If control ID is set, it cannot be found in ens_member_ids + if(!control_id.empty() && ens_member_ids.has(control_id)) { + mlog << Error << "\nGenEnsProdConfInfo::process_config() -> " + << "control_id (" << control_id << ") must not be found " + << "in ens_member_ids\n\n"; + exit(1); + } + } + + // If no ensemble member IDs were provided, add an empty string + if(ens_member_ids.n() == 0) { + ens_member_ids.add(""); + } + // Conf: ens.field edict = conf.lookup_array(conf_key_ens_field); @@ -136,41 +174,87 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype) { // Parse the ensemble field information for(i=0,max_n_cat=0; iset_dict(i_edict); + // get VarInfo magic string without substituted values + ens_info->raw_magic_str = raw_magic_str(i_edict); - // Dump the contents of the current VarInfo - if(mlog.verbosity_level() >= 5) { - mlog << Debug(5) - << "Parsed ensemble field number " << i+1 << ":\n"; - ens_info[i]->dump(cout); + // Loop over ensemble member IDs to substitute + for(j=0; jset_dict(i_edict); + + // Dump the contents of the current VarInfo + if(mlog.verbosity_level() >= 5) { + mlog << Debug(5) + << "Parsed ensemble field number " << i+1 + << " (" << j+1 << "):\n"; + next_var->dump(cout); + } + + InputInfo input_info; + input_info.var_info = next_var; + input_info.file_index = 0; + input_info.file_list = ens_files; + ens_info->add_input(input_info); + + // Add InputInfo to ens info list for each ensemble file provided + // set var_info to NULL to note first VarInfo should be used + for(int k=1; kadd_input(input_info); + } // end for k + + } // end for j + + // Get field info for control member if set + if(!control_id.empty()) { + + // Set environment variable for ens member ID + setenv(met_ens_member_id, control_id.c_str(), 1); + + // Allocate new VarInfo object + next_var = info_factory.new_var_info(etype); + + // Set the current dictionary + next_var->set_dict(i_edict); + + ens_info->set_ctrl(next_var); } // Conf: nc_var_str - nc_var_str.add(parse_conf_string(&i_edict, conf_key_nc_var_str, false)); + ens_info->nc_var_str =parse_conf_string(&i_edict, conf_key_nc_var_str, false); // Conf: cat_thresh - cat_ta.push_back(i_edict.lookup_thresh_array(conf_key_cat_thresh)); + ens_info->cat_ta = i_edict.lookup_thresh_array(conf_key_cat_thresh); // Dump the contents of the current thresholds if(mlog.verbosity_level() >= 5) { mlog << Debug(5) << "Parsed thresholds for ensemble field number " << i+1 << ":\n"; - cat_ta[i].dump(cout); + ens_info->cat_ta.dump(cout); } // Keep track of the maximum number of thresholds - if(cat_ta[i].n() > max_n_cat) max_n_cat = cat_ta[i].n(); + if(ens_info->cat_ta.n() > max_n_cat) max_n_cat = ens_info->cat_ta.n(); // Conf: ensemble_flag - nc_info.push_back(parse_nc_info(&i_edict)); - } + ens_info->nc_info = parse_nc_info(&i_edict); + + ens_input.push_back(ens_info); + } // end for i // Conf: ens.ens_thresh vld_ens_thresh = conf.lookup_double(conf_key_ens_ens_thresh); @@ -360,3 +444,94 @@ void GenEnsProdNcOutInfo::set_all_true() { } //////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +// +// Code for class EnsVarInfo +// +//////////////////////////////////////////////////////////////////////// + +EnsVarInfo::EnsVarInfo() { + ctrl_info = NULL; +} + +//////////////////////////////////////////////////////////////////////// + +EnsVarInfo::~EnsVarInfo() { + vector::const_iterator it; + for(it = inputs.begin(); it != inputs.end(); it++) { + if((*it).var_info) { delete (*it).var_info; } + } + + if(ctrl_info) { delete ctrl_info; } +} + +//////////////////////////////////////////////////////////////////////// + +void EnsVarInfo::add_input(InputInfo input) { + inputs.push_back(input); +} + +//////////////////////////////////////////////////////////////////////// + +int EnsVarInfo::inputs_n() { + return inputs.size(); +} + +//////////////////////////////////////////////////////////////////////// + +void EnsVarInfo::set_ctrl(VarInfo * ctrl) { + ctrl_info = ctrl; +} + +//////////////////////////////////////////////////////////////////////// + +VarInfo * EnsVarInfo::get_ctrl(int index) { + if(ctrl_info) { + return ctrl_info; + } + return inputs[index].var_info; +} + +//////////////////////////////////////////////////////////////////////// + +VarInfo * EnsVarInfo::get_var_info(int index) { + if(inputs[index].var_info) { + return inputs[index].var_info; + } + return inputs[0].var_info; +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString EnsVarInfo::get_file(int index) { + int file_index = inputs[index].file_index; + return (*inputs[index].file_list)[file_index]; +} + +//////////////////////////////////////////////////////////////////////// + +int EnsVarInfo::get_file_index(int index) { + return inputs[index].file_index; +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString raw_magic_str(Dictionary i_edict) { + ConcatString magic_str; + + ConcatString name = i_edict.lookup_string("name"); + ConcatString level = i_edict.lookup_string("level"); + + if(level.nonempty() && level[0] != '(') { + magic_str << name << "/" << level; + } else { + magic_str << name << level; + } + + return magic_str; + +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h index 2ec6014824..d0d5e60bbe 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h @@ -51,6 +51,43 @@ struct GenEnsProdNcOutInfo { void set_all_true(); }; + +//////////////////////////////////////////////////////////////////////// + +struct InputInfo { + VarInfo * var_info; // Variable information to read + int file_index; // Index in file_list of file to read + StringArray * file_list; // Array of files (unallocated) +}; + +//////////////////////////////////////////////////////////////////////// + +class EnsVarInfo { + + private: + vector inputs; // Vector of InputInfo + VarInfo * ctrl_info; // Field info for control member + public: + EnsVarInfo(); + ~EnsVarInfo(); + + void add_input(InputInfo); + int inputs_n(); + + void set_ctrl(VarInfo *); + VarInfo * get_ctrl(int); + + // Get VarInfo from first InputInfo if requested VarInfo is NULL + VarInfo * get_var_info(int index=0); + ConcatString get_file(int index=0); + int get_file_index(int index=0); + + ConcatString nc_var_str; // Ensemble variable name strings + ThreshArray cat_ta; // Ensemble categorical thresholds + GenEnsProdNcOutInfo nc_info; // Ensemble product outputs + ConcatString raw_magic_str; // Magic string w/o var substitution +}; + //////////////////////////////////////////////////////////////////////// class GenEnsProdConfInfo { @@ -76,12 +113,11 @@ class GenEnsProdConfInfo { // Data parsed from the Gen-Ens-Prod configuration object ConcatString model; // Model name ConcatString desc; // Description + ConcatString control_id; // Control ID - vector ens_info; // Array of VarInfo pointers (allocated) + vector ens_input; // Vector of EnsVarInfo pointers (allocated) vector cdf_info; // Array of climo CDF info objects - vector cat_ta; // Array for ensemble categorical thresholds - StringArray nc_var_str; // Array of ensemble variable name strings - vector nc_info; // Array of ensemble product outputs + StringArray ens_member_ids; // Array of ensemble member ID strings NbrhdInfo nbrhd_prob; // Neighborhood probability definition InterpInfo nmep_smooth; // Neighborhood maximum smoothing information @@ -96,7 +132,7 @@ class GenEnsProdConfInfo { void clear(); void read_config (const ConcatString, const ConcatString); - void process_config(GrdFileType); + void process_config(GrdFileType, StringArray *); GenEnsProdNcOutInfo parse_nc_info(Dictionary *); @@ -116,6 +152,8 @@ inline int GenEnsProdConfInfo::get_compression_level() { return(conf.nc_compress //////////////////////////////////////////////////////////////////////// +ConcatString raw_magic_str(Dictionary i_edict); + #endif /* __GEN_ENS_PROD_CONF_INFO_H__ */ //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/other/mode_graphics/plot_mode_field.cc b/met/src/tools/other/mode_graphics/plot_mode_field.cc index 8d0894f154..ab77a6bb4c 100644 --- a/met/src/tools/other/mode_graphics/plot_mode_field.cc +++ b/met/src/tools/other/mode_graphics/plot_mode_field.cc @@ -1111,7 +1111,7 @@ if ( e->type() != StringType ) { } -s = *(e->string_value()); +s = e->string_value(); return ( s ); diff --git a/scripts/environment/development.seneca b/scripts/environment/development.seneca index 325e80ed3b..5b3497c0c1 100644 --- a/scripts/environment/development.seneca +++ b/scripts/environment/development.seneca @@ -48,5 +48,5 @@ export MET_TEST_RSCRIPT=/usr/local/R-4.1.2/bin/Rscript # - NetCDF is for ncdump. export PATH="/usr/local/nco/bin:/usr/local/netcdf/bin:\ /usr/local/sbin:/usr/local/bin:/usr/sbin:\ - /usr/bin:/sbin:/bin:/usr/bin/X11:/opt/bin" + /usr/bin:/sbin:/bin:/usr/bin/X11:/opt/bin:$PATH" diff --git a/test/config/GenEnsProdConfig b/test/config/GenEnsProdConfig index 33fcc2337f..3c4af297ef 100644 --- a/test/config/GenEnsProdConfig +++ b/test/config/GenEnsProdConfig @@ -74,6 +74,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/GenEnsProdConfig_single_file_grib b/test/config/GenEnsProdConfig_single_file_grib new file mode 100644 index 0000000000..cc5edda640 --- /dev/null +++ b/test/config/GenEnsProdConfig_single_file_grib @@ -0,0 +1,149 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Gen-Ens-Prod configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "GEFS"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "NA"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// May be set separately in each "field" entry +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + +// +// Ensemble fields to be processed +// +ens = { + ens_thresh = 1.0; + vld_thresh = 1.0; + + field = [ + { + name = "PRMSL"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "MET_ENS_MEMBER_ID"; + } + ]; +} + +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = ["+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15", "+16", "+17", "+18", "+19", "+20"]; +control_id = "hi_res_ctl"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood ensemble probabilities +// +nbrhd_prob = { + width = [ 5 ]; + shape = CIRCLE; + vld_thresh = 0.0; +} + +// +// NMEP smoothing methods +// +nmep_smooth = { + vld_thresh = 0.0; + shape = CIRCLE; + gaussian_dx = 81.27; + gaussian_radius = 120; + type = [ + { + method = GAUSSIAN; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = { + + file_name = []; + field = []; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 31; + hour_interval = 6; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Ensemble product output types +// May be set separately in each "ens.field" entry +// +ensemble_flag = { + latlon = TRUE; + mean = TRUE; + stdev = TRUE; + minus = TRUE; + plus = TRUE; + min = TRUE; + max = TRUE; + range = TRUE; + vld_count = TRUE; + frequency = TRUE; + nep = FALSE; + nmep = FALSE; + climo = FALSE; + climo_cdp = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_single_file_nc b/test/config/GenEnsProdConfig_single_file_nc new file mode 100644 index 0000000000..1049dc6a3a --- /dev/null +++ b/test/config/GenEnsProdConfig_single_file_nc @@ -0,0 +1,149 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Gen-Ens-Prod configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "WRF"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "NA"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// May be set separately in each "field" entry +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + +// +// Ensemble fields to be processed +// +ens = { + file_type = NETCDF_NCCF; + ens_thresh = 1.0; + vld_thresh = 1.0; + + field = [ + { + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,0,*,*)"; + cat_thresh = [ >0.0, >=5.0 ]; + } + ]; +} + +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]; +control_id = "0"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood ensemble probabilities +// +nbrhd_prob = { + width = [ 5 ]; + shape = CIRCLE; + vld_thresh = 0.0; +} + +// +// NMEP smoothing methods +// +nmep_smooth = { + vld_thresh = 0.0; + shape = CIRCLE; + gaussian_dx = 81.27; + gaussian_radius = 120; + type = [ + { + method = GAUSSIAN; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = ens; +climo_mean = { + + file_name = []; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 31; + hour_interval = 6; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Ensemble product output types +// May be set separately in each "ens.field" entry +// +ensemble_flag = { + latlon = TRUE; + mean = TRUE; + stdev = TRUE; + minus = TRUE; + plus = TRUE; + min = TRUE; + max = TRUE; + range = TRUE; + vld_count = TRUE; + frequency = TRUE; + nep = FALSE; + nmep = FALSE; + climo = FALSE; + climo_cdp = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/xml/unit_gen_ens_prod.xml b/test/xml/unit_gen_ens_prod.xml index 9d3f2b0c75..91f2321431 100644 --- a/test/xml/unit_gen_ens_prod.xml +++ b/test/xml/unit_gen_ens_prod.xml @@ -75,4 +75,58 @@ - + + &MET_BIN;/gen_ens_prod + \ + -ens &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -config &CONFIG_DIR;/GenEnsProdConfig_single_file_nc \ + -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_NC_NO_CTRL.nc \ + -v 2 + + + &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_NC_NO_CTRL.nc + + + + + &MET_BIN;/gen_ens_prod + \ + -ens &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -config &CONFIG_DIR;/GenEnsProdConfig_single_file_nc \ + -ctrl &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_NC_WITH_CTRL.nc \ + -v 2 + + + &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_NC_WITH_CTRL.nc + + + + + &MET_BIN;/gen_ens_prod + \ + -ens &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -config &CONFIG_DIR;/GenEnsProdConfig_single_file_grib \ + -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_GRIB_NO_CTRL.nc \ + -v 2 + + + &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_GRIB_NO_CTRL.nc + + + + + &MET_BIN;/gen_ens_prod + \ + -ens &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -config &CONFIG_DIR;/GenEnsProdConfig_single_file_grib \ + -ctrl &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_GRIB_WITH_CTRL.nc \ + -v 2 + + + &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_GRIB_WITH_CTRL.nc + + + + From be7910eaa6bc3a8f4191ae501d0e9095880ec0ce Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Wed, 12 Jan 2022 16:21:10 -0700 Subject: [PATCH 052/172] Feature 1965 NB faile with time summary by ioda2nc (#2008) Co-authored-by: Howard Soh --- met/src/tools/other/ioda2nc/ioda2nc.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index 323cd83447..df1830c084 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -369,7 +369,7 @@ void process_ioda_file(int i_pb) { IntArray diff_file_times; int diff_file_time_count; StringArray variables_big_nlevels; - static const char *method_name = "process_ioda_file() ->"; + static const char *method_name = "process_ioda_file() -> "; static const char *method_name_s = "process_ioda_file() "; bool apply_grid_mask = (conf_info.grid_mask.nx() > 0 && @@ -961,7 +961,9 @@ void addObservation(const float *obs_arr, const ConcatString &hdr_typ, else obs_qty.format("%d", nint(quality_mark)); int var_index = obs_arr[1]; + map name_map = conf_info.getObsVarMap(); string var_name = obs_var_names[var_index]; + string out_name = name_map[var_name]; Observation obs = Observation(hdr_typ.text(), hdr_sid.text(), hdr_vld, @@ -969,7 +971,7 @@ void addObservation(const float *obs_arr, const ConcatString &hdr_typ, obs_qty.text(), var_index, obs_arr[2], obs_arr[3], obs_arr[4], - var_name); + (0addObservationObj(obs); From 1e13dea8e927ca9982bac3c2ec5c97bde1ef1cf6 Mon Sep 17 00:00:00 2001 From: johnhg Date: Wed, 12 Jan 2022 20:12:20 -0700 Subject: [PATCH 053/172] Feature 1810 shapes (#2005) --- met/docs/Users_Guide/tc-gen.rst | 73 ++- met/src/basic/vx_config/Makefile.am | 1 - met/src/libcode/vx_color/Makefile.am | 1 - met/src/libcode/vx_gis/Makefile.am | 28 +- met/src/libcode/vx_gis/dbf_file.cc | 400 +++++++++++++++- met/src/libcode/vx_gis/dbf_file.h | 78 +++- met/src/libcode/vx_gis/shp_array.h | 2 + met/src/libcode/vx_gis/shp_file.cc | 5 - met/src/libcode/vx_gis/shp_file.h | 5 - met/src/libcode/vx_gis/shp_poly_record.cc | 21 + met/src/libcode/vx_gis/shp_poly_record.h | 11 +- met/src/libcode/vx_gis/vx_gis.h | 29 ++ met/src/libcode/vx_statistics/Makefile.am | 1 + .../vx_statistics}/grid_closed_poly.cc | 226 ++++------ .../vx_statistics}/grid_closed_poly.h | 38 +- met/src/libcode/vx_statistics/vx_statistics.h | 1 + met/src/libcode/vx_tc_util/Makefile.am | 1 + met/src/libcode/vx_tc_util/gen_shape_info.cc | 377 ++++++++++++++++ met/src/libcode/vx_tc_util/gen_shape_info.h | 149 ++++++ met/src/libcode/vx_tc_util/vx_tc_util.h | 1 + met/src/tools/core/grid_stat/grid_stat.cc | 2 +- met/src/tools/core/point_stat/point_stat.cc | 2 +- met/src/tools/other/gen_vx_mask/Makefile.am | 6 +- .../tools/other/gen_vx_mask/gen_vx_mask.cc | 75 +-- met/src/tools/tc_utils/tc_gen/Makefile.am | 1 + met/src/tools/tc_utils/tc_gen/tc_gen.cc | 426 ++++++++++++++++-- met/src/tools/tc_utils/tc_gen/tc_gen.h | 16 +- .../tools/tc_utils/tc_gen/tc_gen_conf_info.cc | 154 ++++++- .../tools/tc_utils/tc_gen/tc_gen_conf_info.h | 33 +- test/config/TCGenConfig_shape | 292 ++++++++++++ test/xml/unit_tc_gen.xml | 19 + 31 files changed, 2102 insertions(+), 372 deletions(-) create mode 100644 met/src/libcode/vx_gis/vx_gis.h rename met/src/{tools/other/gen_vx_mask => libcode/vx_statistics}/grid_closed_poly.cc (53%) rename met/src/{tools/other/gen_vx_mask => libcode/vx_statistics}/grid_closed_poly.h (76%) create mode 100644 met/src/libcode/vx_tc_util/gen_shape_info.cc create mode 100644 met/src/libcode/vx_tc_util/gen_shape_info.h create mode 100644 test/config/TCGenConfig_shape diff --git a/met/docs/Users_Guide/tc-gen.rst b/met/docs/Users_Guide/tc-gen.rst index b67f1a26b9..74271ec9e1 100644 --- a/met/docs/Users_Guide/tc-gen.rst +++ b/met/docs/Users_Guide/tc-gen.rst @@ -6,19 +6,25 @@ TC-Gen Tool Introduction ____________ -The TC-Gen tool provides verification of deterministic and probabilistic tropical cyclone genesis forecasts in the ATCF file format. Producing reliable tropical cyclone genesis forecasts is an important metric for global numerical weather prediction models. This tool ingests deterministic model output post-processed by a genesis tracking software (e.g. GFDL vortex tracker), ATCF edeck files containing probability of genesis forecasts, and ATCF reference track dataset(s) (e.g. Best Track analysis and CARQ operational tracks). It writes categorical counts and statistics. The capability to modify the spatial and temporal tolerances when matching forecasts to reference genesis events, as well as scoring those matched pairs, gives users the ability to condition the criteria based on model performance and/or conduct sensitivity analyses. Statistical aspects are outlined in :numref:`tc-gen_stat_aspects` and practical aspects of the TC-Gen tool are described in :numref:`tc-gen_practical_info`. +The TC-Gen tool provides verification of deterministic and probabilistic tropical cyclone genesis forecasts in the ATCF file and shapefile formats. Producing reliable tropical cyclone genesis forecasts is an important metric for global numerical weather prediction models. This tool ingests deterministic model output post-processed by genesis tracking software (e.g. GFDL vortex tracker), ATCF edeck files containing probability of genesis forecasts, operational shapefile warning areas, and ATCF reference track dataset(s) (e.g. Best Track analysis and CARQ operational tracks). It writes categorical counts and statistics. The capability to modify the spatial and temporal tolerances when matching forecasts to reference genesis events, as well as scoring those matched pairs, gives users the ability to condition the criteria based on model performance and/or conduct sensitivity analyses. Statistical aspects are outlined in :numref:`tc-gen_stat_aspects` and practical aspects of the TC-Gen tool are described in :numref:`tc-gen_practical_info`. .. _tc-gen_stat_aspects: Statistical aspects ___________________ -The TC-Gen tool processes both deterministic and probabilistic forecasts. For deterministic forecasts specified using the **-track** command line option, it identifies genesis events in both the forecasts and reference datasets, typically Best tracks. It applies user-specified configuration options to pair up the forecast and reference genesis events and categorize each pair as a hit, miss, or false alarm. +The TC-Gen tool processes both deterministic and probabilistic forecasts. + +For deterministic forecasts specified using the **-track** command line option, it identifies genesis events in both the forecasts and reference datasets, typically Best tracks. It applies user-specified configuration options to pair up the forecast and reference genesis events and categorize each pair as a hit, miss, or false alarm. As with other extreme events (where the event occurs much less frequently than the non-event), the correct negative category is not computed since the non-events would dominate the contingency table. Therefore, only statistics that do not include correct negatives should be considered for this tool. The following CTS statistics are relevant: Base rate (BASER), Mean forecast (FMEAN), Frequency Bias (FBIAS), Probability of Detection (PODY), False Alarm Ratio (FAR), Critical Success Index (CSI), Gilbert Skill Score (GSS), Extreme Dependency Score (EDS), Symmetric Extreme Dependency Score (SEDS), Bias Adjusted Gilbert Skill Score (BAGSS). For probabilistic forecasts specified using the **-edeck** command line option, it identifies genesis events in the reference dataset. It applies user-specified configuration options to pair the forecast probabilities to the reference genesis events. These pairs are added to an Nx2 probabilistic contingency table. If the reference genesis event occurs within in the predicted time window, the pair is counted in the observation-yes column. Otherwise, it is added to the observation-no column. +For warning area shapefiles specified using the **-shape** command line option, it processes metadata from the corresponding database files. The database file is assumed to exist at exactly the same path as the shapefile, but with a ".dbf" suffix instead of ".shp". Note that only shapefiles exactly following the NOAA National Hurricane Center's (NHC) "gtwo_areas_YYYYMMDDHHMM.shp" file naming and corresonding metadata conventions are supported. For each shapefile record, the database file defines up to three corresponding probability values. The first percentage is interpreted as the probability of genesis inside the shape within 48 hours. The second and, if provided, third percentages are interpreted as the 120-hour and 168-hour probabilities, respectively. Care is taken to identify and either ignore or update duplicate shapes found in the input. + +The shapes are then subset based on the filtering criteria in the configuration file. For each probability and shape, the reference genesis events are searched for a match within the defined time window. These pairs are added to an Nx2 probabilistic contingency table. The probabilistic contingeny tables and statistics are computed and reported separately for filter defined and lead hour encountered in the input. + Other considerations for interpreting the output of the TC-Gen tool involve the size of the contingency table output. The size of the contingency table will change depending on the number of matches. Additionally, the number of misses is based on the forecast duration and interval (specified in the configuration file). This change is due to the number of model opportunities to forecast the event, which is determined by the specified duration/interval. Care should be taken when interpreting the statistics for filtered data. In some cases, variables (e.g. storm name) are only available in either the forecast or reference datasets, rather than both. When filtering on a field that is only present in one dataset, the contingency table counts will be impacted. Similarly, the initialization field only impacts the model forecast data. If the valid time (which will impact the reference dataset) isn't also specified, the forecasts will be filtered and matched such that the number of misses will erroneously increase. See :numref:`tc-gen_practical_info` for more detail. @@ -28,7 +34,7 @@ Care should be taken when interpreting the statistics for filtered data. In some Practical information _____________________ -This section describes how to configure and run the TC-Gen tool. The TC-Gen tool identifies tropical cyclone genesis events in both genesis forecasts and ATCF track datasets. It applies configurable logic to process the forecast and observed genesis events, classify them, and populate a contingency table with hits, misses, and false alarms. It writes the categorical counts and statistics to the output file(s). The tool can be configured to apply one or more sets of filtering criteria in a single run. The following sections describe the usage statement, required arguments, and optional arguments for tc_gen. +This section describes how to configure and run the TC-Gen tool. The following sections describe the usage statement, required arguments, and optional arguments for tc_gen. tc_gen usage ~~~~~~~~~~~~ @@ -38,7 +44,9 @@ The usage statement for tc_gen is shown below: .. code-block:: none Usage: tc_gen - -genesis source and/or -edeck source + -genesis source + -edeck source + -shape source -track source -config file [-out base] @@ -52,20 +60,24 @@ Required arguments for tc_gen 1. The **-genesis source** argument is the path to one or more ATCF or fort.66 (see documentation listed below) files generated by the Geophysical Fluid Dynamics Laboratory (GFDL) Vortex Tracker when run in tcgen mode or an ASCII file list or a top-level directory containing them. The required file format is described in the "Output formats" section of the `GFDL Vortex Tracker users guide. `_ -2. The **-edeck source** argument is the path to one or more ATCF edeck files, an ASCII file list containing them, or a top-level directory with files matching the regular expression ".dat". The probability of genesis are read from each edeck input file and verified against at the **-track** data. The **-genesis** or **-edeck** option must be used at least once. +2. The **-edeck source** argument is the path to one or more ATCF edeck files, an ASCII file list containing them, or a top-level directory with files matching the regular expression ".dat". The probability of genesis are read from each edeck input file and verified against at the **-track** data. -3. The **-track source** argument is one or more ATCF reference track files or an ASCII file list or top-level directory containing them, with files ending in ".dat". This tool processes either Best track data from bdeck files, or operational track data (e.g. CARQ) from adeck files, or both. Providing both bdeck and adeck files will result in a richer dataset to match with the **-genesis** files. Both adeck and bdeck data should be provided using the **-track** option. The **-track** option must be used at least once. +3. The **-shape source** argument is the path to one or more NHC genesis warning area shapefiles, an ASCII file list containing them, or a top-level directory with files matching the regular expression "gtwo_areas.*.shp". The genesis warning areas and corresponding 2, 5, and 7 day probability values area verified against the **-track** data. -4. The **-config** file argument indicates the name of the configuration file to be used. The contents of the configuration file are discussed below. +Note: The **-genesis**, **-edeck**, or **-shape** options must be used at least once. + +4. The **-track source** argument is one or more ATCF reference track files or an ASCII file list or top-level directory containing them, with files ending in ".dat". This tool processes either Best track data from bdeck files, or operational track data (e.g. CARQ) from adeck files, or both. Providing both bdeck and adeck files will result in a richer dataset to match with the **-genesis** files. Both adeck and bdeck data should be provided using the **-track** option. The **-track** option must be used at least once. + +5. The **-config** file argument indicates the name of the configuration file to be used. The contents of the configuration file are discussed below. Optional arguments for tc_gen ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -5. The **-out base** argument indicates the path of the output file base. This argument overrides the default output file base (./tc_gen) +6. The **-out base** argument indicates the path of the output file base. This argument overrides the default output file base (./tc_gen) -6. The **-log file** option directs output and errors to the specified log file. All messages will be written to that file as well as standard out and error. Thus, users can save the messages without having to redirect the output on the command line. The default behavior is no log file. +7. The **-log file** option directs output and errors to the specified log file. All messages will be written to that file as well as standard out and error. Thus, users can save the messages without having to redirect the output on the command line. The default behavior is no log file. -7. The **-v level** option indicates the desired level of verbosity. The contents of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity above 1 will increase the amount of logging. +8. The **-v level** option indicates the desired level of verbosity. The contents of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity above 1 will increase the amount of logging. Scoring Logic ^^^^^^^^^^^^^ @@ -120,6 +132,29 @@ The TC-Gen tool implements the following logic: * Report the Nx2 probabilistic contingency table counts and statistics for each forecast model, lead time, and configuration file filter. These counts and statistics are identified in the output files as *PROB_GENESIS*. +* For **-shape** inputs: + + * For each input shapefile, parse the timestamp from the "gtwo_areas_YYYYMMDDHHMM.shp" naming convention, and error out otherwise. Round the timestamp to the nearest synoptic time (e.g. 00, 06, 12, 18) and store that as the issuance time. + + * Open the shapefile and corresponding database file. Process each record. + + * For each record, extract the shape and metadata which defines the basin and 2, 5, and 7 day probabilities. + + * Check if this shape is a duplicate that has already been processed. If it is an exact duplicate, with the same basin, file timestamp, issue time, and min/max lat/lon values, ignore it. If the file timestamp is older than the existing shape, also ignore it. If the file timestamp is newer than the existing shape, replace the existing shape with the new one. + + * Loop over the filters defined in the configuration file and apply the following logic for each. + + * Subset the list of genesis shapes based on the current filter criteria. + + * Search the Best track genesis events to see if any occurred inside the shape within 7 days of the issuance time. If multiple genesis events occurred, choose the one closest to the issuance time. + + * If not found, score each probability as a miss. + + * If found, further check the 2 and 5 day time windows to classify each probability as a hit or miss. + + * Add each probability pair to an Nx2 probabilistic contingency table, tracking results separately for each lead time. + + * Report the Nx2 probabilistic contingency table counts and statistics for each lead time. These counts and statistics are identified in the output files as *GENESIS_SHAPE*. tc_gen configuration file ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -239,6 +274,8 @@ ______________________ The **init_beg**, **init_end**, **init_inc**, and **init_exc** entries define strings in YYYYMMDD[_HH[MMSS]] format which defines which forecast and operational tracks initializations to be processed. If left empty, all tracks will be used. Otherwise, only those tracks whose initialization time meets all the criteria will be processed. The initialization time must fall between **init_beg**, and **init_end**, must appear in **init_inc** inclusion list, and must not appear in the **init_exc** exclusion list. Note that these settings only apply to the forecast and operational tracks, not the Best tracks, for which the initialization time is undefined. Care should be given when interpreting the contingency table results for filtered data. +For genesis shapes, these options are used to filter the warning issuance time. + ______________________ .. code-block:: none @@ -257,6 +294,8 @@ ______________________ The **init_hour** and **lead** entries are arrays of strings in HH[MMSS] format defining which forecast tracks should be included. If left empty, all tracks will be used. Otherwise, only those forecast tracks whose initialization hour and lead times appear in the list will be used. Note that these settings only apply to the forecast tracks, not the Best tracks, for which the initialization time is undefined. Care should be given when interpreting the contingency table results for filtered data. +For genesis shapes, the **init_hour** option is used to filter the warning issuance hour. + ______________________ .. code-block:: none @@ -265,6 +304,8 @@ ______________________ The **vx_mask** entry is a string defining the path to a Lat/Lon polyline file or a gridded data file that MET can read to subset the results spatially. If specified, only those genesis events whose Lat/Lon location falls within the specified area will be included. +If specified for genesis shapes, the lat/lon of the central location of the shape will be checked. The central location is computed as the average of the min/max lat/lon values of the shape points. + ______________________ .. code-block:: none @@ -275,6 +316,8 @@ The **basin_mask** entry is an array of strings listing tropical cycline basin a The **vx_mask** and **basin_mask** names are concatenated and written to the **VX_MASK** output column. +If **vx_mask** is not specified for genesis shapes and **basin_mask** is, the basin name is extracted from the shapefile metadata and compared to the **basin_mask** list. + ______________________ .. code-block:: none @@ -415,7 +458,7 @@ ______________________ prob_genesis_thresh = ==0.25; -The **prob_genesis_thresh** entry defines the probability thresholds used to create the output Nx2 contingency table when verifying edeck probability of genesis forecasts. The default is probability bins of width 0.25. These probabilities may be specified as a list (>0.00,>0.25,>0.50,>0.75,>1.00) or using shorthand notation (==0.25) for bins of equal width. +The **prob_genesis_thresh** entry defines the probability thresholds used to create the output Nx2 contingency table when verifying edeck probability of genesis forecasts and probabilistic shapefile warning areas. The default is probability bins of width 0.25. These probabilities may be specified as a list (>0.00,>0.25,>0.50,>0.75,>1.00) or using shorthand notation (==0.25) for bins of equal width. ______________________ @@ -435,12 +478,12 @@ ______________________ dland_file = "MET_BASE/tc_data/dland_global_tenth_degree.nc"; version = "VN.N"; -The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. TC-Gen writes output for 2x2 contingency tables to the **FHO**, **CTC**, and **CTS** line types when verifying deterministic genesis forecasts specified using the **-track** command line option. TC-Gen writes output for Nx2 probabilistic contingency tables to the **PCT**, **PSTD**, **PJC**, and **PRC** line types when verifying the probability of genesis forecasts specified using the **-edeck** command line option. Note that the **genmpr** line type is specific to TC-Gen and describes individual genesis matched pairs. +The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. TC-Gen writes output for 2x2 contingency tables to the **FHO**, **CTC**, and **CTS** line types when verifying deterministic genesis forecasts specified using the **-track** command line option. TC-Gen writes output for Nx2 probabilistic contingency tables to the **PCT**, **PSTD**, **PJC**, and **PRC** line types when verifying the probability of genesis forecasts specified using the **-edeck** command line option and probabilistic shapefiles using the **-shape** command line option. Note that the **genmpr** line type is specific to TC-Gen and describes individual genesis matched pairs. tc_gen output ~~~~~~~~~~~~~ -TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The ASCII output duplicates the STAT output but has the data organized by line type. The output files are created based on the **-out** command line argument. The default output base name, **./tc_gen** writes output files in the current working directory named **tc_gen.stat** and, optionally, **tc_gen_fho.txt, tc_gen_ctc.txt**, **tc_gen_cts.txt**, **tc_gen_genmpr.txt**, and **tc_gen_pairs.nc**. The format of the STAT and ASCII output of the TC-Gen tool matches the output of other MET tools with the exception of the genesis matched pair line type. Please refer to the tables in :numref:`point_stat-output` for a description of the common output line types. The genesis matched pair line type and NetCDF output file are described below. +TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The ASCII output duplicates the STAT output but has the data organized by line type. The output files are created based on the **-out** command line argument. The default output base name, **./tc_gen** writes output files in the current working directory named **tc_gen.stat** and, optionally, **tc_gen_pairs.nc** and **tc_gen_{TYPE}.txt** for each of the supported output line types. These output files can easily be redirected to another location using the **-out** command line option. The format of the STAT and ASCII output of the TC-Gen tool matches the output of other MET tools with the exception of the genesis matched pair line type. Please refer to the tables in :numref:`point_stat-output` for a description of the common output line types. The genesis matched pair line type and NetCDF output file are described below. .. _table_TG_header_info_tg_outputs: @@ -483,7 +526,7 @@ TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The AS - Maximum Best track valid time in YYYYMMDD_HHMMSS format * - 10 - FCST_VAR - - Genesis methodology (GENESIS_DEV, GENESIS_OPS, or PROB_GENESIS) + - Genesis methodology (GENESIS_DEV, GENESIS_OPS, PROB_GENESIS, or GENESIS_SHAPE) * - 11 - FCST_UNITS - Does not apply and is set to NA @@ -492,7 +535,7 @@ TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The AS - Does not apply and is set to NA * - 13 - OBS_VAR - - Genesis methodology (GENESIS_DEV, GENESIS_OPS, or PROB_GENESIS) + - Genesis methodology (GENESIS_DEV, GENESIS_OPS, PROB_GENESIS, or GENESIS_SHAPE) * - 14 - OBS_UNITS - Does not apply and is set to NA diff --git a/met/src/basic/vx_config/Makefile.am b/met/src/basic/vx_config/Makefile.am index bce95fa29c..b4d2d52ce6 100644 --- a/met/src/basic/vx_config/Makefile.am +++ b/met/src/basic/vx_config/Makefile.am @@ -11,7 +11,6 @@ include ${top_srcdir}/Make-include # Yacc/lex flags AM_YFLAGS = --defines=config.tab.h -p config -#AM_LFLAGS = --prefix=config --outfile=lex.yy.c # The library diff --git a/met/src/libcode/vx_color/Makefile.am b/met/src/libcode/vx_color/Makefile.am index 0035825c40..8c147693d7 100644 --- a/met/src/libcode/vx_color/Makefile.am +++ b/met/src/libcode/vx_color/Makefile.am @@ -11,7 +11,6 @@ include ${top_srcdir}/Make-include # YACC/LEX flags AM_YFLAGS = --defines=color_parser_yacc.h -p color -#AM_LFLAGS = --prefix=color --outfile=lex.yy.c # The library diff --git a/met/src/libcode/vx_gis/Makefile.am b/met/src/libcode/vx_gis/Makefile.am index fcc506f49f..f214481071 100644 --- a/met/src/libcode/vx_gis/Makefile.am +++ b/met/src/libcode/vx_gis/Makefile.am @@ -12,24 +12,16 @@ include ${top_srcdir}/Make-include noinst_LIBRARIES = libvx_gis.a -libvx_gis_a_SOURCES = shapetype_to_string.h \ - shapetype_to_string.cc \ - dbf_file.cc \ - dbf_file.h \ - shp_array.h \ - shp_file.cc \ - shp_file.h \ - shp_point_record.cc \ - shp_point_record.h \ - shp_poly_record.cc \ - shp_poly_record.h \ - shp_types.h \ - shx_file.cc \ - shx_file.h - - - - +libvx_gis_a_SOURCES = \ + shapetype_to_string.cc shapetype_to_string.h \ + dbf_file.cc dbf_file.h \ + shx_file.cc shx_file.h \ + shp_file.cc shp_file.h \ + shp_types.h \ + shp_array.h \ + shp_point_record.cc shp_point_record.h \ + shp_poly_record.cc shp_poly_record.h \ + vx_gis.h libvx_gis_a_CPPFLAGS = ${MET_CPPFLAGS} # If we are in development mode, generate the "to_string" files and diff --git a/met/src/libcode/vx_gis/dbf_file.cc b/met/src/libcode/vx_gis/dbf_file.cc index eb0fdc921f..0a5049d150 100644 --- a/met/src/libcode/vx_gis/dbf_file.cc +++ b/met/src/libcode/vx_gis/dbf_file.cc @@ -1,4 +1,3 @@ - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) @@ -9,7 +8,6 @@ //////////////////////////////////////////////////////////////////////// - using namespace std; #include @@ -311,15 +309,12 @@ unsigned char buf[32]; // seek to the first record // -// pos = pos_first_record; - pos = 32; -if ( lseek(fd, pos, SEEK_SET) < 0 ) { +if ( ::lseek(fd, pos, SEEK_SET) < 0 ) { - mlog << Error - << "\n\n DbfHeader::set_subrecords(int) -> lseek error ... " - << strerror(errno) << "\n\n"; + mlog << Error << "\nDbfHeader::set_subrecords(int) -> " + << "lseek error ... " << strerror(errno) << "\n\n"; exit ( 1 ); @@ -339,8 +334,8 @@ for (j=0; j read error ... n_read = " << n_read << "\n\n"; + mlog << Error << "\nDbfHeader::set_subrecords(int) -> " + << "read error ... n_read = " << n_read << "\n\n"; exit ( 1 ); @@ -372,8 +367,8 @@ DbfSubRecord * DbfHeader::lookup_subrec(const char * text) const if ( empty(text) ) { - mlog << Error - << "\n\n DbfHeader::set_subrecords(const char *) -> empty string!\n\n"; + mlog << Error << "\nDbfHeader::set_subrecords(const char *) -> " + << "empty string!\n\n"; exit ( 1 ); @@ -552,7 +547,6 @@ out << prefix << "field_flags = " << ((int) field_flags) << '\n'; out << prefix << "autoinc_next_value = " << autoinc_next_value << '\n'; out << prefix << "autoinc_step_value = " << autoinc_step_value << '\n'; - // // done // @@ -589,9 +583,6 @@ memcpy(&autoinc_next_value, buf + 19, 4); autoinc_step_value = (int) (buf[23]); - - - // // done // @@ -651,7 +642,6 @@ for (j=0; j<(h.n_subrecs); ++j) { } - // for (k=0; k " + << "should never be called!\n\n"; + +exit ( 1 ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +DbfFile & DbfFile::operator=(const DbfFile &) + +{ + +mlog << Error << "\nDbfFile::operator=(const DbfFile &) -> " + << "should never be called!\n\n"; + +exit ( 1 ); + +return ( * this ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void DbfFile::init_from_scratch() + +{ + +fd = -1; + +close(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void DbfFile::close() + +{ + +if ( fd >= 0 ) ::close(fd); + +fd = -1; + +memset(&Header, 0, sizeof(Header)); + +Filename.clear(); + +At_Eof = false; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +const char * DbfFile::filename() const + +{ + +if ( Filename.empty() ) return ( (const char *) 0 ); + +return ( Filename.text() ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool DbfFile::open(const char * path) + +{ + +size_t n_read, bytes; +int j; + +close(); + +if ( (fd = met_open(path, O_RDONLY)) < 0 ) { + + fd = -1; + + return ( false ); + +} + +Filename = path; + + // + // read the file header + // + +const size_t buf_size = 65536; +unsigned char buf[buf_size]; + +bytes = 32; + +if((n_read = ::read(fd, buf, bytes)) != bytes) { + mlog << Warning << "\nDbfFile::open(const char * path) -> " + << "trouble reading file header from dbf file \"" + << path << "\"\n\n"; + close(); + + return(false); +} + +Header.set_header(buf); + + // + // subrecords + // + +Header.set_subrecords(fd); + + // + // done + // + +return ( true ); + +} + +//////////////////////////////////////////////////////////////////////// + + +int DbfFile::position() const + +{ + +if ( ! is_open() ) { + + mlog << Error << "\nDbfFile::position() -> " + << "no file open!\n\n"; + + exit ( 1 ); + +} + +const int pos = ::lseek(fd, 0, SEEK_CUR); + +if ( pos < 0 ) { + + mlog << Error << "\nDbfFile::position() const -> " + << "lseek error ... " << strerror(errno) << "\n\n"; + + exit ( 1 ); + +} + + +return ( pos ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void DbfFile::lseek(int offset, int whence) + +{ + + +if ( ! is_open() ) { + + mlog << Error << "\nDbfFile::lseek() -> " + << "no file open!\n\n"; + + exit ( 1 ); + +} + + +if ( ::lseek(fd, offset, whence) < 0 ) { + + mlog << Error << "\nDbfFile::lseek() -> " + << "lseek(2) failed! ... " << strerror(errno) << "\n\n"; + + exit ( 1 ); + +} + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool DbfFile::read(unsigned char * buf, int n_bytes) + +{ + +if ( ! is_open() ) { + + mlog << Error << "\nDbfFile::read() -> " + << "no file open!\n\n"; + + exit ( 1 ); + +} + +int n_read; + +n_read = ::read(fd, buf, n_bytes); + +if ( n_read < 0 ) { // some kind of error + + mlog << Error << "\nDbfFile::read() -> " + << "read error on dbf file \"" << Filename << "\"\n\n"; + + exit ( 1 ); + +} + +if ( n_read == 0 ) return ( false ); + +if ( n_read == n_bytes ) return ( true ); + +return ( false ); // gotta return something + +} + + +//////////////////////////////////////////////////////////////////////// + + +StringArray DbfFile::subrecord_names() + +{ + +StringArray sa; + + // + // subrecords (if any) + // + +if ( Header.subrec ) { + + for (int j=0; j (Header.n_records) ) { + + mlog << Error << "\nDbfFile::subrecord_values(int i_rec) -> " + << "requested record index (" << i_rec << ") out of range (0," + << Header.n_records << ")!\n\n"; + + exit ( 1 ); +} + +bytes = Header.record_length; + +if ( ::lseek(fd, Header.pos_first_record + i_rec * bytes, SEEK_SET) < 0 ) { + + mlog << Error << "\nDbfFile::subrecord_values(int i_rec) -> " + << "lseek error\n\n"; + + exit ( 1 ); + +} + + // + // read the requested record into the buffer + // + +n_read = ::read(fd, buf, bytes < buf_size ? bytes : buf_size); + +if ( n_read != bytes ) { + + mlog << Error << "\nDbfFile::subrecord_values(int i_rec) -> " + << "read error ... n_read = " << n_read << "\n\n"; + + exit ( 1 ); + +} + +if ( Header.record_length < buf_size) buf[Header.record_length] = 0; + +std::string s = (const char *) buf+1; // skip first byte + + // + // parse each subrecord value + // + +for (j=0,pos=0; j<(Header.n_subrecs); ++j) { + + cs = s.substr(pos, Header.subrec[j].field_length); + cs.ws_strip(); + sa.add(cs); + + pos += Header.subrec[j].field_length; + +} + +return ( sa ); + +} + + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_gis/dbf_file.h b/met/src/libcode/vx_gis/dbf_file.h index 6bc2a354f4..7e60e681e5 100644 --- a/met/src/libcode/vx_gis/dbf_file.h +++ b/met/src/libcode/vx_gis/dbf_file.h @@ -6,17 +6,13 @@ // ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - //////////////////////////////////////////////////////////////////////// - #ifndef __VX_SHAPEFILES_DBF_FILE_H__ #define __VX_SHAPEFILES_DBF_FILE_H__ - //////////////////////////////////////////////////////////////////////// - // // Got info on the dbf file format at // @@ -27,16 +23,12 @@ // http://web.archive.org/web/20150323061445/http://ulisse.elettra.trieste.it/services/doc/dbase/DBFstruct.htm // - //////////////////////////////////////////////////////////////////////// - struct DbfSubRecord; // forward reference - //////////////////////////////////////////////////////////////////////// - class DbfHeader { private: @@ -85,10 +77,8 @@ class DbfHeader { }; - //////////////////////////////////////////////////////////////////////// - class DbfSubRecord { private: @@ -133,19 +123,83 @@ class DbfSubRecord { }; +//////////////////////////////////////////////////////////////////////// + +void dump_record(ostream &, const int depth, const unsigned char * buf, const DbfHeader &); //////////////////////////////////////////////////////////////////////// +class DbfFile { -void dump_record(ostream &, const int depth, const unsigned char * buf, const DbfHeader &); + private: + + DbfFile(const DbfFile &); + DbfFile & operator=(const DbfFile &); + + protected: + + void init_from_scratch(); + + int fd; + + bool At_Eof; + + DbfHeader Header; + + ConcatString Filename; + + public: + + DbfFile(); + ~DbfFile(); + + bool open(const char * path); + + void close(); + + // + // set stuff + // + + // + // get stuff + // + + const DbfHeader * header() const; + + const char * filename() const; + + bool at_eof() const; + + int position() const; // offset in bytes from beginning of file + + bool is_open() const; + + // + // do stuff + // + + void lseek(int offset, int whence = SEEK_SET); // just like lseek(2) + + bool read(unsigned char * buf, int nbytes); + + StringArray subrecord_names(); + + StringArray subrecord_values(int i_rec); + +}; //////////////////////////////////////////////////////////////////////// +inline const DbfHeader * DbfFile::header() const { return ( &Header ); } -#endif /* __VX_SHAPEFILES_DBF_FILE_H__ */ +inline bool DbfFile::at_eof() const { return ( At_Eof ); } +inline bool DbfFile::is_open() const { return ( fd >= 0 ); } //////////////////////////////////////////////////////////////////////// +#endif /* __VX_SHAPEFILES_DBF_FILE_H__ */ +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_gis/shp_array.h b/met/src/libcode/vx_gis/shp_array.h index 419d1ca5bf..bfeeba578b 100644 --- a/met/src/libcode/vx_gis/shp_array.h +++ b/met/src/libcode/vx_gis/shp_array.h @@ -97,6 +97,8 @@ class Shp_Array { int n() const { return ( Nelements ); } + int n_elements() const { return ( Nelements ); } + // // do stuff // diff --git a/met/src/libcode/vx_gis/shp_file.cc b/met/src/libcode/vx_gis/shp_file.cc index 14417c0048..1f311fce2a 100644 --- a/met/src/libcode/vx_gis/shp_file.cc +++ b/met/src/libcode/vx_gis/shp_file.cc @@ -1,8 +1,3 @@ - - -//////////////////////////////////////////////////////////////////////// - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) diff --git a/met/src/libcode/vx_gis/shp_file.h b/met/src/libcode/vx_gis/shp_file.h index 77b2c48418..7a362d9e52 100644 --- a/met/src/libcode/vx_gis/shp_file.h +++ b/met/src/libcode/vx_gis/shp_file.h @@ -1,8 +1,3 @@ - - -//////////////////////////////////////////////////////////////////////// - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) diff --git a/met/src/libcode/vx_gis/shp_poly_record.cc b/met/src/libcode/vx_gis/shp_poly_record.cc index b540b78779..b5876253ab 100644 --- a/met/src/libcode/vx_gis/shp_poly_record.cc +++ b/met/src/libcode/vx_gis/shp_poly_record.cc @@ -50,6 +50,27 @@ static SmartBuffer Buf; //////////////////////////////////////////////////////////////////////// +void ShpPolyRecord::clear() + +{ + + memset(&rh, 0, sizeof(rh)); + memset(&bbox, 0, sizeof(bbox)); + + shape_type = bad_data_int; + + n_parts = 0; + n_points = 0; + + parts.clear(); + points.clear(); + +} + + +//////////////////////////////////////////////////////////////////////// + + void ShpPolyRecord::set(unsigned char * buf) { diff --git a/met/src/libcode/vx_gis/shp_poly_record.h b/met/src/libcode/vx_gis/shp_poly_record.h index faad26478d..18131cadaa 100644 --- a/met/src/libcode/vx_gis/shp_poly_record.h +++ b/met/src/libcode/vx_gis/shp_poly_record.h @@ -30,13 +30,6 @@ #include "shp_array.h" -//////////////////////////////////////////////////////////////////////// - - -// static const int max_shp_poly_parts = 600; -// static const int max_shp_poly_points = (1 << 17); - - //////////////////////////////////////////////////////////////////////// @@ -63,6 +56,8 @@ struct ShpPolyRecord { // this should really be a class, not a struct // + void clear(); + double x_min() const; double x_max() const; @@ -81,7 +76,7 @@ struct ShpPolyRecord { // this should really be a class, not a struct bool is_closed() const; - void toggle_longitudes(); + void toggle_longitudes(); }; diff --git a/met/src/libcode/vx_gis/vx_gis.h b/met/src/libcode/vx_gis/vx_gis.h new file mode 100644 index 0000000000..40ade039ec --- /dev/null +++ b/met/src/libcode/vx_gis/vx_gis.h @@ -0,0 +1,29 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 __VX_GIS_H__ +#define __VX_GIS_H__ + +//////////////////////////////////////////////////////////////////////// + +#include "dbf_file.h" +#include "shx_file.h" +#include "shp_file.h" +#include "shp_types.h" +#include "shp_array.h" +#include "shapetype_to_string.h" +#include "shp_point_record.h" +#include "shp_poly_record.h" + +//////////////////////////////////////////////////////////////////////// + +#endif // __VX_GIS_H__ + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_statistics/Makefile.am b/met/src/libcode/vx_statistics/Makefile.am index 8d3a183cbd..bf1cd72c74 100644 --- a/met/src/libcode/vx_statistics/Makefile.am +++ b/met/src/libcode/vx_statistics/Makefile.am @@ -13,6 +13,7 @@ include ${top_srcdir}/Make-include noinst_LIBRARIES = libvx_statistics.a libvx_statistics_a_SOURCES = \ apply_mask.cc apply_mask.h \ + grid_closed_poly.cc grid_closed_poly.h \ compute_ci.cc compute_ci.h \ contable.cc contable.h \ contable_stats.cc \ diff --git a/met/src/tools/other/gen_vx_mask/grid_closed_poly.cc b/met/src/libcode/vx_statistics/grid_closed_poly.cc similarity index 53% rename from met/src/tools/other/gen_vx_mask/grid_closed_poly.cc rename to met/src/libcode/vx_statistics/grid_closed_poly.cc index a39c63457a..e010cca11b 100644 --- a/met/src/tools/other/gen_vx_mask/grid_closed_poly.cc +++ b/met/src/libcode/vx_statistics/grid_closed_poly.cc @@ -8,7 +8,7 @@ /////////////////////////////////////////////////////////////////////////////// // -// Filename: polyline.cc +// Filename: grid_closed_poly.cc // // Description: // @@ -34,257 +34,187 @@ using namespace std; #include "vx_util.h" #include "grid_closed_poly.h" - /////////////////////////////////////////////////////////////////////////////// // // Code for class GridClosedPoly // /////////////////////////////////////////////////////////////////////////////// - -GridClosedPoly::GridClosedPoly() - -{ - -gcp_init_from_scratch(); - +GridClosedPoly::GridClosedPoly() { + gcp_init_from_scratch(); } - /////////////////////////////////////////////////////////////////////////////// - -GridClosedPoly::~GridClosedPoly() - -{ - -} - +GridClosedPoly::~GridClosedPoly() { } /////////////////////////////////////////////////////////////////////////////// +void GridClosedPoly::clear() { -void GridClosedPoly::clear() - -{ + Polyline::clear(); -Polyline::clear(); - -u_min = u_max = v_min = v_max = 0.0; - -return; + u_min = u_max = v_min = v_max = 0.0; + return; } - /////////////////////////////////////////////////////////////////////////////// +GridClosedPoly::GridClosedPoly(const GridClosedPoly & g) { -GridClosedPoly::GridClosedPoly(const GridClosedPoly & g) - -{ - -gcp_init_from_scratch(); - -gcp_assign(g); + gcp_init_from_scratch(); + gcp_assign(g); } - /////////////////////////////////////////////////////////////////////////////// +GridClosedPoly & GridClosedPoly::operator=(const GridClosedPoly & g) { -GridClosedPoly & GridClosedPoly::operator=(const GridClosedPoly & g) - -{ + if(this == &g) return(*this); -if ( this == &g ) return ( * this ); - -gcp_assign(g); - - -return ( * this ); + gcp_assign(g); + return(*this); } - /////////////////////////////////////////////////////////////////////////////// +void GridClosedPoly::gcp_init_from_scratch() { -void GridClosedPoly::gcp_init_from_scratch() - -{ - -u_min = u_max = v_min = v_max = 0.0; - -return; + u_min = u_max = v_min = v_max = 0.0; + return; } - /////////////////////////////////////////////////////////////////////////////// +void GridClosedPoly::gcp_assign(const GridClosedPoly & g) { -void GridClosedPoly::gcp_assign(const GridClosedPoly & g) + Polyline::assign(g); -{ + u_min = g.u_min; + u_max = g.u_max; -Polyline::assign(g); - -u_min = g.u_min; -u_max = g.u_max; - -v_min = g.v_min; -v_max = g.v_max; - -return; + v_min = g.v_min; + v_max = g.v_max; + return; } - /////////////////////////////////////////////////////////////////////////////// +void GridClosedPoly::add_point(double uu, double vv) { -void GridClosedPoly::add_point(double uu, double vv) + if(n_points == 0) { + u_min = u_max = uu; + v_min = v_max = vv; + } + else { + if(uu < u_min) u_min = uu; + if(uu > u_max) u_max = uu; -{ + if(vv < v_min) v_min = vv; + if(vv > v_max) v_max = vv; + } -if ( n_points == 0 ) { - - u_min = u_max = uu; v_min = v_max = vv; - -} else { - - if ( uu < u_min ) u_min = uu; - if ( uu > u_max ) u_max = uu; - - if ( vv < v_min ) v_min = vv; - if ( vv > v_max ) v_max = vv; - -} - -Polyline::add_point(uu, vv); - - -return; + Polyline::add_point(uu, vv); + return; } - /////////////////////////////////////////////////////////////////////////////// -int GridClosedPoly::is_inside(double u_test, double v_test) const - -{ +int GridClosedPoly::is_inside(double u_test, double v_test) const { // // test bounding box // -if ( u_test < u_min ) return ( 0 ); -if ( u_test > u_max ) return ( 0 ); + if(u_test < u_min) return(0); + if(u_test > u_max) return(0); -if ( v_test < v_min ) return ( 0 ); -if ( v_test > v_max ) return ( 0 ); + if(v_test < v_min) return(0); + if(v_test > v_max) return(0); // // test polyline // -const int status = Polyline::is_inside(u_test, v_test); - -return ( status ); + const int status = Polyline::is_inside(u_test, v_test); + return(status); } - /////////////////////////////////////////////////////////////////////////////// // // Code for class GridClosedPolyArray // /////////////////////////////////////////////////////////////////////////////// +bool GridClosedPolyArray::is_inside(double u_test, double v_test) const { -bool GridClosedPolyArray::is_inside(double u_test, double v_test) const - -{ + if(Nelements == 0) return(false); -if ( Nelements == 0 ) return ( false ); - -int j, status; + int j, status; // - // if the test point is inside **ANY** of the element polylines, return true + // return true if the test point is inside **ANY** of the polylines // + for(j=0; jis_inside(u_test, v_test); + status = e[j]->is_inside(u_test, v_test); - if ( status != 0 ) return ( true ); - -} + if(status != 0) return(true); + } - -return ( false ); + return(false); } - /////////////////////////////////////////////////////////////////////////////// +void GridClosedPolyArray::set(const ShpPolyRecord &r, const Grid &grid) { -void GridClosedPolyArray::set(const ShpPolyRecord & r, const Grid & grid) - -{ - -clear(); - -int i, j, k, m; -int start, stop; -double lat, lon; -double x, y; -GridClosedPoly g; - + clear(); -if ( r.n_parts == 0 ) return; + int i, j, k, m; + int start, stop; + double lat, lon; + double x, y; + GridClosedPoly p; + for(j=0; j<(r.n_parts); j++) { -for (j=0; j<(r.n_parts); ++j) { + p.clear(); - g.clear(); + start = r.start_index(j); + stop = r.stop_index(j); - start = r.start_index(j); + i = stop - start + 1; - stop = r.stop_index(j); + for(k=0; k #include "polyline.h" @@ -33,13 +32,9 @@ #include "shp_poly_record.h" #include "vx_grid.h" - /////////////////////////////////////////////////////////////////////////////// - -class GridClosedPoly : public Polyline - -{ +class GridClosedPoly : public Polyline { protected: @@ -47,8 +42,7 @@ class GridClosedPoly : public Polyline void gcp_assign(const GridClosedPoly &); - // bounding box info - + // bounding box limits double u_min, u_max; double v_min, v_max; @@ -61,36 +55,28 @@ class GridClosedPoly : public Polyline void clear(); - int is_inside(double u_test, double v_test) const; // test bounding box first + // tests bounding box first for efficiency + int is_inside(double u_test, double v_test) const; - void add_point(double, double); // updates bounding box + // updates bounding box for each new point + void add_point(double, double); }; - /////////////////////////////////////////////////////////////////////////////// - -class GridClosedPolyArray : public NCRR_Array - -{ +class GridClosedPolyArray : public NCRR_Array { public: bool is_inside(double u_test, double v_test) const; - void set (const ShpPolyRecord &, const Grid &); + void set(const ShpPolyRecord &, const Grid &); }; - /////////////////////////////////////////////////////////////////////////////// - -#endif // __DATA2D_UTIL_GCP_H__ - +#endif // __GRID_CLOSED_POLY_H__ /////////////////////////////////////////////////////////////////////////////// - - - diff --git a/met/src/libcode/vx_statistics/vx_statistics.h b/met/src/libcode/vx_statistics/vx_statistics.h index db1d6685d1..11c06f68e8 100644 --- a/met/src/libcode/vx_statistics/vx_statistics.h +++ b/met/src/libcode/vx_statistics/vx_statistics.h @@ -19,6 +19,7 @@ #include "apply_mask.h" +#include "grid_closed_poly.h" #include "compute_ci.h" #include "contable.h" #include "met_stats.h" diff --git a/met/src/libcode/vx_tc_util/Makefile.am b/met/src/libcode/vx_tc_util/Makefile.am index 733ef9cd6b..390eb1e5ae 100644 --- a/met/src/libcode/vx_tc_util/Makefile.am +++ b/met/src/libcode/vx_tc_util/Makefile.am @@ -24,6 +24,7 @@ libvx_tc_util_a_SOURCES = \ prob_gen_info.h prob_gen_info.cc \ prob_rirw_pair_info.h prob_rirw_pair_info.cc \ genesis_info.cc genesis_info.h \ + gen_shape_info.cc gen_shape_info.h \ pair_data_genesis.cc pair_data_genesis.h \ tc_hdr_columns.cc tc_hdr_columns.h \ tc_columns.cc tc_columns.h \ diff --git a/met/src/libcode/vx_tc_util/gen_shape_info.cc b/met/src/libcode/vx_tc_util/gen_shape_info.cc new file mode 100644 index 0000000000..f51b92c4e7 --- /dev/null +++ b/met/src/libcode/vx_tc_util/gen_shape_info.cc @@ -0,0 +1,377 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +//////////////////////////////////////////////////////////////////////// + +using namespace std; + +#include +#include +#include +#include +#include +#include + +#include "gen_shape_info.h" + +//////////////////////////////////////////////////////////////////////// +// +// Code for class GenShapeInfo +// +//////////////////////////////////////////////////////////////////////// + +GenShapeInfo::GenShapeInfo() { + clear(); +} + +//////////////////////////////////////////////////////////////////////// + +GenShapeInfo::~GenShapeInfo() { + clear(); +} + +//////////////////////////////////////////////////////////////////////// + +GenShapeInfo::GenShapeInfo(const GenShapeInfo &g) { + clear(); + assign(g); +} + +//////////////////////////////////////////////////////////////////////// + +GenShapeInfo & GenShapeInfo::operator=(const GenShapeInfo &g) { + + if(this == &g) return(*this); + + assign(g); + + return(*this); +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfo::clear() { + + Basin.clear(); + + FileTime = (unixtime) 0; + IssueTime = (unixtime) 0; + + Poly.clear(); + LeadSec.clear(); + ProbVal.clear(); + + return; +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString GenShapeInfo::serialize() const { + ConcatString s; + + s << "GenShapeInfo: " + << "Basin = \"" << Basin << "\"" + << ", FileTime = \"" << (FileTime > 0 ? + unix_to_yyyymmdd_hhmmss(FileTime).text() : na_str) << "\"" + << ", IssueTime = \"" << (IssueTime > 0 ? + unix_to_yyyymmdd_hhmmss(IssueTime).text() : na_str) << "\"" + << ", NPoints = " << Poly.n_points + << ", Lat = " << Poly.y_min() << " to " << Poly.y_max() + << ", Lon = " << Poly.x_min() << " to " << Poly.x_max(); + + return(s); + +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfo::assign(const GenShapeInfo &gsi) { + + clear(); + + Basin = gsi.Basin; + + FileTime = gsi.FileTime; + IssueTime = gsi.IssueTime; + + Poly = gsi.Poly; + LeadSec = gsi.LeadSec; + ProbVal = gsi.ProbVal; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfo::set_basin(const char *s) { + Basin = s; + return; +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfo::set_time(unixtime file_ut) { + + FileTime = file_ut; + + // Round the file timestamp to the nearest synoptic time (00, 06, 12, 18) + int h3 = 3*sec_per_hour; + int h6 = 6*sec_per_hour; + IssueTime = ( (int) (file_ut + h3) / h6 ) * h6; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfo::set_poly(const ShpPolyRecord &rec) { + Poly = rec; + return; +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfo::add_prob(int sec, double prob) { + + // Check range of values + if(sec < 0 || prob < 0.0 || prob > 1.0) { + mlog << Error << "\nGenShapeInfo::add_prob() -> " + << "unexpected lead time (" << sec + << ") or probability value (" << prob + << ")!\n\n"; + exit(1); + } + + LeadSec.add(sec); + ProbVal.add(prob); + + return; +} + +//////////////////////////////////////////////////////////////////////// + +const ShpPolyRecord &GenShapeInfo::poly() const { + return(Poly); +} + +//////////////////////////////////////////////////////////////////////// + +double GenShapeInfo::center_lat() const { + return((Poly.y_min() + Poly.y_max())/2.0); +} + +//////////////////////////////////////////////////////////////////////// + +double GenShapeInfo::center_lon() const { + return((Poly.x_min() + Poly.x_max())/2.0); +} + +//////////////////////////////////////////////////////////////////////// + +int GenShapeInfo::n_prob() const { + return(ProbVal.n()); +} + +//////////////////////////////////////////////////////////////////////// + +int GenShapeInfo::lead_sec(int i) const { + + // Check range of values + if(i < 0 || i > LeadSec.n()) { + mlog << Error << "\nGenShapeInfo::lead_sec(int) -> " + << "range check error (" << i << ")!\n\n"; + exit(1); + } + + return(LeadSec[i]); +} + +//////////////////////////////////////////////////////////////////////// + +double GenShapeInfo::prob_val(int i) const { + + // Check range of values + if(i < 0 || i > ProbVal.n()) { + mlog << Error << "\nGenShapeInfo::prob_val(int) -> " + << "range check error (" << i << ")!\n\n"; + exit(1); + } + + return(ProbVal[i]); +} + +//////////////////////////////////////////////////////////////////////// +// +// Code for class GenShapeInfoArray +// +//////////////////////////////////////////////////////////////////////// + +GenShapeInfoArray::GenShapeInfoArray() { + + init_from_scratch(); +} + +//////////////////////////////////////////////////////////////////////// + +GenShapeInfoArray::~GenShapeInfoArray() { + + clear(); +} + +//////////////////////////////////////////////////////////////////////// + +GenShapeInfoArray::GenShapeInfoArray(const GenShapeInfoArray & t) { + + init_from_scratch(); + + assign(t); +} + +//////////////////////////////////////////////////////////////////////// + +GenShapeInfoArray & GenShapeInfoArray::operator=(const GenShapeInfoArray & t) { + + if(this == &t) return(*this); + + assign(t); + + return(*this); +} + +//////////////////////////////////////////////////////////////////////// +// +// Define equality as duplicates with the same file time +// +//////////////////////////////////////////////////////////////////////// + +bool GenShapeInfo::operator==(const GenShapeInfo & gsi) const { + + return(is_duplicate(gsi) && FileTime == gsi.FileTime); +} + + +//////////////////////////////////////////////////////////////////////// +// +// Duplicates have the same basin, issue time, number of points, +// and range of lat/lons +// +//////////////////////////////////////////////////////////////////////// + +bool GenShapeInfo::is_duplicate(const GenShapeInfo & gsi) const { + + return(Basin == gsi.Basin && + IssueTime == gsi.IssueTime && + Poly.n_points == gsi.Poly.n_points && + Poly.x_min() == gsi.Poly.x_min() && + Poly.x_max() == gsi.Poly.x_max() && + Poly.y_min() == gsi.Poly.y_min() && + Poly.y_max() == gsi.Poly.y_max()); +} + + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfoArray::init_from_scratch() { + + clear(); + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfoArray::clear() { + + GenShape.clear(); + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void GenShapeInfoArray::assign(const GenShapeInfoArray &ga) { + + clear(); + + for(int i=0; i= GenShape.size())) { + mlog << Error << "\nGenShapeInfoArray::operator[](int) -> " + << "range check error for index value " << n << "\n\n"; + exit(1); + } + + return(GenShape[n]); +} + +//////////////////////////////////////////////////////////////////////// + +bool GenShapeInfoArray::add(const GenShapeInfo &gsi, bool check_dup) { + + // Check for duplicates: + // - Skip exact duplicates + // - Replace older duplicates with newer ones + // - Skip older duplicates + if(check_dup) { + + // Loop over existing shapes + for(int i=0; i +#include + +#include "vx_cal.h" +#include "vx_math.h" +#include "vx_util.h" +#include "vx_gis.h" + +//////////////////////////////////////////////////////////////////////// +// +// GenShapeInfo class stores information about genesis shapefiles. +// +//////////////////////////////////////////////////////////////////////// + +class GenShapeInfo { + + private: + + void assign(const GenShapeInfo &); + + // Shapefile information + ConcatString Basin; + unixtime FileTime; + unixtime IssueTime; + + ShpPolyRecord Poly; + + IntArray LeadSec; + NumArray ProbVal; + + public: + + GenShapeInfo(); + ~GenShapeInfo(); + GenShapeInfo(const GenShapeInfo &); + + GenShapeInfo & operator=(const GenShapeInfo &); + bool operator==(const GenShapeInfo &) const; + bool is_duplicate(const GenShapeInfo &) const; + + void clear(); + ConcatString serialize() const; + + // + // set stuff + // + + void set_basin(const char *); + void set_time(unixtime); + void set_poly(const ShpPolyRecord &); + void add_prob(int, double); + + // + // get stuff + // + + const ConcatString & basin() const; + + unixtime file_time() const; + unixtime issue_time() const; + int issue_hour() const; + + const ShpPolyRecord & poly() const; + + double center_lat() const; + double center_lon() const; + + int n_prob() const; + int lead_sec(int) const; + double prob_val(int) const; + + // + // do stuff + // +}; + +//////////////////////////////////////////////////////////////////////// + +inline const ConcatString & GenShapeInfo::basin() const { return(Basin); } + +inline unixtime GenShapeInfo::file_time() const { return(FileTime); } +inline unixtime GenShapeInfo::issue_time() const { return(IssueTime); } +inline int GenShapeInfo::issue_hour() const { return(unix_to_sec_of_day(IssueTime)); } + +//////////////////////////////////////////////////////////////////////// +// +// GenShapeInfoArray class stores an array of GenShapeInfo objects. +// +//////////////////////////////////////////////////////////////////////// + +class GenShapeInfoArray { + + private: + + void init_from_scratch(); + void assign(const GenShapeInfoArray &); + + vector GenShape; + + public: + + GenShapeInfoArray(); + ~GenShapeInfoArray(); + GenShapeInfoArray(const GenShapeInfoArray &); + GenShapeInfoArray & operator=(const GenShapeInfoArray &); + + void clear(); + + ConcatString serialize() const; + + // + // set stuff + // + + bool add(const GenShapeInfo &, bool check_dup = false); + bool has(const GenShapeInfo &) const; + + // + // get stuff + // + + const GenShapeInfo & operator[](int) const; + int n() const; +}; + +//////////////////////////////////////////////////////////////////////// + +inline int GenShapeInfoArray::n() const { return(GenShape.size()); } + +//////////////////////////////////////////////////////////////////////// + +#endif /* __VX_GEN_SHAPE_INFO_H__ */ + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_tc_util/vx_tc_util.h b/met/src/libcode/vx_tc_util/vx_tc_util.h index 76e5448429..89a4434432 100644 --- a/met/src/libcode/vx_tc_util/vx_tc_util.h +++ b/met/src/libcode/vx_tc_util/vx_tc_util.h @@ -24,6 +24,7 @@ #include "prob_rirw_info.h" #include "prob_rirw_pair_info.h" #include "genesis_info.h" +#include "gen_shape_info.h" #include "tc_columns.h" #include "tc_hdr_columns.h" #include "tc_stat_line.h" diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 9b2447818a..f420e568c4 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -85,7 +85,7 @@ // output line types. // 034 05/10/16 Halley Gotway Add grid weighting. // 035 05/20/16 Prestopnik J Removed -version (now in command_line.cc) -// 036 02/14/17 Win MET#621 Add nc_pairs_flag.apply_mask +// 036 02/14/17 Win MET #621 Add nc_pairs_flag.apply_mask // 037 05/15/17 Prestopnik P Add shape for regrid, nbrhd and interp // 038 06/26/17 Halley Gotway Add ECLV line type. // 039 08/18/17 Halley Gotway Add fourier decomposition. diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 7e78611c59..f62f3ae511 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -98,7 +98,7 @@ // 047 08/23/21 Seth Linden Add ORANK line type for HiRA. // 048 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. -// 049 12/11/21 Halley Gotway MET#1991 Fix VCNT output. +// 049 12/11/21 Halley Gotway MET #1991 Fix VCNT output. // //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/other/gen_vx_mask/Makefile.am b/met/src/tools/other/gen_vx_mask/Makefile.am index f8b773183b..5eb4938ea7 100644 --- a/met/src/tools/other/gen_vx_mask/Makefile.am +++ b/met/src/tools/other/gen_vx_mask/Makefile.am @@ -12,8 +12,7 @@ include ${top_srcdir}/Make-include bin_PROGRAMS = gen_vx_mask -gen_vx_mask_SOURCES = gen_vx_mask.cc \ - grid_closed_poly.cc +gen_vx_mask_SOURCES = gen_vx_mask.cc gen_vx_mask_CPPFLAGS = ${MET_CPPFLAGS} gen_vx_mask_LDFLAGS = ${MET_LDFLAGS} gen_vx_mask_LDADD = -lvx_shapedata \ @@ -51,5 +50,4 @@ gen_vx_mask_LDADD = -lvx_shapedata \ -lvx_log \ -lm -lnetcdf_c++4 -lnetcdf -lgsl -lgslcblas -EXTRA_DIST = gen_vx_mask.h \ - grid_closed_poly.h +EXTRA_DIST = gen_vx_mask.h diff --git a/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc b/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc index 1fd7bb9bc2..ed5ac52802 100644 --- a/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc +++ b/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc @@ -25,8 +25,8 @@ // 007 04/08/19 Halley Gotway Add percentile thresholds. // 008 04/06/20 Halley Gotway Generalize input_grid option. // 009 06/01/21 Seth Linden Change -type from optional to required. -// 010 08/30/21 Halley Gotway MET#1891 Fix input and mask fields. -// 011 12/13/21 Halley Gotway MET#1993 Fix -type grid. +// 010 08/30/21 Halley Gotway MET #1891 Fix input and mask fields. +// 011 12/13/21 Halley Gotway MET #1993 Fix -type grid. // //////////////////////////////////////////////////////////////////////// @@ -549,10 +549,8 @@ void apply_poly_mask(DataPlane & dp) { bool inside; double lat, lon; - n_in = 0; - // Check each grid point being inside the polyline - for(x=0; x 0) { + mlog << Debug(2) + << "Scoring track genesis forecasts.\n"; score_track_genesis(best_ga, oper_ta); } // Score EDECK genesis probabilities and write output if(edeck_source.n() > 0) { + mlog << Debug(2) + << "Scoring probability of genesis forecasts.\n"; score_genesis_prob(best_ga, oper_ta); } + // Score genesis shapefiles and write output + if(shape_source.n() > 0) { + mlog << Debug(2) + << "Scoring genesis shapefiles.\n"; + score_genesis_shape(best_ga); + } + // Finish output files finish_txt_files(); @@ -205,6 +233,7 @@ void process_command_line(int argc, char **argv) { // Add function calls for the arguments cline.add(set_genesis, "-genesis", -1); cline.add(set_edeck, "-edeck", -1); + cline.add(set_shape, "-shape", -1); cline.add(set_track, "-track", -1); cline.add(set_config, "-config", 1); cline.add(set_out, "-out", 1); @@ -224,10 +253,10 @@ void process_command_line(int argc, char **argv) { } // Check for the minimum number of arguments - if(genesis_source.n() == 0 && edeck_source.n() == 0) { + if((genesis_source.n() + edeck_source.n() + shape_source.n()) == 0) { mlog << Error << "\nprocess_command_line(int argc, char **argv) -> " - << "at least one of the \"-genesis\" or \"-edeck\" command " - << "line options are required\n\n"; + << "at least one of the \"-genesis\", \"-edeck\", or \"-shape\" " + << "command line options are required\n\n"; usage(); } @@ -255,6 +284,13 @@ void process_command_line(int argc, char **argv) { << ", Model Suffix: " << edeck_model_suffix[i] << "\n"; } + // List the input shapefiles + for(i=0; igenesis_time() - fcst_sa[i].issue_time()) < + (fcst_sa[i].lead_sec(j)); + + if(is_event) { + case_cs << "MATCHES " + << unix_to_yyyymmdd_hhmmss(bgi->genesis_time()) + << " BEST track " << bgi->storm_id() + << " genesis at (" << bgi->lat() << ", " + << bgi->lon() << ").\n"; + } + else { + case_cs << "has NO MATCH in the BEST track.\n"; + } + } + // No Best track match + else { + case_cs << "has NO MATCH in the BEST track.\n"; + } + + mlog << Debug(5) << case_cs; + + // Store pair info + pgi.add_genshape(fcst_sa[i], j, bgi, is_event); + + } // end for j + } // end for i + + return; +} //////////////////////////////////////////////////////////////////////// @@ -966,6 +1131,48 @@ int find_probgen_match(const ProbGenInfo &prob_gi, return(i_best); } +//////////////////////////////////////////////////////////////////////// + +int find_genshape_match(const GenShapeInfo &gsi, + const GenesisInfoArray &bga) { + int i, i_bga; + double x, y; + unixtime min_ut; + + // Time window + unixtime beg_ut = gsi.issue_time(); + unixtime end_ut = beg_ut + shape_prob_search_sec; + + // Load the shape + GridClosedPolyArray p; + p.set(gsi.poly(), conf_info.DLandGrid); + + // Search Best track genesis events for a match + for(i=0,i_bga=bad_data_int; i end_ut) continue; + + // Second, check the polyline + conf_info.DLandGrid.latlon_to_xy(bga[i].lat(), -1.0*bga[i].lon(), x, y); + if(p.is_inside(x, y)) { + + // First match found + if(is_bad_data(i_bga)) { + i_bga = i; + min_ut = bga[i].genesis_time(); + } + // Better match found + else if(bga[i].genesis_time() < min_ut) { + i_bga = i; + min_ut = bga[i].genesis_time(); + } + } + } // end for i + + return(i_bga); +} //////////////////////////////////////////////////////////////////////// @@ -1358,6 +1565,140 @@ void process_edecks(const StringArray &files, return; } +//////////////////////////////////////////////////////////////////////// + +void process_shapes(const StringArray &files, + GenShapeInfoArray &shapes) { + int i, j, k, n_rec, total_probs; + unixtime file_ut; + ConcatString shp_file_name, dbf_file_name; + StringArray sa; + ConcatString cs; + GenShapeInfo gsi; + DbfFile dbf_file; + ShpFile shp_file; + ShpPolyRecord poly_rec; + + // Initialize + total_probs = 0; + + // Process each shapefile + for(i=0; i " + << "the specified shapefile (" << shp_file_name + << ") and corresponding database file (" << dbf_file_name + << ") must both exists!\n\n"; + } + + // Extract the issue time from the filename: + // gtwo_areas_YYYYMMDDHHMM.shp + sa = shp_file_name.basename().split("_."); + if(sa.n() >= 3 && sa[2].length() >= 12) { + cs << cs_erase + << sa[2].substr(0, 8).c_str() << "_" + << sa[2].substr(8, 4).c_str() << "00"; + file_ut = yyyymmdd_hhmmss_to_unix(cs.c_str()); + } + else { + mlog << Error << "\nprocess_shapes() -> " + << "can't extract the issue time from \"" << shp_file_name + << "\" since it does not match the regular expression \"" + << gen_shp_reg_exp << "\"!\n\n"; + exit(1); + } + + // Open the dbf and shp files + dbf_file.open(dbf_file_name.c_str()); + shp_file.open(shp_file_name.c_str()); + + // Store the number of records + n_rec = dbf_file.header()->n_records; + + // Check expected shape types + const ShapeType shape_type = (ShapeType) (shp_file.header()->shape_type); + if(shape_type != shape_type_polygon) { + mlog << Error << "\nprocess_shapes() -> " + << "shapefile type \"" << shapetype_to_string(shape_type) + << "\" in file \"" << shp_file_name + << "\" is not supported!\n\n"; + exit(1); + } + + mlog << Debug(4) << "[File " << i+1 << " of " << files.n() << "]: " + << "Found " << n_rec << " records in file \"" << shp_file_name << "\".\n"; + + // Process each shape + for(j=0; j " + << "hit shp file EOF before reading all records!\n\n"; + exit(1); + } + + // Read the current shape and metadata + shp_file >> poly_rec; + poly_rec.toggle_longitudes(); + sa = dbf_file.subrecord_values(j); + + // Initialize GenShapeInfo + gsi.clear(); + gsi.set_time(file_ut); + gsi.set_basin(string_to_basin_abbr(sa[0]).c_str()); + gsi.set_poly(poly_rec); + + // Parse probabilities from the subrecord values + for(k=0; k= max_n_shape_prob) { + mlog << Warning << "\nprocess_shapes() -> " + << "unexpected number of shapefile probabilities (" + << gsi.n_prob() << ") in record " << j+1 + << " of file \"" << dbf_file_name + << "\"!\n\n"; + continue; + } + + // Store the probability info + gsi.add_prob(shape_prob_lead_hr[gsi.n_prob()]*sec_per_hour, + atoi(sa[k].c_str())/100.0); + } + } // end for k + + // Store this shape, check for duplicates + if(shapes.add(gsi, true)) { + mlog << Debug(5) << "Add new " << gsi.serialize() << "\n"; + total_probs += gsi.n_prob(); + } + + } // end for j + + // Close files + dbf_file.close(); + shp_file.close(); + + } // end for i + + mlog << Debug(3) << "Found a total of " << total_probs + << " probabilities in " << shapes.n() << " genesis shapes from " + << files.n() << " input files.\n"; + + return; +} + //////////////////////////////////////////////////////////////////////// // // Setup the output ASCII files @@ -1391,7 +1732,7 @@ void setup_txt_files(int n_model, int max_n_prob, int n_pair) { break; // Nx2 probabilistic contingency table output: - // 1 header + 1 vx method * # models * #probs * # filters + // 1 header + 1 vx method * # models * # probs * # filters case(i_pct): case(i_pstd): case(i_pjc): @@ -1818,16 +2159,19 @@ void write_ctc_genmpr_row(StatHdrColumns &shc, //////////////////////////////////////////////////////////////////////// void write_pct_stats(ProbGenPCTInfo &pgi) { + + // Check for no data to write + if(pgi.PCTMap.size() == 0) return; + int i, lead_hr, lead_sec; // Setup header columns shc.set_model(pgi.Model.c_str()); shc.set_desc(pgi.VxOpt->Desc.c_str()); shc.set_obtype(conf_info.BestEventInfo.Technique.c_str()); - shc.set_mask(pgi.VxOpt->VxMaskName.empty() ? - na_str : pgi.VxOpt->VxMaskName.c_str()); - shc.set_fcst_var(prob_genesis_name); - shc.set_obs_var (prob_genesis_name); + shc.set_mask(pgi.VxMask.c_str()); + shc.set_fcst_var(pgi.VarName.c_str()); + shc.set_obs_var (pgi.VarName.c_str()); // Write results for each lead time for(i=0; ioutput_map(stat_pjc) != STATOutputType_None) { - write_pct_row(shc, pgi.PCTMap[lead_hr], + write_pjc_row(shc, pgi.PCTMap[lead_hr], pgi.VxOpt->output_map(stat_pjc), 1, 1, stat_at, i_stat_row, txt_at[i_pjc], i_txt_row[i_pjc]); @@ -1871,22 +2215,19 @@ void write_pct_stats(ProbGenPCTInfo &pgi) { // Write PRC output if(pgi.VxOpt->output_map(stat_pjc) != STATOutputType_None) { - write_pct_row(shc, pgi.PCTMap[lead_hr], - pgi.VxOpt->output_map(stat_pjc), + write_prc_row(shc, pgi.PCTMap[lead_hr], + pgi.VxOpt->output_map(stat_prc), 1, 1, stat_at, i_stat_row, txt_at[i_prc], i_txt_row[i_prc]); } // Write out GENMPR if(pgi.VxOpt->output_map(stat_genmpr) != STATOutputType_None) { - shc.set_fcst_var(prob_genesis_name); - shc.set_obs_var (prob_genesis_name); write_pct_genmpr_row(shc, pgi, lead_hr, pgi.VxOpt->output_map(stat_genmpr), stat_at, i_stat_row, txt_at[i_genmpr], i_txt_row[i_genmpr]); } - } // end for i return; @@ -1912,10 +2253,10 @@ void write_pct_genmpr_row(StatHdrColumns &shc, shc.set_alpha(bad_data_double); // Write a line for each matched pair - for(i=0; i 50 are for testing or invests static const int max_best_cyclone_number = 50; +// 2, 5, and 7 days shapefile probabilities +static const int max_n_shape_prob = 3; +static const int shape_prob_lead_hr[max_n_shape_prob] = { + 48, 120, 168 +}; +static const int shape_prob_search_sec = 168*sec_per_hour; + //////////////////////////////////////////////////////////////////////// // // Variables for Command Line Arguments @@ -95,6 +100,7 @@ static const int max_best_cyclone_number = 50; // Input files static StringArray genesis_source, genesis_model_suffix; static StringArray edeck_source, edeck_model_suffix; +static StringArray shape_source; static StringArray track_source, track_model_suffix; static ConcatString config_file; static TCGenConfInfo conf_info; diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc index 0592c667b4..a39a7fc06c 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc @@ -150,6 +150,7 @@ void TCGenVxOpt::clear() { ValidBeg = ValidEnd = (unixtime) 0; InitHour.clear(); Lead.clear(); + VxMaskConf.clear(); VxMaskName.clear(); VxPolyMask.clear(); VxGridMask.clear(); @@ -228,8 +229,9 @@ void TCGenVxOpt::process_config(Dictionary &dict) { } // Conf: vx_mask - if(nonempty(dict.lookup_string(conf_key_vx_mask).c_str())) { - file_name = replace_path(dict.lookup_string(conf_key_vx_mask)); + VxMaskConf = dict.lookup_string(conf_key_vx_mask); + if(VxMaskConf.nonempty()) { + file_name = replace_path(VxMaskConf); mlog << Debug(2) << "Masking File: " << file_name << "\n"; parse_poly_mask(file_name, VxPolyMask, VxGridMask, VxAreaMask, VxMaskName); @@ -359,7 +361,8 @@ void TCGenVxOpt::process_basin_mask(const Grid &basin_grid, if(!basin_abbr.has(VxBasinMask[i], j)) { mlog << Error << "\nTCGenConfInfo::process_basin_mask() -> " << "\"" << VxBasinMask[i] - << "\" is not a valid basin name!\n\n"; + << "\" is not a valid basin name (" + << write_css(basin_abbr) << ")!\n\n"; exit(1); } @@ -570,6 +573,60 @@ bool TCGenVxOpt::is_keeper(const ProbGenInfo &gi) const { //////////////////////////////////////////////////////////////////////// +bool TCGenVxOpt::is_keeper(const GenShapeInfo &gsi) const { + bool keep = true; + + // ATCF ID and storm name do not apply + + // Initialization time + if((InitBeg > 0 && InitBeg > gsi.issue_time()) || + (InitEnd > 0 && InitEnd < gsi.issue_time()) || + (InitInc.n() > 0 && !InitInc.has(gsi.issue_time())) || + (InitExc.n() > 0 && InitExc.has(gsi.issue_time()))) + keep = false; + + // Initialization hours + if(InitHour.n() > 0 && !InitHour.has(gsi.issue_hour())) + keep = false; + + // Lead and valid times: + // GenShapeInfo objects contain multiple lead/valid times. + // Do not filter by them here. + + // If VxMaskConf set, filter spatially by the center of the shape + if(keep && VxMaskConf.nonempty()) { + + // Poly masking: use center lat/lon + if(VxPolyMask.n_points() > 0 && + !VxPolyMask.latlon_is_inside(gsi.center_lat(), gsi.center_lon())) + keep = false; + + // Area masking: use center lat/lon + if(!VxAreaMask.is_empty()) { + double x, y; + VxGridMask.latlon_to_xy(gsi.center_lat(), -1.0*gsi.center_lon(), x, y); + if(x < 0 || x >= VxGridMask.nx() || + y < 0 || y >= VxGridMask.ny()) { + keep = false; + } + else { + keep = VxAreaMask(nint(x), nint(y)); + } + } + } + // Otherwise, if VxBasinMask set, filter by the GenShapeArea basin + else if(keep && VxBasinMask.n() > 0) { + keep = VxBasinMask.has(gsi.basin()); + } + + // Distance to land does not apply + + // Return the keep status + return(keep); +} + +//////////////////////////////////////////////////////////////////////// + STATOutputType TCGenVxOpt::output_map(STATLineType t) const { return(OutputMap.at(t)); } @@ -1242,12 +1299,16 @@ void ProbGenPCTInfo::clear() { DefaultPCT.clear(); Model.clear(); + VarName.clear(); + VxMask.clear(); + InitBeg = InitEnd = (unixtime) 0; BestBeg = BestEnd = (unixtime) 0; PCTMap.clear(); - FcstGenMap.clear(); - FcstIdxMap.clear(); + ProbGenMap.clear(); + GenShapeMap.clear(); + ProbIdxMap.clear(); BestGenMap.clear(); BestEvtMap.clear(); @@ -1276,16 +1337,18 @@ void ProbGenPCTInfo::set_vx_opt(const TCGenVxOpt *vx_opt) { //////////////////////////////////////////////////////////////////////// -void ProbGenPCTInfo::add(const ProbGenInfo &fgi, int index, - const GenesisInfo *bgi, bool is_event) { - int i; +void ProbGenPCTInfo::add_probgen(const ProbGenInfo &pgi, int index, + const GenesisInfo *bgi, bool is_event) { unixtime ut; - // Store the model name - if(Model.empty()) Model = fgi.technique(); + // Store the model and variable names + if(Model.empty()) Model = pgi.technique(); + if(VarName.empty()) VarName = prob_genesis_name; + if(VxMask.empty()) VxMask = (VxOpt->VxMaskName.empty() ? + na_str : VxOpt->VxMaskName); // Track the range of forecast initalization times - ut = fgi.init(); + ut = pgi.init(); if(InitBeg == 0 || InitBeg > ut) InitBeg = ut; if(InitEnd == 0 || InitEnd < ut) InitEnd = ut; @@ -1297,28 +1360,28 @@ void ProbGenPCTInfo::add(const ProbGenInfo &fgi, int index, } // Current lead time and probability value - int lead_hr = nint(fgi.prob_item(index)); - double prob = fgi.prob(index) / 100.0; + int lead_hr = nint(pgi.prob_item(index)); + double prob = pgi.prob(index) / 100.0; // Add new map entries, if needed if(!LeadTimes.has(lead_hr)) { LeadTimes.add(lead_hr); - vector empty_fgi; + vector empty_pgi; vector empty_idx; vector empty_bgi; vector empty_evt; PCTMap [lead_hr] = DefaultPCT; - FcstGenMap[lead_hr] = empty_fgi; - FcstIdxMap[lead_hr] = empty_idx; + ProbGenMap[lead_hr] = empty_pgi; + ProbIdxMap[lead_hr] = empty_idx; BestGenMap[lead_hr] = empty_bgi; BestEvtMap[lead_hr] = empty_evt; } // Update map entries - FcstGenMap[lead_hr].push_back(&fgi); - FcstIdxMap[lead_hr].push_back(index); + ProbGenMap[lead_hr].push_back(&pgi); + ProbIdxMap[lead_hr].push_back(index); BestGenMap[lead_hr].push_back(bgi); BestEvtMap[lead_hr].push_back(is_event); @@ -1330,3 +1393,58 @@ void ProbGenPCTInfo::add(const ProbGenInfo &fgi, int index, } //////////////////////////////////////////////////////////////////////// + +void ProbGenPCTInfo::add_genshape(const GenShapeInfo &gsi, int index, + const GenesisInfo *bgi, bool is_event) { + unixtime ut; + int lead_hr; + + // Store the model and variable names + if(Model.empty()) Model = "OPER"; + if(VarName.empty()) VarName = genesis_shape_name; + if(VxMask.empty()) VxMask = (VxOpt->VxMaskName.empty() ? + na_str : VxOpt->VxMaskName); + + // Track the range of forecast issue times + ut = gsi.issue_time(); + if(InitBeg == 0 || InitBeg > ut) InitBeg = ut; + if(InitEnd == 0 || InitEnd < ut) InitEnd = ut; + + // Track the range of verifying BEST genesis events + if(bgi) { + ut = bgi->genesis_time(); + if(BestBeg == 0 || BestBeg > ut) BestBeg = ut; + if(BestEnd == 0 || BestEnd < ut) BestEnd = ut; + } + + // Add new map entries, if needed + lead_hr = gsi.lead_sec(index)/sec_per_hour; + if(!LeadTimes.has(lead_hr)) { + + LeadTimes.add(lead_hr); + vector empty_gsi; + vector empty_idx; + vector empty_bgi; + vector empty_evt; + + PCTMap [lead_hr] = DefaultPCT; + GenShapeMap[lead_hr] = empty_gsi; + ProbIdxMap[lead_hr] = empty_idx; + BestGenMap[lead_hr] = empty_bgi; + BestEvtMap[lead_hr] = empty_evt; + } + + // Update map entries + GenShapeMap[lead_hr].push_back(&gsi); + ProbIdxMap[lead_hr].push_back(index); + BestGenMap[lead_hr].push_back(bgi); + BestEvtMap[lead_hr].push_back(is_event); + + // Increment counts + if(is_event) PCTMap[lead_hr].pct.inc_event (gsi.prob_val(index)); + else PCTMap[lead_hr].pct.inc_nonevent(gsi.prob_val(index)); + + return; +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h index b3512c0d8c..487ce9245b 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h @@ -49,6 +49,14 @@ static const STATLineType txt_file_type[n_txt] = { stat_genmpr // 7 }; +// Output data type names + +static const string genesis_name ("GENESIS"); +static const string genesis_dev_name ("GENESIS_DEV"); +static const string genesis_ops_name ("GENESIS_OPS"); +static const string prob_genesis_name ("PROB_GENESIS"); +static const string genesis_shape_name("GENESIS_SHAPE"); + // Names for output data plane types static const string fgen_str = "fcst_genesis"; @@ -129,6 +137,7 @@ class TCGenVxOpt { NumArray Lead; // Spatial masking information + ConcatString VxMaskConf; ConcatString VxMaskName; MaskPoly VxPolyMask; Grid VxGridMask; @@ -168,8 +177,9 @@ class TCGenVxOpt { const StringArray &); void parse_nc_info(Dictionary &); - bool is_keeper(const GenesisInfo &) const; - bool is_keeper(const ProbGenInfo &) const; + bool is_keeper(const GenesisInfo &) const; + bool is_keeper(const ProbGenInfo &) const; + bool is_keeper(const GenShapeInfo &) const; STATOutputType output_map(STATLineType) const; }; @@ -331,6 +341,9 @@ class ProbGenPCTInfo { ////////////////////////////////////////////////////////////////// ConcatString Model; + ConcatString VarName; + ConcatString VxMask; + unixtime InitBeg, InitEnd; unixtime BestBeg, BestEnd; const TCGenVxOpt* VxOpt; @@ -340,10 +353,11 @@ class ProbGenPCTInfo { map PCTMap; // Map of lead times to vectors of pair info - map > FcstGenMap; - map > FcstIdxMap; - map > BestGenMap; - map > BestEvtMap; + map > ProbGenMap; + map > GenShapeMap; + map > ProbIdxMap; + map > BestGenMap; + map > BestEvtMap; ////////////////////////////////////////////////////////////////// @@ -351,8 +365,11 @@ class ProbGenPCTInfo { void set_vx_opt(const TCGenVxOpt *); - void add(const ProbGenInfo &, int, - const GenesisInfo *, bool); + void add_probgen(const ProbGenInfo &, int, + const GenesisInfo *, bool); + + void add_genshape(const GenShapeInfo &, int, + const GenesisInfo *, bool); }; diff --git a/test/config/TCGenConfig_shape b/test/config/TCGenConfig_shape new file mode 100644 index 0000000000..767349741e --- /dev/null +++ b/test/config/TCGenConfig_shape @@ -0,0 +1,292 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// TC-Gen configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// ATCF file format reference: +// http://www.nrlmry.navy.mil/atcf_web/docs/database/new/abrdeck.html +// + +//////////////////////////////////////////////////////////////////////////////// +// +// Genesis event definition criteria +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Model initialization frequency in hours, starting at 0 +// +init_freq = 6; + +// +// Valid hour frequency to be analyzed in hours, starting at 0 +// +valid_freq = 6; + +// +// Forecast hours to be searched for genesis events +// +fcst_hr_window = { + beg = 6; + end = 120; +} + +// +// Minimum track duration for genesis event in hours +// +min_duration = 12; + +// +// Forecast genesis event criteria. Defined as tracks reaching the specified +// intensity category, maximum wind speed threshold, and minimum sea-level +// pressure threshold. The forecast genesis time is the valid time of the first +// track point where all of these criteria are met. +// +fcst_genesis = { + vmax_thresh = NA; + mslp_thresh = NA; +} + +// +// BEST track genesis event criteria. Defined as tracks reaching the specified +// intensity category, maximum wind speed threshold, and minimum sea-level +// pressure threshold. The BEST track genesis time is the valid time of the +// first track point where all of these criteria are met. +// +best_genesis = { + technique = "BEST"; + category = [ "TD", "TS" ]; + vmax_thresh = NA; + mslp_thresh = NA; +} + +// +// Operational track technique name +// +oper_technique = "CARQ"; + +//////////////////////////////////////////////////////////////////////////////// +// +// Track filtering options +// May be specified separately in each filter array entry. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Array of dictionaries containing the track filtering options +// If empty, a single filter is defined using the top-level settings. +// +filter = [ + { desc = "SUMMER_INIT"; init_beg = "20210601"; init_end = "20210901"; }, + { desc = "00Z_12Z_INIT"; init_hour = [ "00", "12" ]; }, + { desc = "06Z_18Z_INIT"; init_hour = [ "06", "18" ]; }, + { desc = "AL_EP_BASIN"; basin_mask = ["AL", "EP" ]; }, + { desc = "AL_BASIN"; basin_mask = "AL"; }, + { desc = "EP_BASIN"; basin_mask = "EP"; } +]; + +// +// Description written to output DESC column +// +desc = "ALL"; + +// +// Forecast ATCF ID's +// If empty, all ATCF ID's found will be processed. +// Statistics will be generated separately for each ATCF ID. +// +model = []; + +// +// BEST and operational track storm identifiers +// +storm_id = []; + +// +// BEST and operational track storm names +// +storm_name = []; + +// +// Forecast and operational initialization times to include or exclude +// +init_beg = ""; +init_end = ""; +init_inc = []; +init_exc = []; + +// +// Forecast, BEST, and operational valid time window +// +valid_beg = ""; +valid_end = ""; + +// +// Forecast and operational initialization hours +// +init_hour = []; + +// +// Forecast and operational lead times in hours +// +lead = []; + +// +// Spatial masking region (path to gridded data file or polyline file) +// +vx_mask = ""; + +// +// Spatial masking of hurricane basin names from the basin_file +// +basin_mask = []; + +// +// Distance to land threshold +// +dland_thresh = NA; + +//////////////////////////////////////////////////////////////////////////////// +// +// Matching and scoring options +// May be specified separately in each filter array entry. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Genesis matching logic. Compare the forecast genesis point to all points in +// the Best track (TRUE) or the single Best track genesis point (FALSE). +// +genesis_match_point_to_track = TRUE; + +// +// Radius in km to search for a matching genesis event +// +genesis_match_radius = 500; + +// +// Time window in hours, relative to the model genesis time, to search for a +// matching Best track point +// +genesis_match_window = { + beg = 0; + end = 0; +} + +// +// Radius in km for a development scoring method hit +// +dev_hit_radius = 500; + +// +// Time window in hours, relative to the model genesis time, for a development +// scoring method hit +// +dev_hit_window = { + beg = -24; + end = 24; +} + +// +// Time window in hours for the Best track genesis minus model initialization +// time difference for an operational scoring method hit +// +ops_hit_window = { + beg = 0; + end = 48; +} + +// +// Discard genesis forecasts for initializations at or after the matching +// BEST track genesis time +// +discard_init_post_genesis_flag = TRUE; + +// +// Scoring methods to be applied +// +dev_method_flag = TRUE; +ops_method_flag = TRUE; + +//////////////////////////////////////////////////////////////////////////////// +// +// Output options +// May be specified separately in each filter array entry. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Probability of genesis thresholds +// +prob_genesis_thresh = ==0.25; + +// +// Confidence interval alpha value +// +ci_alpha = 0.05; + +// +// Statistical output types +// +output_flag = { + fho = NONE; + ctc = NONE; + cts = NONE; + pct = BOTH; + pstd = STAT; + pjc = STAT; + prc = STAT; + genmpr = NONE; +} + + +// +// NetCDF genesis pair counts +// +nc_pairs_flag = FALSE; + +// +// Specify which track points should be counted by thresholding the track point +// valid time minus genesis time difference. +// +valid_minus_genesis_diff_thresh = NA; + +// +// Count unique BEST track genesis event locations (TRUE) versus counting the +// location for all pairs (FALSE). +// +best_unique_flag = TRUE; + +//////////////////////////////////////////////////////////////////////////////// +// +// Global settings +// May only be specified once. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Specify the NetCDF output of the gen_dland tool containing a gridded +// representation of the minimum distance to land. +// +dland_file = "MET_BASE/tc_data/dland_global_tenth_degree.nc"; + +// +// Specify the NetCDF file containing a gridded representation of the +// global basins. +// +basin_file = "MET_BASE/tc_data/basin_global_tenth_degree.nc"; + +// +// NetCDF genesis pairs grid +// +nc_pairs_grid = "G003"; + +// +// Indicate a version number for the contents of this configuration file. +// The value should generally not be modified. +// +version = "V10.1.0"; diff --git a/test/xml/unit_tc_gen.xml b/test/xml/unit_tc_gen.xml index 86245745d8..6146f1d3ec 100644 --- a/test/xml/unit_tc_gen.xml +++ b/test/xml/unit_tc_gen.xml @@ -53,4 +53,23 @@ + + + + &MET_BIN;/tc_gen + \ + -shape &DATA_DIR;/genesis/shape/atl \ + -shape &DATA_DIR;/genesis/shape/epac \ + -track &DATA_DIR;/genesis/atcf/2021 \ + -config &CONFIG_DIR;/TCGenConfig_shape \ + -out &OUTPUT_DIR;/tc_gen/tc_gen_2021_shape \ + -log &OUTPUT_DIR;/tc_gen/tc_gen_2021_shape.log \ + -v 3 + + + &OUTPUT_DIR;/tc_gen/tc_gen_2021_shape.stat + &OUTPUT_DIR;/tc_gen/tc_gen_2021_shape_pct.txt + + + From edd61fd49f4aa3b484a95124ac8423075c5e567e Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 12 Jan 2022 20:59:16 -0700 Subject: [PATCH 054/172] #1844 Added log message for use_var_id --- met/src/libcode/vx_pointdata_python/python_pointdata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/libcode/vx_pointdata_python/python_pointdata.cc b/met/src/libcode/vx_pointdata_python/python_pointdata.cc index 0712bbb13a..43196acc5f 100644 --- a/met/src/libcode/vx_pointdata_python/python_pointdata.cc +++ b/met/src/libcode/vx_pointdata_python/python_pointdata.cc @@ -318,7 +318,7 @@ python_value = PyDict_GetItemString (python_met_point_data, python_use_var_id); bool use_var_id = pyobject_as_bool(python_value); met_pd_out.set_use_var_id(use_var_id); - +mlog << Debug(9) << method_name << "use_var_id: \"" << use_var_id << "\" from python. is_using_var_id(): " << met_pd_out.is_using_var_id() << "\n"; python_value = PyDict_GetItemString (python_met_point_data, python_key_nhdr); From 6cae6b526cc31364e9f8e0347a0938ac70981729 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 12 Jan 2022 21:00:10 -0700 Subject: [PATCH 055/172] #1844 Get use_var_id for python embedding --- met/src/tools/other/plot_point_obs/plot_point_obs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs.cc b/met/src/tools/other/plot_point_obs/plot_point_obs.cc index af45a93641..243f4d0c29 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs.cc +++ b/met/src/tools/other/plot_point_obs/plot_point_obs.cc @@ -189,7 +189,6 @@ void process_point_obs(const char *point_obs_filename) { nc_point_obs.check_nc(point_obs_filename, method_name_s); // exit if missing dims/vars nc_point_obs.read_obs_data(); - use_var_id = nc_point_obs.is_using_var_id(); use_obs_arr = nc_point_obs.is_using_obs_arr(); // Print warning about ineffective command line arguments @@ -219,6 +218,7 @@ void process_point_obs(const char *point_obs_filename) { int obs_qty_block[buf_size]; float obs_arr_block[buf_size][OBS_ARRAY_LEN]; + use_var_id = met_point_obs->is_using_var_id(); if(use_var_id) var_list = met_point_obs->get_var_names(); qty_list = met_point_obs->get_qty_data(); From aaa1010f44b62150009b6dee88de7a952efe4f69 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 12 Jan 2022 21:01:36 -0700 Subject: [PATCH 056/172] #1844 Initial release --- met/scripts/python/met_point_obs.py | 169 +++++++++++++++++++++++ met/scripts/python/read_met_point_obs.py | 136 ++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100755 met/scripts/python/met_point_obs.py create mode 100755 met/scripts/python/read_met_point_obs.py diff --git a/met/scripts/python/met_point_obs.py b/met/scripts/python/met_point_obs.py new file mode 100755 index 0000000000..b4e1e59e30 --- /dev/null +++ b/met/scripts/python/met_point_obs.py @@ -0,0 +1,169 @@ +''' +Created on Nov 10, 2021 + +@author: hsoh +''' + + +import numpy as np + +COUNT_SHOW = 30 + +MET_PYTHON_OBS_ARGS = "MET_POINT_PYTHON_ARGS" + +class met_point_obs(object): + ''' + classdocs + ''' + python_prefix = 'PYTHON_POINT_RAW' + + def __init__(self, use_var_id=True): + ''' + Constructor + ''' + self.raw_data = None + self.use_var_id = use_var_id # True if variable index, False if GRIB code + + # Header + self.nhdr = 0 + self.npbhdr = 0 + self.nhdr_typ = 0 # type table + self.nhdr_sid = 0 #station_uid table + self.nhdr_vld = 0 # valid time strings + self.hdr_typ = [] # (nhdr) + self.hdr_sid = [] # (nhdr) + self.hdr_vld = [] # (nhdr) + self.hdr_lat = [] # (nhdr) + self.hdr_lon = [] # (nhdr) + self.hdr_elv = [] # (nhdr) + self.hdr_typ_table = [] # (nhdr_typ, mxstr2) + self.hdr_sid_table = [] # (nhdr_sid, mxstr2) + self.hdr_vld_table = [] # (nhdr_vld, mxstr) + self.hdr_prpt_typ = [] # optional + self.hdr_irpt_typ = [] # optional + self.hdr_inst_typ = [] # optional + + #Observation data + self.nobs = 0 + self.nobs_qty = 0 + self.nobs_var = 0 + self.obs_qty = [] # (nobs_qty ) + self.obs_hid = [] # (nobs) + self.obs_vid = [] # (nobs) veriable index or GRIB code + self.obs_lvl = [] # (nobs) + self.obs_hgt = [] # (nobs) + self.obs_val = [] # (nobs) + self.obs_qty_table = [] # (nobs_qty, mxstr) + self.obs_var_table = [] # (nobs_var, mxstr2) optional if GRIB code at self.obs_vid + + #def convert(self): + # pass + + def get_point_data(self): + if self.nhdr <= 0: + self.nhdr = len(self.hdr_lat) + if self.nobs <= 0: + self.nobs = len(self.obs_val) + if self.nhdr_typ <= 0: + self.nhdr_typ = len(self.hdr_typ_table) + if self.nhdr_sid <= 0: + self.nhdr_sid = len(self.hdr_sid_table) + if self.nhdr_vld <= 0: + self.nhdr_vld = len(self.hdr_vld_table) + if self.npbhdr <= 0: + self.npbhdr = len(self.hdr_prpt_typ) + if self.nobs_qty <= 0: + self.nobs_qty = len(self.obs_qty_table) + if self.nobs_var <= 0: + self.nobs_var = len(self.obs_var_table) + return self.__dict__ + + @staticmethod + def is_python_script(arg_value): + return arg_value.startswith(met_point_obs.python_prefix) + + @staticmethod + def get_python_script(arg_value): + return arg_value[len(met_point_obs.python_prefix)+1:] + + @staticmethod + def print_data(key, data_array, show_count=COUNT_SHOW): + if isinstance(data_array, list): + data_len = len(data_array) + if show_count >= data_len: + print(" {k:10s}: {v}".format(k=key, v= data_array)) + else: + end_offset = int(show_count/2) + print(" {k:10s}: count={v}".format(k=key, v=data_len)) + print(" {k:10s}[0:{o}] {v}".format(k=key, v=data_array[:end_offset], o=end_offset)) + print(" {k:10s}[{s}:{e}]: {v}".format(k=key, v='...', s=end_offset+1, e=data_len-end_offset-1)) + print(" {k:10s}[{s}:{e}]: {v}".format(k=key, v= data_array[-end_offset:], s=(data_len-end_offset), e=(data_len-1))) + else: + print(" {k:10s}: {v}".format(k=key, v= data_array)) + + @staticmethod + def print_point_data(met_point_data): + print(' === MET point data by python embedding ===') + met_point_obs.print_data('nhdr', met_point_data['nhdr']) + met_point_obs.print_data('nobs' , met_point_data['nobs']) + met_point_obs.print_data('use_var_id',met_point_data['use_var_id']) + met_point_obs.print_data('hdr_typ',met_point_data['hdr_typ']) + met_point_obs.print_data('obs_hid',met_point_data['obs_hid']) + met_point_obs.print_data('obs_vid',met_point_data['obs_vid']) + met_point_obs.print_data('obs_val',met_point_data['obs_val']) + met_point_obs.print_data('obs_var_table',met_point_data['obs_var_table']) + met_point_obs.print_data('obs_qty_table',met_point_data['obs_qty_table']) + met_point_obs.print_data('hdr_typ_table',met_point_data['hdr_typ_table']) + met_point_obs.print_data('hdr_sid_table',met_point_data['hdr_sid_table']) + met_point_obs.print_data('hdr_vld_table',met_point_data['hdr_vld_table']) + print(' === MET point data by python embedding ===') + + +def get_sample_point_obs(): + point_obs_data = met_point_obs() + point_obs_data.hdr_typ = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) + point_obs_data.hdr_sid = np.array([ 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 2, 2, 3 ]) + point_obs_data.hdr_vld = np.array([ 0, 1, 2, 3, 4, 4, 3, 4, 3, 4, 5, 4, 3, 0, 1, 2, 3, 4, 4, 3, 4, 3, 4, 5, 4, 3 ]) + point_obs_data.hdr_lat = np.array([ 43., 43., 43., 43., 43., 43., 43., 43., 43., 46., 46., 46., 46., 43., 43., 43., 43., 43., 43., 43., 43., 43., 46., 46., 46., 46. ]) + point_obs_data.hdr_lon = np.array([ -89., -89., -89., -89., -89., -89., -89., -89., -89., -92., -92., -92., -92., -89., -89., -89., -89., -89., -89., -89., -89., -89., -92., -92., -92., -92. ]) + point_obs_data.hdr_elv = np.array([ 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220. ]) + + point_obs_data.obs_qid = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) + point_obs_data.obs_hid = np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25 ]) + point_obs_data.obs_vid = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]) + point_obs_data.obs_lvl = np.array([ 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000. ]) + point_obs_data.obs_hgt = np.array([ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2. ]) + point_obs_data.obs_val = np.array([ 292., 292.5, 293., 293.5, 294., 294.5, 295., 295.5, 296., 292., 293.4, 293., 296., 294., 92., 92.5, 93., 93.5, 94., 94.5, 95., 95.5, 96., 92., 93.4, 93., 96., 94. ]) + + point_obs_data.hdr_typ_table = [ "ADPSFC" ] + point_obs_data.hdr_sid_table = [ "001", "002", "003", "004" ] + point_obs_data.hdr_vld_table = [ + "20120409_115000", "20120409_115500", "20120409_120100", "20120409_120500", "20120409_121000", + "20120409_120000" ] + point_obs_data.obs_var_table = [ "TMP", "RH" ] + point_obs_data.obs_qty_table = [ "NA" ] + point_obs_data.nhdr = len(point_obs_data.hdr_lat) + point_obs_data.nobs = len(point_obs_data.obs_val) + #point_obs_data.met_point_data = point_obs_data + return point_obs_data + + +def main(): + met_point_data = get_sample_point_obs().get_point_data() + + print('All',met_point_data) + print(" nhdr: ",met_point_data['nhdr']) + print(" nobs: ",met_point_data['nobs']) + print('use_var_id: ',met_point_data['use_var_id']) + print('hdr_typ: ',met_point_data['hdr_typ']) + print('obs_vid: ',met_point_data['obs_vid']) + print('obs_val: ',met_point_data['obs_val']) + print('obs_var_table: ',met_point_data['obs_var_table']) + print('obs_qty_table: ',met_point_data['obs_qty_table']) + print('hdr_typ_table: ',met_point_data['hdr_typ_table']) + print('hdr_sid_table: ',met_point_data['hdr_sid_table']) + print('hdr_vld_table: ',met_point_data['hdr_vld_table']) + print('Done python scripot') + +if __name__ == '__main__': + main() diff --git a/met/scripts/python/read_met_point_obs.py b/met/scripts/python/read_met_point_obs.py new file mode 100755 index 0000000000..5a99f63a8e --- /dev/null +++ b/met/scripts/python/read_met_point_obs.py @@ -0,0 +1,136 @@ +''' +Created on Nov 10, 2021 + +@author: hsoh +''' + +import os +import sys +import time +import numpy as np +import netCDF4 as nc + +from met_point_obs import met_point_obs, get_sample_point_obs, MET_PYTHON_OBS_ARGS + +DO_PRINT_DATA = False +ARG_PRINT_DATA = 'show_data' + +class nc_point_obs(met_point_obs): + + @staticmethod + def get_num_array(dataset, var_name): + nc_var = dataset.variables.get(var_name, None) + return nc_var[:].filled(nc_var._FillValue if '_FillValue' in nc_var.ncattrs() else -9999) if nc_var else [] + + @staticmethod + def get_ncbyte_array_to_str(nc_var): + nc_str_data = nc_var[:] + if nc_var.datatype.name == 'bytes8': + nc_str_data = [ str(s.compressed(),"utf-8") for s in nc_var[:]] + return nc_str_data + + @staticmethod + def get_string_array(dataset, var_name): + nc_var = dataset.variables.get(var_name, None) + return nc_point_obs.get_ncbyte_array_to_str(nc_var) if nc_var else [] + + #def convert(self): + # pass + + def read_nectdf(self, nc_filename): + if os.path.exists(nc_filename): + dataset = nc.Dataset(nc_filename, 'r') + # Header + self.hdr_typ = dataset['hdr_typ'][:] + self.hdr_sid = dataset['hdr_sid'][:] + self.hdr_vld = dataset['hdr_vld'][:] + self.hdr_lat = dataset['hdr_lat'][:] + self.hdr_lon = dataset['hdr_lon'][:] + self.hdr_elv = dataset['hdr_elv'][:] + self.hdr_typ_table = self.get_string_array(dataset, 'hdr_typ_table') + self.hdr_sid_table = self.get_string_array(dataset, 'hdr_sid_table') + self.hdr_vld_table = self.get_string_array(dataset, 'hdr_vld_table') + + nc_var = dataset.variables.get('hdr_prpt_typ', None) + if nc_var: + self.hdr_prpt_typ = nc_var[:] + nc_var = dataset.variables.get('hdr_irpt_typ', None) + if nc_var: + self.hdr_irpt_typ = nc_var[:] + nc_var = dataset.variables.get('hdr_inst_typ', None) + if nc_var: + self.hdr_inst_typ =nc_var[:] + + #Observation data + self.nobs = 0 + self.hdr_sid = dataset['hdr_sid'][:] + #self.obs_qty = self.get_num_array(dataset, 'obs_qty') + self.obs_qty = np.array(dataset['obs_qty'][:]) + self.obs_hid = np.array(dataset['obs_hid'][:]) + self.obs_lvl = np.array(dataset['obs_lvl'][:]) + self.obs_hgt = np.array(dataset['obs_hgt'][:]) + self.obs_val = np.array(dataset['obs_val'][:]) + nc_var = dataset.variables.get('obs_vid', None) + if nc_var is None: + self.use_var_id = False + nc_var = dataset.variables.get('obs_gc', None) + else: + self.obs_var_table = self.get_string_array(dataset, 'obs_var') + if nc_var: + self.obs_vid = np.array(nc_var[:]) + + self.obs_qty_rwo = dataset['obs_qty'][:] + + self.obs_qty_table = self.get_string_array(dataset, 'obs_qty_table') + else: + print("==ERROR== netcdf file ({f}) does not exist".format(f=nc_filename)) + + + +perf_start_time = time.time() +perf_start_counter = time.perf_counter_ns() + +point_obs_data = None +if len(sys.argv) == 1: + point_obs_data = get_sample_point_obs() +else: + netcdf_filename = sys.argv[1] + if os.path.exists(netcdf_filename): + point_obs_data = nc_point_obs() + point_obs_data.read_nectdf(netcdf_filename) + elif met_point_obs.is_python_script(netcdf_filename): + python_script = met_point_obs.get_python_script(netcdf_filename) + python_args = [] + if len(sys.argv) > 2: + if ARG_PRINT_DATA == sys.argv[-1]: + python_args = sys.argv[2:-1] + else: + python_args = sys.argv[2:] + python_args_string = " ".join(python_args) if 0 < len(python_args) else '' + os.environ[MET_PYTHON_OBS_ARGS] = python_args_string + #os.system(python_command) + exec(open(python_script).read()) + print('------') + + if point_obs_data is None: + print("PYTHON: Fail to get point_obs_data by calling {s} from {m}".format( + s=python_script, m=sys.argv[0])) + if ARG_PRINT_DATA == sys.argv[-1]: + DO_PRINT_DATA = True + + point_obs_data = nc_point_obs() + point_obs_data.read_nectdf(netcdf_filename) + +if point_obs_data is not None: + met_point_data = point_obs_data.get_point_data() + met_point_data['met_point_data'] = point_obs_data + + if DO_PRINT_DATA: + met_point_obs.print_point_data(met_point_data) + +perf_end_time = time.time() +perf_end_counter = time.perf_counter_ns() +perf_duration = perf_end_time - perf_start_time +perf_duration_counter = (perf_end_counter - perf_start_counter) / 1000000000 + +print('Done python script {s} Took walltime: {t1} & perf: {t2} seconds'.format(s=sys.argv[0], t1=perf_duration, t2=perf_duration_counter)) From adf4928a8dd35933781c79d0cbe40c40cfdd0dcd Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 12 Jan 2022 21:02:14 -0700 Subject: [PATCH 057/172] #1844 Added met_point_obs.py and read_met_point_obs.py --- met/scripts/python/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/met/scripts/python/Makefile.am b/met/scripts/python/Makefile.am index 78dc7d88bc..368da3da7f 100644 --- a/met/scripts/python/Makefile.am +++ b/met/scripts/python/Makefile.am @@ -26,11 +26,13 @@ pythonscriptsdir = $(pkgdatadir)/python pythonscripts_DATA = \ + met_point_obs.py \ read_ascii_numpy.py \ read_ascii_numpy_grid.py \ read_ascii_xarray.py \ read_ascii_point.py \ - read_ascii_mpr.py + read_ascii_mpr.py \ + read_met_point_obs.py EXTRA_DIST = ${pythonscripts_DATA} From 0640d8ddfe39c33d70f76e19d9dd942812eebcbb Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 12 Jan 2022 21:04:17 -0700 Subject: [PATCH 058/172] #1844 Added 4 unit test for python embedding of MET point data --- test/xml/unit_python.xml | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/test/xml/unit_python.xml b/test/xml/unit_python.xml index 35993ed441..6b0850343d 100644 --- a/test/xml/unit_python.xml +++ b/test/xml/unit_python.xml @@ -446,4 +446,111 @@ + + &MET_BIN;/point2grid + \ + 'PYTHON_NUMPY=&MET_BASE;/python/read_met_point_obs.py &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc' \ + G212 \ + &OUTPUT_DIR;/python/pb2nc_TMP.nc \ + -field 'name="TMP"; level="*"; valid_time="20120409_120000"; censor_thresh=[ <0 ]; censor_val=[0];' \ + -name TEMP \ + -v 1 + + + &OUTPUT_DIR;/python/pb2nc_TMP.nc + + + + + &MET_BIN;/plot_point_obs + + TO_GRID NONE + + \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &OUTPUT_DIR;/python/nam_and_ndas.20120409.t12z.prepbufr_CONFIG.ps \ + -point_obs &OUTPUT_DIR;/ascii2nc/trmm_2012040912_3hr.nc \ + -plot_grid &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ + -config &CONFIG_DIR;/PlotPointObsConfig \ + -title "NAM 2012040900 F12 vs NDAS 500mb RH and TRMM 3h > 0" \ + -v 3 + + + &OUTPUT_DIR;/python/nam_and_ndas.20120409.t12z.prepbufr_CONFIG.ps + + + + + &MET_BIN;/plot_point_obs + + TO_GRID NONE + + \ + 'PYTHON_NUMPY=&MET_BASE;/python/read_met_point_obs.py &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc' \ + &OUTPUT_DIR;/python/nam_and_ndas.20120409.t12z.prepbufr_CONFIG.ps \ + -point_obs 'PYTHON_NUMPY=&MET_BASE;/python/read_met_point_obs.py &OUTPUT_DIR;/ascii2nc/trmm_2012040912_3hr.nc' \ + -plot_grid &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ + -config &CONFIG_DIR;/PlotPointObsConfig \ + -title "NAM 2012040900 F12 vs NDAS 500mb RH and TRMM 3h > 0" \ + -v 3 + + + &OUTPUT_DIR;/python/nam_and_ndas.20120409.t12z.prepbufr_CONFIG.ps + + + + + echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib" \ + > &OUTPUT_DIR;/python/ensemble_stat/input_file_list; \ + &MET_BIN;/ensemble_stat + + DESC NA + OBS_ERROR_FLAG FALSE + SKIP_CONST FALSE + OUTPUT_PREFIX FILE_LIST + + \ + &OUTPUT_DIR;/python/ensemble_stat/input_file_list \ + &CONFIG_DIR;/EnsembleStatConfig \ + -grid_obs &DATA_DIR_OBS;/laps/laps_2012041012_F000.grib \ + -point_obs 'PYTHON_NUMPY=&MET_BASE;/python/read_met_point_obs.py &OUTPUT_DIR;/ascii2nc/gauge_2012041012_24hr.nc' \ + -outdir &OUTPUT_DIR;/python/ensemble_stat -v 1 + + + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V.stat + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_ecnt.txt + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_rhist.txt + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_phist.txt + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_orank.txt + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_ssvar.txt + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_ens.nc + &OUTPUT_DIR;/python/ensemble_stat/ensemble_stat_FILE_LIST_20120410_120000V_orank.nc + + + + + &MET_BIN;/point_stat + + BEG_DS -1800 + END_DS 1800 + OUTPUT_PREFIX GRIB1_NAM_GDAS_WINDS + CONFIG_DIR &CONFIG_DIR; + CLIMO_FILE "&DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012_gNam.grib" + + \ + &DATA_DIR_MODEL;/grib1/nam/nam_2012040900_F012.grib \ + 'PYTHON_NUMPY=&MET_BASE;/python/read_met_point_obs.py &OUTPUT_DIR;/pb2nc/gdas1.20120409.t12z.prepbufr.nc' \ + &CONFIG_DIR;/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/python -v 1 + + + &OUTPUT_DIR;/python/point_stat_GRIB1_NAM_GDAS_WINDS_120000L_20120409_120000V.stat + + + From 37f4f321b07a1933aea85cb3120356605e0e2a72 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 12 Jan 2022 21:25:51 -0700 Subject: [PATCH 059/172] More changes to test_util.R to account for differences between 4.7.0 and 4.9.2 of ncdiff. The earlier version reported 0 diffs for the time_bounds, lat, lon, latitude, and longitude variables while the newer version reports their raw values. Simply ignore these variables for now. This isn't a great solution but when we reimplement this testing logic in python, we can address this issue then. --- test/R_test/test_util.R | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/R_test/test_util.R b/test/R_test/test_util.R index d00616209a..bcbeb14e71 100644 --- a/test/R_test/test_util.R +++ b/test/R_test/test_util.R @@ -753,6 +753,21 @@ compareNc = function(nc1, nc2, verb, strict=0, delta=-1, comp_var=0){ # for each variable present in the file, check for differences for(strVar in names(ncFileD$var)){ + # Skip the time_bounds, lat, and lon variables + # Note: Running "ncdiff -x -v time_bounds" successfully excludes that variable + # in version 4.7.0, but not in version 4.9.2. Similarly, version 4.7.0 + # returns 0 diffs for variables named lat and lon while version 4.9.2 + # returns the raw values rather than their diffs. + # For now, just ignore these variables. + if(strVar == "time_bounds" || + strVar == "lat" || + strVar == "latitude" || + strVar == "lon" || + strVar == "longitude" ){ + if( 1 <= verb ){ cat("ignored var", strVar, "\n"); } + next; + } + # check the variable attributes for differences listAtt1 = ncatt_get(ncFile1, varid=strVar); listAtt1Nam = names(listAtt1); From 4f57edd62d52d5496a881aecc696bf14d8a8d6a2 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 12 Jan 2022 22:37:42 -0700 Subject: [PATCH 060/172] #1844 Added python embedding for point observation data --- met/docs/Users_Guide/appendixF.rst | 50 +++++++++++++++++++++++++ met/docs/Users_Guide/ensemble-stat.rst | 2 +- met/docs/Users_Guide/plotting.rst | 15 ++++++++ met/docs/Users_Guide/point-stat.rst | 2 +- met/docs/Users_Guide/reformat_point.rst | 19 ++++++++++ 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/appendixF.rst b/met/docs/Users_Guide/appendixF.rst index 3a4046e9ea..586c264c9e 100644 --- a/met/docs/Users_Guide/appendixF.rst +++ b/met/docs/Users_Guide/appendixF.rst @@ -257,3 +257,53 @@ The **read_ascii_mpr.py** sample script can be found in: • MET installation directory in *MET_BASE/python*. • `MET GitHub repository `_ in *met/scripts/python*. + + +Python Embedding for Point Observations as input +________________________________________________ + + +The point2grid, plot_point_obs, ensemble_stat, and point_stat tools use MET point observation NetCDF. They support the python embedding by the prefix 'PYTHON_NUMPY=" and followed by a python script name instead of the MET point observastion NetCDF filename. The customized python script is expected to extend MET_BASE/python/met_point_obs.py and to produce the python variable, **met_point_data**, which is the dictionary of the MET point observation data. They are defined at MET_BASE/python/met_point_obs.py. + + +.. _pyembed-point-obs-data: + + +.. code-block:: none + + met_point_data = { + + 'use_var_id': Trur/False, # obs_vid are variable index if True, otherwise GRIB codes + + # Header data + 'nhdr': integer_value, # number of headers + 'pbhdr': integer_value, # number of PREPBUFR specific headers + 'nhdr_typ': integer_value, # number of message types + 'nhdr_sid': integer_value, # number of station IDs + 'nhdr_vld': integer_value, # number of valid times + 'hdr_typ': nympy_integer_array, # index of message type + 'hdr_sid': nympy_integer_array, # index of station ID + 'hdr_vld': nympy_integer_array, # index of valid time + 'hdr_lat': nympy_float_array, # latitude + 'hdr_lon': nympy_float_array, # longitude + 'hdr_elv': nympy_float_array, # station elevation + 'hdr_typ_table': string_value, # message types + 'hdr_sid_table': string_value, # station IDs + 'hdr_vld_table': string_value, # valid times "yyyymmdd_hhmmss" + 'hdr_prpt_typ': nympy_integer_array, # optional + 'hdr_irpt_typ': nympy_integer_array, # optional + 'hdr_inst_typ': nympy_integer_array, # optional + + # Observation data + 'nobs': integer_value, # number of observation + 'nobs_qty': integer_value # number of quality marks + 'nobs_var': integer_value # number of variable names + 'obs_qty': nympy_integer_array, # index of quality mark + 'obs_hid': nympy_integer_array, # index of header + 'obs_vid': nympy_integer_array, # index of veriable or GRIB code + 'obs_lvl': nympy_float_array, # pressure level + 'obs_hgt': nympy_float_array, # height of observation data + 'obs_val' nympy_float_array, # observatin value + 'obs_qty_table': string_array, # quality marks + 'obs_var_table': string_array, # variable names + } diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index 266519da4f..bf3bd54291 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -93,7 +93,7 @@ Optional arguments for ensemble_stat 4. To produce ensemble statistics using gridded observations, use the **-grid_obs file** option to specify a gridded observation file. This option may be used multiple times if your observations are in several files. -5. To produce ensemble statistics using point observations, use the **-point_obs file** option to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. +5. To produce ensemble statistics using point observations, use the **-point_obs file** option to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. The python embedding will be activated if the **file** begines with 'PYTHON_NUMPY=" and followed by a python script name. 6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** option specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** option from earlier versions of MET. diff --git a/met/docs/Users_Guide/plotting.rst b/met/docs/Users_Guide/plotting.rst index 7f748e7885..a96dca605a 100644 --- a/met/docs/Users_Guide/plotting.rst +++ b/met/docs/Users_Guide/plotting.rst @@ -8,6 +8,9 @@ __________________ This section describes how to check your data files using plotting utilities. Point observations can be plotted using the Plot-Point-Obs utility. A single model level can be plotted using the plot_data_plane utility. For object based evaluations, the MODE objects can be plotted using plot_mode_field. Occasionally, a post-processing or timing error can lead to errors in MET. These tools can assist the user by showing the data to be verified to ensure that times and locations match up as expected. +MET version 10.1 adds support for the passing point observations to plot_point_obs using a Python scriptAn example of running plot_point_obs with Python embedding is included below. + + plot_point_obs usage ~~~~~~~~~~~~~~~~~~~~ @@ -66,6 +69,18 @@ An example of the plot_point_obs calling sequence is shown below: In this example, the Plot-Point-Obs tool will process the input sample_pb.nc file and write a postscript file containing a plot to a file named sample_pb.ps. +This is an equivalent command with the python embedding. This is an example for the python embeddingt. + +.. code-block:: none + + plot_point_obs 'PYTHON_NUMPY=MET_BASE/python/read_met_point_obs.py sample_pb.nc' sample_data.ps + + +The user should replace the python script with the customized python script for the custom point observation data. + +Please refer to :numref:`Appendix F, Section %s ` for more details about Python embedding in MET. + + plot_point_obs configuration file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index 7a9966511c..ce7b74e905 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -286,7 +286,7 @@ Required arguments for point_stat Optional arguments for point_stat ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -4. The **-point_obs** file may be used to pass additional NetCDF point observation files to be used in the verification. +4. The **-point_obs** file may be used to pass additional NetCDF point observation files to be used in the verification. The python embedding will be activated if the **file** begines with 'PYTHON_NUMPY=" and followed by a python script name. 5. The **-obs_valid_beg** time option in YYYYMMDD[_HH[MMSS]] format sets the beginning of the observation matching time window, overriding the configuration file setting. diff --git a/met/docs/Users_Guide/reformat_point.rst b/met/docs/Users_Guide/reformat_point.rst index 999393b72d..9e41ca80dc 100644 --- a/met/docs/Users_Guide/reformat_point.rst +++ b/met/docs/Users_Guide/reformat_point.rst @@ -981,6 +981,8 @@ _______________ The Point2Grid tool takes point observations from a NetCDF output file from one of the four previously mentioned MET tools (ascii2nc, madis2nc, pb2nc, lidar2nc) and creates a gridded NetCDF file. The other point observations are GOES-16/17 input files in NetCDF format (especially, Aerosol Optical Depth. Future development will include support for reading input files not produced from MET tools. +MET version 10.1 adds support for the passing point observations to point2grid using a Python script with "input_filename" which begins with the "PYTHON_NUMPY= [arguments]" instead of MET point observation NetCDF input. An example of running point2grid with Python embedding is included below. + point2grid usage ~~~~~~~~~~~~~~~~ @@ -1013,6 +1015,8 @@ Required arguments for point2grid 1. The **input_filename** argument indicates the name of the input NetCDF file to be processed. Currently, only NetCDF files produced from the ascii2nc, madis2nc, pb2nc, and lidar2nc are supported. And AOD dataset from GOES16/17 are supported, too. Support for additional file types will be added in future releases. +The MET point observation NetCDF file name as **input_filename** argument is equivalent with "PYTHON_NUMPY=MET_BASE/python/read_met_point_obs.py netcdf_file name'. + 2. The **to_grid** argument defines the output grid as: (1) a named grid, (2) the path to a gridded data file, or (3) an explicit grid specification string. 3. The **output_filename** argument is the name of the output NetCDF file to be written. @@ -1065,6 +1069,21 @@ For the GOES-16 and GOES-17 data, the computing lat/long is time consuming. So t When processing GOES-16 data, the **-qc** option may also be used to specify the acceptable quality control flag values. The example above regrids the GOES-16 AOD values to NCEP Grid number 212 (which QC flags are high, medium, and low), writing to the output the maximum AOD value falling inside each grid box. +Here is an example of processing the same set of observations but using Python embedding instead: + + +.. code-block:: none + + point2grid \ + 'PYTHON_NUMPY=MET_BASE/python/read_met_point_obs.py ascii2nc_edr_hourly.20130827.nc' \ + G212 python_gridded_ascii_python.nc -config Point2GridConfig_edr \ + -field 'name="200"; level="*"; valid_time="20130827_205959";' -method MAX -v 1 + +The user should replace the python script with the customized python script for the custom point observation data. This is an example for the python embedding. + +Please refer to :numref:`Appendix F, Section %s ` for more details about Python embedding in MET. + + point2grid output ~~~~~~~~~~~~~~~~~ From de81526c4894e14ca0496eba9872462f8cc1dfd8 Mon Sep 17 00:00:00 2001 From: mo-mglover <78152252+mo-mglover@users.noreply.github.com> Date: Thu, 13 Jan 2022 22:48:26 +0000 Subject: [PATCH 061/172] Feature 1926 gridstat openmp (#1977) Co-authored-by: johnhg Co-authored-by: John Halley Gotway Co-authored-by: Julie Prestopnik --- met/configure.ac | 7 + met/docs/Users_Guide/config_options.rst | 119 ++++++++++-- met/docs/Users_Guide/installation.rst | 8 + met/src/basic/vx_util/Makefile.am | 1 + met/src/basic/vx_util/data_plane_util.cc | 170 ++++++++++-------- met/src/basic/vx_util/handle_openmp.cc | 52 ++++++ met/src/basic/vx_util/handle_openmp.h | 24 +++ .../tools/core/ensemble_stat/ensemble_stat.cc | 5 + met/src/tools/core/grid_stat/grid_stat.cc | 5 + .../tools/other/gen_ens_prod/gen_ens_prod.cc | 5 + test/config/GridStatConfig_rtma | 2 +- test/xml/unit_grid_stat.xml | 26 +++ 12 files changed, 336 insertions(+), 88 deletions(-) create mode 100644 met/src/basic/vx_util/handle_openmp.cc create mode 100644 met/src/basic/vx_util/handle_openmp.h diff --git a/met/configure.ac b/met/configure.ac index 2fc599e47a..7008748079 100644 --- a/met/configure.ac +++ b/met/configure.ac @@ -8,6 +8,13 @@ AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.9 foreign]) +# OpenMP + +AC_OPENMP() + +CPPFLAGS="${CPPFLAGS} ${OPENMP_CFLAGS}" +LDFLAGS="${LDFLAGS} ${OPENMP_CFLAGS}" + # # Look for the NetCDF library # diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index e6d2349cc4..b56cb65d75 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -202,6 +202,12 @@ to use one configuration file rather than maintianing many very similar ones. An error in the syntax of a configuration file will result in an error from the MET tool stating the location of the parsing error. +Runtime Environment Variables +----------------------------- + +MET_BASE +^^^^^^^^ + The MET_BASE variable is defined in the code at compilation time as the path to the MET shared data. These are things like the default configuration files, common polygons and color scales. MET_BASE may be used in the MET configuration @@ -209,6 +215,9 @@ files when specifying paths and the appropriate path will be substituted in. If MET_BASE is defined as an environment variable, its value will be used instead of the one defined at compilation time. +MET_OBS_ERROR_TABLE +^^^^^^^^^^^^^^^^^^^ + The MET_OBS_ERROR_TABLE environment variable can be set to specify the location of an ASCII file defining observation error information. The default table can be found in the installed *share/met/table_files/obs_error_table.txt*. This @@ -236,6 +245,9 @@ values and randomly perturbed ensemble member values. Values less than MIN are reset to the mimimum value and values greater than MAX are reset to the maximum value. A value of NA indicates that the variable is unbounded. +MET_GRIB_TABLES +^^^^^^^^^^^^^^^ + The MET_GRIB_TABLES environment variable can be set to specify the location of custom GRIB tables. It can either be set to a specific file name or to a directory containing custom GRIB tables files. These file names must begin with @@ -289,9 +301,96 @@ References: | `NCEP WMO GRIB2 Documentation `_ | +OMP_NUM_THREADS +^^^^^^^^^^^^^^^ + +**Introduction** + +There are a number of different ways of parallelizing code. OpenMP offers +parallelism within a single shared-memory workstation or supercomputer node. +The programmer writes OpenMP directives into the code to parallelize +particular code regions. + +When a parallelized code region is reached, which we shall hereafter call a +parallel region, a number of threads are spawned and work is shared among them. +Running on different cores, this reduces the execution time. At the end of the +parallel region, the code returns to single-thread execution. + +A limited number of code regions are parallelized in MET. As a consequence, +there are limits to the overall speed gains acheivable. Only the parallel +regions of code will get faster with more threads, leaving the remaining +serial portions to dominate the runtime. + +Not all top-level executables use parallelized code. If OpenMP is available, +a log message will appear inviting the user to increase the number of threads +for faster runtimes. + +**Setting the number of threads** + +The number of threads is controlled by the environment variable +*OMP_NUM_THREADS* . For example, on a quad core machine, the user might choose +to run on 4 threads: + +.. code :: bash + + export OMP_NUM_THREADS=4 + +Alternatively, the variable may be specified as a prefix to the executable +itself. For example: + +.. code :: bash + + OMP_NUM_THREADS=4 + +The case where this variable remains unset is handled inside the code, which +defaults to a single thread. + +There are choices when deciding how many threads to use. To perform a single run +as fast as possible, it would likely be appropriate to use as many threads as +there are (physical) cores available on the specific system. However, it is not +a cast-iron guarantee that more threads will always translate into more speed. +In theory, there is a chance that running across multiple non-uniform memory +access (NUMA) regions may carry negative performance impacts. This has not been +observed in practice, however. + +A lower thread count is appropriate when time-to-solution is not so critical, +because cores remain idle when the code is not inside a parallel region. Fewer +threads typically means better resource utilization. + +**Which code is parallelized?** + +Regions of parallelized code are: + + * :code:`fractional_coverage (data_plane_util.cc)` + +Only the following top-level executables can presently benefit from OpenMP +parallelization: + + * :code:`grid_stat` + * :code:`ensemble_stat` + * :code:`grid_ens_prod` + +**Thread Binding** + +It is normally beneficial to bind threads to particular cores, sometimes called +*affinitization*. There are a few reasons for this, but at the very least it +guarantees that threads remain evenly distributed across the available cores. +Otherwise, the operating system may migrate threads between cores during a run. + +OpenMP provides some environment variables to handle this: :code:`OMP_PLACES` +and :code:`OMP_PROC_BIND`. We anticipate that the effect of setting only +:code:`OMP_PROC_BIND=true` would be neutral-to-positive. + +However, there are sometimes compiler-specific environment variables. Instead, +thread affinitization is sometimes handled by MPI launchers, since OpenMP is +often used in MPI codes to reduce intra-node communications. + +Where code is running in a production context, it is worth being familiar with +the binding / affinitization method on the particular system and building it +into any relevant scripting. Settings common to multiple tools -_________________________________ +--------------------------------- .. _exit_on_warning: @@ -2190,10 +2289,10 @@ are empty. Note: grib_code 11 is equivalent to obs_var "TMP". } Settings specific to individual tools -_____________________________________ +------------------------------------- EnsembleStatConfig_default -~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _ens: @@ -2505,7 +2604,7 @@ used for random assignment of ranks when they are tied. } MODEAnalysisConfig_default -~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^ MODE line options are used to create filters that determine which MODE output lines are read in and processed. The MODE line options are numerous. They @@ -2843,7 +2942,7 @@ MET User's Guide for a description of these attributes. MODEConfig_default -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ .. _quilt: @@ -3158,7 +3257,7 @@ much more flexible "regrid" option may be used instead. shift_right = 0; PB2NCConfig_default -~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^ The PB2NC tool filters out observations from PREPBUFR or BUFR files using the following criteria: @@ -3484,7 +3583,7 @@ stack (most quality controlled) or the bottom of the event stack (most raw). event_stack_flag = TOP; SeriesAnalysisConfig_default -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _block_size: @@ -3539,7 +3638,7 @@ grid is large. } STATAnalysisConfig_default -~~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _jobs: @@ -4008,7 +4107,7 @@ confidence intervals computed for the aggregated statistics. vif_flag = FALSE; WaveletStatConfig_default -~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^ .. _grid_decomp_flag: @@ -4099,7 +4198,7 @@ similar to the "fcst_raw_plot" described in the "Settings common to multiple tools" section. WWMCARegridConfig_default -~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^ .. _to_grid: diff --git a/met/docs/Users_Guide/installation.rst b/met/docs/Users_Guide/installation.rst index 963545ac2f..b4459fed0d 100644 --- a/met/docs/Users_Guide/installation.rst +++ b/met/docs/Users_Guide/installation.rst @@ -290,6 +290,14 @@ Enable compilation of the MODE-Graphics tool. Requires $MET_CAIRO and $MET_FREET Disable use of BLOCK4 in the compilation. Use this if you have trouble using PrepBUFR files. +.. code-block:: none + + --disable-openmp + +Disable compilation of OpenMP directives within the code which allows some code +regions to benefit from thread-parallel execution. Runtime environment variable +:code:`OMP_NUM_THREADS` controls the number of threads. + Run the configure script with the **-help** argument to see the full list of configuration options. Make Targets diff --git a/met/src/basic/vx_util/Makefile.am b/met/src/basic/vx_util/Makefile.am index 57b7a100db..ae466f0963 100644 --- a/met/src/basic/vx_util/Makefile.am +++ b/met/src/basic/vx_util/Makefile.am @@ -69,6 +69,7 @@ libvx_util_a_SOURCES = ascii_table.cc ascii_table.h \ GridOffset.h GridOffset.cc \ observation.h observation.cc \ stat_column_defs.h \ + handle_openmp.h handle_openmp.cc \ RectangularTemplate.h RectangularTemplate.cc $(OPT_PYTHON_SOURCES) libvx_util_a_CPPFLAGS = ${MET_CPPFLAGS} diff --git a/met/src/basic/vx_util/data_plane_util.cc b/met/src/basic/vx_util/data_plane_util.cc index 3f5b5f7278..39fbb67679 100644 --- a/met/src/basic/vx_util/data_plane_util.cc +++ b/met/src/basic/vx_util/data_plane_util.cc @@ -16,6 +16,10 @@ using namespace std; #include #include +#ifdef _OPENMP + #include "omp.h" +#endif + #include "data_plane_util.h" #include "interp_util.h" #include "two_to_one.h" @@ -247,83 +251,95 @@ void fractional_coverage(const DataPlane &dp, DataPlane &frac_dp, } } - // Build the grid template - GridTemplateFactory gtf; - GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); - - mlog << Debug(3) - << "Computing fractional coverage field using the " - << t.get_str() << " threshold and the " - << interpmthd_to_string(InterpMthd_Nbrhd) << "(" << gt->size() - << ") " << gt->getClassName() << " interpolation method.\n"; - - // Initialize the fractional coverage field - frac_dp = dp; - frac_dp.set_constant(bad_data_double); - - // Compute the fractional coverage meeting the threshold criteria - for(x=0; xgetFirstInGrid(x, y, dp.nx(), dp.ny()); - gp != NULL; - gp = gt->getNextInGrid()) { - if(is_bad_data(v = dp.get(gp->x, gp->y))) continue; - n_vld++; - if(t.check(v, - (use_climo ? cmn->get(gp->x, gp->y) : bad), - (use_climo ? csd->get(gp->x, gp->y) : bad))) n_thr++; - } - } - // Subtract off the bottom edge, shift up, and add the top. - else { - - // Subtract points from the the bottom edge - for(gp = gt->getFirstInBotEdge(); - gp != NULL; - gp = gt->getNextInBotEdge()) { - if(is_bad_data(v = dp.get(gp->x, gp->y))) continue; - n_vld--; - if(t.check(v, - (use_climo ? cmn->get(gp->x, gp->y) : bad), - (use_climo ? csd->get(gp->x, gp->y) : bad))) n_thr--; - } - - // Increment Y - gt->incBaseY(1); - - // Add points from the the top edge - for(gp = gt->getFirstInTopEdge(); - gp != NULL; - gp = gt->getNextInTopEdge()) { - if(is_bad_data(v = dp.get(gp->x, gp->y))) continue; - n_vld++; - if(t.check(v, - (use_climo ? cmn->get(gp->x, gp->y) : bad), - (use_climo ? csd->get(gp->x, gp->y) : bad))) n_thr++; - } - } - - // Check for enough valid data and compute fractional coverage - if((double)(n_vld)/gt->size() >= vld_t && n_vld != 0) { - frac_dp.set((double) n_thr/n_vld, x, y); - } - - } // end for y - - // Increment X - if(x < (dp.nx() - 1)) gt->incBaseX(1); - - } // end for x - - delete gt; +#pragma omp parallel default(none) \ + shared(mlog, dp, frac_dp, width, wrap_lon, t) \ + shared(use_climo, cmn, csd, vld_t, bad) \ + private(x, y, n_vld, n_thr, gp, v) + { + + // Build the grid template + GridTemplateFactory gtf; + GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); + +#pragma omp single + { + mlog << Debug(3) + << "Computing fractional coverage field using the " + << t.get_str() << " threshold and the " + << interpmthd_to_string(InterpMthd_Nbrhd) << "(" << gt->size() + << ") " << gt->getClassName() << " interpolation method.\n"; + + // Initialize the fractional coverage field + frac_dp = dp; + frac_dp.set_constant(bad_data_double); + } + + // Compute the fractional coverage meeting the threshold criteria +#pragma omp for schedule (static) + for(x=0; xgetFirstInGrid(x, y, dp.nx(), dp.ny()); + gp != NULL; + gp = gt->getNextInGrid()) { + if(is_bad_data(v = dp.get(gp->x, gp->y))) continue; + n_vld++; + if(t.check(v, + (use_climo ? cmn->get(gp->x, gp->y) : bad), + (use_climo ? csd->get(gp->x, gp->y) : bad))) n_thr++; + } + } + // Subtract off the bottom edge, shift up, and add the top. + else { + + // Subtract points from the the bottom edge + for(gp = gt->getFirstInBotEdge(); + gp != NULL; + gp = gt->getNextInBotEdge()) { + if(is_bad_data(v = dp.get(gp->x, gp->y))) continue; + n_vld--; + if(t.check(v, + (use_climo ? cmn->get(gp->x, gp->y) : bad), + (use_climo ? csd->get(gp->x, gp->y) : bad))) n_thr--; + } + + // Increment Y + gt->incBaseY(1); + + // Add points from the the top edge + for(gp = gt->getFirstInTopEdge(); + gp != NULL; + gp = gt->getNextInTopEdge()) { + if(is_bad_data(v = dp.get(gp->x, gp->y))) continue; + n_vld++; + if(t.check(v, + (use_climo ? cmn->get(gp->x, gp->y) : bad), + (use_climo ? csd->get(gp->x, gp->y) : bad))) n_thr++; + } + } + + // Check for enough valid data and compute fractional coverage + if((double)(n_vld)/gt->size() >= vld_t && n_vld != 0) { + frac_dp.set((double) n_thr/n_vld, x, y); + } + + } // end for y + + // Increment X + if(x < (dp.nx() - 1)) gt->incBaseX(1); + + } // end for x + + delete gt; + + } // End of omp parallel return; } diff --git a/met/src/basic/vx_util/handle_openmp.cc b/met/src/basic/vx_util/handle_openmp.cc new file mode 100644 index 0000000000..f23d09b4ca --- /dev/null +++ b/met/src/basic/vx_util/handle_openmp.cc @@ -0,0 +1,52 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// + +#include + +#ifdef _OPENMP + #include "omp.h" +#endif + +#include "vx_log.h" +#include "handle_openmp.h" + +/////////////////////////////////////////////////////////////////////////////// + +void init_openmp() { + +#ifdef _OPENMP + + // If OMP_NUM_THREADS was not set, use the OpenMP API to set the thread count + // to 1 thread only. + const char* env_omp_num_threads = std::getenv("OMP_NUM_THREADS"); + if (!env_omp_num_threads) { + mlog << Debug(2) << "OMP_NUM_THREADS is not set." + << " Defaulting to 1 thread." + << " Recommend setting OMP_NUM_THREADS for faster runtimes.\n"; + omp_set_num_threads(1); + } + +#pragma omp parallel +#pragma omp single + { + mlog << Debug(2) << "OpenMP running on " + << omp_get_num_threads() << " thread(s).\n"; + } + +#else /* _OPENMP */ + + mlog << Debug(2) << "OpenMP disabled.\n"; + +#endif /* _OPENMP */ + +} + +/////////////////////////////////////////////////////////////////////////////// + diff --git a/met/src/basic/vx_util/handle_openmp.h b/met/src/basic/vx_util/handle_openmp.h new file mode 100644 index 0000000000..e2ea2e6a38 --- /dev/null +++ b/met/src/basic/vx_util/handle_openmp.h @@ -0,0 +1,24 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** 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 __HANDLE_OPENMP_H___ +#define __HANDLE_OPENMP_H___ + +/////////////////////////////////////////////////////////////////////////////// + +void init_openmp(); + +/////////////////////////////////////////////////////////////////////////////// + +#endif /* __HANDLE_OPENMP_H__ */ + +/////////////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index fe5d160157..ab296a2528 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -92,6 +92,8 @@ using namespace std; #include "nc_obs_util.h" #include "nc_point_obs_in.h" +#include "handle_openmp.h" + //////////////////////////////////////////////////////////////////////// static void process_command_line (int, char **); @@ -171,6 +173,9 @@ static void set_compress(const StringArray &); int main(int argc, char *argv[]) { + // Set up OpenMP (if enabled) + init_openmp(); + // Set handler to be called for memory allocation error set_new_handler(oom); diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index f420e568c4..e7055ed596 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -127,6 +127,8 @@ using namespace std; #include #include +#include "handle_openmp.h" + #include "grid_stat.h" #include "vx_statistics.h" @@ -185,6 +187,9 @@ static bool read_data_plane(VarInfo* info, DataPlane& dp, Met2dDataFile* mtddf, int main(int argc, char *argv[]) { + // Set up OpenMP (if enabled) + init_openmp(); + // Set handler to be called for memory allocation error set_new_handler(oom); diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 1f634c38b2..786a56b390 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -45,6 +45,8 @@ using namespace std; #include "nc_obs_util.h" #include "nc_point_obs_in.h" +#include "handle_openmp.h" + //////////////////////////////////////////////////////////////////////// static void process_command_line(int, char **); @@ -81,6 +83,9 @@ static void set_ctrl_file (const StringArray &); int main(int argc, char *argv[]) { + // Set up OpenMP (if enabled) + init_openmp(); + // Set handler to be called for memory allocation error set_new_handler(oom); diff --git a/test/config/GridStatConfig_rtma b/test/config/GridStatConfig_rtma index 178a1269b1..2c3d3ba058 100644 --- a/test/config/GridStatConfig_rtma +++ b/test/config/GridStatConfig_rtma @@ -111,7 +111,7 @@ interp = { type = [ { method = NEAREST; width = 1; }, { method = UW_MEAN; width = 3; }, - { method = MIN; width = 1; }, + { method = MIN; width = 3; }, { method = MAX; width = 3; } ]; } diff --git a/test/xml/unit_grid_stat.xml b/test/xml/unit_grid_stat.xml index 1d562778f7..c31455c0ce 100644 --- a/test/xml/unit_grid_stat.xml +++ b/test/xml/unit_grid_stat.xml @@ -75,6 +75,32 @@ + + &MET_BIN;/grid_stat + + OMP_NUM_THREADS 2 + OUTPUT_PREFIX GRIB2_NAM_RTMA_NP2 + + \ + &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012_gRtma.grib2 \ + &DATA_DIR_OBS;/rtma/rtma_2012051712_F000.grib2 \ + &CONFIG_DIR;/GridStatConfig_rtma \ + -outdir &OUTPUT_DIR;/grid_stat -v 1 + + + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V.stat + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_fho.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_ctc.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_cts.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_cnt.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_sl1l2.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_nbrctc.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_nbrcts.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_nbrcnt.txt + &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_NP2_120000L_20120409_120000V_pairs.nc + + + &MET_BIN;/grid_stat From e96a2116e88cf58d152f95e5d9f1d9cdc587534d Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 13 Jan 2022 19:33:04 -0700 Subject: [PATCH 062/172] feature 1695 ensemble single file (ensemble_stat) (#2007) Co-authored-by: johnhg --- met/data/config/EnsembleStatConfig_default | 7 + met/docs/Users_Guide/ensemble-stat.rst | 46 +- met/docs/Users_Guide/gen-ens-prod.rst | 2 +- met/src/libcode/vx_data2d/var_info.cc | 123 ++++++ met/src/libcode/vx_data2d/var_info.h | 48 +++ .../vx_statistics/pair_data_ensemble.cc | 29 +- .../vx_statistics/pair_data_ensemble.h | 4 +- .../tools/core/ensemble_stat/ensemble_stat.cc | 392 +++++++++++------- .../tools/core/ensemble_stat/ensemble_stat.h | 10 +- .../ensemble_stat/ensemble_stat_conf_info.cc | 227 ++++++++-- .../ensemble_stat/ensemble_stat_conf_info.h | 15 +- .../tools/other/gen_ens_prod/gen_ens_prod.cc | 22 +- .../gen_ens_prod/gen_ens_prod_conf_info.cc | 99 +---- .../gen_ens_prod/gen_ens_prod_conf_info.h | 53 +-- scripts/environment/development.seneca | 1 - test/config/EnsembleStatConfig | 7 + test/config/EnsembleStatConfig_MASK_SID | 7 + test/config/EnsembleStatConfig_climo | 7 + test/config/EnsembleStatConfig_grid_weight | 7 + test/config/EnsembleStatConfig_one_cdf_bin | 7 + test/config/EnsembleStatConfig_python | 7 + test/config/EnsembleStatConfig_qty_inc_exc | 7 + .../EnsembleStatConfig_single_file_grib | 317 ++++++++++++++ test/config/EnsembleStatConfig_single_file_nc | 315 ++++++++++++++ test/xml/unit_ensemble_stat.xml | 82 ++++ 25 files changed, 1464 insertions(+), 377 deletions(-) create mode 100644 test/config/EnsembleStatConfig_single_file_grib create mode 100644 test/config/EnsembleStatConfig_single_file_nc diff --git a/met/data/config/EnsembleStatConfig_default b/met/data/config/EnsembleStatConfig_default index ea10765e17..339ab939be 100644 --- a/met/data/config/EnsembleStatConfig_default +++ b/met/data/config/EnsembleStatConfig_default @@ -62,6 +62,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index 266519da4f..5c6277b179 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -97,7 +97,7 @@ Optional arguments for ensemble_stat 6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** option specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** option from earlier versions of MET. -7. The **-ctrl file** option specifies an ensemble control member data file. The control member is included in the computation of the ensemble mean but excluded from the spread. The control file should not appear in the list of ensemble member files. +7. The **-ctrl file** option specifies an ensemble control member data file. The control member is included in the computation of the ensemble mean but excluded from the spread. The control file should not appear in the list of ensemble member files (unless processing a single file that contains all ensemble members). 8. To filter point observations by time, use **-obs_valid_beg time** in YYYYMMDD[_HH[MMSS]] format to set the beginning of the matching observation time window. @@ -188,6 +188,50 @@ For each **field** listed in the forecast field, give the name and vertical or a _______________________ +.. code-block:: none + + ens_member_ids = []; + control_id = ""; + +The **ens_member_ids** array is only used if reading a single file that contains all ensemble members. +It should contain a list of string identifiers that are substituted into the **ens** and/or **fcst** dictionary fields +to determine which data to read from the file. +The length of the array determines how many ensemble members will be processed for a given field. +Each value in the array will replace the text **MET_ENS_MEMBER_ID**. + +**NetCDF Example:** + +.. code-block:: none + + ens = { + field = [ + { + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,0,*,*)"; + } + ]; + } + +**GRIB Example:** + +.. code-block:: none + + ens = { + field = [ + { + name = "fcst"; + level = "L0"; + GRIB_ens = "MET_ENS_MEMBER_ID"; + } + ]; + } + +**control_id** is a string that is substituted in the same way as the **ens_member_ids** values +to read a control member. This value is only used when the **-ctrl** command line argument is +used. The value should not be found in the **ens_member_ids** array. + +_______________________ + .. code-block:: none nbrhd_prob = { diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index 459a9778f1..6d6e562ee0 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -167,7 +167,7 @@ Each value in the array will replace the text **MET_ENS_MEMBER_ID**. { name = "fcst"; level = "L0"; - GRIB_ens = "+MET_ENS_MEMBER_ID"; + GRIB_ens = "MET_ENS_MEMBER_ID"; } ]; } diff --git a/met/src/libcode/vx_data2d/var_info.cc b/met/src/libcode/vx_data2d/var_info.cc index 81e8f11252..009fdfe4c3 100644 --- a/met/src/libcode/vx_data2d/var_info.cc +++ b/met/src/libcode/vx_data2d/var_info.cc @@ -790,3 +790,126 @@ int parse_set_attr_flag(Dictionary &dict, const char *key) { } /////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +// +// Code for class EnsVarInfo +// +//////////////////////////////////////////////////////////////////////// + +EnsVarInfo::EnsVarInfo() { + ctrl_info = NULL; +} + +//////////////////////////////////////////////////////////////////////// + +EnsVarInfo::~EnsVarInfo() { + clear(); +} +/////////////////////////////////////////////////////////////////////////////// + +EnsVarInfo::EnsVarInfo(const EnsVarInfo &f) { + + clear(); + + assign(f); +} + +//////////////////////////////////////////////////////////////////////// + +void EnsVarInfo::clear() { + vector::const_iterator it; + for(it = inputs.begin(); it != inputs.end(); it++) { + if((*it).var_info) { delete (*it).var_info; } + } + + if(ctrl_info) { delete ctrl_info; } +} + +/////////////////////////////////////////////////////////////////////////////// + +void EnsVarInfo::assign(const EnsVarInfo &v) { + + // Copy + inputs = v.inputs; + ctrl_info = v.ctrl_info; + + nc_var_str = v.nc_var_str; + cat_ta = v.cat_ta; + raw_magic_str = v.raw_magic_str; + + return; +} + +//////////////////////////////////////////////////////////////////////// + +void EnsVarInfo::add_input(InputInfo input) { + inputs.push_back(input); +} + +//////////////////////////////////////////////////////////////////////// + +int EnsVarInfo::inputs_n() { + return inputs.size(); +} + +//////////////////////////////////////////////////////////////////////// + +void EnsVarInfo::set_ctrl(VarInfo * ctrl) { + ctrl_info = ctrl; +} + +//////////////////////////////////////////////////////////////////////// + +VarInfo * EnsVarInfo::get_ctrl(int index) { + if(ctrl_info) { + return ctrl_info; + } + return inputs[index].var_info; +} + +//////////////////////////////////////////////////////////////////////// + +VarInfo * EnsVarInfo::get_var_info(int index) { + if(inputs[index].var_info) { + return inputs[index].var_info; + } + return inputs[0].var_info; +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString EnsVarInfo::get_file(int index) { + int file_index = inputs[index].file_index; + return (*inputs[index].file_list)[file_index]; +} + +//////////////////////////////////////////////////////////////////////// + +int EnsVarInfo::get_file_index(int index) { + return inputs[index].file_index; +} + +//////////////////////////////////////////////////////////////////////// + +ConcatString raw_magic_str(Dictionary i_edict, GrdFileType file_type) { + ConcatString magic_str; + + ConcatString name = i_edict.lookup_string("name"); + ConcatString level = i_edict.lookup_string("level", false); + + if(level.empty()) { + return name; + } + + if(level[0] != '(') { + magic_str << name << "/" << level; + } else { + magic_str << name << level; + } + + return magic_str; + +} + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_data2d/var_info.h b/met/src/libcode/vx_data2d/var_info.h index 2d80138878..2bd1f42973 100644 --- a/met/src/libcode/vx_data2d/var_info.h +++ b/met/src/libcode/vx_data2d/var_info.h @@ -251,6 +251,54 @@ inline unixtime VarInfo::valid_attr() const { return(SetAttrValid); } inline int VarInfo::lead_attr() const { return(SetAttrLead); } inline int VarInfo::accum_attr() const { return(SetAttrAccum); } +//////////////////////////////////////////////////////////////////////// + +// +// Struct to store input file and field information +// + +struct InputInfo { + VarInfo * var_info; // Variable information to read + int file_index; // Index in file_list of file to read + StringArray * file_list; // Array of files (unallocated) +}; + +//////////////////////////////////////////////////////////////////////// + +// +// Struct to store ensemble information +// +class EnsVarInfo { + +private: + vector inputs; // Vector of InputInfo + VarInfo * ctrl_info; // Field info for control member +public: + EnsVarInfo(); + ~EnsVarInfo(); + EnsVarInfo(const EnsVarInfo &); + + void clear(); + void assign(const EnsVarInfo &); + + void add_input(InputInfo); + int inputs_n(); + + void set_ctrl(VarInfo *); + VarInfo * get_ctrl(int); + + // Get VarInfo from first InputInfo if requested VarInfo is NULL + VarInfo * get_var_info(int index=0); + ConcatString get_file(int index=0); + int get_file_index(int index=0); + + ConcatString nc_var_str; // Ensemble variable name strings + ThreshArray cat_ta; // Ensemble categorical thresholds + ConcatString raw_magic_str; // Magic string w/o var substitution +}; + +ConcatString raw_magic_str(Dictionary i_edict, GrdFileType file_type); + /////////////////////////////////////////////////////////////////////////////// #endif // __VAR_INFO_H__ diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 6f6471b63a..2af587f2ea 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -891,7 +891,7 @@ VxPairDataEnsemble & VxPairDataEnsemble::operator=(const VxPairDataEnsemble &vx_ void VxPairDataEnsemble::init_from_scratch() { - fcst_info = (VarInfo *) 0; + fcst_info = (EnsVarInfo *) 0; climo_info = (VarInfo *) 0; obs_info = (VarInfo *) 0; pd = (PairDataEnsemble ***) 0; @@ -910,7 +910,7 @@ void VxPairDataEnsemble::init_from_scratch() { void VxPairDataEnsemble::clear() { int i, j, k; - if(fcst_info) { delete fcst_info; fcst_info = (VarInfo *) 0; } + if(fcst_info) { delete fcst_info; fcst_info = (EnsVarInfo *) 0; } if(climo_info) { delete climo_info; climo_info = (VarInfo *) 0; } if(obs_info) { delete obs_info; obs_info = (VarInfo *) 0; } @@ -993,15 +993,14 @@ void VxPairDataEnsemble::assign(const VxPairDataEnsemble &vx_pd) { //////////////////////////////////////////////////////////////////////// -void VxPairDataEnsemble::set_fcst_info(VarInfo *info) { +void VxPairDataEnsemble::set_fcst_info(EnsVarInfo *info) { VarInfoFactory f; // Deallocate, if necessary - if(fcst_info) { delete fcst_info; fcst_info = (VarInfo *) 0; } + if(fcst_info) { delete fcst_info; fcst_info = (EnsVarInfo *) 0; } // Perform a deep copy - fcst_info = f.new_var_info(info->file_type()); - *fcst_info = *info; + fcst_info = new EnsVarInfo(*info); return; } @@ -1458,7 +1457,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, // below the observation point. else { // Interpolate using the observation pressure level or height - to_lvl = (fcst_info->level().type() == LevelType_Pres ? + to_lvl = (fcst_info->get_var_info()->level().type() == LevelType_Pres ? obs_lvl : obs_hgt); find_vert_lvl(climo_mn_dpa, to_lvl, cmn_lvl_blw, cmn_lvl_abv); } @@ -1472,7 +1471,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, // levels above and below the observation point. else { // Interpolate using the observation pressure level or height - to_lvl = (fcst_info->level().type() == LevelType_Pres ? + to_lvl = (fcst_info->get_var_info()->level().type() == LevelType_Pres ? obs_lvl : obs_hgt); find_vert_lvl(climo_sd_dpa, to_lvl, csd_lvl_blw, csd_lvl_abv); } @@ -1486,7 +1485,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, } // Set flag for specific humidity - bool spfh_flag = fcst_info->is_specific_humidity() && + bool spfh_flag = fcst_info->get_var_info()->is_specific_humidity() && obs_info->is_specific_humidity(); // Store pointer to ObsErrorEntry @@ -1561,7 +1560,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, // Compute the interpolated climatology values using the // observation pressure level or height - to_lvl = (fcst_info->level().type() == LevelType_Pres ? + to_lvl = (fcst_info->get_var_info()->level().type() == LevelType_Pres ? obs_lvl : obs_hgt); // Compute the interpolated climatology mean @@ -1570,7 +1569,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, - fcst_info->level().type(), + fcst_info->get_var_info()->level().type(), to_lvl, cmn_lvl_blw, cmn_lvl_abv); // Check for bad data @@ -1597,7 +1596,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, - fcst_info->level().type(), + fcst_info->get_var_info()->level().type(), to_lvl, csd_lvl_blw, csd_lvl_abv); // Check for bad data @@ -1630,7 +1629,7 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { double to_lvl, fcst_v; // Set flag for specific humidity - bool spfh_flag = fcst_info->is_specific_humidity() && + bool spfh_flag = fcst_info->get_var_info()->is_specific_humidity() && obs_info->is_specific_humidity(); // Loop through all the PairDataEnsemble objects and interpolate @@ -1642,7 +1641,7 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { for(l=0; llevel().type() == LevelType_Pres ? + to_lvl = (fcst_info->get_var_info()->level().type() == LevelType_Pres ? pd[i][j][k].lvl_na[l] : pd[i][j][k].elv_na[l]); // For a single forecast field @@ -1668,7 +1667,7 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, - fcst_info->level().type(), + fcst_info->get_var_info()->level().type(), to_lvl, f_lvl_blw, f_lvl_abv); // Store the ensemble mean diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index bee6b11838..67e0319d27 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -174,7 +174,7 @@ class VxPairDataEnsemble { // ////////////////////////////////////////////////////////////////// - VarInfo *fcst_info; // Forecast field, allocated by VarInfoFactory + EnsVarInfo *fcst_info; // Forecast field, allocated by EnsVarInfo VarInfo *climo_info; // Climatology field, allocated by VarInfoFactory VarInfo *obs_info; // Observation field, allocated by VarInfoFactory @@ -233,7 +233,7 @@ class VxPairDataEnsemble { void clear(); - void set_fcst_info(VarInfo *); + void set_fcst_info(EnsVarInfo *); void set_climo_info(VarInfo *); void set_obs_info(VarInfo *); diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index ab296a2528..0299932cf5 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -128,7 +128,7 @@ static void do_rps (const EnsembleStatVxOpt &, const PairDataEnsemble *); static void clear_counts(); -static void track_counts(int, const DataPlane &, bool); +static void track_counts(EnsVarInfo *, const DataPlane &, bool); static ConcatString get_ens_mn_var_name(int); @@ -138,12 +138,12 @@ static void setup_table (AsciiTable &); static void build_outfile_name(unixtime, const char *, ConcatString &); -static void write_ens_nc(int, DataPlane &); -static void write_ens_var_float(int, float *, const DataPlane &, +static void write_ens_nc(EnsVarInfo *, int, DataPlane &); +static void write_ens_var_float(EnsVarInfo *, float *, const DataPlane &, const char *, const char *); -static void write_ens_var_int(int, int *, const DataPlane &, +static void write_ens_var_int(EnsVarInfo *, int *, const DataPlane &, const char *, const char *); -static void write_ens_data_plane(int, const DataPlane &, const DataPlane &, +static void write_ens_data_plane(EnsVarInfo *, const DataPlane &, const DataPlane &, const char *, const char *); static void write_orank_nc(PairDataEnsemble &, DataPlane &, int, int, int); @@ -256,7 +256,7 @@ void process_command_line(int argc, char **argv) { // if(is_integer(cline[0].c_str()) == 0) { ens_file_list = parse_ascii_file_list(cline[0].c_str()); - n_ens = ens_file_list.n(); + n_ens_files = ens_file_list.n(); } else { usage(); @@ -270,21 +270,21 @@ void process_command_line(int argc, char **argv) { // if(is_integer(cline[0].c_str()) == 1) { - n_ens = atoi(cline[0].c_str()); + n_ens_files = atoi(cline[0].c_str()); - if(n_ens <= 0) { + if(n_ens_files <= 0) { mlog << Error << "\nprocess_command_line() -> " << "the number of ensemble member files must be >= 1 (" - << n_ens << ")\n\n"; + << n_ens_files << ")\n\n"; exit(1); } - if((cline.n() - 2) == n_ens) { + if((cline.n() - 2) == n_ens_files) { // // Add each of the ensemble members to the list of files. // - for(i=1; i<=n_ens; i++) ens_file_list.add(cline[i]); + for(i=1; i<=n_ens_files; i++) ens_file_list.add(cline[i]); } else { usage(); @@ -293,16 +293,19 @@ void process_command_line(int argc, char **argv) { } // Check for at least one valid input ensemble file - if(ens_file_list.n() == 0) { + if(n_ens_files == 0) { mlog << Error << "\nprocess_command_line() -> " << "no valid input ensemble member files specified!\n\n"; exit(1); } + // Copy ensemble file list to forecast file list + fcst_file_list = ens_file_list; + // Prepend the control member, if specified if(ctrl_file.nonempty()) { - if(ens_file_list.has(ctrl_file)) { + if(ens_file_list.has(ctrl_file) && n_ens_files != 1) { mlog << Error << "\nprocess_command_line() -> " << "the ensemble control file should not appear in the list " << "of ensemble member files:\n" << ctrl_file << "\n\n"; @@ -310,8 +313,9 @@ void process_command_line(int argc, char **argv) { } ctrl_index = 0; - ens_file_list.insert(ctrl_index, ctrl_file.c_str()); - n_ens++; + + // Add control file to beginning of forecast file list + fcst_file_list.insert(ctrl_index, ctrl_file.c_str()); } // Check that the end_ut >= beg_ut @@ -387,7 +391,7 @@ void process_command_line(int argc, char **argv) { } // Process the configuration - conf_info.process_config(etype, otype, grid_obs_flag, point_obs_flag, use_var_id); + conf_info.process_config(etype, otype, grid_obs_flag, point_obs_flag, use_var_id, &ens_file_list, &fcst_file_list, ctrl_file.nonempty()); // Set the model name shc.set_model(conf_info.model.c_str()); @@ -402,12 +406,15 @@ void process_command_line(int argc, char **argv) { // List the input ensemble files mlog << Debug(1) << "Ensemble Files[" - << ens_file_list.n() << "]:\n"; - for(i=0; i 0) { mlog << Debug(1) << "Gridded Observation Files[" @@ -427,7 +434,7 @@ void process_command_line(int argc, char **argv) { } // Check for missing non-python ensemble files - for(i=0; i " + << "can't open input forecast file: " + << fcst_file_list[i] << "\n\n"; + fcst_file_vld.add(0); + } + else { + fcst_file_vld.add(1); + } + } + // Set flag to indicate whether verification is to be performed if((point_obs_flag || grid_obs_flag) && (conf_info.get_n_vx() > 0) && @@ -489,11 +511,17 @@ void process_command_line(int argc, char **argv) { if(!conf_info.nc_info.do_mean) { mlog << Warning << "\nprocess_command_line() -> " << "enabling NetCDF ensemble mean computation to be used " - << "in verificaiton.\n\n"; + << "in verification.\n\n"; conf_info.nc_info.do_mean = true; } } + if(conf_info.control_id.nonempty() && ctrl_file.empty()) { + mlog << Warning << "\nprocess_command_line() -> " + << "control_id is set in the config file but " + << "control file is not provided with -ctrl argument\n\n"; + } + // Deallocate memory for data files if(ens_mtddf) { delete ens_mtddf; ens_mtddf = (Met2dDataFile *) 0; } if(obs_mtddf) { delete obs_mtddf; obs_mtddf = (Met2dDataFile *) 0; } @@ -508,11 +536,11 @@ void process_grid(const Grid &fcst_grid) { // Parse regridding logic RegridInfo ri; - if(conf_info.get_n_ens_var() > 0) { - ri = conf_info.ens_info[0]->regrid(); + if(conf_info.ens_input.size() > 0) { + ri = conf_info.ens_input[0]->get_var_info()->regrid(); } else if(conf_info.get_n_vx() > 0) { - ri = conf_info.vx_opt[0].vx_pd.fcst_info->regrid(); + ri = conf_info.vx_opt[0].vx_pd.fcst_info->get_var_info()->regrid(); } else { mlog << Error << "\nprocess_grid() -> " @@ -572,30 +600,40 @@ void process_grid(const Grid &fcst_grid) { //////////////////////////////////////////////////////////////////////// void process_n_vld() { - int i, j, n_vld; + int i_var, i_ens, j, n_vld, n_ens_inputs; DataPlane dp; DataPlaneArray dpa; + VarInfo * var_info; + ConcatString ens_file, fcst_file; + vector::const_iterator var_it; // Initialize n_ens_vld.clear(); n_vx_vld.clear(); // Loop through the ensemble fields to be processed - for(i=0; iinputs_n(); + + for(i_var=0; var_it != conf_info.ens_input.end(); var_it++, i_var++) { - // Loop through the ensemble files - for(j=0, n_vld=0; jget_file(i_ens); + var_info = (*var_it)->get_var_info(i_ens); // Check for valid file - if(!ens_file_vld[j]) continue; + if(!ens_file_vld[(*var_it)->get_file_index(i_ens)]) continue; // Check for valid data - if(!get_data_plane(ens_file_list[j].c_str(), etype, - conf_info.ens_info[i], dp, false)) { + if(!get_data_plane(ens_file.c_str(), etype, + var_info, dp, false)) { mlog << Warning << "\nprocess_n_vld() -> " << "ensemble field \"" - << conf_info.ens_info[i]->magic_str() - << "\" not found in file \"" << ens_file_list[j] + << var_info->magic_str() + << "\" not found in file \"" << ens_file << "\"\n\n"; } else { @@ -603,46 +641,56 @@ void process_n_vld() { // Increment the valid counter n_vld++; } - } // end for j + } // end for i_ens // Check for enough valid data - if((double) n_vld/n_ens < conf_info.vld_ens_thresh) { + if((double) n_vld/n_ens_inputs < conf_info.vld_ens_thresh) { mlog << Error << "\nprocess_n_vld() -> " - << n_ens - n_vld << " missing ensemble fields exceeds the " - << "maximum allowable specified by \"ens.ens_thresh\" " - << "in the configuration file.\n\n"; + << n_vld << " of " << n_ens_inputs + << " (" << (double)n_vld/n_ens_inputs << ")" + << " fields found for \"" << (*var_it)->get_var_info()->magic_str() + << "\" does not meet the threshold specified by \"" + << conf_key_ens_ens_thresh << "\" (" << conf_info.vld_ens_thresh + << ") in the configuration file.\n\n"; exit(1); } // Store the valid data count n_ens_vld.add(n_vld); - } // end for i + } // end for i_var // Loop through the verification fields to be processed - for(i=0; iinputs_n(); + + // Loop through the forecast inputs + for(i_ens=n_vld=0; i_ens < n_ens_inputs; i_ens++) { - // Loop through the ensemble files - for(j=0, n_vld=0; jget_file(i_ens); + var_info = conf_info.vx_opt[i_var].vx_pd.fcst_info->get_var_info(i_ens); + j = conf_info.vx_opt[i_var].vx_pd.fcst_info->get_file_index(i_ens); // Check for valid file - if(!ens_file_vld[j]) continue; + if(!fcst_file_vld[j]) continue; // Check for valid data fields. // Call data_plane_array to handle multiple levels. - if(!get_data_plane_array(ens_file_list[j].c_str(), etype, - conf_info.vx_opt[i].vx_pd.fcst_info, + if(!get_data_plane_array(fcst_file.c_str(), etype, + var_info, dpa, false)) { mlog << Warning << "\nprocess_n_vld() -> " << "no data found for forecast field \"" - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() - << "\" in file \"" << ens_file_list[j] + << var_info->magic_str() + << "\" in file \"" << fcst_file << "\"\n\n"; } else { // Store the lead times for the first verification field - if(i==0) ens_lead_na.add(dpa[0].lead()); + if(i_var==0) ens_lead_na.add(dpa[0].lead()); // Increment the valid counter n_vld++; @@ -650,11 +698,15 @@ void process_n_vld() { } // end for j // Check for enough valid data - if((double) n_vld/n_ens < conf_info.vld_ens_thresh) { + if((double) n_vld/n_ens_inputs < conf_info.vld_ens_thresh) { mlog << Error << "\nprocess_n_vld() -> " - << n_ens - n_vld << " missing forecast fields exceeds the " - << "maximum allowable specified by \"ens.ens_thresh\" " - << "in the configuration file.\n\n"; + << n_vld << " of " << n_ens_inputs + << " (" << (double)n_vld/n_ens_inputs << ")" + << " forecast fields found for \"" + << conf_info.vx_opt[i_var].vx_pd.fcst_info->get_var_info()->magic_str() + << "\" does not meet the threshold specified by \"" + << conf_key_ens_ens_thresh << "\" (" << conf_info.vld_ens_thresh + << ") in the configuration file.\n\n"; exit(1); } @@ -778,50 +830,44 @@ bool get_data_plane_array(const char *infile, GrdFileType ftype, //////////////////////////////////////////////////////////////////////// void process_ensemble() { - int i, j; + int i_var, i_ens, j; bool reset; - DataPlane ens_dp; + DataPlane ens_dp, ctrl_dp; unixtime max_init_ut = bad_data_ll; + VarInfo * var_info; + VarInfo * ctrl_info; + ConcatString ens_file; + + vector::const_iterator var_it = conf_info.ens_input.begin(); // Loop through each of the ensemble fields to be processed - for(i=0; iget_var_info(); mlog << Debug(2) << "\n" << sep_str << "\n\n" << "Processing ensemble field: " - << conf_info.ens_info[i]->magic_str() << "\n"; + << (*var_it)->raw_magic_str << "\n"; + + // Loop through each of the input forecast files/variables + for(i_ens=0,reset=true; i_ens < (*var_it)->inputs_n(); i_ens++) { - // Loop through each of the input forecast files - for(j=0, reset=true; jget_file_index(i_ens); // Skip bad data files - if(!ens_file_vld[j]) { + if(!ens_file_vld[j]) { continue; } - // Error out if the control member file is not valid - if(j==ctrl_index) { - mlog << Error << "\nprocess_ensemble() -> " - << "the control member file is not valid.\n\n"; - exit(1); - } + // get file and VarInfo to process + ens_file = (*var_it)->get_file(i_ens); + var_info = (*var_it)->get_var_info(i_ens); - // Otherwise, continue - continue; - } + mlog << Debug(3) << "\n" + << "Reading field: " + << var_info->magic_str() << "\n"; // Read the current field - if(!get_data_plane(ens_file_list[j].c_str(), etype, - conf_info.ens_info[i], ens_dp, true)) { - - // Error out if the control member data cannot be read - if(j==ctrl_index) { - mlog << Error << "\nprocess_ensemble() -> " - << "can't find \"" << conf_info.ens_info[i]->magic_str() - << "\" data in the control member file.\n\n"; - exit(1); - } - - // Otherwise, continue - continue; - } + if(!get_data_plane(ens_file.c_str(), etype, + var_info, ens_dp, true)) { continue; } // Create a NetCDF file to store the ensemble output if(nc_out == (NcFile *) 0) { @@ -832,26 +878,48 @@ void process_ensemble() { if(reset) { clear_counts(); reset = false; + + // Read ensemble control member data, if provided + if(ctrl_file.nonempty()) { + ctrl_info = (*var_it)->get_ctrl(i_ens); + + mlog << Debug(3) << "\n" + << "Reading control field: " + << ctrl_info->magic_str() << "\n"; + + // Error out if missing + if (!get_data_plane(ctrl_file.c_str(), etype, + ctrl_info, ctrl_dp, true)) { + mlog << Error << "\nprocess_ensemble() -> " + << "control member ensemble field \"" + << ctrl_info->magic_str() + << "\" not found in file \"" << ctrl_file << "\"\n\n"; + exit(1); + } + + // Apply current data to the running sums and counts + track_counts(*var_it, ctrl_dp, true); + } } // Apply current data to the running sums and counts - track_counts(i, ens_dp, j == ctrl_index); + track_counts(*var_it, ens_dp, false); // Keep track of the maximum initialization time if(is_bad_data(max_init_ut) || ens_dp.init() > max_init_ut) { max_init_ut = ens_dp.init(); } - } // end for j + } // end for i_ens // Write out the ensemble information to a NetCDF file ens_dp.set_init(max_init_ut); - write_ens_nc(i, ens_dp); + write_ens_nc(*var_it, i_var, ens_dp); // Store the ensemble mean output file ens_mean_file = out_nc_file_list[out_nc_file_list.n() - 1]; - } // end for i + } // end for var_it // Close the output NetCDF file if(nc_out) { @@ -896,7 +964,7 @@ void process_vx() { //////////////////////////////////////////////////////////////////////// void process_point_vx() { - int i, n_miss; + int i, i_file, n_miss; unixtime beg_ut, end_ut; // Set observation time window for each verification task @@ -934,11 +1002,13 @@ void process_point_vx() { conf_info.vx_opt[i].vx_pd.print_obs_summary(); } - // Process each ensemble file - for(i=0, n_miss=0; iinputs_n(); i++) { + + i_file = conf_info.vx_opt[0].vx_pd.fcst_info->get_file_index(i); // If the current forecast file is valid, process it - if(!ens_file_vld[i]) { + if(!fcst_file_vld[i_file]) { n_miss++; continue; } @@ -1120,8 +1190,11 @@ int process_point_ens(int i_ens, int &n_miss) { bool is_ens_mean = (-1 == i_ens); const char *file_type = (is_ens_mean ? "mean" : "ensemble"); + // get file index from first verification for logging + int i_file = conf_info.vx_opt[0].vx_pd.fcst_info->get_file_index(i_ens); + // Determine the correct file to process - if(!is_ens_mean) ens_file = ConcatString(ens_file_list[i_ens]); + if(!is_ens_mean) ens_file = ConcatString(fcst_file_list[i_file]); else ens_file = (ens_mean_user.empty() ? ens_mean_file : ens_mean_user); @@ -1142,9 +1215,12 @@ int process_point_ens(int i_ens, int &n_miss) { info = &ens_mean_info; } else { - info = conf_info.vx_opt[i].vx_pd.fcst_info; + info = conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info(i_ens); } + // if not processing mean, get file based on current vx and ensemble index + if(!is_ens_mean) ens_file = conf_info.vx_opt[i].vx_pd.fcst_info->get_file(i_ens); + // Read the gridded data from the input forecast file if(!get_data_plane_array(ens_file.c_str(), info->file_type(), info, fcst_dpa, true)) { @@ -1205,13 +1281,13 @@ void process_point_scores() { shc.set_desc(conf_info.vx_opt[i].vx_pd.desc.c_str()); // Store the forecast variable name - shc.set_fcst_var(conf_info.vx_opt[i].vx_pd.fcst_info->name_attr()); + shc.set_fcst_var(conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->name_attr()); // Store the forecast variable units - shc.set_fcst_units(conf_info.vx_opt[i].vx_pd.fcst_info->units_attr()); + shc.set_fcst_units(conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->units_attr()); // Set the forecast level name - shc.set_fcst_lev(conf_info.vx_opt[i].vx_pd.fcst_info->level_attr().c_str()); + shc.set_fcst_lev(conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->level_attr().c_str()); // Store the observation variable name shc.set_obs_var(conf_info.vx_opt[i].vx_pd.obs_info->name_attr()); @@ -1255,7 +1331,7 @@ void process_point_scores() { mlog << Debug(2) << "Processing point verification " - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() + << conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->magic_str() << " versus " << conf_info.vx_opt[i].vx_pd.obs_info->magic_str() << ", for observation type " << pd_ptr->msg_typ @@ -1393,7 +1469,7 @@ void process_point_scores() { //////////////////////////////////////////////////////////////////////// void process_grid_vx() { - int i, j, k, l, m, n_miss; + int i, j, k, l, m, n_miss, i_file; bool found; MaskPlane mask_mp; DataPlane *fcst_dp = (DataPlane *) 0; @@ -1402,6 +1478,8 @@ void process_grid_vx() { DataPlane emn_dp, cmn_dp, csd_dp; PairDataEnsemble pd_all, pd; ObsErrorEntry *oerr_ptr = (ObsErrorEntry *) 0; + VarInfo * var_info; + ConcatString fcst_file; mlog << Debug(2) << "\n" << sep_str << "\n\n"; @@ -1409,8 +1487,9 @@ void process_grid_vx() { shc.set_obtype(conf_info.obtype.c_str()); // Allocate space to store the forecast fields - fcst_dp = new DataPlane [n_ens]; - fraw_dp = new DataPlane [n_ens]; + int num_dp = conf_info.vx_opt[0].vx_pd.fcst_info->inputs_n(); + fcst_dp = new DataPlane [num_dp]; + fraw_dp = new DataPlane [num_dp]; // Loop through each of the fields to be verified for(i=0; iname_attr()); + shc.set_fcst_var(conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->name_attr()); // Store the forecast variable units - shc.set_fcst_units(conf_info.vx_opt[i].vx_pd.fcst_info->units_attr()); + shc.set_fcst_units(conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->units_attr()); // Set the forecast level name - shc.set_fcst_lev(conf_info.vx_opt[i].vx_pd.fcst_info->level_attr().c_str()); + shc.set_fcst_lev(conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->level_attr().c_str()); // Set the ObsErrorEntry pointer if(conf_info.vx_opt[i].obs_error.flag) { @@ -1486,16 +1565,20 @@ void process_grid_vx() { } } - // Loop through each of the input ensemble files - for(j=0, n_miss=0; jinputs_n(); j++) { // Initialize fcst_dp[j].clear(); + i_file = conf_info.vx_opt[i].vx_pd.fcst_info->get_file_index(j); + var_info = conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info(j); + fcst_file = conf_info.vx_opt[i].vx_pd.fcst_info->get_file(j); + // If the current ensemble file is valid, read the field - if(ens_file_vld[j]) { - found = get_data_plane(ens_file_list[j].c_str(), etype, - conf_info.vx_opt[i].vx_pd.fcst_info, + if(fcst_file_vld[i_file]) { + found = get_data_plane(fcst_file.c_str(), etype, + var_info, fcst_dp[j], true); } else { @@ -1521,7 +1604,7 @@ void process_grid_vx() { << "Found " << (cmn_dp.nx() == 0 ? 0 : 1) << " climatology mean field(s) and " << (csd_dp.nx() == 0 ? 0 : 1) << " climatology standard deviation field(s) for forecast " - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() << ".\n"; + << conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->magic_str() << ".\n"; // If requested in the config file, create a NetCDF file to store // the verification matched pairs @@ -1588,7 +1671,7 @@ void process_grid_vx() { info = &ens_mean_info; } else { - info = conf_info.vx_opt[i].vx_pd.fcst_info; + info = conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info(); } // Read the gridded data from the mean file @@ -1648,7 +1731,7 @@ void process_grid_vx() { // Store a copy of the unperturbed observation field oraw_dp = obs_dp; - // Apply observation error bias correciton, if requested + // Apply observation error bias correction, if requested if(conf_info.vx_opt[i].obs_error.flag) { mlog << Debug(3) << "Applying observation error bias correction to " @@ -1659,8 +1742,8 @@ void process_grid_vx() { conf_info.obtype.c_str()); } - // Looop through the ensemble members - for(k=0; kinputs_n(); k++) { // Smooth the forecast field, if requested if(field == FieldType_Fcst || field == FieldType_Both) { @@ -1711,7 +1794,7 @@ void process_grid_vx() { mlog << Debug(2) << "Processing gridded verification " - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() + << conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info()->magic_str() << " versus " << conf_info.vx_opt[i].vx_pd.obs_info->magic_str() << ", for observation type " << shc.get_obtype() @@ -1916,7 +1999,7 @@ void process_grid_scores(int i_vx, y = nint(pd.y_na[i]); // Loop through each of the ensemble members - for(j=0, n_miss=0; jinputs_n(); j++) { // Skip missing data if(fcst_dp[j].nx() == 0 || fcst_dp[j].ny() == 0) { @@ -1932,6 +2015,7 @@ void process_grid_scores(int i_vx, if(j != ctrl_index) pd.add_ens_var_sums(i, fraw_dp[j](x, y)); } } // end for j + } // end for i return; @@ -2027,13 +2111,13 @@ void clear_counts() { //////////////////////////////////////////////////////////////////////// -void track_counts(int i_vx, const DataPlane &ens_dp, bool is_ctrl) { +void track_counts(EnsVarInfo * ens_info, const DataPlane &ens_dp, bool is_ctrl) { int i, j, k; double v; // Ensemble thresholds - const int n_thr = conf_info.ens_ta[i_vx].n(); - SingleThresh *thr_buf = conf_info.ens_ta[i_vx].buf(); + const int n_thr = ens_info->cat_ta.n(); + SingleThresh *thr_buf = ens_info->cat_ta.buf(); // Increment counts for each grid point for(i=0; iname_attr() << "_" - << conf_info.vx_opt[i_vx].vx_pd.fcst_info->level_attr() + cs << conf_info.vx_opt[i_vx].vx_pd.fcst_info->get_var_info()->name_attr() << "_" + << conf_info.vx_opt[i_vx].vx_pd.fcst_info->get_var_info()->level_attr() << "_ENS_MEAN"; cs.replace(",", "_", false); cs.replace("*", "all", false); @@ -2355,7 +2439,7 @@ void build_outfile_name(unixtime ut, const char *suffix, ConcatString &str) { //////////////////////////////////////////////////////////////////////// -void write_ens_nc(int i_var, DataPlane &ens_dp) { +void write_ens_nc(EnsVarInfo * ens_info, int i_var, DataPlane &ens_dp) { int i, j, k, l; double t, v; char type_str[max_str_len]; @@ -2408,56 +2492,56 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { // Add the ensemble mean, if requested if(conf_info.nc_info.do_mean) { - write_ens_var_float(i_var, ens_mean, ens_dp, + write_ens_var_float(ens_info, ens_mean, ens_dp, "ENS_MEAN", "Ensemble Mean"); } // Add the ensemble standard deviation, if requested if(conf_info.nc_info.do_stdev) { - write_ens_var_float(i_var, ens_stdev, ens_dp, + write_ens_var_float(ens_info, ens_stdev, ens_dp, "ENS_STDEV", "Ensemble Standard Deviation"); } // Add the ensemble mean minus one standard deviation, if requested if(conf_info.nc_info.do_minus) { - write_ens_var_float(i_var, ens_minus, ens_dp, + write_ens_var_float(ens_info, ens_minus, ens_dp, "ENS_MINUS", "Ensemble Mean Minus 1 Standard Deviation"); } // Add the ensemble mean plus one standard deviation, if requested if(conf_info.nc_info.do_plus) { - write_ens_var_float(i_var, ens_plus, ens_dp, + write_ens_var_float(ens_info, ens_plus, ens_dp, "ENS_PLUS", "Ensemble Mean Plus 1 Standard Deviation"); } // Add the ensemble minimum value, if requested if(conf_info.nc_info.do_min) { - write_ens_var_float(i_var, ens_min, ens_dp, + write_ens_var_float(ens_info, ens_min, ens_dp, "ENS_MIN", "Ensemble Minimum"); } // Add the ensemble maximum value, if requested if(conf_info.nc_info.do_max) { - write_ens_var_float(i_var, ens_max, ens_dp, + write_ens_var_float(ens_info, ens_max, ens_dp, "ENS_MAX", "Ensemble Maximum"); } // Add the ensemble range, if requested if(conf_info.nc_info.do_range) { - write_ens_var_float(i_var, ens_range, ens_dp, + write_ens_var_float(ens_info, ens_range, ens_dp, "ENS_RANGE", "Ensemble Range"); } // Add the ensemble valid data count, if requested if(conf_info.nc_info.do_vld) { - write_ens_var_int(i_var, ens_vld, ens_dp, + write_ens_var_int(ens_info, ens_vld, ens_dp, "ENS_VLD", "Ensemble Valid Data Count"); } @@ -2469,7 +2553,7 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { prob_dp.set_size(grid.nx(), grid.ny()); // Loop through each threshold - for(i=0; icat_ta.n(); i++) { // Initialize prob_dp.erase(); @@ -2484,8 +2568,8 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { // Write ensemble relative frequency if(conf_info.nc_info.do_freq) { snprintf(type_str, sizeof(type_str), "ENS_FREQ_%s", - conf_info.ens_ta[i_var][i].get_abbr_str().contents().c_str()); - write_ens_data_plane(i_var, prob_dp, ens_dp, type_str, + ens_info->cat_ta[i].get_abbr_str().contents().c_str()); + write_ens_data_plane(ens_info, prob_dp, ens_dp, type_str, "Ensemble Relative Frequency"); } @@ -2503,10 +2587,10 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { // Write neighborhood ensemble probability snprintf(type_str, sizeof(type_str), "ENS_NEP_%s_%s%i", - conf_info.ens_ta[i_var][i].get_abbr_str().contents().c_str(), + ens_info->cat_ta[i].get_abbr_str().contents().c_str(), interpmthd_to_string(InterpMthd_Nbrhd).c_str(), conf_info.nbrhd_prob.width[j]*conf_info.nbrhd_prob.width[j]); - write_ens_data_plane(i_var, nbrhd_dp, ens_dp, type_str, + write_ens_data_plane(ens_info, nbrhd_dp, ens_dp, type_str, "Neighborhood Ensemble Probability"); } // end for j } // end if do_nep @@ -2519,7 +2603,7 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { prob_dp.set_size(grid.nx(), grid.ny()); // Loop through each threshold - for(i=0; icat_ta.n(); i++) { // Loop through each neigbhorhood size for(j=0; jcat_ta[i].get_abbr_str().contents().c_str(), interpmthd_to_string(InterpMthd_Nbrhd).c_str(), conf_info.nbrhd_prob.width[j]*conf_info.nbrhd_prob.width[j], conf_info.nmep_smooth.method[k].c_str(), conf_info.nmep_smooth.width[k]*conf_info.nmep_smooth.width[k]); - write_ens_data_plane(i_var, nbrhd_dp, ens_dp, type_str, + write_ens_data_plane(ens_info, nbrhd_dp, ens_dp, type_str, "Neighborhood Maximum Ensemble Probability"); } // end for k } // end for j @@ -2573,20 +2657,20 @@ void write_ens_nc(int i_var, DataPlane &ens_dp) { //////////////////////////////////////////////////////////////////////// -void write_ens_var_float(int i_var, float *ens_data, const DataPlane &dp, +void write_ens_var_float(EnsVarInfo * ens_info, float *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; // Append nc_pairs_var_str config file entry - cs = conf_info.ens_var_str[i_var]; + cs = ens_info->nc_var_str; if(cs.length() > 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" - << conf_info.ens_info[i_var]->level_attr() + << ens_info->get_var_info()->name_attr() << "_" + << ens_info->get_var_info()->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -2604,16 +2688,16 @@ void write_ens_var_float(int i_var, float *ens_data, const DataPlane &dp, // if(strcmp(type_str, "ENS_MEAN") == 0) { name_str << cs_erase - << conf_info.ens_info[i_var]->name_attr(); + << ens_info->get_var_info()->name_attr(); } else { name_str << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" + << ens_info->get_var_info()->name_attr() << "_" << type_str; } // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_var], &ens_var, false, dp, + add_var_att_local(ens_info->get_var_info(), &ens_var, false, dp, name_str.c_str(), long_name_str); // Write the data @@ -2629,20 +2713,20 @@ void write_ens_var_float(int i_var, float *ens_data, const DataPlane &dp, //////////////////////////////////////////////////////////////////////// -void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, +void write_ens_var_int(EnsVarInfo * ens_info, int *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; // Append nc_pairs_var_str config file entry - cs = conf_info.ens_var_str[i_var]; + cs = ens_info->nc_var_str; if(cs.length() > 0) var_str << "_" << cs; // Construct the variable name ens_var_name << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" - << conf_info.ens_info[i_var]->level_attr() + << ens_info->get_var_info()->name_attr() << "_" + << ens_info->get_var_info()->level_attr() << var_str << "_" << type_str; // Skip variable names that have already been written @@ -2657,11 +2741,11 @@ void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, // Construct the variable name attribute name_str << cs_erase - << conf_info.ens_info[i_var]->name_attr() << "_" + << ens_info->get_var_info()->name_attr() << "_" << type_str; // Add the variable attributes - add_var_att_local(conf_info.ens_info[i_var], &ens_var, true, dp, + add_var_att_local(ens_info->get_var_info(), &ens_var, true, dp, name_str.c_str(), long_name_str); // Write the data @@ -2677,7 +2761,7 @@ void write_ens_var_int(int i_var, int *ens_data, const DataPlane &dp, //////////////////////////////////////////////////////////////////////// -void write_ens_data_plane(int i_var, const DataPlane &ens_dp, const DataPlane &dp, +void write_ens_data_plane(EnsVarInfo * ens_info, const DataPlane &ens_dp, const DataPlane &dp, const char *type_str, const char *long_name_str) { // Allocate memory for this data @@ -2687,7 +2771,7 @@ void write_ens_data_plane(int i_var, const DataPlane &ens_dp, const DataPlane &d for(int i=0; iget_var_info(), &nc_var, false, dp, name_str.c_str(), long_name_str); // Write the data @@ -2878,7 +2962,7 @@ void write_orank_var_int(int i_vx, int i_interp, int i_mask, nc_var = add_var(nc_out, (string)var_name, ncInt, lat_dim, lon_dim); // Add the variable attributes - add_var_att_local(conf_info.vx_opt[i_vx].vx_pd.fcst_info, &nc_var, true, dp, + add_var_att_local(conf_info.vx_opt[i_vx].vx_pd.fcst_info->get_var_info(), &nc_var, true, dp, name_str.c_str(), long_name_str); // Write the data diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.h b/met/src/tools/core/ensemble_stat/ensemble_stat.h index c40771d1da..2cc02de2a1 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.h @@ -93,12 +93,14 @@ static const int max_n_rec = 300; //////////////////////////////////////////////////////////////////////// // Input Ensemble files -static int n_ens; // Number of ensemble members -static IntArray n_ens_vld; // Number of members with valid data for each ensemble field [n_ens] +static int n_ens_files; // Number of ensemble members +static IntArray n_ens_vld; // Number of members with valid data for each ensemble field [n_ens_files] static IntArray n_vx_vld; // Number of members with valid data for each verification field [n_vx] -static StringArray ens_file_list; -static IntArray ens_file_vld; +static StringArray ens_file_list; // Array of ensemble input files +static StringArray fcst_file_list; // Array of ensemble input files including control +static IntArray ens_file_vld; // Array of ensemble file valid status +static IntArray fcst_file_vld; // Array of forecast file valid status static GrdFileType etype = FileType_None; static bool ens_mean_flag; // Flag for ensemble mean processing diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index b338fe4f3f..6db4407c39 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -50,8 +50,6 @@ EnsembleStatConfInfo::~EnsembleStatConfInfo() { void EnsembleStatConfInfo::init_from_scratch() { // Initialize pointers - ens_info = (VarInfo **) 0; - ens_ta = (ThreshArray *) 0; vx_opt = (EnsembleStatVxOpt *) 0; rng_ptr = (gsl_rng *) 0; @@ -64,9 +62,9 @@ void EnsembleStatConfInfo::init_from_scratch() { void EnsembleStatConfInfo::clear() { int i; + vector::const_iterator it = ens_input.begin(); // Initialize values - ens_var_str.clear(); model.clear(); obtype.clear(); vld_ens_thresh = bad_data_double; @@ -92,12 +90,12 @@ void EnsembleStatConfInfo::clear() { // Deallocate memory if(vx_opt) { delete [] vx_opt; vx_opt = (EnsembleStatVxOpt *) 0; } - if(ens_info) { - for(i=0; ioutput_map; Dictionary *edict = (Dictionary *) 0; @@ -139,6 +140,7 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, Dictionary *odict = (Dictionary *) 0; Dictionary i_edict, i_fdict, i_odict; InterpMthd mthd; + VarInfo * next_var; // Dump the contents of the config file if(mlog.verbosity_level() >= 5) conf.dump(cout); @@ -146,6 +148,11 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, // Initialize clear(); + n_ens_files = ens_files->n(); + + // Unset MET_ENS_MEMBER_ID in case it is set by the user + unsetenv(met_ens_member_id); + // Conf: version version = parse_conf_version(&conf); @@ -187,63 +194,134 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, // Conf: ensemble_flag parse_nc_info(); + // Conf: ens_member_ids + ens_member_ids = parse_conf_ens_member_ids(&conf); + + // Conf: control_id + control_id = parse_conf_string(&conf, conf_key_control_id, false); + + // Error check ens_member_ids and ensemble file list + if(ens_member_ids.n() > 1) { + + // Only a single file should be provided if using ens_member_ids + if(ens_files->n() > 1) { + mlog << Error << "\nEnsembleStatConfInfo::process_config() -> " + << "The \"" << conf_key_ens_member_ids << "\" " + << "must be empty if more than " + << "one file is provided.\n\n"; + exit(1); + } + + // If control ID is set, it cannot be found in ens_member_ids + if(!control_id.empty() && ens_member_ids.has(control_id)) { + mlog << Error << "\nEnsembleStatConfInfo::process_config() -> " + << "control_id (" << control_id << ") must not be found " + << "in ens_member_ids\n\n"; + exit(1); + } + } + + // If no ensemble member IDs were provided, add an empty string + if(ens_member_ids.n() == 0) { + ens_member_ids.add(""); + } + // Conf: ens.field edict = conf.lookup_array(conf_key_ens_field); + // Determine the number of ensemble fields to be processed n_ens_var = parse_conf_n_vx(edict); - // Allocate space based on the number of ensemble fields - if(n_ens_var > 0) { - ens_info = new VarInfo * [n_ens_var]; - ens_ta = new ThreshArray [n_ens_var]; - } - - // Initialize pointers - for(i=0; iset_dict(i_edict); + // get VarInfo magic string without substituted values + ens_info->raw_magic_str = raw_magic_str(i_edict, etype); + + // Loop over ensemble member IDs to substitute + for(j=0; j= 5) { - mlog << Debug(5) - << "Parsed ensemble field number " << i+1 << ":\n"; - ens_info[i]->dump(cout); + // Set the current dictionary + next_var->set_dict(i_edict); + + + // Dump the contents of the current VarInfo + if(mlog.verbosity_level() >= 5) { + mlog << Debug(5) + << "Parsed ensemble field number " << i+1 + << " (" << j+1 << "):\n"; + next_var->dump(cout); + } + + InputInfo input_info; + input_info.var_info = next_var; + input_info.file_index = 0; + input_info.file_list = ens_files; + ens_info->add_input(input_info); + + // Add InputInfo to ens info list for each ensemble file provided + // set var_info to NULL to note first VarInfo should be used + for(int k=1; kadd_input(input_info); + } // end for k + + } // end for j + + // Get field info for control member if set + if(!control_id.empty()) { + + // Set environment variable for ens member ID + setenv(met_ens_member_id, control_id.c_str(), 1); + + // Allocate new VarInfo object + next_var = info_factory.new_var_info(etype); + + // Set the current dictionary + next_var->set_dict(i_edict); + + ens_info->set_ctrl(next_var); } // Conf: ens_nc_var_str - ens_var_str.add(parse_conf_string(&i_edict, conf_key_nc_var_str, false)); + ens_info->nc_var_str =parse_conf_string(&i_edict, conf_key_nc_var_str, false); // Conf: ens_nc_pairs // Only parse thresholds if probabilities are requested if(nc_info.do_freq || nc_info.do_nep || nc_info.do_nmep) { // Conf: cat_thresh - ens_ta[i] = i_edict.lookup_thresh_array(conf_key_cat_thresh); + ens_info->cat_ta = i_edict.lookup_thresh_array(conf_key_cat_thresh); // Dump the contents of the current thresholds if(mlog.verbosity_level() >= 5) { mlog << Debug(5) << "Parsed thresholds for ensemble field number " << i+1 << ":\n"; - ens_ta[i].dump(cout); + ens_info->cat_ta.dump(cout); } // Keep track of the maximum number of thresholds - if(ens_ta[i].n_elements() > max_n_thresh) { - max_n_thresh = ens_ta[i].n_elements(); + if(ens_info->cat_ta.n_elements() > max_n_thresh) { + max_n_thresh = ens_info->cat_ta.n_elements(); } } - } + + ens_input.push_back(ens_info); + } // end for i // Conf: ens.ens_thresh vld_ens_thresh = conf.lookup_double(conf_key_ens_ens_thresh); @@ -345,7 +423,8 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, // Process the options for this verification task vx_opt[i].process_config(etype, i_fdict, otype, i_odict, rng_ptr, grid_vx, point_vx, - use_var_id); + use_var_id, ens_member_ids, + fcst_files, use_ctrl, control_id); // For no point verification, store obtype as the message type if(!point_vx) { @@ -673,21 +752,77 @@ void EnsembleStatVxOpt::clear() { void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, GrdFileType otype, Dictionary &odict, gsl_rng *rng_ptr, bool grid_vx, - bool point_vx, bool use_var_id) { - int i; + bool point_vx, bool use_var_id, + StringArray ens_member_ids, + StringArray * fcst_files, + bool use_ctrl, ConcatString control_id) { + int i, j; + int file_index_start = 0; VarInfoFactory info_factory; mapoutput_map; Dictionary *dict; + VarInfo * next_var; + InputInfo input_info; // Initialize clear(); - // Allocate new VarInfo objects - vx_pd.fcst_info = info_factory.new_var_info(ftype); + // Allocate new EnsVarInfo object for fcst + vx_pd.fcst_info = new EnsVarInfo(); + + // Add control member as first input + if(use_ctrl) { + + // Set environment variable for ens member ID + setenv(met_ens_member_id, control_id.c_str(), 1); + + // Allocate new VarInfo object + next_var = info_factory.new_var_info(ftype); + + // Set the current dictionary + next_var->set_dict(fdict); + + input_info.var_info = next_var; + input_info.file_index = 0; + input_info.file_list = fcst_files; + vx_pd.fcst_info->add_input(input_info); + + // Change the starting index to the first non-control file + file_index_start = 1; + } + + // Loop over ensemble member IDs to substitute + for(i=0; iset_dict(fdict); + + input_info.var_info = next_var; + input_info.file_index = file_index_start; + input_info.file_list = fcst_files; + vx_pd.fcst_info->add_input(input_info); + + // Add InputInfo to fcst info list for each ensemble file provided + // set var_info to NULL to note first VarInfo should be used + for(j=file_index_start+1; jn(); j++) { + input_info.var_info = NULL; + input_info.file_index = j; + input_info.file_list = fcst_files; + vx_pd.fcst_info->add_input(input_info); + } // end for j + + } // end for i + + // Allocate new VarInfo object for obs vx_pd.obs_info = info_factory.new_var_info(otype); // Set the VarInfo objects - vx_pd.fcst_info->set_dict(fdict); vx_pd.obs_info->set_dict(odict); // Set the GRIB code for point observations @@ -697,7 +832,7 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, if(mlog.verbosity_level() >= 5) { mlog << Debug(5) << "Parsed forecast field:\n"; - vx_pd.fcst_info->dump(cout); + vx_pd.fcst_info->get_var_info()->dump(cout); mlog << Debug(5) << "Parsed observation field:\n"; vx_pd.obs_info->dump(cout); @@ -707,10 +842,10 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, // forecast field is a range of pressure levels, check to see if the // range of observation field pressure levels is wholly contained in the // fcst levels. If not, print a warning message. - if(vx_pd.fcst_info->level().type() == LevelType_Pres && - !is_eq(vx_pd.fcst_info->level().lower(), vx_pd.fcst_info->level().upper()) && - (vx_pd.obs_info->level().lower() < vx_pd.fcst_info->level().lower() || - vx_pd.obs_info->level().upper() > vx_pd.fcst_info->level().upper())) { + if(vx_pd.fcst_info->get_var_info()->level().type() == LevelType_Pres && + !is_eq(vx_pd.fcst_info->get_var_info()->level().lower(), vx_pd.fcst_info->get_var_info()->level().upper()) && + (vx_pd.obs_info->level().lower() < vx_pd.fcst_info->get_var_info()->level().lower() || + vx_pd.obs_info->level().upper() > vx_pd.fcst_info->get_var_info()->level().upper())) { mlog << Warning << "\nEnsembleStatVxOpt::process_config() -> " @@ -723,7 +858,7 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, } // No support for wind direction - if(vx_pd.fcst_info->is_wind_direction() || + if(vx_pd.fcst_info->get_var_info()->is_wind_direction() || vx_pd.obs_info->is_wind_direction()) { mlog << Error << "\nEnsembleStatVxOpt::process_config() -> " << "wind direction may not be verified using grid_stat.\n\n"; diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h index df46f8ecf7..879fa04e95 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h @@ -112,7 +112,7 @@ class EnsembleStatVxOpt { StringArray msg_typ; // Verifying message types - ThreshArray othr_ta; // Observation filetering thresholds + ThreshArray othr_ta; // Observation filtering thresholds ClimoCDFInfo cdf_info; // Climo CDF info @@ -139,7 +139,9 @@ class EnsembleStatVxOpt { void process_config(GrdFileType, Dictionary &, GrdFileType, Dictionary &, - gsl_rng *, bool, bool, bool); + gsl_rng *, bool, bool, bool, + StringArray, StringArray *, + bool, ConcatString); void set_vx_pd(EnsembleStatConfInfo *, int); void set_perc_thresh(const PairDataEnsemble *); @@ -196,9 +198,9 @@ class EnsembleStatConfInfo { ConcatString model; // Model name ConcatString obtype; // Observation type - VarInfo ** ens_info; // Array of pointers for ensemble [n_ens_var] (allocated) - ThreshArray * ens_ta; // Array for ensemble thresholds [n_ens_var] (allocated) - StringArray ens_var_str; // Array for ensemble variable name strings [n_ens_var] + vector ens_input; // Vector of EnsVarInfo pointers (allocated) + StringArray ens_member_ids; // Array of ensemble member ID strings + ConcatString control_id; // Control ID NbrhdInfo nbrhd_prob; // Neighborhood probability definition int n_nbrhd; // Number of neighborhood sizes @@ -235,7 +237,8 @@ class EnsembleStatConfInfo { void clear(); void read_config (const ConcatString , const ConcatString); - void process_config(GrdFileType, GrdFileType, bool, bool, bool); + void process_config(GrdFileType, GrdFileType, bool, bool, bool, + StringArray *, StringArray *, bool); void process_flags (); void parse_nc_info (); void process_masks (const Grid &); diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 786a56b390..33d8351c8d 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -55,17 +55,17 @@ static void process_ensemble(); static bool get_data_plane(const char *, GrdFileType, VarInfo *, DataPlane &); static void clear_counts(); -static void track_counts(EnsVarInfo *, const DataPlane &, bool, +static void track_counts(GenEnsProdVarInfo *, const DataPlane &, bool, const DataPlane &, const DataPlane &); static void setup_nc_file(); -static void write_ens_nc(EnsVarInfo *, int, const DataPlane &, +static void write_ens_nc(GenEnsProdVarInfo *, int, const DataPlane &, const DataPlane &, const DataPlane &); -static void write_ens_var_float(EnsVarInfo *, float *, const DataPlane &, +static void write_ens_var_float(GenEnsProdVarInfo *, float *, const DataPlane &, const char *, const char *); -static void write_ens_var_int(EnsVarInfo *, int *, const DataPlane &, +static void write_ens_var_int(GenEnsProdVarInfo *, int *, const DataPlane &, const char *, const char *); -static void write_ens_data_plane(EnsVarInfo *, const DataPlane &, const DataPlane &, +static void write_ens_data_plane(GenEnsProdVarInfo *, const DataPlane &, const DataPlane &, const char *, const char *); static void add_var_att_local(VarInfo *, NcVar *, bool is_int, @@ -327,7 +327,7 @@ void process_ensemble() { ConcatString ens_file; // Loop through each of the ensemble fields to be processed - vector::const_iterator var_it = conf_info.ens_input.begin(); + vector::const_iterator var_it = conf_info.ens_input.begin(); for(i_var=0; var_it != conf_info.ens_input.end(); var_it++, i_var++) { // Need to reinitialize counts and sums for each ensemble field @@ -470,7 +470,7 @@ void clear_counts() { //////////////////////////////////////////////////////////////////////// -void track_counts(EnsVarInfo * ens_info, const DataPlane &ens_dp, bool is_ctrl, +void track_counts(GenEnsProdVarInfo * ens_info, const DataPlane &ens_dp, bool is_ctrl, const DataPlane &cmn_dp, const DataPlane &csd_dp) { int i, j, k; double ens, cmn, csd; @@ -581,7 +581,7 @@ void setup_nc_file() { //////////////////////////////////////////////////////////////////////// -void write_ens_nc(EnsVarInfo * ens_info, int n_ens_vld, +void write_ens_nc(GenEnsProdVarInfo * ens_info, int n_ens_vld, const DataPlane &ens_dp, const DataPlane &cmn_dp, const DataPlane &csd_dp) { @@ -838,7 +838,7 @@ void write_ens_nc(EnsVarInfo * ens_info, int n_ens_vld, //////////////////////////////////////////////////////////////////////// -void write_ens_var_float(EnsVarInfo * ens_info, float *ens_data, const DataPlane &dp, +void write_ens_var_float(GenEnsProdVarInfo * ens_info, float *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; @@ -894,7 +894,7 @@ void write_ens_var_float(EnsVarInfo * ens_info, float *ens_data, const DataPlane //////////////////////////////////////////////////////////////////////// -void write_ens_var_int(EnsVarInfo * ens_info, int *ens_data, const DataPlane &dp, +void write_ens_var_int(GenEnsProdVarInfo * ens_info, int *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; @@ -941,7 +941,7 @@ void write_ens_var_int(EnsVarInfo * ens_info, int *ens_data, const DataPlane &dp //////////////////////////////////////////////////////////////////////// -void write_ens_data_plane(EnsVarInfo * ens_info, const DataPlane &ens_dp, const DataPlane &dp, +void write_ens_data_plane(GenEnsProdVarInfo * ens_info, const DataPlane &ens_dp, const DataPlane &dp, const char *type_str, const char *long_name_str) { // Allocate memory for this data diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc index f8aa2169ac..96ee7be396 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc @@ -55,7 +55,7 @@ void GenEnsProdConfInfo::init_from_scratch() { //////////////////////////////////////////////////////////////////////// void GenEnsProdConfInfo::clear() { - vector::const_iterator var_it = ens_input.begin(); + vector::const_iterator var_it = ens_input.begin(); // Clear, erase, and initialize members model.clear(); @@ -173,14 +173,14 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_fil // Parse the ensemble field information for(i=0,max_n_cat=0; iraw_magic_str = raw_magic_str(i_edict); + ens_info->raw_magic_str = raw_magic_str(i_edict, etype); // Loop over ensemble member IDs to substitute for(j=0; j::const_iterator it; - for(it = inputs.begin(); it != inputs.end(); it++) { - if((*it).var_info) { delete (*it).var_info; } - } - - if(ctrl_info) { delete ctrl_info; } -} - -//////////////////////////////////////////////////////////////////////// - -void EnsVarInfo::add_input(InputInfo input) { - inputs.push_back(input); -} - -//////////////////////////////////////////////////////////////////////// - -int EnsVarInfo::inputs_n() { - return inputs.size(); -} - -//////////////////////////////////////////////////////////////////////// - -void EnsVarInfo::set_ctrl(VarInfo * ctrl) { - ctrl_info = ctrl; -} - -//////////////////////////////////////////////////////////////////////// - -VarInfo * EnsVarInfo::get_ctrl(int index) { - if(ctrl_info) { - return ctrl_info; - } - return inputs[index].var_info; -} - -//////////////////////////////////////////////////////////////////////// - -VarInfo * EnsVarInfo::get_var_info(int index) { - if(inputs[index].var_info) { - return inputs[index].var_info; - } - return inputs[0].var_info; -} - -//////////////////////////////////////////////////////////////////////// - -ConcatString EnsVarInfo::get_file(int index) { - int file_index = inputs[index].file_index; - return (*inputs[index].file_list)[file_index]; -} - -//////////////////////////////////////////////////////////////////////// - -int EnsVarInfo::get_file_index(int index) { - return inputs[index].file_index; -} - -//////////////////////////////////////////////////////////////////////// - -ConcatString raw_magic_str(Dictionary i_edict) { - ConcatString magic_str; - - ConcatString name = i_edict.lookup_string("name"); - ConcatString level = i_edict.lookup_string("level"); - - if(level.nonempty() && level[0] != '(') { - magic_str << name << "/" << level; - } else { - magic_str << name << level; - } - - return magic_str; - -} - -//////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h index d0d5e60bbe..9510cc32b7 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h @@ -24,6 +24,10 @@ //////////////////////////////////////////////////////////////////////// +class GenEnsProdVarInfo; // forward reference + +//////////////////////////////////////////////////////////////////////// + struct GenEnsProdNcOutInfo { bool do_latlon; @@ -51,43 +55,6 @@ struct GenEnsProdNcOutInfo { void set_all_true(); }; - -//////////////////////////////////////////////////////////////////////// - -struct InputInfo { - VarInfo * var_info; // Variable information to read - int file_index; // Index in file_list of file to read - StringArray * file_list; // Array of files (unallocated) -}; - -//////////////////////////////////////////////////////////////////////// - -class EnsVarInfo { - - private: - vector inputs; // Vector of InputInfo - VarInfo * ctrl_info; // Field info for control member - public: - EnsVarInfo(); - ~EnsVarInfo(); - - void add_input(InputInfo); - int inputs_n(); - - void set_ctrl(VarInfo *); - VarInfo * get_ctrl(int); - - // Get VarInfo from first InputInfo if requested VarInfo is NULL - VarInfo * get_var_info(int index=0); - ConcatString get_file(int index=0); - int get_file_index(int index=0); - - ConcatString nc_var_str; // Ensemble variable name strings - ThreshArray cat_ta; // Ensemble categorical thresholds - GenEnsProdNcOutInfo nc_info; // Ensemble product outputs - ConcatString raw_magic_str; // Magic string w/o var substitution -}; - //////////////////////////////////////////////////////////////////////// class GenEnsProdConfInfo { @@ -115,9 +82,9 @@ class GenEnsProdConfInfo { ConcatString desc; // Description ConcatString control_id; // Control ID - vector ens_input; // Vector of EnsVarInfo pointers (allocated) - vector cdf_info; // Array of climo CDF info objects - StringArray ens_member_ids; // Array of ensemble member ID strings + vector ens_input; // Vector of GenEnsProdVarInfo pointers (allocated) + vector cdf_info; // Array of climo CDF info objects + StringArray ens_member_ids; // Array of ensemble member ID strings NbrhdInfo nbrhd_prob; // Neighborhood probability definition InterpInfo nmep_smooth; // Neighborhood maximum smoothing information @@ -152,7 +119,11 @@ inline int GenEnsProdConfInfo::get_compression_level() { return(conf.nc_compress //////////////////////////////////////////////////////////////////////// -ConcatString raw_magic_str(Dictionary i_edict); +class GenEnsProdVarInfo: public EnsVarInfo { + +public: + GenEnsProdNcOutInfo nc_info; // Ensemble product outputs +}; #endif /* __GEN_ENS_PROD_CONF_INFO_H__ */ diff --git a/scripts/environment/development.seneca b/scripts/environment/development.seneca index 5b3497c0c1..a535aeaa67 100644 --- a/scripts/environment/development.seneca +++ b/scripts/environment/development.seneca @@ -49,4 +49,3 @@ export MET_TEST_RSCRIPT=/usr/local/R-4.1.2/bin/Rscript export PATH="/usr/local/nco/bin:/usr/local/netcdf/bin:\ /usr/local/sbin:/usr/local/bin:/usr/sbin:\ /usr/bin:/sbin:/bin:/usr/bin/X11:/opt/bin:$PATH" - diff --git a/test/config/EnsembleStatConfig b/test/config/EnsembleStatConfig index c99f8da963..296555748e 100644 --- a/test/config/EnsembleStatConfig +++ b/test/config/EnsembleStatConfig @@ -56,6 +56,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_MASK_SID b/test/config/EnsembleStatConfig_MASK_SID index 2ad34e2f27..764ad8280c 100644 --- a/test/config/EnsembleStatConfig_MASK_SID +++ b/test/config/EnsembleStatConfig_MASK_SID @@ -53,6 +53,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_climo b/test/config/EnsembleStatConfig_climo index 1656128df9..478ceb1552 100644 --- a/test/config/EnsembleStatConfig_climo +++ b/test/config/EnsembleStatConfig_climo @@ -48,6 +48,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_grid_weight b/test/config/EnsembleStatConfig_grid_weight index da710a73e5..dbd72bc580 100644 --- a/test/config/EnsembleStatConfig_grid_weight +++ b/test/config/EnsembleStatConfig_grid_weight @@ -47,6 +47,13 @@ ens = { field = tmp_field; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_one_cdf_bin b/test/config/EnsembleStatConfig_one_cdf_bin index 7e19af2b80..2a02b9475e 100644 --- a/test/config/EnsembleStatConfig_one_cdf_bin +++ b/test/config/EnsembleStatConfig_one_cdf_bin @@ -48,6 +48,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_python b/test/config/EnsembleStatConfig_python index de502a7250..1e137fad3d 100644 --- a/test/config/EnsembleStatConfig_python +++ b/test/config/EnsembleStatConfig_python @@ -56,6 +56,13 @@ ens = { field = [ { name = "${FCST_COMMAND}"; } ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_qty_inc_exc b/test/config/EnsembleStatConfig_qty_inc_exc index 17009a61a0..620511dd4c 100644 --- a/test/config/EnsembleStatConfig_qty_inc_exc +++ b/test/config/EnsembleStatConfig_qty_inc_exc @@ -51,6 +51,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // diff --git a/test/config/EnsembleStatConfig_single_file_grib b/test/config/EnsembleStatConfig_single_file_grib new file mode 100644 index 0000000000..cae96307fe --- /dev/null +++ b/test/config/EnsembleStatConfig_single_file_grib @@ -0,0 +1,317 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Ensemble-Stat configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "GEFS"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "${DESC}"; + +// +// Output observation type to be written +// +obtype = "ANALYS"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// May be set separately in each "field" entry +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + +// +// Ensemble product fields to be processed +// +ens = { + ens_thresh = 1.0; + vld_thresh = 1.0; + + field = [ + { + name = "PRMSL"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "MET_ENS_MEMBER_ID"; + } + ]; +} + +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = ["+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15", "+16", "+17", "+18", "+19", "+20"]; +control_id = "hi_res_ctl"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood ensemble probabilities +// +nbrhd_prob = { + width = [ 5 ]; + shape = CIRCLE; + vld_thresh = 0.0; +} + +// +// NMEP smoothing methods +// +nmep_smooth = { + vld_thresh = 0.0; + shape = CIRCLE; + gaussian_dx = 81.27; + gaussian_radius = 120; + type = [ + { + method = GAUSSIAN; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Forecast and observation fields to be verified +// +fcst = { + + field = [ + { + name = "PRMSL"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "MET_ENS_MEMBER_ID"; + } + ]; +} + +obs = { + field = [ + { + name = "PRMSL"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "hi_res_ctl"; + } + ]; +} +//////////////////////////////////////////////////////////////////////////////// + +// +// Point observation filtering options +// May be set separately in each "obs.field" entry +// +message_type = [ "ADPUPA" ]; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; + +// +// Observation error options +// Set dist_type to NONE to use the observation error table instead +// May be set separately in each "obs.field" entry +// +obs_error = { + flag = FALSE; // TRUE or FALSE + dist_type = NONE; // Distribution type + dist_parm = []; // Distribution parameters + inst_bias_scale = 1.0; // Instrument bias scale adjustment + inst_bias_offset = 0.0; // Instrument bias offset adjustment + min = NA; // Valid range of data + max = NA; +} + +// +// Mapping of message type group name to comma-separated list of values +// +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"; } +]; + +// +// Ensemble bin sizes +// May be set separately in each "obs.field" entry +// +ens_ssvar_bin_size = 1.0; +ens_phist_bin_size = 0.05; + +// +// Categorical thresholds to define ensemble probabilities +// May be set separately in each "fcst.field" entry +// +prob_cat_thresh = []; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = { + + file_name = []; + field = []; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 31; + hour_interval = 6; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = []; +} + +// +// May be set separately in each "obs.field" entry +// +climo_cdf = { + cdf_bins = 10; + center_bins = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Point observation time window +// +obs_window = { + beg = -5400; + end = 5400; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification masking regions +// +mask = { + grid = [ "FULL" ]; + poly = []; + sid = []; + llpnt = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Interpolation methods +// +interp = { + field = BOTH; + vld_thresh = 1.0; + shape = SQUARE; + + type = [ + { + method = NEAREST; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Statistical output types +// +output_flag = { + ecnt = STAT; + rps = NONE; + rhist = NONE; + phist = NONE; + orank = NONE; + ssvar = NONE; + relp = NONE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Ensemble product output types +// +ensemble_flag = { + latlon = TRUE; + mean = TRUE; + stdev = TRUE; + minus = TRUE; + plus = TRUE; + min = TRUE; + max = TRUE; + range = TRUE; + vld_count = TRUE; + frequency = TRUE; + nep = FALSE; + nmep = FALSE; + rank = TRUE; + weight = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Random number generator +// +rng = { + type = "mt19937"; + seed = ""; +} + +//////////////////////////////////////////////////////////////////////////////// + +grid_weight_flag = NONE; +output_prefix = "${OUTPUT_PREFIX}"; +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_single_file_nc b/test/config/EnsembleStatConfig_single_file_nc new file mode 100644 index 0000000000..47ed145c44 --- /dev/null +++ b/test/config/EnsembleStatConfig_single_file_nc @@ -0,0 +1,315 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Ensemble-Stat configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "WRF"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "${DESC}"; + +// +// Output observation type to be written +// +obtype = "ANALYS"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// May be set separately in each "field" entry +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + +// +// Ensemble product fields to be processed +// +ens = { + file_type = NETCDF_NCCF; + ens_thresh = 1.0; + vld_thresh = 1.0; + + field = [ + { + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,0,*,*)"; + cat_thresh = [ >0.0, >=5.0 ]; + } + ]; +} + +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]; +control_id = "0"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood ensemble probabilities +// +nbrhd_prob = { + width = [ 5 ]; + shape = CIRCLE; + vld_thresh = 0.0; +} + +// +// NMEP smoothing methods +// +nmep_smooth = { + vld_thresh = 0.0; + shape = CIRCLE; + gaussian_dx = 81.27; + gaussian_radius = 120; + type = [ + { + method = GAUSSIAN; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Forecast and observation fields to be verified +// +fcst = { + file_type = NETCDF_NCCF; + field = [ + { + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,0,*,*)"; + cat_thresh = [ >0.0, >=5.0 ]; + } + ]; +} + +obs = { + field = [ + { + name = "fcst"; + level = "(0,0,*,*)"; + cat_thresh = [ >0.0, >=5.0 ]; + } + ]; +} +//////////////////////////////////////////////////////////////////////////////// + +// +// Point observation filtering options +// May be set separately in each "obs.field" entry +// +message_type = [ "ADPUPA" ]; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; + +// +// Observation error options +// Set dist_type to NONE to use the observation error table instead +// May be set separately in each "obs.field" entry +// +obs_error = { + flag = FALSE; // TRUE or FALSE + dist_type = NONE; // Distribution type + dist_parm = []; // Distribution parameters + inst_bias_scale = 1.0; // Instrument bias scale adjustment + inst_bias_offset = 0.0; // Instrument bias offset adjustment + min = NA; // Valid range of data + max = NA; +} + +// +// Mapping of message type group name to comma-separated list of values +// +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"; } +]; + +// +// Ensemble bin sizes +// May be set separately in each "obs.field" entry +// +ens_ssvar_bin_size = 1.0; +ens_phist_bin_size = 0.05; + +// +// Categorical thresholds to define ensemble probabilities +// May be set separately in each "fcst.field" entry +// +prob_cat_thresh = []; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = { + + file_name = []; + field = []; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 31; + hour_interval = 6; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = []; +} + +// +// May be set separately in each "obs.field" entry +// +climo_cdf = { + cdf_bins = 10; + center_bins = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Point observation time window +// +obs_window = { + beg = -5400; + end = 5400; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification masking regions +// +mask = { + grid = [ "FULL" ]; + poly = []; + sid = []; + llpnt = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Interpolation methods +// +interp = { + field = BOTH; + vld_thresh = 1.0; + shape = SQUARE; + + type = [ + { + method = NEAREST; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Statistical output types +// +output_flag = { + ecnt = STAT; + rps = NONE; + rhist = NONE; + phist = NONE; + orank = NONE; + ssvar = NONE; + relp = NONE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Ensemble product output types +// +ensemble_flag = { + latlon = TRUE; + mean = TRUE; + stdev = TRUE; + minus = TRUE; + plus = TRUE; + min = TRUE; + max = TRUE; + range = TRUE; + vld_count = TRUE; + frequency = TRUE; + nep = FALSE; + nmep = FALSE; + rank = TRUE; + weight = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Random number generator +// +rng = { + type = "mt19937"; + seed = ""; +} + +//////////////////////////////////////////////////////////////////////////////// + +grid_weight_flag = NONE; +output_prefix = "${OUTPUT_PREFIX}"; +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/xml/unit_ensemble_stat.xml b/test/xml/unit_ensemble_stat.xml index 105d19c3d4..034ff07cbf 100644 --- a/test/xml/unit_ensemble_stat.xml +++ b/test/xml/unit_ensemble_stat.xml @@ -250,4 +250,86 @@ + + + + &MET_BIN;/ensemble_stat + + DESC SINGLE_FILE_NC_NO_CTRL + OUTPUT_PREFIX SINGLE_FILE_NC_NO_CTRL + + \ + 1 \ + &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + &CONFIG_DIR;/EnsembleStatConfig_single_file_nc \ + -grid_obs &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + + + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_NO_CTRL_19700101_000000V_ens.nc + + + + + + + &MET_BIN;/ensemble_stat + + DESC SINGLE_FILE_NC_WITH_CTRL + OUTPUT_PREFIX SINGLE_FILE_NC_WITH_CTRL + + \ + 1 \ + &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + &CONFIG_DIR;/EnsembleStatConfig_single_file_nc \ + -grid_obs &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -ctrl &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + + + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_WITH_CTRL_19700101_000000V_ens.nc + + + + + + + &MET_BIN;/ensemble_stat + + DESC SINGLE_FILE_GRIB_NO_CTRL + OUTPUT_PREFIX SINGLE_FILE_GRIB_NO_CTRL + + \ + 1 \ + &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + &CONFIG_DIR;/EnsembleStatConfig_single_file_grib \ + -grid_obs &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + + + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_NO_CTRL_20160608_060000V_ens.nc + + + + + + + &MET_BIN;/ensemble_stat + + DESC SINGLE_FILE_GRIB_WITH_CTRL + OUTPUT_PREFIX SINGLE_FILE_GRIB_WITH_CTRL + + \ + 1 \ + &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + &CONFIG_DIR;/EnsembleStatConfig_single_file_grib \ + -grid_obs &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -ctrl &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + + + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_WITH_CTRL_20160608_060000V_ens.nc + + + From 032456bbce311d69bbaf8da194df53b928d1f60b Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 14 Jan 2022 16:33:36 -0700 Subject: [PATCH 063/172] Committing directly to the develop branch. Removing many, many instances of MET_BUILD_BASE and a couple instances of MET_BASE from the examples listed in Appendix A. The inconsistent use of these variables will only cause confusion. Removing them will help avoid that confusion. Big picture... MET_BASE defines the installed 'share/met' directory. It can be used to reference the location of map or polyline files. MET_BUILD_BASE is only used in the context of the test scripts. There, it's defined as the top-level source code directory in which the code was compiled. Its used to reference the location of sample data files or Rscript included in the tarball. I left a couple references to these variables in Appendix A where thier use is not confusing. But I removed all instances which are used to the define the location of the 'bin' directory. Instead, let's just assume the MET binaries are already in their path... or the user knows where to find them. --- met/docs/Users_Guide/appendixA.rst | 103 ++++++++++++++--------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/met/docs/Users_Guide/appendixA.rst b/met/docs/Users_Guide/appendixA.rst index 7271ecb1de..d5e3752ecf 100644 --- a/met/docs/Users_Guide/appendixA.rst +++ b/met/docs/Users_Guide/appendixA.rst @@ -57,7 +57,7 @@ in the configuration string on the command line: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane + plot_data_plane sample.grib china_tmp_2m_admin.ps \ 'name="TMP"; level="Z2"; \ map_data = { source = [ { file_name = \ @@ -149,7 +149,7 @@ Let's use plot_data_plane as an example: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane \ + plot_data_plane \ MERGE_20161201_20170228.nc \ obs.ps \ 'name="APCP"; level="(5,*,*)";' @@ -281,20 +281,20 @@ lat/lon grid over Europe: .. code-block:: none - ${MET_BUILD_BASE}/bin/regrid_data_plane gfs.t12z.pgrb2.0p50.f000 \ + regrid_data_plane gfs.t12z.pgrb2.0p50.f000 \ 'latlon 100 100 25 0 0.5 0.5' gfs_euro.nc -field 'name="TMP"; level="Z2";' Run the MET gen_vx_mask tool to apply your polyline to the European domain: .. code-block:: none - ${MET_BUILD_BASE}/bin/gen_vx_mask gfs_euro.nc POLAND.poly POLAND_mask.nc + gen_vx_mask gfs_euro.nc POLAND.poly POLAND_mask.nc Run the MET plot_data_plane tool to display the resulting mask field: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane POLAND_mask.nc POLAND_mask.ps 'name="POLAND"; level="(*,*)";' + plot_data_plane POLAND_mask.nc POLAND_mask.ps 'name="POLAND"; level="(*,*)";' In this example, the mask is in roughly the right spot, but there are obvious problems with the latitude and longitude values used @@ -452,7 +452,7 @@ Run Grid-Stat using the following commands and the attached config file .. code-block:: none mkdir out - ${MET_BUILD_BASE}/bin/grid_stat \ + grid_stat \ gfs_4_20160220_0000_012.grb2 \ ST4.2016022012.06h \ GridStatConfig \ @@ -490,7 +490,7 @@ commands to plot its NetCDF matched pairs output file: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane \ + plot_data_plane \ out/grid_stat_120000L_20160220_120000V_pairs.nc \ out/DIFF_APCP_06_A06_APCP_06_A06_CONUS.ps \ 'name="DIFF_APCP_06_A06_APCP_06_A06_CONUS"; level="(*,*)";' @@ -524,7 +524,7 @@ point where the temperature is less than 290 K to a value of 0: .. code-block:: none - {MET_BUILD_BASE}/bin/gen_vx_mask \ + gen_vx_mask \ data/sample_fcst/2005080700/wrfprs_ruc13_12.tm00_G212 \ data/sample_fcst/2005080700/wrfprs_ruc13_12.tm00_G212 \ APCP_03_where_2m_TMPge290.nc \ @@ -568,11 +568,10 @@ the output through plot_data_plane: .. code-block:: none - {MET_BUILD_BASE}/bin/plot_data_plane \ - - APCP_03_where_2m_TMPge290.nc APCP_03_where_2m_TMPge290.ps \ - - 'name="data_mask"; level="(*,*)";' + plot_data_plane \ + APCP_03_where_2m_TMPge290.nc \ + APCP_03_where_2m_TMPge290.ps \ + 'name="data_mask"; level="(*,*)";' In the resulting plot, anywhere you see the pink value of 10, that's where gen_vx_mask has masked out the grid point. @@ -593,21 +592,21 @@ through pcp_combine as a pass-through to put it into NetCDF format: .. code-block:: none - [MET_BUILD_BASE}/pcp_combine -add 03_file.grb 03 APCP_00_03.nc + pcp_combine -add 03_file.grb 03 APCP_00_03.nc If the user wanted the 3-6 hour accumulation, they would subtract 0-6 and 0-3 accumulations: .. code-block:: none - [MET_BUILD_BASE}/pcp_combine -subtract 06_file.grb 06 03_file.grb 03 APCP_03_06.nc + pcp_combine -subtract 06_file.grb 06 03_file.grb 03 APCP_03_06.nc Similarly, if they wanted the 6-9 hour accumulation, they would subtract 0-9 and 0-6 accumulations: .. code-block:: none - [MET_BUILD_BASE}/pcp_combine -subtract 09_file.grb 09 06_file.grb 06 APCP_06_09.nc + pcp_combine -subtract 09_file.grb 09 06_file.grb 06 APCP_06_09.nc And so on. @@ -626,7 +625,7 @@ option instead. .. code-block:: none - ${MET_BUILD_BASE}/bin/pcp_combine -add \ + pcp_combine -add \ WRFPRS_1997-06-03_APCP_A12.nc 'name="APCP_12"; level="(*,*)";' \ WRFPRS_d01_1997-06-04_00_APCP_A12.grb 12 \ Sum.nc @@ -647,17 +646,17 @@ Here are 3 commands you could use to plot these data files: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane WRFPRS_1997-06-03_APCP_A12.nc \ + plot_data_plane WRFPRS_1997-06-03_APCP_A12.nc \ WRFPRS_1997-06-03_APCP_A12.ps 'name="APCP_12"; level="(*,*)";' .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane WRFPRS_d01_1997-06-04_00_APCP_A12.grb \ + plot_data_plane WRFPRS_d01_1997-06-04_00_APCP_A12.grb \ WRFPRS_d01_1997-06-04_00_APCP_A12.ps 'name="APCP" level="A12";' .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane sum.nc sum.ps 'name="APCP_24"; level="(*,*)";' + plot_data_plane sum.nc sum.ps 'name="APCP_24"; level="(*,*)";' **Q. Pcp-Combine - How do I correct a precipitation time range?** @@ -756,11 +755,11 @@ examples: .. code-block:: none # Only using Stage IV data (ST4) - ${MET_BUILD_BASE}/bin/pcp_combine -sum 00000000_000000 06 \ + pcp_combine -sum 00000000_000000 06 \ 20161015_18 12 ST4.2016101518.APCP_12_SUM.nc -pcprx "ST4.*.06h" # Specify that files starting with pgbq[number][number]be used: - [MET_BUILD_BASE]/bin/pcp_combine \ + pcp_combine \ -sum 20160221_18 06 20160222_18 24 \ gfs_APCP_24_20160221_18_F00_F24.nc \ -pcpdir /scratch4/BMC/shout/ptmp/Andrew.Kren/pre2016c3_corr/temp \ @@ -826,7 +825,7 @@ Try the command: .. code-block:: none - ${MET_BUILD_BASE}/bin/pcp_combine -subtract \ + pcp_combine -subtract \ forecast.grb 'name="APCP"; level="L0"; lead_time="165500";' \ forecast2.grb 'name="APCP"; level="L0"; lead_time="160500";' \ forecast.nc -name APCP_A005000 @@ -877,7 +876,7 @@ GFS. In this example, process the 20150220 00Z initialization of GFS. .. code-block:: none - ${MET_BUILD_BASE}/bin/pcp_combine \ + pcp_combine \ -sum 20150220_00 06 20150221_00 24 \ gfs_APCP_24_20150220_00_F00_F24.nc \ -pcprx "gfs_4_20150220_00.*grb2" \ @@ -897,7 +896,7 @@ hours 12 and 36: .. code-block:: none - ${MET_BUILD_BASE}/bin/pcp_combine \ + pcp_combine \ -sum 20150220_00 06 20150221_12 24 \ gfs_APCP_24_20150220_00_F12_F36.nc \ -pcprx "gfs_4_20150220_00.*grb2" \ @@ -911,7 +910,7 @@ the previous "-sum" job could be rewritten with "-add" like this: .. code-block:: none - ${MET_BUILD_BASE}/bin/pcp_combine -add \ + pcp_combine -add \ /d1/model_data/20150220/gfs_4_20150220_0000_018.grb2 06 \ /d1/model_data/20150220/gfs_4_20150220_0000_024.grb2 06 \ /d1/model_data/20150220/gfs_4_20150220_0000_030.grb2 06 \ @@ -950,13 +949,12 @@ Plot-Data-Plane A. Check to see if the call to Gen-Vx-Mask actually did create good output -with Plot-Data-Plane. -Try running the following command from the top-level ${MET_BUILD_BASE} -directory. +with Plot-Data-Plane. The following commands assume that the MET executables +are found in your path. .. code-block:: none - bin/plot_data_plane \ + plot_data_plane \ out/gen_vx_mask/CONUS_poly.nc \ out/gen_vx_mask/CONUS_poly.ps \ 'name="CONUS"; level="(*,*)";' @@ -997,7 +995,7 @@ MET configuration files (i.e. Grid-Stat, MODE, and so on) that you use: .. code-block:: none - {MET_BASE}/bin/plot_data_plane \ + plot_data_plane \ test_2.5_prog.grib \ test_2.5_prog.ps \ 'name="TSTM"; level="A0"; file_type=GRIB2;' \ @@ -1013,7 +1011,7 @@ by running: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane LTIA98_KWBR_201305180600.grb2 tmp_z2.ps 'name="TMP"; level="R2"; + plot_data_plane LTIA98_KWBR_201305180600.grb2 tmp_z2.ps 'name="TMP"; level="R2"; "R2" tells MET to plot record number 2. Record numbers 1 and 2 both contain temperature data and 2-meters. Here's some wgrib2 output: @@ -1039,9 +1037,9 @@ named wrf.grb, please try running the following commands to plot wind speed: .. code-block:: none - ${MET_BUILD_BASE}/bin/plot_data_plane wrf.grb wrf_wind.ps \ + plot_data_plane wrf.grb wrf_wind.ps \ 'name"WIND"; level="Z10";' -v 3 - ${MET_BUILD_BASE}/bin/plot_data_plane rtma.grb2 rtma_wind.ps \ + plot_data_plane rtma.grb2 rtma_wind.ps \ 'name"WIND"; level="Z10";' -v 3 In the first call, the log message should be similar to this: @@ -1114,7 +1112,7 @@ Run the "aggregate" job type in stat_analysis to do this: .. code-block:: none - ${MET_BUILD_BASE}/bin/stat_analysis -lookin directory/file*_nbrcnt.txt \ + stat_analysis -lookin directory/file*_nbrcnt.txt \ -job aggregate -line_type NBRCNT -by FCST_VAR,FCST_LEAD,FCST_THRESH,INTERP_MTHD,INTERP_PNTS -out_stat agg_nbrcnt.txt This job reads all the files that are passed to it on the command line with @@ -1141,7 +1139,7 @@ to run the job separately for each unique entry found in the FCST_VAR column. .. code-block:: none - ${MET_BUILD_BASE}/bin/stat_analysis \ + stat_analysis \ -lookin point_stat_model2_120000L_20160501_120000V.stat \ -job aggregate_stat -line_type MPR -out_line_type PSTD \ -out_fcst_thresh ge0,ge0.1,ge0.2,ge0.3,ge0.4,ge0.5,ge0.6,ge0.7,ge0.8,ge0.9,ge1.0 \ @@ -1161,7 +1159,7 @@ cases without having to modify the source code. .. code-block:: none - ${MET_BUILD_BASE}/bin/stat_analysis \ + stat_analysis \ -lookin out/grid_stat/grid_stat_120000L_20050807_120000V.stat \ -job filter -dump_row filter_cts.txt -line_type CTS \ -column_min BASER 0.05 -column_min FMEAN 0.05 @@ -1193,7 +1191,7 @@ Run the following job on the output from Grid-Stat generated when the .. code-block:: none - ${MET_BUILD_BASE}/bin/stat_analysis -lookin out/grid_stat \ + stat_analysis -lookin out/grid_stat \ -job aggregate_stat -line_type SL1L2 -out_line_type CNT \ -by FCST_VAR,FCST_LEV \ -out_stat cnt.txt @@ -1226,7 +1224,7 @@ Two more suggestions for faster run times. .. code-block:: none - ${MET_BUILD_BASE}/bin/stat_analysis \ + stat_analysis \ -lookin diag_conv_anl.2015060100.stat \ -job aggregate_stat -line_type MPR -out_line_type CNT -by FCST_VAR \ -out_stat diag_conv_anl.2015060100_cnt.txt -set_hdr OBTYPE ALL_TYPES \ @@ -1250,7 +1248,7 @@ all grouped together. .. code-block:: none - ${MET_BUILD_BASE}/bin/tc_stat \ + tc_stat \ -lookin d2014_vx_20141117_reset/al/tc_pairs/tc_pairs_H3WI_* \ -lookin d2014_vx_20141117_reset/al/tc_pairs/tc_pairs_HWFI_* \ -job summary -lead 480000 -column TRACK -amodel HWFI,H3WI \ @@ -1266,7 +1264,7 @@ To get the most output, run something like this: .. code-block:: none - ${MET_BUILD_BASE}/bin/tc_stat \ + tc_stat \ -lookin path/to/tc_pairs/output \ -job rirw -dump_row test \ -out_line_type CTC,CTS,MPR @@ -1280,7 +1278,7 @@ in time. .. code-block:: none - {MET_BASE}/bin/tc_stat \ + tc_stat \ -lookin path/to/tc_pairs/output \ -job rirw -dump_row test \ -rirw_time 36 -rirw_window 12 \ @@ -1291,7 +1289,7 @@ To stratify your results by lead time, you could add the "-by LEAD" option. .. code-block:: none - {MET_BASE}/bin/tc_stat \ + tc_stat \ -lookin path/to/tc_pairs/output \ -job rirw -dump_row test \ -rirw_time 36 -rirw_window 12 \ @@ -1314,9 +1312,9 @@ and call convert to reformat from PostScript to PNG. #!/bin/sh for case in `echo "FCST OBS"`; do export TO_GRID=${case} - /usr/local/${MET_BUILD_BASE}/bin/grid_stat gfs.t00z.pgrb2.0p25.f000 \ - nam.t00z.conusnest.hiresf00.tm00.grib2 GridStatConfig \ - /usr/local/${MET_BUILD_BASE}/bin/plot_data_plane \ + grid_stat gfs.t00z.pgrb2.0p25.f000 \ + nam.t00z.conusnest.hiresf00.tm00.grib2 GridStatConfig + plot_data_plane \ *TO_GRID_${case}*_pairs.nc TO_GRID_${case}.ps 'name="DIFF_TMP_P500_TMP_P500_FULL"; \ level="(*,*)";' convert -rotate 90 -background white -flatten TO_GRID_${case}.ps @@ -1349,7 +1347,7 @@ http://dtcenter.org/community-code/model-evaluation-tools-met/input-data Rscript trmmbin2nc.R 3B42.100921.00z.7.precipitation.bin \ 3B42.100921.00z.7.precipitation.nc # Plot the result - ${MET_BUILD_BASE}/bin/plot_data_plane 3B42.100921.00z.7.precipitation.nc \ + plot_data_plane 3B42.100921.00z.7.precipitation.nc \ 3B42.100921.00z.7.precipitation.ps 'name="APCP_03"; level="(*,*)";' It may be possible that the domain of the data is smaller. Here are some options: @@ -1413,8 +1411,7 @@ and then plot the result. .. code-block:: none - setenv MET_BUILD_BASE `pwd` - Rscript scripts/Rscripts/plot_tcmpr.R \ + Rscript ${MET_BUILD_BASE}/scripts/Rscripts/plot_tcmpr.R \ -lookin tc_pairs_output.tcst \ -filter '-amodel AHWI,GFSI' \ -series AMODEL AHWI,GFSI,AHWI-GFSI \ @@ -1452,7 +1449,7 @@ some GFS data to a LatLon grid: .. code-block:: none - ${MET_BUILD_BASE}/bin/regrid_data_plane \ + regrid_data_plane \ gfs_2012040900_F012.grib G110 \ gfs_g110.nc -field 'name="TMP"; level="Z2";' @@ -1499,7 +1496,7 @@ Below is a command example to run: .. code-block:: none - ${MET_BUILD_BASE}/bin/tc_pairs \ + tc_pairs \ -adeck aep142014.h4hw.dat \ -bdeck bep142014.dat \ -config TCPairsConfig_v5.0 \ @@ -1557,7 +1554,7 @@ this example (suffix=_EXP): .. code-block:: none - ${MET_BUILD_BASE}/bin/tc_pairs \ + tc_pairs \ -adeck aal032014.h4hw.dat suffix=_EXP \ -adeck aal032014_hfip_d2014_BERTHA.dat \ -bdeck bal032014.dat \ @@ -1753,7 +1750,7 @@ breaking the command up like the below example. .. code-block:: none - ['/h/WXQC/{MET_BUILD_BASE}/bin/regrid_data_plane', + ['regrid_data_plane', '/h/data/global/WXQC/data/umm/1701150006', 'G003', '/h/data/global/WXQC/data/met/nc_mdl/umm/1701150006', '- field', '\'name="HGT"; level="P500";\'', '-v', '6'] From ee4a3a4b725826f57a0060c4b0aa0aab20c8baca Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 14 Jan 2022 17:56:00 -0700 Subject: [PATCH 064/172] feature 2011 v10.1.0-beta5 (#2014) --- met/docs/Users_Guide/release-notes.rst | 21 +++++++++++++++++++++ met/docs/conf.py | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index eebd4f9e28..ac8a6bcd85 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -5,6 +5,27 @@ When applicable, release notes are followed by the GitHub issue number which describes the bugfix, enhancement, or new feature: `MET GitHub issues. `_ +MET Version 10.1.0-beta5 release notes (20220114) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Enhancements: + + * **Enhance GridStat to use OpenMP for efficient computation of neighborhood statistics by setting $OMP_NUM_THREADS** (`#1926 `_). + * **Enhance EnsembleStat and GenEnsProd to read all ensemble members from a single input file** (`#1695 `_). + * **Enhance TCGen to verify NHC tropical weather outlook shapefiles** (`#1810 `_). + * **Refine logic to prevent rounding shapefile points to the nearest grid point (affects GenVxMask -type shape masks)** (`#1810 `_). + * Enhance MADIS2NC to handle the 2016 updates to its format (`#1936 `_). + * Modify the interpretation of the message_type_group_map values to support the use of regular expressions (`#1974 `_). + * Address findings from the Cppcheck code analysis tool (`#1996 `_). + * Sort files read from directories to provide consistent behavior across platforms (`#1989 `_). + +* Bugfixes: + + * **Fix MTD to compute the CDIST_TRAVELLED value correctly** (`#1976 `_). + * Fix PointStat and GridStat to write VCNT output even if no VL1L2 or VAL1L2 output is requested (`#1991 `_). + * Fix GenVxMask to handle named grids and grid specification strings for -type grid (`#1993 `_). + * Fix IODA2NC to handle the same input file being provided multiple times (`#1965 `_). + MET Version 10.1.0-beta4 release notes (20211117) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/met/docs/conf.py b/met/docs/conf.py index c04f0ceeb3..775b1d88ea 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 = 'Halley Gotway, J., K. Newman, H. Soh, J. Opatz, T. Jensen, J. Prestopnik, L. Goodrich, D. Fillmore, B. Brown, R. Bullock, T. Fowler' -version = '10.1.0-beta4' +version = '10.1.0-beta5' verinfo = version release = f'{version}' -release_year = '2021' -release_date = f'{release_year}-11-17' +release_year = '2022' +release_date = f'{release_year}-01-14' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- From 18ccf3ad7f8585f381424770a0bfbd5f41beb00c Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 14 Jan 2022 21:08:33 -0700 Subject: [PATCH 065/172] feature 1695 fix issues with ensemble changes (#2012) Co-authored-by: John Halley Gotway Co-authored-by: John Halley Gotway --- .../tools/core/ensemble_stat/ensemble_stat.cc | 22 +++++--- .../tools/core/ensemble_stat/ensemble_stat.h | 4 +- .../ensemble_stat/ensemble_stat_conf_info.cc | 55 +++++++++++-------- .../tools/other/gen_ens_prod/gen_ens_prod.cc | 3 +- .../gen_ens_prod/gen_ens_prod_conf_info.cc | 10 +++- .../gen_ens_prod/gen_ens_prod_conf_info.h | 2 +- scripts/environment/development.seneca | 2 +- .../EnsembleStatConfig_single_file_grib | 8 +-- test/config/EnsembleStatConfig_single_file_nc | 36 ++++++------ test/xml/unit_ensemble_stat.xml | 12 +++- 10 files changed, 93 insertions(+), 61 deletions(-) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 0299932cf5..ac3ad664a6 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -62,7 +62,8 @@ // 031 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. // 032 10/07/21 Halley Gotway MET #1905 Add -ctrl option. -// 032 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. +// 033 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. +// 034 01/14/21 McCabe MET #1695 All members in one file. // //////////////////////////////////////////////////////////////////////// @@ -302,7 +303,7 @@ void process_command_line(int argc, char **argv) { // Copy ensemble file list to forecast file list fcst_file_list = ens_file_list; - // Prepend the control member, if specified + // Append the control member, if specified if(ctrl_file.nonempty()) { if(ens_file_list.has(ctrl_file) && n_ens_files != 1) { @@ -312,10 +313,9 @@ void process_command_line(int argc, char **argv) { exit(1); } - ctrl_index = 0; - - // Add control file to beginning of forecast file list - fcst_file_list.insert(ctrl_index, ctrl_file.c_str()); + // Add control member file to end of the forecast file list + fcst_file_list.add(ctrl_file.c_str()); + ctrl_file_index = fcst_file_list.n()-1; } // Check that the end_ut >= beg_ut @@ -948,8 +948,12 @@ void process_vx() { // Process masks Grids and Polylines in the config file conf_info.process_masks(grid); + // Determine the index of the control member in list of data values + int ctrl_data_index = (is_bad_data(ctrl_file_index) ? + bad_data_int : fcst_file_vld.sum()-1); + // Setup the PairDataEnsemble objects - conf_info.set_vx_pd(n_vx_vld, ctrl_index); + conf_info.set_vx_pd(n_vx_vld, ctrl_data_index); // Process the point observations if(point_obs_flag) process_point_vx(); @@ -1200,7 +1204,7 @@ int process_point_ens(int i_ens, int &n_miss) { mlog << Debug(2) << "\n" << sep_str << "\n\n" << "Processing " << file_type << " file: " << ens_file - << (i_ens == ctrl_index ? " (control)\n" : "\n"); + << (i_ens == ctrl_file_index ? " (control)\n" : "\n"); // Loop through each of the fields to be verified and extract // the forecast fields for verification @@ -2012,7 +2016,7 @@ void process_grid_scores(int i_vx, // Store the unperturbed ensemble value // Exclude the control member from the variance - if(j != ctrl_index) pd.add_ens_var_sums(i, fraw_dp[j](x, y)); + if(j != ctrl_file_index) pd.add_ens_var_sums(i, fraw_dp[j](x, y)); } } // end for j diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.h b/met/src/tools/core/ensemble_stat/ensemble_stat.h index 2cc02de2a1..482c0dfceb 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.h @@ -107,8 +107,8 @@ static bool ens_mean_flag; // Flag for ensemble mean processing static ConcatString ens_mean_user; // User-specified ensemble mean data file static ConcatString ens_mean_file; // Computed ensemble mean output file -static ConcatString ctrl_file; // Control member -static int ctrl_index = bad_data_int; // Control member index +static ConcatString ctrl_file; // Control member file +static int ctrl_file_index = bad_data_int; // Control member file index // Input Observation files static StringArray grid_obs_file_list; diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index 6db4407c39..85ed9581ca 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -212,6 +212,14 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, exit(1); } + // The control ID must be set when the control file is specified + if(control_id.empty() && use_ctrl) { + mlog << Error << "\nEnsembleStatConfInfo::process_config() -> " + << "the control_id must be set if processing a single input " + << "file with the -ctrl option\n\n"; + exit(1); + } + // If control ID is set, it cannot be found in ens_member_ids if(!control_id.empty() && ens_member_ids.has(control_id)) { mlog << Error << "\nEnsembleStatConfInfo::process_config() -> " @@ -323,6 +331,9 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, ens_input.push_back(ens_info); } // end for i + // Unset MET_ENS_MEMBER_ID that was previously set + unsetenv(met_ens_member_id); + // Conf: ens.ens_thresh vld_ens_thresh = conf.lookup_double(conf_key_ens_ens_thresh); @@ -757,7 +768,6 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, StringArray * fcst_files, bool use_ctrl, ConcatString control_id) { int i, j; - int file_index_start = 0; VarInfoFactory info_factory; mapoutput_map; Dictionary *dict; @@ -770,11 +780,11 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, // Allocate new EnsVarInfo object for fcst vx_pd.fcst_info = new EnsVarInfo(); - // Add control member as first input - if(use_ctrl) { + // Loop over ensemble member IDs to substitute + for(i=0; iadd_input(input_info); - // Change the starting index to the first non-control file - file_index_start = 1; - } + // Add InputInfo to fcst info list for each ensemble file provided + // set var_info to NULL to note first VarInfo should be used + int last_member_index = fcst_files->n() - (use_ctrl ? 1 : 0); + for(j=1; jadd_input(input_info); + } // end for j + } // end for i - // Loop over ensemble member IDs to substitute - for(i=0; iset_dict(fdict); input_info.var_info = next_var; - input_info.file_index = file_index_start; + input_info.file_index = fcst_files->n() - 1; input_info.file_list = fcst_files; vx_pd.fcst_info->add_input(input_info); - - // Add InputInfo to fcst info list for each ensemble file provided - // set var_info to NULL to note first VarInfo should be used - for(j=file_index_start+1; jn(); j++) { - input_info.var_info = NULL; - input_info.file_index = j; - input_info.file_list = fcst_files; - vx_pd.fcst_info->add_input(input_info); - } // end for j - - } // end for i + } // Allocate new VarInfo object for obs vx_pd.obs_info = info_factory.new_var_info(otype); diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 33d8351c8d..8fb7656e3d 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -16,6 +16,7 @@ // ---- ---- ---- ----------- // 000 09/10/21 Halley Gotway MET #1904 Initial version. // 001 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. +// 002 01/14/21 McCabe MET #1695 All members in one file. // //////////////////////////////////////////////////////////////////////// @@ -186,7 +187,7 @@ void process_command_line(int argc, char **argv) { etype = ens_mtddf->file_type(); // Process the configuration - conf_info.process_config(etype, &ens_files); + conf_info.process_config(etype, &ens_files, ctrl_file.nonempty()); // Allocate arrays to store threshold counts thresh_cnt_na = new NumArray [conf_info.get_max_n_cat()]; diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc index 96ee7be396..f085a20c24 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc @@ -100,7 +100,7 @@ void GenEnsProdConfInfo::read_config(const ConcatString default_file_name, //////////////////////////////////////////////////////////////////////// -void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_files) { +void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_files, bool use_ctrl) { int i, j; VarInfoFactory info_factory; Dictionary *edict = (Dictionary *) 0; @@ -146,6 +146,14 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_fil exit(1); } + // The control ID must be set when the control file is specified + if(control_id.empty() && use_ctrl) { + mlog << Error << "\nGenEnsProdConfInfo::process_config() -> " + << "the control_id must be set if processing a single input " + << "file with the -ctrl option\n\n"; + exit(1); + } + // If control ID is set, it cannot be found in ens_member_ids if(!control_id.empty() && ens_member_ids.has(control_id)) { mlog << Error << "\nGenEnsProdConfInfo::process_config() -> " diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h index 9510cc32b7..ae455daac7 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h @@ -99,7 +99,7 @@ class GenEnsProdConfInfo { void clear(); void read_config (const ConcatString, const ConcatString); - void process_config(GrdFileType, StringArray *); + void process_config(GrdFileType, StringArray *, bool); GenEnsProdNcOutInfo parse_nc_info(Dictionary *); diff --git a/scripts/environment/development.seneca b/scripts/environment/development.seneca index a535aeaa67..650257b3ab 100644 --- a/scripts/environment/development.seneca +++ b/scripts/environment/development.seneca @@ -27,7 +27,7 @@ export MET_PYTHON_CC="-I${MET_PYTHON}/include/python3.8" export MET_PYTHON_LD="-L${MET_PYTHON}/lib -lpython3.8 -lcrypt -lpthread -ldl -lutil -lm" # -D__64BIT__ is required because we've compiled libgrib2c.a with that flag -export CFLAGS="-DUNDERSCORE -fPIC -D__64BIT__" +export CFLAGS="-DUNDERSCORE -fPIC -D__64BIT__ -g" export CXXFLAGS=${CFLAGS} # Set LDFLAGS to include -rpath settings when compiling MET diff --git a/test/config/EnsembleStatConfig_single_file_grib b/test/config/EnsembleStatConfig_single_file_grib index cae96307fe..baf0c18c19 100644 --- a/test/config/EnsembleStatConfig_single_file_grib +++ b/test/config/EnsembleStatConfig_single_file_grib @@ -285,13 +285,13 @@ ensemble_flag = { latlon = TRUE; mean = TRUE; stdev = TRUE; - minus = TRUE; - plus = TRUE; + minus = FALSE; + plus = FALSE; min = TRUE; max = TRUE; - range = TRUE; + range = FALSE; vld_count = TRUE; - frequency = TRUE; + frequency = FALSE; nep = FALSE; nmep = FALSE; rank = TRUE; diff --git a/test/config/EnsembleStatConfig_single_file_nc b/test/config/EnsembleStatConfig_single_file_nc index 47ed145c44..610883a812 100644 --- a/test/config/EnsembleStatConfig_single_file_nc +++ b/test/config/EnsembleStatConfig_single_file_nc @@ -9,7 +9,7 @@ // // Output model name to be written // -model = "WRF"; +model = "CFS"; // // Output description to be written @@ -46,19 +46,26 @@ censor_val = []; cat_thresh = []; nc_var_str = ""; +// +// Override the NetCDF CFS variable names and times +// +file_type = NETCDF_NCCF; +set_attr_init = "19820101"; +set_attr_valid = "19820701"; +set_attr_name = "TMP"; +set_attr_level = "Z2"; + // // Ensemble product fields to be processed // ens = { - file_type = NETCDF_NCCF; ens_thresh = 1.0; vld_thresh = 1.0; field = [ { - name = "fcst"; - level = "(MET_ENS_MEMBER_ID,0,*,*)"; - cat_thresh = [ >0.0, >=5.0 ]; + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,6,*,*)"; } ]; } @@ -103,12 +110,10 @@ nmep_smooth = { // Forecast and observation fields to be verified // fcst = { - file_type = NETCDF_NCCF; field = [ { - name = "fcst"; - level = "(MET_ENS_MEMBER_ID,0,*,*)"; - cat_thresh = [ >0.0, >=5.0 ]; + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,6,*,*)"; } ]; } @@ -116,9 +121,8 @@ fcst = { obs = { field = [ { - name = "fcst"; - level = "(0,0,*,*)"; - cat_thresh = [ >0.0, >=5.0 ]; + name = "fcst"; + level = "(0,6,*,*)"; } ]; } @@ -283,13 +287,13 @@ ensemble_flag = { latlon = TRUE; mean = TRUE; stdev = TRUE; - minus = TRUE; - plus = TRUE; + minus = FALSE; + plus = FALSE; min = TRUE; max = TRUE; - range = TRUE; + range = FALSE; vld_count = TRUE; - frequency = TRUE; + frequency = FALSE; nep = FALSE; nmep = FALSE; rank = TRUE; diff --git a/test/xml/unit_ensemble_stat.xml b/test/xml/unit_ensemble_stat.xml index 034ff07cbf..93ec40b228 100644 --- a/test/xml/unit_ensemble_stat.xml +++ b/test/xml/unit_ensemble_stat.xml @@ -266,7 +266,9 @@ -outdir &OUTPUT_DIR;/ensemble_stat -v 1 - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_NO_CTRL_19700101_000000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_NO_CTRL_19820701_000000V.stat + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_NO_CTRL_19820701_000000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_NO_CTRL_19820701_000000V_orank.nc @@ -287,7 +289,9 @@ -outdir &OUTPUT_DIR;/ensemble_stat -v 1 - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_WITH_CTRL_19700101_000000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_WITH_CTRL_19820701_000000V.stat + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_WITH_CTRL_19820701_000000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_NC_WITH_CTRL_19820701_000000V_orank.nc @@ -307,7 +311,9 @@ -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_NO_CTRL_20160608_060000V.stat &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_NO_CTRL_20160608_060000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_NO_CTRL_20160608_060000V_orank.nc @@ -328,7 +334,9 @@ -outdir &OUTPUT_DIR;/ensemble_stat -v 1 + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_WITH_CTRL_20160608_060000V.stat &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_WITH_CTRL_20160608_060000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SINGLE_FILE_GRIB_WITH_CTRL_20160608_060000V_orank.nc From e9df2fc4b5773fa75448dfafef4c4a33ccf8700f Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Sun, 16 Jan 2022 10:46:01 -0700 Subject: [PATCH 066/172] Hotfix for #1695 committed directly to the develop branch. The new Ensemble-Stat config files added for this issue don't define a random number generator seed. This results in different output for each run and prevents the regression test from producing repeatable results. Defining the seed here to fix that. --- test/config/EnsembleStatConfig_python | 2 +- test/config/EnsembleStatConfig_single_file_grib | 2 +- test/config/EnsembleStatConfig_single_file_nc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/config/EnsembleStatConfig_python b/test/config/EnsembleStatConfig_python index 1e137fad3d..59ae439495 100644 --- a/test/config/EnsembleStatConfig_python +++ b/test/config/EnsembleStatConfig_python @@ -274,7 +274,7 @@ ensemble_flag = { // rng = { type = "mt19937"; - seed = ""; + seed = "1"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_single_file_grib b/test/config/EnsembleStatConfig_single_file_grib index baf0c18c19..76bb0bf3b5 100644 --- a/test/config/EnsembleStatConfig_single_file_grib +++ b/test/config/EnsembleStatConfig_single_file_grib @@ -305,7 +305,7 @@ ensemble_flag = { // rng = { type = "mt19937"; - seed = ""; + seed = "1"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_single_file_nc b/test/config/EnsembleStatConfig_single_file_nc index 610883a812..67bd0e3399 100644 --- a/test/config/EnsembleStatConfig_single_file_nc +++ b/test/config/EnsembleStatConfig_single_file_nc @@ -307,7 +307,7 @@ ensemble_flag = { // rng = { type = "mt19937"; - seed = ""; + seed = "1"; } //////////////////////////////////////////////////////////////////////////////// From 65539e111d10668adbfa782b73d82a40416e20ee Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 18 Jan 2022 09:24:25 -0700 Subject: [PATCH 067/172] Adding George to email list for the nightly build. --- scripts/regression/test_nightly.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/regression/test_nightly.sh b/scripts/regression/test_nightly.sh index 992981f702..96930bb30a 100755 --- a/scripts/regression/test_nightly.sh +++ b/scripts/regression/test_nightly.sh @@ -21,7 +21,7 @@ #======================================================================= # Constants -EMAIL_LIST="johnhg@ucar.edu hsoh@ucar.edu jpresto@ucar.edu linden@ucar.edu" +EMAIL_LIST="johnhg@ucar.edu hsoh@ucar.edu jpresto@ucar.edu linden@ucar.edu mccabe@ucar.edu" KEEP_DAYS=5 # Usage statement From 7c182317e0f0cdc128fc82cdc01667200d024ee4 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 20 Jan 2022 09:32:08 -0700 Subject: [PATCH 068/172] Fix the links for the met-10.1.0-beta5 release notes. --- met/docs/Users_Guide/release-notes.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index ac8a6bcd85..5cac6e7006 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -10,21 +10,21 @@ MET Version 10.1.0-beta5 release notes (20220114) * Enhancements: - * **Enhance GridStat to use OpenMP for efficient computation of neighborhood statistics by setting $OMP_NUM_THREADS** (`#1926 `_). - * **Enhance EnsembleStat and GenEnsProd to read all ensemble members from a single input file** (`#1695 `_). - * **Enhance TCGen to verify NHC tropical weather outlook shapefiles** (`#1810 `_). - * **Refine logic to prevent rounding shapefile points to the nearest grid point (affects GenVxMask -type shape masks)** (`#1810 `_). - * Enhance MADIS2NC to handle the 2016 updates to its format (`#1936 `_). - * Modify the interpretation of the message_type_group_map values to support the use of regular expressions (`#1974 `_). - * Address findings from the Cppcheck code analysis tool (`#1996 `_). - * Sort files read from directories to provide consistent behavior across platforms (`#1989 `_). + * **Enhance GridStat to use OpenMP for efficient computation of neighborhood statistics by setting $OMP_NUM_THREADS** (`#1926 `_). + * **Enhance EnsembleStat and GenEnsProd to read all ensemble members from a single input file** (`#1695 `_). + * **Enhance TCGen to verify NHC tropical weather outlook shapefiles** (`#1810 `_). + * **Refine logic to prevent rounding shapefile points to the nearest grid point (affects GenVxMask -type shape masks)** (`#1810 `_). + * Enhance MADIS2NC to handle the 2016 updates to its format (`#1936 `_). + * Modify the interpretation of the message_type_group_map values to support the use of regular expressions (`#1974 `_). + * Address findings from the Cppcheck code analysis tool (`#1996 `_). + * Sort files read from directories to provide consistent behavior across platforms (`#1989 `_). * Bugfixes: - * **Fix MTD to compute the CDIST_TRAVELLED value correctly** (`#1976 `_). - * Fix PointStat and GridStat to write VCNT output even if no VL1L2 or VAL1L2 output is requested (`#1991 `_). - * Fix GenVxMask to handle named grids and grid specification strings for -type grid (`#1993 `_). - * Fix IODA2NC to handle the same input file being provided multiple times (`#1965 `_). + * **Fix MTD to compute the CDIST_TRAVELLED value correctly** (`#1976 `_). + * Fix PointStat and GridStat to write VCNT output even if no VL1L2 or VAL1L2 output is requested (`#1991 `_). + * Fix GenVxMask to handle named grids and grid specification strings for -type grid (`#1993 `_). + * Fix IODA2NC to handle the same input file being provided multiple times (`#1965 `_). MET Version 10.1.0-beta4 release notes (20211117) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From b8e0de3ce3a208d8fbded5e912f7c60c7ca6726c Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Fri, 21 Jan 2022 11:31:48 -0700 Subject: [PATCH 069/172] #1844 Make met_point_obs as abstract class --- met/scripts/python/met_point_obs.py | 358 ++++++++++++----------- met/scripts/python/read_met_point_obs.py | 107 +++---- 2 files changed, 237 insertions(+), 228 deletions(-) diff --git a/met/scripts/python/met_point_obs.py b/met/scripts/python/met_point_obs.py index b4e1e59e30..c306839226 100755 --- a/met/scripts/python/met_point_obs.py +++ b/met/scripts/python/met_point_obs.py @@ -1,169 +1,189 @@ -''' -Created on Nov 10, 2021 - -@author: hsoh -''' - - -import numpy as np - -COUNT_SHOW = 30 - -MET_PYTHON_OBS_ARGS = "MET_POINT_PYTHON_ARGS" - -class met_point_obs(object): - ''' - classdocs - ''' - python_prefix = 'PYTHON_POINT_RAW' - - def __init__(self, use_var_id=True): - ''' - Constructor - ''' - self.raw_data = None - self.use_var_id = use_var_id # True if variable index, False if GRIB code - - # Header - self.nhdr = 0 - self.npbhdr = 0 - self.nhdr_typ = 0 # type table - self.nhdr_sid = 0 #station_uid table - self.nhdr_vld = 0 # valid time strings - self.hdr_typ = [] # (nhdr) - self.hdr_sid = [] # (nhdr) - self.hdr_vld = [] # (nhdr) - self.hdr_lat = [] # (nhdr) - self.hdr_lon = [] # (nhdr) - self.hdr_elv = [] # (nhdr) - self.hdr_typ_table = [] # (nhdr_typ, mxstr2) - self.hdr_sid_table = [] # (nhdr_sid, mxstr2) - self.hdr_vld_table = [] # (nhdr_vld, mxstr) - self.hdr_prpt_typ = [] # optional - self.hdr_irpt_typ = [] # optional - self.hdr_inst_typ = [] # optional - - #Observation data - self.nobs = 0 - self.nobs_qty = 0 - self.nobs_var = 0 - self.obs_qty = [] # (nobs_qty ) - self.obs_hid = [] # (nobs) - self.obs_vid = [] # (nobs) veriable index or GRIB code - self.obs_lvl = [] # (nobs) - self.obs_hgt = [] # (nobs) - self.obs_val = [] # (nobs) - self.obs_qty_table = [] # (nobs_qty, mxstr) - self.obs_var_table = [] # (nobs_var, mxstr2) optional if GRIB code at self.obs_vid - - #def convert(self): - # pass - - def get_point_data(self): - if self.nhdr <= 0: - self.nhdr = len(self.hdr_lat) - if self.nobs <= 0: - self.nobs = len(self.obs_val) - if self.nhdr_typ <= 0: - self.nhdr_typ = len(self.hdr_typ_table) - if self.nhdr_sid <= 0: - self.nhdr_sid = len(self.hdr_sid_table) - if self.nhdr_vld <= 0: - self.nhdr_vld = len(self.hdr_vld_table) - if self.npbhdr <= 0: - self.npbhdr = len(self.hdr_prpt_typ) - if self.nobs_qty <= 0: - self.nobs_qty = len(self.obs_qty_table) - if self.nobs_var <= 0: - self.nobs_var = len(self.obs_var_table) - return self.__dict__ - - @staticmethod - def is_python_script(arg_value): - return arg_value.startswith(met_point_obs.python_prefix) - - @staticmethod - def get_python_script(arg_value): - return arg_value[len(met_point_obs.python_prefix)+1:] - - @staticmethod - def print_data(key, data_array, show_count=COUNT_SHOW): - if isinstance(data_array, list): - data_len = len(data_array) - if show_count >= data_len: - print(" {k:10s}: {v}".format(k=key, v= data_array)) - else: - end_offset = int(show_count/2) - print(" {k:10s}: count={v}".format(k=key, v=data_len)) - print(" {k:10s}[0:{o}] {v}".format(k=key, v=data_array[:end_offset], o=end_offset)) - print(" {k:10s}[{s}:{e}]: {v}".format(k=key, v='...', s=end_offset+1, e=data_len-end_offset-1)) - print(" {k:10s}[{s}:{e}]: {v}".format(k=key, v= data_array[-end_offset:], s=(data_len-end_offset), e=(data_len-1))) - else: - print(" {k:10s}: {v}".format(k=key, v= data_array)) - - @staticmethod - def print_point_data(met_point_data): - print(' === MET point data by python embedding ===') - met_point_obs.print_data('nhdr', met_point_data['nhdr']) - met_point_obs.print_data('nobs' , met_point_data['nobs']) - met_point_obs.print_data('use_var_id',met_point_data['use_var_id']) - met_point_obs.print_data('hdr_typ',met_point_data['hdr_typ']) - met_point_obs.print_data('obs_hid',met_point_data['obs_hid']) - met_point_obs.print_data('obs_vid',met_point_data['obs_vid']) - met_point_obs.print_data('obs_val',met_point_data['obs_val']) - met_point_obs.print_data('obs_var_table',met_point_data['obs_var_table']) - met_point_obs.print_data('obs_qty_table',met_point_data['obs_qty_table']) - met_point_obs.print_data('hdr_typ_table',met_point_data['hdr_typ_table']) - met_point_obs.print_data('hdr_sid_table',met_point_data['hdr_sid_table']) - met_point_obs.print_data('hdr_vld_table',met_point_data['hdr_vld_table']) - print(' === MET point data by python embedding ===') - - -def get_sample_point_obs(): - point_obs_data = met_point_obs() - point_obs_data.hdr_typ = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) - point_obs_data.hdr_sid = np.array([ 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 2, 2, 3 ]) - point_obs_data.hdr_vld = np.array([ 0, 1, 2, 3, 4, 4, 3, 4, 3, 4, 5, 4, 3, 0, 1, 2, 3, 4, 4, 3, 4, 3, 4, 5, 4, 3 ]) - point_obs_data.hdr_lat = np.array([ 43., 43., 43., 43., 43., 43., 43., 43., 43., 46., 46., 46., 46., 43., 43., 43., 43., 43., 43., 43., 43., 43., 46., 46., 46., 46. ]) - point_obs_data.hdr_lon = np.array([ -89., -89., -89., -89., -89., -89., -89., -89., -89., -92., -92., -92., -92., -89., -89., -89., -89., -89., -89., -89., -89., -89., -92., -92., -92., -92. ]) - point_obs_data.hdr_elv = np.array([ 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220. ]) - - point_obs_data.obs_qid = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) - point_obs_data.obs_hid = np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25 ]) - point_obs_data.obs_vid = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]) - point_obs_data.obs_lvl = np.array([ 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000. ]) - point_obs_data.obs_hgt = np.array([ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2. ]) - point_obs_data.obs_val = np.array([ 292., 292.5, 293., 293.5, 294., 294.5, 295., 295.5, 296., 292., 293.4, 293., 296., 294., 92., 92.5, 93., 93.5, 94., 94.5, 95., 95.5, 96., 92., 93.4, 93., 96., 94. ]) - - point_obs_data.hdr_typ_table = [ "ADPSFC" ] - point_obs_data.hdr_sid_table = [ "001", "002", "003", "004" ] - point_obs_data.hdr_vld_table = [ - "20120409_115000", "20120409_115500", "20120409_120100", "20120409_120500", "20120409_121000", - "20120409_120000" ] - point_obs_data.obs_var_table = [ "TMP", "RH" ] - point_obs_data.obs_qty_table = [ "NA" ] - point_obs_data.nhdr = len(point_obs_data.hdr_lat) - point_obs_data.nobs = len(point_obs_data.obs_val) - #point_obs_data.met_point_data = point_obs_data - return point_obs_data - - -def main(): - met_point_data = get_sample_point_obs().get_point_data() - - print('All',met_point_data) - print(" nhdr: ",met_point_data['nhdr']) - print(" nobs: ",met_point_data['nobs']) - print('use_var_id: ',met_point_data['use_var_id']) - print('hdr_typ: ',met_point_data['hdr_typ']) - print('obs_vid: ',met_point_data['obs_vid']) - print('obs_val: ',met_point_data['obs_val']) - print('obs_var_table: ',met_point_data['obs_var_table']) - print('obs_qty_table: ',met_point_data['obs_qty_table']) - print('hdr_typ_table: ',met_point_data['hdr_typ_table']) - print('hdr_sid_table: ',met_point_data['hdr_sid_table']) - print('hdr_vld_table: ',met_point_data['hdr_vld_table']) - print('Done python scripot') - -if __name__ == '__main__': - main() +''' +Created on Nov 10, 2021 + +@author: hsoh + +- This is the base class and the customized script should extend the met_point_obs. +- The customized script (for example "custom_reader") must implement "def read_data(self, args)" + which fills the array (list) variables at __init__(). +- The args can be 1) single string argument, 2) the list of arguments, and 3) the dictionary of arguments. +- The variable "met_point_data" must be set for MET tools +- The customized script is expected to include following codes: + + # prepare arguments for the customized script + args = {'input', sys.argv[1]} # or args = [] + point_obs_data = custom_reader() + point_obs_data.read_data() + met_point_data = point_obs_data.get_point_data() +''' + +from abc import ABC, abstractmethod +import numpy as np + +COUNT_SHOW = 30 + +MET_PYTHON_OBS_ARGS = "MET_POINT_PYTHON_ARGS" + +class met_point_obs(ABC): + ''' + classdocs + ''' + + python_prefix = 'PYTHON_POINT_RAW' + + def __init__(self, use_var_id=True): + ''' + Constructor + ''' + self.use_var_id = use_var_id # True if variable index, False if GRIB code + + # Header + self.nhdr = 0 + self.npbhdr = 0 + self.nhdr_typ = 0 # type table + self.nhdr_sid = 0 #station_uid table + self.nhdr_vld = 0 # valid time strings + self.hdr_typ = [] # (nhdr) + self.hdr_sid = [] # (nhdr) + self.hdr_vld = [] # (nhdr) + self.hdr_lat = [] # (nhdr) + self.hdr_lon = [] # (nhdr) + self.hdr_elv = [] # (nhdr) + self.hdr_typ_table = [] # (nhdr_typ, mxstr2) + self.hdr_sid_table = [] # (nhdr_sid, mxstr2) + self.hdr_vld_table = [] # (nhdr_vld, mxstr) + self.hdr_prpt_typ = [] # optional + self.hdr_irpt_typ = [] # optional + self.hdr_inst_typ = [] # optional + + #Observation data + self.nobs = 0 + self.nobs_qty = 0 + self.nobs_var = 0 + self.obs_qty = [] # (nobs_qty ) + self.obs_hid = [] # (nobs) + self.obs_vid = [] # (nobs) veriable index or GRIB code + self.obs_lvl = [] # (nobs) + self.obs_hgt = [] # (nobs) + self.obs_val = [] # (nobs) + self.obs_qty_table = [] # (nobs_qty, mxstr) + self.obs_var_table = [] # (nobs_var, mxstr2) optional if GRIB code at self.obs_vid + + @abstractmethod + def read_data(self, args): + # args should be list or dictionary + pass + + def get_point_data(self): + if self.nhdr <= 0: + self.nhdr = len(self.hdr_lat) + if self.nobs <= 0: + self.nobs = len(self.obs_val) + if self.nhdr_typ <= 0: + self.nhdr_typ = len(self.hdr_typ_table) + if self.nhdr_sid <= 0: + self.nhdr_sid = len(self.hdr_sid_table) + if self.nhdr_vld <= 0: + self.nhdr_vld = len(self.hdr_vld_table) + if self.npbhdr <= 0: + self.npbhdr = len(self.hdr_prpt_typ) + if self.nobs_qty <= 0: + self.nobs_qty = len(self.obs_qty_table) + if self.nobs_var <= 0: + self.nobs_var = len(self.obs_var_table) + return self.__dict__ + + @staticmethod + def is_python_script(arg_value): + return arg_value.startswith(met_point_obs.python_prefix) + + @staticmethod + def get_python_script(arg_value): + return arg_value[len(met_point_obs.python_prefix)+1:] + + @staticmethod + def print_data(key, data_array, show_count=COUNT_SHOW): + if isinstance(data_array, list): + data_len = len(data_array) + if show_count >= data_len: + print(" {k:10s}: {v}".format(k=key, v= data_array)) + else: + end_offset = int(show_count/2) + print(" {k:10s}: count={v}".format(k=key, v=data_len)) + print(" {k:10s}[0:{o}] {v}".format(k=key, v=data_array[:end_offset], o=end_offset)) + print(" {k:10s}[{s}:{e}]: {v}".format(k=key, v='...', s=end_offset+1, e=data_len-end_offset-1)) + print(" {k:10s}[{s}:{e}]: {v}".format(k=key, v= data_array[-end_offset:], s=(data_len-end_offset), e=(data_len-1))) + else: + print(" {k:10s}: {v}".format(k=key, v= data_array)) + + @staticmethod + def print_point_data(met_point_data, print_subset=True): + print(' === MET point data by python embedding ===') + if print_subset: + met_point_obs.print_data('nhdr', met_point_data['nhdr']) + met_point_obs.print_data('nobs' , met_point_data['nobs']) + met_point_obs.print_data('use_var_id',met_point_data['use_var_id']) + met_point_obs.print_data('hdr_typ',met_point_data['hdr_typ']) + met_point_obs.print_data('obs_hid',met_point_data['obs_hid']) + met_point_obs.print_data('obs_vid',met_point_data['obs_vid']) + met_point_obs.print_data('obs_val',met_point_data['obs_val']) + met_point_obs.print_data('obs_var_table',met_point_data['obs_var_table']) + met_point_obs.print_data('obs_qty_table',met_point_data['obs_qty_table']) + met_point_obs.print_data('hdr_typ_table',met_point_data['hdr_typ_table']) + met_point_obs.print_data('hdr_sid_table',met_point_data['hdr_sid_table']) + met_point_obs.print_data('hdr_vld_table',met_point_data['hdr_vld_table']) + else: + print('All',met_point_data) + print(" nhdr: ",met_point_data['nhdr']) + print(" nobs: ",met_point_data['nobs']) + print('use_var_id: ',met_point_data['use_var_id']) + print('hdr_typ: ',met_point_data['hdr_typ']) + print('obs_vid: ',met_point_data['obs_vid']) + print('obs_val: ',met_point_data['obs_val']) + print('obs_var_table: ',met_point_data['obs_var_table']) + print('obs_qty_table: ',met_point_data['obs_qty_table']) + print('hdr_typ_table: ',met_point_data['hdr_typ_table']) + print('hdr_sid_table: ',met_point_data['hdr_sid_table']) + print('hdr_vld_table: ',met_point_data['hdr_vld_table']) + print(' === MET point data by python embedding ===') + + +# This is a sample drived class +class sample_met_point_obs(met_point_obs): + + #@abstractmethod + def read_data(self, arg_map={}): + self.hdr_typ = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) + self.hdr_sid = np.array([ 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 2, 2, 3 ]) + self.hdr_vld = np.array([ 0, 1, 2, 3, 4, 4, 3, 4, 3, 4, 5, 4, 3, 0, 1, 2, 3, 4, 4, 3, 4, 3, 4, 5, 4, 3 ]) + self.hdr_lat = np.array([ 43., 43., 43., 43., 43., 43., 43., 43., 43., 46., 46., 46., 46., 43., 43., 43., 43., 43., 43., 43., 43., 43., 46., 46., 46., 46. ]) + self.hdr_lon = np.array([ -89., -89., -89., -89., -89., -89., -89., -89., -89., -92., -92., -92., -92., -89., -89., -89., -89., -89., -89., -89., -89., -89., -92., -92., -92., -92. ]) + self.hdr_elv = np.array([ 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220., 220. ]) + + self.obs_qid = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) + self.obs_hid = np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25 ]) + self.obs_vid = np.array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]) + self.obs_lvl = np.array([ 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000. ]) + self.obs_hgt = np.array([ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2. ]) + self.obs_val = np.array([ 292., 292.5, 293., 293.5, 294., 294.5, 295., 295.5, 296., 292., 293.4, 293., 296., 294., 92., 92.5, 93., 93.5, 94., 94.5, 95., 95.5, 96., 92., 93.4, 93., 96., 94. ]) + + self.hdr_typ_table = [ "ADPSFC" ] + self.hdr_sid_table = [ "001", "002", "003", "004" ] + self.hdr_vld_table = [ + "20120409_115000", "20120409_115500", "20120409_120100", "20120409_120500", "20120409_121000", + "20120409_120000" ] + self.obs_var_table = [ "TMP", "RH" ] + self.obs_qty_table = [ "NA" ] + + +def main(): + args = {} # or args = [] + point_obs_data = sample_met_point_obs() + point_obs_data.read_data(args) + met_point_data = point_obs_data.get_point_data() + + point_obs_data.print_point_data(met_point_data, print_subset=False) + +if __name__ == '__main__': + main() + print('Done python scripot') diff --git a/met/scripts/python/read_met_point_obs.py b/met/scripts/python/read_met_point_obs.py index 5a99f63a8e..15667541ec 100755 --- a/met/scripts/python/read_met_point_obs.py +++ b/met/scripts/python/read_met_point_obs.py @@ -2,6 +2,8 @@ Created on Nov 10, 2021 @author: hsoh + +This script reads the MET point observation NetCDF file like MET tools do. ''' import os @@ -10,35 +12,26 @@ import numpy as np import netCDF4 as nc -from met_point_obs import met_point_obs, get_sample_point_obs, MET_PYTHON_OBS_ARGS +from met_point_obs import met_point_obs, sample_met_point_obs DO_PRINT_DATA = False ARG_PRINT_DATA = 'show_data' class nc_point_obs(met_point_obs): - @staticmethod - def get_num_array(dataset, var_name): - nc_var = dataset.variables.get(var_name, None) - return nc_var[:].filled(nc_var._FillValue if '_FillValue' in nc_var.ncattrs() else -9999) if nc_var else [] - - @staticmethod - def get_ncbyte_array_to_str(nc_var): - nc_str_data = nc_var[:] - if nc_var.datatype.name == 'bytes8': - nc_str_data = [ str(s.compressed(),"utf-8") for s in nc_var[:]] - return nc_str_data - - @staticmethod - def get_string_array(dataset, var_name): - nc_var = dataset.variables.get(var_name, None) - return nc_point_obs.get_ncbyte_array_to_str(nc_var) if nc_var else [] - - #def convert(self): - # pass - - def read_nectdf(self, nc_filename): - if os.path.exists(nc_filename): + def read_data(self, args): + # args should be list or dictionaryu + if isinstance(args, dict): + nc_filename = args.get('nc_name',None) + elif isinstance(args, list): + nc_filename = args[0] + else: + nc_filename = args + if nc_filename is None: + print("==ERROR== The input NetCDF filename is missing") + elif not os.path.exists(nc_filename): + print("==ERROR== input NetCDF file ({f}) does not exist".format(f=nc_filename)) + else: dataset = nc.Dataset(nc_filename, 'r') # Header self.hdr_typ = dataset['hdr_typ'][:] @@ -47,10 +40,10 @@ def read_nectdf(self, nc_filename): self.hdr_lat = dataset['hdr_lat'][:] self.hdr_lon = dataset['hdr_lon'][:] self.hdr_elv = dataset['hdr_elv'][:] - self.hdr_typ_table = self.get_string_array(dataset, 'hdr_typ_table') - self.hdr_sid_table = self.get_string_array(dataset, 'hdr_sid_table') - self.hdr_vld_table = self.get_string_array(dataset, 'hdr_vld_table') - + self.hdr_typ_table = nc_tools.get_string_array(dataset, 'hdr_typ_table') + self.hdr_sid_table = nc_tools.get_string_array(dataset, 'hdr_sid_table') + self.hdr_vld_table = nc_tools.get_string_array(dataset, 'hdr_vld_table') + nc_var = dataset.variables.get('hdr_prpt_typ', None) if nc_var: self.hdr_prpt_typ = nc_var[:] @@ -62,9 +55,7 @@ def read_nectdf(self, nc_filename): self.hdr_inst_typ =nc_var[:] #Observation data - self.nobs = 0 self.hdr_sid = dataset['hdr_sid'][:] - #self.obs_qty = self.get_num_array(dataset, 'obs_qty') self.obs_qty = np.array(dataset['obs_qty'][:]) self.obs_hid = np.array(dataset['obs_hid'][:]) self.obs_lvl = np.array(dataset['obs_lvl'][:]) @@ -75,16 +66,31 @@ def read_nectdf(self, nc_filename): self.use_var_id = False nc_var = dataset.variables.get('obs_gc', None) else: - self.obs_var_table = self.get_string_array(dataset, 'obs_var') + self.obs_var_table = nc_tools.get_string_array(dataset, 'obs_var') if nc_var: self.obs_vid = np.array(nc_var[:]) - self.obs_qty_rwo = dataset['obs_qty'][:] + self.obs_qty_table = nc_tools.get_string_array(dataset, 'obs_qty_table') - self.obs_qty_table = self.get_string_array(dataset, 'obs_qty_table') - else: - print("==ERROR== netcdf file ({f}) does not exist".format(f=nc_filename)) - + +class nc_tools(): + + @staticmethod + def get_num_array(dataset, var_name): + nc_var = dataset.variables.get(var_name, None) + return nc_var[:].filled(nc_var._FillValue if '_FillValue' in nc_var.ncattrs() else -9999) if nc_var else [] + + @staticmethod + def get_ncbyte_array_to_str(nc_var): + nc_str_data = nc_var[:] + if nc_var.datatype.name == 'bytes8': + nc_str_data = [ str(s.compressed(),"utf-8") for s in nc_var[:]] + return nc_str_data + + @staticmethod + def get_string_array(dataset, var_name): + nc_var = dataset.variables.get(var_name, None) + return nc_tools.get_ncbyte_array_to_str(nc_var) if nc_var else [] perf_start_time = time.time() @@ -92,34 +98,17 @@ def read_nectdf(self, nc_filename): point_obs_data = None if len(sys.argv) == 1: - point_obs_data = get_sample_point_obs() + point_obs_data = sample_met_point_obs() + point_obs_data.read_data([]) else: netcdf_filename = sys.argv[1] - if os.path.exists(netcdf_filename): - point_obs_data = nc_point_obs() - point_obs_data.read_nectdf(netcdf_filename) - elif met_point_obs.is_python_script(netcdf_filename): - python_script = met_point_obs.get_python_script(netcdf_filename) - python_args = [] - if len(sys.argv) > 2: - if ARG_PRINT_DATA == sys.argv[-1]: - python_args = sys.argv[2:-1] - else: - python_args = sys.argv[2:] - python_args_string = " ".join(python_args) if 0 < len(python_args) else '' - os.environ[MET_PYTHON_OBS_ARGS] = python_args_string - #os.system(python_command) - exec(open(python_script).read()) - print('------') - - if point_obs_data is None: - print("PYTHON: Fail to get point_obs_data by calling {s} from {m}".format( - s=python_script, m=sys.argv[0])) + args = [ netcdf_filename ] + #args = { 'nc_name': netcdf_filename } + point_obs_data = nc_point_obs() + point_obs_data.read_data(args) + if ARG_PRINT_DATA == sys.argv[-1]: DO_PRINT_DATA = True - - point_obs_data = nc_point_obs() - point_obs_data.read_nectdf(netcdf_filename) if point_obs_data is not None: met_point_data = point_obs_data.get_point_data() From 29d479f02b9c9fa79807405a77f11666eaf388a6 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Fri, 21 Jan 2022 11:32:47 -0700 Subject: [PATCH 070/172] #1844 correctedb for loop end condition on processing obs bdata --- met/src/tools/core/ensemble_stat/ensemble_stat.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 14fd5c7b0e..29e62d0b72 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -1164,7 +1164,7 @@ void process_point_obs(int i_nc) { if (!status) exit(1); // Process each observation in the file - for(int i_offset=0; i_offset Date: Mon, 24 Jan 2022 16:03:17 -0700 Subject: [PATCH 071/172] Feature 1546 unit_tests (#2021) --- test/bin/unit_test.sh | 7 +- test/config/PlotModeFieldConfig | 2 +- test/xml/unit_aeronet.xml | 2 + test/xml/unit_airnow.xml | 2 + test/xml/unit_ascii2nc.xml | 10 ++- test/xml/unit_climatology.xml | 3 +- test/xml/unit_duplicate_flag.xml | 16 ++-- test/xml/unit_ensemble_stat.xml | 25 +++--- test/xml/unit_gaussian.xml | 3 +- test/xml/unit_gen_ens_prod.xml | 5 +- test/xml/unit_gen_vx_mask.xml | 2 + ...t_grib_tables.xml => unit_grib_tables.xml} | 18 +++-- test/xml/unit_grid_diag.xml | 2 + test/xml/unit_grid_stat.xml | 2 + test/xml/unit_grid_weight.xml | 2 + test/xml/unit_gsi_tools.xml | 52 ++++++------ test/xml/unit_hira.xml | 2 + test/xml/unit_interp_shape.xml | 2 + test/xml/unit_ioda2nc.xml | 41 +--------- test/xml/unit_lidar2nc.xml | 2 + test/xml/unit_madis2nc.xml | 2 + test/xml/unit_met_test_scripts.xml | 2 + test/xml/unit_mode.xml | 36 +-------- test/xml/unit_mode_analysis.xml | 4 +- test/xml/unit_mode_graphics.xml | 49 +----------- test/xml/unit_modis.xml | 2 + test/xml/unit_mtd.xml | 2 + test/xml/unit_netcdf.xml | 4 +- test/xml/unit_obs_summary.xml | 80 +++++++++---------- test/xml/unit_pb2nc.xml | 2 + test/xml/unit_pcp_combine.xml | 15 ++++ test/xml/unit_perc_thresh.xml | 2 + test/xml/unit_plot_data_plane.xml | 4 +- test/xml/unit_plot_point_obs.xml | 3 +- test/xml/unit_plot_tc.xml | 4 +- test/xml/unit_point2grid.xml | 6 +- test/xml/unit_point_stat.xml | 2 + test/xml/unit_python.xml | 4 +- test/xml/unit_quality_filter.xml | 29 +++---- test/xml/unit_ref_config.xml | 2 + test/xml/unit_regrid.xml | 2 + test/xml/unit_rmw_analysis.xml | 2 + test/xml/unit_series_analysis.xml | 2 + test/xml/unit_shift_data_plane.xml | 2 + test/xml/unit_stat_analysis.xml | 6 +- test/xml/unit_tc_dland.xml | 2 + test/xml/unit_tc_gen.xml | 2 + test/xml/unit_tc_pairs.xml | 2 + test/xml/unit_tc_rmw.xml | 2 + test/xml/unit_tc_stat.xml | 2 + test/xml/unit_trmm2nc.xml | 2 + test/xml/unit_wavelet_stat.xml | 2 + test/xml/unit_wwmca_plot.xml | 2 + test/xml/unit_wwmca_regrid.xml | 2 + 54 files changed, 234 insertions(+), 252 deletions(-) rename test/xml/{unit_test_grib_tables.xml => unit_grib_tables.xml} (77%) diff --git a/test/bin/unit_test.sh b/test/bin/unit_test.sh index 5e48e3bb44..fd1c7149cb 100755 --- a/test/bin/unit_test.sh +++ b/test/bin/unit_test.sh @@ -19,6 +19,11 @@ else echo "export MET_TEST_OUTPUT=${MET_TEST_OUTPUT}" fi +# if MET_TEST_MET_PYTHON_EXE is not set, use default value +if [[ -z "${MET_TEST_MET_PYTHON_EXE}" ]] ; then + export MET_TEST_MET_PYTHON_EXE=/usr/local/python3/bin/python3 +fi + PERL_UNIT_OPTS="" for arg in $@; do [ $arg == "-memchk" -o $arg == "memchk" ] && PERL_UNIT_OPTS="$PERL_UNIT_OPTS -memchk" @@ -67,7 +72,7 @@ UNIT_XML="unit_ascii2nc.xml \ unit_shift_data_plane.xml \ unit_mtd.xml \ unit_climatology.xml \ - unit_test_grib_tables.xml \ + unit_grib_tables.xml \ unit_grid_weight.xml \ unit_netcdf.xml \ unit_hira.xml \ diff --git a/test/config/PlotModeFieldConfig b/test/config/PlotModeFieldConfig index f6915f4c4a..816535ff25 100644 --- a/test/config/PlotModeFieldConfig +++ b/test/config/PlotModeFieldConfig @@ -9,7 +9,7 @@ plot_info = { - output_directory = "${MET_TEST_OUTPUT}/plot_mode_field"; + output_directory = "${MET_TEST_OUTPUT}/mode_graphics"; size = 4; diff --git a/test/xml/unit_aeronet.xml b/test/xml/unit_aeronet.xml index 4d1fd80ec5..0892c623ad 100644 --- a/test/xml/unit_aeronet.xml +++ b/test/xml/unit_aeronet.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_airnow.xml b/test/xml/unit_airnow.xml index 9c616e5872..9afa68d292 100644 --- a/test/xml/unit_airnow.xml +++ b/test/xml/unit_airnow.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_ascii2nc.xml b/test/xml/unit_ascii2nc.xml index 2edb2bf9b7..11c46a3ea5 100644 --- a/test/xml/unit_ascii2nc.xml +++ b/test/xml/unit_ascii2nc.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; @@ -68,11 +70,11 @@ &MET_BIN;/ascii2nc \ &DATA_DIR_OBS;/ascii/qc_out_2012-09-07_00:00:00.GRM_P+FCST \ - &OUTPUT_DIR;/ascii2nc/qc_out_2012-09-07_00:00:00.GRM_P+FCST.nc \ + &OUTPUT_DIR;/ascii2nc/qc_out_2012-09-07_00:00:00.GRM_P_FCST.nc \ -v 1 - &OUTPUT_DIR;/ascii2nc/qc_out_2012-09-07_00:00:00.GRM_P+FCST.nc + &OUTPUT_DIR;/ascii2nc/qc_out_2012-09-07_00:00:00.GRM_P_FCST.nc @@ -80,11 +82,11 @@ &MET_BIN;/ascii2nc \ &DATA_DIR_OBS;/ascii/OBS:2015080700_bad_record \ - &OUTPUT_DIR;/ascii2nc/OBS:2015080700_bad_record.nc \ + &OUTPUT_DIR;/ascii2nc/OBS_2015080700_bad_record.nc \ -v 1 - &OUTPUT_DIR;/ascii2nc/OBS:2015080700_bad_record.nc + &OUTPUT_DIR;/ascii2nc/OBS_2015080700_bad_record.nc diff --git a/test/xml/unit_climatology.xml b/test/xml/unit_climatology.xml index c3a946072e..d50dc86ccf 100644 --- a/test/xml/unit_climatology.xml +++ b/test/xml/unit_climatology.xml @@ -11,12 +11,13 @@ ]> + + &TEST_DIR; true - &MET_BIN;/point_stat diff --git a/test/xml/unit_duplicate_flag.xml b/test/xml/unit_duplicate_flag.xml index 51de6cecc0..dcd287f59b 100644 --- a/test/xml/unit_duplicate_flag.xml +++ b/test/xml/unit_duplicate_flag.xml @@ -10,9 +10,9 @@ ]> - + - + &TEST_DIR; false @@ -27,11 +27,11 @@ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ &OUTPUT_DIR;/ascii2nc/dup_test.nc \ &CONFIG_DIR;/PointStatConfig_dup \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/duplicate_flag -v 3 - &OUTPUT_DIR;/point_stat/point_stat_DUP_NONE_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_DUP_NONE_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/duplicate_flag/point_stat_DUP_NONE_120000L_20120409_120000V.stat + &OUTPUT_DIR;/duplicate_flag/point_stat_DUP_NONE_120000L_20120409_120000V_mpr.txt @@ -45,11 +45,11 @@ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ &OUTPUT_DIR;/ascii2nc/dup_test.nc \ &CONFIG_DIR;/PointStatConfig_dup \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/duplicate_flag -v 3 - &OUTPUT_DIR;/point_stat/point_stat_DUP_UNIQUE_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_DUP_UNIQUE_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/duplicate_flag/point_stat_DUP_UNIQUE_120000L_20120409_120000V.stat + &OUTPUT_DIR;/duplicate_flag/point_stat_DUP_UNIQUE_120000L_20120409_120000V_mpr.txt diff --git a/test/xml/unit_ensemble_stat.xml b/test/xml/unit_ensemble_stat.xml index 93ec40b228..98a97a4779 100644 --- a/test/xml/unit_ensemble_stat.xml +++ b/test/xml/unit_ensemble_stat.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; @@ -18,7 +20,6 @@ - @@ -216,7 +217,7 @@ - + echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ @@ -226,10 +227,10 @@ > &OUTPUT_DIR;/ensemble_stat/input_file_list; \ &MET_BIN;/ensemble_stat - DESC OBS_ERROR + DESC OBSERR OBS_ERROR_FLAG TRUE SKIP_CONST TRUE - OUTPUT_PREFIX OBS_ERROR + OUTPUT_PREFIX OBSERR \ &OUTPUT_DIR;/ensemble_stat/input_file_list \ @@ -239,14 +240,14 @@ -outdir &OUTPUT_DIR;/ensemble_stat -v 1 - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V.stat - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_ecnt.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_rhist.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_phist.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_orank.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_ssvar.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_ens.nc - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V_orank.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V.stat + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_ecnt.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_rhist.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_phist.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_orank.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_ssvar.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_ens.nc + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V_orank.nc diff --git a/test/xml/unit_gaussian.xml b/test/xml/unit_gaussian.xml index ef6f74e49d..0c024e76d2 100644 --- a/test/xml/unit_gaussian.xml +++ b/test/xml/unit_gaussian.xml @@ -8,6 +8,8 @@ ]> + + &TEST_DIR; @@ -25,5 +27,4 @@ - diff --git a/test/xml/unit_gen_ens_prod.xml b/test/xml/unit_gen_ens_prod.xml index 91f2321431..3c014a08f2 100644 --- a/test/xml/unit_gen_ens_prod.xml +++ b/test/xml/unit_gen_ens_prod.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; @@ -17,7 +19,6 @@ - @@ -120,7 +121,7 @@ \ -ens &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ -config &CONFIG_DIR;/GenEnsProdConfig_single_file_grib \ - -ctrl &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ + -ctrl &DATA_DIR_MODEL;/grib2/gefs/enspost_grb2.t00z.prmsl \ -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_SINGLE_FILE_GRIB_WITH_CTRL.nc \ -v 2 diff --git a/test/xml/unit_gen_vx_mask.xml b/test/xml/unit_gen_vx_mask.xml index 6416d0a048..e9664fe0f9 100644 --- a/test/xml/unit_gen_vx_mask.xml +++ b/test/xml/unit_gen_vx_mask.xml @@ -12,6 +12,8 @@ ]> + + diff --git a/test/xml/unit_test_grib_tables.xml b/test/xml/unit_grib_tables.xml similarity index 77% rename from test/xml/unit_test_grib_tables.xml rename to test/xml/unit_grib_tables.xml index 41d3886867..88e8370e23 100644 --- a/test/xml/unit_test_grib_tables.xml +++ b/test/xml/unit_grib_tables.xml @@ -1,14 +1,16 @@ - - - + + + + - - - - ]> + + + +]> + + diff --git a/test/xml/unit_grid_diag.xml b/test/xml/unit_grid_diag.xml index 0da3a2bd95..10049144ac 100644 --- a/test/xml/unit_grid_diag.xml +++ b/test/xml/unit_grid_diag.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_grid_stat.xml b/test/xml/unit_grid_stat.xml index c31455c0ce..9d154a91a6 100644 --- a/test/xml/unit_grid_stat.xml +++ b/test/xml/unit_grid_stat.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_grid_weight.xml b/test/xml/unit_grid_weight.xml index 2c2949b920..f355401441 100644 --- a/test/xml/unit_grid_weight.xml +++ b/test/xml/unit_grid_weight.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_gsi_tools.xml b/test/xml/unit_gsi_tools.xml index e80505d2fd..78ec34ce56 100644 --- a/test/xml/unit_gsi_tools.xml +++ b/test/xml/unit_gsi_tools.xml @@ -10,24 +10,24 @@ ]> + + &TEST_DIR; true - - &MET_BIN;/gsid2mpr \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_conv_ges.mem001 \ -set_hdr MODEL GSI_MEM001 \ - -outdir &OUTPUT_DIR;/gsid2mpr \ + -outdir &OUTPUT_DIR;/gsi_tools/gsid2mpr \ -swap -v 1 - &OUTPUT_DIR;/gsid2mpr/diag_conv_ges.mem001.stat + &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_conv_ges.mem001.stat @@ -37,11 +37,11 @@ \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_conv_ges.mem001 \ -set_hdr MODEL GSI_MEM001 \ - -outdir &OUTPUT_DIR;/gsid2mpr \ + -outdir &OUTPUT_DIR;/gsi_tools/gsid2mpr \ -swap -no_check_dup -suffix _DUP_mpr.txt -v 1 - &OUTPUT_DIR;/gsid2mpr/diag_conv_ges.mem001_DUP_mpr.txt + &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_conv_ges.mem001_DUP_mpr.txt @@ -51,13 +51,13 @@ \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_amsua_n18_ges.mem001 \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_amsua_n18_ges.mem002 \ - -outdir &OUTPUT_DIR;/gsid2mpr \ + -outdir &OUTPUT_DIR;/gsi_tools/gsid2mpr \ -suffix _mpr.txt \ -swap -v 1 - &OUTPUT_DIR;/gsid2mpr/diag_amsua_n18_ges.mem001_mpr.txt - &OUTPUT_DIR;/gsid2mpr/diag_amsua_n18_ges.mem002_mpr.txt + &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_amsua_n18_ges.mem001_mpr.txt + &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_amsua_n18_ges.mem002_mpr.txt @@ -66,11 +66,11 @@ &MET_BIN;/gsidens2orank \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_conv_ges.mem* \ - -out &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_no_mean_orank.txt \ + -out &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_no_mean_orank.txt \ -swap -v 1 - &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_no_mean_orank.txt + &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_no_mean_orank.txt @@ -80,11 +80,11 @@ \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_conv_ges.mem* \ -ens_mean &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_conv_ges.ensmean \ - -out &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_orank.txt \ + -out &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_orank.txt \ -swap -v 1 - &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_orank.txt + &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_orank.txt @@ -93,11 +93,11 @@ &MET_BIN;/gsidens2orank \ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_amsua_n18_ges.mem* \ - -out &OUTPUT_DIR;/gsidens2orank/diag_amsua_n18_ges_all_channels_orank.txt \ + -out &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_amsua_n18_ges_all_channels_orank.txt \ -swap -v 1 - &OUTPUT_DIR;/gsidens2orank/diag_amsua_n18_ges_all_channels_orank.txt + &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_amsua_n18_ges_all_channels_orank.txt @@ -108,11 +108,11 @@ &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_amsua_n18_ges.mem* \ -ens_mean &INPUT_DIR;/gsi_data/GSIdiags4EnKF/diag_amsua_n18_ges.ensmean \ -channel 2,7,10 \ - -out &OUTPUT_DIR;/gsidens2orank/diag_amsua_n18_ges_some_channels_orank.txt \ + -out &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_amsua_n18_ges_some_channels_orank.txt \ -swap -v 1 - &OUTPUT_DIR;/gsidens2orank/diag_amsua_n18_ges_some_channels_orank.txt + &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_amsua_n18_ges_some_channels_orank.txt @@ -120,14 +120,14 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/gsid2mpr/diag_conv_ges.mem001.stat \ + -lookin &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_conv_ges.mem001.stat \ -job aggregate_stat -line_type MPR -out_line_type CNT -by fcst_var \ -column_thresh ANLY_USE ==1 \ - -out_stat &OUTPUT_DIR;/gsid2mpr/diag_conv_ges.mem001_cnt.txt \ + -out_stat &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_conv_ges.mem001_cnt.txt \ -v 1 - &OUTPUT_DIR;/gsid2mpr/diag_conv_ges.mem001_cnt.txt + &OUTPUT_DIR;/gsi_tools/gsid2mpr/diag_conv_ges.mem001_cnt.txt @@ -135,14 +135,14 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_orank.txt \ + -lookin &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_orank.txt \ -job aggregate_stat -line_type ORANK -out_line_type RHIST -by fcst_var \ -column_thresh N_USE ==20 \ - -out_stat &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_rhist.txt \ + -out_stat &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_rhist.txt \ -v 1 - &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_rhist.txt + &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_rhist.txt @@ -150,14 +150,14 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_orank.txt \ + -lookin &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_orank.txt \ -job aggregate_stat -line_type ORANK -out_line_type SSVAR -by fcst_var \ -column_thresh N_USE ==20 -out_bin_size 0.10 \ - -out_stat &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_ssvar.txt \ + -out_stat &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_ssvar.txt \ -v 1 - &OUTPUT_DIR;/gsidens2orank/diag_conv_ges_ens_mean_ssvar.txt + &OUTPUT_DIR;/gsi_tools/gsidens2orank/diag_conv_ges_ens_mean_ssvar.txt diff --git a/test/xml/unit_hira.xml b/test/xml/unit_hira.xml index 696199ce98..13d9888216 100644 --- a/test/xml/unit_hira.xml +++ b/test/xml/unit_hira.xml @@ -10,6 +10,8 @@ ]> + + diff --git a/test/xml/unit_interp_shape.xml b/test/xml/unit_interp_shape.xml index 962adf2a6e..be8aba9bd3 100644 --- a/test/xml/unit_interp_shape.xml +++ b/test/xml/unit_interp_shape.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_ioda2nc.xml b/test/xml/unit_ioda2nc.xml index b519a08d4d..91f2a7cbb4 100644 --- a/test/xml/unit_ioda2nc.xml +++ b/test/xml/unit_ioda2nc.xml @@ -12,49 +12,12 @@ ]> + + &TEST_DIR; true - &MET_BIN;/ioda2nc diff --git a/test/xml/unit_lidar2nc.xml b/test/xml/unit_lidar2nc.xml index dc46dab4bc..4fedf5c895 100644 --- a/test/xml/unit_lidar2nc.xml +++ b/test/xml/unit_lidar2nc.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_madis2nc.xml b/test/xml/unit_madis2nc.xml index 802eebc3c7..550b793ff0 100644 --- a/test/xml/unit_madis2nc.xml +++ b/test/xml/unit_madis2nc.xml @@ -11,6 +11,8 @@ ]> + + + diff --git a/test/xml/unit_mode.xml b/test/xml/unit_mode.xml index 113eac7934..c13e74676f 100644 --- a/test/xml/unit_mode.xml +++ b/test/xml/unit_mode.xml @@ -11,24 +11,13 @@ ]> + + &TEST_DIR; true - - &MET_BIN;/pcp_combine - \ - -subtract \ - &DATA_DIR_MODEL;/grib1/arw-tom-gep0/arw-tom-gep0_2012040912_F030.grib 30 \ - &DATA_DIR_MODEL;/grib1/arw-tom-gep0/arw-tom-gep0_2012040912_F024.grib 24 \ - &OUTPUT_DIR;/pcp_combine/arw-tom-gep0_2012040912_F030_APCP06.nc - - - &OUTPUT_DIR;/pcp_combine/arw-tom-gep0_2012040912_F030_APCP06.nc - - - &MET_BIN;/mode @@ -125,27 +114,6 @@ - - &MET_BIN;/mode diff --git a/test/xml/unit_mode_analysis.xml b/test/xml/unit_mode_analysis.xml index 12bb7b871c..f0815df484 100644 --- a/test/xml/unit_mode_analysis.xml +++ b/test/xml/unit_mode_analysis.xml @@ -10,13 +10,13 @@ ]> + + &TEST_DIR; true - - &MET_BIN;/mode_analysis \ diff --git a/test/xml/unit_mode_graphics.xml b/test/xml/unit_mode_graphics.xml index 824ba86907..485d4fe22e 100644 --- a/test/xml/unit_mode_graphics.xml +++ b/test/xml/unit_mode_graphics.xml @@ -10,54 +10,13 @@ ]> - + &TEST_DIR; true - - &MET_BIN;/plot_mode_field \ @@ -67,9 +26,9 @@ &OUTPUT_DIR;/met_test_scripts/mode/mode_*_obj.nc - &OUTPUT_DIR;/plot_mode_field/mode_120000L_20050807_120000V_000000A_obj_obs_simple.png - &OUTPUT_DIR;/plot_mode_field/mode_120000L_20050807_120000V_120000A_obj_obs_simple.png - &OUTPUT_DIR;/plot_mode_field/mode_240000L_20050808_000000V_240000A_obj_obs_simple.png + &OUTPUT_DIR;/mode_graphics/mode_120000L_20050807_120000V_000000A_obj_obs_simple.png + &OUTPUT_DIR;/mode_graphics/mode_120000L_20050807_120000V_120000A_obj_obs_simple.png + &OUTPUT_DIR;/mode_graphics/mode_240000L_20050808_000000V_240000A_obj_obs_simple.png diff --git a/test/xml/unit_modis.xml b/test/xml/unit_modis.xml index d5e1faf2a7..3f28d132e5 100644 --- a/test/xml/unit_modis.xml +++ b/test/xml/unit_modis.xml @@ -15,6 +15,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_mtd.xml b/test/xml/unit_mtd.xml index 0190dd2080..367bc6991a 100644 --- a/test/xml/unit_mtd.xml +++ b/test/xml/unit_mtd.xml @@ -9,6 +9,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_netcdf.xml b/test/xml/unit_netcdf.xml index b0e6e2fe48..5c0b255240 100644 --- a/test/xml/unit_netcdf.xml +++ b/test/xml/unit_netcdf.xml @@ -10,10 +10,12 @@ ]> + + diff --git a/test/xml/unit_obs_summary.xml b/test/xml/unit_obs_summary.xml index eb150fdaf1..eb98b3099b 100644 --- a/test/xml/unit_obs_summary.xml +++ b/test/xml/unit_obs_summary.xml @@ -10,9 +10,9 @@ ]> - + - + &TEST_DIR; false @@ -21,11 +21,11 @@ &MET_BIN;/ascii2nc \ &DATA_DIR_OBS;/ascii/obs_sum_test_qty.txt \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ -v 1 - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc @@ -38,13 +38,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_NONE_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_NONE_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_NONE_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_NONE_120000L_20120409_120000V_mpr.txt @@ -57,13 +57,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_NEAREST_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_NEAREST_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_NEAREST_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_NEAREST_120000L_20120409_120000V_mpr.txt @@ -76,13 +76,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_MIN_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_MIN_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_MIN_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_MIN_120000L_20120409_120000V_mpr.txt @@ -95,13 +95,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_MAX_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_MAX_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_MAX_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_MAX_120000L_20120409_120000V_mpr.txt @@ -114,13 +114,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_UW_MEAN_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_UW_MEAN_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_UW_MEAN_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_UW_MEAN_120000L_20120409_120000V_mpr.txt @@ -133,13 +133,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_DW_MEAN_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_DW_MEAN_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_DW_MEAN_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_DW_MEAN_120000L_20120409_120000V_mpr.txt @@ -152,13 +152,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_MEDIAN_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_MEDIAN_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_MEDIAN_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_MEDIAN_120000L_20120409_120000V_mpr.txt @@ -171,13 +171,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_PERC_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_PERC_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_PERC_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_PERC_120000L_20120409_120000V_mpr.txt @@ -188,13 +188,13 @@ \ &DATA_DIR_MODEL;/grib2/nam/nam_2012040900_F012.grib2 \ - &OUTPUT_DIR;/ascii2nc/obs_sum_test.nc \ + &OUTPUT_DIR;/obs_summary/obs_sum_test.nc \ &CONFIG_DIR;/PointStatConfig_obs_summary_all \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/obs_summary -v 3 - &OUTPUT_DIR;/point_stat/point_stat_OS_UNIQUE_ALL_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_OS_UNIQUE_ALL_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/obs_summary/point_stat_OS_UNIQUE_ALL_120000L_20120409_120000V.stat + &OUTPUT_DIR;/obs_summary/point_stat_OS_UNIQUE_ALL_120000L_20120409_120000V_mpr.txt diff --git a/test/xml/unit_pb2nc.xml b/test/xml/unit_pb2nc.xml index 3c7c6175fb..d6d79def22 100644 --- a/test/xml/unit_pb2nc.xml +++ b/test/xml/unit_pb2nc.xml @@ -12,6 +12,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_pcp_combine.xml b/test/xml/unit_pcp_combine.xml index 6d44e95b9b..4a1c39b76b 100644 --- a/test/xml/unit_pcp_combine.xml +++ b/test/xml/unit_pcp_combine.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; @@ -140,6 +142,19 @@ + + &MET_BIN;/pcp_combine + \ + -subtract \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep0/arw-tom-gep0_2012040912_F030.grib 30 \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep0/arw-tom-gep0_2012040912_F024.grib 24 \ + &OUTPUT_DIR;/pcp_combine/arw-tom-gep0_2012040912_F030_APCP06.nc + + + &OUTPUT_DIR;/pcp_combine/arw-tom-gep0_2012040912_F030_APCP06.nc + + + &MET_BIN;/pcp_combine \ diff --git a/test/xml/unit_perc_thresh.xml b/test/xml/unit_perc_thresh.xml index 893dedf3cf..366b32e3d7 100644 --- a/test/xml/unit_perc_thresh.xml +++ b/test/xml/unit_perc_thresh.xml @@ -12,6 +12,8 @@ ]> + + diff --git a/test/xml/unit_plot_data_plane.xml b/test/xml/unit_plot_data_plane.xml index f7642b24c2..25d47c1397 100644 --- a/test/xml/unit_plot_data_plane.xml +++ b/test/xml/unit_plot_data_plane.xml @@ -11,13 +11,13 @@ ]> + + &TEST_DIR; true - - &MET_BIN;/plot_data_plane \ diff --git a/test/xml/unit_plot_point_obs.xml b/test/xml/unit_plot_point_obs.xml index 31e2489b72..9daac9a880 100644 --- a/test/xml/unit_plot_point_obs.xml +++ b/test/xml/unit_plot_point_obs.xml @@ -10,12 +10,13 @@ ]> + + &TEST_DIR; true - diff --git a/test/xml/unit_plot_tc.xml b/test/xml/unit_plot_tc.xml index c4f308adb4..d67ade00f0 100644 --- a/test/xml/unit_plot_tc.xml +++ b/test/xml/unit_plot_tc.xml @@ -7,9 +7,9 @@ ]> - + - + &TEST_DIR; true diff --git a/test/xml/unit_point2grid.xml b/test/xml/unit_point2grid.xml index 1ab073e20a..dd1792ccf0 100644 --- a/test/xml/unit_point2grid.xml +++ b/test/xml/unit_point2grid.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; @@ -109,12 +111,12 @@ \ &DATA_DIR_OBS;/point_obs/prepbufr.gdas.2017060300.nc \ G212 \ - &OUTPUT_DIR;/regrid/pb2nc_TMP_big_input.nc \ + &OUTPUT_DIR;/point2grid/pb2nc_TMP_big_input.nc \ -field 'name="TMP"; level="Z2";' \ -v 1 - &OUTPUT_DIR;/regrid/pb2nc_TMP_big_input.nc + &OUTPUT_DIR;/point2grid/pb2nc_TMP_big_input.nc diff --git a/test/xml/unit_point_stat.xml b/test/xml/unit_point_stat.xml index 8750e1ee68..d5446343cd 100644 --- a/test/xml/unit_point_stat.xml +++ b/test/xml/unit_point_stat.xml @@ -11,6 +11,8 @@ ]> + + diff --git a/test/xml/unit_python.xml b/test/xml/unit_python.xml index 35993ed441..698f550f69 100644 --- a/test/xml/unit_python.xml +++ b/test/xml/unit_python.xml @@ -6,7 +6,7 @@ - + @@ -15,6 +15,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_quality_filter.xml b/test/xml/unit_quality_filter.xml index 912f52bda3..cbf086e4d5 100644 --- a/test/xml/unit_quality_filter.xml +++ b/test/xml/unit_quality_filter.xml @@ -10,16 +10,13 @@ ]> + + &TEST_DIR; true - - - - - &MET_BIN;/point_stat @@ -33,13 +30,13 @@ &DATA_DIR_MODEL;/grib1/nam/nam_2012040900_F012.grib \ &OUTPUT_DIR;/pb2nc/gdas1.20120409.t12z.prepbufr.nc \ &CONFIG_DIR;/PointStatConfig_qty_inc_exc \ - -outdir &OUTPUT_DIR;/point_stat -v 3 + -outdir &OUTPUT_DIR;/quality_filter -v 3 - &OUTPUT_DIR;/point_stat/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V.stat - &OUTPUT_DIR;/point_stat/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V_ctc.txt - &OUTPUT_DIR;/point_stat/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V_sl1l2.txt - &OUTPUT_DIR;/point_stat/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/quality_filter/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V.stat + &OUTPUT_DIR;/quality_filter/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V_ctc.txt + &OUTPUT_DIR;/quality_filter/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V_sl1l2.txt + &OUTPUT_DIR;/quality_filter/point_stat_QTY_INC_EXC_PB_120000L_20120409_120000V_mpr.txt @@ -57,14 +54,14 @@ &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040900_F012.grib \ &CONFIG_DIR;/EnsembleStatConfig_qty_inc_exc \ -point_obs &OUTPUT_DIR;/madis2nc/metar_2012040912_F000.nc \ - -outdir &OUTPUT_DIR;/ensemble_stat -v 3 + -outdir &OUTPUT_DIR;/quality_filter -v 3 - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V.stat - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_ecnt.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_rhist.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_orank.txt - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_ens.nc + &OUTPUT_DIR;/quality_filter/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V.stat + &OUTPUT_DIR;/quality_filter/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_ecnt.txt + &OUTPUT_DIR;/quality_filter/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_rhist.txt + &OUTPUT_DIR;/quality_filter/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_orank.txt + &OUTPUT_DIR;/quality_filter/ensemble_stat_QTY_INC_EXC_MADIS_VGS_20120409_120000V_ens.nc diff --git a/test/xml/unit_ref_config.xml b/test/xml/unit_ref_config.xml index 648da522a9..5f9320ba5d 100644 --- a/test/xml/unit_ref_config.xml +++ b/test/xml/unit_ref_config.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_regrid.xml b/test/xml/unit_regrid.xml index 8fdc3cb7a6..512b4f0a6c 100644 --- a/test/xml/unit_regrid.xml +++ b/test/xml/unit_regrid.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_rmw_analysis.xml b/test/xml/unit_rmw_analysis.xml index f5d871e61d..14f7328957 100644 --- a/test/xml/unit_rmw_analysis.xml +++ b/test/xml/unit_rmw_analysis.xml @@ -6,6 +6,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_series_analysis.xml b/test/xml/unit_series_analysis.xml index 8a1e2f7e6a..c1e64416b3 100644 --- a/test/xml/unit_series_analysis.xml +++ b/test/xml/unit_series_analysis.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_shift_data_plane.xml b/test/xml/unit_shift_data_plane.xml index 3d05e4879b..c8339e089e 100644 --- a/test/xml/unit_shift_data_plane.xml +++ b/test/xml/unit_shift_data_plane.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_stat_analysis.xml b/test/xml/unit_stat_analysis.xml index 93ef98b5bc..078b76e072 100644 --- a/test/xml/unit_stat_analysis.xml +++ b/test/xml/unit_stat_analysis.xml @@ -10,13 +10,13 @@ ]> + + &TEST_DIR; true - - @@ -147,7 +147,7 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBS_ERROR_20120410_120000V.stat \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V.stat \ -job aggregate_stat -line_type ORANK -out_line_type ECNT \ -fcst_var APCP_24 -by VX_MASK \ -set_hdr DESC VX_MASK \ diff --git a/test/xml/unit_tc_dland.xml b/test/xml/unit_tc_dland.xml index baa53b8cb8..3a294af977 100644 --- a/test/xml/unit_tc_dland.xml +++ b/test/xml/unit_tc_dland.xml @@ -6,6 +6,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_tc_gen.xml b/test/xml/unit_tc_gen.xml index 6146f1d3ec..85357e6bb3 100644 --- a/test/xml/unit_tc_gen.xml +++ b/test/xml/unit_tc_gen.xml @@ -9,6 +9,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_tc_pairs.xml b/test/xml/unit_tc_pairs.xml index c0e22dcf37..d35465237a 100644 --- a/test/xml/unit_tc_pairs.xml +++ b/test/xml/unit_tc_pairs.xml @@ -9,6 +9,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_tc_rmw.xml b/test/xml/unit_tc_rmw.xml index c45d71f10e..347ef88d87 100644 --- a/test/xml/unit_tc_rmw.xml +++ b/test/xml/unit_tc_rmw.xml @@ -9,6 +9,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_tc_stat.xml b/test/xml/unit_tc_stat.xml index 7353d72f68..5029a1f9a8 100644 --- a/test/xml/unit_tc_stat.xml +++ b/test/xml/unit_tc_stat.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_trmm2nc.xml b/test/xml/unit_trmm2nc.xml index bbd9e136cf..0aca61588e 100644 --- a/test/xml/unit_trmm2nc.xml +++ b/test/xml/unit_trmm2nc.xml @@ -11,6 +11,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_wavelet_stat.xml b/test/xml/unit_wavelet_stat.xml index 9e5f6efdd9..f1de40fa53 100644 --- a/test/xml/unit_wavelet_stat.xml +++ b/test/xml/unit_wavelet_stat.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_wwmca_plot.xml b/test/xml/unit_wwmca_plot.xml index 2e2a304495..2ea1da991b 100644 --- a/test/xml/unit_wwmca_plot.xml +++ b/test/xml/unit_wwmca_plot.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; diff --git a/test/xml/unit_wwmca_regrid.xml b/test/xml/unit_wwmca_regrid.xml index 86e225718c..1f5b19f9be 100644 --- a/test/xml/unit_wwmca_regrid.xml +++ b/test/xml/unit_wwmca_regrid.xml @@ -10,6 +10,8 @@ ]> + + &TEST_DIR; From b177c3bea86bfd81ab24c900f757539b4ae56d08 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 24 Jan 2022 17:48:53 -0700 Subject: [PATCH 072/172] #2020 Added SonarQube related varibales --- scripts/environment/development.seneca | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/environment/development.seneca b/scripts/environment/development.seneca index 650257b3ab..ccbf506dbf 100644 --- a/scripts/environment/development.seneca +++ b/scripts/environment/development.seneca @@ -49,3 +49,8 @@ export MET_TEST_RSCRIPT=/usr/local/R-4.1.2/bin/Rscript export PATH="/usr/local/nco/bin:/usr/local/netcdf/bin:\ /usr/local/sbin:/usr/local/bin:/usr/sbin:\ /usr/bin:/sbin:/bin:/usr/bin/X11:/opt/bin:$PATH" + +# SonarQube +export SONARQUBE_DIR=/d1/projects/SonarQube/ +export SONARQUBE_WRAPPER_BIN=$SONARQUBE_DIR/build-wrapper-linux-x86 +export SONARQUBE_SCANNER_BIN=$SONARQUBE_DIR/sonar-scanner-4.6.2.2472-linux/bin From 11daa46fdaed235956682f815d7f3e5127cd7f49 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 24 Jan 2022 17:52:25 -0700 Subject: [PATCH 073/172] #2020 Initial release --- scripts/sonarqube/run_nightly.sh | 75 +++++++++++ scripts/sonarqube/run_sonarqube.sh | 144 +++++++++++++++++++++ scripts/sonarqube/sonar-project.properties | 18 +++ 3 files changed, 237 insertions(+) create mode 100755 scripts/sonarqube/run_nightly.sh create mode 100755 scripts/sonarqube/run_sonarqube.sh create mode 100644 scripts/sonarqube/sonar-project.properties diff --git a/scripts/sonarqube/run_nightly.sh b/scripts/sonarqube/run_nightly.sh new file mode 100755 index 0000000000..6fcc166950 --- /dev/null +++ b/scripts/sonarqube/run_nightly.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# Run nightly SonarQube scan +#======================================================================= +# +# This run_nightly.sh script calls the run_sonarqube.sh script. +# It is intented to be run nightly through cron. Output should be +# directed to the LOGFILE, per cron convention. To run this script, use +# the following commands: +# +# git clone https://github.com/dtcenter/MET +# MET/scripts/sosnarqube/run_nightly.sh name +# +# Usage: run_nightly.sh name +# where "name" specifies a branch, tag, or hash +# +# For example, scan the develop branch: +# run_nightly.sh develop +# +#======================================================================= + +# Constants +#EMAIL_LIST="johnhg@ucar.edu hsoh@ucar.edu jpresto@ucar.edu linden@ucar.edu mccabe@ucar.edu" +EMAIL_LIST="hsoh@ucar.edu" +KEEP_DAYS=5 + +function usage { + echo + echo "USAGE: run_nightly.sh name" + echo " where \"name\" specifies a branch, tag, or hash." + echo +} + +# Check for arguments +if [ $# -lt 1 ]; then usage; exit 1; fi + +# Store the full path to the scripts directory +SCRIPT_DIR=`dirname $0` +if [[ ${0:0:1} != "/" ]]; then SCRIPT_DIR=$(pwd)/${SCRIPT_DIR}; fi + +# Define the development environment +ENV_FILE=${SCRIPT_DIR}/../environment/development.`hostname` +if [[ ! -e ${ENV_FILE} ]]; then + echo "$0: ERROR -> Development environment file missing: ${ENV_FILE}" + exit 1 +fi +source ${ENV_FILE} + +# Delete old directories +find ${MET_PROJ_DIR}/MET_regression/sonarqube \ + -mtime +${KEEP_DAYS} -name "NB*" | \ + xargs rm -rf + +# Create and switch to a run directory +TODAY=`date +%Y%m%d` +YESTERDAY=`date -d "1 day ago" +%Y%m%d` +RUN_DIR=${MET_PROJ_DIR}/MET_regression/sonarqube/NB${TODAY} +if [[ -e ${RUN_DIR} ]]; then rm -rf ${RUN_DIR}; fi +mkdir -p ${RUN_DIR} +cd ${RUN_DIR} + +# Create a logfile +LOGFILE=${RUN_DIR}/run_sonarqube_${TODAY}.log + +# Run scan and check for bad return status +${SCRIPT_DIR}/run_sonarqube.sh ${1} > ${LOGFILE} +if [[ $? -ne 0 ]]; then + echo "$0: The nightly SonarQube scan FAILED in `basename ${RUN_DIR}`." >> ${LOGFILE} + cat ${LOGFILE} | mail -s "MET SonarQube scan Failed for ${1} in `basename ${RUN_DIR}` (autogen msg)" ${EMAIL_LIST} + exit 1 +fi + +# Convert SonarQube report from pdf to html + +exit 0 diff --git a/scripts/sonarqube/run_sonarqube.sh b/scripts/sonarqube/run_sonarqube.sh new file mode 100755 index 0000000000..98c4e15bbe --- /dev/null +++ b/scripts/sonarqube/run_sonarqube.sh @@ -0,0 +1,144 @@ +#!/bin/bash +# +# Run SonarQube Source Code Analyzer on a specified revision of MET +#======================================================================= +# +# This run_sonarqube.sh script will check out the specified version +# of MET and run the SonarQube Source Code Analyzer on it. First, +# go to the directory where you would like the SCA output written and +# then run: +# +# git clone https://github.com/dtcenter/MET +# MET/scripts/sonarqube/run_sonarqube_sca.sh name +# +# Usage: run_sonarqube_sca.sh name +# Test the specified branched version of MET: +# run_sonarqube_sca.sh {branch name} +# Test the specified tagged version of MET: +# run_sonarqube_sca.sh {tag name} +# +#======================================================================= + +# Constants +GIT_REPO="https://github.com/dtcenter/MET" + +function usage { + echo + echo "USAGE: $(basename $0) name" + echo " where \"name\" specifies a branch, tag, or hash." + echo +} + +# Check for arguments +if [[ $# -lt 1 ]]; then usage; exit; fi + +# Check that SONARQUBE_WRAPPER_BIN is defined +if [ -z ${SONARQUBE_WRAPPER_BIN} ]; then + which build-wrapper-linux-x86-64 2> /dev/null + if [ $? -eq 0 ]; then + SONARQUBE_WRAPPER_BIN=$(which build-wrapper-linux-x86-64 2> /dev/null) + else + which build-wrapper 2> /dev/null + if [ $? -eq 0 ]; then + SONARQUBE_WRAPPER_BIN=$(which build-wrapper 2> /dev/null) + else + echo "ERROR: SONARQUBE_WRAPPER_BIN must be set" + exit 1 + fi + fi +fi +if [ ! -e ${SONARQUBE_WRAPPER_BIN} ]; then + echo "ERROR: SONARQUBE_WRAPPER_BIN (${SONARQUBE_WRAPPER_BIN}) does not exist" + exit 1 +fi + +# Check that SONARQUBE_SCANNER_BIN is defined +if [ -z ${SONARQUBE_SCANNER_BIN} ]; then + which sonar-scanner 2> /dev/null + if [ $? -eq 0 ]; then + SONARQUBE_SCANNER_BIN=$(which sonar-scanner 2> /dev/null) + else + echo "ERROR: SONARQUBE_SCANNER_BIN must be set" + exit 1 + fi +fi +if [ ! -e ${SONARQUBE_SCANNER_BIN} ]; then + echo "ERROR: SONARQUBE_SCANNER_BIN (${SONARQUBE_SCANNER_BIN}) does not exist" + exit 1 +fi + +if [ -z ${SONARQUBE_OUT_DIR} ]; then + export SONARQUBE_OUT_DIR=bw-outputs +fi + +# Sub-routine for running a command and checking return status +function run_command() { + + # Print the command being called + echo "CALLING: $1" + + # Run the command and store the return status + $1 + STATUS=$? + + # Check return status + if [[ ${STATUS} -ne 0 ]]; then + echo "ERROR: Command returned with non-zero status ($STATUS): $1" + exit ${STATUS} + fi + + return ${STATUS} +} + + +# Store the full path to the scripts directory +SCRIPT_DIR=`dirname $0` +if [[ ${0:0:1} != "/" ]]; then SCRIPT_DIR=$(pwd)/${SCRIPT_DIR}; fi + +# Clone repo into a sub-directory and checkout the requested version +REPO_DIR="MET-${1}" + +if [ -e ${REPO_DIR} ]; then + run_command "rm -rf ${REPO_DIR}" +fi +run_command "git clone ${GIT_REPO} ${REPO_DIR}" +run_command "cd ${REPO_DIR}" +run_command "git checkout ${1}" + +# Build the MET instance +run_command "cd met" + +# Run bootstrap +run_command "./bootstrap" + +# Do no manually set the CXX and F77 compilers. +# Let the configure script pick them. +# Otherwise, the SonarQube logic does not work. +export MET_DEVELOPMENT=true + +# Run the configure script +run_command "./configure --prefix=`pwd` \ + --enable-grib2 \ + --enable-modis \ + --enable-mode_graphics \ + --enable-lidar2nc \ + --enable-python" + +# Set the build id +#BUILD_ID="MET-${1}" + +# Copy sonar-project.properties +[ ! -e "sonar-project.properties" ] && cp -p $SCRIPT_DIR/sonar-project.properties . + +# Run SonarQube clean +run_command "make clean" + + +# Run SonarQube make +run_command "${SONARQUBE_WRAPPER_BIN}/build-wrapper-linux-x86-64 --out-dir $SONARQUBE_OUT_DIR make" + +# Run SonarQube scan +run_command "${SONARQUBE_SCANNER_BIN}/sonar-scanner" + +# Run SonarQube report generator to make a PDF file +#TODAY=`date +%Y%m%d` diff --git a/scripts/sonarqube/sonar-project.properties b/scripts/sonarqube/sonar-project.properties new file mode 100644 index 0000000000..387a9a3d74 --- /dev/null +++ b/scripts/sonarqube/sonar-project.properties @@ -0,0 +1,18 @@ +sonar.projectKey=org.sonarqube:MET_develop_NB +sonar.projectName=MET Nightly build +sonar.projectVersion=1.0 + +sonar.sources=src + +# The build-wrapper output dir +sonar.cfamily.build-wrapper-output=bw-outputs + +# Encoding of the source files +sonar.sourceEncoding=UTF-8 + +#----- Default SonarQube server +#sonar.host.url=http://localhost:9000 +sonar.host.url=http://mandan:9000 + +sonar.login=met +sonar.password=met@sonar.ucar From 89642fccbc5c44ef76e69cba2a37d6352442c3ee Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 25 Jan 2022 11:03:40 -0700 Subject: [PATCH 074/172] #2015 Avoid the repeasted debug message if derived varibales are disabled --- met/src/tools/other/pb2nc/pb2nc.cc | 139 ++++++++++++++++------------- 1 file changed, 77 insertions(+), 62 deletions(-) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index dd0ba183d8..6aa01dd547 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -367,7 +367,7 @@ static int combine_tqz_and_uv(map, static float compute_pbl(map pqtzuv_map_tq, map pqtzuv_map_uv); static void copy_pqtzuv(float *to_pqtzuv, float *from_pqtzuv, bool copy_all=true); -static void insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, +static bool insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, const float pbl_p, const float pbl_h, const float pbl_qm, const float hdr_lat, const float hdr_lon, const float hdr_elv, const time_t hdr_vld_ut, @@ -807,6 +807,7 @@ void process_pbfile(int i_pb) { int rej_typ, rej_sid, rej_vld, rej_grid, rej_poly; int rej_elv, rej_pb_rpt, rej_in_rpt, rej_itp, rej_nobs; int lv, ev, ev_temp, kk, len1, len2; + int n_derived_obs; double x, y; @@ -844,7 +845,8 @@ void process_pbfile(int i_pb) { IntArray diff_file_times; int diff_file_time_count; StringArray variables_big_nlevels; - static const char *method_name = "process_pbfile()"; + static const char *method_name_s = "process_pbfile()"; + static const char *method_name = "process_pbfile() -> "; bool apply_grid_mask = (conf_info.grid_mask.nx() > 0 && conf_info.grid_mask.ny() > 0); @@ -881,7 +883,7 @@ void process_pbfile(int i_pb) { // Check for multiple PrepBufr files if(pbfile.n_elements() > 1) { - mlog << Error << "\n" << method_name << " -> " + mlog << Error << "\n" << method_name << "the \"-dump\" and \"-pbfile\" options may not be " << "used together. Only one Bufr file may be dump " << "to ASCII at a time.\n\n"; @@ -894,7 +896,7 @@ void process_pbfile(int i_pb) { unit = dump_unit+i_pb; if (unit > MAX_FORTRAN_FILE_ID || unit < MIN_FORTRAN_FILE_ID) { - mlog << Error << "\n" << method_name << " -> " + mlog << Error << "\n" << method_name << "Invalid file ID [" << unit << "] between 1 and 99.\n\n"; } prefix = get_short_name(pbfile[i_pb].c_str()); @@ -907,7 +909,7 @@ void process_pbfile(int i_pb) { // Open the blocked temp PrepBufr file for reading unit = file_unit + i_pb; if (unit > MAX_FORTRAN_FILE_ID || unit < MIN_FORTRAN_FILE_ID) { - mlog << Error << "\n" << method_name << " -> " + mlog << Error << "\n" << method_name << "Invalid file ID [" << unit << "] between 1 and 99.\n\n"; } openpb_(blk_file.c_str(), &unit); @@ -925,7 +927,7 @@ void process_pbfile(int i_pb) { // Check for zero messages to process if(npbmsg <= 0 || npbmsg_total <= 0) { - mlog << Warning << "\n" << method_name << " -> " + mlog << Warning << "\n" << method_name << "No Bufr messages to process in file: " << pbfile[i_pb] << "\n\n"; @@ -936,6 +938,7 @@ void process_pbfile(int i_pb) { } // Initialize counts + n_derived_obs = 0; i_ret = n_file_obs = i_msg = 0; rej_typ = rej_sid = rej_vld = rej_grid = rej_poly = 0; rej_elv = rej_pb_rpt = rej_in_rpt = rej_itp = rej_nobs = 0; @@ -946,7 +949,7 @@ void process_pbfile(int i_pb) { bool is_prepbufr = is_prepbufr_file(&event_names); if(mlog.verbosity_level() >= debug_level_for_performance) { end_t = clock(); - mlog << Debug(debug_level_for_performance) << " PERF: " << method_name << " " + mlog << Debug(debug_level_for_performance) << " PERF: " << method_name_s << " " << (end_t-start_t)/double(CLOCKS_PER_SEC) << " seconds for preparing\n"; start_t = clock(); @@ -1011,8 +1014,8 @@ void process_pbfile(int i_pb) { if (cal_pbl) { is_same_header = false; prev_hdr_vld_ut = -1; - m_strncpy(prev_hdr_typ, not_assigned, m_strlen(not_assigned), method_name, "prev_hdr_typ"); - m_strncpy(prev_hdr_sid, not_assigned, m_strlen(not_assigned), method_name, "prev_hdr_sid"); + m_strncpy(prev_hdr_typ, not_assigned, m_strlen(not_assigned), method_name_s, "prev_hdr_typ"); + m_strncpy(prev_hdr_sid, not_assigned, m_strlen(not_assigned), method_name_s, "prev_hdr_sid"); } IMM = JMM =1; @@ -1023,6 +1026,14 @@ void process_pbfile(int i_pb) { diff_file_time_count = 0; cycle_minute = missing_cycle_minute; // initialize + // Derive quantities which can be derived from + // P, Q, T, Z, U, V + if (n_derive_gc > bufr_derive_cfgs.size()) { + mlog << Debug(3) << "\n" << method_name + << "Skip the derived variables because of not requested (" + << bufr_derive_cfgs.size() << ").\n\n"; + } + for (int idx=0; idx " + mlog << Debug(6) << "\n" << method_name << "Switching report type \"" << hdr_typ << "\" to message type \"" << mappedMessageType << "\".\n"; if (mappedMessageType.length() > HEADER_STR_LEN) max_buf = HEADER_STR_LEN; - m_strncpy(modified_hdr_typ, mappedMessageType.c_str(), max_buf, method_name, "modified_hdr_typ1"); + m_strncpy(modified_hdr_typ, mappedMessageType.c_str(), max_buf, method_name_s, "modified_hdr_typ1"); } else { - m_strncpy(modified_hdr_typ, hdr_typ, sizeof(modified_hdr_typ), method_name, "modified_hdr_typ2"); + m_strncpy(modified_hdr_typ, hdr_typ, sizeof(modified_hdr_typ), method_name_s, "modified_hdr_typ2"); } if (max_buf >= max_str_len) max_buf--; modified_hdr_typ[max_buf] = '\0'; @@ -1307,7 +1318,7 @@ void process_pbfile(int i_pb) { buf_nlev = mxr8lv; for(kk=0; kk " + mlog << Warning << "\n" << method_name << "Too many vertical levels (" << nlev << ") for " << bufr_obs_name_arr[kk] << "). Ignored the vertical levels above " << mxr8lv << ".\n\n"; @@ -1520,40 +1531,36 @@ void process_pbfile(int i_pb) { // Derive quantities which can be derived from // P, Q, T, Z, U, V - if (n_derive_gc > bufr_derive_cfgs.size()) { - mlog << Debug(3) << "\n" << method_name << " -> " - << "Skip the derived variables because of not requested (" - << bufr_derive_cfgs.size() << ").\n\n"; - } - else { + if (n_derive_gc <= bufr_derive_cfgs.size()) { for(i=0; i MAX_CAPE_LEVEL) cape_level = MAX_CAPE_LEVEL; reverse_levels = (cape_data_pres[0] > cape_data_pres[cape_level-1]); if (reverse_levels) { @@ -1618,11 +1625,11 @@ void process_pbfile(int i_pb) { swap_value = cape_data_pres[idx]; cape_data_pres[idx] = cape_data_pres[buf_idx]; cape_data_pres[buf_idx] = swap_value; - + swap_value = cape_data_temp[idx]; cape_data_temp[idx] = cape_data_temp[buf_idx]; cape_data_temp[buf_idx] = swap_value; - + swap_value = cape_data_spfh[idx]; cape_data_spfh[idx] = cape_data_spfh[buf_idx]; cape_data_spfh[buf_idx] = swap_value; @@ -1638,7 +1645,7 @@ void process_pbfile(int i_pb) { cape_data_spfh[idx] = r8bfms * 10; } } - + //p1d = cape_p; //t1d = cape_data_temp[cape_level-1]; //q1d = cape_data_spfh[cape_level-1]; @@ -1646,15 +1653,15 @@ void process_pbfile(int i_pb) { &p1d,&t1d,&q1d, static_dummy_201, &cape_level, &IMM,&JMM, &cape_level, &cape_val, &cin_val, &PLCL, &PEQL, static_dummy_200); - + if(mlog.verbosity_level() >= 7) { mlog << Debug(7) << method_name << " index,P,T,Q to compute CAPE from " << i_read << "-th message\n" ; for (int idx=0; idx MAX_CAPE_VALUE) { cape_cnt_too_big++; - mlog << Debug(5) << method_name + mlog << Debug(5) << method_name << " Ignored cape_value: " << cape_val << " cape_level: " << cape_level << ", cin_val: " << cin_val << ", PLCL: " << PLCL << ", PEQL: " << PEQL << "\n"; @@ -1681,6 +1688,7 @@ void process_pbfile(int i_pb) { hdr_lat, hdr_lon, hdr_elv, cape_qm, OBS_BUFFER_SIZE); cape_count++; + n_derived_obs++; if (is_eq(cape_val, 0.)) cape_cnt_zero_values++; } else cape_cnt_missing_values++; @@ -1747,7 +1755,7 @@ void process_pbfile(int i_pb) { if (nlev2 > mxr8lv) { buf_nlev = mxr8lv; if (!variables_big_nlevels.has(var_name, false)) { - mlog << Warning << "\n" << method_name << " -> " + mlog << Warning << "\n" << method_name << "Too many vertical levels (" << nlev2 << ") for " << var_name << ". Ignored the vertical levels above " << mxr8lv << ".\n\n"; @@ -1833,9 +1841,9 @@ void process_pbfile(int i_pb) { has_pbl_data = (pqtzuv_map_tq.size() > 0 && pqtzuv_map_uv.size() > 0); if (is_same_header && has_pbl_data) { float pbl_value = compute_pbl(pqtzuv_map_tq, pqtzuv_map_uv); - - insert_pbl(obs_arr, pbl_value, pbl_code, pbl_p, pbl_h, pbl_qm, - hdr_lat, hdr_lon, hdr_elv, hdr_vld_ut, hdr_typ, hdr_sid); + + if (insert_pbl(obs_arr, pbl_value, pbl_code, pbl_p, pbl_h, pbl_qm, + hdr_lat, hdr_lon, hdr_elv, hdr_vld_ut, hdr_typ, hdr_sid)) n_derived_obs++; for(vector::iterator it = pqtzuv_list.begin(); it != pqtzuv_list.end(); ++it) { @@ -1850,8 +1858,8 @@ void process_pbfile(int i_pb) { prev_hdr_lat = hdr_lat; prev_hdr_lon = hdr_lon; prev_hdr_elv = hdr_elv; - m_strncpy(prev_hdr_typ, hdr_typ, m_strlen(not_assigned), method_name, "prev_hdr_typ"); - m_strncpy(prev_hdr_sid, hdr_sid.c_str(), m_strlen(not_assigned), method_name, "prev_hdr_sid"); + m_strncpy(prev_hdr_typ, hdr_typ, m_strlen(not_assigned), method_name_s, "prev_hdr_typ"); + m_strncpy(prev_hdr_sid, hdr_sid.c_str(), m_strlen(not_assigned), method_name_s, "prev_hdr_sid"); } // If the number of observations for this header is non-zero, @@ -1874,8 +1882,8 @@ void process_pbfile(int i_pb) { has_pbl_data = (pqtzuv_map_tq.size() > 0 || pqtzuv_map_uv.size() > 0); if (do_pbl && has_pbl_data) { float pbl_value = compute_pbl(pqtzuv_map_tq, pqtzuv_map_uv); - insert_pbl(obs_arr, pbl_value, pbl_code, pbl_p, pbl_h, pbl_qm, - hdr_lat, hdr_lon, hdr_elv, hdr_vld_ut, hdr_typ, hdr_sid); + if (insert_pbl(obs_arr, pbl_value, pbl_code, pbl_p, pbl_h, pbl_qm, + hdr_lat, hdr_lon, hdr_elv, hdr_vld_ut, hdr_typ, hdr_sid)) n_derived_obs++; for(vector::iterator it = pqtzuv_list.begin(); it != pqtzuv_list.end(); ++it) { @@ -1898,7 +1906,7 @@ void process_pbfile(int i_pb) { if(0 < diff_file_time_count && 0 < diff_file_times.n_elements()) { mlog << Warning << "\n" << method_name - << " -> The observation time should remain the same for " + << "The observation time should remain the same for " << "all " << (is_prepbufr ? "PrepBufr" : "Bufr") << " messages\n"; mlog << Warning << method_name << " " << diff_file_time_count << " messages with different reference time (" @@ -1952,7 +1960,7 @@ void process_pbfile(int i_pb) { if (npbmsg == rej_vld && 0 < rej_vld) { - mlog << Warning << "\n" << method_name << " -> " + mlog << Warning << "\n" << method_name << "All messages were filtered out by valid time.\n" << "\tPlease adjust time range with \"-valid_beg\" and \"-valid_end\".\n" << "\tmin/max obs time from BUFR file: " << min_time_str @@ -1981,17 +1989,17 @@ void process_pbfile(int i_pb) { remove_temp_file(blk_file); if(mlog.verbosity_level() >= debug_level_for_performance) { method_end = clock(); - cout << " PERF: " << method_name << " " + cout << " PERF: " << method_name_s << " " << (method_end-method_start)/double(CLOCKS_PER_SEC) << " seconds\n"; } if(i_msg <= 0) { - mlog << Warning << "\n" << method_name << " -> " + mlog << Warning << "\n" << method_name + << ((n_derived_obs > 0) ? "Saved the derived variables only. " : " ") << "No " << (is_prepbufr ? "PrepBufr" : "Bufr") << " messages retained from file: " << pbfile[i_pb] << "\n\n"; - return; } return; @@ -2306,7 +2314,7 @@ void process_pbfile_metadata(int i_pb) { readpbint_(&unit, &i_ret, &nlev2, bufr_obs, (char*)var_name.c_str(), &var_name_len, &nlev_max_req); if (0 >= nlev2) continue; - + // Search through the vertical levels has_valid_data = false; for(lv=0; lv pqtzuv_map_tq, } interpolate_pqtzuv(prev_pqtzuv, pqtzuv_merged, next_pqtzuv); } - float first_pres = (pqtzuv_merged == 0 ? bad_data_float : pqtzuv_merged[0]); + float first_pres = (pqtzuv_merged[0] == 0 ? bad_data_float : pqtzuv_merged[0]); pqtzuv_map_merged[first_pres] = pqtzuv_merged; mlog << Debug(9) << method_name << "Added " << first_pres << " to merged records\n"; @@ -3094,11 +3102,12 @@ float compute_pbl(map pqtzuv_map_tq, //////////////////////////////////////////////////////////////////////// -void insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, +bool insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, const float pbl_p, const float pbl_h, const float pbl_qm, const float hdr_lat, const float hdr_lon, - const float hdr_elv, const time_t hdr_vld_ut, + const float hdr_elv, const time_t hdr_vld_ut, const ConcatString &hdr_typ, const ConcatString &hdr_sid) { + bool added = false; ConcatString hdr_info; hdr_info << unix_to_yyyymmdd_hhmmss(hdr_vld_ut) << " " << hdr_typ << " " << hdr_sid; @@ -3124,9 +3133,13 @@ void insert_pbl(float *obs_arr, const float pbl_value, const int pbl_code, << pbl_value << ") because of the MAX PBL " << MAX_PBL << " (" << hdr_info<< ")\n"; } - else addObservation(obs_arr, (string)hdr_typ, (string)hdr_sid, hdr_vld_ut, - hdr_lat, hdr_lon, hdr_elv, pbl_qm, OBS_BUFFER_SIZE); + else { + addObservation(obs_arr, (string)hdr_typ, (string)hdr_sid, hdr_vld_ut, + hdr_lat, hdr_lon, hdr_elv, pbl_qm, OBS_BUFFER_SIZE); + added = true; + } } + return added; } //////////////////////////////////////////////////////////////////////// @@ -3189,7 +3202,7 @@ void interpolate_pqtzuv(float *prev_pqtzuv, float *cur_pqtzuv, float *next_pqtzu if ((nint(prev_pqtzuv[0]) == nint(cur_pqtzuv[0])) || (nint(next_pqtzuv[0]) == nint(cur_pqtzuv[0])) || (nint(prev_pqtzuv[0]) == nint(next_pqtzuv[0]))) { - mlog << Error << "\n" << method_name + mlog << Error << "\n" << method_name << " Can't interpolate because of same pressure levels. prev: " << prev_pqtzuv[0] << ", cur: " << cur_pqtzuv[0] << ", next: " << prev_pqtzuv[0] << "\n\n"; @@ -3284,7 +3297,7 @@ void merge_records(float *first_pqtzuv, map pqtzuv_map_pivot, break; } } - + if (it_aux->first == cur_pres) { copy_pqtzuv(pqtzuv_merged, it_aux->second, false); prev_pqtzuv = pqtzuv_merged; @@ -3383,16 +3396,18 @@ void log_pbl_input(int pbl_level, const char *method_name) { for (int idx=0; idx=0; idx--) { - mlog << Debug(PBL_DEBUG_LEVEL) << method_name << " input to calpbl_: " + mlog << Debug(PBL_DEBUG_LEVEL) << method_name << " " << offset++ << "\t" << log_array[idx] << "\n"; } log_array.clear(); From 6b9b41127a2becb30ed813f08349f097f7f5243d Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 25 Jan 2022 13:23:00 -0700 Subject: [PATCH 075/172] #1996 Initialize right and left --- met/src/basic/vx_util/ascii_table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/basic/vx_util/ascii_table.cc b/met/src/basic/vx_util/ascii_table.cc index 28fb9004d6..e5b917c377 100644 --- a/met/src/basic/vx_util/ascii_table.cc +++ b/met/src/basic/vx_util/ascii_table.cc @@ -1336,7 +1336,7 @@ const char fill_char = ' '; const int r_start = 1; // skip the header row -for (r=0; r Date: Tue, 25 Jan 2022 13:24:07 -0700 Subject: [PATCH 076/172] #1966 Call clear() instead of reset memory for Header variable --- met/src/libcode/vx_gis/dbf_file.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/libcode/vx_gis/dbf_file.cc b/met/src/libcode/vx_gis/dbf_file.cc index 0a5049d150..174c356c5f 100644 --- a/met/src/libcode/vx_gis/dbf_file.cc +++ b/met/src/libcode/vx_gis/dbf_file.cc @@ -750,7 +750,7 @@ if ( fd >= 0 ) ::close(fd); fd = -1; -memset(&Header, 0, sizeof(Header)); +Header.clear(); Filename.clear(); From 4142c48b86627d38a2adc68451a337c7fe1c8b97 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 25 Jan 2022 13:25:00 -0700 Subject: [PATCH 077/172] #1966 Make sure the levels from variable does not exceed the maxLevel --- met/src/tools/other/madis2nc/madis2nc.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/met/src/tools/other/madis2nc/madis2nc.cc b/met/src/tools/other/madis2nc/madis2nc.cc index 6f48a30ccc..0f8164945a 100644 --- a/met/src/tools/other/madis2nc/madis2nc.cc +++ b/met/src/tools/other/madis2nc/madis2nc.cc @@ -3410,6 +3410,11 @@ void process_madis_acarsProfiles(NcFile *&f_in) { levelsQty[i_idx], GET_NC_NAME(in_var).c_str()); nlvl = levels[i_idx]; + if (nlvl > maxLevels) { + mlog << Warning << "\n" << method_name << " The level (" << nlvl + << ") at nLevels variable can not exceed dimension maxLevels (" << maxLevels<< ")\n\n"; + nlvl = maxLevels; + } obs_arr[2] = levels[i_idx]; // From c4f5a1bb969dce20707df462099ee0ed40bd2305 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 25 Jan 2022 13:25:44 -0700 Subject: [PATCH 078/172] #1966 Removed unreachable codes --- met/src/tools/other/mode_graphics/cgraph_main.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/met/src/tools/other/mode_graphics/cgraph_main.cc b/met/src/tools/other/mode_graphics/cgraph_main.cc index d9963263fc..5020cfe719 100644 --- a/met/src/tools/other/mode_graphics/cgraph_main.cc +++ b/met/src/tools/other/mode_graphics/cgraph_main.cc @@ -2223,14 +2223,10 @@ int my_conic (const FT_Vector * control, const FT_Vector * to, void * u) { -ft_user_info * info = (ft_user_info *) u; - mlog << Error << "\n\n my_conic() -> should never be called!\n\n"; exit ( 1 ); -info->have_path = true; - return ( 0 ); } From 4226cbe44c5e237797813f6b06bffa32a27c919e Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 25 Jan 2022 13:27:10 -0700 Subject: [PATCH 079/172] #1966 Do not write into NetcDF if empty data --- met/src/libcode/vx_nc_obs/nc_obs_util.cc | 40 +++++++++++++----------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.cc b/met/src/libcode/vx_nc_obs/nc_obs_util.cc index 70ea844d49..0467f49eee 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.cc +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.cc @@ -1132,26 +1132,28 @@ void NetcdfObsVars::write_header_to_nc(NcDataBuffer &data_buf, else if (data_buf.hdr_data_offset == data_buf.pb_hdr_data_offset) { int save_len = lengths[0]; int pb_hdr_len = raw_hdr_cnt - offsets[0]; - if (pb_hdr_len > buf_size) pb_hdr_len = buf_size; - - lengths[0] = pb_hdr_len; - if(IS_VALID_NC(hdr_prpt_typ_var) && !put_nc_data((NcVar *)&hdr_prpt_typ_var, - data_buf.hdr_prpt_typ_buf, lengths, offsets)) { - mlog << Error << "error writing the pb message type to the netCDF file\n\n"; - exit(1); - } - if(IS_VALID_NC(hdr_irpt_typ_var) && !put_nc_data((NcVar *)&hdr_irpt_typ_var, - data_buf.hdr_irpt_typ_buf, lengths, offsets)) { - mlog << Error << "error writing the in message type to the netCDF file\n\n"; - exit(1); - } - if(IS_VALID_NC(hdr_inst_typ_var) && !put_nc_data((NcVar *)&hdr_inst_typ_var, - data_buf.hdr_inst_typ_buf, lengths, offsets)) { - mlog << Error << "error writing the instrument type to the netCDF file\n\n"; - exit(1); + if (pb_hdr_len > 0) { + if (pb_hdr_len > buf_size) pb_hdr_len = buf_size; + + lengths[0] = pb_hdr_len; + if(IS_VALID_NC(hdr_prpt_typ_var) && !put_nc_data((NcVar *)&hdr_prpt_typ_var, + data_buf.hdr_prpt_typ_buf, lengths, offsets)) { + mlog << Error << "error writing the pb message type to the netCDF file\n\n"; + exit(1); + } + if(IS_VALID_NC(hdr_irpt_typ_var) && !put_nc_data((NcVar *)&hdr_irpt_typ_var, + data_buf.hdr_irpt_typ_buf, lengths, offsets)) { + mlog << Error << "error writing the in message type to the netCDF file\n\n"; + exit(1); + } + if(IS_VALID_NC(hdr_inst_typ_var) && !put_nc_data((NcVar *)&hdr_inst_typ_var, + data_buf.hdr_inst_typ_buf, lengths, offsets)) { + mlog << Error << "error writing the instrument type to the netCDF file\n\n"; + exit(1); + } + lengths[0] = save_len; + data_buf.pb_hdr_data_offset += pb_hdr_len; } - lengths[0] = save_len; - data_buf.pb_hdr_data_offset += pb_hdr_len; } else { mlog << Debug(6) << method_name From 587b936ceb3afd0e974538351d1730b3eb36ea84 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 26 Jan 2022 18:59:21 -0700 Subject: [PATCH 080/172] #2015 Corrected "retained or derived" count --- met/src/tools/other/pb2nc/pb2nc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index 6aa01dd547..50a8fa9ab8 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -1946,7 +1946,7 @@ void process_pbfile(int i_pb) { << "Total Messages retained\t\t= " << i_msg << "\n" << "Total observations retained or derived\t= " - << n_file_obs << "\n"; + << (n_file_obs + n_derived_obs) << "\n"; if (cal_cape) { mlog << Debug(3) << "\nDerived CAPE = " << cape_count From 3097278e2496d9cdc2fa9c20002ae284e00d06d8 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Jan 2022 14:50:02 -0700 Subject: [PATCH 081/172] Feature 1546 CI testing (#2029) Co-authored-by: John Halley Gotway --- .github/jobs/Dockerfile.truth | 17 + .github/jobs/bash_functions.sh | 27 + .github/jobs/build_and_push_docker_image.sh | 40 - .github/jobs/build_docker_image.sh | 14 + .github/jobs/copy_diff_files.py | 80 ++ .github/jobs/create_docker_truth.sh | 18 + .github/jobs/get_branch_name.sh | 15 + .github/jobs/get_test_input_data.sh | 7 + .github/jobs/get_test_truth_data.sh | 11 + .github/jobs/pull_docker_image.sh | 7 + .github/jobs/push_docker_image.sh | 15 + .github/jobs/run_diff_docker.sh | 48 + .github/jobs/run_diff_tests.sh | 33 + .github/jobs/run_unit_docker.sh | 37 + .github/jobs/run_unit_tests.sh | 26 + .github/jobs/set_job_controls.sh | 94 ++ .github/jobs/test_env_vars.sh | 13 + .../build_docker_and_trigger_metplus.yml | 17 +- .github/workflows/unit_tests.yml | 377 +++++++ .gitignore | 3 + met/scripts/python/read_met_point_obs.py | 12 +- scripts/docker/Dockerfile | 154 +-- scripts/docker/Dockerfile.copy | 46 + scripts/docker/Dockerfile.minimum | 138 +++ scripts/docker/Dockerfile.test | 26 + scripts/docker/README.md | 40 + scripts/docker/build_met_docker.sh | 37 + test/bin/unit_test.sh | 16 +- test/xml/unit_ascii2nc.xml | 319 +----- test/xml/unit_ascii2nc_indy.xml | 340 +++++++ test/xml/unit_climatology.xml | 361 ------- test/xml/unit_climatology_1.0deg.xml | 252 +++++ test/xml/unit_climatology_1.5deg.xml | 98 ++ test/xml/unit_climatology_2.5deg.xml | 53 + test/xml/unit_pb2nc.xml | 136 +-- test/xml/unit_pb2nc_indy.xml | 157 +++ test/xml/unit_pcp_combine.xml | 4 +- test/xml/unit_plot_data_plane.xml | 4 +- test/xml/unit_python.xml | 12 +- test/xml/unit_ref_config.xml | 931 +----------------- test/xml/unit_ref_config_lead_00.xml | 178 ++++ test/xml/unit_ref_config_lead_12.xml | 230 +++++ test/xml/unit_ref_config_lead_24.xml | 231 +++++ test/xml/unit_ref_config_lead_36.xml | 274 ++++++ test/xml/unit_ref_config_lead_48.xml | 231 +++++ test/xml/unit_stat_analysis.xml | 331 ------- test/xml/unit_stat_analysis_es.xml | 182 ++++ test/xml/unit_stat_analysis_gs.xml | 45 + test/xml/unit_stat_analysis_ps.xml | 120 +++ test/xml/unit_stat_analysis_ws.xml | 38 + 50 files changed, 3621 insertions(+), 2274 deletions(-) create mode 100644 .github/jobs/Dockerfile.truth create mode 100755 .github/jobs/bash_functions.sh delete mode 100755 .github/jobs/build_and_push_docker_image.sh create mode 100755 .github/jobs/build_docker_image.sh create mode 100755 .github/jobs/copy_diff_files.py create mode 100755 .github/jobs/create_docker_truth.sh create mode 100755 .github/jobs/get_branch_name.sh create mode 100755 .github/jobs/get_test_input_data.sh create mode 100755 .github/jobs/get_test_truth_data.sh create mode 100755 .github/jobs/pull_docker_image.sh create mode 100755 .github/jobs/push_docker_image.sh create mode 100755 .github/jobs/run_diff_docker.sh create mode 100755 .github/jobs/run_diff_tests.sh create mode 100755 .github/jobs/run_unit_docker.sh create mode 100755 .github/jobs/run_unit_tests.sh create mode 100755 .github/jobs/set_job_controls.sh create mode 100755 .github/jobs/test_env_vars.sh create mode 100644 .github/workflows/unit_tests.yml create mode 100644 scripts/docker/Dockerfile.copy create mode 100644 scripts/docker/Dockerfile.minimum create mode 100644 scripts/docker/Dockerfile.test create mode 100644 scripts/docker/README.md create mode 100755 scripts/docker/build_met_docker.sh create mode 100644 test/xml/unit_ascii2nc_indy.xml delete mode 100644 test/xml/unit_climatology.xml create mode 100644 test/xml/unit_climatology_1.0deg.xml create mode 100644 test/xml/unit_climatology_1.5deg.xml create mode 100644 test/xml/unit_climatology_2.5deg.xml create mode 100644 test/xml/unit_pb2nc_indy.xml create mode 100644 test/xml/unit_ref_config_lead_00.xml create mode 100644 test/xml/unit_ref_config_lead_12.xml create mode 100644 test/xml/unit_ref_config_lead_24.xml create mode 100644 test/xml/unit_ref_config_lead_36.xml create mode 100644 test/xml/unit_ref_config_lead_48.xml delete mode 100644 test/xml/unit_stat_analysis.xml create mode 100644 test/xml/unit_stat_analysis_es.xml create mode 100644 test/xml/unit_stat_analysis_gs.xml create mode 100644 test/xml/unit_stat_analysis_ps.xml create mode 100644 test/xml/unit_stat_analysis_ws.xml diff --git a/.github/jobs/Dockerfile.truth b/.github/jobs/Dockerfile.truth new file mode 100644 index 0000000000..6366360e13 --- /dev/null +++ b/.github/jobs/Dockerfile.truth @@ -0,0 +1,17 @@ +FROM centos:7 +MAINTAINER George McCabe + +ENV OUTPUT_DIR /data/output +RUN mkdir -p ${OUTPUT_DIR} + +ARG TRUTH_DIR + +COPY ${TRUTH_DIR} ${OUTPUT_DIR}/ + +ARG TRUTH_DIR + +# Define the volume mount point +VOLUME ${OUTPUT_DIR}/${TRUTH_DIR} + +USER root +CMD ["true"] \ No newline at end of file diff --git a/.github/jobs/bash_functions.sh b/.github/jobs/bash_functions.sh new file mode 100755 index 0000000000..5205753780 --- /dev/null +++ b/.github/jobs/bash_functions.sh @@ -0,0 +1,27 @@ +#! /bin/bash + +# utility function to run command get log the time it took to run +# if CMD_LOGFILE is set, send output to that file and unset var +function time_command { + local start_seconds=$SECONDS + echo "RUNNING: $*" + + local error + # pipe output to log file if set + if [ "x$CMD_LOGFILE" == "x" ]; then + "$@" + error=$? + else + echo "Logging to ${CMD_LOGFILE}" + "$@" &>> $CMD_LOGFILE + error=$? + unset CMD_LOGFILE + fi + + local duration=$(( SECONDS - start_seconds )) + echo "TIMING: Command took `printf '%02d' $(($duration / 60))`:`printf '%02d' $(($duration % 60))` (MM:SS): '$*'" + if [ ${error} -ne 0 ]; then + echo "ERROR: '$*' exited with status = ${error}" + fi + return $error +} diff --git a/.github/jobs/build_and_push_docker_image.sh b/.github/jobs/build_and_push_docker_image.sh deleted file mode 100755 index 766b67cc41..0000000000 --- a/.github/jobs/build_and_push_docker_image.sh +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/bash - -# utility function to run command get log the time it took to run -function time_command { - local start_seconds=$SECONDS - echo "RUNNING: $*" - "$@" - local error=$? - - local duration=$(( SECONDS - start_seconds )) - echo "TIMING: Command took `printf '%02d' $(($duration / 60))`:`printf '%02d' $(($duration % 60))` (MM:SS): '$*'" - if [ ${error} -ne 0 ]; then - echo "ERROR: '$*' exited with status = ${error}" - fi - return $error -} - -prefix=refs/heads/ -branch_name=${GITHUB_REF#"$prefix"} -DOCKERHUB_TAG=dtcenter/met:${branch_name} - -DOCKERFILE_DIR=${GITHUB_WORKSPACE}/scripts/docker - -echo "::group::Docker Build Command" -time_command docker build -t ${DOCKERHUB_TAG} \ - --build-arg SOURCE_BRANCH=$branch_name \ - $DOCKERFILE_DIR -echo "::endgroup::" - -# skip docker push if credentials are not set -if [ -z ${DOCKER_USERNAME+x} ] || [ -z ${DOCKER_PASSWORD+x} ]; then - echo "DockerHub credentials not set. Skipping docker push" - exit 0 -fi - -echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin - -echo "::group::Docker Push Command" -time_command docker push ${DOCKERHUB_TAG} -echo "::endgroup::" diff --git a/.github/jobs/build_docker_image.sh b/.github/jobs/build_docker_image.sh new file mode 100755 index 0000000000..5a9b2e8cf7 --- /dev/null +++ b/.github/jobs/build_docker_image.sh @@ -0,0 +1,14 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DOCKERHUB_TAG=${DOCKERHUB_REPO}:${SOURCE_BRANCH} + +DOCKERFILE_PATH=${GITHUB_WORKSPACE}/scripts/docker/Dockerfile.copy + +CMD_LOGFILE=${GITHUB_WORKSPACE}/docker_build.log + +time_command docker build -t ${DOCKERHUB_TAG} \ + --build-arg SOURCE_BRANCH \ + --build-arg MET_BASE_IMAGE \ + -f $DOCKERFILE_PATH ${GITHUB_WORKSPACE} diff --git a/.github/jobs/copy_diff_files.py b/.github/jobs/copy_diff_files.py new file mode 100755 index 0000000000..eed5b6a339 --- /dev/null +++ b/.github/jobs/copy_diff_files.py @@ -0,0 +1,80 @@ +#! /usr/bin/env python3 + +import os +import shutil + +OUTPUT_DIR = os.environ['MET_TEST_OUTPUT'] +TRUTH_DIR = os.environ['MET_TEST_TRUTH'] +DIFF_DIR = os.environ['MET_TEST_DIFF'] + +LOG_DIR = '/met/logs' + +def get_files_with_diffs(log_file): + files_to_copy = set() + + with open(log_file, 'r') as file_handle: + file_content = file_handle.read() + + missing_section, *test_sections = file_content.split( + '\n# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n' + ) + + # parse list of missing files + if 'ERROR:' in missing_section: + for missing_group in missing_section.split('ERROR:')[1:]: + dir_str, *rel_paths = missing_group.splitlines() + dir_str = dir_str.split()[1] + if OUTPUT_DIR in dir_str: + top_dir = dir_str.replace(OUTPUT_DIR, TRUTH_DIR) + elif TRUTH_DIR in dir_str: + top_dir = dir_str.replace(TRUTH_DIR, OUTPUT_DIR) + else: + print("ERROR: SOMETHING WENT WRONG PARSING COMP_DIR OUTPUT") + continue + for rel_path in rel_paths: + files_to_copy.add(os.path.join(top_dir, rel_path.strip())) + + # parse file paths out of sections that have errors + error_sections = [item for item in test_sections if 'ERROR:' in item] + for error_section in error_sections: + for line in error_section.splitlines(): + for item in line.split(): + if OUTPUT_DIR in item or TRUTH_DIR in item: + files_to_copy.add(item) + + return files_to_copy + +def copy_files_to_diff_dir(files_to_copy): + + print(f"Found {len(files_to_copy)} diff files") + + # add extension for output/truth and copy files to diff directory + for filename in files_to_copy: + output_path, extension = os.path.splitext(filename) + if OUTPUT_DIR in output_path: + output_path = f'{output_path}_OUTPUT{extension}' + output_path = output_path.replace(OUTPUT_DIR, DIFF_DIR) + elif TRUTH_DIR in output_path: + output_path = f'{output_path}_TRUTH{extension}' + output_path = output_path.replace(TRUTH_DIR, DIFF_DIR) + else: + continue + + # change bad char - this can be removed once test output is changed + output_path = output_path.replace(':', '_') + + print(f"Copy {filename} to {output_path}") + output_dir = os.path.dirname(output_path) + if not os.path.exists(output_dir): + os.makedirs(output_dir) + shutil.copyfile(filename, output_path) + +def main(): + log_file = os.path.join(LOG_DIR, 'comp_dir.log') + print(f"Parsing {log_file}") + all_files_to_copy = get_files_with_diffs(log_file) + + copy_files_to_diff_dir(all_files_to_copy) + +if __name__ == "__main__": + main() diff --git a/.github/jobs/create_docker_truth.sh b/.github/jobs/create_docker_truth.sh new file mode 100755 index 0000000000..298852f80a --- /dev/null +++ b/.github/jobs/create_docker_truth.sh @@ -0,0 +1,18 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +image_name=dtcenter/met-data-output:${TRUTH_DATA_VERSION} + +time_command docker build -t ${image_name} \ + --build-arg TRUTH_DIR=met_test_truth \ + -f ${GITHUB_WORKSPACE}/.github/jobs/Dockerfile.truth \ + ${RUNNER_WORKSPACE} +if [ $? != 0 ]; then + echo "ERROR: Docker build failed" + exit 1 +fi + +echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin + +time_command docker push ${image_name} diff --git a/.github/jobs/get_branch_name.sh b/.github/jobs/get_branch_name.sh new file mode 100755 index 0000000000..ec42a94e38 --- /dev/null +++ b/.github/jobs/get_branch_name.sh @@ -0,0 +1,15 @@ +#! /bin/bash + +# If pull request, use GitHub head ref and add -PR to end +# Otherwise use GitHub ref + +if [ "${GITHUB_EVENT_NAME}" == "pull_request" ] ; then + branch_name=${GITHUB_HEAD_REF}-PR +else + branch_name=${GITHUB_REF} +fi + +branch_name=${branch_name#"refs/heads/"} + +echo ::set-output name=branch_name::$branch_name +echo branch_name: $branch_name diff --git a/.github/jobs/get_test_input_data.sh b/.github/jobs/get_test_input_data.sh new file mode 100755 index 0000000000..d11c651265 --- /dev/null +++ b/.github/jobs/get_test_input_data.sh @@ -0,0 +1,7 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DATA_VERSION=$1 + +time_command docker create --name met_input dtcenter/met-data-dev:${DATA_VERSION} diff --git a/.github/jobs/get_test_truth_data.sh b/.github/jobs/get_test_truth_data.sh new file mode 100755 index 0000000000..3b4055b4be --- /dev/null +++ b/.github/jobs/get_test_truth_data.sh @@ -0,0 +1,11 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DATA_VERSION=$1 + +time_command docker create --name met_truth dtcenter/met-data-output:${DATA_VERSION} +if [ $? != 0 ]; then + echo "Image tag ${DATA_VERSION} does not exist. Using develop..." + time_command docker create --name met_truth dtcenter/met-data-output:develop +fi diff --git a/.github/jobs/pull_docker_image.sh b/.github/jobs/pull_docker_image.sh new file mode 100755 index 0000000000..e97c6a1f07 --- /dev/null +++ b/.github/jobs/pull_docker_image.sh @@ -0,0 +1,7 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DOCKERHUB_TAG=$1 + +time_command docker pull ${DOCKERHUB_TAG} diff --git a/.github/jobs/push_docker_image.sh b/.github/jobs/push_docker_image.sh new file mode 100755 index 0000000000..83a8e4fc5f --- /dev/null +++ b/.github/jobs/push_docker_image.sh @@ -0,0 +1,15 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DOCKERHUB_TAG=${DOCKERHUB_REPO}:${SOURCE_BRANCH} + +# skip docker push if credentials are not set +if [ -z ${DOCKER_USERNAME+x} ] || [ -z ${DOCKER_PASSWORD+x} ]; then + echo "DockerHub credentials not set. Skipping docker push" + exit 0 +fi + +echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin + +time_command docker push ${DOCKERHUB_TAG} diff --git a/.github/jobs/run_diff_docker.sh b/.github/jobs/run_diff_docker.sh new file mode 100755 index 0000000000..b4095fb21e --- /dev/null +++ b/.github/jobs/run_diff_docker.sh @@ -0,0 +1,48 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DOCKERHUB_TAG=${DOCKERHUB_REPO}:${SOURCE_BRANCH} + +# Get truth output data +${GITHUB_WORKSPACE}/.github/jobs/get_test_truth_data.sh ${TRUTH_DATA_VERSION} + +# Set up directories to mount +LOCAL_OUTPUT_DIR=${RUNNER_WORKSPACE}/output +DOCKER_OUTPUT_DIR=/data/output/met_test_output + +LOCAL_DIFF_DIR=${RUNNER_WORKSPACE}/diff +DOCKER_DIFF_DIR=/data/output/met_test_diff + +LOCAL_LOG_DIR=${RUNNER_WORKSPACE}/logs +DOCKER_LOG_DIR=/met/logs + +# Create local directories to store output +mkdir -p ${LOCAL_LOG_DIR} +mkdir -p ${LOCAL_DIFF_DIR} + +# mount output and log dirs, mount GitHub files into MET_REPO_DIR +mount_args="-v ${LOCAL_OUTPUT_DIR}:${DOCKER_OUTPUT_DIR} -v ${LOCAL_DIFF_DIR}:${DOCKER_DIFF_DIR} -v ${LOCAL_LOG_DIR}:${DOCKER_LOG_DIR}" + +# Set up data volumes +volumes_from="--volumes-from met_truth" + +# run unit test script inside Docker, mount MET output and truth data +# set MET_REPO_DIR env var in Docker to mounted directory +cmd="\${MET_REPO_DIR}/.github/jobs/run_diff_tests.sh" +time_command docker run ${volumes_from} ${mount_args} ${DOCKERHUB_TAG} bash -c \"${cmd}\" +if [ $? != 0 ]; then + exit 1 +fi + +if [ "$(ls -A ${LOCAL_DIFF_DIR})" ]; then + echo "ERROR: Differences exist in the output" + + # only exit non-zero (job fails) if not updating truth data + # this makes difference output available when updating truth data + # so it is easier to see what changed with the update + if [ "${RUN_UPDATE_TRUTH}" != "true" ]; then + exit 1 + fi + +fi diff --git a/.github/jobs/run_diff_tests.sh b/.github/jobs/run_diff_tests.sh new file mode 100755 index 0000000000..fd84a6953f --- /dev/null +++ b/.github/jobs/run_diff_tests.sh @@ -0,0 +1,33 @@ +#! /bin/bash + +source ${MET_REPO_DIR}/.github/jobs/bash_functions.sh + +### +# Set environment variables needed to run unit tests +### + +source ${MET_REPO_DIR}/.github/jobs/test_env_vars.sh + +### +# Run comparison of MET unit test output +### + +echo "Running comparison on test output" +CMD_LOGFILE=/met/logs/comp_dir.log +time_command ${MET_TEST_BASE}/bin/comp_dir.sh ${MET_TEST_TRUTH} ${MET_TEST_OUTPUT} +if [ $? != 0 ]; then + echo "ERROR: Test output comparison failed" + cat /met/logs/comp_dir.log + exit 1 +fi + +echo "Running copy_diff_files.py" +CMD_LOGFILE=/met/logs/copy_diff_files.log +time_command ${MET_REPO_DIR}/.github/jobs/copy_diff_files.py +if [ $? != 0 ]; then + echo "ERROR: Copy diff files script failed" + cat /met/logs/copy_diff_files.log + exit 1 +fi + +echo "Success" diff --git a/.github/jobs/run_unit_docker.sh b/.github/jobs/run_unit_docker.sh new file mode 100755 index 0000000000..95f4b2c626 --- /dev/null +++ b/.github/jobs/run_unit_docker.sh @@ -0,0 +1,37 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DOCKERHUB_TAG=${DOCKERHUB_REPO}:${SOURCE_BRANCH} + +# Pull MET Image from DockerHub +${GITHUB_WORKSPACE}/.github/jobs/pull_docker_image.sh ${DOCKERHUB_TAG} + +# Get test input data if needed +volumes_from="" +if [ "${INPUT_DATA_VERSION}" != "none" ]; then + ${GITHUB_WORKSPACE}/.github/jobs/get_test_input_data.sh ${INPUT_DATA_VERSION} + volumes_from=${volumes_from}"--volumes-from met_input" +fi + +# Set up directories to mount +LOCAL_OUTPUT_DIR=${RUNNER_WORKSPACE}/output +DOCKER_OUTPUT_DIR=/data/output/met_test_output + +LOCAL_LOG_DIR=${RUNNER_WORKSPACE}/logs +DOCKER_LOG_DIR=/met/logs + +# Create local directories to store output +mkdir -p ${LOCAL_LOG_DIR} +mkdir -p ${LOCAL_OUTPUT_DIR} + +mount_args="-v ${LOCAL_OUTPUT_DIR}:${DOCKER_OUTPUT_DIR} -v ${LOCAL_LOG_DIR}:${DOCKER_LOG_DIR}" + +export TESTS_TO_RUN=$TESTS + +# run unit test script inside Docker, mount MET input and truth data +cmd="\${MET_REPO_DIR}/.github/jobs/run_unit_tests.sh" +time_command docker run -e TESTS_TO_RUN ${volumes_from} ${mount_args} ${DOCKERHUB_TAG} bash -c \"${cmd}\" +if [ $? != 0 ]; then + exit 1 +fi diff --git a/.github/jobs/run_unit_tests.sh b/.github/jobs/run_unit_tests.sh new file mode 100755 index 0000000000..e866b2cc61 --- /dev/null +++ b/.github/jobs/run_unit_tests.sh @@ -0,0 +1,26 @@ +#! /bin/bash + +source ${MET_REPO_DIR}/.github/jobs/bash_functions.sh + +### +# Set environment variables needed to run unit tests +### + +source ${MET_REPO_DIR}/.github/jobs/test_env_vars.sh + +### +# Run MET unit tests +### + +echo "Running MET unit tests..." +for testname in $TESTS_TO_RUN; do + CMD_LOGFILE=/met/logs/unit_${testname}.log + time_command ${MET_TEST_BASE}/perl/unit.pl ${MET_TEST_BASE}/xml/unit_${testname}.xml + if [ $? != 0 ]; then + echo "ERROR: Unit test ${testname} failed" + cat /met/logs/unit_${testname}.log + exit 1 + fi +done + +echo "Success" diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh new file mode 100755 index 0000000000..6a4e4bdf82 --- /dev/null +++ b/.github/jobs/set_job_controls.sh @@ -0,0 +1,94 @@ +#! /bin/bash + +run_compile=true +run_push=false +run_unit_tests=false +run_diff=false +run_update_truth=false +met_base_image=minimum +input_data_version=develop +truth_data_version=develop + +if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then + + # only run diff logic if pull request INTO + # branches not ending with -ref + if [ "${GITHUB_BASE_REF: -4}" != "-ref" ]; then + + run_diff=true + + fi + +elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then + + branch_name=`cut -d "/" -f3 <<< "${GITHUB_REF}"` + + # if branch ends with -ref, update truth data from unit tests + if [ "${branch_name: -4}" == -ref ]; then + + run_update_truth=true + run_diff=true + truth_data_version=${branch_name: -4} + + else + + # if develop or main_vX.Y branch, run diff tests using branch's truth data + if [ "$branch_name" == "develop" ] || + [ "${branch_name:0:6}" == "main_v" ]; then + + run_diff=true + truth_data_version=${branch_name} + + fi + + # check commit messages for ci-skip or ci-run keywords + if grep -q "ci-skip-compile" <<< "$commit_msg"; then + + run_compile=false + + fi + + if grep -q "ci-run-unit" <<< "$commit_msg"; then + + run_diff=true + + fi + fi + +fi + +# if updating truth or running diff, run unit tests +if [ "$run_update_truth" == "true" ] || [ "$run_diff" == "true" ]; then + + run_unit_tests=true + +fi + +# if running unit tests, use unit_test MET base image and push image +if [ "$run_unit_tests" == "true" ]; then + + met_base_image=unit_test + run_push=true + +fi + +echo ::set-output name=run_compile::$run_compile +echo ::set-output name=run_push::$run_push +echo ::set-output name=run_unit_tests::$run_unit_tests +echo ::set-output name=run_diff::$run_diff +echo ::set-output name=run_update_truth::$run_update_truth +echo ::set-output name=met_base_image::$met_base_image +echo ::set-output name=input_data_version::$input_data_version +echo ::set-output name=truth_data_version::$truth_data_version + +echo run_compile: $run_compile +echo run_push: $run_push +echo run_unit_tests: $run_unit_tests +echo run_diff: $run_diff +echo run_update_truth: $run_update_truth +echo met_base_image: $met_base_image +echo input_data_version: $input_data_version +echo truth_data_version: $truth_data_version + +# get name of branch +.github/jobs/get_branch_name.sh diff --git a/.github/jobs/test_env_vars.sh b/.github/jobs/test_env_vars.sh new file mode 100755 index 0000000000..5eaaa44dd9 --- /dev/null +++ b/.github/jobs/test_env_vars.sh @@ -0,0 +1,13 @@ +export MET_BASE=/usr/local/share/met + +export MET_BUILD_BASE=${MET_REPO_DIR}/met +export MET_TEST_BASE=${MET_REPO_DIR}/test +export PERL5LIB=${MET_TEST_BASE}/lib + +export MET_TEST_INPUT=/data/input/MET_test_data/unit_test +export MET_TEST_OUTPUT=/data/output/met_test_output +export MET_TEST_TRUTH=/data/output/met_test_truth +export MET_TEST_DIFF=/data/output/met_test_diff + +export MET_TEST_RSCRIPT=/usr/bin/Rscript +export MET_TEST_MET_PYTHON_EXE=/usr/bin/python3 diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 070fa071a6..153adcb060 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -8,16 +8,29 @@ on: - 'met/docs/**' jobs: + build_met_docker: name: Handle Docker Image runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Build and Push Docker Image - run: .github/jobs/build_and_push_docker_image.sh + + - name: Get branch name + id: get_branch_name + run: echo ::set-output name=branch_name::${GITHUB_REF#"refs/heads/"} + + - name: Build Docker Image + run: .github/jobs/build_docker_image.sh + env: + SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }} + MET_BASE_IMAGE: minimum + + - name: Push Docker Image + run: .github/jobs/push_docker_image.sh env: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + trigger_metplus: name: Trigger METplus testing workflow runs-on: ubuntu-latest diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 0000000000..c114c61028 --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,377 @@ +name: Unit Tests + +# Compile MET and run unit tests +# for pull requests into develop branch + +on: + pull_request: + types: [opened, reopened, synchronize] + branches: + - develop + - 'main_v*' + push: + branches: + - 'feature_*' + - 'bugfix_*' + - 'develop' + - 'develop-ref' + - 'main_v*' + +env: + DOCKERHUB_REPO: dtcenter/met-dev + +jobs: + + job_control: + name: Determine which jobs to run + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set job controls + id: job_status + run: .github/jobs/set_job_controls.sh + env: + commit_msg: ${{ github.event.head_commit.message }} + + outputs: + run_compile: ${{ steps.job_status.outputs.run_compile }} + run_push: ${{ steps.job_status.outputs.run_push }} + run_unit_tests: ${{ steps.job_status.outputs.run_unit_tests }} + run_diff: ${{ steps.job_status.outputs.run_diff }} + run_update_truth: ${{ steps.job_status.outputs.run_update_truth }} + met_base_image: ${{ steps.job_status.outputs.met_base_image }} + branch_name: ${{ steps.job_status.outputs.branch_name }} + truth_data_version: ${{ steps.job_status.outputs.truth_data_version }} + input_data_version: ${{ steps.job_status.outputs.input_data_version }} + + compile: + name: Compile MET + runs-on: ubuntu-latest + needs: job_control + if: ${{ needs.job_control.outputs.run_compile == 'true' }} + steps: + - uses: actions/checkout@v2 + + - name: Create directories to store output + run: mkdir -p ${RUNNER_WORKSPACE}/logs + + - name: Compile MET in Docker + run: .github/jobs/build_docker_image.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + MET_BASE_IMAGE: ${{ needs.job_control.outputs.met_base_image }} + + - name: Copy Docker build log into logs directory + if: always() + run: cp ${GITHUB_WORKSPACE}/docker_build.log ${RUNNER_WORKSPACE}/logs/ + + - name: Push Docker Image + run: .github/jobs/push_docker_image.sh + if: ${{ needs.job_control.outputs.run_push == 'true' }} + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + unit_tests_1a: + name: MET Unit Tests 1a + runs-on: ubuntu-latest + needs: [job_control, compile] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + strategy: + matrix: + tests: + - 'ascii2nc' + - 'pb2nc madis2nc pcp_combine' + fail-fast: false + steps: + - uses: actions/checkout@v2 + + - name: Run Unit Tests in Docker + run: .github/jobs/run_unit_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + TESTS: ${{ matrix.tests }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + + - name: Upload output as artifact + uses: actions/upload-artifact@v2 + with: + name: unit_tests_1a + path: ${{ runner.workspace }}/output + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + unit_tests_1b: + name: MET Unit Tests 1b + runs-on: ubuntu-latest + needs: [job_control, compile] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + strategy: + matrix: + tests: + - 'ascii2nc_indy pb2nc_indy tc_dland tc_pairs tc_stat plot_tc tc_rmw rmw_analysis tc_gen' + - 'met_test_scripts mode_graphics mtd regrid airnow gsi_tools netcdf modis series_analysis gen_ens_prod wwmca_regrid gen_vx_mask grid_weight interp_shape grid_diag grib_tables lidar2nc shift_data_plane trmm2nc aeronet wwmca_plot ioda2nc gaussian' + fail-fast: false + steps: + - uses: actions/checkout@v2 + + - name: Run Unit Tests in Docker + run: .github/jobs/run_unit_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + TESTS: ${{ matrix.tests }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + + - name: Upload output as artifact + uses: actions/upload-artifact@v2 + with: + name: unit_tests_1b + path: ${{ runner.workspace }}/output + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + unit_tests_ref_config_leads: + name: MET Unit Tests ref_config leads + runs-on: ubuntu-latest + needs: [job_control, compile] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + strategy: + matrix: + tests: + - 'ref_config_lead_00 ref_config_lead_12' + - 'ref_config_lead_24 ref_config_lead_48' + - 'ref_config_lead_36' + fail-fast: false + steps: + - uses: actions/checkout@v2 + + - name: Run Unit Tests in Docker + run: .github/jobs/run_unit_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + TESTS: ${{ matrix.tests }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + + - name: Upload output as artifact + uses: actions/upload-artifact@v2 + with: + name: unit_tests_ref_config_leads + path: ${{ runner.workspace }}/output + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + unit_tests_ref_config: + name: MET Unit Tests ref_config + runs-on: ubuntu-latest + needs: [job_control, unit_tests_ref_config_leads] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + strategy: + matrix: + tests: + - 'ref_config' + fail-fast: false + steps: + - uses: actions/checkout@v2 + + - name: Download ref_config_leads output from artifact + uses: actions/download-artifact@v2 + with: + name: unit_tests_ref_config_leads + path: ${{ runner.workspace }}/output + + - name: Run Unit Tests in Docker + run: .github/jobs/run_unit_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + TESTS: ${{ matrix.tests }} + INPUT_DATA_VERSION: 'none' + + - name: Upload output as artifact + uses: actions/upload-artifact@v2 + with: + name: unit_tests_ref_config + path: ${{ runner.workspace }}/output + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + unit_tests_2a: + name: MET Unit Tests 2a + runs-on: ubuntu-latest + needs: [job_control, unit_tests_1a] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + strategy: + matrix: + tests: + - 'point_stat stat_analysis_ps' + - 'grid_stat stat_analysis_gs' + - 'wavelet_stat stat_analysis_ws' + - 'ensemble_stat stat_analysis_es' + fail-fast: false + steps: + - uses: actions/checkout@v2 + + - name: Download 1a output from artifact + uses: actions/download-artifact@v2 + with: + name: unit_tests_1a + path: ${{ runner.workspace }}/output + + - name: Run Unit Tests in Docker + run: .github/jobs/run_unit_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + TESTS: ${{ matrix.tests }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + + - name: Upload output as artifact + uses: actions/upload-artifact@v2 + with: + name: unit_tests_2a + path: ${{ runner.workspace }}/output + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + unit_tests_2b: + name: MET Unit Tests 2b + runs-on: ubuntu-latest + needs: [job_control, unit_tests_1a] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + strategy: + matrix: + tests: + - 'climatology_1.0deg' + - 'climatology_1.5deg' + - 'climatology_2.5deg' + - '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@v2 + + - name: Download 1a output from artifact + uses: actions/download-artifact@v2 + with: + name: unit_tests_1a + path: ${{ runner.workspace }}/output + + - name: Run Unit Tests in Docker + run: .github/jobs/run_unit_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + TESTS: ${{ matrix.tests }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + + - name: Upload output as artifact + uses: actions/upload-artifact@v2 + with: + name: unit_tests_2b + path: ${{ runner.workspace }}/output + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + run_diffs: + name: Check for Differences + runs-on: ubuntu-latest + needs: [job_control, unit_tests_1b, unit_tests_2a, unit_tests_2b, unit_tests_ref_config] + if: ${{ needs.job_control.outputs.run_diff == 'true' }} + steps: + - name: Download data from previous jobs + uses: actions/download-artifact@v2 + + - name: Copy test output into single directory + run: | + mkdir ${RUNNER_WORKSPACE}/output + cp -r unit_tests_*/* ${RUNNER_WORKSPACE}/output/ + + - uses: actions/checkout@v2 + + - name: Run Diff Tests in Docker + run: .github/jobs/run_diff_docker.sh + env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + RUN_UPDATE_TRUTH: ${{ needs.job_control.outputs.run_update_truth }} + TRUTH_DATA_VERSION: ${{ needs.job_control.outputs.truth_data_version }} + + - name: Upload diff files as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: diff + path: ${{ runner.workspace }}/diff + if-no-files-found: ignore + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v2 + with: + name: logs + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + + update_truth: + name: Update Truth Data + runs-on: ubuntu-latest + needs: [job_control, unit_tests_1b, unit_tests_2a, unit_tests_2b, unit_tests_ref_config] + if: ${{ needs.job_control.outputs.run_update_truth == 'true' }} + steps: + - uses: actions/checkout@v2 + + - name: Download data from previous jobs + uses: actions/download-artifact@v2 + + - name: Copy test output into single directory + run: | + mkdir ${RUNNER_WORKSPACE}/met_test_truth + cp -r unit_tests_*/* ${RUNNER_WORKSPACE}/met_test_truth/ + + - name: Create Docker Data Volume + run: .github/jobs/create_docker_truth.sh + env: + TRUTH_DATA_VERSION: ${{ needs.job_control.outputs.truth_data_version }} + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.gitignore b/.gitignore index f2060b9284..bbd74b866f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ met/docs/_build/ # tilda files generated by emacs *~ + +# log file created in Docker image +make_install.log diff --git a/met/scripts/python/read_met_point_obs.py b/met/scripts/python/read_met_point_obs.py index 15667541ec..60f2c62065 100755 --- a/met/scripts/python/read_met_point_obs.py +++ b/met/scripts/python/read_met_point_obs.py @@ -8,7 +8,7 @@ import os import sys -import time +from datetime import datetime import numpy as np import netCDF4 as nc @@ -93,8 +93,7 @@ def get_string_array(dataset, var_name): return nc_tools.get_ncbyte_array_to_str(nc_var) if nc_var else [] -perf_start_time = time.time() -perf_start_counter = time.perf_counter_ns() +start_time = datetime.now() point_obs_data = None if len(sys.argv) == 1: @@ -117,9 +116,6 @@ def get_string_array(dataset, var_name): if DO_PRINT_DATA: met_point_obs.print_point_data(met_point_data) -perf_end_time = time.time() -perf_end_counter = time.perf_counter_ns() -perf_duration = perf_end_time - perf_start_time -perf_duration_counter = (perf_end_counter - perf_start_counter) / 1000000000 +run_time = datetime.now() - start_time -print('Done python script {s} Took walltime: {t1} & perf: {t2} seconds'.format(s=sys.argv[0], t1=perf_duration, t2=perf_duration_counter)) +print('Done python script {s} took {t}'.format(s=sys.argv[0], t=run_time)) diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile index 330e0bbadd..ddeb6b0a81 100644 --- a/scripts/docker/Dockerfile +++ b/scripts/docker/Dockerfile @@ -1,4 +1,6 @@ -FROM centos:7 +ARG MET_BASE_IMAGE=minimum + +FROM dtcenter/met-base:${MET_BASE_IMAGE} MAINTAINER John Halley Gotway # @@ -17,163 +19,21 @@ RUN if [ "x${SOURCE_BRANCH}" = "x" ]; then \ fi ENV MET_GIT_NAME ${SOURCE_BRANCH} +ENV MET_REPO_DIR /met/MET-${MET_GIT_NAME} ENV MET_GIT_URL https://github.com/dtcenter/MET ENV MET_DEVELOPMENT true -# -# Define the compilers. -# -ENV CC /usr/bin/gcc -ENV CXX /usr/bin/g++ -ENV FC /usr/bin/gfortran -ENV F77 /usr/bin/gfortran - -# -# Define package URL's. -# -ENV HDF4_URL http://www.hdfgroup.org/ftp/HDF/releases/HDF4.2r3/src/HDF4.2r3.tar.gz -ENV HDFEOS_URL https://dtcenter.ucar.edu/dfiles/code/METplus/MET/docker_data/HDF-EOS2.16v1.00.tar.Z - -ENV NETCDF4C_URL https://github.com/Unidata/netcdf-c/archive/v4.4.1.1.zip -ENV NETCDF4CXX_URL https://github.com/Unidata/netcdf-cxx4/archive/v4.3.0.tar.gz - -ENV BUFRLIB_URL https://dtcenter.ucar.edu/dfiles/code/METplus/MET/docker_data/BUFRLIB_v10-2-3.tar -ENV GSFONT_URL https://dtcenter.ucar.edu/dfiles/code/METplus/MET/docker_data/ghostscript-fonts-std-8.11.tar.gz - -# -# Install the required packages. -# -RUN yum -y update \ - && yum -y install file gcc gcc-gfortran gcc-c++ glibc.i686 libgcc.i686 \ - libpng-devel jasper jasper-devel zlib zlib-devel \ - cairo-devel freetype-devel epel-release \ - hostname m4 make tar tcsh ksh time wget which \ - flex flex-devel bison bison-devel unzip \ - && yum -y install git g2clib-devel hdf5-devel.x86_64 gsl-devel \ - && yum -y install gv ncview wgrib wgrib2 ImageMagick ps2pdf \ - && yum -y install python3 python3-devel python3-pip \ - && pip3 install --upgrade pip \ - && python3 -m pip install numpy xarray netCDF4 - # # Set the working directory. # WORKDIR /met -# -# Setup the environment for interactive bash/csh container shells. -# -RUN echo export MET_BASE=/usr/local/share/met >> /etc/bashrc \ - && echo setenv MET_BASE /usr/local/share/met >> /etc/csh.cshrc \ - && echo export MET_FONT_DIR=/usr/local/share/met/fonts >> /etc/bashrc \ - && echo setenv MET_FONT_DIR /usr/local/share/met/fonts >> /etc/csh.cshrc \ - && echo export RSCRIPTS_BASE=/usr/local/share/met/Rscripts >> /etc/bashrc \ - && echo setenv RSCRIPTS_BASE /usr/local/share/met/Rscripts >> /etc/csh.cshrc \ - && echo export LD_LIBRARY_PATH=/usr/local/lib >> /etc/bashrc \ - && echo setenv LD_LIBRARY_PATH /usr/local/lib >> /etc/csh.cshrc -ENV LD_LIBRARY_PATH /usr/local/lib - -# -# Download and install BUFRLIB. -# -RUN mkdir -p /met/logs \ - && mkdir -p /met/external_libs/BUFRLIB \ - && cd /met/external_libs/BUFRLIB \ - && echo "Downloading BUFRLIB from ${BUFRLIB_URL}" \ - && curl -SL ${BUFRLIB_URL} | tar xC /met/external_libs/BUFRLIB \ - && cat preproc.sh | sed 's/cpp /cpp -traditional-cpp /g' > preproc_patch.sh \ - && chmod +x preproc_patch.sh \ - && LOG_FILE=/met/logs/BUFRLIB_build.log \ - && echo "Compiling BUFRLIB and writing log file ${LOG_FILE}" \ - && ./preproc_patch.sh *.F > ${LOG_FILE} \ - && ${CC} -c -DUNDERSCORE *.c >> ${LOG_FILE} \ - && ${FC} -c -fno-second-underscore *.f >> ${LOG_FILE} \ - && ar crv libbufr.a *.o >> ${LOG_FILE} \ - && rm -f /usr/local/lib/libbufr.a \ - && cp *.a /usr/local/lib \ - && cd /met/external_libs \ - && rm -rf BUFRLIB - -# -# Download and install NetCDF4 (C and C++). -# -RUN mkdir -p /met/external_libs/netcdf \ - && cd /met/external_libs/netcdf \ - && echo "Downloading netcdf-c-4.4.1.1 from ${NETCDF4C_URL}" \ - && wget ${NETCDF4C_URL} \ - && unzip v4.4.1.1.zip \ - && cd netcdf-c-4.4.1.1 \ - && LOG_FILE=/met/logs/netcdf-c-4.4.1.1_configure.log \ - && echo "Configuring netcdf-c-4.4.1.1 and writing log file ${LOG_FILE}" \ - && ./configure > ${LOG_FILE} \ - && LOG_FILE=/met/logs/netcdf-c-4.4.1.1_make_install.log \ - && echo "Compiling netcdf-c-4.4.1.1 and writing log file ${LOG_FILE}" \ - && make install > ${LOG_FILE} \ - && echo "Downloading from ${NETCDF4CXX_URL}" \ - && cd /met/external_libs/netcdf \ - && wget ${NETCDF4CXX_URL} \ - && tar -xzf v4.3.0.tar.gz \ - && cd netcdf-cxx4-4.3.0 \ - && LOG_FILE=/met/logs/netcdf-cxx4-4.3.0_configure.log \ - && echo "Configuring netcdf-cxx4-4.3.0 and writing log file ${LOG_FILE}" \ - && ./configure > ${LOG_FILE} \ - && LOG_FILE=/met/logs/netcdf-cxx4-4.3.0_make_install.log \ - && echo "Compiling netcdf-cxx4-4.3.0 and writing log file ${LOG_FILE}" \ - && make install > ${LOG_FILE} \ - && cd /met/external_libs \ - && rm -rf netcdf - -# -# Download and install HDF4 and HDFEOS. -# -RUN echo "Downloading HDF4.2r3 from ${HDF4_URL}" \ - && curl -SL ${HDF4_URL} | tar zxC /met/external_libs \ - && cd /met/external_libs/HDF4.2r3 \ - && LOG_FILE=/met/logs/HDF4.2r3_configure.log \ - && echo "Configuring HDF4.2r3 and writing log file ${LOG_FILE}" \ - && ./configure --prefix=/usr/local/hdf --disable-netcdf > ${LOG_FILE} \ - && cat mfhdf/hdiff/Makefile | sed 's/LIBS = -ljpeg -lz/LIBS = -ljpeg -lz -lm/g' > Makefile_NEW \ - && mv -f Makefile_NEW mfhdf/hdiff/Makefile \ - && LOG_FILE=/met/logs/HDF4.2r3_make_install.log \ - && echo "Compiling HDF4.2r3 and writing log file ${LOG_FILE}" \ - && make install > ${LOG_FILE} \ - && echo "Downloading hdfeos from ${HDFEOS_URL}" \ - && curl -SL ${HDFEOS_URL} | tar zxC /met/external_libs \ - && cd /met/external_libs/hdfeos \ - && LOG_FILE=/met/logs/hdfeos_configure.log \ - && echo "Configuring hdfeos and writing log file ${LOG_FILE}" \ - && ./configure --prefix=/usr/local/hdfeos --with-hdf4=/usr/local/hdf CC=/usr/local/hdf/bin/h4cc > ${LOG_FILE} \ - && LOG_FILE=/met/logs/hdfeos_make_install.log \ - && echo "Compiling hdfeos and writing log file ${LOG_FILE}" \ - && make install > ${LOG_FILE} \ - && mkdir /usr/local/hdfeos/include \ - && cp include/*.h /usr/local/hdfeos/include/. \ - && cd /met/external_libs \ - && rm -rf HDF4.2r3 hdfeos - # # Download and install MET and GhostScript fonts. # Delete the MET source code for tagged releases matching "v"*. # RUN echo "Checking out MET ${MET_GIT_NAME} from ${MET_GIT_URL}" \ - && git clone ${MET_GIT_URL} /met/MET-${MET_GIT_NAME} \ - && cd /met/MET-${MET_GIT_NAME}/met \ + && git clone ${MET_GIT_URL} ${MET_REPO_DIR} \ + && cd ${MET_REPO_DIR}/met \ && git checkout ${MET_GIT_NAME} \ - && LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_configure.log \ - && echo "Running bootstrap" \ - && ./bootstrap \ - && echo "Configuring MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}" \ - && ./configure --enable-grib2 --enable-mode_graphics --enable-modis --enable-lidar2nc --enable-python \ - MET_HDF=/usr/local/hdf MET_HDFEOS=/usr/local/hdfeos \ - MET_FREETYPEINC=/usr/include/freetype2 MET_FREETYPELIB=/usr/lib \ - MET_CAIROINC=/usr/include/cairo MET_CAIROLIB=/usr/lib \ - MET_PYTHON_CC='-I/usr/include/python3.6m' MET_PYTHON_LD='-lpython3.6m' > ${LOG_FILE} \ - && LOG_FILE=/met/MET-${MET_GIT_NAME}/make_install.log \ - && echo "Compiling MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}" \ - && make install > ${LOG_FILE} \ - && LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_make_test.log \ - && echo "Testing MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}" \ - && make test > ${LOG_FILE} 2>&1 \ - && if [[ $MET_GIT_NAME == "v"* ]]; then cd /met; rm -rf MET-*; fi \ - && echo "Downloading GhostScript fonts from ${GSFONT_URL}" \ - && curl -SL ${GSFONT_URL} | tar zxC /usr/local/share/met + && ../scripts/docker/build_met_docker.sh diff --git a/scripts/docker/Dockerfile.copy b/scripts/docker/Dockerfile.copy new file mode 100644 index 0000000000..18a71e4185 --- /dev/null +++ b/scripts/docker/Dockerfile.copy @@ -0,0 +1,46 @@ +ARG MET_BASE_IMAGE=minimum + +FROM dtcenter/met-base:${MET_BASE_IMAGE} +MAINTAINER John Halley Gotway + +# +# This Dockerfile checks out MET from GitHub and compiles the specified branch or tag from source. +# +ARG SOURCE_BRANCH + +# +# SOURCE_BRANCH is not defined when built via Docker Hub. +# +RUN if [ "x${SOURCE_BRANCH}" = "x" ]; then \ + echo "ERROR: SOURCE_BRANCH undefined! Rebuild with \"--build-arg SOURCE_BRANCH={branch name}\""; \ + exit 1; \ + else \ + echo "Build Argument SOURCE_BRANCH=${SOURCE_BRANCH}"; \ + fi + +ENV MET_GIT_NAME ${SOURCE_BRANCH} +ENV MET_REPO_DIR /met/MET-${MET_GIT_NAME} +ENV MET_GIT_URL https://github.com/dtcenter/MET +ENV MET_DEVELOPMENT true + +# +# Set the working directory. +# +WORKDIR /met + +# +# Download and install MET and GhostScript fonts. +# Delete the MET source code for tagged releases matching "v"*. +# +RUN echo "Copying MET into ${MET_REPO_DIR}" \ + && mkdir -p ${MET_REPO_DIR} + +COPY . ${MET_REPO_DIR} + +RUN if [ ! -e "${MET_REPO_DIR}/met/configure.ac" ]; then \ + echo "ERROR: docker build must be run from the MET directory"; \ + exit 1; \ + fi + +RUN cd ${MET_REPO_DIR}/met \ + && ../scripts/docker/build_met_docker.sh diff --git a/scripts/docker/Dockerfile.minimum b/scripts/docker/Dockerfile.minimum new file mode 100644 index 0000000000..028871196b --- /dev/null +++ b/scripts/docker/Dockerfile.minimum @@ -0,0 +1,138 @@ +FROM centos:7 +MAINTAINER John Halley Gotway + +# +# Define the compilers. +# +ENV CC /usr/bin/gcc +ENV CXX /usr/bin/g++ +ENV FC /usr/bin/gfortran +ENV F77 /usr/bin/gfortran + +# +# Define package URL's. +# +ENV HDF4_URL http://www.hdfgroup.org/ftp/HDF/releases/HDF4.2r3/src/HDF4.2r3.tar.gz +ENV HDFEOS_URL https://dtcenter.ucar.edu/dfiles/code/METplus/MET/docker_data/HDF-EOS2.16v1.00.tar.Z + +ENV NETCDF4C_URL https://github.com/Unidata/netcdf-c/archive/v4.4.1.1.zip +ENV NETCDF4CXX_URL https://github.com/Unidata/netcdf-cxx4/archive/v4.3.0.tar.gz + +ENV BUFRLIB_URL https://dtcenter.ucar.edu/dfiles/code/METplus/MET/docker_data/BUFRLIB_v10-2-3.tar +ENV GSFONT_URL https://dtcenter.ucar.edu/dfiles/code/METplus/MET/docker_data/ghostscript-fonts-std-8.11.tar.gz + +# +# Install the required packages. +# +RUN yum -y update \ + && yum -y install file gcc gcc-gfortran gcc-c++ glibc.i686 libgcc.i686 \ + libpng-devel jasper jasper-devel zlib zlib-devel \ + cairo-devel freetype-devel epel-release \ + hostname m4 make tar tcsh ksh time wget which \ + flex flex-devel bison bison-devel unzip \ + && yum -y install git g2clib-devel hdf5-devel.x86_64 gsl-devel \ + && yum -y install gv ncview wgrib wgrib2 ImageMagick ps2pdf \ + && yum -y install python3 python3-devel python3-pip \ + && pip3 install --upgrade pip \ + && python3 -m pip install numpy xarray netCDF4 + +# +# Set the working directory. +# +WORKDIR /met + +# +# Setup the environment for interactive bash/csh container shells. +# +RUN echo export MET_BASE=/usr/local/share/met >> /etc/bashrc \ + && echo setenv MET_BASE /usr/local/share/met >> /etc/csh.cshrc \ + && echo export MET_FONT_DIR=/usr/local/share/met/fonts >> /etc/bashrc \ + && echo setenv MET_FONT_DIR /usr/local/share/met/fonts >> /etc/csh.cshrc \ + && echo export RSCRIPTS_BASE=/usr/local/share/met/Rscripts >> /etc/bashrc \ + && echo setenv RSCRIPTS_BASE /usr/local/share/met/Rscripts >> /etc/csh.cshrc \ + && echo export LD_LIBRARY_PATH=/usr/local/lib >> /etc/bashrc \ + && echo setenv LD_LIBRARY_PATH /usr/local/lib >> /etc/csh.cshrc +ENV LD_LIBRARY_PATH /usr/local/lib +ENV MET_FONT_DIR /usr/local/share/met/fonts + +# +# Download and install BUFRLIB. +# +RUN mkdir -p /met/logs \ + && mkdir -p /met/external_libs/BUFRLIB \ + && cd /met/external_libs/BUFRLIB \ + && echo "Downloading BUFRLIB from ${BUFRLIB_URL}" \ + && curl -SL ${BUFRLIB_URL} | tar xC /met/external_libs/BUFRLIB \ + && cat preproc.sh | sed 's/cpp /cpp -traditional-cpp /g' > preproc_patch.sh \ + && chmod +x preproc_patch.sh \ + && LOG_FILE=/met/logs/BUFRLIB_build.log \ + && echo "Compiling BUFRLIB and writing log file ${LOG_FILE}" \ + && ./preproc_patch.sh *.F > ${LOG_FILE} \ + && ${CC} -c -DUNDERSCORE *.c >> ${LOG_FILE} \ + && ${FC} -c -fno-second-underscore *.f >> ${LOG_FILE} \ + && ar crv libbufr.a *.o >> ${LOG_FILE} \ + && rm -f /usr/local/lib/libbufr.a \ + && cp *.a /usr/local/lib \ + && cd /met/external_libs \ + && rm -rf BUFRLIB + +# +# Download and install NetCDF4 (C and C++). +# +RUN mkdir -p /met/external_libs/netcdf \ + && cd /met/external_libs/netcdf \ + && echo "Downloading netcdf-c-4.4.1.1 from ${NETCDF4C_URL}" \ + && wget ${NETCDF4C_URL} \ + && unzip v4.4.1.1.zip \ + && cd netcdf-c-4.4.1.1 \ + && LOG_FILE=/met/logs/netcdf-c-4.4.1.1_configure.log \ + && echo "Configuring netcdf-c-4.4.1.1 and writing log file ${LOG_FILE}" \ + && ./configure > ${LOG_FILE} \ + && LOG_FILE=/met/logs/netcdf-c-4.4.1.1_make_install.log \ + && echo "Compiling netcdf-c-4.4.1.1 and writing log file ${LOG_FILE}" \ + && make install > ${LOG_FILE} \ + && echo "Downloading from ${NETCDF4CXX_URL}" \ + && cd /met/external_libs/netcdf \ + && wget ${NETCDF4CXX_URL} \ + && tar -xzf v4.3.0.tar.gz \ + && cd netcdf-cxx4-4.3.0 \ + && LOG_FILE=/met/logs/netcdf-cxx4-4.3.0_configure.log \ + && echo "Configuring netcdf-cxx4-4.3.0 and writing log file ${LOG_FILE}" \ + && ./configure > ${LOG_FILE} \ + && LOG_FILE=/met/logs/netcdf-cxx4-4.3.0_make_install.log \ + && echo "Compiling netcdf-cxx4-4.3.0 and writing log file ${LOG_FILE}" \ + && make install > ${LOG_FILE} \ + && cd /met/external_libs \ + && rm -rf netcdf + +# +# Download and install HDF4 and HDFEOS. +# +RUN echo "Downloading HDF4.2r3 from ${HDF4_URL}" \ + && curl -SL ${HDF4_URL} | tar zxC /met/external_libs \ + && cd /met/external_libs/HDF4.2r3 \ + && LOG_FILE=/met/logs/HDF4.2r3_configure.log \ + && echo "Configuring HDF4.2r3 and writing log file ${LOG_FILE}" \ + && ./configure --prefix=/usr/local/hdf --disable-netcdf > ${LOG_FILE} \ + && cat mfhdf/hdiff/Makefile | sed 's/LIBS = -ljpeg -lz/LIBS = -ljpeg -lz -lm/g' > Makefile_NEW \ + && mv -f Makefile_NEW mfhdf/hdiff/Makefile \ + && LOG_FILE=/met/logs/HDF4.2r3_make_install.log \ + && echo "Compiling HDF4.2r3 and writing log file ${LOG_FILE}" \ + && make install > ${LOG_FILE} \ + && echo "Downloading hdfeos from ${HDFEOS_URL}" \ + && curl -SL ${HDFEOS_URL} | tar zxC /met/external_libs \ + && cd /met/external_libs/hdfeos \ + && LOG_FILE=/met/logs/hdfeos_configure.log \ + && echo "Configuring hdfeos and writing log file ${LOG_FILE}" \ + && ./configure --prefix=/usr/local/hdfeos --with-hdf4=/usr/local/hdf CC=/usr/local/hdf/bin/h4cc > ${LOG_FILE} \ + && LOG_FILE=/met/logs/hdfeos_make_install.log \ + && echo "Compiling hdfeos and writing log file ${LOG_FILE}" \ + && make install > ${LOG_FILE} \ + && mkdir /usr/local/hdfeos/include \ + && cp include/*.h /usr/local/hdfeos/include/. \ + && cd /met/external_libs \ + && rm -rf HDF4.2r3 hdfeos + +RUN echo "Downloading GhostScript fonts from ${GSFONT_URL} into /usr/local/share/met" \ + && mkdir -p /usr/local/share/met \ + && curl -SL ${GSFONT_URL} | tar zxC /usr/local/share/met diff --git a/scripts/docker/Dockerfile.test b/scripts/docker/Dockerfile.test new file mode 100644 index 0000000000..bc7963cb91 --- /dev/null +++ b/scripts/docker/Dockerfile.test @@ -0,0 +1,26 @@ +ARG MET_BASE_IMAGE=minimum + +FROM dtcenter/met-base:${MET_BASE_IMAGE} +MAINTAINER John Halley Gotway + +# +# Set the working directory. +# +WORKDIR /met + +# +# Download and install MET and GhostScript fonts. +# Delete the MET source code for tagged releases matching "v"*. +# +RUN echo "Installing tools needed for running MET unit tests..." \ + && echo "Installing Perl XML Parser..." \ + && yum makecache \ + && yum -y install perl-XML-Parser \ + && echo "Installing R..." \ + && yum -y install R \ + && echo "Installing R ncdf4 1.19..." \ + && wget https://cran.r-project.org/src/contrib/ncdf4_1.19.tar.gz \ + && R CMD INSTALL ncdf4_1.19.tar.gz \ + && echo "Installing NCO (for ncdiff)..." \ + && yum -y install nco \ + && echo "Finished installing unit test tools" diff --git a/scripts/docker/README.md b/scripts/docker/README.md new file mode 100644 index 0000000000..80c6acaa08 --- /dev/null +++ b/scripts/docker/README.md @@ -0,0 +1,40 @@ +# How to Use Dockerfiles + +Run all of the Docker commands from the top-level directory of the MET repository + +## Build image with minimum requirements needed to build MET + +```docker build -t dtcenter/met-base:minimum -f scripts/docker/Dockerfile.minimum . +docker push dtcenter/met-base:minimum``` + +## Build image with requirements to build MET and run MET unit tests + +```docker build -t dtcenter/met-base:unit_test -f scripts/docker/Dockerfile.test . +docker push dtcenter/met-base:unit_test``` + +## Build MET from clone + +```docker build -t dtcenter/met:${TAG_NAME} --build-arg SOURCE_BRANCH=${BRANCH_NAME} scripts/docker +docker push dtcenter/met:${TAG_NAME}``` + +where: +* TAG_NAME is the name of the DockerHub tag to create +* BRANCH_NAME is the MET branch to checkout + +## Build MET from local source code with minimum requirements + +```docker build -t dtcenter/met:${TAG_NAME} --build-arg SOURCE_BRANCH=${BRANCH_NAME} -f scripts/docker/Dockerfile.copy . +docker push dtcenter/met:${TAG_NAME}``` + +where: +* TAG_NAME is the name of the DockerHub tag to create +* BRANCH_NAME is the identifier to use for $MET_GIT_NAME inside image + +## Build MET from local source code with unit test requirements + +```docker build -t dtcenter/met:${TAG_NAME} --build-arg SOURCE_BRANCH=${BRANCH_NAME} --build-arg MET_BASE_IMAGE=unit_test -f scripts/docker/Dockerfile.copy . +docker push dtcenter/met:${TAG_NAME}``` + +where: +* TAG_NAME is the name of the DockerHub tag to create +* BRANCH_NAME is the identifier to use for $MET_GIT_NAME inside image diff --git a/scripts/docker/build_met_docker.sh b/scripts/docker/build_met_docker.sh new file mode 100755 index 0000000000..fae3682113 --- /dev/null +++ b/scripts/docker/build_met_docker.sh @@ -0,0 +1,37 @@ +#! /bin/bash + +echo "Running script to build MET in Docker" + +LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_configure.log + +echo "Running bootstrap" +./bootstrap + +echo "Configuring MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}" +./configure --enable-grib2 --enable-mode_graphics --enable-modis --enable-lidar2nc --enable-python \ + MET_HDF=/usr/local/hdf MET_HDFEOS=/usr/local/hdfeos \ + MET_FREETYPEINC=/usr/include/freetype2 MET_FREETYPELIB=/usr/lib \ + MET_CAIROINC=/usr/include/cairo MET_CAIROLIB=/usr/lib \ + MET_PYTHON_CC='-I/usr/include/python3.6m' MET_PYTHON_LD='-lpython3.6m' > ${LOG_FILE} +if [ $? != 0 ]; then + exit 1 +fi + +LOG_FILE=/met/MET-${MET_GIT_NAME}/make_install.log +echo "Compiling MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}" +make install > ${LOG_FILE} +if [ $? != 0 ]; then + exit 1 +fi + +LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_make_test.log +echo "Testing MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}" +make test > ${LOG_FILE} 2>&1 +if [ $? != 0 ]; then + exit 1 +fi + + +if [[ $MET_GIT_NAME == "v"* ]]; then + cd /met; rm -rf MET-*; +fi diff --git a/test/bin/unit_test.sh b/test/bin/unit_test.sh index fd1c7149cb..0c95bba7ac 100755 --- a/test/bin/unit_test.sh +++ b/test/bin/unit_test.sh @@ -35,20 +35,25 @@ PERL_UNIT=${MET_TEST_BASE}/perl/unit.pl # Unit test XML UNIT_XML="unit_ascii2nc.xml \ + unit_ascii2nc_indy.xml \ unit_madis2nc.xml \ unit_trmm2nc.xml \ unit_pb2nc.xml \ + unit_pb2nc_indy.xml \ unit_gen_vx_mask.xml \ unit_gen_ens_prod.xml \ unit_pcp_combine.xml \ unit_wwmca_regrid.xml \ unit_point_stat.xml \ + unit_stat_analysis_ps.xml \ unit_duplicate_flag.xml \ unit_obs_summary.xml \ unit_grid_stat.xml \ + unit_stat_analysis_gs.xml \ unit_wavelet_stat.xml \ + unit_stat_analysis_ws.xml \ unit_ensemble_stat.xml \ - unit_stat_analysis.xml \ + unit_stat_analysis_es.xml \ unit_mode.xml \ unit_mode_analysis.xml \ unit_plot_point_obs.xml \ @@ -64,6 +69,11 @@ UNIT_XML="unit_ascii2nc.xml \ unit_tc_gen.xml \ unit_met_test_scripts.xml \ unit_modis.xml \ + unit_ref_config_lead_00.xml \ + unit_ref_config_lead_12.xml \ + unit_ref_config_lead_24.xml \ + unit_ref_config_lead_36.xml \ + unit_ref_config_lead_48.xml \ unit_ref_config.xml \ unit_mode_graphics.xml \ unit_regrid.xml \ @@ -71,7 +81,9 @@ UNIT_XML="unit_ascii2nc.xml \ unit_aeronet.xml \ unit_shift_data_plane.xml \ unit_mtd.xml \ - unit_climatology.xml \ + unit_climatology_1.0deg.xml \ + unit_climatology_1.5deg.xml \ + unit_climatology_2.5deg.xml \ unit_grib_tables.xml \ unit_grid_weight.xml \ unit_netcdf.xml \ diff --git a/test/xml/unit_ascii2nc.xml b/test/xml/unit_ascii2nc.xml index 11c46a3ea5..feef57c65d 100644 --- a/test/xml/unit_ascii2nc.xml +++ b/test/xml/unit_ascii2nc.xml @@ -13,6 +13,8 @@ + + &TEST_DIR; @@ -30,18 +32,6 @@ - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/trmm/TRMM_3B42.007.accumulated_precipitation.22:30Z07Aug2012-10:30Z08Aug2012.G3.output.mtxt \ - &OUTPUT_DIR;/ascii2nc/trmm_2008080812_12hr.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/trmm_2008080812_12hr.nc - - - &MET_BIN;/ascii2nc \ @@ -66,44 +56,6 @@ - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/ascii/qc_out_2012-09-07_00:00:00.GRM_P+FCST \ - &OUTPUT_DIR;/ascii2nc/qc_out_2012-09-07_00:00:00.GRM_P_FCST.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/qc_out_2012-09-07_00:00:00.GRM_P_FCST.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/ascii/OBS:2015080700_bad_record \ - &OUTPUT_DIR;/ascii2nc/OBS_2015080700_bad_record.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/OBS_2015080700_bad_record.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/ascii/surfrad_tbl12136.txt \ - &DATA_DIR_OBS;/ascii/surfrad_tbl12137.txt \ - &DATA_DIR_OBS;/ascii/surfrad_tbl12138.txt \ - &OUTPUT_DIR;/ascii2nc/surfrad_tbl12.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/surfrad_tbl12.nc - - - &MET_BIN;/ascii2nc \ @@ -118,92 +70,6 @@ - - &MET_BIN;/ascii2nc - - BEG_TS 000000 - END_TS 235959 - STEP_TS 300 - WIDTH_TS 300 - - \ - &DATA_DIR_OBS;/surfrad/tbl12001.dat \ - &DATA_DIR_OBS;/surfrad/tbl12002.dat \ - &DATA_DIR_OBS;/surfrad/tbl12003.dat \ - -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ - &OUTPUT_DIR;/ascii2nc/surfrad_summary1.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/surfrad_summary1.nc - - - - - &MET_BIN;/ascii2nc - - BEG_TS 03 - END_TS 20 - STEP_TS 300 - WIDTH_TS 600 - - \ - &DATA_DIR_OBS;/surfrad/tbl12001.dat \ - &DATA_DIR_OBS;/surfrad/tbl12002.dat \ - &DATA_DIR_OBS;/surfrad/tbl12003.dat \ - -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ - &OUTPUT_DIR;/ascii2nc/surfrad_summary2.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/surfrad_summary2.nc - - - - - &MET_BIN;/ascii2nc - - BEG_TS 17 - END_TS 03 - STEP_TS 420 - WIDTH_TS 420 - - \ - &DATA_DIR_OBS;/surfrad/tbl12001.dat \ - &DATA_DIR_OBS;/surfrad/tbl12002.dat \ - &DATA_DIR_OBS;/surfrad/tbl12003.dat \ - -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ - &OUTPUT_DIR;/ascii2nc/surfrad_summary3.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/surfrad_summary3.nc - - - - - - - &MET_BIN;/ascii2nc - - BEG_TS 17 - END_TS 03 - STEP_TS 420 - WIDTH_TS {beg=-420;end=0;} - - \ - &DATA_DIR_OBS;/surfrad/tbl12001.dat \ - &DATA_DIR_OBS;/surfrad/tbl12002.dat \ - &DATA_DIR_OBS;/surfrad/tbl12003.dat \ - -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ - &OUTPUT_DIR;/ascii2nc/surfrad_summary4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/surfrad_summary4.nc - - - &MET_BIN;/ascii2nc \ @@ -223,187 +89,6 @@ - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.13.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.14.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.15.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.16.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.17.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.18.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.19.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.20.ascii \ - &OUTPUT_DIR;/ascii2nc/edr_hourly.20130827.mask_sid.nc \ - -mask_sid "MY_STATIONS:N526UA,N567UA,N571UA,N594UA" \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/edr_hourly.20130827.mask_sid.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.13.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.14.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.15.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.16.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.17.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.18.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.19.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.20.ascii \ - &OUTPUT_DIR;/ascii2nc/edr_hourly.20130827.mask_grid_data.nc \ - -mask_grid &TEST_DIR;/data/mnc/test_grid_valid.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/edr_hourly.20130827.mask_grid_data.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.13.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.14.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.15.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.16.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.17.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.18.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.19.ascii \ - &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.20.ascii \ - &OUTPUT_DIR;/ascii2nc/edr_hourly.20130827.mask_named_grid.nc \ - -mask_grid G212 -v 1 - - - &OUTPUT_DIR;/ascii2nc/edr_hourly.20130827.mask_named_grid.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/trmm/TRMM_3B42.007.accumulated_precipitation.10:30Z09Apr2012.G3.output.mtxt \ - &OUTPUT_DIR;/ascii2nc/trmm_2012040912_3hr_mask_grid_dtc165.nc \ - -mask_grid DTC165 \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/trmm_2012040912_3hr_mask_grid_dtc165.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/trmm/TRMM_3B42.007.accumulated_precipitation.10:30Z09Apr2012.G3.output.mtxt \ - &OUTPUT_DIR;/ascii2nc/trmm_2012040912_3hr_mask_poly_lmv.nc \ - -mask_poly &MET_BASE;/poly/LMV.poly \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/trmm_2012040912_3hr_mask_poly_lmv.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_five_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_five_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_five_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_ten_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_ten_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_ten_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/clear_pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/HA_pvwatts_315510615_2006_30MW_sixty_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/HA_pvwatts_315510615_2006_30MW_sixty_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/HA_pvwatts_315510615_2006_30MW_sixty_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/wwsis/pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.csv \ - &OUTPUT_DIR;/ascii2nc/pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc - - - - - &MET_BIN;/ascii2nc - \ - &DATA_DIR_OBS;/ascii/obs_test_name.txt \ - &OUTPUT_DIR;/ascii2nc/obs_test_name.nc \ - -v 1 - - - &OUTPUT_DIR;/ascii2nc/obs_test_name.nc - - - &MET_BIN;/ascii2nc \ diff --git a/test/xml/unit_ascii2nc_indy.xml b/test/xml/unit_ascii2nc_indy.xml new file mode 100644 index 0000000000..11ba012820 --- /dev/null +++ b/test/xml/unit_ascii2nc_indy.xml @@ -0,0 +1,340 @@ + + + + + + + + + + +]> + + + + + + + + &TEST_DIR; + true + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/trmm/TRMM_3B42.007.accumulated_precipitation.22:30Z07Aug2012-10:30Z08Aug2012.G3.output.mtxt \ + &OUTPUT_DIR;/ascii2nc_indy/trmm_2008080812_12hr.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/trmm_2008080812_12hr.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/ascii/qc_out_2012-09-07_00:00:00.GRM_P+FCST \ + &OUTPUT_DIR;/ascii2nc_indy/qc_out_2012-09-07_00_00_00.GRM_P_FCST.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/qc_out_2012-09-07_00_00_00.GRM_P_FCST.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/ascii/OBS:2015080700_bad_record \ + &OUTPUT_DIR;/ascii2nc_indy/OBS_2015080700_bad_record.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/OBS_2015080700_bad_record.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/ascii/surfrad_tbl12136.txt \ + &DATA_DIR_OBS;/ascii/surfrad_tbl12137.txt \ + &DATA_DIR_OBS;/ascii/surfrad_tbl12138.txt \ + &OUTPUT_DIR;/ascii2nc_indy/surfrad_tbl12.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/surfrad_tbl12.nc + + + + + &MET_BIN;/ascii2nc + + BEG_TS 000000 + END_TS 235959 + STEP_TS 300 + WIDTH_TS 300 + + \ + &DATA_DIR_OBS;/surfrad/tbl12001.dat \ + &DATA_DIR_OBS;/surfrad/tbl12002.dat \ + &DATA_DIR_OBS;/surfrad/tbl12003.dat \ + -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary1.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary1.nc + + + + + &MET_BIN;/ascii2nc + + BEG_TS 03 + END_TS 20 + STEP_TS 300 + WIDTH_TS 600 + + \ + &DATA_DIR_OBS;/surfrad/tbl12001.dat \ + &DATA_DIR_OBS;/surfrad/tbl12002.dat \ + &DATA_DIR_OBS;/surfrad/tbl12003.dat \ + -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary2.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary2.nc + + + + + &MET_BIN;/ascii2nc + + BEG_TS 17 + END_TS 03 + STEP_TS 420 + WIDTH_TS 420 + + \ + &DATA_DIR_OBS;/surfrad/tbl12001.dat \ + &DATA_DIR_OBS;/surfrad/tbl12002.dat \ + &DATA_DIR_OBS;/surfrad/tbl12003.dat \ + -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary3.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary3.nc + + + + + + + &MET_BIN;/ascii2nc + + BEG_TS 17 + END_TS 03 + STEP_TS 420 + WIDTH_TS {beg=-420;end=0;} + + \ + &DATA_DIR_OBS;/surfrad/tbl12001.dat \ + &DATA_DIR_OBS;/surfrad/tbl12002.dat \ + &DATA_DIR_OBS;/surfrad/tbl12003.dat \ + -config &CONFIG_DIR;/Ascii2NcConfig.surfrad \ + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/surfrad_summary4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.13.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.14.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.15.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.16.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.17.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.18.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.19.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.20.ascii \ + &OUTPUT_DIR;/ascii2nc_indy/edr_hourly.20130827.mask_sid.nc \ + -mask_sid "MY_STATIONS:N526UA,N567UA,N571UA,N594UA" \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/edr_hourly.20130827.mask_sid.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.13.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.14.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.15.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.16.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.17.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.18.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.19.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.20.ascii \ + &OUTPUT_DIR;/ascii2nc_indy/edr_hourly.20130827.mask_grid_data.nc \ + -mask_grid &TEST_DIR;/data/mnc/test_grid_valid.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/edr_hourly.20130827.mask_grid_data.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.13.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.14.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.15.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.16.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.17.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.18.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.19.ascii \ + &DATA_DIR_OBS;/insitu_ascii/20130827/edr_hourly.20130827.20.ascii \ + &OUTPUT_DIR;/ascii2nc_indy/edr_hourly.20130827.mask_named_grid.nc \ + -mask_grid G212 -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/edr_hourly.20130827.mask_named_grid.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/trmm/TRMM_3B42.007.accumulated_precipitation.10:30Z09Apr2012.G3.output.mtxt \ + &OUTPUT_DIR;/ascii2nc_indy/trmm_2012040912_3hr_mask_grid_dtc165.nc \ + -mask_grid DTC165 \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/trmm_2012040912_3hr_mask_grid_dtc165.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/trmm/TRMM_3B42.007.accumulated_precipitation.10:30Z09Apr2012.G3.output.mtxt \ + &OUTPUT_DIR;/ascii2nc_indy/trmm_2012040912_3hr_mask_poly_lmv.nc \ + -mask_poly &MET_BASE;/poly/LMV.poly \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/trmm_2012040912_3hr_mask_poly_lmv.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_five_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_five_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_five_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_ten_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_ten_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_ten_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/clear_pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/clear_pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/HA_pvwatts_315510615_2006_30MW_sixty_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/HA_pvwatts_315510615_2006_30MW_sixty_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/HA_pvwatts_315510615_2006_30MW_sixty_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/pvwatts_315510615_2006_pv_30MW_one_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/wwsis/pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.csv \ + &OUTPUT_DIR;/ascii2nc_indy/pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/pvwatts_315510615_2006_pv_30MW_sixty_min_v3pt4.nc + + + + + &MET_BIN;/ascii2nc + \ + &DATA_DIR_OBS;/ascii/obs_test_name.txt \ + &OUTPUT_DIR;/ascii2nc_indy/obs_test_name.nc \ + -v 1 + + + &OUTPUT_DIR;/ascii2nc_indy/obs_test_name.nc + + + + diff --git a/test/xml/unit_climatology.xml b/test/xml/unit_climatology.xml deleted file mode 100644 index d50dc86ccf..0000000000 --- a/test/xml/unit_climatology.xml +++ /dev/null @@ -1,361 +0,0 @@ - - - - - - - - - - -]> - - - - - - &TEST_DIR; - true - - - &MET_BIN;/point_stat - - OUTPUT_PREFIX GFS_CLIMO_2.5DEG - DAY_INTERVAL 31 - HOUR_INTERVAL 6 - CLIMO_MEAN_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19590315", - "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19590415" - - - CLIMO_STDEV_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19590315", - "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19590415" - - - - \ - &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ - &CONFIG_DIR;/PointStatConfig_climo \ - -outdir &OUTPUT_DIR;/climatology -v 4 - - - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V.stat - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_cnt.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_sl1l2.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_sal1l2.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_mpr.txt - - - - - &MET_BIN;/point_stat - - OUTPUT_PREFIX GFS_CLIMO_1.0DEG - DAY_INTERVAL 1 - HOUR_INTERVAL 6 - CLIMO_MEAN_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409" - - - CLIMO_STDEV_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409" - - - - \ - &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ - &CONFIG_DIR;/PointStatConfig_climo \ - -outdir &OUTPUT_DIR;/climatology -v 4 - - - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V.stat - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_cnt.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_sl1l2.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_sal1l2.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_mpr.txt - - - - - &MET_BIN;/point_stat - - OUTPUT_PREFIX GFS_CLIMO_PREV_MONTH - DAY_INTERVAL NA - HOUR_INTERVAL 6 - CLIMO_MEAN_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590309" - - - CLIMO_STDEV_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590309" - - - - \ - &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ - &CONFIG_DIR;/PointStatConfig_climo \ - -outdir &OUTPUT_DIR;/climatology -v 4 - - - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V.stat - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_cnt.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_sl1l2.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_sal1l2.txt - &OUTPUT_DIR;/climatology/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_mpr.txt - - - - - &MET_BIN;/point_stat - - OUTPUT_PREFIX WMO_CLIMO_1.5DEG - CLIMO_DIR &DATA_DIR_CLIMO;/ERA_DAILY_1.5deg - - \ - &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ - &CONFIG_DIR;/PointStatConfig_climo_WMO \ - -outdir &OUTPUT_DIR;/climatology -v 4 - - - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V.stat - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_ctc.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_cnt.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_sl1l2.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_sal1l2.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_vl1l2.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_val1l2.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_pct.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_pstd.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_ecnt.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_rps.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_mpr.txt - &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_vcnt.txt - - - - - &MET_BIN;/stat_analysis - - OUTPUT_DIR &OUTPUT_DIR;/climatology - - \ - -lookin &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V.stat \ - -job aggregate_stat -line_type MPR -out_line_type CTC -fcst_lev P850 -interp_mthd NEAREST -by FCST_VAR -out_thresh '>CDP90' \ - -out_stat &OUTPUT_DIR;/climatology/stat_analysis_WMO_1.5DEG_MPR_to_CTC_out.stat - - - &OUTPUT_DIR;/climatology/stat_analysis_WMO_1.5DEG_MPR_to_CTC_out.stat - - - - - &MET_BIN;/stat_analysis - - OUTPUT_DIR &OUTPUT_DIR;/climatology - - \ - -lookin &OUTPUT_DIR;/climatology/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V.stat \ - -job filter -line_type MPR -column_thresh CLIMO_CDF 'lt0.1||gt0.9' \ - -dump_row &OUTPUT_DIR;/climatology/stat_analysis_WMO_1.5DEG_FILTER_CDF_dump.stat - - - &OUTPUT_DIR;/climatology/stat_analysis_WMO_1.5DEG_FILTER_CDF_dump.stat - - - - - &MET_BIN;/grid_stat - - OUTPUT_PREFIX WMO_CLIMO_1.5DEG - CLIMO_DIR &DATA_DIR_CLIMO;/ERA_DAILY_1.5deg - - \ - &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F024.grib2 \ - &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0000_000.grb2 \ - &CONFIG_DIR;/GridStatConfig_climo_WMO \ - -outdir &OUTPUT_DIR;/climatology -v 2 - - - &OUTPUT_DIR;/climatology/grid_stat_WMO_CLIMO_1.5DEG_240000L_20120410_000000V.stat - &OUTPUT_DIR;/climatology/grid_stat_WMO_CLIMO_1.5DEG_240000L_20120410_000000V_pairs.nc - - - - - &MET_BIN;/point_stat - - OUTPUT_PREFIX PROB_GFS_CLIMO_1.0DEG - DAY_INTERVAL 1 - CLIMO_MEAN_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409" - - - CLIMO_STDEV_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409" - - - - \ - &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F015.grib2 \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ - &CONFIG_DIR;/PointStatConfig_climo_prob \ - -outdir &OUTPUT_DIR;/climatology -v 4 - - - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V.stat - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pct.txt - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pstd.txt - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pjc.txt - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_prc.txt - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_eclv.txt - &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_mpr.txt - - - - - &MET_BIN;/grid_stat - - OUTPUT_PREFIX PROB_GFS_CLIMO_1.0DEG - DAY_INTERVAL 1 - CLIMO_MEAN_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409" - - - CLIMO_STDEV_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409" - - - - \ - &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F015.grib2 \ - &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \ - &CONFIG_DIR;/GridStatConfig_climo_prob \ - -outdir &OUTPUT_DIR;/climatology -v 4 - - - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V.stat - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pct.txt - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pstd.txt - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pjc.txt - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_prc.txt - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_eclv.txt - &OUTPUT_DIR;/climatology/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pairs.nc - - - - - &MET_BIN;/stat_analysis - - OUTPUT_DIR &OUTPUT_DIR;/climatology - - \ - -lookin &OUTPUT_DIR;/climatology/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V.stat \ - -config &CONFIG_DIR;/STATAnalysisConfig_climo \ - -v 4 - - - &OUTPUT_DIR;/climatology/stat_analysis_MPR_to_PSTD.stat - - - - - &MET_BIN;/series_analysis - - CLIMO_MEAN_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409", - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410", - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590411" - - - CLIMO_STDEV_FILE_LIST - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409", - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590410", - "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590411" - - - - \ - -fcst &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F012.grib2 \ - &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F024.grib2 \ - &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F036.grib2 \ - &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F048.grib2 \ - -obs &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \ - &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0000_000.grb2 \ - &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_1200_000.grb2 \ - &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120411_0000_000.grb2 \ - -paired \ - -out &OUTPUT_DIR;/climatology/series_analysis_GFS_CLIMO_1.0DEG.nc \ - -config &CONFIG_DIR;/SeriesAnalysisConfig_climo \ - -v 2 - - - &OUTPUT_DIR;/climatology/series_analysis_GFS_CLIMO_1.0DEG.nc - - - - - echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib" \ - > &OUTPUT_DIR;/climatology/ensemble_stat_input_file_list; \ - &MET_BIN;/ensemble_stat - - OUTPUT_PREFIX NCEP_1.0DEG - CLIMO_MEAN_FILE_LIST "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410" - CLIMO_STDEV_FILE_LIST "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590410" - - \ - &OUTPUT_DIR;/climatology/ensemble_stat_input_file_list \ - &CONFIG_DIR;/EnsembleStatConfig_climo \ - -point_obs &OUTPUT_DIR;/pb2nc/ndas.20120410.t12z.prepbufr.tm00.nc \ - -grid_obs &DATA_DIR_OBS;/laps/laps_2012041012_F000.grib \ - -outdir &OUTPUT_DIR;/climatology - - - &OUTPUT_DIR;/climatology/ensemble_stat_NCEP_1.0DEG_20120410_120000V.stat - &OUTPUT_DIR;/climatology/ensemble_stat_NCEP_1.0DEG_20120410_120000V_ecnt.txt - &OUTPUT_DIR;/climatology/ensemble_stat_NCEP_1.0DEG_20120410_120000V_orank.txt - &OUTPUT_DIR;/climatology/ensemble_stat_NCEP_1.0DEG_20120410_120000V_ens.nc - &OUTPUT_DIR;/climatology/ensemble_stat_NCEP_1.0DEG_20120410_120000V_orank.nc - - - - - - - echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ - &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib" \ - > &OUTPUT_DIR;/climatology/ensemble_stat_input_file_list; \ - &MET_BIN;/ensemble_stat - - OUTPUT_PREFIX ONE_CDF_BIN - CLIMO_MEAN_FILE_LIST "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410" - - \ - &OUTPUT_DIR;/climatology/ensemble_stat_input_file_list \ - &CONFIG_DIR;/EnsembleStatConfig_one_cdf_bin \ - -point_obs &OUTPUT_DIR;/pb2nc/ndas.20120410.t12z.prepbufr.tm00.nc \ - -grid_obs &DATA_DIR_OBS;/laps/laps_2012041012_F000.grib \ - -outdir &OUTPUT_DIR;/climatology - - - &OUTPUT_DIR;/climatology/ensemble_stat_ONE_CDF_BIN_20120410_120000V.stat - &OUTPUT_DIR;/climatology/ensemble_stat_ONE_CDF_BIN_20120410_120000V_ecnt.txt - &OUTPUT_DIR;/climatology/ensemble_stat_ONE_CDF_BIN_20120410_120000V_ens.nc - - - - diff --git a/test/xml/unit_climatology_1.0deg.xml b/test/xml/unit_climatology_1.0deg.xml new file mode 100644 index 0000000000..8fad5f3be1 --- /dev/null +++ b/test/xml/unit_climatology_1.0deg.xml @@ -0,0 +1,252 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + &MET_BIN;/point_stat + + OUTPUT_PREFIX GFS_CLIMO_1.0DEG + DAY_INTERVAL 1 + HOUR_INTERVAL 6 + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409" + + + + \ + &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &CONFIG_DIR;/PointStatConfig_climo \ + -outdir &OUTPUT_DIR;/climatology_1.0deg -v 4 + + + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V.stat + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_cnt.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_sl1l2.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_sal1l2.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_1.0DEG_120000L_20120409_120000V_mpr.txt + + + + + &MET_BIN;/point_stat + + OUTPUT_PREFIX GFS_CLIMO_PREV_MONTH + DAY_INTERVAL NA + HOUR_INTERVAL 6 + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590309" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590309" + + + + \ + &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &CONFIG_DIR;/PointStatConfig_climo \ + -outdir &OUTPUT_DIR;/climatology_1.0deg -v 4 + + + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V.stat + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_cnt.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_sl1l2.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_sal1l2.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_GFS_CLIMO_PREV_MONTH_120000L_20120409_120000V_mpr.txt + + + + + &MET_BIN;/point_stat + + OUTPUT_PREFIX PROB_GFS_CLIMO_1.0DEG + DAY_INTERVAL 1 + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409" + + + + \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F015.grib2 \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &CONFIG_DIR;/PointStatConfig_climo_prob \ + -outdir &OUTPUT_DIR;/climatology_1.0deg -v 4 + + + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V.stat + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pct.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pstd.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pjc.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_prc.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_eclv.txt + &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_mpr.txt + + + + + &MET_BIN;/grid_stat + + OUTPUT_PREFIX PROB_GFS_CLIMO_1.0DEG + DAY_INTERVAL 1 + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409" + + + + \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F015.grib2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \ + &CONFIG_DIR;/GridStatConfig_climo_prob \ + -outdir &OUTPUT_DIR;/climatology_1.0deg -v 4 + + + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V.stat + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pct.txt + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pstd.txt + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pjc.txt + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_prc.txt + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_eclv.txt + &OUTPUT_DIR;/climatology_1.0deg/grid_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V_pairs.nc + + + + + &MET_BIN;/stat_analysis + + OUTPUT_DIR &OUTPUT_DIR;/climatology_1.0deg + + \ + -lookin &OUTPUT_DIR;/climatology_1.0deg/point_stat_PROB_GFS_CLIMO_1.0DEG_150000L_20120409_120000V.stat \ + -config &CONFIG_DIR;/STATAnalysisConfig_climo \ + -v 4 + + + &OUTPUT_DIR;/climatology_1.0deg/stat_analysis_MPR_to_PSTD.stat + + + + + &MET_BIN;/series_analysis + + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590411" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590410", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590411" + + + + \ + -fcst &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F012.grib2 \ + &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F024.grib2 \ + &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F036.grib2 \ + &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F048.grib2 \ + -obs &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0000_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_1200_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120411_0000_000.grb2 \ + -paired \ + -out &OUTPUT_DIR;/climatology_1.0deg/series_analysis_GFS_CLIMO_1.0DEG.nc \ + -config &CONFIG_DIR;/SeriesAnalysisConfig_climo \ + -v 2 + + + &OUTPUT_DIR;/climatology_1.0deg/series_analysis_GFS_CLIMO_1.0DEG.nc + + + + + echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib" \ + > &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_input_file_list; \ + &MET_BIN;/ensemble_stat + + OUTPUT_PREFIX NCEP_1.0DEG + CLIMO_MEAN_FILE_LIST "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410" + CLIMO_STDEV_FILE_LIST "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590410" + + \ + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_input_file_list \ + &CONFIG_DIR;/EnsembleStatConfig_climo \ + -point_obs &OUTPUT_DIR;/pb2nc/ndas.20120410.t12z.prepbufr.tm00.nc \ + -grid_obs &DATA_DIR_OBS;/laps/laps_2012041012_F000.grib \ + -outdir &OUTPUT_DIR;/climatology_1.0deg + + + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V.stat + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_ecnt.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_orank.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_ens.nc + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_orank.nc + + + + + + + echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib" \ + > &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_input_file_list; \ + &MET_BIN;/ensemble_stat + + OUTPUT_PREFIX ONE_CDF_BIN + CLIMO_MEAN_FILE_LIST "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410" + + \ + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_input_file_list \ + &CONFIG_DIR;/EnsembleStatConfig_one_cdf_bin \ + -point_obs &OUTPUT_DIR;/pb2nc/ndas.20120410.t12z.prepbufr.tm00.nc \ + -grid_obs &DATA_DIR_OBS;/laps/laps_2012041012_F000.grib \ + -outdir &OUTPUT_DIR;/climatology_1.0deg + + + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_ONE_CDF_BIN_20120410_120000V.stat + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_ONE_CDF_BIN_20120410_120000V_ecnt.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_ONE_CDF_BIN_20120410_120000V_ens.nc + + + + diff --git a/test/xml/unit_climatology_1.5deg.xml b/test/xml/unit_climatology_1.5deg.xml new file mode 100644 index 0000000000..52dd69897b --- /dev/null +++ b/test/xml/unit_climatology_1.5deg.xml @@ -0,0 +1,98 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + &MET_BIN;/point_stat + + OUTPUT_PREFIX WMO_CLIMO_1.5DEG + CLIMO_DIR &DATA_DIR_CLIMO;/ERA_DAILY_1.5deg + + \ + &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &CONFIG_DIR;/PointStatConfig_climo_WMO \ + -outdir &OUTPUT_DIR;/climatology_1.5deg -v 4 + + + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V.stat + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_ctc.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_cnt.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_sl1l2.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_sal1l2.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_vl1l2.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_val1l2.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_pct.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_pstd.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_ecnt.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_rps.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_mpr.txt + &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V_vcnt.txt + + + + + &MET_BIN;/stat_analysis + + OUTPUT_DIR &OUTPUT_DIR;/climatology_1.5deg + + \ + -lookin &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V.stat \ + -job aggregate_stat -line_type MPR -out_line_type CTC -fcst_lev P850 -interp_mthd NEAREST -by FCST_VAR -out_thresh '>CDP90' \ + -out_stat &OUTPUT_DIR;/climatology_1.5deg/stat_analysis_WMO_1.5DEG_MPR_to_CTC_out.stat + + + &OUTPUT_DIR;/climatology_1.5deg/stat_analysis_WMO_1.5DEG_MPR_to_CTC_out.stat + + + + + &MET_BIN;/stat_analysis + + OUTPUT_DIR &OUTPUT_DIR;/climatology_1.5deg + + \ + -lookin &OUTPUT_DIR;/climatology_1.5deg/point_stat_WMO_CLIMO_1.5DEG_120000L_20120409_120000V.stat \ + -job filter -line_type MPR -column_thresh CLIMO_CDF 'lt0.1||gt0.9' \ + -dump_row &OUTPUT_DIR;/climatology_1.5deg/stat_analysis_WMO_1.5DEG_FILTER_CDF_dump.stat + + + &OUTPUT_DIR;/climatology_1.5deg/stat_analysis_WMO_1.5DEG_FILTER_CDF_dump.stat + + + + + &MET_BIN;/grid_stat + + OUTPUT_PREFIX WMO_CLIMO_1.5DEG + CLIMO_DIR &DATA_DIR_CLIMO;/ERA_DAILY_1.5deg + + \ + &DATA_DIR_MODEL;/grib2/gfs/gfs_2012040900_F024.grib2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0000_000.grb2 \ + &CONFIG_DIR;/GridStatConfig_climo_WMO \ + -outdir &OUTPUT_DIR;/climatology_1.5deg -v 2 + + + &OUTPUT_DIR;/climatology_1.5deg/grid_stat_WMO_CLIMO_1.5DEG_240000L_20120410_000000V.stat + &OUTPUT_DIR;/climatology_1.5deg/grid_stat_WMO_CLIMO_1.5DEG_240000L_20120410_000000V_pairs.nc + + + + diff --git a/test/xml/unit_climatology_2.5deg.xml b/test/xml/unit_climatology_2.5deg.xml new file mode 100644 index 0000000000..7c8c0b300a --- /dev/null +++ b/test/xml/unit_climatology_2.5deg.xml @@ -0,0 +1,53 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + &MET_BIN;/point_stat + + OUTPUT_PREFIX GFS_CLIMO_2.5DEG + DAY_INTERVAL 31 + HOUR_INTERVAL 6 + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19590315", + "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19590415" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19590315", + "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19590415" + + + + \ + &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F012.grib \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &CONFIG_DIR;/PointStatConfig_climo \ + -outdir &OUTPUT_DIR;/climatology_2.5deg -v 4 + + + &OUTPUT_DIR;/climatology_2.5deg/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V.stat + &OUTPUT_DIR;/climatology_2.5deg/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_cnt.txt + &OUTPUT_DIR;/climatology_2.5deg/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_sl1l2.txt + &OUTPUT_DIR;/climatology_2.5deg/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_sal1l2.txt + &OUTPUT_DIR;/climatology_2.5deg/point_stat_GFS_CLIMO_2.5DEG_120000L_20120409_120000V_mpr.txt + + + + diff --git a/test/xml/unit_pb2nc.xml b/test/xml/unit_pb2nc.xml index d6d79def22..fc31e0e61b 100644 --- a/test/xml/unit_pb2nc.xml +++ b/test/xml/unit_pb2nc.xml @@ -14,6 +14,8 @@ + + &TEST_DIR; @@ -75,139 +77,5 @@ &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc - - - &MET_BIN;/pb2nc - - STATION_ID "72265","72274","72364","72426" - MASK_GRID - MASK_POLY - QUALITY_MARK_THRESH 2 - - \ - &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.mask_sid.nc \ - &CONFIG_DIR;/PB2NCConfig \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.mask_sid.nc - - - - - &MET_BIN;/pb2nc - - STATION_ID "&CONFIG_DIR;/SID_CO.txt" - MASK_GRID - MASK_POLY - QUALITY_MARK_THRESH 2 - - \ - &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.mask_sid_file.nc \ - &CONFIG_DIR;/PB2NCConfig \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.mask_sid_file.nc - - - - - &MET_BIN;/pb2nc - - STATION_ID - MASK_GRID &MET_DATA;/sample_fcst/2005080700/wrfprs_ruc13_00.tm00_G212 - MASK_POLY - QUALITY_MARK_THRESH 2 - - \ - &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.mask_grid_data.nc \ - &CONFIG_DIR;/PB2NCConfig \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.mask_grid_data.nc - - - - - &MET_BIN;/pb2nc - - STATION_ID - MASK_GRID - MASK_POLY - QUALITY_MARK_THRESH 2 - - \ - &DATA_DIR_OBS;/prepbufr/nam.20210311.t00z.prepbufr.tm00 \ - &OUTPUT_DIR;/pb2nc/nam.20210311.t00z.prepbufr.tm00.pbl.nc \ - &CONFIG_DIR;/PB2NCConfig_pbl \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/nam.20210311.t00z.prepbufr.tm00.pbl.nc - - - - - &MET_BIN;/pb2nc - - STATION_ID "72364","72265","72274","72426","72489","14008" - MASK_GRID - MASK_POLY - QUALITY_MARK_THRESH 2 - - \ - &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.var_all.nc \ - &CONFIG_DIR;/PB2NCConfig_all \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.var_all.nc - - - - - &MET_BIN;/pb2nc - - STATION_ID "SC-GSP","TX-HGX","KY-HPX" - MASK_GRID - MASK_POLY - QUALITY_MARK_THRESH 9 - - \ - &DATA_DIR_OBS;/bufr/nam_20170502.t00z.radwnd.tm02.bufr_d \ - &OUTPUT_DIR;/pb2nc/nam_20170502.t00z.radwnd.tm02.bufr_d.vlevel_500.nc \ - &CONFIG_DIR;/PB2NCConfig_vlevel -valid_end 20170501_22 \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/nam_20170502.t00z.radwnd.tm02.bufr_d.vlevel_500.nc - - - - - &MET_BIN;/pb2nc - - STATION_ID - MASK_GRID - MASK_POLY MET_BASE/poly/CONUS.poly - QUALITY_MARK_THRESH 2 - - \ - &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.summary.nc \ - &CONFIG_DIR;/PB2NCConfig_summary \ - -v 1 - - - &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.summary.nc - - - diff --git a/test/xml/unit_pb2nc_indy.xml b/test/xml/unit_pb2nc_indy.xml new file mode 100644 index 0000000000..d0483d2c6a --- /dev/null +++ b/test/xml/unit_pb2nc_indy.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + +]> + + + + + + + + &TEST_DIR; + true + + + &MET_BIN;/pb2nc + + STATION_ID "72265","72274","72364","72426" + MASK_GRID + MASK_POLY + QUALITY_MARK_THRESH 2 + + \ + &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.mask_sid.nc \ + &CONFIG_DIR;/PB2NCConfig \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.mask_sid.nc + + + + + &MET_BIN;/pb2nc + + STATION_ID "&CONFIG_DIR;/SID_CO.txt" + MASK_GRID + MASK_POLY + QUALITY_MARK_THRESH 2 + + \ + &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.mask_sid_file.nc \ + &CONFIG_DIR;/PB2NCConfig \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.mask_sid_file.nc + + + + + &MET_BIN;/pb2nc + + STATION_ID + MASK_GRID &MET_DATA;/sample_fcst/2005080700/wrfprs_ruc13_00.tm00_G212 + MASK_POLY + QUALITY_MARK_THRESH 2 + + \ + &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.mask_grid_data.nc \ + &CONFIG_DIR;/PB2NCConfig \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.mask_grid_data.nc + + + + + &MET_BIN;/pb2nc + + STATION_ID + MASK_GRID + MASK_POLY + QUALITY_MARK_THRESH 2 + + \ + &DATA_DIR_OBS;/prepbufr/nam.20210311.t00z.prepbufr.tm00 \ + &OUTPUT_DIR;/pb2nc_indy/nam.20210311.t00z.prepbufr.tm00.pbl.nc \ + &CONFIG_DIR;/PB2NCConfig_pbl \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/nam.20210311.t00z.prepbufr.tm00.pbl.nc + + + + + &MET_BIN;/pb2nc + + STATION_ID "72364","72265","72274","72426","72489","14008" + MASK_GRID + MASK_POLY + QUALITY_MARK_THRESH 2 + + \ + &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.var_all.nc \ + &CONFIG_DIR;/PB2NCConfig_all \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.var_all.nc + + + + + &MET_BIN;/pb2nc + + STATION_ID "SC-GSP","TX-HGX","KY-HPX" + MASK_GRID + MASK_POLY + QUALITY_MARK_THRESH 9 + + \ + &DATA_DIR_OBS;/bufr/nam_20170502.t00z.radwnd.tm02.bufr_d \ + &OUTPUT_DIR;/pb2nc_indy/nam_20170502.t00z.radwnd.tm02.bufr_d.vlevel_500.nc \ + &CONFIG_DIR;/PB2NCConfig_vlevel -valid_end 20170501_22 \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/nam_20170502.t00z.radwnd.tm02.bufr_d.vlevel_500.nc + + + + + &MET_BIN;/pb2nc + + STATION_ID + MASK_GRID + MASK_POLY MET_BASE/poly/CONUS.poly + QUALITY_MARK_THRESH 2 + + \ + &DATA_DIR_OBS;/prepbufr/ndas/nam.20120409.t12z.prepbufr.tm00.nr \ + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.summary.nc \ + &CONFIG_DIR;/PB2NCConfig_summary \ + -v 1 + + + &OUTPUT_DIR;/pb2nc_indy/ndas.20120409.t12z.prepbufr.tm00.summary.nc + + + + diff --git a/test/xml/unit_pcp_combine.xml b/test/xml/unit_pcp_combine.xml index 4a1c39b76b..b2de557363 100644 --- a/test/xml/unit_pcp_combine.xml +++ b/test/xml/unit_pcp_combine.xml @@ -187,10 +187,10 @@ -subtract \ &DATA_DIR_MODEL;/p_interp/wrfout_d01_2008-08-08_12:00:00_PLEV 'name="RAINNC";level="(0,*,*)";' \ &DATA_DIR_MODEL;/p_interp/wrfout_d01_2008-08-08_06:00:00_PLEV 'name="RAINNC";level="(0,*,*)";' \ - &OUTPUT_DIR;/pcp_combine/wrfout_d01_2008-08-08_12:00:00_PLEV_APCP06.nc + &OUTPUT_DIR;/pcp_combine/wrfout_d01_2008-08-08_12_00_00_PLEV_APCP06.nc - &OUTPUT_DIR;/pcp_combine/wrfout_d01_2008-08-08_12:00:00_PLEV_APCP06.nc + &OUTPUT_DIR;/pcp_combine/wrfout_d01_2008-08-08_12_00_00_PLEV_APCP06.nc diff --git a/test/xml/unit_plot_data_plane.xml b/test/xml/unit_plot_data_plane.xml index 25d47c1397..c118078829 100644 --- a/test/xml/unit_plot_data_plane.xml +++ b/test/xml/unit_plot_data_plane.xml @@ -135,13 +135,13 @@ &MET_BIN;/plot_data_plane \ &DATA_DIR_MODEL;/p_interp/wrfout_d01_2008-08-08_12:00:00_PLEV \ - &OUTPUT_DIR;/plot_data_plane/wrfout_d01_2008-08-08_12:00:00_PLEV_NC_PINTERP_PRES_SFC.ps \ + &OUTPUT_DIR;/plot_data_plane/wrfout_d01_2008-08-08_12_00_00_PLEV_NC_PINTERP_PRES_SFC.ps \ 'name = "PSFC"; level = "(0,*,*)";' \ -title "NC PINTERP Pressure at the Surface" \ -v 1 - &OUTPUT_DIR;/plot_data_plane/wrfout_d01_2008-08-08_12:00:00_PLEV_NC_PINTERP_PRES_SFC.ps + &OUTPUT_DIR;/plot_data_plane/wrfout_d01_2008-08-08_12_00_00_PLEV_NC_PINTERP_PRES_SFC.ps diff --git a/test/xml/unit_python.xml b/test/xml/unit_python.xml index 226d61869b..b2b1dad44b 100644 --- a/test/xml/unit_python.xml +++ b/test/xml/unit_python.xml @@ -15,7 +15,7 @@ ]> - + @@ -378,7 +378,8 @@ - &MET_BIN;/plot_data_plane + echo "MET_PYTHON_EXE=&MET_PYTHON_EXE;"; \ + &MET_BIN;/plot_data_plane MET_PYTHON_EXE &MET_PYTHON_EXE; PYTHON_GRID G212 @@ -398,7 +399,8 @@ - &MET_BIN;/ascii2nc + echo "MET_PYTHON_EXE=&MET_PYTHON_EXE;"; \ + &MET_BIN;/ascii2nc MET_PYTHON_EXE &MET_PYTHON_EXE; @@ -415,6 +417,7 @@ export PATH='&ANACONDA_BIN;:${PATH}'; \ + echo "MET_PYTHON_EXE=&MET_PYTHON_EXE;"; \ &MET_BIN;/plot_data_plane MET_PYTHON_EXE &MET_PYTHON_EXE; @@ -434,7 +437,8 @@ - &MET_BIN;/stat_analysis + echo "MET_PYTHON_EXE=&MET_PYTHON_EXE;"; \ + &MET_BIN;/stat_analysis MET_PYTHON_EXE &MET_PYTHON_EXE; diff --git a/test/xml/unit_ref_config.xml b/test/xml/unit_ref_config.xml index 5f9320ba5d..0cf9a8b8f3 100644 --- a/test/xml/unit_ref_config.xml +++ b/test/xml/unit_ref_config.xml @@ -11,930 +11,13 @@ ]> - + &TEST_DIR; true - - - - - - &MET_BIN;/gen_vx_mask - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ - &MET_BASE;/poly/CONUS.poly \ - &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc \ - -type poly -v 2 - - - &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - - - - - - - - --> - &MET_BIN;/pb2nc - - MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly - - \ - &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090212/ndas.t12z.prepbufr.tm12.nr \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PB2NCConfig \ - -valid_beg 20110901_223000\ - -valid_end 20110902_013000\ - -v 2 - - - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc - - - - --> - &MET_BIN;/pb2nc - - MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly - - \ - &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090300/ndas.t00z.prepbufr.tm12.nr \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PB2NCConfig \ - -valid_beg 20110902_103000\ - -valid_end 20110902_133000\ - -v 2 - - - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc - - - - --> - &MET_BIN;/pb2nc - - MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly - - \ - &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090312/ndas.t12z.prepbufr.tm12.nr \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PB2NCConfig \ - -valid_beg 20110902_223000\ - -valid_end 20110903_013000\ - -v 2 - - - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc - - - - --> - &MET_BIN;/pb2nc - - MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly - - \ - &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090400/ndas.t00z.prepbufr.tm12.nr \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PB2NCConfig \ - -valid_beg 20110903_103000\ - -valid_end 20110903_133000\ - -v 2 - - - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc - - - - --> - &MET_BIN;/pb2nc - - MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly - - \ - &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090412/ndas.t12z.prepbufr.tm12.nr \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PB2NCConfig \ - -valid_beg 20110903_223000\ - -valid_end 20110904_013000\ - -v 2 - - - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc - - - - - - - - - - &MET_BIN;/pcp_combine - \ - -sum \ - 00000000_000000 1 20110902_120000 3 \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110902/ST2ml2011090212.03h.nc \ - -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110902 - - - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110902/ST2ml2011090212.03h.nc - - - - - &MET_BIN;/pcp_combine - \ - -sum \ - 00000000_000000 1 20110903_000000 3 \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110903/ST2ml2011090300.03h.nc \ - -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110902 \ - -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110903 - - - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110903/ST2ml2011090300.03h.nc - - - - - &MET_BIN;/pcp_combine - \ - -sum \ - 00000000_000000 1 20110903_120000 3 \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110903/ST2ml2011090312.03h.nc \ - -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110903 - - - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110903/ST2ml2011090312.03h.nc - - - - - &MET_BIN;/pcp_combine - \ - -sum \ - 00000000_000000 1 20110904_000000 3 \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110904/ST2ml2011090400.03h.nc \ - -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110903 \ - -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110904 - - - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110904/ST2ml2011090400.03h.nc - - - - - &MET_BIN;/pcp_combine - \ - -add \ - &DATA_DIR_OBS;/ref_config/pcp_combine/2011090324/ST2ml2011090312.24h.grb \ - 24 \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_24h/20110903/ST2ml2011090312.24h.nc - - - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_24h/20110903/ST2ml2011090312.24h.nc - - - - - &MET_BIN;/pcp_combine - \ - -subtract \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 12 \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_009.tm00 9 \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_012.nc - - - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_012.nc - - - - - &MET_BIN;/pcp_combine - \ - -subtract \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 24 \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_021.tm00 21 \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_024.nc - - - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_024.nc - - - - - &MET_BIN;/pcp_combine - \ - -subtract \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 36 \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_033.tm00 33 \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_036.nc - - - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_036.nc - - - - - &MET_BIN;/pcp_combine - \ - -subtract \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 48 \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_045.tm00 45 \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_048.nc - - - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_048.nc - - - - - &MET_BIN;/pcp_combine - \ - -subtract \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 36 \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 12 \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp24_036.nc - - - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp24_036.nc - - - - - - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 000 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_000.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F000_ADPUPA_000000L_20110902_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 000 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_000.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F000_ONLYSF_000000L_20110902_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 000 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_000.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F000_WINDS_000000L_20110902_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 012 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_012.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F012_ADPUPA_120000L_20110902_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 012 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_012.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F012_ONLYSF_120000L_20110902_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 012 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_012.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F012_WINDS_120000L_20110902_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 024 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_024.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F024_ADPUPA_240000L_20110903_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 024 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_024.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F024_ONLYSF_240000L_20110903_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 024 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_024.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F024_WINDS_240000L_20110903_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 036 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_036.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F036_ADPUPA_360000L_20110903_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 036 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_036.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F036_ONLYSF_360000L_20110903_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 036 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_036.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F036_WINDS_360000L_20110903_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 048 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_048.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F048_ADPUPA_480000L_20110904_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 048 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_048.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F048_ONLYSF_480000L_20110904_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv2.7.1 - FCST_TIME 048 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_048.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F048_WINDS_480000L_20110904_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 000 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_000.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F000_ADPUPA_000000L_20110902_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 000 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_000.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F000_ONLYSF_000000L_20110902_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 000 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_000.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F000_WINDS_000000L_20110902_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 012 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F012_ADPUPA_120000L_20110902_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 012 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F012_ONLYSF_120000L_20110902_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 012 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F012_WINDS_120000L_20110902_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 024 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F024_ADPUPA_240000L_20110903_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 024 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F024_ONLYSF_240000L_20110903_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 024 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F024_WINDS_240000L_20110903_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 036 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F036_ADPUPA_360000L_20110903_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 036 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F036_ONLYSF_360000L_20110903_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 036 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F036_WINDS_360000L_20110903_120000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 048 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F048_ADPUPA_480000L_20110904_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 048 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F048_ONLYSF_480000L_20110904_000000V.stat - - - - - &MET_BIN;/point_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 048 - - \ - &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 \ - &OUTPUT_DIR;/ref_config/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ - &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ - -outdir &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3 \ - -v 2 - - - &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F048_WINDS_480000L_20110904_000000V.stat - - - - - - - - - &MET_BIN;/grid_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 12 - - \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_012.nc \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110902/ST2ml2011090212.03h.nc \ - &CONFIG_DIR;/ref_config/GridStatConfig_03h \ - -outdir &OUTPUT_DIR;/ref_config/grid_stat -v 1 - - - &OUTPUT_DIR;/ref_config/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F12_03h_120000L_20110902_120000V.stat - - - - - &MET_BIN;/grid_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 24 - - \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_024.nc \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110903/ST2ml2011090300.03h.nc \ - &CONFIG_DIR;/ref_config/GridStatConfig_03h \ - -outdir &OUTPUT_DIR;/ref_config/grid_stat -v 1 - - - &OUTPUT_DIR;/ref_config/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F24_03h_240000L_20110903_000000V.stat - - - - - &MET_BIN;/grid_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 36 - - \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_036.nc \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110903/ST2ml2011090312.03h.nc \ - &CONFIG_DIR;/ref_config/GridStatConfig_03h \ - -outdir &OUTPUT_DIR;/ref_config/grid_stat -v 1 - - - &OUTPUT_DIR;/ref_config/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F36_03h_360000L_20110903_120000V.stat - - - - - &MET_BIN;/grid_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 48 - - \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp03_048.nc \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_03h/20110904/ST2ml2011090400.03h.nc \ - &CONFIG_DIR;/ref_config/GridStatConfig_03h \ - -outdir &OUTPUT_DIR;/ref_config/grid_stat -v 1 - - - &OUTPUT_DIR;/ref_config/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F48_03h_480000L_20110904_000000V.stat - - - - - &MET_BIN;/grid_stat - - MASK_POLY_FILE &OUTPUT_DIR;/ref_config/gen_vx_mask/CONUS.nc - MODEL AFWAv3.4_Noahv3.3 - FCST_TIME 36 - - \ - &OUTPUT_DIR;/ref_config/pcp_combine/wrf/wrfpcp24_036.nc \ - &OUTPUT_DIR;/ref_config/pcp_combine/ST2_24h/20110903/ST2ml2011090312.24h.nc \ - &CONFIG_DIR;/ref_config/GridStatConfig_24h \ - -outdir &OUTPUT_DIR;/ref_config/grid_stat -v 1 - - - &OUTPUT_DIR;/ref_config/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F36_24h_360000L_20110903_120000V.stat - - - @@ -942,8 +25,8 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/ \ - -lookin &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/ \ + -lookin &OUTPUT_DIR;/ref_config_lead_*/point_stat/AFWAv3.4_Noahv3.3 \ + -lookin &OUTPUT_DIR;/ref_config_lead_*/point_stat/AFWAv3.4_Noahv2.7.1 \ -job go_index -fcst_init_beg 2011090200 -fcst_init_end 2011090200 \ -model AFWAv3.4_Noahv3.3 -model AFWAv3.4_Noahv2.7.1 \ -vx_mask FULL -interp_mthd BILIN \ @@ -962,8 +45,8 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/ \ - -lookin &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/ \ + -lookin &OUTPUT_DIR;/ref_config_lead_*/point_stat/AFWAv3.4_Noahv3.3 \ + -lookin &OUTPUT_DIR;/ref_config_lead_*/point_stat/AFWAv3.4_Noahv2.7.1 \ -job go_index \ -by FCST_INIT_BEG,VX_MASK,OBTYPE -set_hdr DESC Noahv3.3_vs_v2.7.1 \ -model AFWAv3.4_Noahv3.3,AFWAv3.4_Noahv2.7.1 -ss_index_vld_thresh 0.5 \ @@ -981,8 +64,8 @@ &MET_BIN;/stat_analysis \ - -lookin &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv3.3/ \ - -lookin &OUTPUT_DIR;/ref_config/point_stat/AFWAv3.4_Noahv2.7.1/ \ + -lookin &OUTPUT_DIR;/ref_config_lead_*/point_stat/AFWAv3.4_Noahv3.3 \ + -lookin &OUTPUT_DIR;/ref_config_lead_*/point_stat/AFWAv3.4_Noahv2.7.1 \ -job ss_index -config &CONFIG_DIR;/STATAnalysisConfig_SFC_SS_Index \ -by FCST_INIT_BEG,VX_MASK,OBTYPE \ -out_stat &OUTPUT_DIR;/ref_config/stat_analysis/sfc_ss_index_by_option.stat diff --git a/test/xml/unit_ref_config_lead_00.xml b/test/xml/unit_ref_config_lead_00.xml new file mode 100644 index 0000000000..ac65be1546 --- /dev/null +++ b/test/xml/unit_ref_config_lead_00.xml @@ -0,0 +1,178 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + + + + &MET_BIN;/gen_vx_mask + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &MET_BASE;/poly/CONUS.poly \ + &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc \ + -type poly -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + + + + + + + + + &MET_BIN;/pb2nc + + MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly + + \ + &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090212/ndas.t12z.prepbufr.tm12.nr \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PB2NCConfig \ + -valid_beg 20110901_223000\ + -valid_end 20110902_013000\ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc + + + + + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 000 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_000.tm00 \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F000_ADPUPA_000000L_20110902_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 000 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_000.tm00 \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F000_ONLYSF_000000L_20110902_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 000 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_000.tm00 \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F000_WINDS_000000L_20110902_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 000 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_000.tm00 \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F000_ADPUPA_000000L_20110902_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 000 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_000.tm00 \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F000_ONLYSF_000000L_20110902_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_00/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 000 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_000.tm00 \ + &OUTPUT_DIR;/ref_config_lead_00/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_00/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F000_WINDS_000000L_20110902_000000V.stat + + + + diff --git a/test/xml/unit_ref_config_lead_12.xml b/test/xml/unit_ref_config_lead_12.xml new file mode 100644 index 0000000000..989e548da5 --- /dev/null +++ b/test/xml/unit_ref_config_lead_12.xml @@ -0,0 +1,230 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + + + + &MET_BIN;/gen_vx_mask + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &MET_BASE;/poly/CONUS.poly \ + &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc \ + -type poly -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + + + + + + + + + &MET_BIN;/pb2nc + + MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly + + \ + &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090300/ndas.t00z.prepbufr.tm12.nr \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PB2NCConfig \ + -valid_beg 20110902_103000\ + -valid_end 20110902_133000\ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc + + + + + + + + + &MET_BIN;/pcp_combine + \ + -sum \ + 00000000_000000 1 20110902_120000 3 \ + &OUTPUT_DIR;/ref_config_lead_12/pcp_combine/ST2_03h/20110902/ST2ml2011090212.03h.nc \ + -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110902 + + + &OUTPUT_DIR;/ref_config_lead_12/pcp_combine/ST2_03h/20110902/ST2ml2011090212.03h.nc + + + + + &MET_BIN;/pcp_combine + \ + -subtract \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 12 \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_009.tm00 9 \ + &OUTPUT_DIR;/ref_config_lead_12/pcp_combine/wrf/wrfpcp03_012.nc + + + &OUTPUT_DIR;/ref_config_lead_12/pcp_combine/wrf/wrfpcp03_012.nc + + + + + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 012 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_012.tm00 \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F012_ADPUPA_120000L_20110902_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 012 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_012.tm00 \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F012_ONLYSF_120000L_20110902_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 012 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_012.tm00 \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F012_WINDS_120000L_20110902_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 012 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F012_ADPUPA_120000L_20110902_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 012 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F012_ONLYSF_120000L_20110902_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 012 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &OUTPUT_DIR;/ref_config_lead_12/pb2nc/NDAS_03h/20110902/prepbufr.ndas.20110902.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_12/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F012_WINDS_120000L_20110902_120000V.stat + + + + + + + + + &MET_BIN;/grid_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_12/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 12 + + \ + &OUTPUT_DIR;/ref_config_lead_12/pcp_combine/wrf/wrfpcp03_012.nc \ + &OUTPUT_DIR;/ref_config_lead_12/pcp_combine/ST2_03h/20110902/ST2ml2011090212.03h.nc \ + &CONFIG_DIR;/ref_config/GridStatConfig_03h \ + -outdir &OUTPUT_DIR;/ref_config_lead_12/grid_stat -v 1 + + + &OUTPUT_DIR;/ref_config_lead_12/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F12_03h_120000L_20110902_120000V.stat + + + + diff --git a/test/xml/unit_ref_config_lead_24.xml b/test/xml/unit_ref_config_lead_24.xml new file mode 100644 index 0000000000..78cff2ee56 --- /dev/null +++ b/test/xml/unit_ref_config_lead_24.xml @@ -0,0 +1,231 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + + + + &MET_BIN;/gen_vx_mask + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &MET_BASE;/poly/CONUS.poly \ + &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc \ + -type poly -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + + + + + + + + + &MET_BIN;/pb2nc + + MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly + + \ + &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090312/ndas.t12z.prepbufr.tm12.nr \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PB2NCConfig \ + -valid_beg 20110902_223000\ + -valid_end 20110903_013000\ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc + + + + + + + + + &MET_BIN;/pcp_combine + \ + -sum \ + 00000000_000000 1 20110903_000000 3 \ + &OUTPUT_DIR;/ref_config_lead_24/pcp_combine/ST2_03h/20110903/ST2ml2011090300.03h.nc \ + -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110902 \ + -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110903 + + + &OUTPUT_DIR;/ref_config_lead_24/pcp_combine/ST2_03h/20110903/ST2ml2011090300.03h.nc + + + + + &MET_BIN;/pcp_combine + \ + -subtract \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 24 \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_021.tm00 21 \ + &OUTPUT_DIR;/ref_config_lead_24/pcp_combine/wrf/wrfpcp03_024.nc + + + &OUTPUT_DIR;/ref_config_lead_24/pcp_combine/wrf/wrfpcp03_024.nc + + + + + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 024 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_024.tm00 \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F024_ADPUPA_240000L_20110903_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 024 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_024.tm00 \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F024_ONLYSF_240000L_20110903_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 024 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_024.tm00 \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F024_WINDS_240000L_20110903_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 024 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F024_ADPUPA_240000L_20110903_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 024 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F024_ONLYSF_240000L_20110903_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 024 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_024.tm00 \ + &OUTPUT_DIR;/ref_config_lead_24/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_24/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F024_WINDS_240000L_20110903_000000V.stat + + + + + + + + + &MET_BIN;/grid_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_24/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 24 + + \ + &OUTPUT_DIR;/ref_config_lead_24/pcp_combine/wrf/wrfpcp03_024.nc \ + &OUTPUT_DIR;/ref_config_lead_24/pcp_combine/ST2_03h/20110903/ST2ml2011090300.03h.nc \ + &CONFIG_DIR;/ref_config/GridStatConfig_03h \ + -outdir &OUTPUT_DIR;/ref_config_lead_24/grid_stat -v 1 + + + &OUTPUT_DIR;/ref_config_lead_24/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F24_03h_240000L_20110903_000000V.stat + + + + diff --git a/test/xml/unit_ref_config_lead_36.xml b/test/xml/unit_ref_config_lead_36.xml new file mode 100644 index 0000000000..4832ba4ad1 --- /dev/null +++ b/test/xml/unit_ref_config_lead_36.xml @@ -0,0 +1,274 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + + + + &MET_BIN;/gen_vx_mask + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &MET_BASE;/poly/CONUS.poly \ + &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc \ + -type poly -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + + + + + + + + + &MET_BIN;/pb2nc + + MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly + + \ + &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090400/ndas.t00z.prepbufr.tm12.nr \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PB2NCConfig \ + -valid_beg 20110903_103000\ + -valid_end 20110903_133000\ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc + + + + + + + + + &MET_BIN;/pcp_combine + \ + -sum \ + 00000000_000000 1 20110903_120000 3 \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/ST2_03h/20110903/ST2ml2011090312.03h.nc \ + -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110903 + + + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/ST2_03h/20110903/ST2ml2011090312.03h.nc + + + + + &MET_BIN;/pcp_combine + \ + -add \ + &DATA_DIR_OBS;/ref_config/pcp_combine/2011090324/ST2ml2011090312.24h.grb \ + 24 \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/ST2_24h/20110903/ST2ml2011090312.24h.nc + + + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/ST2_24h/20110903/ST2ml2011090312.24h.nc + + + + + &MET_BIN;/pcp_combine + \ + -subtract \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 36 \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_033.tm00 33 \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/wrf/wrfpcp03_036.nc + + + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/wrf/wrfpcp03_036.nc + + + + + &MET_BIN;/pcp_combine + \ + -subtract \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 36 \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 12 \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/wrf/wrfpcp24_036.nc + + + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/wrf/wrfpcp24_036.nc + + + + + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 036 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_036.tm00 \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F036_ADPUPA_360000L_20110903_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 036 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_036.tm00 \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F036_ONLYSF_360000L_20110903_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 036 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_036.tm00 \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F036_WINDS_360000L_20110903_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 036 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F036_ADPUPA_360000L_20110903_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 036 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F036_ONLYSF_360000L_20110903_120000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 036 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_036.tm00 \ + &OUTPUT_DIR;/ref_config_lead_36/pb2nc/NDAS_03h/20110903/prepbufr.ndas.20110903.t12z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_36/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F036_WINDS_360000L_20110903_120000V.stat + + + + + + + + + &MET_BIN;/grid_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 36 + + \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/wrf/wrfpcp03_036.nc \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/ST2_03h/20110903/ST2ml2011090312.03h.nc \ + &CONFIG_DIR;/ref_config/GridStatConfig_03h \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/grid_stat -v 1 + + + &OUTPUT_DIR;/ref_config_lead_36/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F36_03h_360000L_20110903_120000V.stat + + + + + &MET_BIN;/grid_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_36/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 36 + + \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/wrf/wrfpcp24_036.nc \ + &OUTPUT_DIR;/ref_config_lead_36/pcp_combine/ST2_24h/20110903/ST2ml2011090312.24h.nc \ + &CONFIG_DIR;/ref_config/GridStatConfig_24h \ + -outdir &OUTPUT_DIR;/ref_config_lead_36/grid_stat -v 1 + + + &OUTPUT_DIR;/ref_config_lead_36/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F36_24h_360000L_20110903_120000V.stat + + + + diff --git a/test/xml/unit_ref_config_lead_48.xml b/test/xml/unit_ref_config_lead_48.xml new file mode 100644 index 0000000000..b096241afb --- /dev/null +++ b/test/xml/unit_ref_config_lead_48.xml @@ -0,0 +1,231 @@ + + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + + + + &MET_BIN;/gen_vx_mask + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_012.tm00 \ + &MET_BASE;/poly/CONUS.poly \ + &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc \ + -type poly -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + + + + + + + + + &MET_BIN;/pb2nc + + MASK_POLY &CONFIG_DIR;/ref_config/RefConfig.poly + + \ + &DATA_DIR_OBS;/ref_config/prepbufr/ndas/2011090412/ndas.t12z.prepbufr.tm12.nr \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PB2NCConfig \ + -valid_beg 20110903_223000\ + -valid_end 20110904_013000\ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc + + + + + + + + + &MET_BIN;/pcp_combine + \ + -sum \ + 00000000_000000 1 20110904_000000 3 \ + &OUTPUT_DIR;/ref_config_lead_48/pcp_combine/ST2_03h/20110904/ST2ml2011090400.03h.nc \ + -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110903 \ + -pcpdir &DATA_DIR_OBS;/ref_config/pcp_combine/20110904 + + + &OUTPUT_DIR;/ref_config_lead_48/pcp_combine/ST2_03h/20110904/ST2ml2011090400.03h.nc + + + + + &MET_BIN;/pcp_combine + \ + -subtract \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 48 \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_045.tm00 45 \ + &OUTPUT_DIR;/ref_config_lead_48/pcp_combine/wrf/wrfpcp03_048.nc + + + &OUTPUT_DIR;/ref_config_lead_48/pcp_combine/wrf/wrfpcp03_048.nc + + + + + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 048 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_048.tm00 \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F048_ADPUPA_480000L_20110904_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 048 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_048.tm00 \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F048_ONLYSF_480000L_20110904_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv2.7.1 + FCST_TIME 048 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv2.7.1/postprd/wrfprs_048.tm00 \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv2.7.1 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv2.7.1/point_stat_AFWAv3.4_Noahv2.7.1_F048_WINDS_480000L_20110904_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 048 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ADPUPA \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F048_ADPUPA_480000L_20110904_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 048 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_ONLYSF \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F048_ONLYSF_480000L_20110904_000000V.stat + + + + + &MET_BIN;/point_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 048 + + \ + &DATA_DIR_MODEL;/grib1/ref_config/2011090200/AFWAv3.4_Noahv3.3/postprd/wrfprs_048.tm00 \ + &OUTPUT_DIR;/ref_config_lead_48/pb2nc/NDAS_03h/20110904/prepbufr.ndas.20110904.t00z.tm12.nc \ + &CONFIG_DIR;/ref_config/PointStatConfig_WINDS \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv3.3 \ + -v 2 + + + &OUTPUT_DIR;/ref_config_lead_48/point_stat/AFWAv3.4_Noahv3.3/point_stat_AFWAv3.4_Noahv3.3_F048_WINDS_480000L_20110904_000000V.stat + + + + + + + + + &MET_BIN;/grid_stat + + MASK_POLY_FILE &OUTPUT_DIR;/ref_config_lead_48/gen_vx_mask/CONUS.nc + MODEL AFWAv3.4_Noahv3.3 + FCST_TIME 48 + + \ + &OUTPUT_DIR;/ref_config_lead_48/pcp_combine/wrf/wrfpcp03_048.nc \ + &OUTPUT_DIR;/ref_config_lead_48/pcp_combine/ST2_03h/20110904/ST2ml2011090400.03h.nc \ + &CONFIG_DIR;/ref_config/GridStatConfig_03h \ + -outdir &OUTPUT_DIR;/ref_config_lead_48/grid_stat -v 1 + + + &OUTPUT_DIR;/ref_config_lead_48/grid_stat/grid_stat_AFWAv3.4_Noahv3.3_F48_03h_480000L_20110904_000000V.stat + + + + diff --git a/test/xml/unit_stat_analysis.xml b/test/xml/unit_stat_analysis.xml deleted file mode 100644 index 078b76e072..0000000000 --- a/test/xml/unit_stat_analysis.xml +++ /dev/null @@ -1,331 +0,0 @@ - - - - - - - - - -]> - - - - - - &TEST_DIR; - true - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ - -job aggregate -line_type RHIST \ - -fcst_var TMP -vx_mask NWC -vx_mask GRB \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_RHIST_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_RHIST_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_RHIST.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_RHIST_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_RHIST_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_RHIST.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ - -job aggregate -line_type PHIST \ - -fcst_var TMP -vx_mask NWC -vx_mask GRB \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_PHIST_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_PHIST_out.stat \ - -set_hdr VX_MASK NWC_AND_GRB \ - -out &OUTPUT_DIR;/stat_analysis/AGG_PHIST.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_PHIST_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_PHIST_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_PHIST.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SKIP_CONST_20120410_120000V.stat \ - -job aggregate -line_type RELP -by FCST_VAR -vx_mask NWC,GRB \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_RELP_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_RELP_out.stat \ - -set_hdr VX_MASK NWC_AND_GRB \ - -out &OUTPUT_DIR;/stat_analysis/AGG_RELP.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_RELP_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_RELP_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_RELP.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SKIP_CONST_20120410_120000V.stat \ - -job aggregate -line_type ECNT -by FCST_VAR -obs_thresh NA -vx_mask NWC,GRB \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_ECNT_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_ECNT_out.stat \ - -set_hdr VX_MASK NWC_AND_GRB \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_ECNT_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_ECNT_out.stat - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ - -job aggregate_stat -line_type ORANK -out_line_type RHIST,PHIST \ - -fcst_var APCP_24 -vx_mask NWC -vx_mask GRB -out_bin_size 0.10 \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RHIST_PHIST_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RHIST_PHIST_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RHIST_PHIST.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RHIST_PHIST_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RHIST_PHIST_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RHIST_PHIST.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SKIP_CONST_20120410_120000V.stat \ - -job aggregate_stat -line_type ORANK -out_line_type RELP \ - -fcst_var APCP_24 -vx_mask NWC,GRB \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RELP_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RELP_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RELP.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RELP_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RELP_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_RELP.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ - -job aggregate_stat -line_type ORANK -out_line_type SSVAR \ - -fcst_var APCP_24 -vx_mask NWC -vx_mask GRB -out_bin_size 0.25 \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_SSVAR_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_SSVAR_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_SSVAR.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_SSVAR_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_SSVAR_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_SSVAR.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V.stat \ - -job aggregate_stat -line_type ORANK -out_line_type ECNT \ - -fcst_var APCP_24 -by VX_MASK \ - -set_hdr DESC VX_MASK \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_ECNT_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_ECNT_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_ECNT.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_ECNT_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_ECNT_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_STAT_ORANK_ECNT.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ - -job aggregate -line_type SSVAR \ - -fcst_var APCP_24 -obtype ANALYS -vx_mask NWC -vx_mask GRB \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_SSVAR_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_SSVAR_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_SSVAR.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_SSVAR_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_SSVAR_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_SSVAR.out - - - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/wavelet_stat/wavelet_stat_GRIB1_NAM_STAGE4_120000L_20120409_120000V.stat \ - -job aggregate -line_type ISC \ - -fcst_var APCP_12 -fcst_thresh '>0.0' -vx_mask TILE1 -vx_mask TILE2 \ - -dump_row &OUTPUT_DIR;/stat_analysis/AGG_ISC_dump.stat \ - -out_stat &OUTPUT_DIR;/stat_analysis/AGG_ISC_out.stat \ - -out &OUTPUT_DIR;/stat_analysis/AGG_ISC.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/AGG_ISC_dump.stat - &OUTPUT_DIR;/stat_analysis/AGG_ISC_out.stat - &OUTPUT_DIR;/stat_analysis/AGG_ISC.out - - - - - - - - OUTPUT_DIR &OUTPUT_DIR;/stat_analysis - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_120000L_20120409_120000V.stat \ - -config &CONFIG_DIR;/STATAnalysisConfig_grid_stat \ - -out &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT.out - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_filter.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_agg_stat_sl1l2_dump.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_agg_stat_sl1l2_out.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_agg_ctc_dump.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_agg_ctc_out.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_agg_stat_ctc_to_eclv_dump.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_GRID_STAT_agg_stat_ctc_to_eclv_out.stat - - - - - - - - CONFIG_DIR &CONFIG_DIR; - OUTPUT_DIR &OUTPUT_DIR;/stat_analysis - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ - -config &CONFIG_DIR;/STATAnalysisConfig_point_stat \ - -out &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT.out - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_agg_stat_mpr_to_cnt_dump.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_agg_stat_mpr_to_cnt_out.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_agg_stat_mpr_to_cnt_by_vx_mask_out.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_agg_ctc_by_fcst_thresh_out.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_agg_stat_mpr_to_wdir_dump.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_filter_mpr_sid.stat - &OUTPUT_DIR;/stat_analysis/CONFIG_POINT_STAT_filter_mpr_fcst_minus_obs.stat - - - - - - OUTPUT_DIR &OUTPUT_DIR;/stat_analysis - - &MET_BIN;/stat_analysis - \ - -lookin &DATA_DIR_MODEL;/time_series_met_6.0/*.stat \ - -config &CONFIG_DIR;/STATAnalysisConfig_ramps \ - -out &OUTPUT_DIR;/stat_analysis/RAMPS.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/RAMPS.out - &OUTPUT_DIR;/stat_analysis/RAMPS_100_100.stat - &OUTPUT_DIR;/stat_analysis/RAMPS_25_100.stat - &OUTPUT_DIR;/stat_analysis/RAMPS_25_100_30min.stat - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ - -job summary -line_type MPR -by FCST_VAR,FCST_LEV -column 'FCST,OBS,FCST-OBS,ABS(FCST-OBS)' \ - -boot_seed 1 -out &OUTPUT_DIR;/stat_analysis/POINT_STAT_SUMMARY.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/POINT_STAT_SUMMARY.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ - -job summary -line_type MPR -by FCST_VAR,FCST_LEV -column 'FCST,OBS' -column_union true \ - -boot_seed 1 -out &OUTPUT_DIR;/stat_analysis/POINT_STAT_SUMMARY_UNION.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/POINT_STAT_SUMMARY_UNION.out - - - - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ - -job filter -line_type MPR -fcst_var TMP -fcst_lev Z2 -vx_mask DTC165 \ - -column_str OBS_SID KDLN,KDHT,KDEN,KDLS,KDMA,KDMN,KDVT,KDEW \ - -column_str_exc OBS_SID KDLN,KDHT \ - -dump_row &OUTPUT_DIR;/stat_analysis/POINT_STAT_FILTER_OBS_SID.stat \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/POINT_STAT_FILTER_OBS_SID.stat - - - - - - OUTPUT_DIR &OUTPUT_DIR;/stat_analysis - - &MET_BIN;/stat_analysis - \ - -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB2_NAM_NDAS_120000L_20120409_120000V.stat \ - -config &CONFIG_DIR;/STATAnalysisConfig_filter_times \ - -out &OUTPUT_DIR;/stat_analysis/POINT_STAT_FILTER_TIMES.out \ - -v 1 - - - &OUTPUT_DIR;/stat_analysis/POINT_STAT_FILTER_TIMES.out - - - - diff --git a/test/xml/unit_stat_analysis_es.xml b/test/xml/unit_stat_analysis_es.xml new file mode 100644 index 0000000000..a7b446c1c6 --- /dev/null +++ b/test/xml/unit_stat_analysis_es.xml @@ -0,0 +1,182 @@ + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ + -job aggregate -line_type RHIST \ + -fcst_var TMP -vx_mask NWC -vx_mask GRB \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_RHIST_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_RHIST_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_RHIST.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_RHIST_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_RHIST_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_RHIST.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ + -job aggregate -line_type PHIST \ + -fcst_var TMP -vx_mask NWC -vx_mask GRB \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_PHIST_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_PHIST_out.stat \ + -set_hdr VX_MASK NWC_AND_GRB \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_PHIST.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_PHIST_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_PHIST_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_PHIST.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SKIP_CONST_20120410_120000V.stat \ + -job aggregate -line_type RELP -by FCST_VAR -vx_mask NWC,GRB \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_RELP_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_RELP_out.stat \ + -set_hdr VX_MASK NWC_AND_GRB \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_RELP.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_RELP_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_RELP_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_RELP.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SKIP_CONST_20120410_120000V.stat \ + -job aggregate -line_type ECNT -by FCST_VAR -obs_thresh NA -vx_mask NWC,GRB \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_ECNT_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_ECNT_out.stat \ + -set_hdr VX_MASK NWC_AND_GRB \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_ECNT_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_ECNT_out.stat + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ + -job aggregate_stat -line_type ORANK -out_line_type RHIST,PHIST \ + -fcst_var APCP_24 -vx_mask NWC -vx_mask GRB -out_bin_size 0.10 \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RHIST_PHIST_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RHIST_PHIST_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RHIST_PHIST.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RHIST_PHIST_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RHIST_PHIST_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RHIST_PHIST.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_SKIP_CONST_20120410_120000V.stat \ + -job aggregate_stat -line_type ORANK -out_line_type RELP \ + -fcst_var APCP_24 -vx_mask NWC,GRB \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RELP_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RELP_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RELP.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RELP_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RELP_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_RELP.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ + -job aggregate_stat -line_type ORANK -out_line_type SSVAR \ + -fcst_var APCP_24 -vx_mask NWC -vx_mask GRB -out_bin_size 0.25 \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_SSVAR_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_SSVAR_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_SSVAR.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_SSVAR_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_SSVAR_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_SSVAR.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_OBSERR_20120410_120000V.stat \ + -job aggregate_stat -line_type ORANK -out_line_type ECNT \ + -fcst_var APCP_24 -by VX_MASK \ + -set_hdr DESC VX_MASK \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_ECNT_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_ECNT_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_ECNT.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_ECNT_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_ECNT_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_STAT_ORANK_ECNT.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/ensemble_stat/ensemble_stat_CMD_LINE_20120410_120000V.stat \ + -job aggregate -line_type SSVAR \ + -fcst_var APCP_24 -obtype ANALYS -vx_mask NWC -vx_mask GRB \ + -dump_row &OUTPUT_DIR;/stat_analysis_es/AGG_SSVAR_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_es/AGG_SSVAR_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_es/AGG_SSVAR.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_es/AGG_SSVAR_dump.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_SSVAR_out.stat + &OUTPUT_DIR;/stat_analysis_es/AGG_SSVAR.out + + + + diff --git a/test/xml/unit_stat_analysis_gs.xml b/test/xml/unit_stat_analysis_gs.xml new file mode 100644 index 0000000000..6309f57aef --- /dev/null +++ b/test/xml/unit_stat_analysis_gs.xml @@ -0,0 +1,45 @@ + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + + + OUTPUT_DIR &OUTPUT_DIR;/stat_analysis_gs + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/grid_stat/grid_stat_GRIB2_NAM_RTMA_120000L_20120409_120000V.stat \ + -config &CONFIG_DIR;/STATAnalysisConfig_grid_stat \ + -out &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT.out + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_filter.stat + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_agg_stat_sl1l2_dump.stat + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_agg_stat_sl1l2_out.stat + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_agg_ctc_dump.stat + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_agg_ctc_out.stat + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_agg_stat_ctc_to_eclv_dump.stat + &OUTPUT_DIR;/stat_analysis_gs/CONFIG_GRID_STAT_agg_stat_ctc_to_eclv_out.stat + + + + diff --git a/test/xml/unit_stat_analysis_ps.xml b/test/xml/unit_stat_analysis_ps.xml new file mode 100644 index 0000000000..d32fe963f7 --- /dev/null +++ b/test/xml/unit_stat_analysis_ps.xml @@ -0,0 +1,120 @@ + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + + CONFIG_DIR &CONFIG_DIR; + OUTPUT_DIR &OUTPUT_DIR;/stat_analysis_ps + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ + -config &CONFIG_DIR;/STATAnalysisConfig_point_stat \ + -out &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT.out + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_agg_stat_mpr_to_cnt_dump.stat + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_agg_stat_mpr_to_cnt_out.stat + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_agg_stat_mpr_to_cnt_by_vx_mask_out.stat + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_agg_ctc_by_fcst_thresh_out.stat + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_agg_stat_mpr_to_wdir_dump.stat + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_filter_mpr_sid.stat + &OUTPUT_DIR;/stat_analysis_ps/CONFIG_POINT_STAT_filter_mpr_fcst_minus_obs.stat + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ + -job summary -line_type MPR -by FCST_VAR,FCST_LEV -column 'FCST,OBS,FCST-OBS,ABS(FCST-OBS)' \ + -boot_seed 1 -out &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_SUMMARY.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_SUMMARY.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ + -job summary -line_type MPR -by FCST_VAR,FCST_LEV -column 'FCST,OBS' -column_union true \ + -boot_seed 1 -out &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_SUMMARY_UNION.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_SUMMARY_UNION.out + + + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB1_NAM_GDAS_120000L_20120409_120000V.stat \ + -job filter -line_type MPR -fcst_var TMP -fcst_lev Z2 -vx_mask DTC165 \ + -column_str OBS_SID KDLN,KDHT,KDEN,KDLS,KDMA,KDMN,KDVT,KDEW \ + -column_str_exc OBS_SID KDLN,KDHT \ + -dump_row &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_FILTER_OBS_SID.stat \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_FILTER_OBS_SID.stat + + + + + + OUTPUT_DIR &OUTPUT_DIR;/stat_analysis_ps + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/point_stat/point_stat_GRIB2_NAM_NDAS_120000L_20120409_120000V.stat \ + -config &CONFIG_DIR;/STATAnalysisConfig_filter_times \ + -out &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_FILTER_TIMES.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ps/POINT_STAT_FILTER_TIMES.out + + + + + + OUTPUT_DIR &OUTPUT_DIR;/stat_analysis_ps + + &MET_BIN;/stat_analysis + \ + -lookin &DATA_DIR_MODEL;/time_series_met_6.0/*.stat \ + -config &CONFIG_DIR;/STATAnalysisConfig_ramps \ + -out &OUTPUT_DIR;/stat_analysis_ps/RAMPS.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ps/RAMPS.out + &OUTPUT_DIR;/stat_analysis_ps/RAMPS_100_100.stat + &OUTPUT_DIR;/stat_analysis_ps/RAMPS_25_100.stat + &OUTPUT_DIR;/stat_analysis_ps/RAMPS_25_100_30min.stat + + + + diff --git a/test/xml/unit_stat_analysis_ws.xml b/test/xml/unit_stat_analysis_ws.xml new file mode 100644 index 0000000000..4bb01eda9e --- /dev/null +++ b/test/xml/unit_stat_analysis_ws.xml @@ -0,0 +1,38 @@ + + + + + + + + + +]> + + + + + + &TEST_DIR; + true + + + &MET_BIN;/stat_analysis + \ + -lookin &OUTPUT_DIR;/wavelet_stat/wavelet_stat_GRIB1_NAM_STAGE4_120000L_20120409_120000V.stat \ + -job aggregate -line_type ISC \ + -fcst_var APCP_12 -fcst_thresh '>0.0' -vx_mask TILE1 -vx_mask TILE2 \ + -dump_row &OUTPUT_DIR;/stat_analysis_ws/AGG_ISC_dump.stat \ + -out_stat &OUTPUT_DIR;/stat_analysis_ws/AGG_ISC_out.stat \ + -out &OUTPUT_DIR;/stat_analysis_ws/AGG_ISC.out \ + -v 1 + + + &OUTPUT_DIR;/stat_analysis_ws/AGG_ISC_dump.stat + &OUTPUT_DIR;/stat_analysis_ws/AGG_ISC_out.stat + &OUTPUT_DIR;/stat_analysis_ws/AGG_ISC.out + + + + From 42ca71a4e2df51b5fe6ed1042e64db16b5ca2ddb Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Jan 2022 15:48:00 -0700 Subject: [PATCH 082/172] fixed broken workflow by setting environment variable expected for docker build script --- .github/workflows/build_docker_and_trigger_metplus.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 153adcb060..88f2a66ebe 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -7,6 +7,9 @@ on: paths-ignore: - 'met/docs/**' +env: + DOCKERHUB_REPO: dtcenter/met-dev + jobs: build_met_docker: From 59393572b83b462b5d84999275563a66700cdbf2 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Jan 2022 16:03:51 -0700 Subject: [PATCH 083/172] add missing docker tag from push command --- .github/workflows/build_docker_and_trigger_metplus.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 88f2a66ebe..60dec45b66 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -31,6 +31,7 @@ jobs: - name: Push Docker Image run: .github/jobs/push_docker_image.sh env: + SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} From 1e7551f7c199d2b98b13d9a437071d48a06361ae Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Jan 2022 16:26:37 -0700 Subject: [PATCH 084/172] added correct docker tag value --- .github/workflows/build_docker_and_trigger_metplus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index 60dec45b66..ed97e44d80 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -31,7 +31,7 @@ jobs: - name: Push Docker Image run: .github/jobs/push_docker_image.sh env: - SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} + SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} From afe0ad4c709c446f574acf1fc4d8ec7351eb139d Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Jan 2022 16:55:33 -0700 Subject: [PATCH 085/172] fixed incorrect truth data version for updating -ref reference data --- .github/jobs/set_job_controls.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh index 6a4e4bdf82..e6605f959c 100755 --- a/.github/jobs/set_job_controls.sh +++ b/.github/jobs/set_job_controls.sh @@ -28,7 +28,7 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then run_update_truth=true run_diff=true - truth_data_version=${branch_name: -4} + truth_data_version=${branch_name:0: -4} else From 555494bb425691034d68eda22675cc554f0b6994 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 28 Jan 2022 12:55:03 -0700 Subject: [PATCH 086/172] Updating develop with changes to the unit tests names. Renaming unit_test.yml to a more generic testing.yml name since it compiles AND/OR runs unit tests. Also make the job names more concise so its easier to see what's running in the action summary window on GitHub. --- .../workflows/{unit_tests.yml => testing.yml} | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) rename .github/workflows/{unit_tests.yml => testing.yml} (91%) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/testing.yml similarity index 91% rename from .github/workflows/unit_tests.yml rename to .github/workflows/testing.yml index c114c61028..cb18546f42 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/testing.yml @@ -1,4 +1,4 @@ -name: Unit Tests +name: Testing # Compile MET and run unit tests # for pull requests into develop branch @@ -82,8 +82,8 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore - unit_tests_1a: - name: MET Unit Tests 1a + unit_1a: + name: Unit 1a runs-on: ubuntu-latest needs: [job_control, compile] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} @@ -106,7 +106,7 @@ jobs: - name: Upload output as artifact uses: actions/upload-artifact@v2 with: - name: unit_tests_1a + name: unit_1a path: ${{ runner.workspace }}/output - name: Upload logs as artifact @@ -117,8 +117,8 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore - unit_tests_1b: - name: MET Unit Tests 1b + unit_1b: + name: Unit 1b runs-on: ubuntu-latest needs: [job_control, compile] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} @@ -141,7 +141,7 @@ jobs: - name: Upload output as artifact uses: actions/upload-artifact@v2 with: - name: unit_tests_1b + name: unit_1b path: ${{ runner.workspace }}/output - name: Upload logs as artifact @@ -152,8 +152,8 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore - unit_tests_ref_config_leads: - name: MET Unit Tests ref_config leads + unit_rc_leads: + name: Unit RC leads runs-on: ubuntu-latest needs: [job_control, compile] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} @@ -177,7 +177,7 @@ jobs: - name: Upload output as artifact uses: actions/upload-artifact@v2 with: - name: unit_tests_ref_config_leads + name: unit_rc_leads path: ${{ runner.workspace }}/output - name: Upload logs as artifact @@ -188,10 +188,10 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore - unit_tests_ref_config: - name: MET Unit Tests ref_config + unit_rc: + name: Unit RC runs-on: ubuntu-latest - needs: [job_control, unit_tests_ref_config_leads] + needs: [job_control, unit_rc_leads] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} strategy: matrix: @@ -204,7 +204,7 @@ jobs: - name: Download ref_config_leads output from artifact uses: actions/download-artifact@v2 with: - name: unit_tests_ref_config_leads + name: unit_rc_leads path: ${{ runner.workspace }}/output - name: Run Unit Tests in Docker @@ -217,7 +217,7 @@ jobs: - name: Upload output as artifact uses: actions/upload-artifact@v2 with: - name: unit_tests_ref_config + name: unit_rc path: ${{ runner.workspace }}/output - name: Upload logs as artifact @@ -228,10 +228,10 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore - unit_tests_2a: - name: MET Unit Tests 2a + unit_2a: + name: Unit 2a runs-on: ubuntu-latest - needs: [job_control, unit_tests_1a] + needs: [job_control, unit_1a] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} strategy: matrix: @@ -247,7 +247,7 @@ jobs: - name: Download 1a output from artifact uses: actions/download-artifact@v2 with: - name: unit_tests_1a + name: unit_1a path: ${{ runner.workspace }}/output - name: Run Unit Tests in Docker @@ -260,7 +260,7 @@ jobs: - name: Upload output as artifact uses: actions/upload-artifact@v2 with: - name: unit_tests_2a + name: unit_2a path: ${{ runner.workspace }}/output - name: Upload logs as artifact @@ -271,10 +271,10 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore - unit_tests_2b: - name: MET Unit Tests 2b + unit_2b: + name: Unit 2b runs-on: ubuntu-latest - needs: [job_control, unit_tests_1a] + needs: [job_control, unit_1a] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} strategy: matrix: @@ -290,7 +290,7 @@ jobs: - name: Download 1a output from artifact uses: actions/download-artifact@v2 with: - name: unit_tests_1a + name: unit_1a path: ${{ runner.workspace }}/output - name: Run Unit Tests in Docker @@ -303,7 +303,7 @@ jobs: - name: Upload output as artifact uses: actions/upload-artifact@v2 with: - name: unit_tests_2b + name: unit_2b path: ${{ runner.workspace }}/output - name: Upload logs as artifact @@ -317,7 +317,7 @@ jobs: run_diffs: name: Check for Differences runs-on: ubuntu-latest - needs: [job_control, unit_tests_1b, unit_tests_2a, unit_tests_2b, unit_tests_ref_config] + needs: [job_control, unit_1b, unit_2a, unit_2b, unit_rc] if: ${{ needs.job_control.outputs.run_diff == 'true' }} steps: - name: Download data from previous jobs @@ -326,7 +326,7 @@ jobs: - name: Copy test output into single directory run: | mkdir ${RUNNER_WORKSPACE}/output - cp -r unit_tests_*/* ${RUNNER_WORKSPACE}/output/ + cp -r unit_*/* ${RUNNER_WORKSPACE}/output/ - uses: actions/checkout@v2 @@ -356,7 +356,7 @@ jobs: update_truth: name: Update Truth Data runs-on: ubuntu-latest - needs: [job_control, unit_tests_1b, unit_tests_2a, unit_tests_2b, unit_tests_ref_config] + needs: [job_control, unit_1b, unit_2a, unit_2b, unit_rc] if: ${{ needs.job_control.outputs.run_update_truth == 'true' }} steps: - uses: actions/checkout@v2 @@ -367,7 +367,7 @@ jobs: - name: Copy test output into single directory run: | mkdir ${RUNNER_WORKSPACE}/met_test_truth - cp -r unit_tests_*/* ${RUNNER_WORKSPACE}/met_test_truth/ + cp -r unit_*/* ${RUNNER_WORKSPACE}/met_test_truth/ - name: Create Docker Data Volume run: .github/jobs/create_docker_truth.sh From ece4c3ab9a94e1d9c391fb2baba9ea3aaeab7db4 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 28 Jan 2022 14:39:24 -0700 Subject: [PATCH 087/172] fixed directory to copy truth data into -- copy command was copying the content of the directory, not including the directory itself --- .github/jobs/Dockerfile.truth | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/jobs/Dockerfile.truth b/.github/jobs/Dockerfile.truth index 6366360e13..6ee8a90925 100644 --- a/.github/jobs/Dockerfile.truth +++ b/.github/jobs/Dockerfile.truth @@ -1,7 +1,7 @@ FROM centos:7 MAINTAINER George McCabe -ENV OUTPUT_DIR /data/output +ENV OUTPUT_DIR /data/output/met_test_truth RUN mkdir -p ${OUTPUT_DIR} ARG TRUTH_DIR @@ -11,7 +11,7 @@ COPY ${TRUTH_DIR} ${OUTPUT_DIR}/ ARG TRUTH_DIR # Define the volume mount point -VOLUME ${OUTPUT_DIR}/${TRUTH_DIR} +VOLUME ${OUTPUT_DIR} USER root CMD ["true"] \ No newline at end of file From 82d45a9b6e2f370ed750b2675a2b4234b18ebb83 Mon Sep 17 00:00:00 2001 From: jprestop Date: Mon, 31 Jan 2022 13:29:25 -0700 Subject: [PATCH 088/172] Per #1907, added warning about switch from Ensemble-Stat to Gen-Ens-Prod (#2032) Co-authored-by: Julie Prestopnik --- .../tools/core/ensemble_stat/ensemble_stat_conf_info.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index 85ed9581ca..396677987b 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -241,6 +241,15 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, // Determine the number of ensemble fields to be processed n_ens_var = parse_conf_n_vx(edict); + // Print a warning if the ensemble dictionary is not empty + if(n_ens_var != 0) { + mlog << Warning << "\nEnsembleStatConfInfo::process_config() -> " + << "Ensemble post-processing should be moved to the " + << "Gen-Ens-Prod tool, which replaces the logic of the " + << "\"ens\" dictionary. Support for the \"ens\" dictionary " + << "will be deprecated and removed." << "\n\n"; + } + // Parse the ensemble field information for(i=0,max_n_thresh=0; i Date: Tue, 1 Feb 2022 13:59:24 -0700 Subject: [PATCH 089/172] 2028 Check null for header data --- met/src/libcode/vx_nc_obs/met_point_data.cc | 31 ++------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc index 6cc15a7e81..e52762b201 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.cc +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -59,12 +59,6 @@ void MetPointData::init_from_scratch() { } -//////////////////////////////////////////////////////////////////////// - -//void MetPointData::allocate() { -// obs_data.allocate(); -//} - //////////////////////////////////////////////////////////////////////// void MetPointData::clear() { @@ -178,18 +172,9 @@ MetPointDataPython::MetPointDataPython() { MetPointDataPython::MetPointDataPython(MetPointDataPython &d) { init_from_scratch(); - //obs_data = d.get_point_obs_data(); - //header_data = d.get_header_data(); - obs_data->assign(*d.get_point_obs_data()); + MetPointObsData *from_obs_data = d.get_point_obs_data(); + if (from_obs_data) obs_data->assign(*from_obs_data); header_data.assign(*d.get_header_data()); -cout << " DEBUG HS MetPointData(MetPointData &d) is called \n"; -cout << " DEBUG HS MetPointData(MetPointData &d) &header_data.lat_array=" << &(header_data.lat_array) << "\n"; -cout << " DEBUG HS MetPointData(MetPointData &d) header_data.lat_array.n()=" << header_data.lat_array.n() << "\n"; -cout << " DEBUG HS MetPointData(MetPointData &d) header_data.lon_array.n()=" << header_data.lon_array.n() << "\n"; -cout << " DEBUG HS MetPointData(MetPointData &d) header_data.elv_array.n()=" << header_data.elv_array.n() << "\n"; -cout << " DEBUG HS MetPointData(MetPointData &d) header_data.typ_idx_array.n()=" << header_data.typ_idx_array.n() << "\n"; -cout << " DEBUG HS MetPointData(MetPointData &d) header_data.sid_idx_array.n()=" << header_data.sid_idx_array.n() << "\n"; -cout << " DEBUG HS MetPointData(MetPointData &d) header_data.vld_idx_array.n()=" << header_data.vld_idx_array.n() << "\n"; } @@ -199,17 +184,6 @@ MetPointDataPython::~MetPointDataPython() { clear(); } -//////////////////////////////////////////////////////////////////////// - -//void MetPointDataPython::init_from_scratch() { -// nobs = 0; -// nhdr = 0; -// qty_length = 0; -// -// use_var_id = false; -// use_arr_vars = false; -//} - //////////////////////////////////////////////////////////////////////// @@ -434,4 +408,3 @@ void MetPointHeader::reset_counters() { } /////////////////////////////////////////////////////////////////////////////// - From c767e8f79e8a35c205ed647384d1bc0f780cd0af Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 1 Feb 2022 14:00:21 -0700 Subject: [PATCH 090/172] Removed un-reachable code --- met/src/libcode/vx_pointdata_python/pointdata_python.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/met/src/libcode/vx_pointdata_python/pointdata_python.cc b/met/src/libcode/vx_pointdata_python/pointdata_python.cc index 846966a6f1..316ec0dfc2 100644 --- a/met/src/libcode/vx_pointdata_python/pointdata_python.cc +++ b/met/src/libcode/vx_pointdata_python/pointdata_python.cc @@ -84,8 +84,6 @@ mlog << Error << "\nMetPythonPointDataFile::operator=(const MetPythonPointDataFi exit ( 1 ); -return ( * this ); - } From 310c236c8e10ba04fdd7000d08e0b986cd64e922 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 1 Feb 2022 14:02:08 -0700 Subject: [PATCH 091/172] #2028 Check if the pointer (d) is null --- .../tools/other/mode_time_domain/mtd_file_int.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_int.cc b/met/src/tools/other/mode_time_domain/mtd_file_int.cc index 0668e26396..85bda6ba3c 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_int.cc +++ b/met/src/tools/other/mode_time_domain/mtd_file_int.cc @@ -1206,19 +1206,19 @@ if ( Nobjects == 0 ) return; old.ObjVolume = new int [Nobjects]; -d = old.Data; - for (j=0; j Date: Tue, 1 Feb 2022 14:02:56 -0700 Subject: [PATCH 092/172] #2015 Changed warning to debug message --- met/src/tools/other/pb2nc/pb2nc.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index 50a8fa9ab8..b6cfb388dc 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -1995,11 +1995,16 @@ void process_pbfile(int i_pb) { } if(i_msg <= 0) { - mlog << Warning << "\n" << method_name - << ((n_derived_obs > 0) ? "Saved the derived variables only. " : " ") - << "No " << (is_prepbufr ? "PrepBufr" : "Bufr") - << " messages retained from file: " - << pbfile[i_pb] << "\n\n"; + if (n_derived_obs > 0) + mlog << Debug(3) << method_name + << "Saved the derived variables only. No " << (is_prepbufr ? "PrepBufr" : "Bufr") + << " messages retained from file: " + << pbfile[i_pb] << "\n"; + else + mlog << Warning << "\n" << method_name + << "No " << (is_prepbufr ? "PrepBufr" : "Bufr") + << " messages retained from file: " + << pbfile[i_pb] << "\n\n"; } return; From df00576b13a16af6eb43e2302c613895a9dbd30a Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 1 Feb 2022 14:03:53 -0700 Subject: [PATCH 093/172] #2028 Passing two dimensionl cur and dim array --- met/src/tools/other/madis2nc/madis2nc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/met/src/tools/other/madis2nc/madis2nc.cc b/met/src/tools/other/madis2nc/madis2nc.cc index 0f8164945a..2af469236c 100644 --- a/met/src/tools/other/madis2nc/madis2nc.cc +++ b/met/src/tools/other/madis2nc/madis2nc.cc @@ -2114,10 +2114,10 @@ void process_madis_profiler(NcFile *&f_in) { dim[1] = nlvl; get_nc_data(&var_levels, (float *)levels_arr, dim, cur); - if (IS_VALID_NC(in_uComponentQty_var)) get_nc_data(&in_uComponentQty_var, (char *)uComponentQty_arr, buf_size, i_hdr_s); + if (IS_VALID_NC(in_uComponentQty_var)) get_nc_data(&in_uComponentQty_var, (char *)uComponentQty_arr, dim, cur); else memset(uComponentQty_arr, 0, buf_size*dim[1]*sizeof(char)); - if (IS_VALID_NC(in_vComponentQty_var)) get_nc_data(&in_vComponentQty_var, (char *)vComponentQty_arr, buf_size, i_hdr_s); + if (IS_VALID_NC(in_vComponentQty_var)) get_nc_data(&in_vComponentQty_var, (char *)vComponentQty_arr, dim, cur); else memset(vComponentQty_arr, 0, buf_size*dim[1]*sizeof(char)); get_filtered_nc_data_2d(in_uComponent_var, (float *)uComponent_arr, dim, cur, "uComponent"); From 206f74a0075289e5e9e829ca73ff7449c0d80372 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 1 Feb 2022 19:12:23 -0700 Subject: [PATCH 094/172] #2028 Set obs_data --- met/src/libcode/vx_nc_obs/met_point_data.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc index e52762b201..f223c4acff 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.cc +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -172,6 +172,7 @@ MetPointDataPython::MetPointDataPython() { MetPointDataPython::MetPointDataPython(MetPointDataPython &d) { init_from_scratch(); + obs_data = new MetPointObsData(); MetPointObsData *from_obs_data = d.get_point_obs_data(); if (from_obs_data) obs_data->assign(*from_obs_data); header_data.assign(*d.get_header_data()); From 917c300e261ea93da906a16ac567b3434bbe9b21 Mon Sep 17 00:00:00 2001 From: johnhg Date: Wed, 2 Feb 2022 16:37:59 -0700 Subject: [PATCH 095/172] Feature 2003 briercl (#2034) --- met/data/config/GridStatConfig_default | 1 + met/data/config/PointStatConfig_default | 1 + met/data/config/SeriesAnalysisConfig_default | 11 +- met/docs/Users_Guide/config_options.rst | 32 +++- met/docs/Users_Guide/series-analysis.rst | 3 +- met/src/basic/vx_config/config_constants.h | 10 +- met/src/basic/vx_config/config_util.cc | 7 +- .../libcode/vx_statistics/compute_stats.cc | 2 +- met/src/libcode/vx_statistics/ens_stats.cc | 2 +- met/src/libcode/vx_statistics/pair_base.cc | 132 ++++++++++---- met/src/libcode/vx_statistics/pair_base.h | 14 +- .../vx_statistics/pair_data_ensemble.cc | 16 +- .../vx_statistics/pair_data_ensemble.h | 2 +- .../libcode/vx_statistics/pair_data_point.cc | 16 +- .../libcode/vx_statistics/pair_data_point.h | 2 +- .../tools/core/ensemble_stat/ensemble_stat.cc | 2 +- .../ensemble_stat/ensemble_stat_conf_info.cc | 2 +- met/src/tools/core/grid_stat/grid_stat.cc | 2 +- met/src/tools/core/point_stat/point_stat.cc | 2 +- .../core/point_stat/point_stat_conf_info.cc | 2 +- .../core/series_analysis/series_analysis.cc | 40 +++-- .../series_analysis_conf_info.cc | 12 +- .../series_analysis_conf_info.h | 2 + .../core/stat_analysis/aggr_stat_line.cc | 23 ++- .../tools/core/stat_analysis/aggr_stat_line.h | 2 + .../core/stat_analysis/stat_analysis_job.cc | 6 +- met/src/tools/other/pb2nc/pb2nc.cc | 5 +- test/config/GridStatConfig_climo_WMO | 1 + test/config/GridStatConfig_climo_prob | 1 + test/config/GridStatConfig_mpr_thresh | 1 + test/config/PointStatConfig_airnow | 1 + test/config/PointStatConfig_climo | 1 + test/config/PointStatConfig_climo_WMO | 1 + test/config/PointStatConfig_climo_prob | 1 + test/config/PointStatConfig_mpr_thresh | 1 + test/config/PointStatConfig_python | 1 + test/config/SeriesAnalysisConfig | 40 ++++- test/config/SeriesAnalysisConfig_climo | 13 +- test/config/SeriesAnalysisConfig_climo_prob | 164 ++++++++++++++++++ test/config/SeriesAnalysisConfig_conditional | 5 +- test/config/SeriesAnalysisConfig_python | 11 +- test/xml/unit_climatology_1.0deg.xml | 49 ++++++ 42 files changed, 519 insertions(+), 123 deletions(-) create mode 100644 test/config/SeriesAnalysisConfig_climo_prob diff --git a/met/data/config/GridStatConfig_default b/met/data/config/GridStatConfig_default index 89dc90e156..2ee10600a2 100644 --- a/met/data/config/GridStatConfig_default +++ b/met/data/config/GridStatConfig_default @@ -107,6 +107,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/PointStatConfig_default b/met/data/config/PointStatConfig_default index 558e419726..3967152fe6 100644 --- a/met/data/config/PointStatConfig_default +++ b/met/data/config/PointStatConfig_default @@ -149,6 +149,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/SeriesAnalysisConfig_default b/met/data/config/SeriesAnalysisConfig_default index c725cb2a5c..0249671fb6 100644 --- a/met/data/config/SeriesAnalysisConfig_default +++ b/met/data/config/SeriesAnalysisConfig_default @@ -85,6 +85,12 @@ climo_stdev = { file_name = []; } +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + direct_prob = FALSE; +} + //////////////////////////////////////////////////////////////////////////////// // @@ -111,8 +117,9 @@ mask = { } // -// Number of grid points to be processed concurrently. Set smaller to use -// less memory but increase the number of passes through the data. +// Number of grid points to be processed concurrently. Set smaller to use less +// memory but increase the number of passes through the data. If set <= 0, all +// grid points are processed concurrently. // block_size = 1024; diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index b56cb65d75..9f568932bd 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -1307,8 +1307,8 @@ over the "climo_mean" setting and then updating the "file_name" entry. The "climo_cdf" dictionary specifies how the the climatological mean ("climo_mean") and standard deviation ("climo_stdev") data are used to evaluate model performance relative to where the observation value falls -within the climatological distribution. This dictionary consists of 3 -entries: +within the climatological distribution. This dictionary consists of the +following entries: (1) The "cdf_bins" entry defines the climatological bins either as an integer @@ -1320,6 +1320,8 @@ entries: (3) The "write_bins" entry may be set to TRUE or FALSE. +(4) The "direct_prob" entry may be set to TRUE or FALSE. + MET uses the climatological mean and standard deviation to construct a normal PDF at each observation location. The total area under the PDF is 1, and the climatological CDF value is computed as the area of the PDF to the left of @@ -1348,11 +1350,11 @@ an even number of bins can only be uncentered. For example: 5 centered bins (cdf_bins = 5; center_bins = TRUE;) yields: 0.0, 0.125, 0.375, 0.625, 0.875, 1.0 -When multiple climatological bins are used, statistics are computed -separately for each bin, and the average of the statistics across those bins -is written to the output. When "write_bins" is true, the statistics for each -bin are also written to the output. The bin number is appended to the -contents of the VX_MASK output column. +When multiple climatological bins are used for Point-Stat and Grid-Stat, +statistics are computed separately for each bin, and the average of the +statistics across those bins is written to the output. When "write_bins" +is true, the statistics for each bin are also written to the output. +The bin number is appended to the contents of the VX_MASK output column. Setting the number of bins to 1 effectively disables this logic by grouping all pairs into a single climatological bin. @@ -1363,6 +1365,7 @@ all pairs into a single climatological bin. cdf_bins = 11; or an array of floats center_bins = TRUE; or FALSE write_bins = FALSE; or TRUE + direct_prob = FALSE; or TRUE } .. _climato_data: @@ -1381,7 +1384,18 @@ directly to compute Brier Skill Score (BSS). When "climo_mean" and "climo_stdev" are both set to non-probability fields, the MET tools use the mean, standard deviation, and observation event threshold to derive a normal approximation of the climatological -probabilities. Those derived probability values are used to compute BSS. +probabilities. + +The "direct_prob" option controls the derivation logic. When "direct_prob" is +true, the climatological probability is computed directly from the +climatological distribution at each point as the area to the left of +the event threshold value. For greater-than or greater-than-or-equal-to +thresholds, 1.0 minus the area is used. When "direct_prob" is false, the +"cdf_bins" values are sampled from climatological distribution. The probability +is computed as the proportion of those samples which meet the threshold criteria. +In this way, the number of bins impacts the resolution of the climatological +probabilities. These derived probability values are used to compute the +climatological Brier Score and Brier Skill Score. .. _mask_missing_flag: @@ -3593,6 +3607,8 @@ Computation may be memory intensive, especially for large grids. The "block_size" entry sets the number of grid points to be processed concurrently (i.e. in one pass through a time series). Smaller values require less memory but increase the number of passes through the data. +If set less than or equal to 0, it is automatically reset to the number +of grid points, and they are all processed concurrently. .. code-block:: none diff --git a/met/docs/Users_Guide/series-analysis.rst b/met/docs/Users_Guide/series-analysis.rst index bc9095dbf1..640d948012 100644 --- a/met/docs/Users_Guide/series-analysis.rst +++ b/met/docs/Users_Guide/series-analysis.rst @@ -123,8 +123,7 @@ ____________________ block_size = 1024; -Number of grid points to be processed concurrently. Set smaller to use less memory but increase the number of passes through the data. The amount of memory the Series-Analysis tool consumes is determined by the size of the grid, the length of the series, and the block_size entry defined above. The larger this entry is set the faster the tool will run, subject to the amount of memory available on the machine. - +Number of grid points to be processed concurrently. Set smaller to use less memory but increase the number of passes through the data. The amount of memory the Series-Analysis tool consumes is determined by the size of the grid, the length of the series, and the block_size entry defined above. The larger this entry is set the faster the tool will run, subject to the amount of memory available on the machine. If set less than or equal to 0, it is automatically reset to the number of grid points, and they are all processed concurrently. ____________________ diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index 01f03b3840..156c55881b 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -300,10 +300,11 @@ struct RegridInfo { // struct ClimoCDFInfo { - bool flag; // Flag to turn on/off climo CDF logic - int n_bin; // Number of climo CDF cdf bins - ThreshArray cdf_ta; // Array of CDF thresholds - bool write_bins; // Flag for writing the individual bins + bool flag; // Flag to turn on/off climo CDF logic + int n_bin; // Number of climo CDF cdf bins + ThreshArray cdf_ta; // Array of CDF thresholds + bool write_bins; // Flag for writing the individual bins + bool direct_prob; // Flag for the direct computation of probs ClimoCDFInfo(); void clear(); @@ -665,6 +666,7 @@ static const char conf_key_climo_cdf[] = "climo_cdf"; static const char conf_key_cdf_bins[] = "cdf_bins"; static const char conf_key_center_bins[] = "center_bins"; static const char conf_key_write_bins[] = "write_bins"; +static const char conf_key_direct_prob[] = "direct_prob"; static const char conf_key_time_interp_method[] = "time_interp_method"; static const char conf_key_day_interval[] = "day_interval"; static const char conf_key_hour_interval[] = "hour_interval"; diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index 1218e2940d..3d77ff1a8f 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -1498,6 +1498,7 @@ void ClimoCDFInfo::clear() { n_bin = 0; cdf_ta.clear(); write_bins = false; + direct_prob = false; } /////////////////////////////////////////////////////////////////////////////// @@ -1589,9 +1590,13 @@ ClimoCDFInfo parse_conf_climo_cdf(Dictionary *dict) { center = cdf_dict->lookup_bool(conf_key_center_bins); // Conf: write_bins - // Used by Grid-Stat and Point-Stat but not by Ensemble-Stat + // Used by Grid-Stat and Point-Stat + // Not used by Ensemble-Stat or Series-Analysis info.write_bins = cdf_dict->lookup_bool(conf_key_write_bins, false, false); + // Conf: direct_prob + info.direct_prob = cdf_dict->lookup_bool(conf_key_direct_prob, false, false); + // Check that at least one value is provided if(bins.n() == 0) { mlog << Error << "\nparse_conf_climo_cdf() -> " diff --git a/met/src/libcode/vx_statistics/compute_stats.cc b/met/src/libcode/vx_statistics/compute_stats.cc index 4d6a2046c1..4938565694 100644 --- a/met/src/libcode/vx_statistics/compute_stats.cc +++ b/met/src/libcode/vx_statistics/compute_stats.cc @@ -762,7 +762,7 @@ void compute_pctinfo(const PairDataPoint &pd, bool pstd_flag, // Use input climatological probabilities or derive them if(cmn_flag) { if(cprob_in) climo_prob = *cprob_in; - else climo_prob = derive_climo_prob(pd.cdf_info, + else climo_prob = derive_climo_prob(pd.cdf_info_ptr, pd.cmn_na, pd.csd_na, pct_info.othresh); } diff --git a/met/src/libcode/vx_statistics/ens_stats.cc b/met/src/libcode/vx_statistics/ens_stats.cc index ac9805a928..e69b74f786 100644 --- a/met/src/libcode/vx_statistics/ens_stats.cc +++ b/met/src/libcode/vx_statistics/ens_stats.cc @@ -522,7 +522,7 @@ void RPSInfo::set(const PairDataEnsemble &pd) { climo_pct.zero_out(); // Derive climatological probabilities - if(cmn_flag) climo_prob = derive_climo_prob(pd.cdf_info, + if(cmn_flag) climo_prob = derive_climo_prob(pd.cdf_info_ptr, pd.cmn_na, pd.csd_na, fthresh[i]); diff --git a/met/src/libcode/vx_statistics/pair_base.cc b/met/src/libcode/vx_statistics/pair_base.cc index a8f2f2ff83..5a41f95d1b 100644 --- a/met/src/libcode/vx_statistics/pair_base.cc +++ b/met/src/libcode/vx_statistics/pair_base.cc @@ -64,9 +64,11 @@ void PairBase::clear() { IsPointVx = false; mask_name.clear(); - mask_area_ptr = (MaskPlane *) 0; // Not allocated - mask_sid_ptr = (StringArray *) 0; // Not allocated - mask_llpnt_ptr = (MaskLatLon *) 0; // Not allocated + mask_area_ptr = (MaskPlane *) 0; // Not allocated + mask_sid_ptr = (StringArray *) 0; // Not allocated + mask_llpnt_ptr = (MaskLatLon *) 0; // Not allocated + + cdf_info_ptr = (const ClimoCDFInfo *) 0; // Not allocated msg_typ.clear(); msg_typ_vals.clear(); @@ -75,8 +77,6 @@ void PairBase::clear() { interp_mthd = InterpMthd_None; interp_shape = GridTemplateFactory::GridTemplate_None; - cdf_info.clear(); - o_na.clear(); x_na.clear(); y_na.clear(); @@ -114,9 +114,11 @@ void PairBase::erase() { IsPointVx = false; mask_name.erase(); - mask_area_ptr = (MaskPlane *) 0; // Not allocated - mask_sid_ptr = (StringArray *) 0; // Not allocated - mask_llpnt_ptr = (MaskLatLon *) 0; // Not allocated + mask_area_ptr = (MaskPlane *) 0; // Not allocated + mask_sid_ptr = (StringArray *) 0; // Not allocated + mask_llpnt_ptr = (MaskLatLon *) 0; // Not allocated + + cdf_info_ptr = (const ClimoCDFInfo *) 0; // Not allocated msg_typ.clear(); msg_typ_vals.clear(); @@ -124,8 +126,6 @@ void PairBase::erase() { interp_mthd = InterpMthd_None; interp_shape = GridTemplateFactory::GridTemplate_None; - cdf_info.clear(); - o_na.erase(); x_na.erase(); y_na.erase(); @@ -218,6 +218,15 @@ void PairBase::set_mask_llpnt_ptr(MaskLatLon *llpnt_ptr) { //////////////////////////////////////////////////////////////////////// +void PairBase::set_climo_cdf_info_ptr(const ClimoCDFInfo *info_ptr) { + + cdf_info_ptr = info_ptr; + + return; +} + +//////////////////////////////////////////////////////////////////////// + void PairBase::set_msg_typ(const char *c) { msg_typ = c; @@ -272,15 +281,6 @@ void PairBase::set_interp_shape(GridTemplateFactory::GridTemplates shape) { //////////////////////////////////////////////////////////////////////// -void PairBase::set_climo_cdf_info(const ClimoCDFInfo &info) { - - cdf_info = info; - - return; -} - -//////////////////////////////////////////////////////////////////////// - void PairBase::set_fcst_ut(unixtime ut){ fcst_ut = ut; @@ -1027,22 +1027,25 @@ bool set_climo_flag(const NumArray &f_na, const NumArray &c_na) { //////////////////////////////////////////////////////////////////////// -void derive_climo_vals(const ClimoCDFInfo &cdf_info, +void derive_climo_vals(const ClimoCDFInfo *cdf_info_ptr, double m, double s, NumArray &climo_vals) { // Initialize climo_vals.erase(); - // cdf_info.cdf_ta starts with >=0.0 and ends with >=1.0. + // Check for no work to do + if(!cdf_info_ptr) return; + + // cdf_info_ptr->cdf_ta starts with >=0.0 and ends with >=1.0. // The number of bins is the number of thresholds minus 1. // Check for bad mean value - if(is_bad_data(m) || cdf_info.cdf_ta.n() < 2) { + if(is_bad_data(m) || cdf_info_ptr->cdf_ta.n() < 2) { return; } // Single climo bin - else if(cdf_info.cdf_ta.n() == 2) { + else if(cdf_info_ptr->cdf_ta.n() == 2) { climo_vals.add(m); } // Check for bad standard deviation value @@ -1053,9 +1056,9 @@ void derive_climo_vals(const ClimoCDFInfo &cdf_info, else { // Skip the first and last thresholds - for(int i=1; icdf_ta.n()-1; i++) { climo_vals.add( - normal_cdf_inv(cdf_info.cdf_ta[i].get_value(), m, s)); + normal_cdf_inv(cdf_info_ptr->cdf_ta[i].get_value(), m, s)); } } @@ -1064,7 +1067,7 @@ void derive_climo_vals(const ClimoCDFInfo &cdf_info, //////////////////////////////////////////////////////////////////////// -NumArray derive_climo_prob(const ClimoCDFInfo &cdf_info, +NumArray derive_climo_prob(const ClimoCDFInfo *cdf_info_ptr, const NumArray &mn_na, const NumArray &sd_na, const SingleThresh &othresh) { int i, n_mn, n_sd; @@ -1090,21 +1093,74 @@ NumArray derive_climo_prob(const ClimoCDFInfo &cdf_info, // threshold else if(n_mn > 0 && n_sd > 0) { - // The first (>=0.0) and last (>=1.0) climo thresholds are omitted - mlog << Debug(4) - << "Deriving climatological probabilities for threshold " - << othresh.get_str() << " by sampling " << cdf_info.cdf_ta.n()-2 - << " values from the normal climatological distribution.\n"; - - // Compute the probability by sampling from the climo distribution - // and deriving the event frequency - for(i=0; idirect_prob) { + + mlog << Debug(4) + << "Deriving climatological probabilities for threshold " + << othresh.get_str() << " directly from the normal " + << "climatological distribution.\n"; + + // Directly derive the climatological probability + for(i=0; icdf_ta.n() == 0) { + mlog << Error << "\nderive_climo_prob() -> " + << "No climatological probability thresholds defined!\n\n"; + exit(1); + } + + // The first (>=0.0) and last (>=1.0) climo thresholds are omitted + mlog << Debug(4) + << "Deriving climatological probabilities for threshold " + << othresh.get_str() << " by sampling " + << cdf_info_ptr->cdf_ta.n()-2 + << " values from the normal climatological distribution.\n"; + + // Compute the probability by sampling from the climo distribution + // and deriving the event frequency + for(i=0; icdf_ta.n() == 2) { mlog << Debug(3) << "Computing ensemble statistics relative to the " << "climatological mean.\n"; } - else if(cmn_flag && csd_flag && cdf_info.cdf_ta.n() > 2) { + else if(cmn_flag && csd_flag && cdf_info_ptr && cdf_info_ptr->cdf_ta.n() > 2) { mlog << Debug(3) << "Computing ensemble statistics relative to a " - << cdf_info.cdf_ta.n() - 2 + << cdf_info_ptr->cdf_ta.n() - 2 << "-member climatological ensemble.\n"; } else { @@ -468,7 +468,7 @@ void PairDataEnsemble::compute_pair_vals(const gsl_rng *rng_ptr) { } // Derive ensemble from climo mean and standard deviation - derive_climo_vals(cdf_info, cmn_na[i], csd_na[i], cur_clm); + derive_climo_vals(cdf_info_ptr, cmn_na[i], csd_na[i], cur_clm); // Store empirical CRPS stats crps_emp_na.add(compute_crps_emp(o_na[i], cur_ens)); @@ -785,7 +785,7 @@ PairDataEnsemble PairDataEnsemble::subset_pairs_obs_thresh(const SingleThresh &o pd.ssvar_bin_size = ssvar_bin_size; pd.obs_error_entry = obs_error_entry; pd.obs_error_flag = obs_error_flag; - pd.cdf_info = cdf_info; + pd.cdf_info_ptr = cdf_info_ptr; bool cmn_flag = set_climo_flag(o_na, cmn_na); bool csd_flag = set_climo_flag(o_na, csd_na); @@ -1306,12 +1306,12 @@ void VxPairDataEnsemble::set_ens_size(int n) { //////////////////////////////////////////////////////////////////////// -void VxPairDataEnsemble::set_climo_cdf_info(const ClimoCDFInfo &info) { +void VxPairDataEnsemble::set_climo_cdf_info_ptr(const ClimoCDFInfo *info) { for(int i=0; imsg_typ_sfc); diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index e7055ed596..8549cbf2e8 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -1847,7 +1847,7 @@ void get_mask_points(const GridStatVxOpt &vx_opt, pd.erase(); // Store the climo CDF info - pd.set_climo_cdf_info(vx_opt.cdf_info); + pd.set_climo_cdf_info_ptr(&vx_opt.cdf_info); // Apply the mask the data fields or fill with default values apply_mask(*fcst_ptr, mask_mp, pd.f_na); diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 48ffd21c6e..11a88e0391 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -1736,7 +1736,7 @@ void do_hira_ens(int i_vx, const PairDataPoint *pd_ptr) { hira_pd.clear(); hira_pd.extend(pd_ptr->n_obs); hira_pd.set_ens_size(gt->size()); - hira_pd.set_climo_cdf_info(conf_info.vx_opt[i_vx].cdf_info); + hira_pd.set_climo_cdf_info_ptr(&conf_info.vx_opt[i_vx].cdf_info); f_ens.extend(gt->size()); // Process each observation point diff --git a/met/src/tools/core/point_stat/point_stat_conf_info.cc b/met/src/tools/core/point_stat/point_stat_conf_info.cc index 6117a0f7fc..8b90544b44 100644 --- a/met/src/tools/core/point_stat/point_stat_conf_info.cc +++ b/met/src/tools/core/point_stat/point_stat_conf_info.cc @@ -972,7 +972,7 @@ void PointStatVxOpt::set_vx_pd(PointStatConfInfo *conf_info) { vx_pd.set_mpr_thresh(mpr_sa, mpr_ta); // Store the climo CDF info - vx_pd.set_climo_cdf_info(cdf_info); + vx_pd.set_climo_cdf_info_ptr(&cdf_info); // Store the surface message type group cs = surface_msg_typ_group_str; diff --git a/met/src/tools/core/series_analysis/series_analysis.cc b/met/src/tools/core/series_analysis/series_analysis.cc index b89eeff0bb..b7f9aa01b9 100644 --- a/met/src/tools/core/series_analysis/series_analysis.cc +++ b/met/src/tools/core/series_analysis/series_analysis.cc @@ -30,6 +30,7 @@ // 010 12/11/19 Halley Gotway Reorganize logic to support the use // of python embedding. // 011 05/28/21 Halley Gotway Add MCTS HSS_EC output. +// 012 01/20/22 Halley Gotway MET #2003 Add PSTD BRIERCL output. // //////////////////////////////////////////////////////////////////////// @@ -339,6 +340,9 @@ void process_grid(const Grid &fcst_grid, const Grid &obs_grid) { // Process masking regions conf_info.process_masks(grid); + // Set the block size, if needed + if(is_bad_data(conf_info.block_size)) conf_info.block_size = nxy; + // Compute the number of reads required n_reads = nint(ceil((double) nxy / conf_info.block_size)); @@ -666,20 +670,10 @@ void process_scores() { // Number of points skipped due to valid data threshold int n_skip_zero = 0; int n_skip_pos = 0; - - // Allocate space to store the pairs for each grid point - pd_ptr = new PairDataPoint [conf_info.block_size]; - for(i=0; imagic_str() << ".\n"; @@ -1845,7 +1855,11 @@ void store_stat_pstd(int n, const ConcatString &col, else if(c == "BRIER") { v = pct_info.brier.v; } else if(c == "BRIER_NCL") { v = pct_info.brier.v_ncl[i]; } else if(c == "BRIER_NCU") { v = pct_info.brier.v_ncu[i]; } + else if(c == "BRIERCL") { v = pct_info.briercl.v; } + else if(c == "BRIERCL_NCL") { v = pct_info.briercl.v_ncl[i]; } + else if(c == "BRIERCL_NCU") { v = pct_info.briercl.v_ncu[i]; } else if(c == "BSS") { v = pct_info.bss; } + else if(c == "BSS_SMPL") { v = pct_info.bss_smpl; } else { mlog << Error << "\nstore_stat_pstd() -> " << "unsupported column name requested \"" << c diff --git a/met/src/tools/core/series_analysis/series_analysis_conf_info.cc b/met/src/tools/core/series_analysis/series_analysis_conf_info.cc index 0920787d0f..5fa6608650 100644 --- a/met/src/tools/core/series_analysis/series_analysis_conf_info.cc +++ b/met/src/tools/core/series_analysis/series_analysis_conf_info.cc @@ -68,6 +68,7 @@ void SeriesAnalysisConfInfo::clear() { fcnt_ta.clear(); ocnt_ta.clear(); cnt_logic = SetLogic_None; + cdf_info.clear(); ci_alpha.clear(); boot_interval = BootIntervalType_None; boot_rep_prop = bad_data_double; @@ -340,11 +341,11 @@ void SeriesAnalysisConfInfo::process_config(GrdFileType ftype, // Conf: block_size block_size = conf.lookup_int(conf_key_block_size); + // Reset invalid block_sizes to bad data so that they if(block_size <= 0.0) { - mlog << Error << "\nSeriesAnalysisConfInfo::process_config() -> " - << "The \"" << conf_key_block_size << "\" parameter (" - << block_size << ") must be greater than 0.\n\n"; - exit(1); + block_size = bad_data_int; + mlog << Debug(3) << "Automatically setting the \"" + << conf_key_block_size << "\" parameter to the size of the grid.\n"; } // Conf: vld_thresh @@ -414,6 +415,9 @@ void SeriesAnalysisConfInfo::process_config(GrdFileType ftype, } // end if continuous + // Conf: climo_cdf + cdf_info = parse_conf_climo_cdf(&conf); + // Conf: ci_alpha ci_alpha = parse_conf_ci_alpha(&conf); diff --git a/met/src/tools/core/series_analysis/series_analysis_conf_info.h b/met/src/tools/core/series_analysis/series_analysis_conf_info.h index 339de45ef4..f0cd829eed 100644 --- a/met/src/tools/core/series_analysis/series_analysis_conf_info.h +++ b/met/src/tools/core/series_analysis/series_analysis_conf_info.h @@ -57,6 +57,8 @@ class SeriesAnalysisConfInfo { ThreshArray ocnt_ta; // Continuous obs thresholds SetLogic cnt_logic; // Continuous threshold field logic + ClimoCDFInfo cdf_info; // Climo CDF info + NumArray ci_alpha; // Alpha value for confidence intervals BootIntervalType boot_interval; // Bootstrap CI type double boot_rep_prop; // Bootstrap replicate proportion diff --git a/met/src/tools/core/stat_analysis/aggr_stat_line.cc b/met/src/tools/core/stat_analysis/aggr_stat_line.cc index 3e66de254e..edee31714d 100644 --- a/met/src/tools/core/stat_analysis/aggr_stat_line.cc +++ b/met/src/tools/core/stat_analysis/aggr_stat_line.cc @@ -2204,9 +2204,6 @@ void aggr_mpr_lines(LineDataFile &f, STATAnalysisJob &job, // if(m.count(key) == 0) { - bool center = false; - aggr.pd.cdf_info.set_cdf_ta(nint(1.0/job.out_bin_size), center); - aggr.pd.f_na.clear(); aggr.pd.o_na.clear(); aggr.pd.cmn_na.clear(); @@ -2226,8 +2223,14 @@ void aggr_mpr_lines(LineDataFile &f, STATAnalysisJob &job, aggr.obs_var = cur.obs_var; aggr.hdr.clear(); + bool center = false; + aggr.cdf_info.set_cdf_ta(nint(1.0/job.out_bin_size), center); + m[key] = aggr; + // Set the pointer after storing in the map + m[key].pd.set_climo_cdf_info_ptr(&m[key].cdf_info); + mlog << Debug(3) << "[Case " << m.size() << "] Added new case for key \"" << key << "\".\n"; @@ -3084,9 +3087,9 @@ void aggr_orank_lines(LineDataFile &f, STATAnalysisJob &job, // Add a new map entry, if necessary // if(m.count(key) == 0) { + aggr.clear(); - bool center = false; - aggr.ens_pd.cdf_info.set_cdf_ta(nint(1.0/job.out_bin_size), center); + aggr.ens_pd.obs_error_flag = !is_bad_data(cur.ens_mean_oerr); aggr.ens_pd.set_ens_size(cur.n_ens); aggr.ens_pd.extend(cur.total); @@ -3095,7 +3098,15 @@ void aggr_orank_lines(LineDataFile &f, STATAnalysisJob &job, n_bin = ceil(1.0/aggr.ens_pd.phist_bin_size); for(i=0; i= debug_level) { diff --git a/test/config/GridStatConfig_climo_WMO b/test/config/GridStatConfig_climo_WMO index e23f74a2be..f16d03b47e 100644 --- a/test/config/GridStatConfig_climo_WMO +++ b/test/config/GridStatConfig_climo_WMO @@ -130,6 +130,7 @@ climo_cdf = { cdf_bins = 3; center_bins = TRUE; write_bins = FALSE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_prob b/test/config/GridStatConfig_climo_prob index a97291af88..085a8135d9 100644 --- a/test/config/GridStatConfig_climo_prob +++ b/test/config/GridStatConfig_climo_prob @@ -140,6 +140,7 @@ climo_cdf = { cdf_bins = [ 0.0, 0.4, 0.6, 1.0 ]; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_mpr_thresh b/test/config/GridStatConfig_mpr_thresh index 268e24cbc6..b2930f027b 100644 --- a/test/config/GridStatConfig_mpr_thresh +++ b/test/config/GridStatConfig_mpr_thresh @@ -128,6 +128,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_airnow b/test/config/PointStatConfig_airnow index 80df21807a..5c424a3cb6 100644 --- a/test/config/PointStatConfig_airnow +++ b/test/config/PointStatConfig_airnow @@ -126,6 +126,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_climo b/test/config/PointStatConfig_climo index 041642d1a6..207d251ff5 100644 --- a/test/config/PointStatConfig_climo +++ b/test/config/PointStatConfig_climo @@ -173,6 +173,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_climo_WMO b/test/config/PointStatConfig_climo_WMO index 599797cde3..c801f581ac 100644 --- a/test/config/PointStatConfig_climo_WMO +++ b/test/config/PointStatConfig_climo_WMO @@ -121,6 +121,7 @@ climo_cdf = { cdf_bins = 3; center_bins = TRUE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_climo_prob b/test/config/PointStatConfig_climo_prob index e57f5e003f..ca4cadcbc9 100644 --- a/test/config/PointStatConfig_climo_prob +++ b/test/config/PointStatConfig_climo_prob @@ -123,6 +123,7 @@ climo_cdf = { cdf_bins = 11; center_bins = TRUE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_mpr_thresh b/test/config/PointStatConfig_mpr_thresh index 6da3ee7c63..f1559f1d3f 100644 --- a/test/config/PointStatConfig_mpr_thresh +++ b/test/config/PointStatConfig_mpr_thresh @@ -115,6 +115,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_python b/test/config/PointStatConfig_python index 2e97f43f29..8d70867143 100644 --- a/test/config/PointStatConfig_python +++ b/test/config/PointStatConfig_python @@ -112,6 +112,7 @@ climo_cdf = { cdf_bins = 1; center_bins = FALSE; write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig b/test/config/SeriesAnalysisConfig index 8c5e965230..9d28ce3925 100644 --- a/test/config/SeriesAnalysisConfig +++ b/test/config/SeriesAnalysisConfig @@ -53,6 +53,39 @@ obs = { //////////////////////////////////////////////////////////////////////////////// +// +// Climatology data +// +climo_mean = { + + file_name = []; + field = []; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 31; + hour_interval = 6; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = []; +} + +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + direct_prob = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + // // Confidence interval settings // @@ -77,10 +110,11 @@ mask = { } // -// Number of grid points to be processed concurrently. Set smaller to use -// less memory but increase the number of passes through the data. +// Number of grid points to be processed concurrently. Set smaller to use less +// memory but increase the number of passes through the data. If set <= 0, all +// grid points are processed concurrently. // -block_size = 10000; +block_size = 169*154; // // Ratio of valid matched pairs to compute statistics for a grid point diff --git a/test/config/SeriesAnalysisConfig_climo b/test/config/SeriesAnalysisConfig_climo index a1ceb41577..78d9e7449f 100644 --- a/test/config/SeriesAnalysisConfig_climo +++ b/test/config/SeriesAnalysisConfig_climo @@ -82,6 +82,12 @@ climo_stdev = { file_name = [ ${CLIMO_STDEV_FILE_LIST} ]; } +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + direct_prob = FALSE; +} + //////////////////////////////////////////////////////////////////////////////// // @@ -108,10 +114,11 @@ mask = { } // -// Number of grid points to be processed concurrently. Set smaller to use -// less memory but increase the number of passes through the data. +// Number of grid points to be processed concurrently. Set smaller to use less +// memory but increase the number of passes through the data. If set <= 0, all +// grid points are processed concurrently. // -block_size = 150000; +block_size = 0; // // Ratio of valid matched pairs to compute statistics for a grid point diff --git a/test/config/SeriesAnalysisConfig_climo_prob b/test/config/SeriesAnalysisConfig_climo_prob new file mode 100644 index 0000000000..ee023bf6c4 --- /dev/null +++ b/test/config/SeriesAnalysisConfig_climo_prob @@ -0,0 +1,164 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Series-Analysis configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "SREF"; + +// +// Output description to be written +// +desc = "NA"; + +// +// Output observation type to be written +// +obtype = "GFSANL"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// +regrid = { + to_grid = FCST; + method = BILIN; + width = 2; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +censor_thresh = []; +censor_val = []; +cat_thresh = []; +cnt_thresh = [ NA ]; +cnt_logic = UNION; + +// +// Forecast and observation fields to be verified +// +fcst = { + cat_thresh = ==0.1; + + field = [ + { + name = "PROB"; level = "Z2"; + prob = { name = "TMP"; thresh_hi = 273.0; }; + } + ]; +} +obs = { + cat_thresh = <273.0; + + field = [ + { + name = "TMP"; level = "Z2"; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = obs; +climo_mean = { + + file_name = [ ${CLIMO_MEAN_FILE_LIST} ]; + + regrid = { + method = BILIN; + width = 2; + vld_thresh = 0.5; + } + + time_interp_method = DW_MEAN; + day_interval = ${DAY_INTERVAL}; + hour_interval = ${HOUR_INTERVAL}; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = [ ${CLIMO_STDEV_FILE_LIST} ]; +} + +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + direct_prob = TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +boot = { + interval = PCTILE; + rep_prop = 1.0; + n_rep = 0; + rng = "mt19937"; + seed = "1"; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification masking regions +// +mask = { + grid = ""; + poly = ""; +} + +// +// Number of grid points to be processed concurrently. Set smaller to use less +// memory but increase the number of passes through the data. If set <= 0, all +// grid points are processed concurrently. +// +block_size = -9999; + +// +// Ratio of valid matched pairs to compute statistics for a grid point +// +vld_thresh = 0.5; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Statistical output types +// +output_stats = { + fho = [ ]; + ctc = [ ]; + cts = [ ]; + mctc = [ ]; + mcts = [ ]; + cnt = [ ]; + sl1l2 = [ ]; + sal1l2 = [ ]; + pct = [ ]; + pstd = [ "TOTAL", "ROC_AUC", "BRIER", "BRIERCL", "BSS", "BSS_SMPL" ]; + pjc = [ ]; + prc = [ ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +hss_ec_value = NA; +rank_corr_flag = FALSE; +tmp_dir = "/tmp"; +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig_conditional b/test/config/SeriesAnalysisConfig_conditional index a4b1447a1c..b4becd6656 100644 --- a/test/config/SeriesAnalysisConfig_conditional +++ b/test/config/SeriesAnalysisConfig_conditional @@ -77,8 +77,9 @@ mask = { } // -// Number of grid points to be processed concurrently. Set smaller to use -// less memory but increase the number of passes through the data. +// Number of grid points to be processed concurrently. Set smaller to use less +// memory but increase the number of passes through the data. If set <= 0, all +// grid points are processed concurrently. // block_size = 10000; diff --git a/test/config/SeriesAnalysisConfig_python b/test/config/SeriesAnalysisConfig_python index 945a1a56b6..a33b237ab3 100644 --- a/test/config/SeriesAnalysisConfig_python +++ b/test/config/SeriesAnalysisConfig_python @@ -82,6 +82,12 @@ climo_stdev = { file_name = []; } +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + direct_prob = FALSE; +} + //////////////////////////////////////////////////////////////////////////////// // @@ -108,8 +114,9 @@ mask = { } // -// Number of grid points to be processed concurrently. Set smaller to use -// less memory but increase the number of passes through the data. +// Number of grid points to be processed concurrently. Set smaller to use less +// memory but increase the number of passes through the data. If set <= 0, all +// grid points are processed concurrently. // block_size = 24000; diff --git a/test/xml/unit_climatology_1.0deg.xml b/test/xml/unit_climatology_1.0deg.xml index 8fad5f3be1..6f458f13c8 100644 --- a/test/xml/unit_climatology_1.0deg.xml +++ b/test/xml/unit_climatology_1.0deg.xml @@ -190,6 +190,55 @@ + + echo "&DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F003.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F009.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F015.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F021.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F027.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F033.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F039.grib2 \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F045.grib2" \ + > &OUTPUT_DIR;/climatology_1.0deg/input_fcst_file_list; \ + echo "&DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_0000_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_0600_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1800_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0000_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_0600_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_1200_000.grb2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120410_1800_000.grb2" \ + > &OUTPUT_DIR;/climatology_1.0deg/input_obs_file_list; \ + &MET_BIN;/series_analysis + + DAY_INTERVAL 1 + HOUR_INTERVAL 6 + CLIMO_MEAN_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590409", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590410", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cmean_1d.19590411" + + + CLIMO_STDEV_FILE_LIST + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590409", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590410", + "&DATA_DIR_CLIMO;/NCEP_NCAR_40YR_1.0deg/cstdv_1d.19590411" + + + + \ + -fcst &OUTPUT_DIR;/climatology_1.0deg/input_fcst_file_list \ + -obs &OUTPUT_DIR;/climatology_1.0deg/input_obs_file_list \ + -paired \ + -out &OUTPUT_DIR;/climatology_1.0deg/series_analysis_PROB_CLIMO_1.0DEG.nc \ + -config &CONFIG_DIR;/SeriesAnalysisConfig_climo_prob \ + -v 2 + + + &OUTPUT_DIR;/climatology_1.0deg/series_analysis_PROB_CLIMO_1.0DEG.nc + + + echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ From abdc43679a0027eee8e100cf789fe0d17f014d36 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 3 Feb 2022 14:36:40 -0700 Subject: [PATCH 096/172] do not run testing workflow if changes are isolated to the met/docs directory --- .github/workflows/testing.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index cb18546f42..e07673b21b 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -4,11 +4,15 @@ name: Testing # for pull requests into develop branch on: + pull_request: types: [opened, reopened, synchronize] branches: - develop - 'main_v*' + paths-ignore: + - 'met/docs/**' + push: branches: - 'feature_*' @@ -16,6 +20,8 @@ on: - 'develop' - 'develop-ref' - 'main_v*' + paths-ignore: + - 'met/docs/**' env: DOCKERHUB_REPO: dtcenter/met-dev From 4a31d4f13fe27e26320eb388a512baaeaa0ed5ff Mon Sep 17 00:00:00 2001 From: davidalbo Date: Thu, 3 Feb 2022 16:56:50 -0700 Subject: [PATCH 097/172] Per #2013, changed source and README. ci-run-unit (#2039) --- met/README | 2 +- met/data/copyright_notice.txt | 2 +- met/internal_tests/basic/vx_config/test_config.cc | 2 +- met/internal_tests/basic/vx_config/test_lookup.cc | 2 +- met/internal_tests/basic/vx_config/test_lookup2.cc | 2 +- met/internal_tests/basic/vx_config/test_lookup3.cc | 2 +- met/internal_tests/basic/vx_config/test_met_478.cc | 2 +- met/internal_tests/basic/vx_config/test_string.cc | 2 +- met/internal_tests/basic/vx_config/test_string_then_config.cc | 2 +- met/internal_tests/basic/vx_config/test_thresh.cc | 2 +- met/internal_tests/basic/vx_config/test_user_func.cc | 2 +- met/internal_tests/basic/vx_log/test_logger.cc | 2 +- met/internal_tests/basic/vx_log/test_reg_exp.cc | 2 +- met/internal_tests/basic/vx_util/test_add_rows.cc | 2 +- met/internal_tests/basic/vx_util/test_ascii_header.cc | 2 +- met/internal_tests/basic/vx_util/test_command_line.cc | 2 +- met/internal_tests/basic/vx_util/test_data_plane.cc | 2 +- met/internal_tests/basic/vx_util/test_table_float.cc | 2 +- met/internal_tests/libcode/vx_data2d/dump_default_table.cc | 2 +- met/internal_tests/libcode/vx_data2d/test_table_read.cc | 2 +- met/internal_tests/libcode/vx_data2d_factory/test_factory.cc | 2 +- met/internal_tests/libcode/vx_data2d_factory/test_is_grib.cc | 2 +- met/internal_tests/libcode/vx_data2d_grib/test_read_grib1.cc | 2 +- met/internal_tests/libcode/vx_data2d_nc_met/test_read_nc_met.cc | 2 +- met/internal_tests/libcode/vx_data2d_nccf/test_read_nccf.cc | 2 +- met/internal_tests/libcode/vx_geodesy/test_spheroid.cc | 2 +- met/internal_tests/libcode/vx_grid/test_grid_area.cc | 2 +- met/internal_tests/libcode/vx_nc_util/test_pressure_levels.cc | 2 +- met/internal_tests/libcode/vx_physics/test_thermo.cc | 2 +- met/internal_tests/libcode/vx_plot_util/test_map_region.cc | 2 +- met/internal_tests/libcode/vx_ps/test_ps.cc | 2 +- met/internal_tests/libcode/vx_series_data/test_series_data.cc | 2 +- met/internal_tests/libcode/vx_solar/test_ra_dec.cc | 2 +- met/internal_tests/libcode/vx_tc_util/test_read.cc | 2 +- met/internal_tests/libcode/vx_tc_util/test_read_prob.cc | 2 +- met/internal_tests/libcode/vx_tc_util/test_read_rmw.cc | 2 +- .../tools/other/mode_time_domain/test_velocity.cc | 2 +- met/src/basic/enum_to_string/code.cc | 2 +- met/src/basic/enum_to_string/code.h | 2 +- met/src/basic/enum_to_string/enum.tab.h | 2 +- met/src/basic/enum_to_string/enum_to_string.cc | 2 +- met/src/basic/enum_to_string/enum_to_string.h | 2 +- met/src/basic/enum_to_string/info.cc | 2 +- met/src/basic/enum_to_string/info.h | 2 +- met/src/basic/enum_to_string/scope.cc | 2 +- met/src/basic/enum_to_string/scope.h | 2 +- met/src/basic/vx_cal/date_to_mjd.cc | 2 +- met/src/basic/vx_cal/day_dif.cc | 2 +- met/src/basic/vx_cal/day_of_week.cc | 2 +- met/src/basic/vx_cal/doyhms_to_unix.cc | 2 +- met/src/basic/vx_cal/is_dst.cc | 2 +- met/src/basic/vx_cal/is_leap_year.cc | 2 +- met/src/basic/vx_cal/mdyhms_to_unix.cc | 2 +- met/src/basic/vx_cal/mjd_to_date.cc | 2 +- met/src/basic/vx_cal/time_array.cc | 2 +- met/src/basic/vx_cal/time_array.h | 2 +- met/src/basic/vx_cal/time_strings.cc | 2 +- met/src/basic/vx_cal/unix_string.cc | 2 +- met/src/basic/vx_cal/unix_to_mdyhms.cc | 2 +- met/src/basic/vx_cal/vx_cal.h | 2 +- met/src/basic/vx_config/builtin.cc | 2 +- met/src/basic/vx_config/builtin.h | 2 +- met/src/basic/vx_config/calculator.cc | 2 +- met/src/basic/vx_config/calculator.h | 2 +- met/src/basic/vx_config/config_constants.h | 2 +- met/src/basic/vx_config/config_file.cc | 2 +- met/src/basic/vx_config/config_file.h | 2 +- met/src/basic/vx_config/config_funcs.cc | 2 +- met/src/basic/vx_config/config_funcs.h | 2 +- met/src/basic/vx_config/config_gaussian.h | 2 +- met/src/basic/vx_config/config_util.cc | 2 +- met/src/basic/vx_config/config_util.h | 2 +- met/src/basic/vx_config/data_file_type.h | 2 +- met/src/basic/vx_config/dictionary.cc | 2 +- met/src/basic/vx_config/dictionary.h | 2 +- met/src/basic/vx_config/icode.cc | 2 +- met/src/basic/vx_config/icode.h | 2 +- met/src/basic/vx_config/idstack.cc | 2 +- met/src/basic/vx_config/idstack.h | 2 +- met/src/basic/vx_config/number_stack.cc | 2 +- met/src/basic/vx_config/number_stack.h | 2 +- met/src/basic/vx_config/object_types.h | 2 +- met/src/basic/vx_config/scanner_stuff.h | 2 +- met/src/basic/vx_config/temp_file.cc | 2 +- met/src/basic/vx_config/temp_file.h | 2 +- met/src/basic/vx_config/threshold.cc | 2 +- met/src/basic/vx_config/threshold.h | 2 +- met/src/basic/vx_config/vx_config.h | 2 +- met/src/basic/vx_log/concat_string.cc | 2 +- met/src/basic/vx_log/concat_string.h | 2 +- met/src/basic/vx_log/file_fxns.cc | 2 +- met/src/basic/vx_log/file_fxns.h | 2 +- met/src/basic/vx_log/indent.cc | 2 +- met/src/basic/vx_log/indent.h | 2 +- met/src/basic/vx_log/logger.cc | 2 +- met/src/basic/vx_log/logger.h | 2 +- met/src/basic/vx_log/str_wrappers.cc | 2 +- met/src/basic/vx_log/str_wrappers.h | 2 +- met/src/basic/vx_log/string_array.cc | 2 +- met/src/basic/vx_log/string_array.h | 2 +- met/src/basic/vx_log/vx_log.h | 2 +- met/src/basic/vx_math/affine.cc | 2 +- met/src/basic/vx_math/affine.h | 2 +- met/src/basic/vx_math/angles.cc | 2 +- met/src/basic/vx_math/angles.h | 2 +- met/src/basic/vx_math/hist.cc | 2 +- met/src/basic/vx_math/hist.h | 2 +- met/src/basic/vx_math/is_bad_data.h | 2 +- met/src/basic/vx_math/legendre.cc | 2 +- met/src/basic/vx_math/legendre.h | 2 +- met/src/basic/vx_math/math_constants.h | 2 +- met/src/basic/vx_math/nint.cc | 2 +- met/src/basic/vx_math/nint.h | 2 +- met/src/basic/vx_math/nti.cc | 2 +- met/src/basic/vx_math/nti.h | 2 +- met/src/basic/vx_math/ptile.cc | 2 +- met/src/basic/vx_math/ptile.h | 2 +- met/src/basic/vx_math/pwl.cc | 2 +- met/src/basic/vx_math/pwl.h | 2 +- met/src/basic/vx_math/so3.cc | 2 +- met/src/basic/vx_math/so3.h | 2 +- met/src/basic/vx_math/trig.h | 2 +- met/src/basic/vx_math/vx_math.h | 2 +- met/src/basic/vx_math/vx_vector.cc | 2 +- met/src/basic/vx_math/vx_vector.h | 2 +- met/src/basic/vx_util/CircularTemplate.cc | 2 +- met/src/basic/vx_util/CircularTemplate.h | 2 +- met/src/basic/vx_util/GridOffset.cc | 2 +- met/src/basic/vx_util/GridOffset.h | 2 +- met/src/basic/vx_util/GridPoint.cc | 2 +- met/src/basic/vx_util/GridPoint.h | 2 +- met/src/basic/vx_util/GridTemplate.cc | 2 +- met/src/basic/vx_util/GridTemplate.h | 2 +- met/src/basic/vx_util/RectangularTemplate.cc | 2 +- met/src/basic/vx_util/RectangularTemplate.h | 2 +- met/src/basic/vx_util/ascii_header.cc | 2 +- met/src/basic/vx_util/ascii_header.h | 2 +- met/src/basic/vx_util/ascii_table.cc | 2 +- met/src/basic/vx_util/ascii_table.h | 2 +- met/src/basic/vx_util/bool_to_string.h | 2 +- met/src/basic/vx_util/check_endian.cc | 2 +- met/src/basic/vx_util/check_endian.h | 2 +- met/src/basic/vx_util/comma_string.cc | 2 +- met/src/basic/vx_util/comma_string.h | 2 +- met/src/basic/vx_util/command_line.cc | 2 +- met/src/basic/vx_util/command_line.h | 2 +- met/src/basic/vx_util/conversions.cc | 2 +- met/src/basic/vx_util/conversions.h | 2 +- met/src/basic/vx_util/crc_array.h | 2 +- met/src/basic/vx_util/crr_array.h | 2 +- met/src/basic/vx_util/data_cube.cc | 2 +- met/src/basic/vx_util/data_cube.h | 2 +- met/src/basic/vx_util/data_line.cc | 2 +- met/src/basic/vx_util/data_line.h | 2 +- met/src/basic/vx_util/data_plane.cc | 2 +- met/src/basic/vx_util/data_plane.h | 2 +- met/src/basic/vx_util/data_plane_util.cc | 2 +- met/src/basic/vx_util/data_plane_util.h | 2 +- met/src/basic/vx_util/empty_string.h | 2 +- met/src/basic/vx_util/file_exists.cc | 2 +- met/src/basic/vx_util/file_exists.h | 2 +- met/src/basic/vx_util/file_linecount.cc | 2 +- met/src/basic/vx_util/file_linecount.h | 2 +- met/src/basic/vx_util/file_size.cc | 2 +- met/src/basic/vx_util/file_size.h | 2 +- met/src/basic/vx_util/filename_suffix.cc | 2 +- met/src/basic/vx_util/filename_suffix.h | 2 +- met/src/basic/vx_util/fix_float.cc | 2 +- met/src/basic/vx_util/fix_float.h | 2 +- met/src/basic/vx_util/get_filenames.cc | 2 +- met/src/basic/vx_util/get_filenames.h | 2 +- met/src/basic/vx_util/grib_constants.cc | 2 +- met/src/basic/vx_util/grib_constants.h | 2 +- met/src/basic/vx_util/handle_openmp.cc | 2 +- met/src/basic/vx_util/handle_openmp.h | 2 +- met/src/basic/vx_util/int_array.h | 2 +- met/src/basic/vx_util/interp_mthd.cc | 2 +- met/src/basic/vx_util/interp_mthd.h | 2 +- met/src/basic/vx_util/interp_util.cc | 2 +- met/src/basic/vx_util/interp_util.h | 2 +- met/src/basic/vx_util/is_number.cc | 2 +- met/src/basic/vx_util/is_number.h | 2 +- met/src/basic/vx_util/long_array.cc | 2 +- met/src/basic/vx_util/long_array.h | 2 +- met/src/basic/vx_util/make_path.cc | 2 +- met/src/basic/vx_util/make_path.h | 2 +- met/src/basic/vx_util/mask_poly.cc | 2 +- met/src/basic/vx_util/mask_poly.h | 2 +- met/src/basic/vx_util/memory.cc | 2 +- met/src/basic/vx_util/memory.h | 2 +- met/src/basic/vx_util/met_buffer.cc | 2 +- met/src/basic/vx_util/met_buffer.h | 2 +- met/src/basic/vx_util/ncrr_array.h | 2 +- met/src/basic/vx_util/num_array.cc | 2 +- met/src/basic/vx_util/num_array.h | 2 +- met/src/basic/vx_util/observation.cc | 2 +- met/src/basic/vx_util/observation.h | 2 +- met/src/basic/vx_util/ordinal.cc | 2 +- met/src/basic/vx_util/ordinal.h | 2 +- met/src/basic/vx_util/polyline.cc | 2 +- met/src/basic/vx_util/polyline.h | 2 +- met/src/basic/vx_util/python_line.cc | 2 +- met/src/basic/vx_util/python_line.h | 2 +- met/src/basic/vx_util/read_fortran_binary.cc | 2 +- met/src/basic/vx_util/read_fortran_binary.h | 2 +- met/src/basic/vx_util/roman_numeral.cc | 2 +- met/src/basic/vx_util/roman_numeral.h | 2 +- met/src/basic/vx_util/smart_buffer.cc | 2 +- met/src/basic/vx_util/smart_buffer.h | 2 +- met/src/basic/vx_util/stat_column_defs.h | 2 +- met/src/basic/vx_util/string_fxns.cc | 2 +- met/src/basic/vx_util/string_fxns.h | 2 +- met/src/basic/vx_util/substring.cc | 2 +- met/src/basic/vx_util/substring.h | 2 +- met/src/basic/vx_util/thresh_array.cc | 2 +- met/src/basic/vx_util/thresh_array.h | 2 +- met/src/basic/vx_util/two_d_array.h | 2 +- met/src/basic/vx_util/two_to_one.cc | 2 +- met/src/basic/vx_util/two_to_one.h | 2 +- met/src/basic/vx_util/util_constants.h | 2 +- met/src/basic/vx_util/vx_util.h | 2 +- met/src/libcode/vx_afm/afm.cc | 2 +- met/src/libcode/vx_afm/afm.h | 2 +- met/src/libcode/vx_afm/afm_keywords.cc | 2 +- met/src/libcode/vx_afm/afm_keywords.h | 2 +- met/src/libcode/vx_afm/afm_line.cc | 2 +- met/src/libcode/vx_afm/afm_line.h | 2 +- met/src/libcode/vx_afm/afm_token.cc | 2 +- met/src/libcode/vx_afm/afm_token.h | 2 +- met/src/libcode/vx_afm/afm_token_types.h | 2 +- met/src/libcode/vx_afm/afmkeyword_to_string.cc | 2 +- met/src/libcode/vx_afm/afmkeyword_to_string.h | 2 +- met/src/libcode/vx_afm/afmtokentype_to_string.cc | 2 +- met/src/libcode/vx_afm/afmtokentype_to_string.h | 2 +- met/src/libcode/vx_analysis_util/analysis_utils.cc | 2 +- met/src/libcode/vx_analysis_util/analysis_utils.h | 2 +- met/src/libcode/vx_analysis_util/by_case_info.cc | 2 +- met/src/libcode/vx_analysis_util/by_case_info.h | 2 +- met/src/libcode/vx_analysis_util/mode_atts.cc | 2 +- met/src/libcode/vx_analysis_util/mode_atts.h | 2 +- met/src/libcode/vx_analysis_util/mode_job.cc | 2 +- met/src/libcode/vx_analysis_util/mode_job.h | 2 +- met/src/libcode/vx_analysis_util/mode_line.cc | 2 +- met/src/libcode/vx_analysis_util/mode_line.h | 2 +- met/src/libcode/vx_analysis_util/stat_job.cc | 2 +- met/src/libcode/vx_analysis_util/stat_job.h | 2 +- met/src/libcode/vx_analysis_util/stat_line.cc | 2 +- met/src/libcode/vx_analysis_util/stat_line.h | 2 +- met/src/libcode/vx_analysis_util/time_series.cc | 2 +- met/src/libcode/vx_analysis_util/time_series.h | 2 +- met/src/libcode/vx_analysis_util/vx_analysis_util.h | 2 +- met/src/libcode/vx_color/color.cc | 2 +- met/src/libcode/vx_color/color.h | 2 +- met/src/libcode/vx_color/color_list.cc | 2 +- met/src/libcode/vx_color/color_list.h | 2 +- met/src/libcode/vx_color/color_parser.h | 2 +- met/src/libcode/vx_color/color_table.cc | 2 +- met/src/libcode/vx_color/vx_color.h | 2 +- met/src/libcode/vx_data2d/data2d_utils.cc | 2 +- met/src/libcode/vx_data2d/data2d_utils.h | 2 +- met/src/libcode/vx_data2d/data_class.cc | 2 +- met/src/libcode/vx_data2d/data_class.h | 2 +- met/src/libcode/vx_data2d/level_info.cc | 2 +- met/src/libcode/vx_data2d/level_info.h | 2 +- met/src/libcode/vx_data2d/table_lookup.cc | 2 +- met/src/libcode/vx_data2d/table_lookup.h | 2 +- met/src/libcode/vx_data2d/var_info.cc | 2 +- met/src/libcode/vx_data2d/var_info.h | 2 +- met/src/libcode/vx_data2d/vx_data2d.h | 2 +- met/src/libcode/vx_data2d_factory/data2d_factory.cc | 2 +- met/src/libcode/vx_data2d_factory/data2d_factory.h | 2 +- met/src/libcode/vx_data2d_factory/data2d_factory_utils.cc | 2 +- met/src/libcode/vx_data2d_factory/data2d_factory_utils.h | 2 +- met/src/libcode/vx_data2d_factory/is_bufr_file.cc | 2 +- met/src/libcode/vx_data2d_factory/is_bufr_file.h | 2 +- met/src/libcode/vx_data2d_factory/is_grib_file.cc | 2 +- met/src/libcode/vx_data2d_factory/is_grib_file.h | 2 +- met/src/libcode/vx_data2d_factory/is_netcdf_file.cc | 2 +- met/src/libcode/vx_data2d_factory/is_netcdf_file.h | 2 +- met/src/libcode/vx_data2d_factory/parse_file_list.cc | 2 +- met/src/libcode/vx_data2d_factory/parse_file_list.h | 2 +- met/src/libcode/vx_data2d_factory/var_info_factory.cc | 2 +- met/src/libcode/vx_data2d_factory/var_info_factory.h | 2 +- met/src/libcode/vx_data2d_factory/vx_data2d_factory.h | 2 +- met/src/libcode/vx_data2d_grib/data2d_grib.cc | 2 +- met/src/libcode/vx_data2d_grib/data2d_grib.h | 2 +- met/src/libcode/vx_data2d_grib/data2d_grib_utils.cc | 2 +- met/src/libcode/vx_data2d_grib/data2d_grib_utils.h | 2 +- met/src/libcode/vx_data2d_grib/grib_classes.cc | 2 +- met/src/libcode/vx_data2d_grib/grib_classes.h | 2 +- met/src/libcode/vx_data2d_grib/grib_strings.cc | 2 +- met/src/libcode/vx_data2d_grib/grib_strings.h | 2 +- met/src/libcode/vx_data2d_grib/grib_utils.cc | 2 +- met/src/libcode/vx_data2d_grib/grib_utils.h | 2 +- met/src/libcode/vx_data2d_grib/var_info_grib.cc | 2 +- met/src/libcode/vx_data2d_grib/var_info_grib.h | 2 +- met/src/libcode/vx_data2d_grib/vx_data2d_grib.h | 2 +- met/src/libcode/vx_data2d_grib/vx_grib_classes.h | 2 +- met/src/libcode/vx_data2d_grib2/data2d_grib2.cc | 2 +- met/src/libcode/vx_data2d_grib2/data2d_grib2.h | 2 +- met/src/libcode/vx_data2d_grib2/var_info_grib2.cc | 2 +- met/src/libcode/vx_data2d_grib2/var_info_grib2.h | 2 +- met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc | 2 +- met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h | 2 +- met/src/libcode/vx_data2d_nc_met/get_met_grid.cc | 2 +- met/src/libcode/vx_data2d_nc_met/get_met_grid.h | 2 +- met/src/libcode/vx_data2d_nc_met/met_file.cc | 2 +- met/src/libcode/vx_data2d_nc_met/met_file.h | 2 +- met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc | 2 +- met/src/libcode/vx_data2d_nc_met/var_info_nc_met.h | 2 +- met/src/libcode/vx_data2d_nc_met/vx_data2d_nc_met.h | 2 +- met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.cc | 2 +- met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.h | 2 +- met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc | 2 +- met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.h | 2 +- met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.cc | 2 +- met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.h | 2 +- met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc | 2 +- met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.h | 2 +- met/src/libcode/vx_data2d_nc_pinterp/vx_data2d_nc_pinterp.h | 2 +- met/src/libcode/vx_data2d_nccf/data2d_nccf.cc | 2 +- met/src/libcode/vx_data2d_nccf/data2d_nccf.h | 2 +- met/src/libcode/vx_data2d_nccf/nccf_file.cc | 2 +- met/src/libcode/vx_data2d_nccf/nccf_file.h | 2 +- met/src/libcode/vx_data2d_nccf/var_info_nccf.cc | 2 +- met/src/libcode/vx_data2d_nccf/var_info_nccf.h | 2 +- met/src/libcode/vx_data2d_nccf/vx_data2d_nccf.h | 2 +- met/src/libcode/vx_data2d_python/data2d_python.cc | 2 +- met/src/libcode/vx_data2d_python/data2d_python.h | 2 +- met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.cc | 2 +- met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.h | 2 +- met/src/libcode/vx_data2d_python/dataplane_from_xarray.cc | 2 +- met/src/libcode/vx_data2d_python/dataplane_from_xarray.h | 2 +- met/src/libcode/vx_data2d_python/grid_from_python_dict.cc | 2 +- met/src/libcode/vx_data2d_python/grid_from_python_dict.h | 2 +- met/src/libcode/vx_data2d_python/python_dataplane.cc | 2 +- met/src/libcode/vx_data2d_python/python_dataplane.h | 2 +- met/src/libcode/vx_data2d_python/var_info_python.cc | 2 +- met/src/libcode/vx_data2d_python/var_info_python.h | 2 +- met/src/libcode/vx_geodesy/spheroid.cc | 2 +- met/src/libcode/vx_geodesy/spheroid.h | 2 +- met/src/libcode/vx_geodesy/vx_geodesy.h | 2 +- met/src/libcode/vx_gis/dbf_file.cc | 2 +- met/src/libcode/vx_gis/dbf_file.h | 2 +- met/src/libcode/vx_gis/shp_array.h | 2 +- met/src/libcode/vx_gis/shp_file.cc | 2 +- met/src/libcode/vx_gis/shp_file.h | 2 +- met/src/libcode/vx_gis/shp_point_record.cc | 2 +- met/src/libcode/vx_gis/shp_point_record.h | 2 +- met/src/libcode/vx_gis/shp_poly_record.cc | 2 +- met/src/libcode/vx_gis/shp_poly_record.h | 2 +- met/src/libcode/vx_gis/shp_types.h | 2 +- met/src/libcode/vx_gis/shx_file.cc | 2 +- met/src/libcode/vx_gis/shx_file.h | 2 +- met/src/libcode/vx_gis/vx_gis.h | 2 +- met/src/libcode/vx_gnomon/gnomon.cc | 2 +- met/src/libcode/vx_gnomon/gnomon.h | 2 +- met/src/libcode/vx_grid/earth_rotation.cc | 2 +- met/src/libcode/vx_grid/earth_rotation.h | 2 +- met/src/libcode/vx_grid/find_grid_by_name.cc | 2 +- met/src/libcode/vx_grid/find_grid_by_name.h | 2 +- met/src/libcode/vx_grid/gaussian_grid.cc | 2 +- met/src/libcode/vx_grid/gaussian_grid.h | 2 +- met/src/libcode/vx_grid/gaussian_grid_defs.h | 2 +- met/src/libcode/vx_grid/goes_grid.cc | 2 +- met/src/libcode/vx_grid/goes_grid.h | 2 +- met/src/libcode/vx_grid/goes_grid_defs.h | 2 +- met/src/libcode/vx_grid/grid_base.cc | 2 +- met/src/libcode/vx_grid/grid_base.h | 2 +- met/src/libcode/vx_grid/latlon_grid.cc | 2 +- met/src/libcode/vx_grid/latlon_grid.h | 2 +- met/src/libcode/vx_grid/latlon_grid_defs.h | 2 +- met/src/libcode/vx_grid/latlon_xyz.cc | 2 +- met/src/libcode/vx_grid/latlon_xyz.h | 2 +- met/src/libcode/vx_grid/lc_grid.cc | 2 +- met/src/libcode/vx_grid/lc_grid.h | 2 +- met/src/libcode/vx_grid/lc_grid_defs.h | 2 +- met/src/libcode/vx_grid/merc_grid.cc | 2 +- met/src/libcode/vx_grid/merc_grid.h | 2 +- met/src/libcode/vx_grid/merc_grid_defs.h | 2 +- met/src/libcode/vx_grid/rot_latlon_grid.cc | 2 +- met/src/libcode/vx_grid/rot_latlon_grid.h | 2 +- met/src/libcode/vx_grid/st_grid.cc | 2 +- met/src/libcode/vx_grid/st_grid.h | 2 +- met/src/libcode/vx_grid/st_grid_defs.h | 2 +- met/src/libcode/vx_grid/tcrmw_grid.cc | 2 +- met/src/libcode/vx_grid/tcrmw_grid.h | 2 +- met/src/libcode/vx_grid/vx_grid.h | 2 +- met/src/libcode/vx_gsl_prob/gsl_bvn.cc | 2 +- met/src/libcode/vx_gsl_prob/gsl_bvn.h | 2 +- met/src/libcode/vx_gsl_prob/gsl_cdf.cc | 2 +- met/src/libcode/vx_gsl_prob/gsl_cdf.h | 2 +- met/src/libcode/vx_gsl_prob/gsl_randist.cc | 2 +- met/src/libcode/vx_gsl_prob/gsl_randist.h | 2 +- met/src/libcode/vx_gsl_prob/gsl_statistics.cc | 2 +- met/src/libcode/vx_gsl_prob/gsl_statistics.h | 2 +- met/src/libcode/vx_gsl_prob/gsl_wavelet2d.cc | 2 +- met/src/libcode/vx_gsl_prob/gsl_wavelet2d.h | 2 +- met/src/libcode/vx_gsl_prob/vx_gsl_prob.h | 2 +- met/src/libcode/vx_nav/nav.cc | 2 +- met/src/libcode/vx_nav/nav.h | 2 +- met/src/libcode/vx_nc_obs/met_point_data.cc | 2 +- met/src/libcode/vx_nc_obs/met_point_data.h | 2 +- met/src/libcode/vx_nc_obs/nc_obs_util.cc | 2 +- met/src/libcode/vx_nc_obs/nc_obs_util.h | 2 +- met/src/libcode/vx_nc_obs/nc_point_obs.cc | 2 +- met/src/libcode/vx_nc_obs/nc_point_obs.h | 2 +- met/src/libcode/vx_nc_obs/nc_point_obs_in.cc | 2 +- met/src/libcode/vx_nc_obs/nc_point_obs_in.h | 2 +- met/src/libcode/vx_nc_obs/nc_point_obs_out.cc | 2 +- met/src/libcode/vx_nc_obs/nc_point_obs_out.h | 2 +- met/src/libcode/vx_nc_obs/nc_summary.cc | 2 +- met/src/libcode/vx_nc_obs/nc_summary.h | 2 +- met/src/libcode/vx_nc_util/grid_output.cc | 2 +- met/src/libcode/vx_nc_util/grid_output.h | 2 +- met/src/libcode/vx_nc_util/load_tc_data.cc | 2 +- met/src/libcode/vx_nc_util/load_tc_data.h | 2 +- met/src/libcode/vx_nc_util/nc_constants.h | 2 +- met/src/libcode/vx_nc_util/nc_utils.cc | 2 +- met/src/libcode/vx_nc_util/nc_utils.h | 2 +- met/src/libcode/vx_nc_util/nc_var_info.cc | 2 +- met/src/libcode/vx_nc_util/nc_var_info.h | 2 +- met/src/libcode/vx_nc_util/vx_nc_util.h | 2 +- met/src/libcode/vx_nc_util/write_netcdf.cc | 2 +- met/src/libcode/vx_nc_util/write_netcdf.h | 2 +- met/src/libcode/vx_pb_util/copy_bytes.cc | 2 +- met/src/libcode/vx_pb_util/copy_bytes.h | 2 +- met/src/libcode/vx_pb_util/do_blocking.cc | 2 +- met/src/libcode/vx_pb_util/do_blocking.h | 2 +- met/src/libcode/vx_pb_util/do_unblocking.cc | 2 +- met/src/libcode/vx_pb_util/do_unblocking.h | 2 +- met/src/libcode/vx_pb_util/pblock.cc | 2 +- met/src/libcode/vx_pb_util/pblock.h | 2 +- met/src/libcode/vx_pb_util/vx_pb_util.h | 2 +- met/src/libcode/vx_physics/thermo.cc | 2 +- met/src/libcode/vx_physics/thermo.h | 2 +- met/src/libcode/vx_plot_util/data_plane_plot.cc | 2 +- met/src/libcode/vx_plot_util/data_plane_plot.h | 2 +- met/src/libcode/vx_plot_util/map_region.cc | 2 +- met/src/libcode/vx_plot_util/map_region.h | 2 +- met/src/libcode/vx_plot_util/vx_plot_util.cc | 2 +- met/src/libcode/vx_plot_util/vx_plot_util.h | 2 +- met/src/libcode/vx_pointdata_python/pointdata_from_array.cc | 2 +- met/src/libcode/vx_pointdata_python/pointdata_from_array.h | 2 +- met/src/libcode/vx_pointdata_python/pointdata_python.cc | 2 +- met/src/libcode/vx_pointdata_python/pointdata_python.h | 2 +- met/src/libcode/vx_pointdata_python/python_pointdata.cc | 2 +- met/src/libcode/vx_pointdata_python/python_pointdata.h | 2 +- met/src/libcode/vx_ps/ps_text.cc | 2 +- met/src/libcode/vx_ps/ps_text.h | 2 +- met/src/libcode/vx_ps/table_helper.cc | 2 +- met/src/libcode/vx_ps/table_helper.h | 2 +- met/src/libcode/vx_ps/vx_ps.cc | 2 +- met/src/libcode/vx_ps/vx_ps.h | 2 +- met/src/libcode/vx_pxm/pbm.cc | 2 +- met/src/libcode/vx_pxm/pbm.h | 2 +- met/src/libcode/vx_pxm/pcm.cc | 2 +- met/src/libcode/vx_pxm/pcm.h | 2 +- met/src/libcode/vx_pxm/pgm.cc | 2 +- met/src/libcode/vx_pxm/pgm.h | 2 +- met/src/libcode/vx_pxm/ppm.cc | 2 +- met/src/libcode/vx_pxm/ppm.h | 2 +- met/src/libcode/vx_pxm/pxm_base.cc | 2 +- met/src/libcode/vx_pxm/pxm_base.h | 2 +- met/src/libcode/vx_pxm/pxm_utils.cc | 2 +- met/src/libcode/vx_pxm/pxm_utils.h | 2 +- met/src/libcode/vx_pxm/vx_pxm.h | 2 +- met/src/libcode/vx_python3_utils/global_python.h | 2 +- met/src/libcode/vx_python3_utils/python3_dict.cc | 2 +- met/src/libcode/vx_python3_utils/python3_dict.h | 2 +- met/src/libcode/vx_python3_utils/python3_list.cc | 2 +- met/src/libcode/vx_python3_utils/python3_list.h | 2 +- met/src/libcode/vx_python3_utils/wchar_argv.cc | 2 +- met/src/libcode/vx_python3_utils/wchar_argv.h | 2 +- met/src/libcode/vx_regrid/vx_regrid.cc | 2 +- met/src/libcode/vx_regrid/vx_regrid.h | 2 +- met/src/libcode/vx_regrid/vx_regrid_budget.cc | 2 +- met/src/libcode/vx_render/ascii85_filter.cc | 2 +- met/src/libcode/vx_render/ascii85_filter.h | 2 +- met/src/libcode/vx_render/bit_filter.cc | 2 +- met/src/libcode/vx_render/bit_filter.h | 2 +- met/src/libcode/vx_render/flate_filter.cc | 2 +- met/src/libcode/vx_render/flate_filter.h | 2 +- met/src/libcode/vx_render/hex_filter.cc | 2 +- met/src/libcode/vx_render/hex_filter.h | 2 +- met/src/libcode/vx_render/ps_filter.cc | 2 +- met/src/libcode/vx_render/ps_filter.h | 2 +- met/src/libcode/vx_render/psout_filter.cc | 2 +- met/src/libcode/vx_render/psout_filter.h | 2 +- met/src/libcode/vx_render/render_pbm.cc | 2 +- met/src/libcode/vx_render/render_pcm.cc | 2 +- met/src/libcode/vx_render/render_pgm.cc | 2 +- met/src/libcode/vx_render/render_ppm.cc | 2 +- met/src/libcode/vx_render/renderinfo.cc | 2 +- met/src/libcode/vx_render/renderinfo.h | 2 +- met/src/libcode/vx_render/rle_filter.cc | 2 +- met/src/libcode/vx_render/rle_filter.h | 2 +- met/src/libcode/vx_render/uc_queue.cc | 2 +- met/src/libcode/vx_render/uc_queue.h | 2 +- met/src/libcode/vx_render/vx_render.h | 2 +- met/src/libcode/vx_series_data/series_data.cc | 2 +- met/src/libcode/vx_series_data/series_data.h | 2 +- met/src/libcode/vx_series_data/series_pdf.cc | 2 +- met/src/libcode/vx_series_data/series_pdf.h | 2 +- met/src/libcode/vx_shapedata/engine.cc | 2 +- met/src/libcode/vx_shapedata/engine.h | 2 +- met/src/libcode/vx_shapedata/interest.cc | 2 +- met/src/libcode/vx_shapedata/interest.h | 2 +- met/src/libcode/vx_shapedata/mode_columns.h | 2 +- met/src/libcode/vx_shapedata/mode_conf_info.cc | 2 +- met/src/libcode/vx_shapedata/mode_conf_info.h | 2 +- met/src/libcode/vx_shapedata/moments.cc | 2 +- met/src/libcode/vx_shapedata/moments.h | 2 +- met/src/libcode/vx_shapedata/node.cc | 2 +- met/src/libcode/vx_shapedata/node.h | 2 +- met/src/libcode/vx_shapedata/set.cc | 2 +- met/src/libcode/vx_shapedata/set.h | 2 +- met/src/libcode/vx_shapedata/shape.h | 2 +- met/src/libcode/vx_shapedata/shapedata.cc | 2 +- met/src/libcode/vx_shapedata/shapedata.h | 2 +- met/src/libcode/vx_shapedata/vx_shapedata.h | 2 +- met/src/libcode/vx_solar/astro_constants.h | 2 +- met/src/libcode/vx_solar/siderial.cc | 2 +- met/src/libcode/vx_solar/siderial.h | 2 +- met/src/libcode/vx_solar/solar.cc | 2 +- met/src/libcode/vx_solar/solar.h | 2 +- met/src/libcode/vx_stat_out/stat_columns.cc | 2 +- met/src/libcode/vx_stat_out/stat_columns.h | 2 +- met/src/libcode/vx_stat_out/stat_hdr_columns.cc | 2 +- met/src/libcode/vx_stat_out/stat_hdr_columns.h | 2 +- met/src/libcode/vx_stat_out/vx_stat_out.h | 2 +- met/src/libcode/vx_statistics/apply_mask.cc | 2 +- met/src/libcode/vx_statistics/apply_mask.h | 2 +- met/src/libcode/vx_statistics/compute_ci.cc | 2 +- met/src/libcode/vx_statistics/compute_ci.h | 2 +- met/src/libcode/vx_statistics/compute_stats.cc | 2 +- met/src/libcode/vx_statistics/compute_stats.h | 2 +- met/src/libcode/vx_statistics/contable.cc | 2 +- met/src/libcode/vx_statistics/contable.h | 2 +- met/src/libcode/vx_statistics/contable_nx2.cc | 2 +- met/src/libcode/vx_statistics/contable_stats.cc | 2 +- met/src/libcode/vx_statistics/ens_stats.cc | 2 +- met/src/libcode/vx_statistics/ens_stats.h | 2 +- met/src/libcode/vx_statistics/grid_closed_poly.cc | 2 +- met/src/libcode/vx_statistics/grid_closed_poly.h | 2 +- met/src/libcode/vx_statistics/met_stats.cc | 2 +- met/src/libcode/vx_statistics/met_stats.h | 2 +- met/src/libcode/vx_statistics/obs_error.cc | 2 +- met/src/libcode/vx_statistics/obs_error.h | 2 +- met/src/libcode/vx_statistics/pair_base.cc | 2 +- met/src/libcode/vx_statistics/pair_base.h | 2 +- met/src/libcode/vx_statistics/pair_data_ensemble.cc | 2 +- met/src/libcode/vx_statistics/pair_data_ensemble.h | 2 +- met/src/libcode/vx_statistics/pair_data_point.cc | 2 +- met/src/libcode/vx_statistics/pair_data_point.h | 2 +- met/src/libcode/vx_statistics/read_climo.cc | 2 +- met/src/libcode/vx_statistics/read_climo.h | 2 +- met/src/libcode/vx_statistics/vx_statistics.h | 2 +- met/src/libcode/vx_summary/summary_calc.cc | 2 +- met/src/libcode/vx_summary/summary_calc.h | 2 +- met/src/libcode/vx_summary/summary_calc_max.cc | 2 +- met/src/libcode/vx_summary/summary_calc_max.h | 2 +- met/src/libcode/vx_summary/summary_calc_mean.cc | 2 +- met/src/libcode/vx_summary/summary_calc_mean.h | 2 +- met/src/libcode/vx_summary/summary_calc_median.cc | 2 +- met/src/libcode/vx_summary/summary_calc_median.h | 2 +- met/src/libcode/vx_summary/summary_calc_min.cc | 2 +- met/src/libcode/vx_summary/summary_calc_min.h | 2 +- met/src/libcode/vx_summary/summary_calc_percentile.cc | 2 +- met/src/libcode/vx_summary/summary_calc_percentile.h | 2 +- met/src/libcode/vx_summary/summary_calc_range.cc | 2 +- met/src/libcode/vx_summary/summary_calc_range.h | 2 +- met/src/libcode/vx_summary/summary_calc_stdev.cc | 2 +- met/src/libcode/vx_summary/summary_calc_stdev.h | 2 +- met/src/libcode/vx_summary/summary_key.cc | 2 +- met/src/libcode/vx_summary/summary_key.h | 2 +- met/src/libcode/vx_summary/summary_obs.cc | 2 +- met/src/libcode/vx_summary/summary_obs.h | 2 +- met/src/libcode/vx_summary/time_summary_interval.cc | 2 +- met/src/libcode/vx_summary/time_summary_interval.h | 2 +- met/src/libcode/vx_summary/vx_summary.h | 2 +- met/src/libcode/vx_tc_util/atcf_line_base.cc | 2 +- met/src/libcode/vx_tc_util/atcf_line_base.h | 2 +- met/src/libcode/vx_tc_util/atcf_offsets.h | 2 +- met/src/libcode/vx_tc_util/atcf_prob_line.cc | 2 +- met/src/libcode/vx_tc_util/atcf_prob_line.h | 2 +- met/src/libcode/vx_tc_util/atcf_track_line.cc | 2 +- met/src/libcode/vx_tc_util/atcf_track_line.h | 2 +- met/src/libcode/vx_tc_util/gen_shape_info.cc | 2 +- met/src/libcode/vx_tc_util/gen_shape_info.h | 2 +- met/src/libcode/vx_tc_util/genesis_info.cc | 2 +- met/src/libcode/vx_tc_util/genesis_info.h | 2 +- met/src/libcode/vx_tc_util/pair_data_genesis.cc | 2 +- met/src/libcode/vx_tc_util/pair_data_genesis.h | 2 +- met/src/libcode/vx_tc_util/prob_gen_info.cc | 2 +- met/src/libcode/vx_tc_util/prob_gen_info.h | 2 +- met/src/libcode/vx_tc_util/prob_info_array.cc | 2 +- met/src/libcode/vx_tc_util/prob_info_array.h | 2 +- met/src/libcode/vx_tc_util/prob_info_base.cc | 2 +- met/src/libcode/vx_tc_util/prob_info_base.h | 2 +- met/src/libcode/vx_tc_util/prob_pair_info.cc | 2 +- met/src/libcode/vx_tc_util/prob_pair_info.h | 2 +- met/src/libcode/vx_tc_util/prob_rirw_info.cc | 2 +- met/src/libcode/vx_tc_util/prob_rirw_info.h | 2 +- met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc | 2 +- met/src/libcode/vx_tc_util/prob_rirw_pair_info.h | 2 +- met/src/libcode/vx_tc_util/tc_columns.cc | 2 +- met/src/libcode/vx_tc_util/tc_columns.h | 2 +- met/src/libcode/vx_tc_util/tc_hdr_columns.cc | 2 +- met/src/libcode/vx_tc_util/tc_hdr_columns.h | 2 +- met/src/libcode/vx_tc_util/tc_stat_line.cc | 2 +- met/src/libcode/vx_tc_util/tc_stat_line.h | 2 +- met/src/libcode/vx_tc_util/track_info.cc | 2 +- met/src/libcode/vx_tc_util/track_info.h | 2 +- met/src/libcode/vx_tc_util/track_pair_info.cc | 2 +- met/src/libcode/vx_tc_util/track_pair_info.h | 2 +- met/src/libcode/vx_tc_util/track_point.cc | 2 +- met/src/libcode/vx_tc_util/track_point.h | 2 +- met/src/libcode/vx_tc_util/vx_tc_nc_util.cc | 2 +- met/src/libcode/vx_tc_util/vx_tc_nc_util.h | 2 +- met/src/libcode/vx_tc_util/vx_tc_util.h | 2 +- met/src/libcode/vx_time_series/compute_swinging_door.cc | 2 +- met/src/libcode/vx_time_series/compute_swinging_door.h | 2 +- met/src/libcode/vx_time_series/time_series_util.cc | 2 +- met/src/libcode/vx_time_series/time_series_util.h | 2 +- met/src/libcode/vx_time_series/vx_time_series.h | 2 +- met/src/tools/core/ensemble_stat/ensemble_stat.cc | 2 +- met/src/tools/core/ensemble_stat/ensemble_stat.h | 2 +- met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc | 2 +- met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h | 2 +- met/src/tools/core/grid_stat/grid_stat.cc | 2 +- met/src/tools/core/grid_stat/grid_stat.h | 2 +- met/src/tools/core/grid_stat/grid_stat_conf_info.cc | 2 +- met/src/tools/core/grid_stat/grid_stat_conf_info.h | 2 +- met/src/tools/core/mode/cluster_page.cc | 2 +- met/src/tools/core/mode/fcst_enlarge_page.cc | 2 +- met/src/tools/core/mode/mode.cc | 2 +- met/src/tools/core/mode/mode_exec.cc | 2 +- met/src/tools/core/mode/mode_exec.h | 2 +- met/src/tools/core/mode/mode_ps_file.cc | 2 +- met/src/tools/core/mode/mode_ps_file.h | 2 +- met/src/tools/core/mode/mode_ps_table_defs.h | 2 +- met/src/tools/core/mode/obs_enlarge_page.cc | 2 +- met/src/tools/core/mode/overlap_page.cc | 2 +- met/src/tools/core/mode/page_1.cc | 2 +- met/src/tools/core/mode/plot_engine.cc | 2 +- met/src/tools/core/mode_analysis/config_to_att.cc | 2 +- met/src/tools/core/mode_analysis/config_to_att.h | 2 +- met/src/tools/core/mode_analysis/mode_analysis.cc | 2 +- met/src/tools/core/pcp_combine/pcp_combine.cc | 2 +- met/src/tools/core/point_stat/point_stat.cc | 2 +- met/src/tools/core/point_stat/point_stat.h | 2 +- met/src/tools/core/point_stat/point_stat_conf_info.cc | 2 +- met/src/tools/core/point_stat/point_stat_conf_info.h | 2 +- met/src/tools/core/series_analysis/series_analysis.cc | 2 +- met/src/tools/core/series_analysis/series_analysis.h | 2 +- met/src/tools/core/series_analysis/series_analysis_conf_info.cc | 2 +- met/src/tools/core/series_analysis/series_analysis_conf_info.h | 2 +- met/src/tools/core/stat_analysis/aggr_stat_line.cc | 2 +- met/src/tools/core/stat_analysis/aggr_stat_line.h | 2 +- met/src/tools/core/stat_analysis/parse_stat_line.cc | 2 +- met/src/tools/core/stat_analysis/parse_stat_line.h | 2 +- met/src/tools/core/stat_analysis/skill_score_index_job.cc | 2 +- met/src/tools/core/stat_analysis/skill_score_index_job.h | 2 +- met/src/tools/core/stat_analysis/stat_analysis.cc | 2 +- met/src/tools/core/stat_analysis/stat_analysis.h | 2 +- met/src/tools/core/stat_analysis/stat_analysis_job.cc | 2 +- met/src/tools/core/stat_analysis/stat_analysis_job.h | 2 +- met/src/tools/core/wavelet_stat/wavelet_stat.cc | 2 +- met/src/tools/core/wavelet_stat/wavelet_stat.h | 2 +- met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.cc | 2 +- met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.h | 2 +- met/src/tools/dev_utils/chk4copyright.cc | 2 +- met/src/tools/dev_utils/gen_climo_bin.cc | 2 +- met/src/tools/dev_utils/gribtab.dat_to_flat.cc | 2 +- met/src/tools/dev_utils/insitu_nc_file.cc | 2 +- met/src/tools/dev_utils/insitu_nc_file.h | 2 +- met/src/tools/dev_utils/insitu_nc_to_ascii.cc | 2 +- met/src/tools/dev_utils/met_nc_file.cc | 2 +- met/src/tools/dev_utils/met_nc_file.h | 2 +- met/src/tools/dev_utils/nceptab_to_flat.cc | 2 +- met/src/tools/dev_utils/pbtime.cc | 2 +- met/src/tools/dev_utils/reformat_county_data.cc | 2 +- met/src/tools/dev_utils/reformat_map_data.cc | 2 +- met/src/tools/dev_utils/shapefiles/make_mapfiles.cc | 2 +- met/src/tools/dev_utils/swinging_door.cc | 2 +- met/src/tools/other/ascii2nc/aeronet_handler.cc | 2 +- met/src/tools/other/ascii2nc/aeronet_handler.h | 2 +- met/src/tools/other/ascii2nc/ascii2nc.cc | 2 +- met/src/tools/other/ascii2nc/ascii2nc_conf_info.cc | 2 +- met/src/tools/other/ascii2nc/ascii2nc_conf_info.h | 2 +- met/src/tools/other/ascii2nc/file_handler.cc | 2 +- met/src/tools/other/ascii2nc/file_handler.h | 2 +- met/src/tools/other/ascii2nc/little_r_handler.cc | 2 +- met/src/tools/other/ascii2nc/little_r_handler.h | 2 +- met/src/tools/other/ascii2nc/met_handler.cc | 2 +- met/src/tools/other/ascii2nc/met_handler.h | 2 +- met/src/tools/other/ascii2nc/python_handler.cc | 2 +- met/src/tools/other/ascii2nc/python_handler.h | 2 +- met/src/tools/other/ascii2nc/surfrad_handler.cc | 2 +- met/src/tools/other/ascii2nc/surfrad_handler.h | 2 +- met/src/tools/other/ascii2nc/wwsis_handler.cc | 2 +- met/src/tools/other/ascii2nc/wwsis_handler.h | 2 +- met/src/tools/other/gen_ens_prod/gen_ens_prod.cc | 2 +- met/src/tools/other/gen_ens_prod/gen_ens_prod.h | 2 +- met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc | 2 +- met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h | 2 +- met/src/tools/other/gen_vx_mask/gen_vx_mask.cc | 2 +- met/src/tools/other/gen_vx_mask/gen_vx_mask.h | 2 +- met/src/tools/other/gis_utils/gis_dump_dbf.cc | 2 +- met/src/tools/other/gis_utils/gis_dump_shp.cc | 2 +- met/src/tools/other/gis_utils/gis_dump_shx.cc | 2 +- met/src/tools/other/grid_diag/grid_diag.cc | 2 +- met/src/tools/other/grid_diag/grid_diag.h | 2 +- met/src/tools/other/grid_diag/grid_diag_conf_info.cc | 2 +- met/src/tools/other/grid_diag/grid_diag_conf_info.h | 2 +- met/src/tools/other/gsi_tools/conv_offsets.h | 2 +- met/src/tools/other/gsi_tools/conv_record.cc | 2 +- met/src/tools/other/gsi_tools/conv_record.h | 2 +- met/src/tools/other/gsi_tools/ftto.h | 2 +- met/src/tools/other/gsi_tools/gsi_record.cc | 2 +- met/src/tools/other/gsi_tools/gsi_record.h | 2 +- met/src/tools/other/gsi_tools/gsi_util.cc | 2 +- met/src/tools/other/gsi_tools/gsi_util.h | 2 +- met/src/tools/other/gsi_tools/gsid2mpr.cc | 2 +- met/src/tools/other/gsi_tools/gsid2mpr.h | 2 +- met/src/tools/other/gsi_tools/gsidens2orank.cc | 2 +- met/src/tools/other/gsi_tools/gsidens2orank.h | 2 +- met/src/tools/other/gsi_tools/rad_config.cc | 2 +- met/src/tools/other/gsi_tools/rad_config.h | 2 +- met/src/tools/other/gsi_tools/rad_offsets.h | 2 +- met/src/tools/other/gsi_tools/rad_record.cc | 2 +- met/src/tools/other/gsi_tools/rad_record.h | 2 +- met/src/tools/other/ioda2nc/ioda2nc.cc | 2 +- met/src/tools/other/ioda2nc/ioda2nc_conf_info.cc | 2 +- met/src/tools/other/ioda2nc/ioda2nc_conf_info.h | 2 +- met/src/tools/other/lidar2nc/calipso_5km.cc | 2 +- met/src/tools/other/lidar2nc/calipso_5km.h | 2 +- met/src/tools/other/lidar2nc/hdf_utils.cc | 2 +- met/src/tools/other/lidar2nc/hdf_utils.h | 2 +- met/src/tools/other/lidar2nc/lidar2nc.cc | 2 +- met/src/tools/other/madis2nc/madis2nc.cc | 2 +- met/src/tools/other/madis2nc/madis2nc.h | 2 +- met/src/tools/other/madis2nc/madis2nc_conf_info.cc | 2 +- met/src/tools/other/madis2nc/madis2nc_conf_info.h | 2 +- met/src/tools/other/mode_graphics/cgraph.h | 2 +- met/src/tools/other/mode_graphics/cgraph_font.cc | 2 +- met/src/tools/other/mode_graphics/cgraph_font.h | 2 +- met/src/tools/other/mode_graphics/cgraph_main.cc | 2 +- met/src/tools/other/mode_graphics/cgraph_main.h | 2 +- met/src/tools/other/mode_graphics/color_stack.cc | 2 +- met/src/tools/other/mode_graphics/color_stack.h | 2 +- met/src/tools/other/mode_graphics/gs_ps_map.h | 2 +- met/src/tools/other/mode_graphics/mode_nc_output_file.cc | 2 +- met/src/tools/other/mode_graphics/mode_nc_output_file.h | 2 +- met/src/tools/other/mode_graphics/plot_mode_field.cc | 2 +- met/src/tools/other/mode_graphics/sincosd.h | 2 +- met/src/tools/other/mode_time_domain/2d_att.cc | 2 +- met/src/tools/other/mode_time_domain/2d_att.h | 2 +- met/src/tools/other/mode_time_domain/2d_att_array.cc | 2 +- met/src/tools/other/mode_time_domain/2d_att_array.h | 2 +- met/src/tools/other/mode_time_domain/2d_columns.h | 2 +- met/src/tools/other/mode_time_domain/2d_moments.cc | 2 +- met/src/tools/other/mode_time_domain/2d_moments.h | 2 +- met/src/tools/other/mode_time_domain/3d_att.cc | 2 +- met/src/tools/other/mode_time_domain/3d_att.h | 2 +- met/src/tools/other/mode_time_domain/3d_att_pair_array.cc | 2 +- met/src/tools/other/mode_time_domain/3d_att_pair_array.h | 2 +- met/src/tools/other/mode_time_domain/3d_att_single_array.cc | 2 +- met/src/tools/other/mode_time_domain/3d_att_single_array.h | 2 +- met/src/tools/other/mode_time_domain/3d_conv.cc | 2 +- met/src/tools/other/mode_time_domain/3d_moments.cc | 2 +- met/src/tools/other/mode_time_domain/3d_moments.h | 2 +- met/src/tools/other/mode_time_domain/3d_pair_columns.h | 2 +- met/src/tools/other/mode_time_domain/3d_single_columns.h | 2 +- met/src/tools/other/mode_time_domain/3d_txt_header.h | 2 +- met/src/tools/other/mode_time_domain/fo_graph.cc | 2 +- met/src/tools/other/mode_time_domain/fo_graph.h | 2 +- met/src/tools/other/mode_time_domain/fo_node.cc | 2 +- met/src/tools/other/mode_time_domain/fo_node.h | 2 +- met/src/tools/other/mode_time_domain/fo_node_array.cc | 2 +- met/src/tools/other/mode_time_domain/fo_node_array.h | 2 +- met/src/tools/other/mode_time_domain/interest_calc.cc | 2 +- met/src/tools/other/mode_time_domain/interest_calc.h | 2 +- met/src/tools/other/mode_time_domain/mm_engine.cc | 2 +- met/src/tools/other/mode_time_domain/mm_engine.h | 2 +- met/src/tools/other/mode_time_domain/mtd.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_config_info.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_config_info.h | 2 +- met/src/tools/other/mode_time_domain/mtd_file.h | 2 +- met/src/tools/other/mode_time_domain/mtd_file_base.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_file_base.h | 2 +- met/src/tools/other/mode_time_domain/mtd_file_float.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_file_float.h | 2 +- met/src/tools/other/mode_time_domain/mtd_file_int.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_file_int.h | 2 +- met/src/tools/other/mode_time_domain/mtd_nc_defs.h | 2 +- met/src/tools/other/mode_time_domain/mtd_nc_output.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_nc_output.h | 2 +- met/src/tools/other/mode_time_domain/mtd_partition.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_partition.h | 2 +- met/src/tools/other/mode_time_domain/mtd_read_data.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_read_data.h | 2 +- met/src/tools/other/mode_time_domain/mtd_txt_output.cc | 2 +- met/src/tools/other/mode_time_domain/mtd_txt_output.h | 2 +- met/src/tools/other/mode_time_domain/nc_grid.cc | 2 +- met/src/tools/other/mode_time_domain/nc_grid.h | 2 +- met/src/tools/other/mode_time_domain/nc_utils_local.cc | 2 +- met/src/tools/other/mode_time_domain/nc_utils_local.h | 2 +- met/src/tools/other/modis_regrid/cloudsat_swath_file.cc | 2 +- met/src/tools/other/modis_regrid/cloudsat_swath_file.h | 2 +- met/src/tools/other/modis_regrid/data_averager.cc | 2 +- met/src/tools/other/modis_regrid/data_averager.h | 2 +- met/src/tools/other/modis_regrid/data_plane_to_netcdf.cc | 2 +- met/src/tools/other/modis_regrid/data_plane_to_netcdf.h | 2 +- met/src/tools/other/modis_regrid/modis_file.cc | 2 +- met/src/tools/other/modis_regrid/modis_file.h | 2 +- met/src/tools/other/modis_regrid/modis_regrid.cc | 2 +- met/src/tools/other/modis_regrid/sat_utils.cc | 2 +- met/src/tools/other/modis_regrid/sat_utils.h | 2 +- met/src/tools/other/pb2nc/closepb.f | 2 +- met/src/tools/other/pb2nc/dumppb.f | 2 +- met/src/tools/other/pb2nc/numpbmsg.f | 2 +- met/src/tools/other/pb2nc/openpb.f | 2 +- met/src/tools/other/pb2nc/pb2nc.cc | 2 +- met/src/tools/other/pb2nc/pb2nc_conf_info.cc | 2 +- met/src/tools/other/pb2nc/pb2nc_conf_info.h | 2 +- met/src/tools/other/pb2nc/readpb.f | 2 +- met/src/tools/other/plot_data_plane/plot_data_plane.cc | 2 +- met/src/tools/other/plot_point_obs/plot_point_obs.cc | 2 +- met/src/tools/other/plot_point_obs/plot_point_obs.h | 2 +- met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.cc | 2 +- met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.h | 2 +- met/src/tools/other/point2grid/point2grid.cc | 2 +- met/src/tools/other/point2grid/point2grid_conf_info.cc | 2 +- met/src/tools/other/point2grid/point2grid_conf_info.h | 2 +- met/src/tools/other/regrid_data_plane/regrid_data_plane.cc | 2 +- met/src/tools/other/shift_data_plane/shift_data_plane.cc | 2 +- met/src/tools/other/wwmca_tool/af_cp_file.cc | 2 +- met/src/tools/other/wwmca_tool/af_cp_file.h | 2 +- met/src/tools/other/wwmca_tool/af_file.cc | 2 +- met/src/tools/other/wwmca_tool/af_file.h | 2 +- met/src/tools/other/wwmca_tool/af_pt_file.cc | 2 +- met/src/tools/other/wwmca_tool/af_pt_file.h | 2 +- met/src/tools/other/wwmca_tool/ave_interp.cc | 2 +- met/src/tools/other/wwmca_tool/ave_interp.h | 2 +- met/src/tools/other/wwmca_tool/interp_base.cc | 2 +- met/src/tools/other/wwmca_tool/interp_base.h | 2 +- met/src/tools/other/wwmca_tool/max_interp.cc | 2 +- met/src/tools/other/wwmca_tool/max_interp.h | 2 +- met/src/tools/other/wwmca_tool/min_interp.cc | 2 +- met/src/tools/other/wwmca_tool/min_interp.h | 2 +- met/src/tools/other/wwmca_tool/nc_output.cc | 2 +- met/src/tools/other/wwmca_tool/nearest_interp.cc | 2 +- met/src/tools/other/wwmca_tool/nearest_interp.h | 2 +- met/src/tools/other/wwmca_tool/wwmca_plot.cc | 2 +- met/src/tools/other/wwmca_tool/wwmca_ref.cc | 2 +- met/src/tools/other/wwmca_tool/wwmca_ref.h | 2 +- met/src/tools/other/wwmca_tool/wwmca_regrid.cc | 2 +- met/src/tools/other/wwmca_tool/wwmca_utils.cc | 2 +- met/src/tools/other/wwmca_tool/wwmca_utils.h | 2 +- met/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc | 2 +- met/src/tools/tc_utils/rmw_analysis/rmw_analysis.h | 2 +- met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.cc | 2 +- met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.h | 2 +- met/src/tools/tc_utils/tc_dland/tc_dland.cc | 2 +- met/src/tools/tc_utils/tc_dland/tc_poly.cc | 2 +- met/src/tools/tc_utils/tc_dland/tc_poly.h | 2 +- met/src/tools/tc_utils/tc_gen/tc_gen.cc | 2 +- met/src/tools/tc_utils/tc_gen/tc_gen.h | 2 +- met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc | 2 +- met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h | 2 +- met/src/tools/tc_utils/tc_pairs/tc_pairs.cc | 2 +- met/src/tools/tc_utils/tc_pairs/tc_pairs.h | 2 +- met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.cc | 2 +- met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.h | 2 +- met/src/tools/tc_utils/tc_rmw/tc_rmw.cc | 2 +- met/src/tools/tc_utils/tc_rmw/tc_rmw.h | 2 +- met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.cc | 2 +- met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.h | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat.cc | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat.h | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.cc | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.h | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat_files.cc | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat_files.h | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat_job.cc | 2 +- met/src/tools/tc_utils/tc_stat/tc_stat_job.h | 2 +- 888 files changed, 888 insertions(+), 888 deletions(-) diff --git a/met/README b/met/README index 11a9bce6b7..d05da60c0e 100644 --- a/met/README +++ b/met/README @@ -2,7 +2,7 @@ Model Evaluation Tools (MET) TERMS OF USE - IMPORTANT! ================================================================================ -Copyright 2021, UCAR/NCAR, NOAA, and CSU/CIRA +Copyright 2022, UCAR/NCAR, NOAA, CSU/CIRA, and CU/CIRES Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/met/data/copyright_notice.txt b/met/data/copyright_notice.txt index 59f11fd7d9..ee9ed72744 100644 --- a/met/data/copyright_notice.txt +++ b/met/data/copyright_notice.txt @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_config.cc b/met/internal_tests/basic/vx_config/test_config.cc index bc98cf99c9..f47dd2c02e 100644 --- a/met/internal_tests/basic/vx_config/test_config.cc +++ b/met/internal_tests/basic/vx_config/test_config.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_lookup.cc b/met/internal_tests/basic/vx_config/test_lookup.cc index acfdd6ce47..87ef8284fd 100644 --- a/met/internal_tests/basic/vx_config/test_lookup.cc +++ b/met/internal_tests/basic/vx_config/test_lookup.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_lookup2.cc b/met/internal_tests/basic/vx_config/test_lookup2.cc index f0550e51cb..5552c5f0e1 100644 --- a/met/internal_tests/basic/vx_config/test_lookup2.cc +++ b/met/internal_tests/basic/vx_config/test_lookup2.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_lookup3.cc b/met/internal_tests/basic/vx_config/test_lookup3.cc index 00b5092ef0..b7075104e2 100644 --- a/met/internal_tests/basic/vx_config/test_lookup3.cc +++ b/met/internal_tests/basic/vx_config/test_lookup3.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_met_478.cc b/met/internal_tests/basic/vx_config/test_met_478.cc index d8eb495d1e..0ac1c8bb3e 100644 --- a/met/internal_tests/basic/vx_config/test_met_478.cc +++ b/met/internal_tests/basic/vx_config/test_met_478.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_string.cc b/met/internal_tests/basic/vx_config/test_string.cc index 1ff22b98a4..1fb2d080fa 100644 --- a/met/internal_tests/basic/vx_config/test_string.cc +++ b/met/internal_tests/basic/vx_config/test_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_string_then_config.cc b/met/internal_tests/basic/vx_config/test_string_then_config.cc index 1749c65838..b869fb42ef 100644 --- a/met/internal_tests/basic/vx_config/test_string_then_config.cc +++ b/met/internal_tests/basic/vx_config/test_string_then_config.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_thresh.cc b/met/internal_tests/basic/vx_config/test_thresh.cc index 1a8d346d4f..9931349259 100644 --- a/met/internal_tests/basic/vx_config/test_thresh.cc +++ b/met/internal_tests/basic/vx_config/test_thresh.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_config/test_user_func.cc b/met/internal_tests/basic/vx_config/test_user_func.cc index f32a198878..a9e1d97c89 100644 --- a/met/internal_tests/basic/vx_config/test_user_func.cc +++ b/met/internal_tests/basic/vx_config/test_user_func.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_log/test_logger.cc b/met/internal_tests/basic/vx_log/test_logger.cc index 723cb38df3..242d8d4149 100644 --- a/met/internal_tests/basic/vx_log/test_logger.cc +++ b/met/internal_tests/basic/vx_log/test_logger.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_log/test_reg_exp.cc b/met/internal_tests/basic/vx_log/test_reg_exp.cc index 81fc9b246e..6d4fa123d5 100644 --- a/met/internal_tests/basic/vx_log/test_reg_exp.cc +++ b/met/internal_tests/basic/vx_log/test_reg_exp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_util/test_add_rows.cc b/met/internal_tests/basic/vx_util/test_add_rows.cc index bff68be679..4865fc2936 100644 --- a/met/internal_tests/basic/vx_util/test_add_rows.cc +++ b/met/internal_tests/basic/vx_util/test_add_rows.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_util/test_ascii_header.cc b/met/internal_tests/basic/vx_util/test_ascii_header.cc index f71643b0b6..03aa3dbbfb 100644 --- a/met/internal_tests/basic/vx_util/test_ascii_header.cc +++ b/met/internal_tests/basic/vx_util/test_ascii_header.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_util/test_command_line.cc b/met/internal_tests/basic/vx_util/test_command_line.cc index ce5fcfc137..4f278a9f99 100644 --- a/met/internal_tests/basic/vx_util/test_command_line.cc +++ b/met/internal_tests/basic/vx_util/test_command_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_util/test_data_plane.cc b/met/internal_tests/basic/vx_util/test_data_plane.cc index dea6b89c32..d49dd501d3 100644 --- a/met/internal_tests/basic/vx_util/test_data_plane.cc +++ b/met/internal_tests/basic/vx_util/test_data_plane.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/basic/vx_util/test_table_float.cc b/met/internal_tests/basic/vx_util/test_table_float.cc index 2afeceeab2..f372c52b3e 100644 --- a/met/internal_tests/basic/vx_util/test_table_float.cc +++ b/met/internal_tests/basic/vx_util/test_table_float.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d/dump_default_table.cc b/met/internal_tests/libcode/vx_data2d/dump_default_table.cc index 0bbac5baa1..5ed3af7229 100644 --- a/met/internal_tests/libcode/vx_data2d/dump_default_table.cc +++ b/met/internal_tests/libcode/vx_data2d/dump_default_table.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d/test_table_read.cc b/met/internal_tests/libcode/vx_data2d/test_table_read.cc index 0d726501cd..2f6c5c6c9c 100644 --- a/met/internal_tests/libcode/vx_data2d/test_table_read.cc +++ b/met/internal_tests/libcode/vx_data2d/test_table_read.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d_factory/test_factory.cc b/met/internal_tests/libcode/vx_data2d_factory/test_factory.cc index 0701e448b8..3d92477366 100644 --- a/met/internal_tests/libcode/vx_data2d_factory/test_factory.cc +++ b/met/internal_tests/libcode/vx_data2d_factory/test_factory.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d_factory/test_is_grib.cc b/met/internal_tests/libcode/vx_data2d_factory/test_is_grib.cc index 7100114d20..c0b09a7cef 100644 --- a/met/internal_tests/libcode/vx_data2d_factory/test_is_grib.cc +++ b/met/internal_tests/libcode/vx_data2d_factory/test_is_grib.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d_grib/test_read_grib1.cc b/met/internal_tests/libcode/vx_data2d_grib/test_read_grib1.cc index 0595ef9ff6..a63b72649c 100644 --- a/met/internal_tests/libcode/vx_data2d_grib/test_read_grib1.cc +++ b/met/internal_tests/libcode/vx_data2d_grib/test_read_grib1.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d_nc_met/test_read_nc_met.cc b/met/internal_tests/libcode/vx_data2d_nc_met/test_read_nc_met.cc index b4f7b00cf7..4aa27c431e 100644 --- a/met/internal_tests/libcode/vx_data2d_nc_met/test_read_nc_met.cc +++ b/met/internal_tests/libcode/vx_data2d_nc_met/test_read_nc_met.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_data2d_nccf/test_read_nccf.cc b/met/internal_tests/libcode/vx_data2d_nccf/test_read_nccf.cc index 60dea1f633..53504d3683 100644 --- a/met/internal_tests/libcode/vx_data2d_nccf/test_read_nccf.cc +++ b/met/internal_tests/libcode/vx_data2d_nccf/test_read_nccf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_geodesy/test_spheroid.cc b/met/internal_tests/libcode/vx_geodesy/test_spheroid.cc index dd6e8392e7..5068fa2954 100644 --- a/met/internal_tests/libcode/vx_geodesy/test_spheroid.cc +++ b/met/internal_tests/libcode/vx_geodesy/test_spheroid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_grid/test_grid_area.cc b/met/internal_tests/libcode/vx_grid/test_grid_area.cc index 28e95dda08..77adb84839 100644 --- a/met/internal_tests/libcode/vx_grid/test_grid_area.cc +++ b/met/internal_tests/libcode/vx_grid/test_grid_area.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_nc_util/test_pressure_levels.cc b/met/internal_tests/libcode/vx_nc_util/test_pressure_levels.cc index ed1e369549..7e38a3e30d 100644 --- a/met/internal_tests/libcode/vx_nc_util/test_pressure_levels.cc +++ b/met/internal_tests/libcode/vx_nc_util/test_pressure_levels.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_physics/test_thermo.cc b/met/internal_tests/libcode/vx_physics/test_thermo.cc index 49d1ad5622..7f13c662a9 100644 --- a/met/internal_tests/libcode/vx_physics/test_thermo.cc +++ b/met/internal_tests/libcode/vx_physics/test_thermo.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_plot_util/test_map_region.cc b/met/internal_tests/libcode/vx_plot_util/test_map_region.cc index 4bad8a606f..b8079e5619 100644 --- a/met/internal_tests/libcode/vx_plot_util/test_map_region.cc +++ b/met/internal_tests/libcode/vx_plot_util/test_map_region.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_ps/test_ps.cc b/met/internal_tests/libcode/vx_ps/test_ps.cc index a5db88dc92..3901959076 100644 --- a/met/internal_tests/libcode/vx_ps/test_ps.cc +++ b/met/internal_tests/libcode/vx_ps/test_ps.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_series_data/test_series_data.cc b/met/internal_tests/libcode/vx_series_data/test_series_data.cc index 69b0ec000a..d9cd9f0cb3 100644 --- a/met/internal_tests/libcode/vx_series_data/test_series_data.cc +++ b/met/internal_tests/libcode/vx_series_data/test_series_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_solar/test_ra_dec.cc b/met/internal_tests/libcode/vx_solar/test_ra_dec.cc index 1318e77bf2..070c057354 100644 --- a/met/internal_tests/libcode/vx_solar/test_ra_dec.cc +++ b/met/internal_tests/libcode/vx_solar/test_ra_dec.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_tc_util/test_read.cc b/met/internal_tests/libcode/vx_tc_util/test_read.cc index bcd29bbf3c..320291bd3b 100644 --- a/met/internal_tests/libcode/vx_tc_util/test_read.cc +++ b/met/internal_tests/libcode/vx_tc_util/test_read.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc b/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc index eea9a30e2d..153574a362 100644 --- a/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc +++ b/met/internal_tests/libcode/vx_tc_util/test_read_prob.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/libcode/vx_tc_util/test_read_rmw.cc b/met/internal_tests/libcode/vx_tc_util/test_read_rmw.cc index cffcd916bb..164db9bb31 100644 --- a/met/internal_tests/libcode/vx_tc_util/test_read_rmw.cc +++ b/met/internal_tests/libcode/vx_tc_util/test_read_rmw.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/internal_tests/tools/other/mode_time_domain/test_velocity.cc b/met/internal_tests/tools/other/mode_time_domain/test_velocity.cc index 802db6a97a..0096c435f3 100644 --- a/met/internal_tests/tools/other/mode_time_domain/test_velocity.cc +++ b/met/internal_tests/tools/other/mode_time_domain/test_velocity.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/code.cc b/met/src/basic/enum_to_string/code.cc index e72238eecf..769dd26cbc 100644 --- a/met/src/basic/enum_to_string/code.cc +++ b/met/src/basic/enum_to_string/code.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/code.h b/met/src/basic/enum_to_string/code.h index 244841bf13..7b03cada5f 100644 --- a/met/src/basic/enum_to_string/code.h +++ b/met/src/basic/enum_to_string/code.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/enum.tab.h b/met/src/basic/enum_to_string/enum.tab.h index 9c325b693b..6243ac55d0 100644 --- a/met/src/basic/enum_to_string/enum.tab.h +++ b/met/src/basic/enum_to_string/enum.tab.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/enum_to_string.cc b/met/src/basic/enum_to_string/enum_to_string.cc index d80452387a..8cd874453c 100644 --- a/met/src/basic/enum_to_string/enum_to_string.cc +++ b/met/src/basic/enum_to_string/enum_to_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/enum_to_string.h b/met/src/basic/enum_to_string/enum_to_string.h index 0d2baf1c68..c46eee8d59 100644 --- a/met/src/basic/enum_to_string/enum_to_string.h +++ b/met/src/basic/enum_to_string/enum_to_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/info.cc b/met/src/basic/enum_to_string/info.cc index 52c5ab8471..7f1faa3337 100644 --- a/met/src/basic/enum_to_string/info.cc +++ b/met/src/basic/enum_to_string/info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/info.h b/met/src/basic/enum_to_string/info.h index d05e27d635..03a49f6b08 100644 --- a/met/src/basic/enum_to_string/info.h +++ b/met/src/basic/enum_to_string/info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/scope.cc b/met/src/basic/enum_to_string/scope.cc index 86d094d3b0..fa6ecacbd0 100644 --- a/met/src/basic/enum_to_string/scope.cc +++ b/met/src/basic/enum_to_string/scope.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/enum_to_string/scope.h b/met/src/basic/enum_to_string/scope.h index 8ef6312b73..dcd6b46dcc 100644 --- a/met/src/basic/enum_to_string/scope.h +++ b/met/src/basic/enum_to_string/scope.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/date_to_mjd.cc b/met/src/basic/vx_cal/date_to_mjd.cc index faaa780f59..a074ae848d 100644 --- a/met/src/basic/vx_cal/date_to_mjd.cc +++ b/met/src/basic/vx_cal/date_to_mjd.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/day_dif.cc b/met/src/basic/vx_cal/day_dif.cc index 91bba5a773..aceb945931 100644 --- a/met/src/basic/vx_cal/day_dif.cc +++ b/met/src/basic/vx_cal/day_dif.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/day_of_week.cc b/met/src/basic/vx_cal/day_of_week.cc index fc4939b7f8..dcd8a5546e 100644 --- a/met/src/basic/vx_cal/day_of_week.cc +++ b/met/src/basic/vx_cal/day_of_week.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/doyhms_to_unix.cc b/met/src/basic/vx_cal/doyhms_to_unix.cc index e4183ada5b..8c03137841 100644 --- a/met/src/basic/vx_cal/doyhms_to_unix.cc +++ b/met/src/basic/vx_cal/doyhms_to_unix.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/is_dst.cc b/met/src/basic/vx_cal/is_dst.cc index 94fb1be5a4..93e01de398 100644 --- a/met/src/basic/vx_cal/is_dst.cc +++ b/met/src/basic/vx_cal/is_dst.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/is_leap_year.cc b/met/src/basic/vx_cal/is_leap_year.cc index 53e642b8e7..42cc100a76 100644 --- a/met/src/basic/vx_cal/is_leap_year.cc +++ b/met/src/basic/vx_cal/is_leap_year.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/mdyhms_to_unix.cc b/met/src/basic/vx_cal/mdyhms_to_unix.cc index ea09fa197c..5639ff3dad 100644 --- a/met/src/basic/vx_cal/mdyhms_to_unix.cc +++ b/met/src/basic/vx_cal/mdyhms_to_unix.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/mjd_to_date.cc b/met/src/basic/vx_cal/mjd_to_date.cc index df7023f85a..5152d14959 100644 --- a/met/src/basic/vx_cal/mjd_to_date.cc +++ b/met/src/basic/vx_cal/mjd_to_date.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/time_array.cc b/met/src/basic/vx_cal/time_array.cc index 2dab0d0d9c..70bfc0a898 100644 --- a/met/src/basic/vx_cal/time_array.cc +++ b/met/src/basic/vx_cal/time_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/time_array.h b/met/src/basic/vx_cal/time_array.h index 0c01c3cb34..4e38832454 100644 --- a/met/src/basic/vx_cal/time_array.h +++ b/met/src/basic/vx_cal/time_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/time_strings.cc b/met/src/basic/vx_cal/time_strings.cc index 51aec9d8a2..a97a76defd 100644 --- a/met/src/basic/vx_cal/time_strings.cc +++ b/met/src/basic/vx_cal/time_strings.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/unix_string.cc b/met/src/basic/vx_cal/unix_string.cc index 2897d5a0cd..d76ecbffcc 100644 --- a/met/src/basic/vx_cal/unix_string.cc +++ b/met/src/basic/vx_cal/unix_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/unix_to_mdyhms.cc b/met/src/basic/vx_cal/unix_to_mdyhms.cc index 5f5bf1dbfc..e7d2a11330 100644 --- a/met/src/basic/vx_cal/unix_to_mdyhms.cc +++ b/met/src/basic/vx_cal/unix_to_mdyhms.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_cal/vx_cal.h b/met/src/basic/vx_cal/vx_cal.h index 4648f2ed77..74885b50a1 100644 --- a/met/src/basic/vx_cal/vx_cal.h +++ b/met/src/basic/vx_cal/vx_cal.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/builtin.cc b/met/src/basic/vx_config/builtin.cc index 4396064a80..16da02d761 100644 --- a/met/src/basic/vx_config/builtin.cc +++ b/met/src/basic/vx_config/builtin.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/builtin.h b/met/src/basic/vx_config/builtin.h index d2691a2e5f..b010732b85 100644 --- a/met/src/basic/vx_config/builtin.h +++ b/met/src/basic/vx_config/builtin.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/calculator.cc b/met/src/basic/vx_config/calculator.cc index 0ce9d6cb6b..4d155b8d7c 100644 --- a/met/src/basic/vx_config/calculator.cc +++ b/met/src/basic/vx_config/calculator.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/calculator.h b/met/src/basic/vx_config/calculator.h index 32c2d5f3c7..fd8fcbd28f 100644 --- a/met/src/basic/vx_config/calculator.h +++ b/met/src/basic/vx_config/calculator.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index 156c55881b..4649c555a4 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_file.cc b/met/src/basic/vx_config/config_file.cc index 1e229d5aa9..ba0a80d7ad 100644 --- a/met/src/basic/vx_config/config_file.cc +++ b/met/src/basic/vx_config/config_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_file.h b/met/src/basic/vx_config/config_file.h index b3e90d80ff..e5a2953692 100644 --- a/met/src/basic/vx_config/config_file.h +++ b/met/src/basic/vx_config/config_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_funcs.cc b/met/src/basic/vx_config/config_funcs.cc index adaf585f34..50536d5cd3 100644 --- a/met/src/basic/vx_config/config_funcs.cc +++ b/met/src/basic/vx_config/config_funcs.cc @@ -3,7 +3,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_funcs.h b/met/src/basic/vx_config/config_funcs.h index 6f1db7c0c1..59a0810e50 100644 --- a/met/src/basic/vx_config/config_funcs.h +++ b/met/src/basic/vx_config/config_funcs.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_gaussian.h b/met/src/basic/vx_config/config_gaussian.h index 1a8e193231..adf3749fe4 100644 --- a/met/src/basic/vx_config/config_gaussian.h +++ b/met/src/basic/vx_config/config_gaussian.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index 3d77ff1a8f..bfdeef07b2 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/config_util.h b/met/src/basic/vx_config/config_util.h index ff9d38e7d4..f9750e0212 100644 --- a/met/src/basic/vx_config/config_util.h +++ b/met/src/basic/vx_config/config_util.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////// // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/data_file_type.h b/met/src/basic/vx_config/data_file_type.h index f1407b5004..d150bbe8a3 100644 --- a/met/src/basic/vx_config/data_file_type.h +++ b/met/src/basic/vx_config/data_file_type.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/dictionary.cc b/met/src/basic/vx_config/dictionary.cc index f090916ace..a4e5473143 100644 --- a/met/src/basic/vx_config/dictionary.cc +++ b/met/src/basic/vx_config/dictionary.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/dictionary.h b/met/src/basic/vx_config/dictionary.h index 3a90e047e5..08f84191c3 100644 --- a/met/src/basic/vx_config/dictionary.h +++ b/met/src/basic/vx_config/dictionary.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/icode.cc b/met/src/basic/vx_config/icode.cc index b17aac432f..ee5afbae0c 100644 --- a/met/src/basic/vx_config/icode.cc +++ b/met/src/basic/vx_config/icode.cc @@ -2,7 +2,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/icode.h b/met/src/basic/vx_config/icode.h index f0db2d0afb..816beaf969 100644 --- a/met/src/basic/vx_config/icode.h +++ b/met/src/basic/vx_config/icode.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/idstack.cc b/met/src/basic/vx_config/idstack.cc index 49b94c53af..0030172b25 100644 --- a/met/src/basic/vx_config/idstack.cc +++ b/met/src/basic/vx_config/idstack.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/idstack.h b/met/src/basic/vx_config/idstack.h index b50f3c1b90..f2f36fe909 100644 --- a/met/src/basic/vx_config/idstack.h +++ b/met/src/basic/vx_config/idstack.h @@ -2,7 +2,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/number_stack.cc b/met/src/basic/vx_config/number_stack.cc index 92e557a4e6..321e0f96d4 100644 --- a/met/src/basic/vx_config/number_stack.cc +++ b/met/src/basic/vx_config/number_stack.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/number_stack.h b/met/src/basic/vx_config/number_stack.h index 31a53b6888..bfd540e40b 100644 --- a/met/src/basic/vx_config/number_stack.h +++ b/met/src/basic/vx_config/number_stack.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/object_types.h b/met/src/basic/vx_config/object_types.h index 9da202d731..0a7845cf4e 100644 --- a/met/src/basic/vx_config/object_types.h +++ b/met/src/basic/vx_config/object_types.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/scanner_stuff.h b/met/src/basic/vx_config/scanner_stuff.h index 2474c740ad..fe3fcb27b1 100644 --- a/met/src/basic/vx_config/scanner_stuff.h +++ b/met/src/basic/vx_config/scanner_stuff.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/temp_file.cc b/met/src/basic/vx_config/temp_file.cc index 5746993957..411dafe7b1 100644 --- a/met/src/basic/vx_config/temp_file.cc +++ b/met/src/basic/vx_config/temp_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/temp_file.h b/met/src/basic/vx_config/temp_file.h index d46c99317a..9a5ae1ec62 100644 --- a/met/src/basic/vx_config/temp_file.h +++ b/met/src/basic/vx_config/temp_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/threshold.cc b/met/src/basic/vx_config/threshold.cc index 78147f1071..214cecaf94 100644 --- a/met/src/basic/vx_config/threshold.cc +++ b/met/src/basic/vx_config/threshold.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/threshold.h b/met/src/basic/vx_config/threshold.h index cf7d5640fe..e35c894618 100644 --- a/met/src/basic/vx_config/threshold.h +++ b/met/src/basic/vx_config/threshold.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_config/vx_config.h b/met/src/basic/vx_config/vx_config.h index 98550a5b22..73ea857cfd 100644 --- a/met/src/basic/vx_config/vx_config.h +++ b/met/src/basic/vx_config/vx_config.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/concat_string.cc b/met/src/basic/vx_log/concat_string.cc index 198f17ff66..36ea8b17a1 100644 --- a/met/src/basic/vx_log/concat_string.cc +++ b/met/src/basic/vx_log/concat_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/concat_string.h b/met/src/basic/vx_log/concat_string.h index 03424effbc..df41cbf78e 100644 --- a/met/src/basic/vx_log/concat_string.h +++ b/met/src/basic/vx_log/concat_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/file_fxns.cc b/met/src/basic/vx_log/file_fxns.cc index 49a5fec382..f5a31253e5 100644 --- a/met/src/basic/vx_log/file_fxns.cc +++ b/met/src/basic/vx_log/file_fxns.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/file_fxns.h b/met/src/basic/vx_log/file_fxns.h index f5d571962d..5ffaa463fe 100644 --- a/met/src/basic/vx_log/file_fxns.h +++ b/met/src/basic/vx_log/file_fxns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/indent.cc b/met/src/basic/vx_log/indent.cc index 0c70ff60df..1aa56cab40 100644 --- a/met/src/basic/vx_log/indent.cc +++ b/met/src/basic/vx_log/indent.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/indent.h b/met/src/basic/vx_log/indent.h index 63f0d6af48..71bb97052a 100644 --- a/met/src/basic/vx_log/indent.h +++ b/met/src/basic/vx_log/indent.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/logger.cc b/met/src/basic/vx_log/logger.cc index 899fbffd2e..bd4f19151d 100644 --- a/met/src/basic/vx_log/logger.cc +++ b/met/src/basic/vx_log/logger.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/logger.h b/met/src/basic/vx_log/logger.h index 6a92e43e71..60c40ff1d8 100644 --- a/met/src/basic/vx_log/logger.h +++ b/met/src/basic/vx_log/logger.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/str_wrappers.cc b/met/src/basic/vx_log/str_wrappers.cc index 7862c1e525..79578d4362 100644 --- a/met/src/basic/vx_log/str_wrappers.cc +++ b/met/src/basic/vx_log/str_wrappers.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/str_wrappers.h b/met/src/basic/vx_log/str_wrappers.h index 9a2e72a09d..579f702b4e 100644 --- a/met/src/basic/vx_log/str_wrappers.h +++ b/met/src/basic/vx_log/str_wrappers.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/string_array.cc b/met/src/basic/vx_log/string_array.cc index 57f90dac49..59539bdf5b 100644 --- a/met/src/basic/vx_log/string_array.cc +++ b/met/src/basic/vx_log/string_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/string_array.h b/met/src/basic/vx_log/string_array.h index 3662719197..22f300b305 100644 --- a/met/src/basic/vx_log/string_array.h +++ b/met/src/basic/vx_log/string_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_log/vx_log.h b/met/src/basic/vx_log/vx_log.h index 7ffb9d3ab8..b8f26c758c 100644 --- a/met/src/basic/vx_log/vx_log.h +++ b/met/src/basic/vx_log/vx_log.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/affine.cc b/met/src/basic/vx_math/affine.cc index 974eb32aa4..30f24381c4 100644 --- a/met/src/basic/vx_math/affine.cc +++ b/met/src/basic/vx_math/affine.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/affine.h b/met/src/basic/vx_math/affine.h index 7e05c53496..e97934e613 100644 --- a/met/src/basic/vx_math/affine.h +++ b/met/src/basic/vx_math/affine.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/angles.cc b/met/src/basic/vx_math/angles.cc index 4e7be72e40..9da6d376c8 100644 --- a/met/src/basic/vx_math/angles.cc +++ b/met/src/basic/vx_math/angles.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/angles.h b/met/src/basic/vx_math/angles.h index 5a53164aff..e3b292a328 100644 --- a/met/src/basic/vx_math/angles.h +++ b/met/src/basic/vx_math/angles.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/hist.cc b/met/src/basic/vx_math/hist.cc index 73d5ac2291..9858812d94 100644 --- a/met/src/basic/vx_math/hist.cc +++ b/met/src/basic/vx_math/hist.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/hist.h b/met/src/basic/vx_math/hist.h index 2580ad57c4..00e282dd9a 100644 --- a/met/src/basic/vx_math/hist.h +++ b/met/src/basic/vx_math/hist.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/is_bad_data.h b/met/src/basic/vx_math/is_bad_data.h index 809fa2f210..d8bc9b92a1 100644 --- a/met/src/basic/vx_math/is_bad_data.h +++ b/met/src/basic/vx_math/is_bad_data.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/legendre.cc b/met/src/basic/vx_math/legendre.cc index 34521d3dfd..a84f790b17 100644 --- a/met/src/basic/vx_math/legendre.cc +++ b/met/src/basic/vx_math/legendre.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/legendre.h b/met/src/basic/vx_math/legendre.h index fca0738f72..fc16ef8c5b 100644 --- a/met/src/basic/vx_math/legendre.h +++ b/met/src/basic/vx_math/legendre.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/math_constants.h b/met/src/basic/vx_math/math_constants.h index b2638c4654..89d7cf8d12 100644 --- a/met/src/basic/vx_math/math_constants.h +++ b/met/src/basic/vx_math/math_constants.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/nint.cc b/met/src/basic/vx_math/nint.cc index d013916ca3..08e8da3adb 100644 --- a/met/src/basic/vx_math/nint.cc +++ b/met/src/basic/vx_math/nint.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/nint.h b/met/src/basic/vx_math/nint.h index 712823ecba..a72f2074a1 100644 --- a/met/src/basic/vx_math/nint.h +++ b/met/src/basic/vx_math/nint.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/nti.cc b/met/src/basic/vx_math/nti.cc index bd19f6cfc2..5fc01acb4f 100644 --- a/met/src/basic/vx_math/nti.cc +++ b/met/src/basic/vx_math/nti.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/nti.h b/met/src/basic/vx_math/nti.h index b32d721ce2..9197d89a66 100644 --- a/met/src/basic/vx_math/nti.h +++ b/met/src/basic/vx_math/nti.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/ptile.cc b/met/src/basic/vx_math/ptile.cc index a712c6ff05..1869320d33 100644 --- a/met/src/basic/vx_math/ptile.cc +++ b/met/src/basic/vx_math/ptile.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/ptile.h b/met/src/basic/vx_math/ptile.h index 46a91c69f7..c1f1f75a7b 100644 --- a/met/src/basic/vx_math/ptile.h +++ b/met/src/basic/vx_math/ptile.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/pwl.cc b/met/src/basic/vx_math/pwl.cc index 102ecf586c..eef083a600 100644 --- a/met/src/basic/vx_math/pwl.cc +++ b/met/src/basic/vx_math/pwl.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/pwl.h b/met/src/basic/vx_math/pwl.h index 22e6894dbb..2290e33c19 100644 --- a/met/src/basic/vx_math/pwl.h +++ b/met/src/basic/vx_math/pwl.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/so3.cc b/met/src/basic/vx_math/so3.cc index 3f3c93ab73..115681465d 100644 --- a/met/src/basic/vx_math/so3.cc +++ b/met/src/basic/vx_math/so3.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/so3.h b/met/src/basic/vx_math/so3.h index 9d6a8e7377..ecbfdbd952 100644 --- a/met/src/basic/vx_math/so3.h +++ b/met/src/basic/vx_math/so3.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/trig.h b/met/src/basic/vx_math/trig.h index d88a2aeb79..0d6540b7ac 100644 --- a/met/src/basic/vx_math/trig.h +++ b/met/src/basic/vx_math/trig.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/vx_math.h b/met/src/basic/vx_math/vx_math.h index 08dc84b355..e4b4ffc411 100644 --- a/met/src/basic/vx_math/vx_math.h +++ b/met/src/basic/vx_math/vx_math.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/vx_vector.cc b/met/src/basic/vx_math/vx_vector.cc index a1fd9fe12a..90ba1f1fac 100644 --- a/met/src/basic/vx_math/vx_vector.cc +++ b/met/src/basic/vx_math/vx_vector.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_math/vx_vector.h b/met/src/basic/vx_math/vx_vector.h index 960ba8b63e..59dc87daf1 100644 --- a/met/src/basic/vx_math/vx_vector.h +++ b/met/src/basic/vx_math/vx_vector.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/CircularTemplate.cc b/met/src/basic/vx_util/CircularTemplate.cc index 2b2bac65d6..6ce293847d 100644 --- a/met/src/basic/vx_util/CircularTemplate.cc +++ b/met/src/basic/vx_util/CircularTemplate.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/CircularTemplate.h b/met/src/basic/vx_util/CircularTemplate.h index 835aa99ed5..a22534ef11 100644 --- a/met/src/basic/vx_util/CircularTemplate.h +++ b/met/src/basic/vx_util/CircularTemplate.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/GridOffset.cc b/met/src/basic/vx_util/GridOffset.cc index f21fd39636..f499e03a72 100644 --- a/met/src/basic/vx_util/GridOffset.cc +++ b/met/src/basic/vx_util/GridOffset.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/GridOffset.h b/met/src/basic/vx_util/GridOffset.h index dd04a36bcc..dc3b9ec147 100644 --- a/met/src/basic/vx_util/GridOffset.h +++ b/met/src/basic/vx_util/GridOffset.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/GridPoint.cc b/met/src/basic/vx_util/GridPoint.cc index bbba9ee87a..1e6f815762 100644 --- a/met/src/basic/vx_util/GridPoint.cc +++ b/met/src/basic/vx_util/GridPoint.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/GridPoint.h b/met/src/basic/vx_util/GridPoint.h index 9e66aceb0e..66c210035a 100644 --- a/met/src/basic/vx_util/GridPoint.h +++ b/met/src/basic/vx_util/GridPoint.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/GridTemplate.cc b/met/src/basic/vx_util/GridTemplate.cc index 486ff28b44..c76306d18a 100644 --- a/met/src/basic/vx_util/GridTemplate.cc +++ b/met/src/basic/vx_util/GridTemplate.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/GridTemplate.h b/met/src/basic/vx_util/GridTemplate.h index fd356c5f36..be191ebecf 100644 --- a/met/src/basic/vx_util/GridTemplate.h +++ b/met/src/basic/vx_util/GridTemplate.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/RectangularTemplate.cc b/met/src/basic/vx_util/RectangularTemplate.cc index 7368e2125c..66a963640b 100644 --- a/met/src/basic/vx_util/RectangularTemplate.cc +++ b/met/src/basic/vx_util/RectangularTemplate.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/RectangularTemplate.h b/met/src/basic/vx_util/RectangularTemplate.h index 507286adbc..659d836a41 100644 --- a/met/src/basic/vx_util/RectangularTemplate.h +++ b/met/src/basic/vx_util/RectangularTemplate.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ascii_header.cc b/met/src/basic/vx_util/ascii_header.cc index 3e171cdacb..9262714746 100644 --- a/met/src/basic/vx_util/ascii_header.cc +++ b/met/src/basic/vx_util/ascii_header.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ascii_header.h b/met/src/basic/vx_util/ascii_header.h index 0046f68c12..5c0a498c77 100644 --- a/met/src/basic/vx_util/ascii_header.h +++ b/met/src/basic/vx_util/ascii_header.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ascii_table.cc b/met/src/basic/vx_util/ascii_table.cc index e5b917c377..fa6845521f 100644 --- a/met/src/basic/vx_util/ascii_table.cc +++ b/met/src/basic/vx_util/ascii_table.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ascii_table.h b/met/src/basic/vx_util/ascii_table.h index e75f64876c..a0f32056fd 100644 --- a/met/src/basic/vx_util/ascii_table.h +++ b/met/src/basic/vx_util/ascii_table.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/bool_to_string.h b/met/src/basic/vx_util/bool_to_string.h index c99cbb8978..115bfeb9c7 100644 --- a/met/src/basic/vx_util/bool_to_string.h +++ b/met/src/basic/vx_util/bool_to_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/check_endian.cc b/met/src/basic/vx_util/check_endian.cc index 795d7014a1..575caf6b39 100644 --- a/met/src/basic/vx_util/check_endian.cc +++ b/met/src/basic/vx_util/check_endian.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/check_endian.h b/met/src/basic/vx_util/check_endian.h index bd4f65dec3..adf0e8970f 100644 --- a/met/src/basic/vx_util/check_endian.h +++ b/met/src/basic/vx_util/check_endian.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/comma_string.cc b/met/src/basic/vx_util/comma_string.cc index 5535b63158..8cd8504ed5 100644 --- a/met/src/basic/vx_util/comma_string.cc +++ b/met/src/basic/vx_util/comma_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/comma_string.h b/met/src/basic/vx_util/comma_string.h index b7cbfaad83..724e2feecd 100644 --- a/met/src/basic/vx_util/comma_string.h +++ b/met/src/basic/vx_util/comma_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/command_line.cc b/met/src/basic/vx_util/command_line.cc index 0b5d48fbd4..d1c1cefcfb 100644 --- a/met/src/basic/vx_util/command_line.cc +++ b/met/src/basic/vx_util/command_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/command_line.h b/met/src/basic/vx_util/command_line.h index 3cb114e980..d992ed81ca 100644 --- a/met/src/basic/vx_util/command_line.h +++ b/met/src/basic/vx_util/command_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/conversions.cc b/met/src/basic/vx_util/conversions.cc index 1851570488..c9e4dab79c 100644 --- a/met/src/basic/vx_util/conversions.cc +++ b/met/src/basic/vx_util/conversions.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/conversions.h b/met/src/basic/vx_util/conversions.h index 1aae66121e..ad072e5c3f 100644 --- a/met/src/basic/vx_util/conversions.h +++ b/met/src/basic/vx_util/conversions.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/crc_array.h b/met/src/basic/vx_util/crc_array.h index d79886b62c..7d86fe97e9 100644 --- a/met/src/basic/vx_util/crc_array.h +++ b/met/src/basic/vx_util/crc_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/crr_array.h b/met/src/basic/vx_util/crr_array.h index b6e9d877e7..9dca709f86 100644 --- a/met/src/basic/vx_util/crr_array.h +++ b/met/src/basic/vx_util/crr_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_cube.cc b/met/src/basic/vx_util/data_cube.cc index fcc416eca8..f81723c669 100644 --- a/met/src/basic/vx_util/data_cube.cc +++ b/met/src/basic/vx_util/data_cube.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_cube.h b/met/src/basic/vx_util/data_cube.h index 7bee93e35e..10c9c8808f 100644 --- a/met/src/basic/vx_util/data_cube.h +++ b/met/src/basic/vx_util/data_cube.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_line.cc b/met/src/basic/vx_util/data_line.cc index 155e7a449e..ca1e8db145 100644 --- a/met/src/basic/vx_util/data_line.cc +++ b/met/src/basic/vx_util/data_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_line.h b/met/src/basic/vx_util/data_line.h index d65c0dfbb5..c64b6fc4b4 100644 --- a/met/src/basic/vx_util/data_line.h +++ b/met/src/basic/vx_util/data_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_plane.cc b/met/src/basic/vx_util/data_plane.cc index c49c360918..994c988029 100644 --- a/met/src/basic/vx_util/data_plane.cc +++ b/met/src/basic/vx_util/data_plane.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_plane.h b/met/src/basic/vx_util/data_plane.h index 4580052c0b..60c82f1f9e 100644 --- a/met/src/basic/vx_util/data_plane.h +++ b/met/src/basic/vx_util/data_plane.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_plane_util.cc b/met/src/basic/vx_util/data_plane_util.cc index 39fbb67679..8f5feea095 100644 --- a/met/src/basic/vx_util/data_plane_util.cc +++ b/met/src/basic/vx_util/data_plane_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/data_plane_util.h b/met/src/basic/vx_util/data_plane_util.h index c5b8a4b65a..1b5788dddc 100644 --- a/met/src/basic/vx_util/data_plane_util.h +++ b/met/src/basic/vx_util/data_plane_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/empty_string.h b/met/src/basic/vx_util/empty_string.h index b1ef49e074..7c3ca38463 100644 --- a/met/src/basic/vx_util/empty_string.h +++ b/met/src/basic/vx_util/empty_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/file_exists.cc b/met/src/basic/vx_util/file_exists.cc index fcf6b07203..92473fe46d 100644 --- a/met/src/basic/vx_util/file_exists.cc +++ b/met/src/basic/vx_util/file_exists.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/file_exists.h b/met/src/basic/vx_util/file_exists.h index 202109ec75..75bcf2879b 100644 --- a/met/src/basic/vx_util/file_exists.h +++ b/met/src/basic/vx_util/file_exists.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/file_linecount.cc b/met/src/basic/vx_util/file_linecount.cc index ce9840bc39..03c4a3d0be 100644 --- a/met/src/basic/vx_util/file_linecount.cc +++ b/met/src/basic/vx_util/file_linecount.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/file_linecount.h b/met/src/basic/vx_util/file_linecount.h index 4a5ddfb0df..9549f9ae28 100644 --- a/met/src/basic/vx_util/file_linecount.h +++ b/met/src/basic/vx_util/file_linecount.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/file_size.cc b/met/src/basic/vx_util/file_size.cc index c58e2785dd..76402f0a26 100644 --- a/met/src/basic/vx_util/file_size.cc +++ b/met/src/basic/vx_util/file_size.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/file_size.h b/met/src/basic/vx_util/file_size.h index 3a3d9f7293..12541b7b3b 100644 --- a/met/src/basic/vx_util/file_size.h +++ b/met/src/basic/vx_util/file_size.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/filename_suffix.cc b/met/src/basic/vx_util/filename_suffix.cc index 1c20b292bf..cf59251c6b 100644 --- a/met/src/basic/vx_util/filename_suffix.cc +++ b/met/src/basic/vx_util/filename_suffix.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/filename_suffix.h b/met/src/basic/vx_util/filename_suffix.h index 8cba40fa33..b71508521b 100644 --- a/met/src/basic/vx_util/filename_suffix.h +++ b/met/src/basic/vx_util/filename_suffix.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/fix_float.cc b/met/src/basic/vx_util/fix_float.cc index 8c9973efa7..0c70b38611 100644 --- a/met/src/basic/vx_util/fix_float.cc +++ b/met/src/basic/vx_util/fix_float.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/fix_float.h b/met/src/basic/vx_util/fix_float.h index 775f2581df..abae7f8665 100644 --- a/met/src/basic/vx_util/fix_float.h +++ b/met/src/basic/vx_util/fix_float.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/get_filenames.cc b/met/src/basic/vx_util/get_filenames.cc index f52d31ae7e..13bfbc1299 100644 --- a/met/src/basic/vx_util/get_filenames.cc +++ b/met/src/basic/vx_util/get_filenames.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/get_filenames.h b/met/src/basic/vx_util/get_filenames.h index 3ee386a73b..8b666ebb69 100644 --- a/met/src/basic/vx_util/get_filenames.h +++ b/met/src/basic/vx_util/get_filenames.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/grib_constants.cc b/met/src/basic/vx_util/grib_constants.cc index e5a1f594e3..7c88309268 100644 --- a/met/src/basic/vx_util/grib_constants.cc +++ b/met/src/basic/vx_util/grib_constants.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/grib_constants.h b/met/src/basic/vx_util/grib_constants.h index 1b1fdfcc0a..e37823aa08 100644 --- a/met/src/basic/vx_util/grib_constants.h +++ b/met/src/basic/vx_util/grib_constants.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/handle_openmp.cc b/met/src/basic/vx_util/handle_openmp.cc index f23d09b4ca..b8bc26a02f 100644 --- a/met/src/basic/vx_util/handle_openmp.cc +++ b/met/src/basic/vx_util/handle_openmp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/handle_openmp.h b/met/src/basic/vx_util/handle_openmp.h index e2ea2e6a38..b877068071 100644 --- a/met/src/basic/vx_util/handle_openmp.h +++ b/met/src/basic/vx_util/handle_openmp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/int_array.h b/met/src/basic/vx_util/int_array.h index 08c815ef6c..87f6cd1dbd 100644 --- a/met/src/basic/vx_util/int_array.h +++ b/met/src/basic/vx_util/int_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/interp_mthd.cc b/met/src/basic/vx_util/interp_mthd.cc index a0c8386a8c..dcd9ff5ac4 100644 --- a/met/src/basic/vx_util/interp_mthd.cc +++ b/met/src/basic/vx_util/interp_mthd.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/interp_mthd.h b/met/src/basic/vx_util/interp_mthd.h index 88cf766d09..e65be8f7ef 100644 --- a/met/src/basic/vx_util/interp_mthd.h +++ b/met/src/basic/vx_util/interp_mthd.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/interp_util.cc b/met/src/basic/vx_util/interp_util.cc index ac37311a9e..631b88d265 100644 --- a/met/src/basic/vx_util/interp_util.cc +++ b/met/src/basic/vx_util/interp_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/interp_util.h b/met/src/basic/vx_util/interp_util.h index c8e6dc3f21..ca6038e5f3 100644 --- a/met/src/basic/vx_util/interp_util.h +++ b/met/src/basic/vx_util/interp_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/is_number.cc b/met/src/basic/vx_util/is_number.cc index f7bb865cb3..f2b49d6073 100644 --- a/met/src/basic/vx_util/is_number.cc +++ b/met/src/basic/vx_util/is_number.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/is_number.h b/met/src/basic/vx_util/is_number.h index 201173e107..ff2c4b59fe 100644 --- a/met/src/basic/vx_util/is_number.h +++ b/met/src/basic/vx_util/is_number.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/long_array.cc b/met/src/basic/vx_util/long_array.cc index b7a80b59b5..834f79e6e8 100644 --- a/met/src/basic/vx_util/long_array.cc +++ b/met/src/basic/vx_util/long_array.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/long_array.h b/met/src/basic/vx_util/long_array.h index c3dc4bccb2..58d33e9413 100644 --- a/met/src/basic/vx_util/long_array.h +++ b/met/src/basic/vx_util/long_array.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/make_path.cc b/met/src/basic/vx_util/make_path.cc index 53dcb632ca..88cafbad6f 100644 --- a/met/src/basic/vx_util/make_path.cc +++ b/met/src/basic/vx_util/make_path.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/make_path.h b/met/src/basic/vx_util/make_path.h index 6e7f1b0c3d..65d298b990 100644 --- a/met/src/basic/vx_util/make_path.h +++ b/met/src/basic/vx_util/make_path.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/mask_poly.cc b/met/src/basic/vx_util/mask_poly.cc index d7e332c6f4..11b0b08f7a 100644 --- a/met/src/basic/vx_util/mask_poly.cc +++ b/met/src/basic/vx_util/mask_poly.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/mask_poly.h b/met/src/basic/vx_util/mask_poly.h index d466b986ed..a568318ae0 100644 --- a/met/src/basic/vx_util/mask_poly.h +++ b/met/src/basic/vx_util/mask_poly.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/memory.cc b/met/src/basic/vx_util/memory.cc index 0189a3fd75..7e94a7cdeb 100644 --- a/met/src/basic/vx_util/memory.cc +++ b/met/src/basic/vx_util/memory.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/memory.h b/met/src/basic/vx_util/memory.h index 37d6091a4d..a29aefbd72 100644 --- a/met/src/basic/vx_util/memory.h +++ b/met/src/basic/vx_util/memory.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/met_buffer.cc b/met/src/basic/vx_util/met_buffer.cc index fb596913ea..d89e961e28 100644 --- a/met/src/basic/vx_util/met_buffer.cc +++ b/met/src/basic/vx_util/met_buffer.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/met_buffer.h b/met/src/basic/vx_util/met_buffer.h index 9ea54b9779..4280baae56 100644 --- a/met/src/basic/vx_util/met_buffer.h +++ b/met/src/basic/vx_util/met_buffer.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ncrr_array.h b/met/src/basic/vx_util/ncrr_array.h index c40e282fe5..68fbd40592 100644 --- a/met/src/basic/vx_util/ncrr_array.h +++ b/met/src/basic/vx_util/ncrr_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/num_array.cc b/met/src/basic/vx_util/num_array.cc index 446bf29034..fb4642d1a6 100644 --- a/met/src/basic/vx_util/num_array.cc +++ b/met/src/basic/vx_util/num_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/num_array.h b/met/src/basic/vx_util/num_array.h index 623f7e39c8..c4a061f0f7 100644 --- a/met/src/basic/vx_util/num_array.h +++ b/met/src/basic/vx_util/num_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/observation.cc b/met/src/basic/vx_util/observation.cc index 7a9d6e7c8c..68f5646f86 100644 --- a/met/src/basic/vx_util/observation.cc +++ b/met/src/basic/vx_util/observation.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/observation.h b/met/src/basic/vx_util/observation.h index 3c84d65405..f9230e2dfe 100644 --- a/met/src/basic/vx_util/observation.h +++ b/met/src/basic/vx_util/observation.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ordinal.cc b/met/src/basic/vx_util/ordinal.cc index 87ec74679e..3eb87891af 100644 --- a/met/src/basic/vx_util/ordinal.cc +++ b/met/src/basic/vx_util/ordinal.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/ordinal.h b/met/src/basic/vx_util/ordinal.h index 41872ca93d..5442deb4d6 100644 --- a/met/src/basic/vx_util/ordinal.h +++ b/met/src/basic/vx_util/ordinal.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/polyline.cc b/met/src/basic/vx_util/polyline.cc index 5b266bf22d..9f3859ae5f 100644 --- a/met/src/basic/vx_util/polyline.cc +++ b/met/src/basic/vx_util/polyline.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/polyline.h b/met/src/basic/vx_util/polyline.h index 5502425d68..1278a71508 100644 --- a/met/src/basic/vx_util/polyline.h +++ b/met/src/basic/vx_util/polyline.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/python_line.cc b/met/src/basic/vx_util/python_line.cc index 75b838427c..66af4de992 100644 --- a/met/src/basic/vx_util/python_line.cc +++ b/met/src/basic/vx_util/python_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/python_line.h b/met/src/basic/vx_util/python_line.h index e65cf9ba0c..a0ceedbaed 100644 --- a/met/src/basic/vx_util/python_line.h +++ b/met/src/basic/vx_util/python_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/read_fortran_binary.cc b/met/src/basic/vx_util/read_fortran_binary.cc index 2d2edf38b0..2eced7fb8e 100644 --- a/met/src/basic/vx_util/read_fortran_binary.cc +++ b/met/src/basic/vx_util/read_fortran_binary.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/read_fortran_binary.h b/met/src/basic/vx_util/read_fortran_binary.h index 7249c04bad..1172a84826 100644 --- a/met/src/basic/vx_util/read_fortran_binary.h +++ b/met/src/basic/vx_util/read_fortran_binary.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/roman_numeral.cc b/met/src/basic/vx_util/roman_numeral.cc index 02bc520282..c4e709fb74 100644 --- a/met/src/basic/vx_util/roman_numeral.cc +++ b/met/src/basic/vx_util/roman_numeral.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/roman_numeral.h b/met/src/basic/vx_util/roman_numeral.h index 68c9cf260f..d26a7e7cad 100644 --- a/met/src/basic/vx_util/roman_numeral.h +++ b/met/src/basic/vx_util/roman_numeral.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/smart_buffer.cc b/met/src/basic/vx_util/smart_buffer.cc index c3ed7e8150..2b3f1669f2 100644 --- a/met/src/basic/vx_util/smart_buffer.cc +++ b/met/src/basic/vx_util/smart_buffer.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/smart_buffer.h b/met/src/basic/vx_util/smart_buffer.h index 1982136c0c..eec99c3dee 100644 --- a/met/src/basic/vx_util/smart_buffer.h +++ b/met/src/basic/vx_util/smart_buffer.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/stat_column_defs.h b/met/src/basic/vx_util/stat_column_defs.h index 9b21762513..130f41bcb1 100644 --- a/met/src/basic/vx_util/stat_column_defs.h +++ b/met/src/basic/vx_util/stat_column_defs.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/string_fxns.cc b/met/src/basic/vx_util/string_fxns.cc index 8817880053..d03976f034 100644 --- a/met/src/basic/vx_util/string_fxns.cc +++ b/met/src/basic/vx_util/string_fxns.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/string_fxns.h b/met/src/basic/vx_util/string_fxns.h index 84db62c4b1..66c569f33a 100644 --- a/met/src/basic/vx_util/string_fxns.h +++ b/met/src/basic/vx_util/string_fxns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/substring.cc b/met/src/basic/vx_util/substring.cc index 3a5f3af102..f34bc2e1d6 100644 --- a/met/src/basic/vx_util/substring.cc +++ b/met/src/basic/vx_util/substring.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/substring.h b/met/src/basic/vx_util/substring.h index a4dee4f502..760b578110 100644 --- a/met/src/basic/vx_util/substring.h +++ b/met/src/basic/vx_util/substring.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/thresh_array.cc b/met/src/basic/vx_util/thresh_array.cc index 75ea29b4ff..1575ef1f04 100644 --- a/met/src/basic/vx_util/thresh_array.cc +++ b/met/src/basic/vx_util/thresh_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/thresh_array.h b/met/src/basic/vx_util/thresh_array.h index 12fcce1499..508398b388 100644 --- a/met/src/basic/vx_util/thresh_array.h +++ b/met/src/basic/vx_util/thresh_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/two_d_array.h b/met/src/basic/vx_util/two_d_array.h index d76777efa7..8b1aba2203 100644 --- a/met/src/basic/vx_util/two_d_array.h +++ b/met/src/basic/vx_util/two_d_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/two_to_one.cc b/met/src/basic/vx_util/two_to_one.cc index 584d53a17c..58a0037470 100644 --- a/met/src/basic/vx_util/two_to_one.cc +++ b/met/src/basic/vx_util/two_to_one.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/two_to_one.h b/met/src/basic/vx_util/two_to_one.h index 72d5e8c8c6..430c1f85aa 100644 --- a/met/src/basic/vx_util/two_to_one.h +++ b/met/src/basic/vx_util/two_to_one.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/util_constants.h b/met/src/basic/vx_util/util_constants.h index ade03d5840..34da0d9e91 100644 --- a/met/src/basic/vx_util/util_constants.h +++ b/met/src/basic/vx_util/util_constants.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/basic/vx_util/vx_util.h b/met/src/basic/vx_util/vx_util.h index f8a79c5767..dceeaa62c1 100644 --- a/met/src/basic/vx_util/vx_util.h +++ b/met/src/basic/vx_util/vx_util.h @@ -1,6 +1,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm.cc b/met/src/libcode/vx_afm/afm.cc index d8355916ef..e4389d3446 100644 --- a/met/src/libcode/vx_afm/afm.cc +++ b/met/src/libcode/vx_afm/afm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm.h b/met/src/libcode/vx_afm/afm.h index 5842a83f06..2d00ad58ff 100644 --- a/met/src/libcode/vx_afm/afm.h +++ b/met/src/libcode/vx_afm/afm.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_keywords.cc b/met/src/libcode/vx_afm/afm_keywords.cc index 3007118b03..64b46a5f09 100644 --- a/met/src/libcode/vx_afm/afm_keywords.cc +++ b/met/src/libcode/vx_afm/afm_keywords.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_keywords.h b/met/src/libcode/vx_afm/afm_keywords.h index 03aa9c5ea1..026f0ca0c5 100644 --- a/met/src/libcode/vx_afm/afm_keywords.h +++ b/met/src/libcode/vx_afm/afm_keywords.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_line.cc b/met/src/libcode/vx_afm/afm_line.cc index 686b8a4ba8..af0586ccbf 100644 --- a/met/src/libcode/vx_afm/afm_line.cc +++ b/met/src/libcode/vx_afm/afm_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_line.h b/met/src/libcode/vx_afm/afm_line.h index 1ed49c33b5..3ccc32b241 100644 --- a/met/src/libcode/vx_afm/afm_line.h +++ b/met/src/libcode/vx_afm/afm_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_token.cc b/met/src/libcode/vx_afm/afm_token.cc index 9dbf1926b4..109b60fb89 100644 --- a/met/src/libcode/vx_afm/afm_token.cc +++ b/met/src/libcode/vx_afm/afm_token.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_token.h b/met/src/libcode/vx_afm/afm_token.h index fc08d7dac6..158afed618 100644 --- a/met/src/libcode/vx_afm/afm_token.h +++ b/met/src/libcode/vx_afm/afm_token.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afm_token_types.h b/met/src/libcode/vx_afm/afm_token_types.h index 0e8e6029ba..ebb8e35d77 100644 --- a/met/src/libcode/vx_afm/afm_token_types.h +++ b/met/src/libcode/vx_afm/afm_token_types.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afmkeyword_to_string.cc b/met/src/libcode/vx_afm/afmkeyword_to_string.cc index 80b9ee4af4..5c65aa4d89 100644 --- a/met/src/libcode/vx_afm/afmkeyword_to_string.cc +++ b/met/src/libcode/vx_afm/afmkeyword_to_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afmkeyword_to_string.h b/met/src/libcode/vx_afm/afmkeyword_to_string.h index 382c62c9f4..e1a2ef31b2 100644 --- a/met/src/libcode/vx_afm/afmkeyword_to_string.h +++ b/met/src/libcode/vx_afm/afmkeyword_to_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afmtokentype_to_string.cc b/met/src/libcode/vx_afm/afmtokentype_to_string.cc index a7a4df02e6..ed7bb851de 100644 --- a/met/src/libcode/vx_afm/afmtokentype_to_string.cc +++ b/met/src/libcode/vx_afm/afmtokentype_to_string.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_afm/afmtokentype_to_string.h b/met/src/libcode/vx_afm/afmtokentype_to_string.h index 122ceb2ead..4799755571 100644 --- a/met/src/libcode/vx_afm/afmtokentype_to_string.h +++ b/met/src/libcode/vx_afm/afmtokentype_to_string.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/analysis_utils.cc b/met/src/libcode/vx_analysis_util/analysis_utils.cc index 313b082236..a464482eb6 100644 --- a/met/src/libcode/vx_analysis_util/analysis_utils.cc +++ b/met/src/libcode/vx_analysis_util/analysis_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/analysis_utils.h b/met/src/libcode/vx_analysis_util/analysis_utils.h index 035c0c7ee8..9acaaf1b5e 100644 --- a/met/src/libcode/vx_analysis_util/analysis_utils.h +++ b/met/src/libcode/vx_analysis_util/analysis_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/by_case_info.cc b/met/src/libcode/vx_analysis_util/by_case_info.cc index 4ed22aa36c..6187d84919 100644 --- a/met/src/libcode/vx_analysis_util/by_case_info.cc +++ b/met/src/libcode/vx_analysis_util/by_case_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/by_case_info.h b/met/src/libcode/vx_analysis_util/by_case_info.h index 1c5391f82f..e95bd49846 100644 --- a/met/src/libcode/vx_analysis_util/by_case_info.h +++ b/met/src/libcode/vx_analysis_util/by_case_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/mode_atts.cc b/met/src/libcode/vx_analysis_util/mode_atts.cc index 138e488b10..e6dc33bec8 100644 --- a/met/src/libcode/vx_analysis_util/mode_atts.cc +++ b/met/src/libcode/vx_analysis_util/mode_atts.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/mode_atts.h b/met/src/libcode/vx_analysis_util/mode_atts.h index f50977ba08..a20570ddc7 100644 --- a/met/src/libcode/vx_analysis_util/mode_atts.h +++ b/met/src/libcode/vx_analysis_util/mode_atts.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/mode_job.cc b/met/src/libcode/vx_analysis_util/mode_job.cc index 077733412a..0ea8acb0cf 100644 --- a/met/src/libcode/vx_analysis_util/mode_job.cc +++ b/met/src/libcode/vx_analysis_util/mode_job.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/mode_job.h b/met/src/libcode/vx_analysis_util/mode_job.h index 27e551a8a5..7e9c2668cc 100644 --- a/met/src/libcode/vx_analysis_util/mode_job.h +++ b/met/src/libcode/vx_analysis_util/mode_job.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/mode_line.cc b/met/src/libcode/vx_analysis_util/mode_line.cc index f62739af92..717a284707 100644 --- a/met/src/libcode/vx_analysis_util/mode_line.cc +++ b/met/src/libcode/vx_analysis_util/mode_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/mode_line.h b/met/src/libcode/vx_analysis_util/mode_line.h index e5b0822255..d02d261449 100644 --- a/met/src/libcode/vx_analysis_util/mode_line.h +++ b/met/src/libcode/vx_analysis_util/mode_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/stat_job.cc b/met/src/libcode/vx_analysis_util/stat_job.cc index 9e1f5c91ec..af3c450c74 100644 --- a/met/src/libcode/vx_analysis_util/stat_job.cc +++ b/met/src/libcode/vx_analysis_util/stat_job.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/stat_job.h b/met/src/libcode/vx_analysis_util/stat_job.h index bed32cdc1a..a1b90849ff 100644 --- a/met/src/libcode/vx_analysis_util/stat_job.h +++ b/met/src/libcode/vx_analysis_util/stat_job.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/stat_line.cc b/met/src/libcode/vx_analysis_util/stat_line.cc index 0a47746f8f..a584e79d8b 100644 --- a/met/src/libcode/vx_analysis_util/stat_line.cc +++ b/met/src/libcode/vx_analysis_util/stat_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/stat_line.h b/met/src/libcode/vx_analysis_util/stat_line.h index fd615ef8d6..e7b63ee9d5 100644 --- a/met/src/libcode/vx_analysis_util/stat_line.h +++ b/met/src/libcode/vx_analysis_util/stat_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/time_series.cc b/met/src/libcode/vx_analysis_util/time_series.cc index 2829989f99..99d2653b03 100644 --- a/met/src/libcode/vx_analysis_util/time_series.cc +++ b/met/src/libcode/vx_analysis_util/time_series.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/time_series.h b/met/src/libcode/vx_analysis_util/time_series.h index efc2f948d3..0474bc6503 100644 --- a/met/src/libcode/vx_analysis_util/time_series.h +++ b/met/src/libcode/vx_analysis_util/time_series.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_analysis_util/vx_analysis_util.h b/met/src/libcode/vx_analysis_util/vx_analysis_util.h index 8ea79ebf2d..2e20899487 100644 --- a/met/src/libcode/vx_analysis_util/vx_analysis_util.h +++ b/met/src/libcode/vx_analysis_util/vx_analysis_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/color.cc b/met/src/libcode/vx_color/color.cc index a15eef78b0..572b8a6064 100644 --- a/met/src/libcode/vx_color/color.cc +++ b/met/src/libcode/vx_color/color.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/color.h b/met/src/libcode/vx_color/color.h index 608d0f2667..746b3610bb 100644 --- a/met/src/libcode/vx_color/color.h +++ b/met/src/libcode/vx_color/color.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/color_list.cc b/met/src/libcode/vx_color/color_list.cc index 517ae095fa..300e5d883a 100644 --- a/met/src/libcode/vx_color/color_list.cc +++ b/met/src/libcode/vx_color/color_list.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/color_list.h b/met/src/libcode/vx_color/color_list.h index 5ebe43af49..8bcee60348 100644 --- a/met/src/libcode/vx_color/color_list.h +++ b/met/src/libcode/vx_color/color_list.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/color_parser.h b/met/src/libcode/vx_color/color_parser.h index 9ac68cfd87..0568f2e386 100644 --- a/met/src/libcode/vx_color/color_parser.h +++ b/met/src/libcode/vx_color/color_parser.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/color_table.cc b/met/src/libcode/vx_color/color_table.cc index aa990b8189..ed6f66843b 100644 --- a/met/src/libcode/vx_color/color_table.cc +++ b/met/src/libcode/vx_color/color_table.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_color/vx_color.h b/met/src/libcode/vx_color/vx_color.h index c8b9a30538..8553f1013c 100644 --- a/met/src/libcode/vx_color/vx_color.h +++ b/met/src/libcode/vx_color/vx_color.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/data2d_utils.cc b/met/src/libcode/vx_data2d/data2d_utils.cc index b86829221c..75cc68c51f 100644 --- a/met/src/libcode/vx_data2d/data2d_utils.cc +++ b/met/src/libcode/vx_data2d/data2d_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/data2d_utils.h b/met/src/libcode/vx_data2d/data2d_utils.h index 20c5793e58..0b1ac12ca0 100644 --- a/met/src/libcode/vx_data2d/data2d_utils.h +++ b/met/src/libcode/vx_data2d/data2d_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/data_class.cc b/met/src/libcode/vx_data2d/data_class.cc index c3da14d83f..09b09684a9 100644 --- a/met/src/libcode/vx_data2d/data_class.cc +++ b/met/src/libcode/vx_data2d/data_class.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/data_class.h b/met/src/libcode/vx_data2d/data_class.h index 0762346ad7..401cd4e0c7 100644 --- a/met/src/libcode/vx_data2d/data_class.h +++ b/met/src/libcode/vx_data2d/data_class.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/level_info.cc b/met/src/libcode/vx_data2d/level_info.cc index f1f18bdabe..2323475e93 100644 --- a/met/src/libcode/vx_data2d/level_info.cc +++ b/met/src/libcode/vx_data2d/level_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/level_info.h b/met/src/libcode/vx_data2d/level_info.h index c551fa0e54..a9becc61e6 100644 --- a/met/src/libcode/vx_data2d/level_info.h +++ b/met/src/libcode/vx_data2d/level_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/table_lookup.cc b/met/src/libcode/vx_data2d/table_lookup.cc index ea3385f323..dbc920ae21 100644 --- a/met/src/libcode/vx_data2d/table_lookup.cc +++ b/met/src/libcode/vx_data2d/table_lookup.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/table_lookup.h b/met/src/libcode/vx_data2d/table_lookup.h index 6a8365d795..d6ae3fa6f7 100644 --- a/met/src/libcode/vx_data2d/table_lookup.h +++ b/met/src/libcode/vx_data2d/table_lookup.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/var_info.cc b/met/src/libcode/vx_data2d/var_info.cc index 009fdfe4c3..f80a0bee69 100644 --- a/met/src/libcode/vx_data2d/var_info.cc +++ b/met/src/libcode/vx_data2d/var_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/var_info.h b/met/src/libcode/vx_data2d/var_info.h index 2bd1f42973..382f25aded 100644 --- a/met/src/libcode/vx_data2d/var_info.h +++ b/met/src/libcode/vx_data2d/var_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d/vx_data2d.h b/met/src/libcode/vx_data2d/vx_data2d.h index d080544991..a560b22dfb 100644 --- a/met/src/libcode/vx_data2d/vx_data2d.h +++ b/met/src/libcode/vx_data2d/vx_data2d.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/data2d_factory.cc b/met/src/libcode/vx_data2d_factory/data2d_factory.cc index 8f2b4fcda8..a2cc01b8af 100644 --- a/met/src/libcode/vx_data2d_factory/data2d_factory.cc +++ b/met/src/libcode/vx_data2d_factory/data2d_factory.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/data2d_factory.h b/met/src/libcode/vx_data2d_factory/data2d_factory.h index 43d0575e49..76cff37050 100644 --- a/met/src/libcode/vx_data2d_factory/data2d_factory.h +++ b/met/src/libcode/vx_data2d_factory/data2d_factory.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/data2d_factory_utils.cc b/met/src/libcode/vx_data2d_factory/data2d_factory_utils.cc index 3d638a065b..f8c33bd8b9 100644 --- a/met/src/libcode/vx_data2d_factory/data2d_factory_utils.cc +++ b/met/src/libcode/vx_data2d_factory/data2d_factory_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/data2d_factory_utils.h b/met/src/libcode/vx_data2d_factory/data2d_factory_utils.h index e86e8df108..6e8695392a 100644 --- a/met/src/libcode/vx_data2d_factory/data2d_factory_utils.h +++ b/met/src/libcode/vx_data2d_factory/data2d_factory_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/is_bufr_file.cc b/met/src/libcode/vx_data2d_factory/is_bufr_file.cc index 78773558d7..d26cb0fb01 100644 --- a/met/src/libcode/vx_data2d_factory/is_bufr_file.cc +++ b/met/src/libcode/vx_data2d_factory/is_bufr_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/is_bufr_file.h b/met/src/libcode/vx_data2d_factory/is_bufr_file.h index 9b2adb27c1..c4af030853 100644 --- a/met/src/libcode/vx_data2d_factory/is_bufr_file.h +++ b/met/src/libcode/vx_data2d_factory/is_bufr_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/is_grib_file.cc b/met/src/libcode/vx_data2d_factory/is_grib_file.cc index 2aaf1e62ee..6c4c21f5a2 100644 --- a/met/src/libcode/vx_data2d_factory/is_grib_file.cc +++ b/met/src/libcode/vx_data2d_factory/is_grib_file.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/is_grib_file.h b/met/src/libcode/vx_data2d_factory/is_grib_file.h index 5301859de7..b1363b544f 100644 --- a/met/src/libcode/vx_data2d_factory/is_grib_file.h +++ b/met/src/libcode/vx_data2d_factory/is_grib_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/is_netcdf_file.cc b/met/src/libcode/vx_data2d_factory/is_netcdf_file.cc index c10de20f9b..805ce8ee81 100644 --- a/met/src/libcode/vx_data2d_factory/is_netcdf_file.cc +++ b/met/src/libcode/vx_data2d_factory/is_netcdf_file.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/is_netcdf_file.h b/met/src/libcode/vx_data2d_factory/is_netcdf_file.h index de06530466..69e458209d 100644 --- a/met/src/libcode/vx_data2d_factory/is_netcdf_file.h +++ b/met/src/libcode/vx_data2d_factory/is_netcdf_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/parse_file_list.cc b/met/src/libcode/vx_data2d_factory/parse_file_list.cc index cd01087acc..17bc194686 100644 --- a/met/src/libcode/vx_data2d_factory/parse_file_list.cc +++ b/met/src/libcode/vx_data2d_factory/parse_file_list.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/parse_file_list.h b/met/src/libcode/vx_data2d_factory/parse_file_list.h index 35443a52ba..2b622a68dd 100644 --- a/met/src/libcode/vx_data2d_factory/parse_file_list.h +++ b/met/src/libcode/vx_data2d_factory/parse_file_list.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/var_info_factory.cc b/met/src/libcode/vx_data2d_factory/var_info_factory.cc index 5deb64d629..c09d03265d 100644 --- a/met/src/libcode/vx_data2d_factory/var_info_factory.cc +++ b/met/src/libcode/vx_data2d_factory/var_info_factory.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/var_info_factory.h b/met/src/libcode/vx_data2d_factory/var_info_factory.h index 35f12051b2..3c8e3a427e 100644 --- a/met/src/libcode/vx_data2d_factory/var_info_factory.h +++ b/met/src/libcode/vx_data2d_factory/var_info_factory.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_factory/vx_data2d_factory.h b/met/src/libcode/vx_data2d_factory/vx_data2d_factory.h index 264c30886f..b0e10d269e 100644 --- a/met/src/libcode/vx_data2d_factory/vx_data2d_factory.h +++ b/met/src/libcode/vx_data2d_factory/vx_data2d_factory.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/data2d_grib.cc b/met/src/libcode/vx_data2d_grib/data2d_grib.cc index adfe298daf..ef5e622b9c 100644 --- a/met/src/libcode/vx_data2d_grib/data2d_grib.cc +++ b/met/src/libcode/vx_data2d_grib/data2d_grib.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/data2d_grib.h b/met/src/libcode/vx_data2d_grib/data2d_grib.h index 63839220a5..6c72eaca1c 100644 --- a/met/src/libcode/vx_data2d_grib/data2d_grib.h +++ b/met/src/libcode/vx_data2d_grib/data2d_grib.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/data2d_grib_utils.cc b/met/src/libcode/vx_data2d_grib/data2d_grib_utils.cc index a1f01334a8..8071ee9548 100644 --- a/met/src/libcode/vx_data2d_grib/data2d_grib_utils.cc +++ b/met/src/libcode/vx_data2d_grib/data2d_grib_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/data2d_grib_utils.h b/met/src/libcode/vx_data2d_grib/data2d_grib_utils.h index fa775f4a18..40744d71e2 100644 --- a/met/src/libcode/vx_data2d_grib/data2d_grib_utils.h +++ b/met/src/libcode/vx_data2d_grib/data2d_grib_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/grib_classes.cc b/met/src/libcode/vx_data2d_grib/grib_classes.cc index e76e9d2631..da1a5f0f76 100644 --- a/met/src/libcode/vx_data2d_grib/grib_classes.cc +++ b/met/src/libcode/vx_data2d_grib/grib_classes.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/grib_classes.h b/met/src/libcode/vx_data2d_grib/grib_classes.h index 6945fad97b..55b7046d65 100644 --- a/met/src/libcode/vx_data2d_grib/grib_classes.h +++ b/met/src/libcode/vx_data2d_grib/grib_classes.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/grib_strings.cc b/met/src/libcode/vx_data2d_grib/grib_strings.cc index d45177e832..7c9c21658b 100644 --- a/met/src/libcode/vx_data2d_grib/grib_strings.cc +++ b/met/src/libcode/vx_data2d_grib/grib_strings.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/grib_strings.h b/met/src/libcode/vx_data2d_grib/grib_strings.h index 500d5f7638..2fddd2dcef 100644 --- a/met/src/libcode/vx_data2d_grib/grib_strings.h +++ b/met/src/libcode/vx_data2d_grib/grib_strings.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/grib_utils.cc b/met/src/libcode/vx_data2d_grib/grib_utils.cc index 3fbbdd23c5..6dc5b7c563 100644 --- a/met/src/libcode/vx_data2d_grib/grib_utils.cc +++ b/met/src/libcode/vx_data2d_grib/grib_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/grib_utils.h b/met/src/libcode/vx_data2d_grib/grib_utils.h index 7b3a1a9400..0a45f36901 100644 --- a/met/src/libcode/vx_data2d_grib/grib_utils.h +++ b/met/src/libcode/vx_data2d_grib/grib_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/var_info_grib.cc b/met/src/libcode/vx_data2d_grib/var_info_grib.cc index a75b699674..1455acfed7 100644 --- a/met/src/libcode/vx_data2d_grib/var_info_grib.cc +++ b/met/src/libcode/vx_data2d_grib/var_info_grib.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/var_info_grib.h b/met/src/libcode/vx_data2d_grib/var_info_grib.h index 1e92bbbd93..9a0b9bf4ce 100644 --- a/met/src/libcode/vx_data2d_grib/var_info_grib.h +++ b/met/src/libcode/vx_data2d_grib/var_info_grib.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/vx_data2d_grib.h b/met/src/libcode/vx_data2d_grib/vx_data2d_grib.h index 92bf8fea02..be2554cfed 100644 --- a/met/src/libcode/vx_data2d_grib/vx_data2d_grib.h +++ b/met/src/libcode/vx_data2d_grib/vx_data2d_grib.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib/vx_grib_classes.h b/met/src/libcode/vx_data2d_grib/vx_grib_classes.h index 06131ea82a..7f6d66be2f 100644 --- a/met/src/libcode/vx_data2d_grib/vx_grib_classes.h +++ b/met/src/libcode/vx_data2d_grib/vx_grib_classes.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc b/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc index 20dc3681d2..5646a2f13c 100644 --- a/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc +++ b/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib2/data2d_grib2.h b/met/src/libcode/vx_data2d_grib2/data2d_grib2.h index 851bb78e0a..0f371c758a 100644 --- a/met/src/libcode/vx_data2d_grib2/data2d_grib2.h +++ b/met/src/libcode/vx_data2d_grib2/data2d_grib2.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc b/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc index 5fa3042bfe..6fc0d45759 100644 --- a/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc +++ b/met/src/libcode/vx_data2d_grib2/var_info_grib2.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_grib2/var_info_grib2.h b/met/src/libcode/vx_data2d_grib2/var_info_grib2.h index dd9cd994a0..beca6c3b07 100644 --- a/met/src/libcode/vx_data2d_grib2/var_info_grib2.h +++ b/met/src/libcode/vx_data2d_grib2/var_info_grib2.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc index 0c73e8f677..0bbb55c718 100644 --- a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc +++ b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h index 36d80858c5..0153d16467 100644 --- a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h +++ b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc b/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc index d4c7519596..8e9e68cf4d 100644 --- a/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc +++ b/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/get_met_grid.h b/met/src/libcode/vx_data2d_nc_met/get_met_grid.h index 16aaf84662..5315025b6e 100644 --- a/met/src/libcode/vx_data2d_nc_met/get_met_grid.h +++ b/met/src/libcode/vx_data2d_nc_met/get_met_grid.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/met_file.cc b/met/src/libcode/vx_data2d_nc_met/met_file.cc index 39dc06ca68..8abf239884 100644 --- a/met/src/libcode/vx_data2d_nc_met/met_file.cc +++ b/met/src/libcode/vx_data2d_nc_met/met_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/met_file.h b/met/src/libcode/vx_data2d_nc_met/met_file.h index f2f218f617..513cb0c49f 100644 --- a/met/src/libcode/vx_data2d_nc_met/met_file.h +++ b/met/src/libcode/vx_data2d_nc_met/met_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc b/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc index facb4e8702..75282d1df8 100644 --- a/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc +++ b/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.h b/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.h index f2abb1e5ec..bc2e0d0673 100644 --- a/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.h +++ b/met/src/libcode/vx_data2d_nc_met/var_info_nc_met.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_met/vx_data2d_nc_met.h b/met/src/libcode/vx_data2d_nc_met/vx_data2d_nc_met.h index 979f915512..f167695580 100644 --- a/met/src/libcode/vx_data2d_nc_met/vx_data2d_nc_met.h +++ b/met/src/libcode/vx_data2d_nc_met/vx_data2d_nc_met.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.cc b/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.cc index 0af7e2e2b3..327cab74a3 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.cc +++ b/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.h b/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.h index f467b41a6b..d9538dfa09 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.h +++ b/met/src/libcode/vx_data2d_nc_pinterp/data2d_nc_pinterp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc b/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc index 0dd8607c0b..b5a78b109a 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc +++ b/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.h b/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.h index 1ca10b7294..6294ed82cf 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.h +++ b/met/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.cc b/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.cc index 02a5e44f45..d4f8451006 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.cc +++ b/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.h b/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.h index 3d2f0dc256..6b7bbf2fe0 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.h +++ b/met/src/libcode/vx_data2d_nc_pinterp/pinterp_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc b/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc index 9f16c1dea8..ecc1744728 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc +++ b/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.h b/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.h index d48e6c2270..e169437291 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.h +++ b/met/src/libcode/vx_data2d_nc_pinterp/var_info_nc_pinterp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nc_pinterp/vx_data2d_nc_pinterp.h b/met/src/libcode/vx_data2d_nc_pinterp/vx_data2d_nc_pinterp.h index 3e6285e090..d33765f400 100644 --- a/met/src/libcode/vx_data2d_nc_pinterp/vx_data2d_nc_pinterp.h +++ b/met/src/libcode/vx_data2d_nc_pinterp/vx_data2d_nc_pinterp.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/data2d_nccf.cc b/met/src/libcode/vx_data2d_nccf/data2d_nccf.cc index 9da4858f33..8a8b2008c3 100644 --- a/met/src/libcode/vx_data2d_nccf/data2d_nccf.cc +++ b/met/src/libcode/vx_data2d_nccf/data2d_nccf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/data2d_nccf.h b/met/src/libcode/vx_data2d_nccf/data2d_nccf.h index 0ebbf50df6..dbe5ed8073 100644 --- a/met/src/libcode/vx_data2d_nccf/data2d_nccf.h +++ b/met/src/libcode/vx_data2d_nccf/data2d_nccf.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.cc b/met/src/libcode/vx_data2d_nccf/nccf_file.cc index 80ae51e415..651129239b 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.cc +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.h b/met/src/libcode/vx_data2d_nccf/nccf_file.h index 71fa039a60..e3c2ecd0fe 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.h +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc b/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc index 8bfc679336..25495392f0 100644 --- a/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc +++ b/met/src/libcode/vx_data2d_nccf/var_info_nccf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/var_info_nccf.h b/met/src/libcode/vx_data2d_nccf/var_info_nccf.h index f3d5a47d5e..f49326d80a 100644 --- a/met/src/libcode/vx_data2d_nccf/var_info_nccf.h +++ b/met/src/libcode/vx_data2d_nccf/var_info_nccf.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_nccf/vx_data2d_nccf.h b/met/src/libcode/vx_data2d_nccf/vx_data2d_nccf.h index e8c7ecc00f..d085b731a0 100644 --- a/met/src/libcode/vx_data2d_nccf/vx_data2d_nccf.h +++ b/met/src/libcode/vx_data2d_nccf/vx_data2d_nccf.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/data2d_python.cc b/met/src/libcode/vx_data2d_python/data2d_python.cc index e246dc8ca2..d8248733a4 100644 --- a/met/src/libcode/vx_data2d_python/data2d_python.cc +++ b/met/src/libcode/vx_data2d_python/data2d_python.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/data2d_python.h b/met/src/libcode/vx_data2d_python/data2d_python.h index 0aebfe2710..161b0a83fb 100644 --- a/met/src/libcode/vx_data2d_python/data2d_python.h +++ b/met/src/libcode/vx_data2d_python/data2d_python.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.cc b/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.cc index 16fe195edc..8988bf2e75 100644 --- a/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.cc +++ b/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.h b/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.h index b6d7a1f25e..856260ffc3 100644 --- a/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.h +++ b/met/src/libcode/vx_data2d_python/dataplane_from_numpy_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/dataplane_from_xarray.cc b/met/src/libcode/vx_data2d_python/dataplane_from_xarray.cc index 9704c73cb9..1b1d6e1aa0 100644 --- a/met/src/libcode/vx_data2d_python/dataplane_from_xarray.cc +++ b/met/src/libcode/vx_data2d_python/dataplane_from_xarray.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/dataplane_from_xarray.h b/met/src/libcode/vx_data2d_python/dataplane_from_xarray.h index 58cb05f30b..dde66f918d 100644 --- a/met/src/libcode/vx_data2d_python/dataplane_from_xarray.h +++ b/met/src/libcode/vx_data2d_python/dataplane_from_xarray.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/grid_from_python_dict.cc b/met/src/libcode/vx_data2d_python/grid_from_python_dict.cc index d60bb8e39a..f66bbf56c6 100644 --- a/met/src/libcode/vx_data2d_python/grid_from_python_dict.cc +++ b/met/src/libcode/vx_data2d_python/grid_from_python_dict.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/grid_from_python_dict.h b/met/src/libcode/vx_data2d_python/grid_from_python_dict.h index a8bee09c2d..f6b00d5b97 100644 --- a/met/src/libcode/vx_data2d_python/grid_from_python_dict.h +++ b/met/src/libcode/vx_data2d_python/grid_from_python_dict.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/python_dataplane.cc b/met/src/libcode/vx_data2d_python/python_dataplane.cc index aac7ac9e15..f588db9c03 100644 --- a/met/src/libcode/vx_data2d_python/python_dataplane.cc +++ b/met/src/libcode/vx_data2d_python/python_dataplane.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/python_dataplane.h b/met/src/libcode/vx_data2d_python/python_dataplane.h index 6b125a393d..0b8ad8fa44 100644 --- a/met/src/libcode/vx_data2d_python/python_dataplane.h +++ b/met/src/libcode/vx_data2d_python/python_dataplane.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/var_info_python.cc b/met/src/libcode/vx_data2d_python/var_info_python.cc index 3ca19e0621..7c1e7e41c3 100644 --- a/met/src/libcode/vx_data2d_python/var_info_python.cc +++ b/met/src/libcode/vx_data2d_python/var_info_python.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_data2d_python/var_info_python.h b/met/src/libcode/vx_data2d_python/var_info_python.h index bc02c8868d..a9d9f781fa 100644 --- a/met/src/libcode/vx_data2d_python/var_info_python.h +++ b/met/src/libcode/vx_data2d_python/var_info_python.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_geodesy/spheroid.cc b/met/src/libcode/vx_geodesy/spheroid.cc index 377a5b746b..b0f196b146 100644 --- a/met/src/libcode/vx_geodesy/spheroid.cc +++ b/met/src/libcode/vx_geodesy/spheroid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_geodesy/spheroid.h b/met/src/libcode/vx_geodesy/spheroid.h index 311940ac24..d872ec197b 100644 --- a/met/src/libcode/vx_geodesy/spheroid.h +++ b/met/src/libcode/vx_geodesy/spheroid.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_geodesy/vx_geodesy.h b/met/src/libcode/vx_geodesy/vx_geodesy.h index fd01ed6f19..631b03660f 100644 --- a/met/src/libcode/vx_geodesy/vx_geodesy.h +++ b/met/src/libcode/vx_geodesy/vx_geodesy.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/dbf_file.cc b/met/src/libcode/vx_gis/dbf_file.cc index 174c356c5f..b20e998f3a 100644 --- a/met/src/libcode/vx_gis/dbf_file.cc +++ b/met/src/libcode/vx_gis/dbf_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/dbf_file.h b/met/src/libcode/vx_gis/dbf_file.h index 7e60e681e5..78fc40e73f 100644 --- a/met/src/libcode/vx_gis/dbf_file.h +++ b/met/src/libcode/vx_gis/dbf_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_array.h b/met/src/libcode/vx_gis/shp_array.h index bfeeba578b..06f6aaeb4a 100644 --- a/met/src/libcode/vx_gis/shp_array.h +++ b/met/src/libcode/vx_gis/shp_array.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_file.cc b/met/src/libcode/vx_gis/shp_file.cc index 1f311fce2a..72e37d93b3 100644 --- a/met/src/libcode/vx_gis/shp_file.cc +++ b/met/src/libcode/vx_gis/shp_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_file.h b/met/src/libcode/vx_gis/shp_file.h index 7a362d9e52..821f0145ce 100644 --- a/met/src/libcode/vx_gis/shp_file.h +++ b/met/src/libcode/vx_gis/shp_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_point_record.cc b/met/src/libcode/vx_gis/shp_point_record.cc index 6fde8fb74c..c5617dcb6a 100644 --- a/met/src/libcode/vx_gis/shp_point_record.cc +++ b/met/src/libcode/vx_gis/shp_point_record.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_point_record.h b/met/src/libcode/vx_gis/shp_point_record.h index e606f3f178..62e529f8d3 100644 --- a/met/src/libcode/vx_gis/shp_point_record.h +++ b/met/src/libcode/vx_gis/shp_point_record.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_poly_record.cc b/met/src/libcode/vx_gis/shp_poly_record.cc index b5876253ab..217dabc924 100644 --- a/met/src/libcode/vx_gis/shp_poly_record.cc +++ b/met/src/libcode/vx_gis/shp_poly_record.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_poly_record.h b/met/src/libcode/vx_gis/shp_poly_record.h index 18131cadaa..bccc220387 100644 --- a/met/src/libcode/vx_gis/shp_poly_record.h +++ b/met/src/libcode/vx_gis/shp_poly_record.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shp_types.h b/met/src/libcode/vx_gis/shp_types.h index d9e240ebe3..e109302cf4 100644 --- a/met/src/libcode/vx_gis/shp_types.h +++ b/met/src/libcode/vx_gis/shp_types.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shx_file.cc b/met/src/libcode/vx_gis/shx_file.cc index 1fec346dac..5674aa2dbf 100644 --- a/met/src/libcode/vx_gis/shx_file.cc +++ b/met/src/libcode/vx_gis/shx_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/shx_file.h b/met/src/libcode/vx_gis/shx_file.h index 43dab61c2b..b4d788183f 100644 --- a/met/src/libcode/vx_gis/shx_file.h +++ b/met/src/libcode/vx_gis/shx_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gis/vx_gis.h b/met/src/libcode/vx_gis/vx_gis.h index 40ade039ec..909c49de6d 100644 --- a/met/src/libcode/vx_gis/vx_gis.h +++ b/met/src/libcode/vx_gis/vx_gis.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gnomon/gnomon.cc b/met/src/libcode/vx_gnomon/gnomon.cc index 9a1305eaed..0de1658ec7 100644 --- a/met/src/libcode/vx_gnomon/gnomon.cc +++ b/met/src/libcode/vx_gnomon/gnomon.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research(UCAR) // ** National Center for Atmospheric Research(NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gnomon/gnomon.h b/met/src/libcode/vx_gnomon/gnomon.h index e413e6161c..81e280526a 100644 --- a/met/src/libcode/vx_gnomon/gnomon.h +++ b/met/src/libcode/vx_gnomon/gnomon.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research(UCAR) // ** National Center for Atmospheric Research(NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/earth_rotation.cc b/met/src/libcode/vx_grid/earth_rotation.cc index 9171175e75..186f643ace 100644 --- a/met/src/libcode/vx_grid/earth_rotation.cc +++ b/met/src/libcode/vx_grid/earth_rotation.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/earth_rotation.h b/met/src/libcode/vx_grid/earth_rotation.h index 3c95b3f4f9..482e578e1d 100644 --- a/met/src/libcode/vx_grid/earth_rotation.h +++ b/met/src/libcode/vx_grid/earth_rotation.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/find_grid_by_name.cc b/met/src/libcode/vx_grid/find_grid_by_name.cc index 06d5a1c374..57e5a3de2e 100644 --- a/met/src/libcode/vx_grid/find_grid_by_name.cc +++ b/met/src/libcode/vx_grid/find_grid_by_name.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/find_grid_by_name.h b/met/src/libcode/vx_grid/find_grid_by_name.h index 0281353f39..96be17247e 100644 --- a/met/src/libcode/vx_grid/find_grid_by_name.h +++ b/met/src/libcode/vx_grid/find_grid_by_name.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/gaussian_grid.cc b/met/src/libcode/vx_grid/gaussian_grid.cc index 61edbbb7f8..9c1be2ff25 100644 --- a/met/src/libcode/vx_grid/gaussian_grid.cc +++ b/met/src/libcode/vx_grid/gaussian_grid.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/gaussian_grid.h b/met/src/libcode/vx_grid/gaussian_grid.h index 1825f853e0..c45f7a6d06 100644 --- a/met/src/libcode/vx_grid/gaussian_grid.h +++ b/met/src/libcode/vx_grid/gaussian_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/gaussian_grid_defs.h b/met/src/libcode/vx_grid/gaussian_grid_defs.h index 6e97f544b5..38df1ce5c4 100644 --- a/met/src/libcode/vx_grid/gaussian_grid_defs.h +++ b/met/src/libcode/vx_grid/gaussian_grid_defs.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/goes_grid.cc b/met/src/libcode/vx_grid/goes_grid.cc index 71e6ff61d5..c6cd53cdaa 100644 --- a/met/src/libcode/vx_grid/goes_grid.cc +++ b/met/src/libcode/vx_grid/goes_grid.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/goes_grid.h b/met/src/libcode/vx_grid/goes_grid.h index 291428fa33..9be97d95bb 100644 --- a/met/src/libcode/vx_grid/goes_grid.h +++ b/met/src/libcode/vx_grid/goes_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/goes_grid_defs.h b/met/src/libcode/vx_grid/goes_grid_defs.h index e402b4cbd8..a6658f102c 100644 --- a/met/src/libcode/vx_grid/goes_grid_defs.h +++ b/met/src/libcode/vx_grid/goes_grid_defs.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/grid_base.cc b/met/src/libcode/vx_grid/grid_base.cc index ece0332ce1..34b84484e4 100644 --- a/met/src/libcode/vx_grid/grid_base.cc +++ b/met/src/libcode/vx_grid/grid_base.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/grid_base.h b/met/src/libcode/vx_grid/grid_base.h index 5a225f6275..4fdab9354e 100644 --- a/met/src/libcode/vx_grid/grid_base.h +++ b/met/src/libcode/vx_grid/grid_base.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/latlon_grid.cc b/met/src/libcode/vx_grid/latlon_grid.cc index 11e779cc66..585a490b03 100644 --- a/met/src/libcode/vx_grid/latlon_grid.cc +++ b/met/src/libcode/vx_grid/latlon_grid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/latlon_grid.h b/met/src/libcode/vx_grid/latlon_grid.h index 21c86d6e2c..3b2124ee8a 100644 --- a/met/src/libcode/vx_grid/latlon_grid.h +++ b/met/src/libcode/vx_grid/latlon_grid.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/latlon_grid_defs.h b/met/src/libcode/vx_grid/latlon_grid_defs.h index 8643686044..adb3d521ef 100644 --- a/met/src/libcode/vx_grid/latlon_grid_defs.h +++ b/met/src/libcode/vx_grid/latlon_grid_defs.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/latlon_xyz.cc b/met/src/libcode/vx_grid/latlon_xyz.cc index e1eae674da..6a9a4c6dd9 100644 --- a/met/src/libcode/vx_grid/latlon_xyz.cc +++ b/met/src/libcode/vx_grid/latlon_xyz.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/latlon_xyz.h b/met/src/libcode/vx_grid/latlon_xyz.h index a59e89324a..dd9adf24b9 100644 --- a/met/src/libcode/vx_grid/latlon_xyz.h +++ b/met/src/libcode/vx_grid/latlon_xyz.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/lc_grid.cc b/met/src/libcode/vx_grid/lc_grid.cc index 41a2e375e9..b4ea96393d 100644 --- a/met/src/libcode/vx_grid/lc_grid.cc +++ b/met/src/libcode/vx_grid/lc_grid.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/lc_grid.h b/met/src/libcode/vx_grid/lc_grid.h index 0b3fefdaaa..981b0cc80f 100644 --- a/met/src/libcode/vx_grid/lc_grid.h +++ b/met/src/libcode/vx_grid/lc_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/lc_grid_defs.h b/met/src/libcode/vx_grid/lc_grid_defs.h index 2fa028a86c..76fe934753 100644 --- a/met/src/libcode/vx_grid/lc_grid_defs.h +++ b/met/src/libcode/vx_grid/lc_grid_defs.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/merc_grid.cc b/met/src/libcode/vx_grid/merc_grid.cc index d89a7898e4..ac2f7c368b 100644 --- a/met/src/libcode/vx_grid/merc_grid.cc +++ b/met/src/libcode/vx_grid/merc_grid.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/merc_grid.h b/met/src/libcode/vx_grid/merc_grid.h index f46a9c3bf8..b4c22cf661 100644 --- a/met/src/libcode/vx_grid/merc_grid.h +++ b/met/src/libcode/vx_grid/merc_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/merc_grid_defs.h b/met/src/libcode/vx_grid/merc_grid_defs.h index a3c485556d..c3073c69de 100644 --- a/met/src/libcode/vx_grid/merc_grid_defs.h +++ b/met/src/libcode/vx_grid/merc_grid_defs.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/rot_latlon_grid.cc b/met/src/libcode/vx_grid/rot_latlon_grid.cc index 12b6286135..d13f9ac2cd 100644 --- a/met/src/libcode/vx_grid/rot_latlon_grid.cc +++ b/met/src/libcode/vx_grid/rot_latlon_grid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/rot_latlon_grid.h b/met/src/libcode/vx_grid/rot_latlon_grid.h index 79a75e1869..456b505dc1 100644 --- a/met/src/libcode/vx_grid/rot_latlon_grid.h +++ b/met/src/libcode/vx_grid/rot_latlon_grid.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/st_grid.cc b/met/src/libcode/vx_grid/st_grid.cc index 3b64e4a14d..5ed2ed9cf6 100644 --- a/met/src/libcode/vx_grid/st_grid.cc +++ b/met/src/libcode/vx_grid/st_grid.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/st_grid.h b/met/src/libcode/vx_grid/st_grid.h index 9fecdba445..c0d6b28a86 100644 --- a/met/src/libcode/vx_grid/st_grid.h +++ b/met/src/libcode/vx_grid/st_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/st_grid_defs.h b/met/src/libcode/vx_grid/st_grid_defs.h index daab0a0df8..66596de81a 100644 --- a/met/src/libcode/vx_grid/st_grid_defs.h +++ b/met/src/libcode/vx_grid/st_grid_defs.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/tcrmw_grid.cc b/met/src/libcode/vx_grid/tcrmw_grid.cc index f1f9b4d10c..ae01500ae3 100644 --- a/met/src/libcode/vx_grid/tcrmw_grid.cc +++ b/met/src/libcode/vx_grid/tcrmw_grid.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/tcrmw_grid.h b/met/src/libcode/vx_grid/tcrmw_grid.h index 9221838bae..4a535b041e 100644 --- a/met/src/libcode/vx_grid/tcrmw_grid.h +++ b/met/src/libcode/vx_grid/tcrmw_grid.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_grid/vx_grid.h b/met/src/libcode/vx_grid/vx_grid.h index 8f81a980ba..9eb152119b 100644 --- a/met/src/libcode/vx_grid/vx_grid.h +++ b/met/src/libcode/vx_grid/vx_grid.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_bvn.cc b/met/src/libcode/vx_gsl_prob/gsl_bvn.cc index 7fe3cc0fe4..dbfa7acef6 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_bvn.cc +++ b/met/src/libcode/vx_gsl_prob/gsl_bvn.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_bvn.h b/met/src/libcode/vx_gsl_prob/gsl_bvn.h index addff50eb4..cd12e86aa8 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_bvn.h +++ b/met/src/libcode/vx_gsl_prob/gsl_bvn.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_cdf.cc b/met/src/libcode/vx_gsl_prob/gsl_cdf.cc index 8d6ee16e0c..c393df481c 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_cdf.cc +++ b/met/src/libcode/vx_gsl_prob/gsl_cdf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_cdf.h b/met/src/libcode/vx_gsl_prob/gsl_cdf.h index 1fea3ada87..bdc57b7a18 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_cdf.h +++ b/met/src/libcode/vx_gsl_prob/gsl_cdf.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_randist.cc b/met/src/libcode/vx_gsl_prob/gsl_randist.cc index d03cc10f8d..fe5ef86330 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_randist.cc +++ b/met/src/libcode/vx_gsl_prob/gsl_randist.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_randist.h b/met/src/libcode/vx_gsl_prob/gsl_randist.h index 619e86199b..0feeaa4064 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_randist.h +++ b/met/src/libcode/vx_gsl_prob/gsl_randist.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_statistics.cc b/met/src/libcode/vx_gsl_prob/gsl_statistics.cc index 4d775903d6..031c47e372 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_statistics.cc +++ b/met/src/libcode/vx_gsl_prob/gsl_statistics.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_statistics.h b/met/src/libcode/vx_gsl_prob/gsl_statistics.h index 05600d8aa6..c4ab8ba951 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_statistics.h +++ b/met/src/libcode/vx_gsl_prob/gsl_statistics.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.cc b/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.cc index afa8fc3aa5..d2a6340fe5 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.cc +++ b/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.h b/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.h index 59aa9ea12f..d3d9bc98c4 100644 --- a/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.h +++ b/met/src/libcode/vx_gsl_prob/gsl_wavelet2d.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_gsl_prob/vx_gsl_prob.h b/met/src/libcode/vx_gsl_prob/vx_gsl_prob.h index 1b94e82ad7..5632c55fea 100644 --- a/met/src/libcode/vx_gsl_prob/vx_gsl_prob.h +++ b/met/src/libcode/vx_gsl_prob/vx_gsl_prob.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nav/nav.cc b/met/src/libcode/vx_nav/nav.cc index 6cc2056268..84cd3c7bac 100644 --- a/met/src/libcode/vx_nav/nav.cc +++ b/met/src/libcode/vx_nav/nav.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nav/nav.h b/met/src/libcode/vx_nav/nav.h index 67274110b7..ea1a623187 100644 --- a/met/src/libcode/vx_nav/nav.h +++ b/met/src/libcode/vx_nav/nav.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc index f223c4acff..8eb762b008 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.cc +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.h b/met/src/libcode/vx_nc_obs/met_point_data.h index 514322bfb6..a061d49741 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.h +++ b/met/src/libcode/vx_nc_obs/met_point_data.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.cc b/met/src/libcode/vx_nc_obs/nc_obs_util.cc index efab7d2384..42c14fd747 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.cc +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.h b/met/src/libcode/vx_nc_obs/nc_obs_util.h index d3d07f3007..b6d25bf1af 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.h +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs.cc b/met/src/libcode/vx_nc_obs/nc_point_obs.cc index 0869f3a31e..559693e462 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs.cc +++ b/met/src/libcode/vx_nc_obs/nc_point_obs.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs.h b/met/src/libcode/vx_nc_obs/nc_point_obs.h index 4d778d3443..4b957638f4 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs.h +++ b/met/src/libcode/vx_nc_obs/nc_point_obs.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc b/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc index 3a91441deb..8ae7c64d48 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc +++ b/met/src/libcode/vx_nc_obs/nc_point_obs_in.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs_in.h b/met/src/libcode/vx_nc_obs/nc_point_obs_in.h index aa55ebcd8f..105ef27e2a 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs_in.h +++ b/met/src/libcode/vx_nc_obs/nc_point_obs_in.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs_out.cc b/met/src/libcode/vx_nc_obs/nc_point_obs_out.cc index 69cc374dca..01b51e3717 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs_out.cc +++ b/met/src/libcode/vx_nc_obs/nc_point_obs_out.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_point_obs_out.h b/met/src/libcode/vx_nc_obs/nc_point_obs_out.h index 510aadd767..34ce1c5ebf 100644 --- a/met/src/libcode/vx_nc_obs/nc_point_obs_out.h +++ b/met/src/libcode/vx_nc_obs/nc_point_obs_out.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_summary.cc b/met/src/libcode/vx_nc_obs/nc_summary.cc index b7c2786027..2dba528bb0 100644 --- a/met/src/libcode/vx_nc_obs/nc_summary.cc +++ b/met/src/libcode/vx_nc_obs/nc_summary.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_obs/nc_summary.h b/met/src/libcode/vx_nc_obs/nc_summary.h index 3f42868ff4..7cebff8932 100644 --- a/met/src/libcode/vx_nc_obs/nc_summary.h +++ b/met/src/libcode/vx_nc_obs/nc_summary.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/grid_output.cc b/met/src/libcode/vx_nc_util/grid_output.cc index e66b6d6766..9912fc06e0 100644 --- a/met/src/libcode/vx_nc_util/grid_output.cc +++ b/met/src/libcode/vx_nc_util/grid_output.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/grid_output.h b/met/src/libcode/vx_nc_util/grid_output.h index 177dae5b53..b22d19fd11 100644 --- a/met/src/libcode/vx_nc_util/grid_output.h +++ b/met/src/libcode/vx_nc_util/grid_output.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/load_tc_data.cc b/met/src/libcode/vx_nc_util/load_tc_data.cc index ec764baf67..1a12e90f1a 100644 --- a/met/src/libcode/vx_nc_util/load_tc_data.cc +++ b/met/src/libcode/vx_nc_util/load_tc_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/load_tc_data.h b/met/src/libcode/vx_nc_util/load_tc_data.h index b6f0e59b45..b99dfea847 100644 --- a/met/src/libcode/vx_nc_util/load_tc_data.h +++ b/met/src/libcode/vx_nc_util/load_tc_data.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/nc_constants.h b/met/src/libcode/vx_nc_util/nc_constants.h index f1417ee916..7d77f0cb0d 100644 --- a/met/src/libcode/vx_nc_util/nc_constants.h +++ b/met/src/libcode/vx_nc_util/nc_constants.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/nc_utils.cc b/met/src/libcode/vx_nc_util/nc_utils.cc index 8d1505875d..8d8e5b1087 100644 --- a/met/src/libcode/vx_nc_util/nc_utils.cc +++ b/met/src/libcode/vx_nc_util/nc_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/nc_utils.h b/met/src/libcode/vx_nc_util/nc_utils.h index f1dec583e3..560ae06309 100644 --- a/met/src/libcode/vx_nc_util/nc_utils.h +++ b/met/src/libcode/vx_nc_util/nc_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/nc_var_info.cc b/met/src/libcode/vx_nc_util/nc_var_info.cc index 0cf01a5c8d..b8acf6228f 100644 --- a/met/src/libcode/vx_nc_util/nc_var_info.cc +++ b/met/src/libcode/vx_nc_util/nc_var_info.cc @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/nc_var_info.h b/met/src/libcode/vx_nc_util/nc_var_info.h index 8e59432f27..ba86dcd011 100644 --- a/met/src/libcode/vx_nc_util/nc_var_info.h +++ b/met/src/libcode/vx_nc_util/nc_var_info.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/vx_nc_util.h b/met/src/libcode/vx_nc_util/vx_nc_util.h index ee3878cdb7..7484828f97 100644 --- a/met/src/libcode/vx_nc_util/vx_nc_util.h +++ b/met/src/libcode/vx_nc_util/vx_nc_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/write_netcdf.cc b/met/src/libcode/vx_nc_util/write_netcdf.cc index 71d67342b7..6de9a43a9f 100644 --- a/met/src/libcode/vx_nc_util/write_netcdf.cc +++ b/met/src/libcode/vx_nc_util/write_netcdf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_nc_util/write_netcdf.h b/met/src/libcode/vx_nc_util/write_netcdf.h index fd4b3adb32..48d547c547 100644 --- a/met/src/libcode/vx_nc_util/write_netcdf.h +++ b/met/src/libcode/vx_nc_util/write_netcdf.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/copy_bytes.cc b/met/src/libcode/vx_pb_util/copy_bytes.cc index eb1655d60a..2a8d39d355 100644 --- a/met/src/libcode/vx_pb_util/copy_bytes.cc +++ b/met/src/libcode/vx_pb_util/copy_bytes.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/copy_bytes.h b/met/src/libcode/vx_pb_util/copy_bytes.h index 8a90f4bbd9..9b5f165939 100644 --- a/met/src/libcode/vx_pb_util/copy_bytes.h +++ b/met/src/libcode/vx_pb_util/copy_bytes.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/do_blocking.cc b/met/src/libcode/vx_pb_util/do_blocking.cc index 1e3d48d6dc..da006266ce 100644 --- a/met/src/libcode/vx_pb_util/do_blocking.cc +++ b/met/src/libcode/vx_pb_util/do_blocking.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/do_blocking.h b/met/src/libcode/vx_pb_util/do_blocking.h index 2eef4d2081..c26f6a52a7 100644 --- a/met/src/libcode/vx_pb_util/do_blocking.h +++ b/met/src/libcode/vx_pb_util/do_blocking.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/do_unblocking.cc b/met/src/libcode/vx_pb_util/do_unblocking.cc index 6e8b6b250f..509359c3ef 100644 --- a/met/src/libcode/vx_pb_util/do_unblocking.cc +++ b/met/src/libcode/vx_pb_util/do_unblocking.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/do_unblocking.h b/met/src/libcode/vx_pb_util/do_unblocking.h index 61359bee87..25e1f42882 100644 --- a/met/src/libcode/vx_pb_util/do_unblocking.h +++ b/met/src/libcode/vx_pb_util/do_unblocking.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/pblock.cc b/met/src/libcode/vx_pb_util/pblock.cc index 643dc06540..7dfcb5832b 100644 --- a/met/src/libcode/vx_pb_util/pblock.cc +++ b/met/src/libcode/vx_pb_util/pblock.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/pblock.h b/met/src/libcode/vx_pb_util/pblock.h index 7f7e83b1eb..d493adbab2 100644 --- a/met/src/libcode/vx_pb_util/pblock.h +++ b/met/src/libcode/vx_pb_util/pblock.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pb_util/vx_pb_util.h b/met/src/libcode/vx_pb_util/vx_pb_util.h index 5da853037e..20124f7cf3 100644 --- a/met/src/libcode/vx_pb_util/vx_pb_util.h +++ b/met/src/libcode/vx_pb_util/vx_pb_util.h @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////// // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_physics/thermo.cc b/met/src/libcode/vx_physics/thermo.cc index 93d6d61289..1dd99b2e33 100644 --- a/met/src/libcode/vx_physics/thermo.cc +++ b/met/src/libcode/vx_physics/thermo.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_physics/thermo.h b/met/src/libcode/vx_physics/thermo.h index 64ae2eda75..5d19480f71 100644 --- a/met/src/libcode/vx_physics/thermo.h +++ b/met/src/libcode/vx_physics/thermo.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_plot_util/data_plane_plot.cc b/met/src/libcode/vx_plot_util/data_plane_plot.cc index d5723c6455..132531c958 100644 --- a/met/src/libcode/vx_plot_util/data_plane_plot.cc +++ b/met/src/libcode/vx_plot_util/data_plane_plot.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_plot_util/data_plane_plot.h b/met/src/libcode/vx_plot_util/data_plane_plot.h index a6069a55e0..eaa5715730 100644 --- a/met/src/libcode/vx_plot_util/data_plane_plot.h +++ b/met/src/libcode/vx_plot_util/data_plane_plot.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_plot_util/map_region.cc b/met/src/libcode/vx_plot_util/map_region.cc index 0481e8787b..5c86739317 100644 --- a/met/src/libcode/vx_plot_util/map_region.cc +++ b/met/src/libcode/vx_plot_util/map_region.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_plot_util/map_region.h b/met/src/libcode/vx_plot_util/map_region.h index b7ee0e101a..b228642231 100644 --- a/met/src/libcode/vx_plot_util/map_region.h +++ b/met/src/libcode/vx_plot_util/map_region.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_plot_util/vx_plot_util.cc b/met/src/libcode/vx_plot_util/vx_plot_util.cc index fc6e54f22a..f072d761f4 100644 --- a/met/src/libcode/vx_plot_util/vx_plot_util.cc +++ b/met/src/libcode/vx_plot_util/vx_plot_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_plot_util/vx_plot_util.h b/met/src/libcode/vx_plot_util/vx_plot_util.h index c13aa3b1b4..066f57cd3e 100644 --- a/met/src/libcode/vx_plot_util/vx_plot_util.h +++ b/met/src/libcode/vx_plot_util/vx_plot_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc b/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc index b3d6cd84fe..fe02aba8eb 100644 --- a/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc +++ b/met/src/libcode/vx_pointdata_python/pointdata_from_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pointdata_python/pointdata_from_array.h b/met/src/libcode/vx_pointdata_python/pointdata_from_array.h index bec9380705..a68c40a83e 100644 --- a/met/src/libcode/vx_pointdata_python/pointdata_from_array.h +++ b/met/src/libcode/vx_pointdata_python/pointdata_from_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pointdata_python/pointdata_python.cc b/met/src/libcode/vx_pointdata_python/pointdata_python.cc index 316ec0dfc2..8fa505877f 100644 --- a/met/src/libcode/vx_pointdata_python/pointdata_python.cc +++ b/met/src/libcode/vx_pointdata_python/pointdata_python.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pointdata_python/pointdata_python.h b/met/src/libcode/vx_pointdata_python/pointdata_python.h index 22b32c7f52..b6d752ea3f 100644 --- a/met/src/libcode/vx_pointdata_python/pointdata_python.h +++ b/met/src/libcode/vx_pointdata_python/pointdata_python.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pointdata_python/python_pointdata.cc b/met/src/libcode/vx_pointdata_python/python_pointdata.cc index 43196acc5f..239e49d092 100644 --- a/met/src/libcode/vx_pointdata_python/python_pointdata.cc +++ b/met/src/libcode/vx_pointdata_python/python_pointdata.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pointdata_python/python_pointdata.h b/met/src/libcode/vx_pointdata_python/python_pointdata.h index 5be19111f0..54cd3ede9b 100644 --- a/met/src/libcode/vx_pointdata_python/python_pointdata.h +++ b/met/src/libcode/vx_pointdata_python/python_pointdata.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_ps/ps_text.cc b/met/src/libcode/vx_ps/ps_text.cc index f92305d78c..bce52870f1 100644 --- a/met/src/libcode/vx_ps/ps_text.cc +++ b/met/src/libcode/vx_ps/ps_text.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_ps/ps_text.h b/met/src/libcode/vx_ps/ps_text.h index efa376cfea..905fb11046 100644 --- a/met/src/libcode/vx_ps/ps_text.h +++ b/met/src/libcode/vx_ps/ps_text.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_ps/table_helper.cc b/met/src/libcode/vx_ps/table_helper.cc index f4dc483f89..4a95cfc1ac 100644 --- a/met/src/libcode/vx_ps/table_helper.cc +++ b/met/src/libcode/vx_ps/table_helper.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_ps/table_helper.h b/met/src/libcode/vx_ps/table_helper.h index d236dceca0..4d804c2686 100644 --- a/met/src/libcode/vx_ps/table_helper.h +++ b/met/src/libcode/vx_ps/table_helper.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_ps/vx_ps.cc b/met/src/libcode/vx_ps/vx_ps.cc index a2501ca1fa..5adde41c52 100644 --- a/met/src/libcode/vx_ps/vx_ps.cc +++ b/met/src/libcode/vx_ps/vx_ps.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_ps/vx_ps.h b/met/src/libcode/vx_ps/vx_ps.h index 28d4f92ccf..3cfeec731e 100644 --- a/met/src/libcode/vx_ps/vx_ps.h +++ b/met/src/libcode/vx_ps/vx_ps.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pbm.cc b/met/src/libcode/vx_pxm/pbm.cc index 7271fa570e..72d375ed6d 100644 --- a/met/src/libcode/vx_pxm/pbm.cc +++ b/met/src/libcode/vx_pxm/pbm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pbm.h b/met/src/libcode/vx_pxm/pbm.h index d24537a7fb..e9bac50a97 100644 --- a/met/src/libcode/vx_pxm/pbm.h +++ b/met/src/libcode/vx_pxm/pbm.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pcm.cc b/met/src/libcode/vx_pxm/pcm.cc index 299c931211..b1f13c1037 100644 --- a/met/src/libcode/vx_pxm/pcm.cc +++ b/met/src/libcode/vx_pxm/pcm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pcm.h b/met/src/libcode/vx_pxm/pcm.h index 3ef1f4968d..ecddb54d57 100644 --- a/met/src/libcode/vx_pxm/pcm.h +++ b/met/src/libcode/vx_pxm/pcm.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pgm.cc b/met/src/libcode/vx_pxm/pgm.cc index 17ae16aefb..a0f302d106 100644 --- a/met/src/libcode/vx_pxm/pgm.cc +++ b/met/src/libcode/vx_pxm/pgm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pgm.h b/met/src/libcode/vx_pxm/pgm.h index adf2481c1e..ece18d1f6e 100644 --- a/met/src/libcode/vx_pxm/pgm.h +++ b/met/src/libcode/vx_pxm/pgm.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/ppm.cc b/met/src/libcode/vx_pxm/ppm.cc index 9a33b4b28a..0d69531877 100644 --- a/met/src/libcode/vx_pxm/ppm.cc +++ b/met/src/libcode/vx_pxm/ppm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/ppm.h b/met/src/libcode/vx_pxm/ppm.h index e9c6d80975..00eb09aa37 100644 --- a/met/src/libcode/vx_pxm/ppm.h +++ b/met/src/libcode/vx_pxm/ppm.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pxm_base.cc b/met/src/libcode/vx_pxm/pxm_base.cc index 2a668bee88..86f4477459 100644 --- a/met/src/libcode/vx_pxm/pxm_base.cc +++ b/met/src/libcode/vx_pxm/pxm_base.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pxm_base.h b/met/src/libcode/vx_pxm/pxm_base.h index 59d5717a04..33abeb3726 100644 --- a/met/src/libcode/vx_pxm/pxm_base.h +++ b/met/src/libcode/vx_pxm/pxm_base.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pxm_utils.cc b/met/src/libcode/vx_pxm/pxm_utils.cc index 58640e2040..bd2812056a 100644 --- a/met/src/libcode/vx_pxm/pxm_utils.cc +++ b/met/src/libcode/vx_pxm/pxm_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/pxm_utils.h b/met/src/libcode/vx_pxm/pxm_utils.h index fee904887a..d3af27654d 100644 --- a/met/src/libcode/vx_pxm/pxm_utils.h +++ b/met/src/libcode/vx_pxm/pxm_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_pxm/vx_pxm.h b/met/src/libcode/vx_pxm/vx_pxm.h index d98c56d492..dfd2d19ecf 100644 --- a/met/src/libcode/vx_pxm/vx_pxm.h +++ b/met/src/libcode/vx_pxm/vx_pxm.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/global_python.h b/met/src/libcode/vx_python3_utils/global_python.h index 3459f27dda..ac796d5187 100644 --- a/met/src/libcode/vx_python3_utils/global_python.h +++ b/met/src/libcode/vx_python3_utils/global_python.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/python3_dict.cc b/met/src/libcode/vx_python3_utils/python3_dict.cc index e3fbcc4191..7f3750f58a 100644 --- a/met/src/libcode/vx_python3_utils/python3_dict.cc +++ b/met/src/libcode/vx_python3_utils/python3_dict.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/python3_dict.h b/met/src/libcode/vx_python3_utils/python3_dict.h index 1b747d183d..add18bfc3f 100644 --- a/met/src/libcode/vx_python3_utils/python3_dict.h +++ b/met/src/libcode/vx_python3_utils/python3_dict.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/python3_list.cc b/met/src/libcode/vx_python3_utils/python3_list.cc index 5a91bb92a9..082442cb3c 100644 --- a/met/src/libcode/vx_python3_utils/python3_list.cc +++ b/met/src/libcode/vx_python3_utils/python3_list.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/python3_list.h b/met/src/libcode/vx_python3_utils/python3_list.h index d502c09005..752cf71e9c 100644 --- a/met/src/libcode/vx_python3_utils/python3_list.h +++ b/met/src/libcode/vx_python3_utils/python3_list.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/wchar_argv.cc b/met/src/libcode/vx_python3_utils/wchar_argv.cc index 9a52363c5b..67c152cfd4 100644 --- a/met/src/libcode/vx_python3_utils/wchar_argv.cc +++ b/met/src/libcode/vx_python3_utils/wchar_argv.cc @@ -2,7 +2,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_python3_utils/wchar_argv.h b/met/src/libcode/vx_python3_utils/wchar_argv.h index a7fe2b42b0..c1834b6575 100644 --- a/met/src/libcode/vx_python3_utils/wchar_argv.h +++ b/met/src/libcode/vx_python3_utils/wchar_argv.h @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_regrid/vx_regrid.cc b/met/src/libcode/vx_regrid/vx_regrid.cc index 6be4189fa7..b21017813f 100644 --- a/met/src/libcode/vx_regrid/vx_regrid.cc +++ b/met/src/libcode/vx_regrid/vx_regrid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_regrid/vx_regrid.h b/met/src/libcode/vx_regrid/vx_regrid.h index 521b2d89c8..fa4caa3622 100644 --- a/met/src/libcode/vx_regrid/vx_regrid.h +++ b/met/src/libcode/vx_regrid/vx_regrid.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_regrid/vx_regrid_budget.cc b/met/src/libcode/vx_regrid/vx_regrid_budget.cc index 42157cb729..8b35a3b7b1 100644 --- a/met/src/libcode/vx_regrid/vx_regrid_budget.cc +++ b/met/src/libcode/vx_regrid/vx_regrid_budget.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/ascii85_filter.cc b/met/src/libcode/vx_render/ascii85_filter.cc index 2646ac7f0d..148b0cff09 100644 --- a/met/src/libcode/vx_render/ascii85_filter.cc +++ b/met/src/libcode/vx_render/ascii85_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/ascii85_filter.h b/met/src/libcode/vx_render/ascii85_filter.h index 85e650595d..5ee488fb76 100644 --- a/met/src/libcode/vx_render/ascii85_filter.h +++ b/met/src/libcode/vx_render/ascii85_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/bit_filter.cc b/met/src/libcode/vx_render/bit_filter.cc index f1d80dc6fc..291971706c 100644 --- a/met/src/libcode/vx_render/bit_filter.cc +++ b/met/src/libcode/vx_render/bit_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/bit_filter.h b/met/src/libcode/vx_render/bit_filter.h index 77ba44f78d..f060ac7f6e 100644 --- a/met/src/libcode/vx_render/bit_filter.h +++ b/met/src/libcode/vx_render/bit_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/flate_filter.cc b/met/src/libcode/vx_render/flate_filter.cc index 40272d3f0a..8dbcb66890 100644 --- a/met/src/libcode/vx_render/flate_filter.cc +++ b/met/src/libcode/vx_render/flate_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/flate_filter.h b/met/src/libcode/vx_render/flate_filter.h index 6d73cdc9f7..3c01ba5e81 100644 --- a/met/src/libcode/vx_render/flate_filter.h +++ b/met/src/libcode/vx_render/flate_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/hex_filter.cc b/met/src/libcode/vx_render/hex_filter.cc index 0e2bc10654..0a6c893a71 100644 --- a/met/src/libcode/vx_render/hex_filter.cc +++ b/met/src/libcode/vx_render/hex_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/hex_filter.h b/met/src/libcode/vx_render/hex_filter.h index 6f6965d099..6f796c205d 100644 --- a/met/src/libcode/vx_render/hex_filter.h +++ b/met/src/libcode/vx_render/hex_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/ps_filter.cc b/met/src/libcode/vx_render/ps_filter.cc index fe74d522a8..8078e8daa0 100644 --- a/met/src/libcode/vx_render/ps_filter.cc +++ b/met/src/libcode/vx_render/ps_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/ps_filter.h b/met/src/libcode/vx_render/ps_filter.h index 041a0f3aa8..23b3100de4 100644 --- a/met/src/libcode/vx_render/ps_filter.h +++ b/met/src/libcode/vx_render/ps_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/psout_filter.cc b/met/src/libcode/vx_render/psout_filter.cc index 45a043ad53..45709a276a 100644 --- a/met/src/libcode/vx_render/psout_filter.cc +++ b/met/src/libcode/vx_render/psout_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/psout_filter.h b/met/src/libcode/vx_render/psout_filter.h index 5ea36d2c17..00032e430f 100644 --- a/met/src/libcode/vx_render/psout_filter.h +++ b/met/src/libcode/vx_render/psout_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/render_pbm.cc b/met/src/libcode/vx_render/render_pbm.cc index 979c3bb12c..1643c3a93b 100644 --- a/met/src/libcode/vx_render/render_pbm.cc +++ b/met/src/libcode/vx_render/render_pbm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/render_pcm.cc b/met/src/libcode/vx_render/render_pcm.cc index eb8e82bb4b..14b6ef67cc 100644 --- a/met/src/libcode/vx_render/render_pcm.cc +++ b/met/src/libcode/vx_render/render_pcm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/render_pgm.cc b/met/src/libcode/vx_render/render_pgm.cc index 76f2d4a33e..a8e4ec93cf 100644 --- a/met/src/libcode/vx_render/render_pgm.cc +++ b/met/src/libcode/vx_render/render_pgm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/render_ppm.cc b/met/src/libcode/vx_render/render_ppm.cc index 20d9f2e1ad..b1a4f69eca 100644 --- a/met/src/libcode/vx_render/render_ppm.cc +++ b/met/src/libcode/vx_render/render_ppm.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/renderinfo.cc b/met/src/libcode/vx_render/renderinfo.cc index 2fe1b85537..ac17b265da 100644 --- a/met/src/libcode/vx_render/renderinfo.cc +++ b/met/src/libcode/vx_render/renderinfo.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/renderinfo.h b/met/src/libcode/vx_render/renderinfo.h index 27475473e8..b67b02885e 100644 --- a/met/src/libcode/vx_render/renderinfo.h +++ b/met/src/libcode/vx_render/renderinfo.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/rle_filter.cc b/met/src/libcode/vx_render/rle_filter.cc index 951c974d3a..32d28e8345 100644 --- a/met/src/libcode/vx_render/rle_filter.cc +++ b/met/src/libcode/vx_render/rle_filter.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/rle_filter.h b/met/src/libcode/vx_render/rle_filter.h index e941d122ce..ab7cb456a1 100644 --- a/met/src/libcode/vx_render/rle_filter.h +++ b/met/src/libcode/vx_render/rle_filter.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/uc_queue.cc b/met/src/libcode/vx_render/uc_queue.cc index f176ee5953..176e21d8bd 100644 --- a/met/src/libcode/vx_render/uc_queue.cc +++ b/met/src/libcode/vx_render/uc_queue.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/uc_queue.h b/met/src/libcode/vx_render/uc_queue.h index 7795c9d2d4..2166c8d0fd 100644 --- a/met/src/libcode/vx_render/uc_queue.h +++ b/met/src/libcode/vx_render/uc_queue.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_render/vx_render.h b/met/src/libcode/vx_render/vx_render.h index 1adb848cf2..f662e579a8 100644 --- a/met/src/libcode/vx_render/vx_render.h +++ b/met/src/libcode/vx_render/vx_render.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_series_data/series_data.cc b/met/src/libcode/vx_series_data/series_data.cc index 02ec7e79bf..079bb5aa3c 100644 --- a/met/src/libcode/vx_series_data/series_data.cc +++ b/met/src/libcode/vx_series_data/series_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_series_data/series_data.h b/met/src/libcode/vx_series_data/series_data.h index 90235519b6..c1551fd0ec 100644 --- a/met/src/libcode/vx_series_data/series_data.h +++ b/met/src/libcode/vx_series_data/series_data.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_series_data/series_pdf.cc b/met/src/libcode/vx_series_data/series_pdf.cc index 9e89cccb7f..446466ae22 100644 --- a/met/src/libcode/vx_series_data/series_pdf.cc +++ b/met/src/libcode/vx_series_data/series_pdf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_series_data/series_pdf.h b/met/src/libcode/vx_series_data/series_pdf.h index de0100c820..3d178ad7b1 100644 --- a/met/src/libcode/vx_series_data/series_pdf.h +++ b/met/src/libcode/vx_series_data/series_pdf.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/engine.cc b/met/src/libcode/vx_shapedata/engine.cc index cbb8974c96..a1ca40798e 100644 --- a/met/src/libcode/vx_shapedata/engine.cc +++ b/met/src/libcode/vx_shapedata/engine.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/engine.h b/met/src/libcode/vx_shapedata/engine.h index 41906284fd..9170265046 100644 --- a/met/src/libcode/vx_shapedata/engine.h +++ b/met/src/libcode/vx_shapedata/engine.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/interest.cc b/met/src/libcode/vx_shapedata/interest.cc index 2c42129b94..e3072a842d 100644 --- a/met/src/libcode/vx_shapedata/interest.cc +++ b/met/src/libcode/vx_shapedata/interest.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/interest.h b/met/src/libcode/vx_shapedata/interest.h index 80a38a7606..3bed46f2b5 100644 --- a/met/src/libcode/vx_shapedata/interest.h +++ b/met/src/libcode/vx_shapedata/interest.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/mode_columns.h b/met/src/libcode/vx_shapedata/mode_columns.h index f478579cba..b37a057b5e 100644 --- a/met/src/libcode/vx_shapedata/mode_columns.h +++ b/met/src/libcode/vx_shapedata/mode_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/mode_conf_info.cc b/met/src/libcode/vx_shapedata/mode_conf_info.cc index 06ac25c914..a145f9f6c4 100644 --- a/met/src/libcode/vx_shapedata/mode_conf_info.cc +++ b/met/src/libcode/vx_shapedata/mode_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/mode_conf_info.h b/met/src/libcode/vx_shapedata/mode_conf_info.h index 7521fad258..8e71a4f3c3 100644 --- a/met/src/libcode/vx_shapedata/mode_conf_info.h +++ b/met/src/libcode/vx_shapedata/mode_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/moments.cc b/met/src/libcode/vx_shapedata/moments.cc index ed7125beab..38bf662c4a 100644 --- a/met/src/libcode/vx_shapedata/moments.cc +++ b/met/src/libcode/vx_shapedata/moments.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/moments.h b/met/src/libcode/vx_shapedata/moments.h index f05ac292c4..ede2c1d565 100644 --- a/met/src/libcode/vx_shapedata/moments.h +++ b/met/src/libcode/vx_shapedata/moments.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/node.cc b/met/src/libcode/vx_shapedata/node.cc index 1174ded749..219b0a33e3 100644 --- a/met/src/libcode/vx_shapedata/node.cc +++ b/met/src/libcode/vx_shapedata/node.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/node.h b/met/src/libcode/vx_shapedata/node.h index 56089e1f1c..c7575f9ca0 100644 --- a/met/src/libcode/vx_shapedata/node.h +++ b/met/src/libcode/vx_shapedata/node.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/set.cc b/met/src/libcode/vx_shapedata/set.cc index 3f1fd4152b..882aa29bd0 100644 --- a/met/src/libcode/vx_shapedata/set.cc +++ b/met/src/libcode/vx_shapedata/set.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/set.h b/met/src/libcode/vx_shapedata/set.h index 4e73eb3082..5aa0fecb12 100644 --- a/met/src/libcode/vx_shapedata/set.h +++ b/met/src/libcode/vx_shapedata/set.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/shape.h b/met/src/libcode/vx_shapedata/shape.h index a78b28cdcd..7e6813c350 100644 --- a/met/src/libcode/vx_shapedata/shape.h +++ b/met/src/libcode/vx_shapedata/shape.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/shapedata.cc b/met/src/libcode/vx_shapedata/shapedata.cc index 7ecd485115..a86974f165 100644 --- a/met/src/libcode/vx_shapedata/shapedata.cc +++ b/met/src/libcode/vx_shapedata/shapedata.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/shapedata.h b/met/src/libcode/vx_shapedata/shapedata.h index c045e9971c..f4bd1e0332 100644 --- a/met/src/libcode/vx_shapedata/shapedata.h +++ b/met/src/libcode/vx_shapedata/shapedata.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/vx_shapedata.h b/met/src/libcode/vx_shapedata/vx_shapedata.h index 77ca27f1c7..1dbdeb58cc 100644 --- a/met/src/libcode/vx_shapedata/vx_shapedata.h +++ b/met/src/libcode/vx_shapedata/vx_shapedata.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_solar/astro_constants.h b/met/src/libcode/vx_solar/astro_constants.h index 53e53a8f7f..d2db13d750 100644 --- a/met/src/libcode/vx_solar/astro_constants.h +++ b/met/src/libcode/vx_solar/astro_constants.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_solar/siderial.cc b/met/src/libcode/vx_solar/siderial.cc index 4e528ca7c3..e850e3af1d 100644 --- a/met/src/libcode/vx_solar/siderial.cc +++ b/met/src/libcode/vx_solar/siderial.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_solar/siderial.h b/met/src/libcode/vx_solar/siderial.h index c2ee6ffed0..ad3f5ec628 100644 --- a/met/src/libcode/vx_solar/siderial.h +++ b/met/src/libcode/vx_solar/siderial.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_solar/solar.cc b/met/src/libcode/vx_solar/solar.cc index 283c71ec4f..cf7598161b 100644 --- a/met/src/libcode/vx_solar/solar.cc +++ b/met/src/libcode/vx_solar/solar.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_solar/solar.h b/met/src/libcode/vx_solar/solar.h index 052d3ffe69..63fbfd1c9d 100644 --- a/met/src/libcode/vx_solar/solar.h +++ b/met/src/libcode/vx_solar/solar.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_stat_out/stat_columns.cc b/met/src/libcode/vx_stat_out/stat_columns.cc index 39707d1e67..c09d6aab51 100644 --- a/met/src/libcode/vx_stat_out/stat_columns.cc +++ b/met/src/libcode/vx_stat_out/stat_columns.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_stat_out/stat_columns.h b/met/src/libcode/vx_stat_out/stat_columns.h index 96a3a0c5c4..1592d56587 100644 --- a/met/src/libcode/vx_stat_out/stat_columns.h +++ b/met/src/libcode/vx_stat_out/stat_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_stat_out/stat_hdr_columns.cc b/met/src/libcode/vx_stat_out/stat_hdr_columns.cc index 23ce8fe8f0..0238227d71 100644 --- a/met/src/libcode/vx_stat_out/stat_hdr_columns.cc +++ b/met/src/libcode/vx_stat_out/stat_hdr_columns.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_stat_out/stat_hdr_columns.h b/met/src/libcode/vx_stat_out/stat_hdr_columns.h index a7d8564d62..5f2b658199 100644 --- a/met/src/libcode/vx_stat_out/stat_hdr_columns.h +++ b/met/src/libcode/vx_stat_out/stat_hdr_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_stat_out/vx_stat_out.h b/met/src/libcode/vx_stat_out/vx_stat_out.h index 19800bb5ce..37e648ee2a 100644 --- a/met/src/libcode/vx_stat_out/vx_stat_out.h +++ b/met/src/libcode/vx_stat_out/vx_stat_out.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/apply_mask.cc b/met/src/libcode/vx_statistics/apply_mask.cc index 01d88f601e..670eec1a61 100644 --- a/met/src/libcode/vx_statistics/apply_mask.cc +++ b/met/src/libcode/vx_statistics/apply_mask.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/apply_mask.h b/met/src/libcode/vx_statistics/apply_mask.h index 5dcb6bd14c..762074929e 100644 --- a/met/src/libcode/vx_statistics/apply_mask.h +++ b/met/src/libcode/vx_statistics/apply_mask.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/compute_ci.cc b/met/src/libcode/vx_statistics/compute_ci.cc index c3dcd1ee7f..ad15d82ec4 100644 --- a/met/src/libcode/vx_statistics/compute_ci.cc +++ b/met/src/libcode/vx_statistics/compute_ci.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/compute_ci.h b/met/src/libcode/vx_statistics/compute_ci.h index ab3fa01977..4879b641dc 100644 --- a/met/src/libcode/vx_statistics/compute_ci.h +++ b/met/src/libcode/vx_statistics/compute_ci.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/compute_stats.cc b/met/src/libcode/vx_statistics/compute_stats.cc index 4938565694..a95c1c9335 100644 --- a/met/src/libcode/vx_statistics/compute_stats.cc +++ b/met/src/libcode/vx_statistics/compute_stats.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/compute_stats.h b/met/src/libcode/vx_statistics/compute_stats.h index 0536350cce..99885002f8 100644 --- a/met/src/libcode/vx_statistics/compute_stats.h +++ b/met/src/libcode/vx_statistics/compute_stats.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/contable.cc b/met/src/libcode/vx_statistics/contable.cc index 02f4f177a3..2232ea0bfa 100644 --- a/met/src/libcode/vx_statistics/contable.cc +++ b/met/src/libcode/vx_statistics/contable.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/contable.h b/met/src/libcode/vx_statistics/contable.h index c7b2602dd1..28689fa58a 100644 --- a/met/src/libcode/vx_statistics/contable.h +++ b/met/src/libcode/vx_statistics/contable.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/contable_nx2.cc b/met/src/libcode/vx_statistics/contable_nx2.cc index ab9b19922c..eb8e4da663 100644 --- a/met/src/libcode/vx_statistics/contable_nx2.cc +++ b/met/src/libcode/vx_statistics/contable_nx2.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/contable_stats.cc b/met/src/libcode/vx_statistics/contable_stats.cc index ab06b0bc6d..f33b5388f3 100644 --- a/met/src/libcode/vx_statistics/contable_stats.cc +++ b/met/src/libcode/vx_statistics/contable_stats.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/ens_stats.cc b/met/src/libcode/vx_statistics/ens_stats.cc index e69b74f786..4b273294a6 100644 --- a/met/src/libcode/vx_statistics/ens_stats.cc +++ b/met/src/libcode/vx_statistics/ens_stats.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/ens_stats.h b/met/src/libcode/vx_statistics/ens_stats.h index 987b172907..7220487f57 100644 --- a/met/src/libcode/vx_statistics/ens_stats.h +++ b/met/src/libcode/vx_statistics/ens_stats.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/grid_closed_poly.cc b/met/src/libcode/vx_statistics/grid_closed_poly.cc index e010cca11b..991b0cefb5 100644 --- a/met/src/libcode/vx_statistics/grid_closed_poly.cc +++ b/met/src/libcode/vx_statistics/grid_closed_poly.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/grid_closed_poly.h b/met/src/libcode/vx_statistics/grid_closed_poly.h index 0a5feeb50d..95b5c662ad 100644 --- a/met/src/libcode/vx_statistics/grid_closed_poly.h +++ b/met/src/libcode/vx_statistics/grid_closed_poly.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 3880ab204a..a5eae44574 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/met_stats.h b/met/src/libcode/vx_statistics/met_stats.h index 6648103f01..77a245c6f4 100644 --- a/met/src/libcode/vx_statistics/met_stats.h +++ b/met/src/libcode/vx_statistics/met_stats.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/obs_error.cc b/met/src/libcode/vx_statistics/obs_error.cc index 03b91b8cdb..da63cc94ae 100644 --- a/met/src/libcode/vx_statistics/obs_error.cc +++ b/met/src/libcode/vx_statistics/obs_error.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/obs_error.h b/met/src/libcode/vx_statistics/obs_error.h index e060aa4854..27bb488ffb 100644 --- a/met/src/libcode/vx_statistics/obs_error.h +++ b/met/src/libcode/vx_statistics/obs_error.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/pair_base.cc b/met/src/libcode/vx_statistics/pair_base.cc index 5a41f95d1b..e595631cd5 100644 --- a/met/src/libcode/vx_statistics/pair_base.cc +++ b/met/src/libcode/vx_statistics/pair_base.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/pair_base.h b/met/src/libcode/vx_statistics/pair_base.h index b07cae0155..984bfa690d 100644 --- a/met/src/libcode/vx_statistics/pair_base.h +++ b/met/src/libcode/vx_statistics/pair_base.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 7e1cd7daf5..c16551fdb7 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index 5f5fc71bc4..86ad381395 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/pair_data_point.cc b/met/src/libcode/vx_statistics/pair_data_point.cc index 2137ba6b77..e6366da500 100644 --- a/met/src/libcode/vx_statistics/pair_data_point.cc +++ b/met/src/libcode/vx_statistics/pair_data_point.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/pair_data_point.h b/met/src/libcode/vx_statistics/pair_data_point.h index 2621966299..a516e3e680 100644 --- a/met/src/libcode/vx_statistics/pair_data_point.h +++ b/met/src/libcode/vx_statistics/pair_data_point.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/read_climo.cc b/met/src/libcode/vx_statistics/read_climo.cc index af682ca973..57e5e575c2 100644 --- a/met/src/libcode/vx_statistics/read_climo.cc +++ b/met/src/libcode/vx_statistics/read_climo.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/read_climo.h b/met/src/libcode/vx_statistics/read_climo.h index f2fe419b23..0e7cbc002d 100644 --- a/met/src/libcode/vx_statistics/read_climo.h +++ b/met/src/libcode/vx_statistics/read_climo.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_statistics/vx_statistics.h b/met/src/libcode/vx_statistics/vx_statistics.h index 11c06f68e8..fb48850931 100644 --- a/met/src/libcode/vx_statistics/vx_statistics.h +++ b/met/src/libcode/vx_statistics/vx_statistics.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc.cc b/met/src/libcode/vx_summary/summary_calc.cc index 727c787549..0345d57caa 100644 --- a/met/src/libcode/vx_summary/summary_calc.cc +++ b/met/src/libcode/vx_summary/summary_calc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc.h b/met/src/libcode/vx_summary/summary_calc.h index 1779603445..ce40206295 100644 --- a/met/src/libcode/vx_summary/summary_calc.h +++ b/met/src/libcode/vx_summary/summary_calc.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_max.cc b/met/src/libcode/vx_summary/summary_calc_max.cc index 3e3d4d6b03..c78ec0138a 100644 --- a/met/src/libcode/vx_summary/summary_calc_max.cc +++ b/met/src/libcode/vx_summary/summary_calc_max.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_max.h b/met/src/libcode/vx_summary/summary_calc_max.h index 51d947a98c..cc22840b75 100644 --- a/met/src/libcode/vx_summary/summary_calc_max.h +++ b/met/src/libcode/vx_summary/summary_calc_max.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_mean.cc b/met/src/libcode/vx_summary/summary_calc_mean.cc index 3fbdece2cd..4bb3b6f16b 100644 --- a/met/src/libcode/vx_summary/summary_calc_mean.cc +++ b/met/src/libcode/vx_summary/summary_calc_mean.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_mean.h b/met/src/libcode/vx_summary/summary_calc_mean.h index 34373a3bed..166891f89a 100644 --- a/met/src/libcode/vx_summary/summary_calc_mean.h +++ b/met/src/libcode/vx_summary/summary_calc_mean.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_median.cc b/met/src/libcode/vx_summary/summary_calc_median.cc index b7e02a7a39..a055cd9f16 100644 --- a/met/src/libcode/vx_summary/summary_calc_median.cc +++ b/met/src/libcode/vx_summary/summary_calc_median.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_median.h b/met/src/libcode/vx_summary/summary_calc_median.h index 5a311796e3..7dadc8e0bc 100644 --- a/met/src/libcode/vx_summary/summary_calc_median.h +++ b/met/src/libcode/vx_summary/summary_calc_median.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_min.cc b/met/src/libcode/vx_summary/summary_calc_min.cc index f6f4f5d05b..eee8084d68 100644 --- a/met/src/libcode/vx_summary/summary_calc_min.cc +++ b/met/src/libcode/vx_summary/summary_calc_min.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_min.h b/met/src/libcode/vx_summary/summary_calc_min.h index 0c65405056..0031c1d999 100644 --- a/met/src/libcode/vx_summary/summary_calc_min.h +++ b/met/src/libcode/vx_summary/summary_calc_min.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_percentile.cc b/met/src/libcode/vx_summary/summary_calc_percentile.cc index 06386b326d..5ebc0ec5d2 100644 --- a/met/src/libcode/vx_summary/summary_calc_percentile.cc +++ b/met/src/libcode/vx_summary/summary_calc_percentile.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_percentile.h b/met/src/libcode/vx_summary/summary_calc_percentile.h index a3b21ba0da..6fbc0bf793 100644 --- a/met/src/libcode/vx_summary/summary_calc_percentile.h +++ b/met/src/libcode/vx_summary/summary_calc_percentile.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_range.cc b/met/src/libcode/vx_summary/summary_calc_range.cc index 4856fa1e2d..131cbd5bf5 100644 --- a/met/src/libcode/vx_summary/summary_calc_range.cc +++ b/met/src/libcode/vx_summary/summary_calc_range.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_range.h b/met/src/libcode/vx_summary/summary_calc_range.h index b155912b99..8e625b7374 100644 --- a/met/src/libcode/vx_summary/summary_calc_range.h +++ b/met/src/libcode/vx_summary/summary_calc_range.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_stdev.cc b/met/src/libcode/vx_summary/summary_calc_stdev.cc index ebe3489c38..b7387c4794 100644 --- a/met/src/libcode/vx_summary/summary_calc_stdev.cc +++ b/met/src/libcode/vx_summary/summary_calc_stdev.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_calc_stdev.h b/met/src/libcode/vx_summary/summary_calc_stdev.h index 6ee6bb3ed6..4d30552eaa 100644 --- a/met/src/libcode/vx_summary/summary_calc_stdev.h +++ b/met/src/libcode/vx_summary/summary_calc_stdev.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_key.cc b/met/src/libcode/vx_summary/summary_key.cc index 31a9fcf27d..7d26cd8282 100644 --- a/met/src/libcode/vx_summary/summary_key.cc +++ b/met/src/libcode/vx_summary/summary_key.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_key.h b/met/src/libcode/vx_summary/summary_key.h index fd6c76e514..6cd4d36e75 100644 --- a/met/src/libcode/vx_summary/summary_key.h +++ b/met/src/libcode/vx_summary/summary_key.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_obs.cc b/met/src/libcode/vx_summary/summary_obs.cc index b1b9c74701..799c72f6b7 100644 --- a/met/src/libcode/vx_summary/summary_obs.cc +++ b/met/src/libcode/vx_summary/summary_obs.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/summary_obs.h b/met/src/libcode/vx_summary/summary_obs.h index 65da966e43..67b2aa353f 100644 --- a/met/src/libcode/vx_summary/summary_obs.h +++ b/met/src/libcode/vx_summary/summary_obs.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/time_summary_interval.cc b/met/src/libcode/vx_summary/time_summary_interval.cc index 2bee215b92..8f6e4d6dd6 100644 --- a/met/src/libcode/vx_summary/time_summary_interval.cc +++ b/met/src/libcode/vx_summary/time_summary_interval.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/time_summary_interval.h b/met/src/libcode/vx_summary/time_summary_interval.h index 74dfd22d1e..f3da9f2109 100644 --- a/met/src/libcode/vx_summary/time_summary_interval.h +++ b/met/src/libcode/vx_summary/time_summary_interval.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_summary/vx_summary.h b/met/src/libcode/vx_summary/vx_summary.h index 429d3dc45d..894d1adde7 100644 --- a/met/src/libcode/vx_summary/vx_summary.h +++ b/met/src/libcode/vx_summary/vx_summary.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_line_base.cc b/met/src/libcode/vx_tc_util/atcf_line_base.cc index 2f35ed9e49..71cb13e2c2 100644 --- a/met/src/libcode/vx_tc_util/atcf_line_base.cc +++ b/met/src/libcode/vx_tc_util/atcf_line_base.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_line_base.h b/met/src/libcode/vx_tc_util/atcf_line_base.h index 313c294e54..000b267d04 100644 --- a/met/src/libcode/vx_tc_util/atcf_line_base.h +++ b/met/src/libcode/vx_tc_util/atcf_line_base.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_offsets.h b/met/src/libcode/vx_tc_util/atcf_offsets.h index 01ed25d5cb..cf21a94a17 100644 --- a/met/src/libcode/vx_tc_util/atcf_offsets.h +++ b/met/src/libcode/vx_tc_util/atcf_offsets.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_prob_line.cc b/met/src/libcode/vx_tc_util/atcf_prob_line.cc index cb4735bbce..ccf413dba9 100644 --- a/met/src/libcode/vx_tc_util/atcf_prob_line.cc +++ b/met/src/libcode/vx_tc_util/atcf_prob_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_prob_line.h b/met/src/libcode/vx_tc_util/atcf_prob_line.h index 6e421c2d99..9dcb426b5b 100644 --- a/met/src/libcode/vx_tc_util/atcf_prob_line.h +++ b/met/src/libcode/vx_tc_util/atcf_prob_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_track_line.cc b/met/src/libcode/vx_tc_util/atcf_track_line.cc index 49c0aad310..1ef1de1c29 100644 --- a/met/src/libcode/vx_tc_util/atcf_track_line.cc +++ b/met/src/libcode/vx_tc_util/atcf_track_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/atcf_track_line.h b/met/src/libcode/vx_tc_util/atcf_track_line.h index f548fa1735..1e93f4e6c6 100644 --- a/met/src/libcode/vx_tc_util/atcf_track_line.h +++ b/met/src/libcode/vx_tc_util/atcf_track_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/gen_shape_info.cc b/met/src/libcode/vx_tc_util/gen_shape_info.cc index f51b92c4e7..3622639d73 100644 --- a/met/src/libcode/vx_tc_util/gen_shape_info.cc +++ b/met/src/libcode/vx_tc_util/gen_shape_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/gen_shape_info.h b/met/src/libcode/vx_tc_util/gen_shape_info.h index 4222a7de87..98a49e1973 100644 --- a/met/src/libcode/vx_tc_util/gen_shape_info.h +++ b/met/src/libcode/vx_tc_util/gen_shape_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/genesis_info.cc b/met/src/libcode/vx_tc_util/genesis_info.cc index 0000d93b8a..bfe13c0fdc 100644 --- a/met/src/libcode/vx_tc_util/genesis_info.cc +++ b/met/src/libcode/vx_tc_util/genesis_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/genesis_info.h b/met/src/libcode/vx_tc_util/genesis_info.h index 5caa835e51..c203334c3d 100644 --- a/met/src/libcode/vx_tc_util/genesis_info.h +++ b/met/src/libcode/vx_tc_util/genesis_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/pair_data_genesis.cc b/met/src/libcode/vx_tc_util/pair_data_genesis.cc index d10b809c58..2b3e5f07b7 100644 --- a/met/src/libcode/vx_tc_util/pair_data_genesis.cc +++ b/met/src/libcode/vx_tc_util/pair_data_genesis.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/pair_data_genesis.h b/met/src/libcode/vx_tc_util/pair_data_genesis.h index 0f0473d53a..12949ec790 100644 --- a/met/src/libcode/vx_tc_util/pair_data_genesis.h +++ b/met/src/libcode/vx_tc_util/pair_data_genesis.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_gen_info.cc b/met/src/libcode/vx_tc_util/prob_gen_info.cc index c0db7ce9fb..365471e0c0 100644 --- a/met/src/libcode/vx_tc_util/prob_gen_info.cc +++ b/met/src/libcode/vx_tc_util/prob_gen_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_gen_info.h b/met/src/libcode/vx_tc_util/prob_gen_info.h index af97bb03fa..0fa15defc8 100644 --- a/met/src/libcode/vx_tc_util/prob_gen_info.h +++ b/met/src/libcode/vx_tc_util/prob_gen_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_info_array.cc b/met/src/libcode/vx_tc_util/prob_info_array.cc index 64809049ec..34419b3f14 100644 --- a/met/src/libcode/vx_tc_util/prob_info_array.cc +++ b/met/src/libcode/vx_tc_util/prob_info_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_info_array.h b/met/src/libcode/vx_tc_util/prob_info_array.h index 881cf3dcfb..e0ea6230e9 100644 --- a/met/src/libcode/vx_tc_util/prob_info_array.h +++ b/met/src/libcode/vx_tc_util/prob_info_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_info_base.cc b/met/src/libcode/vx_tc_util/prob_info_base.cc index fb4147226c..8ee9caf537 100644 --- a/met/src/libcode/vx_tc_util/prob_info_base.cc +++ b/met/src/libcode/vx_tc_util/prob_info_base.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_info_base.h b/met/src/libcode/vx_tc_util/prob_info_base.h index fff06def24..015563e9e5 100644 --- a/met/src/libcode/vx_tc_util/prob_info_base.h +++ b/met/src/libcode/vx_tc_util/prob_info_base.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_pair_info.cc b/met/src/libcode/vx_tc_util/prob_pair_info.cc index 3415f040d2..8a2141e1ff 100644 --- a/met/src/libcode/vx_tc_util/prob_pair_info.cc +++ b/met/src/libcode/vx_tc_util/prob_pair_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_pair_info.h b/met/src/libcode/vx_tc_util/prob_pair_info.h index 3bb29586ed..3ad65cd811 100644 --- a/met/src/libcode/vx_tc_util/prob_pair_info.h +++ b/met/src/libcode/vx_tc_util/prob_pair_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_rirw_info.cc b/met/src/libcode/vx_tc_util/prob_rirw_info.cc index 7799e591d3..93b484682e 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_info.cc +++ b/met/src/libcode/vx_tc_util/prob_rirw_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_rirw_info.h b/met/src/libcode/vx_tc_util/prob_rirw_info.h index 2f04fc4baf..b1034eb00a 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_info.h +++ b/met/src/libcode/vx_tc_util/prob_rirw_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc b/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc index ce38bdfe97..1e4cd9866a 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc +++ b/met/src/libcode/vx_tc_util/prob_rirw_pair_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/prob_rirw_pair_info.h b/met/src/libcode/vx_tc_util/prob_rirw_pair_info.h index 69e1e29835..977c07c67c 100644 --- a/met/src/libcode/vx_tc_util/prob_rirw_pair_info.h +++ b/met/src/libcode/vx_tc_util/prob_rirw_pair_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/tc_columns.cc b/met/src/libcode/vx_tc_util/tc_columns.cc index f3f9eea17e..1c71d754ff 100644 --- a/met/src/libcode/vx_tc_util/tc_columns.cc +++ b/met/src/libcode/vx_tc_util/tc_columns.cc @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////// // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/tc_columns.h b/met/src/libcode/vx_tc_util/tc_columns.h index fe091fc296..5241d92997 100644 --- a/met/src/libcode/vx_tc_util/tc_columns.h +++ b/met/src/libcode/vx_tc_util/tc_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/tc_hdr_columns.cc b/met/src/libcode/vx_tc_util/tc_hdr_columns.cc index c001395d77..34c8388957 100644 --- a/met/src/libcode/vx_tc_util/tc_hdr_columns.cc +++ b/met/src/libcode/vx_tc_util/tc_hdr_columns.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/tc_hdr_columns.h b/met/src/libcode/vx_tc_util/tc_hdr_columns.h index 1d8408cb07..fce5e39260 100644 --- a/met/src/libcode/vx_tc_util/tc_hdr_columns.h +++ b/met/src/libcode/vx_tc_util/tc_hdr_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/tc_stat_line.cc b/met/src/libcode/vx_tc_util/tc_stat_line.cc index f57d4c01ad..c3ef71f08b 100644 --- a/met/src/libcode/vx_tc_util/tc_stat_line.cc +++ b/met/src/libcode/vx_tc_util/tc_stat_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/tc_stat_line.h b/met/src/libcode/vx_tc_util/tc_stat_line.h index 26fd11eff2..771455c292 100644 --- a/met/src/libcode/vx_tc_util/tc_stat_line.h +++ b/met/src/libcode/vx_tc_util/tc_stat_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/track_info.cc b/met/src/libcode/vx_tc_util/track_info.cc index 3566077b9b..4a4c34900c 100644 --- a/met/src/libcode/vx_tc_util/track_info.cc +++ b/met/src/libcode/vx_tc_util/track_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/track_info.h b/met/src/libcode/vx_tc_util/track_info.h index 75e7390f69..73b3317bf6 100644 --- a/met/src/libcode/vx_tc_util/track_info.h +++ b/met/src/libcode/vx_tc_util/track_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/track_pair_info.cc b/met/src/libcode/vx_tc_util/track_pair_info.cc index 5a03a9c0fc..bc013b6821 100644 --- a/met/src/libcode/vx_tc_util/track_pair_info.cc +++ b/met/src/libcode/vx_tc_util/track_pair_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/track_pair_info.h b/met/src/libcode/vx_tc_util/track_pair_info.h index 9bbd8fbb44..6afa9b6437 100644 --- a/met/src/libcode/vx_tc_util/track_pair_info.h +++ b/met/src/libcode/vx_tc_util/track_pair_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/track_point.cc b/met/src/libcode/vx_tc_util/track_point.cc index c3ae422777..1d0004a5b4 100644 --- a/met/src/libcode/vx_tc_util/track_point.cc +++ b/met/src/libcode/vx_tc_util/track_point.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/track_point.h b/met/src/libcode/vx_tc_util/track_point.h index 147c13cfd9..93908858af 100644 --- a/met/src/libcode/vx_tc_util/track_point.h +++ b/met/src/libcode/vx_tc_util/track_point.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc b/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc index 40a6feedc1..fb72b127d5 100644 --- a/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc +++ b/met/src/libcode/vx_tc_util/vx_tc_nc_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/vx_tc_nc_util.h b/met/src/libcode/vx_tc_util/vx_tc_nc_util.h index 9f9ad259d9..8f4bae8387 100644 --- a/met/src/libcode/vx_tc_util/vx_tc_nc_util.h +++ b/met/src/libcode/vx_tc_util/vx_tc_nc_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_tc_util/vx_tc_util.h b/met/src/libcode/vx_tc_util/vx_tc_util.h index 89a4434432..f0c1825cf2 100644 --- a/met/src/libcode/vx_tc_util/vx_tc_util.h +++ b/met/src/libcode/vx_tc_util/vx_tc_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_time_series/compute_swinging_door.cc b/met/src/libcode/vx_time_series/compute_swinging_door.cc index 20330ae837..ab937024af 100644 --- a/met/src/libcode/vx_time_series/compute_swinging_door.cc +++ b/met/src/libcode/vx_time_series/compute_swinging_door.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_time_series/compute_swinging_door.h b/met/src/libcode/vx_time_series/compute_swinging_door.h index 9b48fec68e..9c990fe231 100644 --- a/met/src/libcode/vx_time_series/compute_swinging_door.h +++ b/met/src/libcode/vx_time_series/compute_swinging_door.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_time_series/time_series_util.cc b/met/src/libcode/vx_time_series/time_series_util.cc index 9206598cea..e8ea5bf6b2 100644 --- a/met/src/libcode/vx_time_series/time_series_util.cc +++ b/met/src/libcode/vx_time_series/time_series_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_time_series/time_series_util.h b/met/src/libcode/vx_time_series/time_series_util.h index 41a681b058..76e616b7ff 100644 --- a/met/src/libcode/vx_time_series/time_series_util.h +++ b/met/src/libcode/vx_time_series/time_series_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_time_series/vx_time_series.h b/met/src/libcode/vx_time_series/vx_time_series.h index e440328ced..72ea68824f 100644 --- a/met/src/libcode/vx_time_series/vx_time_series.h +++ b/met/src/libcode/vx_time_series/vx_time_series.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index f1dfa27e36..078c547e8a 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.h b/met/src/tools/core/ensemble_stat/ensemble_stat.h index 482c0dfceb..e17beed66e 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index f6e5a1a9f1..e9aa6a2765 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h index 879fa04e95..ef20e3b8cc 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 8549cbf2e8..fbbdfbc773 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/grid_stat/grid_stat.h b/met/src/tools/core/grid_stat/grid_stat.h index 2e872d0d36..04f694fa96 100644 --- a/met/src/tools/core/grid_stat/grid_stat.h +++ b/met/src/tools/core/grid_stat/grid_stat.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/grid_stat/grid_stat_conf_info.cc b/met/src/tools/core/grid_stat/grid_stat_conf_info.cc index 96a68fe653..f0c31c115f 100644 --- a/met/src/tools/core/grid_stat/grid_stat_conf_info.cc +++ b/met/src/tools/core/grid_stat/grid_stat_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/grid_stat/grid_stat_conf_info.h b/met/src/tools/core/grid_stat/grid_stat_conf_info.h index 73bc476124..1042e9857d 100644 --- a/met/src/tools/core/grid_stat/grid_stat_conf_info.h +++ b/met/src/tools/core/grid_stat/grid_stat_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/cluster_page.cc b/met/src/tools/core/mode/cluster_page.cc index b295da4b6c..1c9dc32b3a 100644 --- a/met/src/tools/core/mode/cluster_page.cc +++ b/met/src/tools/core/mode/cluster_page.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/fcst_enlarge_page.cc b/met/src/tools/core/mode/fcst_enlarge_page.cc index 6713cc5628..1b9431dcae 100644 --- a/met/src/tools/core/mode/fcst_enlarge_page.cc +++ b/met/src/tools/core/mode/fcst_enlarge_page.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode.cc b/met/src/tools/core/mode/mode.cc index 1c3e5f67c7..241c5b052d 100644 --- a/met/src/tools/core/mode/mode.cc +++ b/met/src/tools/core/mode/mode.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_exec.cc b/met/src/tools/core/mode/mode_exec.cc index f0d77012f5..5dcea6e251 100644 --- a/met/src/tools/core/mode/mode_exec.cc +++ b/met/src/tools/core/mode/mode_exec.cc @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////// -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_exec.h b/met/src/tools/core/mode/mode_exec.h index 5f93f51e2f..ee20a83795 100644 --- a/met/src/tools/core/mode/mode_exec.h +++ b/met/src/tools/core/mode/mode_exec.h @@ -3,7 +3,7 @@ //////////////////////////////////////////////////////////////////////// -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_ps_file.cc b/met/src/tools/core/mode/mode_ps_file.cc index c36bd746b1..70d20fd575 100644 --- a/met/src/tools/core/mode/mode_ps_file.cc +++ b/met/src/tools/core/mode/mode_ps_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_ps_file.h b/met/src/tools/core/mode/mode_ps_file.h index 251cc814de..92749b9b46 100644 --- a/met/src/tools/core/mode/mode_ps_file.h +++ b/met/src/tools/core/mode/mode_ps_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_ps_table_defs.h b/met/src/tools/core/mode/mode_ps_table_defs.h index 8215625e62..e60f90d764 100644 --- a/met/src/tools/core/mode/mode_ps_table_defs.h +++ b/met/src/tools/core/mode/mode_ps_table_defs.h @@ -3,7 +3,7 @@ //////////////////////////////////////////////////////////////////////// -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/obs_enlarge_page.cc b/met/src/tools/core/mode/obs_enlarge_page.cc index dd2061d0c5..a28b8188a5 100644 --- a/met/src/tools/core/mode/obs_enlarge_page.cc +++ b/met/src/tools/core/mode/obs_enlarge_page.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/overlap_page.cc b/met/src/tools/core/mode/overlap_page.cc index 1222788c47..b2216a6840 100644 --- a/met/src/tools/core/mode/overlap_page.cc +++ b/met/src/tools/core/mode/overlap_page.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/page_1.cc b/met/src/tools/core/mode/page_1.cc index 09ae0ca2da..4d1d23e636 100644 --- a/met/src/tools/core/mode/page_1.cc +++ b/met/src/tools/core/mode/page_1.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/plot_engine.cc b/met/src/tools/core/mode/plot_engine.cc index ca78825ba5..c8e72cfd78 100644 --- a/met/src/tools/core/mode/plot_engine.cc +++ b/met/src/tools/core/mode/plot_engine.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode_analysis/config_to_att.cc b/met/src/tools/core/mode_analysis/config_to_att.cc index 6df08525c8..d2233d6f5d 100644 --- a/met/src/tools/core/mode_analysis/config_to_att.cc +++ b/met/src/tools/core/mode_analysis/config_to_att.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode_analysis/config_to_att.h b/met/src/tools/core/mode_analysis/config_to_att.h index a909c647e6..332282097f 100644 --- a/met/src/tools/core/mode_analysis/config_to_att.h +++ b/met/src/tools/core/mode_analysis/config_to_att.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode_analysis/mode_analysis.cc b/met/src/tools/core/mode_analysis/mode_analysis.cc index 1debd48121..4159138653 100644 --- a/met/src/tools/core/mode_analysis/mode_analysis.cc +++ b/met/src/tools/core/mode_analysis/mode_analysis.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/pcp_combine/pcp_combine.cc b/met/src/tools/core/pcp_combine/pcp_combine.cc index 56d24002b5..5be8ea838e 100644 --- a/met/src/tools/core/pcp_combine/pcp_combine.cc +++ b/met/src/tools/core/pcp_combine/pcp_combine.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 11a88e0391..0bf1b5fe0c 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research led(UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/point_stat/point_stat.h b/met/src/tools/core/point_stat/point_stat.h index 9b2b823d2a..72651ede4f 100644 --- a/met/src/tools/core/point_stat/point_stat.h +++ b/met/src/tools/core/point_stat/point_stat.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/point_stat/point_stat_conf_info.cc b/met/src/tools/core/point_stat/point_stat_conf_info.cc index 8b90544b44..2d639a20d6 100644 --- a/met/src/tools/core/point_stat/point_stat_conf_info.cc +++ b/met/src/tools/core/point_stat/point_stat_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/point_stat/point_stat_conf_info.h b/met/src/tools/core/point_stat/point_stat_conf_info.h index 5bc964069d..c846cb6365 100644 --- a/met/src/tools/core/point_stat/point_stat_conf_info.h +++ b/met/src/tools/core/point_stat/point_stat_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/series_analysis/series_analysis.cc b/met/src/tools/core/series_analysis/series_analysis.cc index b7f9aa01b9..6a33eefd73 100644 --- a/met/src/tools/core/series_analysis/series_analysis.cc +++ b/met/src/tools/core/series_analysis/series_analysis.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/series_analysis/series_analysis.h b/met/src/tools/core/series_analysis/series_analysis.h index 3dc9618304..fe8e48a948 100644 --- a/met/src/tools/core/series_analysis/series_analysis.h +++ b/met/src/tools/core/series_analysis/series_analysis.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/series_analysis/series_analysis_conf_info.cc b/met/src/tools/core/series_analysis/series_analysis_conf_info.cc index 5fa6608650..b3aa331840 100644 --- a/met/src/tools/core/series_analysis/series_analysis_conf_info.cc +++ b/met/src/tools/core/series_analysis/series_analysis_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/series_analysis/series_analysis_conf_info.h b/met/src/tools/core/series_analysis/series_analysis_conf_info.h index f0cd829eed..92f9cabd75 100644 --- a/met/src/tools/core/series_analysis/series_analysis_conf_info.h +++ b/met/src/tools/core/series_analysis/series_analysis_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/aggr_stat_line.cc b/met/src/tools/core/stat_analysis/aggr_stat_line.cc index edee31714d..5cfcb263f2 100644 --- a/met/src/tools/core/stat_analysis/aggr_stat_line.cc +++ b/met/src/tools/core/stat_analysis/aggr_stat_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/aggr_stat_line.h b/met/src/tools/core/stat_analysis/aggr_stat_line.h index 835d201005..86a1e771d5 100644 --- a/met/src/tools/core/stat_analysis/aggr_stat_line.h +++ b/met/src/tools/core/stat_analysis/aggr_stat_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/parse_stat_line.cc b/met/src/tools/core/stat_analysis/parse_stat_line.cc index c62180d9f9..2a5ff8d0d5 100644 --- a/met/src/tools/core/stat_analysis/parse_stat_line.cc +++ b/met/src/tools/core/stat_analysis/parse_stat_line.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/parse_stat_line.h b/met/src/tools/core/stat_analysis/parse_stat_line.h index 74f1ee3cd6..eed5c91eb8 100644 --- a/met/src/tools/core/stat_analysis/parse_stat_line.h +++ b/met/src/tools/core/stat_analysis/parse_stat_line.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/skill_score_index_job.cc b/met/src/tools/core/stat_analysis/skill_score_index_job.cc index 0c9313b806..08ccef0c9e 100644 --- a/met/src/tools/core/stat_analysis/skill_score_index_job.cc +++ b/met/src/tools/core/stat_analysis/skill_score_index_job.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/skill_score_index_job.h b/met/src/tools/core/stat_analysis/skill_score_index_job.h index 60d2350171..74f2a33e0e 100644 --- a/met/src/tools/core/stat_analysis/skill_score_index_job.h +++ b/met/src/tools/core/stat_analysis/skill_score_index_job.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/stat_analysis.cc b/met/src/tools/core/stat_analysis/stat_analysis.cc index cf01244178..b90c2b7bae 100644 --- a/met/src/tools/core/stat_analysis/stat_analysis.cc +++ b/met/src/tools/core/stat_analysis/stat_analysis.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/stat_analysis.h b/met/src/tools/core/stat_analysis/stat_analysis.h index bd70bb19b9..4c9f461139 100644 --- a/met/src/tools/core/stat_analysis/stat_analysis.h +++ b/met/src/tools/core/stat_analysis/stat_analysis.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/stat_analysis_job.cc b/met/src/tools/core/stat_analysis/stat_analysis_job.cc index 97f44df33f..ca2e2824fc 100644 --- a/met/src/tools/core/stat_analysis/stat_analysis_job.cc +++ b/met/src/tools/core/stat_analysis/stat_analysis_job.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/stat_analysis/stat_analysis_job.h b/met/src/tools/core/stat_analysis/stat_analysis_job.h index 5f67470758..9235af7da3 100644 --- a/met/src/tools/core/stat_analysis/stat_analysis_job.h +++ b/met/src/tools/core/stat_analysis/stat_analysis_job.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/wavelet_stat/wavelet_stat.cc b/met/src/tools/core/wavelet_stat/wavelet_stat.cc index c2dbc61635..db93f4f3bd 100644 --- a/met/src/tools/core/wavelet_stat/wavelet_stat.cc +++ b/met/src/tools/core/wavelet_stat/wavelet_stat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/wavelet_stat/wavelet_stat.h b/met/src/tools/core/wavelet_stat/wavelet_stat.h index ab807cc9a7..c27548cae6 100644 --- a/met/src/tools/core/wavelet_stat/wavelet_stat.h +++ b/met/src/tools/core/wavelet_stat/wavelet_stat.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.cc b/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.cc index b8a8a8c774..a614c0bdb5 100644 --- a/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.cc +++ b/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.h b/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.h index 8b1473572b..2782e30c32 100644 --- a/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.h +++ b/met/src/tools/core/wavelet_stat/wavelet_stat_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/chk4copyright.cc b/met/src/tools/dev_utils/chk4copyright.cc index ecae014bb8..8d44d1b373 100644 --- a/met/src/tools/dev_utils/chk4copyright.cc +++ b/met/src/tools/dev_utils/chk4copyright.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/gen_climo_bin.cc b/met/src/tools/dev_utils/gen_climo_bin.cc index 01c49691fb..ccd19aa5bd 100644 --- a/met/src/tools/dev_utils/gen_climo_bin.cc +++ b/met/src/tools/dev_utils/gen_climo_bin.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/gribtab.dat_to_flat.cc b/met/src/tools/dev_utils/gribtab.dat_to_flat.cc index e5424c065e..bbcb27546f 100644 --- a/met/src/tools/dev_utils/gribtab.dat_to_flat.cc +++ b/met/src/tools/dev_utils/gribtab.dat_to_flat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/insitu_nc_file.cc b/met/src/tools/dev_utils/insitu_nc_file.cc index 82e0d255ea..d1bde55beb 100644 --- a/met/src/tools/dev_utils/insitu_nc_file.cc +++ b/met/src/tools/dev_utils/insitu_nc_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/insitu_nc_file.h b/met/src/tools/dev_utils/insitu_nc_file.h index ccb165a8ad..f4b316d344 100644 --- a/met/src/tools/dev_utils/insitu_nc_file.h +++ b/met/src/tools/dev_utils/insitu_nc_file.h @@ -1,7 +1,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/insitu_nc_to_ascii.cc b/met/src/tools/dev_utils/insitu_nc_to_ascii.cc index efc0b22707..1cbc3249b2 100644 --- a/met/src/tools/dev_utils/insitu_nc_to_ascii.cc +++ b/met/src/tools/dev_utils/insitu_nc_to_ascii.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/met_nc_file.cc b/met/src/tools/dev_utils/met_nc_file.cc index c3563e59ca..20e11cbeaf 100644 --- a/met/src/tools/dev_utils/met_nc_file.cc +++ b/met/src/tools/dev_utils/met_nc_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/met_nc_file.h b/met/src/tools/dev_utils/met_nc_file.h index 03bac0723c..0b89cbdf40 100644 --- a/met/src/tools/dev_utils/met_nc_file.h +++ b/met/src/tools/dev_utils/met_nc_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/nceptab_to_flat.cc b/met/src/tools/dev_utils/nceptab_to_flat.cc index e0a4fa76f3..fc82732879 100644 --- a/met/src/tools/dev_utils/nceptab_to_flat.cc +++ b/met/src/tools/dev_utils/nceptab_to_flat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/pbtime.cc b/met/src/tools/dev_utils/pbtime.cc index 5cda897428..e5e5a6c396 100644 --- a/met/src/tools/dev_utils/pbtime.cc +++ b/met/src/tools/dev_utils/pbtime.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/reformat_county_data.cc b/met/src/tools/dev_utils/reformat_county_data.cc index edb9650e88..74fdfe07c8 100644 --- a/met/src/tools/dev_utils/reformat_county_data.cc +++ b/met/src/tools/dev_utils/reformat_county_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/reformat_map_data.cc b/met/src/tools/dev_utils/reformat_map_data.cc index 5304a521c3..7f6f066857 100644 --- a/met/src/tools/dev_utils/reformat_map_data.cc +++ b/met/src/tools/dev_utils/reformat_map_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/shapefiles/make_mapfiles.cc b/met/src/tools/dev_utils/shapefiles/make_mapfiles.cc index 5dbccfccd3..615b67d2e3 100644 --- a/met/src/tools/dev_utils/shapefiles/make_mapfiles.cc +++ b/met/src/tools/dev_utils/shapefiles/make_mapfiles.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/dev_utils/swinging_door.cc b/met/src/tools/dev_utils/swinging_door.cc index 49181206d9..cd701da0ef 100644 --- a/met/src/tools/dev_utils/swinging_door.cc +++ b/met/src/tools/dev_utils/swinging_door.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/aeronet_handler.cc b/met/src/tools/other/ascii2nc/aeronet_handler.cc index ef7025bec9..0c9bf2ad7a 100644 --- a/met/src/tools/other/ascii2nc/aeronet_handler.cc +++ b/met/src/tools/other/ascii2nc/aeronet_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/aeronet_handler.h b/met/src/tools/other/ascii2nc/aeronet_handler.h index a2c30e3a91..9a04de1dc6 100644 --- a/met/src/tools/other/ascii2nc/aeronet_handler.h +++ b/met/src/tools/other/ascii2nc/aeronet_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/ascii2nc.cc b/met/src/tools/other/ascii2nc/ascii2nc.cc index 4d876793b8..09ee7489f7 100644 --- a/met/src/tools/other/ascii2nc/ascii2nc.cc +++ b/met/src/tools/other/ascii2nc/ascii2nc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/ascii2nc_conf_info.cc b/met/src/tools/other/ascii2nc/ascii2nc_conf_info.cc index 5f856ecdfb..849bffa5bb 100644 --- a/met/src/tools/other/ascii2nc/ascii2nc_conf_info.cc +++ b/met/src/tools/other/ascii2nc/ascii2nc_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/ascii2nc_conf_info.h b/met/src/tools/other/ascii2nc/ascii2nc_conf_info.h index d228aee919..936628fda9 100644 --- a/met/src/tools/other/ascii2nc/ascii2nc_conf_info.h +++ b/met/src/tools/other/ascii2nc/ascii2nc_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/file_handler.cc b/met/src/tools/other/ascii2nc/file_handler.cc index 106667f8d3..9be6e86495 100644 --- a/met/src/tools/other/ascii2nc/file_handler.cc +++ b/met/src/tools/other/ascii2nc/file_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/file_handler.h b/met/src/tools/other/ascii2nc/file_handler.h index 1a50209513..092fd0340a 100644 --- a/met/src/tools/other/ascii2nc/file_handler.h +++ b/met/src/tools/other/ascii2nc/file_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/little_r_handler.cc b/met/src/tools/other/ascii2nc/little_r_handler.cc index b99d3c7f32..6ec35597ac 100644 --- a/met/src/tools/other/ascii2nc/little_r_handler.cc +++ b/met/src/tools/other/ascii2nc/little_r_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/little_r_handler.h b/met/src/tools/other/ascii2nc/little_r_handler.h index 6774bf718f..703dc0c850 100644 --- a/met/src/tools/other/ascii2nc/little_r_handler.h +++ b/met/src/tools/other/ascii2nc/little_r_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/met_handler.cc b/met/src/tools/other/ascii2nc/met_handler.cc index 17fdff2fda..dbb4c4d2a7 100644 --- a/met/src/tools/other/ascii2nc/met_handler.cc +++ b/met/src/tools/other/ascii2nc/met_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/met_handler.h b/met/src/tools/other/ascii2nc/met_handler.h index 4dbc117ce9..edab7dcef0 100644 --- a/met/src/tools/other/ascii2nc/met_handler.h +++ b/met/src/tools/other/ascii2nc/met_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/python_handler.cc b/met/src/tools/other/ascii2nc/python_handler.cc index 92b1a73e05..6325020e14 100644 --- a/met/src/tools/other/ascii2nc/python_handler.cc +++ b/met/src/tools/other/ascii2nc/python_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/python_handler.h b/met/src/tools/other/ascii2nc/python_handler.h index a3b4cfb696..c3d02e6525 100644 --- a/met/src/tools/other/ascii2nc/python_handler.h +++ b/met/src/tools/other/ascii2nc/python_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/surfrad_handler.cc b/met/src/tools/other/ascii2nc/surfrad_handler.cc index c55cb11092..4dfa8b48d8 100644 --- a/met/src/tools/other/ascii2nc/surfrad_handler.cc +++ b/met/src/tools/other/ascii2nc/surfrad_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/surfrad_handler.h b/met/src/tools/other/ascii2nc/surfrad_handler.h index d3680aef57..39092be4c4 100644 --- a/met/src/tools/other/ascii2nc/surfrad_handler.h +++ b/met/src/tools/other/ascii2nc/surfrad_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/wwsis_handler.cc b/met/src/tools/other/ascii2nc/wwsis_handler.cc index 461896e4bb..cb3b5f63b9 100644 --- a/met/src/tools/other/ascii2nc/wwsis_handler.cc +++ b/met/src/tools/other/ascii2nc/wwsis_handler.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ascii2nc/wwsis_handler.h b/met/src/tools/other/ascii2nc/wwsis_handler.h index f960f31408..621f68127e 100644 --- a/met/src/tools/other/ascii2nc/wwsis_handler.h +++ b/met/src/tools/other/ascii2nc/wwsis_handler.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 8fb7656e3d..32f77cbf5c 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod.h index 3afe1c6726..8cfa4e5600 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc index f085a20c24..917e66c76a 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h index ae455daac7..657a908026 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc b/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc index ed5ac52802..bb2b95feec 100644 --- a/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc +++ b/met/src/tools/other/gen_vx_mask/gen_vx_mask.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gen_vx_mask/gen_vx_mask.h b/met/src/tools/other/gen_vx_mask/gen_vx_mask.h index fe6f6f901c..aef3378c43 100644 --- a/met/src/tools/other/gen_vx_mask/gen_vx_mask.h +++ b/met/src/tools/other/gen_vx_mask/gen_vx_mask.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gis_utils/gis_dump_dbf.cc b/met/src/tools/other/gis_utils/gis_dump_dbf.cc index 785db46fd5..f5fddd2a21 100644 --- a/met/src/tools/other/gis_utils/gis_dump_dbf.cc +++ b/met/src/tools/other/gis_utils/gis_dump_dbf.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gis_utils/gis_dump_shp.cc b/met/src/tools/other/gis_utils/gis_dump_shp.cc index b41841931b..0f29a53486 100644 --- a/met/src/tools/other/gis_utils/gis_dump_shp.cc +++ b/met/src/tools/other/gis_utils/gis_dump_shp.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gis_utils/gis_dump_shx.cc b/met/src/tools/other/gis_utils/gis_dump_shx.cc index ba9869d541..c799d50015 100644 --- a/met/src/tools/other/gis_utils/gis_dump_shx.cc +++ b/met/src/tools/other/gis_utils/gis_dump_shx.cc @@ -4,7 +4,7 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/grid_diag/grid_diag.cc b/met/src/tools/other/grid_diag/grid_diag.cc index 46929924b4..60f2446209 100644 --- a/met/src/tools/other/grid_diag/grid_diag.cc +++ b/met/src/tools/other/grid_diag/grid_diag.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/grid_diag/grid_diag.h b/met/src/tools/other/grid_diag/grid_diag.h index e595ed7e96..1bc4d4f30d 100644 --- a/met/src/tools/other/grid_diag/grid_diag.h +++ b/met/src/tools/other/grid_diag/grid_diag.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/grid_diag/grid_diag_conf_info.cc b/met/src/tools/other/grid_diag/grid_diag_conf_info.cc index 14b6edaa29..02f55cc8cd 100644 --- a/met/src/tools/other/grid_diag/grid_diag_conf_info.cc +++ b/met/src/tools/other/grid_diag/grid_diag_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/grid_diag/grid_diag_conf_info.h b/met/src/tools/other/grid_diag/grid_diag_conf_info.h index 7127aa2927..901baf7397 100644 --- a/met/src/tools/other/grid_diag/grid_diag_conf_info.h +++ b/met/src/tools/other/grid_diag/grid_diag_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/conv_offsets.h b/met/src/tools/other/gsi_tools/conv_offsets.h index d64f4169bf..860fa7c80b 100644 --- a/met/src/tools/other/gsi_tools/conv_offsets.h +++ b/met/src/tools/other/gsi_tools/conv_offsets.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/conv_record.cc b/met/src/tools/other/gsi_tools/conv_record.cc index 1bf283f83e..51997aece0 100644 --- a/met/src/tools/other/gsi_tools/conv_record.cc +++ b/met/src/tools/other/gsi_tools/conv_record.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/conv_record.h b/met/src/tools/other/gsi_tools/conv_record.h index 229c55424e..02189c4656 100644 --- a/met/src/tools/other/gsi_tools/conv_record.h +++ b/met/src/tools/other/gsi_tools/conv_record.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/ftto.h b/met/src/tools/other/gsi_tools/ftto.h index a3c316f5e5..5ba7cccb83 100644 --- a/met/src/tools/other/gsi_tools/ftto.h +++ b/met/src/tools/other/gsi_tools/ftto.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsi_record.cc b/met/src/tools/other/gsi_tools/gsi_record.cc index 88f2e6c543..a627622be6 100644 --- a/met/src/tools/other/gsi_tools/gsi_record.cc +++ b/met/src/tools/other/gsi_tools/gsi_record.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsi_record.h b/met/src/tools/other/gsi_tools/gsi_record.h index 048415f4ff..728f29c320 100644 --- a/met/src/tools/other/gsi_tools/gsi_record.h +++ b/met/src/tools/other/gsi_tools/gsi_record.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsi_util.cc b/met/src/tools/other/gsi_tools/gsi_util.cc index e32e86ef34..d38ce4b9e4 100644 --- a/met/src/tools/other/gsi_tools/gsi_util.cc +++ b/met/src/tools/other/gsi_tools/gsi_util.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsi_util.h b/met/src/tools/other/gsi_tools/gsi_util.h index adb8b3e28a..cc3f5aa3ee 100644 --- a/met/src/tools/other/gsi_tools/gsi_util.h +++ b/met/src/tools/other/gsi_tools/gsi_util.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsid2mpr.cc b/met/src/tools/other/gsi_tools/gsid2mpr.cc index 306099ad75..e392986bf5 100644 --- a/met/src/tools/other/gsi_tools/gsid2mpr.cc +++ b/met/src/tools/other/gsi_tools/gsid2mpr.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsid2mpr.h b/met/src/tools/other/gsi_tools/gsid2mpr.h index 4b6eb07313..32b0733b9a 100644 --- a/met/src/tools/other/gsi_tools/gsid2mpr.h +++ b/met/src/tools/other/gsi_tools/gsid2mpr.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsidens2orank.cc b/met/src/tools/other/gsi_tools/gsidens2orank.cc index 3d49135173..f6fc8ff898 100644 --- a/met/src/tools/other/gsi_tools/gsidens2orank.cc +++ b/met/src/tools/other/gsi_tools/gsidens2orank.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/gsidens2orank.h b/met/src/tools/other/gsi_tools/gsidens2orank.h index 15b403684e..0e8fb7dcdd 100644 --- a/met/src/tools/other/gsi_tools/gsidens2orank.h +++ b/met/src/tools/other/gsi_tools/gsidens2orank.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/rad_config.cc b/met/src/tools/other/gsi_tools/rad_config.cc index 955891d595..a4598d74d3 100644 --- a/met/src/tools/other/gsi_tools/rad_config.cc +++ b/met/src/tools/other/gsi_tools/rad_config.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/rad_config.h b/met/src/tools/other/gsi_tools/rad_config.h index c85d3fccaf..8a95aabae2 100644 --- a/met/src/tools/other/gsi_tools/rad_config.h +++ b/met/src/tools/other/gsi_tools/rad_config.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/rad_offsets.h b/met/src/tools/other/gsi_tools/rad_offsets.h index b9c5098d7d..8dc904c081 100644 --- a/met/src/tools/other/gsi_tools/rad_offsets.h +++ b/met/src/tools/other/gsi_tools/rad_offsets.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/rad_record.cc b/met/src/tools/other/gsi_tools/rad_record.cc index d250bcba27..4ce91f1202 100644 --- a/met/src/tools/other/gsi_tools/rad_record.cc +++ b/met/src/tools/other/gsi_tools/rad_record.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/gsi_tools/rad_record.h b/met/src/tools/other/gsi_tools/rad_record.h index 596bb7f49f..c26d768514 100644 --- a/met/src/tools/other/gsi_tools/rad_record.h +++ b/met/src/tools/other/gsi_tools/rad_record.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index df1830c084..cc36eed5fe 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ioda2nc/ioda2nc_conf_info.cc b/met/src/tools/other/ioda2nc/ioda2nc_conf_info.cc index ca5c9c0e92..29ed7be5f4 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc_conf_info.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/ioda2nc/ioda2nc_conf_info.h b/met/src/tools/other/ioda2nc/ioda2nc_conf_info.h index 217c7a8b61..0f09a18abb 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc_conf_info.h +++ b/met/src/tools/other/ioda2nc/ioda2nc_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/lidar2nc/calipso_5km.cc b/met/src/tools/other/lidar2nc/calipso_5km.cc index 185dc58797..21ce377f92 100644 --- a/met/src/tools/other/lidar2nc/calipso_5km.cc +++ b/met/src/tools/other/lidar2nc/calipso_5km.cc @@ -1,6 +1,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/lidar2nc/calipso_5km.h b/met/src/tools/other/lidar2nc/calipso_5km.h index eaa1dd6863..31e5c72179 100644 --- a/met/src/tools/other/lidar2nc/calipso_5km.h +++ b/met/src/tools/other/lidar2nc/calipso_5km.h @@ -1,6 +1,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/lidar2nc/hdf_utils.cc b/met/src/tools/other/lidar2nc/hdf_utils.cc index 165d500bc3..06ccb27750 100644 --- a/met/src/tools/other/lidar2nc/hdf_utils.cc +++ b/met/src/tools/other/lidar2nc/hdf_utils.cc @@ -1,6 +1,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/lidar2nc/hdf_utils.h b/met/src/tools/other/lidar2nc/hdf_utils.h index 7dba934a4e..5e53fabca3 100644 --- a/met/src/tools/other/lidar2nc/hdf_utils.h +++ b/met/src/tools/other/lidar2nc/hdf_utils.h @@ -1,6 +1,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/lidar2nc/lidar2nc.cc b/met/src/tools/other/lidar2nc/lidar2nc.cc index c02dfd2771..87f153bae1 100644 --- a/met/src/tools/other/lidar2nc/lidar2nc.cc +++ b/met/src/tools/other/lidar2nc/lidar2nc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/madis2nc/madis2nc.cc b/met/src/tools/other/madis2nc/madis2nc.cc index 2af469236c..f6ba8a6696 100644 --- a/met/src/tools/other/madis2nc/madis2nc.cc +++ b/met/src/tools/other/madis2nc/madis2nc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/madis2nc/madis2nc.h b/met/src/tools/other/madis2nc/madis2nc.h index 74c03ed917..002f4cb147 100644 --- a/met/src/tools/other/madis2nc/madis2nc.h +++ b/met/src/tools/other/madis2nc/madis2nc.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/madis2nc/madis2nc_conf_info.cc b/met/src/tools/other/madis2nc/madis2nc_conf_info.cc index cf6c2af280..2791d29f8c 100644 --- a/met/src/tools/other/madis2nc/madis2nc_conf_info.cc +++ b/met/src/tools/other/madis2nc/madis2nc_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/madis2nc/madis2nc_conf_info.h b/met/src/tools/other/madis2nc/madis2nc_conf_info.h index 3fd72e1933..8e25d40694 100644 --- a/met/src/tools/other/madis2nc/madis2nc_conf_info.h +++ b/met/src/tools/other/madis2nc/madis2nc_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/cgraph.h b/met/src/tools/other/mode_graphics/cgraph.h index 0d1ba11d63..4a2026cce1 100644 --- a/met/src/tools/other/mode_graphics/cgraph.h +++ b/met/src/tools/other/mode_graphics/cgraph.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/cgraph_font.cc b/met/src/tools/other/mode_graphics/cgraph_font.cc index 83d7b62a41..9f12dca012 100644 --- a/met/src/tools/other/mode_graphics/cgraph_font.cc +++ b/met/src/tools/other/mode_graphics/cgraph_font.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/cgraph_font.h b/met/src/tools/other/mode_graphics/cgraph_font.h index 66184a66b7..0c2ea2cff5 100644 --- a/met/src/tools/other/mode_graphics/cgraph_font.h +++ b/met/src/tools/other/mode_graphics/cgraph_font.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/cgraph_main.cc b/met/src/tools/other/mode_graphics/cgraph_main.cc index 5020cfe719..d6e2726e0d 100644 --- a/met/src/tools/other/mode_graphics/cgraph_main.cc +++ b/met/src/tools/other/mode_graphics/cgraph_main.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/cgraph_main.h b/met/src/tools/other/mode_graphics/cgraph_main.h index 7c445bcdb0..296945ae96 100644 --- a/met/src/tools/other/mode_graphics/cgraph_main.h +++ b/met/src/tools/other/mode_graphics/cgraph_main.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/color_stack.cc b/met/src/tools/other/mode_graphics/color_stack.cc index 0df39516f9..24cf52d2bb 100644 --- a/met/src/tools/other/mode_graphics/color_stack.cc +++ b/met/src/tools/other/mode_graphics/color_stack.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/color_stack.h b/met/src/tools/other/mode_graphics/color_stack.h index 6193027dd1..9afd846a91 100644 --- a/met/src/tools/other/mode_graphics/color_stack.h +++ b/met/src/tools/other/mode_graphics/color_stack.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/gs_ps_map.h b/met/src/tools/other/mode_graphics/gs_ps_map.h index 83b383e911..d320af6ef1 100644 --- a/met/src/tools/other/mode_graphics/gs_ps_map.h +++ b/met/src/tools/other/mode_graphics/gs_ps_map.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/mode_nc_output_file.cc b/met/src/tools/other/mode_graphics/mode_nc_output_file.cc index 641bf1b408..b54b9d3601 100644 --- a/met/src/tools/other/mode_graphics/mode_nc_output_file.cc +++ b/met/src/tools/other/mode_graphics/mode_nc_output_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/mode_nc_output_file.h b/met/src/tools/other/mode_graphics/mode_nc_output_file.h index 3be5937c9e..5959dedd73 100644 --- a/met/src/tools/other/mode_graphics/mode_nc_output_file.h +++ b/met/src/tools/other/mode_graphics/mode_nc_output_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/plot_mode_field.cc b/met/src/tools/other/mode_graphics/plot_mode_field.cc index ab77a6bb4c..6e4a3d5ce5 100644 --- a/met/src/tools/other/mode_graphics/plot_mode_field.cc +++ b/met/src/tools/other/mode_graphics/plot_mode_field.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_graphics/sincosd.h b/met/src/tools/other/mode_graphics/sincosd.h index d61be2fa1c..b347989e8a 100644 --- a/met/src/tools/other/mode_graphics/sincosd.h +++ b/met/src/tools/other/mode_graphics/sincosd.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_att.cc b/met/src/tools/other/mode_time_domain/2d_att.cc index 1df67272cc..a591e4e5fe 100644 --- a/met/src/tools/other/mode_time_domain/2d_att.cc +++ b/met/src/tools/other/mode_time_domain/2d_att.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_att.h b/met/src/tools/other/mode_time_domain/2d_att.h index 0e6f66b059..72a4f5c223 100644 --- a/met/src/tools/other/mode_time_domain/2d_att.h +++ b/met/src/tools/other/mode_time_domain/2d_att.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_att_array.cc b/met/src/tools/other/mode_time_domain/2d_att_array.cc index 6b1502145e..e47190981d 100644 --- a/met/src/tools/other/mode_time_domain/2d_att_array.cc +++ b/met/src/tools/other/mode_time_domain/2d_att_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_att_array.h b/met/src/tools/other/mode_time_domain/2d_att_array.h index 3c7154383a..8248c33144 100644 --- a/met/src/tools/other/mode_time_domain/2d_att_array.h +++ b/met/src/tools/other/mode_time_domain/2d_att_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_columns.h b/met/src/tools/other/mode_time_domain/2d_columns.h index 8d34ef589e..4eb352db8f 100644 --- a/met/src/tools/other/mode_time_domain/2d_columns.h +++ b/met/src/tools/other/mode_time_domain/2d_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_moments.cc b/met/src/tools/other/mode_time_domain/2d_moments.cc index b2d521e75e..4106d4946c 100644 --- a/met/src/tools/other/mode_time_domain/2d_moments.cc +++ b/met/src/tools/other/mode_time_domain/2d_moments.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/2d_moments.h b/met/src/tools/other/mode_time_domain/2d_moments.h index e5de613c1f..65824cc5ff 100644 --- a/met/src/tools/other/mode_time_domain/2d_moments.h +++ b/met/src/tools/other/mode_time_domain/2d_moments.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_att.cc b/met/src/tools/other/mode_time_domain/3d_att.cc index 6c10fadfda..83faef18af 100644 --- a/met/src/tools/other/mode_time_domain/3d_att.cc +++ b/met/src/tools/other/mode_time_domain/3d_att.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_att.h b/met/src/tools/other/mode_time_domain/3d_att.h index 20e1c9a41f..ac5c5a70f2 100644 --- a/met/src/tools/other/mode_time_domain/3d_att.h +++ b/met/src/tools/other/mode_time_domain/3d_att.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_att_pair_array.cc b/met/src/tools/other/mode_time_domain/3d_att_pair_array.cc index 17e281d75d..cfe0c5231a 100644 --- a/met/src/tools/other/mode_time_domain/3d_att_pair_array.cc +++ b/met/src/tools/other/mode_time_domain/3d_att_pair_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_att_pair_array.h b/met/src/tools/other/mode_time_domain/3d_att_pair_array.h index 8aaadaf128..f951539e5e 100644 --- a/met/src/tools/other/mode_time_domain/3d_att_pair_array.h +++ b/met/src/tools/other/mode_time_domain/3d_att_pair_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_att_single_array.cc b/met/src/tools/other/mode_time_domain/3d_att_single_array.cc index 71e34b5b4f..ae0caaebed 100644 --- a/met/src/tools/other/mode_time_domain/3d_att_single_array.cc +++ b/met/src/tools/other/mode_time_domain/3d_att_single_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_att_single_array.h b/met/src/tools/other/mode_time_domain/3d_att_single_array.h index 7a95cbbee8..c0746bf858 100644 --- a/met/src/tools/other/mode_time_domain/3d_att_single_array.h +++ b/met/src/tools/other/mode_time_domain/3d_att_single_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_conv.cc b/met/src/tools/other/mode_time_domain/3d_conv.cc index 44ea6788e7..5a4027eafb 100644 --- a/met/src/tools/other/mode_time_domain/3d_conv.cc +++ b/met/src/tools/other/mode_time_domain/3d_conv.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_moments.cc b/met/src/tools/other/mode_time_domain/3d_moments.cc index 854e3c82dd..1f74b18406 100644 --- a/met/src/tools/other/mode_time_domain/3d_moments.cc +++ b/met/src/tools/other/mode_time_domain/3d_moments.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_moments.h b/met/src/tools/other/mode_time_domain/3d_moments.h index 424249877b..7b1ec20729 100644 --- a/met/src/tools/other/mode_time_domain/3d_moments.h +++ b/met/src/tools/other/mode_time_domain/3d_moments.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_pair_columns.h b/met/src/tools/other/mode_time_domain/3d_pair_columns.h index bd746ef8f3..433177ddd0 100644 --- a/met/src/tools/other/mode_time_domain/3d_pair_columns.h +++ b/met/src/tools/other/mode_time_domain/3d_pair_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_single_columns.h b/met/src/tools/other/mode_time_domain/3d_single_columns.h index 0fbefaccbc..7cacd489c8 100644 --- a/met/src/tools/other/mode_time_domain/3d_single_columns.h +++ b/met/src/tools/other/mode_time_domain/3d_single_columns.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/3d_txt_header.h b/met/src/tools/other/mode_time_domain/3d_txt_header.h index fc7cf7ec70..9235961d75 100644 --- a/met/src/tools/other/mode_time_domain/3d_txt_header.h +++ b/met/src/tools/other/mode_time_domain/3d_txt_header.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/fo_graph.cc b/met/src/tools/other/mode_time_domain/fo_graph.cc index d2032d3f66..5c3f584a51 100644 --- a/met/src/tools/other/mode_time_domain/fo_graph.cc +++ b/met/src/tools/other/mode_time_domain/fo_graph.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/fo_graph.h b/met/src/tools/other/mode_time_domain/fo_graph.h index fa1d5247e4..0eeb4b1f37 100644 --- a/met/src/tools/other/mode_time_domain/fo_graph.h +++ b/met/src/tools/other/mode_time_domain/fo_graph.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/fo_node.cc b/met/src/tools/other/mode_time_domain/fo_node.cc index 7e0891034d..3c22c69e57 100644 --- a/met/src/tools/other/mode_time_domain/fo_node.cc +++ b/met/src/tools/other/mode_time_domain/fo_node.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/fo_node.h b/met/src/tools/other/mode_time_domain/fo_node.h index 58d01ca9c8..0829f12a55 100644 --- a/met/src/tools/other/mode_time_domain/fo_node.h +++ b/met/src/tools/other/mode_time_domain/fo_node.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/fo_node_array.cc b/met/src/tools/other/mode_time_domain/fo_node_array.cc index 5f72d8f456..9c3b4b8395 100644 --- a/met/src/tools/other/mode_time_domain/fo_node_array.cc +++ b/met/src/tools/other/mode_time_domain/fo_node_array.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/fo_node_array.h b/met/src/tools/other/mode_time_domain/fo_node_array.h index 7b6b7dae5b..7e80110ae8 100644 --- a/met/src/tools/other/mode_time_domain/fo_node_array.h +++ b/met/src/tools/other/mode_time_domain/fo_node_array.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/interest_calc.cc b/met/src/tools/other/mode_time_domain/interest_calc.cc index 40e6ce9ada..b9b110f62c 100644 --- a/met/src/tools/other/mode_time_domain/interest_calc.cc +++ b/met/src/tools/other/mode_time_domain/interest_calc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/interest_calc.h b/met/src/tools/other/mode_time_domain/interest_calc.h index c520a5b0be..158cc7aa73 100644 --- a/met/src/tools/other/mode_time_domain/interest_calc.h +++ b/met/src/tools/other/mode_time_domain/interest_calc.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mm_engine.cc b/met/src/tools/other/mode_time_domain/mm_engine.cc index be20d78f2d..200823c9c5 100644 --- a/met/src/tools/other/mode_time_domain/mm_engine.cc +++ b/met/src/tools/other/mode_time_domain/mm_engine.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mm_engine.h b/met/src/tools/other/mode_time_domain/mm_engine.h index e5aecef10f..0af380c050 100644 --- a/met/src/tools/other/mode_time_domain/mm_engine.h +++ b/met/src/tools/other/mode_time_domain/mm_engine.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd.cc b/met/src/tools/other/mode_time_domain/mtd.cc index bcabb80f03..dc816c5400 100644 --- a/met/src/tools/other/mode_time_domain/mtd.cc +++ b/met/src/tools/other/mode_time_domain/mtd.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_config_info.cc b/met/src/tools/other/mode_time_domain/mtd_config_info.cc index baa789d11c..5e149fea2b 100644 --- a/met/src/tools/other/mode_time_domain/mtd_config_info.cc +++ b/met/src/tools/other/mode_time_domain/mtd_config_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_config_info.h b/met/src/tools/other/mode_time_domain/mtd_config_info.h index 93665449e4..dac9bd2c8a 100644 --- a/met/src/tools/other/mode_time_domain/mtd_config_info.h +++ b/met/src/tools/other/mode_time_domain/mtd_config_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file.h b/met/src/tools/other/mode_time_domain/mtd_file.h index 5fc052fe1c..f086a5ed7f 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file.h +++ b/met/src/tools/other/mode_time_domain/mtd_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_base.cc b/met/src/tools/other/mode_time_domain/mtd_file_base.cc index 7c185333f3..4295a2ba85 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_base.cc +++ b/met/src/tools/other/mode_time_domain/mtd_file_base.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_base.h b/met/src/tools/other/mode_time_domain/mtd_file_base.h index 2d1e76d513..205b5feb92 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_base.h +++ b/met/src/tools/other/mode_time_domain/mtd_file_base.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_float.cc b/met/src/tools/other/mode_time_domain/mtd_file_float.cc index 9b1cf559f8..6d7cb262a4 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_float.cc +++ b/met/src/tools/other/mode_time_domain/mtd_file_float.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_float.h b/met/src/tools/other/mode_time_domain/mtd_file_float.h index 630e69577c..20493e5965 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_float.h +++ b/met/src/tools/other/mode_time_domain/mtd_file_float.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_int.cc b/met/src/tools/other/mode_time_domain/mtd_file_int.cc index 85bda6ba3c..931a3cb994 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_int.cc +++ b/met/src/tools/other/mode_time_domain/mtd_file_int.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_file_int.h b/met/src/tools/other/mode_time_domain/mtd_file_int.h index 52f7cfcc87..8611b25368 100644 --- a/met/src/tools/other/mode_time_domain/mtd_file_int.h +++ b/met/src/tools/other/mode_time_domain/mtd_file_int.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_nc_defs.h b/met/src/tools/other/mode_time_domain/mtd_nc_defs.h index df29bc5fa6..af686bb604 100644 --- a/met/src/tools/other/mode_time_domain/mtd_nc_defs.h +++ b/met/src/tools/other/mode_time_domain/mtd_nc_defs.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_nc_output.cc b/met/src/tools/other/mode_time_domain/mtd_nc_output.cc index 2df09ae472..86f1f84c48 100644 --- a/met/src/tools/other/mode_time_domain/mtd_nc_output.cc +++ b/met/src/tools/other/mode_time_domain/mtd_nc_output.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_nc_output.h b/met/src/tools/other/mode_time_domain/mtd_nc_output.h index ec2ed57e8e..413b9bfc66 100644 --- a/met/src/tools/other/mode_time_domain/mtd_nc_output.h +++ b/met/src/tools/other/mode_time_domain/mtd_nc_output.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_partition.cc b/met/src/tools/other/mode_time_domain/mtd_partition.cc index 6de39e9182..fa51e8fa77 100644 --- a/met/src/tools/other/mode_time_domain/mtd_partition.cc +++ b/met/src/tools/other/mode_time_domain/mtd_partition.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_partition.h b/met/src/tools/other/mode_time_domain/mtd_partition.h index 926c9ee495..faab8007d8 100644 --- a/met/src/tools/other/mode_time_domain/mtd_partition.h +++ b/met/src/tools/other/mode_time_domain/mtd_partition.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_read_data.cc b/met/src/tools/other/mode_time_domain/mtd_read_data.cc index a129082909..2b4eb852d0 100644 --- a/met/src/tools/other/mode_time_domain/mtd_read_data.cc +++ b/met/src/tools/other/mode_time_domain/mtd_read_data.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_read_data.h b/met/src/tools/other/mode_time_domain/mtd_read_data.h index cebb9c482f..26d0a9ba18 100644 --- a/met/src/tools/other/mode_time_domain/mtd_read_data.h +++ b/met/src/tools/other/mode_time_domain/mtd_read_data.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/mtd_txt_output.cc b/met/src/tools/other/mode_time_domain/mtd_txt_output.cc index f39a27829f..a0bf061117 100644 --- a/met/src/tools/other/mode_time_domain/mtd_txt_output.cc +++ b/met/src/tools/other/mode_time_domain/mtd_txt_output.cc @@ -1,6 +1,6 @@ // ** National Center for Atmospheric Research (NCAR) // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** Research Applications Lab (RAL) // ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA diff --git a/met/src/tools/other/mode_time_domain/mtd_txt_output.h b/met/src/tools/other/mode_time_domain/mtd_txt_output.h index 797ac26b6e..7778ff1532 100644 --- a/met/src/tools/other/mode_time_domain/mtd_txt_output.h +++ b/met/src/tools/other/mode_time_domain/mtd_txt_output.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/nc_grid.cc b/met/src/tools/other/mode_time_domain/nc_grid.cc index 2b4a3e89b4..516f24756a 100644 --- a/met/src/tools/other/mode_time_domain/nc_grid.cc +++ b/met/src/tools/other/mode_time_domain/nc_grid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/nc_grid.h b/met/src/tools/other/mode_time_domain/nc_grid.h index 79e1115bfe..47bc766d37 100644 --- a/met/src/tools/other/mode_time_domain/nc_grid.h +++ b/met/src/tools/other/mode_time_domain/nc_grid.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/nc_utils_local.cc b/met/src/tools/other/mode_time_domain/nc_utils_local.cc index ce7b74b3ae..12a056f376 100644 --- a/met/src/tools/other/mode_time_domain/nc_utils_local.cc +++ b/met/src/tools/other/mode_time_domain/nc_utils_local.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/mode_time_domain/nc_utils_local.h b/met/src/tools/other/mode_time_domain/nc_utils_local.h index 5e16d2845e..9cf6d18587 100644 --- a/met/src/tools/other/mode_time_domain/nc_utils_local.h +++ b/met/src/tools/other/mode_time_domain/nc_utils_local.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/cloudsat_swath_file.cc b/met/src/tools/other/modis_regrid/cloudsat_swath_file.cc index c3d60ab1ab..0f1908edc5 100644 --- a/met/src/tools/other/modis_regrid/cloudsat_swath_file.cc +++ b/met/src/tools/other/modis_regrid/cloudsat_swath_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/cloudsat_swath_file.h b/met/src/tools/other/modis_regrid/cloudsat_swath_file.h index 33d815e045..2cd797b84a 100644 --- a/met/src/tools/other/modis_regrid/cloudsat_swath_file.h +++ b/met/src/tools/other/modis_regrid/cloudsat_swath_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/data_averager.cc b/met/src/tools/other/modis_regrid/data_averager.cc index a582682bfc..0ed171b2eb 100644 --- a/met/src/tools/other/modis_regrid/data_averager.cc +++ b/met/src/tools/other/modis_regrid/data_averager.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/data_averager.h b/met/src/tools/other/modis_regrid/data_averager.h index adad4f996a..f44c599381 100644 --- a/met/src/tools/other/modis_regrid/data_averager.h +++ b/met/src/tools/other/modis_regrid/data_averager.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/data_plane_to_netcdf.cc b/met/src/tools/other/modis_regrid/data_plane_to_netcdf.cc index 40f9771931..c1b916c236 100644 --- a/met/src/tools/other/modis_regrid/data_plane_to_netcdf.cc +++ b/met/src/tools/other/modis_regrid/data_plane_to_netcdf.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/data_plane_to_netcdf.h b/met/src/tools/other/modis_regrid/data_plane_to_netcdf.h index 682bc3d29b..b4bbb8bd15 100644 --- a/met/src/tools/other/modis_regrid/data_plane_to_netcdf.h +++ b/met/src/tools/other/modis_regrid/data_plane_to_netcdf.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/modis_file.cc b/met/src/tools/other/modis_regrid/modis_file.cc index 33327eed82..d3551a9059 100644 --- a/met/src/tools/other/modis_regrid/modis_file.cc +++ b/met/src/tools/other/modis_regrid/modis_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/modis_file.h b/met/src/tools/other/modis_regrid/modis_file.h index 3a87eacd51..c50510d683 100644 --- a/met/src/tools/other/modis_regrid/modis_file.h +++ b/met/src/tools/other/modis_regrid/modis_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/modis_regrid.cc b/met/src/tools/other/modis_regrid/modis_regrid.cc index 600abf655c..ccf0ad4e95 100644 --- a/met/src/tools/other/modis_regrid/modis_regrid.cc +++ b/met/src/tools/other/modis_regrid/modis_regrid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/sat_utils.cc b/met/src/tools/other/modis_regrid/sat_utils.cc index e1fc2540c0..63d6bea133 100644 --- a/met/src/tools/other/modis_regrid/sat_utils.cc +++ b/met/src/tools/other/modis_regrid/sat_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/modis_regrid/sat_utils.h b/met/src/tools/other/modis_regrid/sat_utils.h index 6cc285f92a..8d4d6a40fe 100644 --- a/met/src/tools/other/modis_regrid/sat_utils.h +++ b/met/src/tools/other/modis_regrid/sat_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/closepb.f b/met/src/tools/other/pb2nc/closepb.f index 7d0cbb7262..cfc3e09ec1 100644 --- a/met/src/tools/other/pb2nc/closepb.f +++ b/met/src/tools/other/pb2nc/closepb.f @@ -1,5 +1,5 @@ C* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -C* ** Copyright UCAR (c) 1992 - 2021 +C* ** Copyright UCAR (c) 1992 - 2022 C* ** University Corporation for Atmospheric Research (UCAR) C* ** National Center for Atmospheric Research (NCAR) C* ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/dumppb.f b/met/src/tools/other/pb2nc/dumppb.f index 8c07364668..b203b36cdf 100644 --- a/met/src/tools/other/pb2nc/dumppb.f +++ b/met/src/tools/other/pb2nc/dumppb.f @@ -1,5 +1,5 @@ C* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -C* ** Copyright UCAR (c) 1992 - 2021 +C* ** Copyright UCAR (c) 1992 - 2022 C* ** University Corporation for Atmospheric Research (UCAR) C* ** National Center for Atmospheric Research (NCAR) C* ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/numpbmsg.f b/met/src/tools/other/pb2nc/numpbmsg.f index d6b5b4b4d4..71df86241a 100644 --- a/met/src/tools/other/pb2nc/numpbmsg.f +++ b/met/src/tools/other/pb2nc/numpbmsg.f @@ -1,5 +1,5 @@ C* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -C* ** Copyright UCAR (c) 1992 - 2021 +C* ** Copyright UCAR (c) 1992 - 2022 C* ** University Corporation for Atmospheric Research (UCAR) C* ** National Center for Atmospheric Research (NCAR) C* ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/openpb.f b/met/src/tools/other/pb2nc/openpb.f index 532cf0ce54..af6b0e64a3 100644 --- a/met/src/tools/other/pb2nc/openpb.f +++ b/met/src/tools/other/pb2nc/openpb.f @@ -1,5 +1,5 @@ C* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -C* ** Copyright UCAR (c) 1992 - 2021 +C* ** Copyright UCAR (c) 1992 - 2022 C* ** University Corporation for Atmospheric Research (UCAR) C* ** National Center for Atmospheric Research (NCAR) C* ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index 9190b4106f..7df4d754eb 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/pb2nc_conf_info.cc b/met/src/tools/other/pb2nc/pb2nc_conf_info.cc index 8acd87755b..d940939072 100644 --- a/met/src/tools/other/pb2nc/pb2nc_conf_info.cc +++ b/met/src/tools/other/pb2nc/pb2nc_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/pb2nc_conf_info.h b/met/src/tools/other/pb2nc/pb2nc_conf_info.h index 26dc20c282..5bff649adf 100644 --- a/met/src/tools/other/pb2nc/pb2nc_conf_info.h +++ b/met/src/tools/other/pb2nc/pb2nc_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/pb2nc/readpb.f b/met/src/tools/other/pb2nc/readpb.f index dec7eab8da..e74fc38132 100644 --- a/met/src/tools/other/pb2nc/readpb.f +++ b/met/src/tools/other/pb2nc/readpb.f @@ -1,5 +1,5 @@ C* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -C* ** Copyright UCAR (c) 1992 - 2021 +C* ** Copyright UCAR (c) 1992 - 2022 C* ** University Corporation for Atmospheric Research (UCAR) C* ** National Center for Atmospheric Research (NCAR) C* ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/plot_data_plane/plot_data_plane.cc b/met/src/tools/other/plot_data_plane/plot_data_plane.cc index 101eb51c0e..1d266bfc40 100644 --- a/met/src/tools/other/plot_data_plane/plot_data_plane.cc +++ b/met/src/tools/other/plot_data_plane/plot_data_plane.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs.cc b/met/src/tools/other/plot_point_obs/plot_point_obs.cc index 243f4d0c29..888b521758 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs.cc +++ b/met/src/tools/other/plot_point_obs/plot_point_obs.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs.h b/met/src/tools/other/plot_point_obs/plot_point_obs.h index 0bf33b0679..aeef6c87b2 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs.h +++ b/met/src/tools/other/plot_point_obs/plot_point_obs.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.cc b/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.cc index 6bf63f95ab..8bab66c7d1 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.cc +++ b/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.h b/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.h index 8261cc3f91..f66310b556 100644 --- a/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.h +++ b/met/src/tools/other/plot_point_obs/plot_point_obs_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/point2grid/point2grid.cc b/met/src/tools/other/point2grid/point2grid.cc index f806023c11..7b4285e0b4 100644 --- a/met/src/tools/other/point2grid/point2grid.cc +++ b/met/src/tools/other/point2grid/point2grid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/point2grid/point2grid_conf_info.cc b/met/src/tools/other/point2grid/point2grid_conf_info.cc index 8c50524235..85346b5632 100644 --- a/met/src/tools/other/point2grid/point2grid_conf_info.cc +++ b/met/src/tools/other/point2grid/point2grid_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/point2grid/point2grid_conf_info.h b/met/src/tools/other/point2grid/point2grid_conf_info.h index fe62f7258a..5c9ad98c4a 100644 --- a/met/src/tools/other/point2grid/point2grid_conf_info.h +++ b/met/src/tools/other/point2grid/point2grid_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/regrid_data_plane/regrid_data_plane.cc b/met/src/tools/other/regrid_data_plane/regrid_data_plane.cc index 695201ed10..b3e77bf356 100644 --- a/met/src/tools/other/regrid_data_plane/regrid_data_plane.cc +++ b/met/src/tools/other/regrid_data_plane/regrid_data_plane.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/shift_data_plane/shift_data_plane.cc b/met/src/tools/other/shift_data_plane/shift_data_plane.cc index 5534ec3a48..d7e85612df 100644 --- a/met/src/tools/other/shift_data_plane/shift_data_plane.cc +++ b/met/src/tools/other/shift_data_plane/shift_data_plane.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/af_cp_file.cc b/met/src/tools/other/wwmca_tool/af_cp_file.cc index c5ad453f95..f0bcb140a4 100644 --- a/met/src/tools/other/wwmca_tool/af_cp_file.cc +++ b/met/src/tools/other/wwmca_tool/af_cp_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/af_cp_file.h b/met/src/tools/other/wwmca_tool/af_cp_file.h index 2b3713fd73..5dd63d6aa1 100644 --- a/met/src/tools/other/wwmca_tool/af_cp_file.h +++ b/met/src/tools/other/wwmca_tool/af_cp_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/af_file.cc b/met/src/tools/other/wwmca_tool/af_file.cc index 1a60ecd0f8..e354b96dda 100644 --- a/met/src/tools/other/wwmca_tool/af_file.cc +++ b/met/src/tools/other/wwmca_tool/af_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/af_file.h b/met/src/tools/other/wwmca_tool/af_file.h index bd95a18c5b..305cd7edbb 100644 --- a/met/src/tools/other/wwmca_tool/af_file.h +++ b/met/src/tools/other/wwmca_tool/af_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/af_pt_file.cc b/met/src/tools/other/wwmca_tool/af_pt_file.cc index e64897d80f..ddfa4267d2 100644 --- a/met/src/tools/other/wwmca_tool/af_pt_file.cc +++ b/met/src/tools/other/wwmca_tool/af_pt_file.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/af_pt_file.h b/met/src/tools/other/wwmca_tool/af_pt_file.h index 61859d8755..85ae4ed8a1 100644 --- a/met/src/tools/other/wwmca_tool/af_pt_file.h +++ b/met/src/tools/other/wwmca_tool/af_pt_file.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/ave_interp.cc b/met/src/tools/other/wwmca_tool/ave_interp.cc index 51b4f88fb0..7e89257db5 100644 --- a/met/src/tools/other/wwmca_tool/ave_interp.cc +++ b/met/src/tools/other/wwmca_tool/ave_interp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/ave_interp.h b/met/src/tools/other/wwmca_tool/ave_interp.h index 96f16737e1..eec32fba2d 100644 --- a/met/src/tools/other/wwmca_tool/ave_interp.h +++ b/met/src/tools/other/wwmca_tool/ave_interp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/interp_base.cc b/met/src/tools/other/wwmca_tool/interp_base.cc index 3bf262eefa..bd1ae69ba8 100644 --- a/met/src/tools/other/wwmca_tool/interp_base.cc +++ b/met/src/tools/other/wwmca_tool/interp_base.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/interp_base.h b/met/src/tools/other/wwmca_tool/interp_base.h index 81b030aef2..ce597e4942 100644 --- a/met/src/tools/other/wwmca_tool/interp_base.h +++ b/met/src/tools/other/wwmca_tool/interp_base.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/max_interp.cc b/met/src/tools/other/wwmca_tool/max_interp.cc index 2f870ea7f2..206369e9fe 100644 --- a/met/src/tools/other/wwmca_tool/max_interp.cc +++ b/met/src/tools/other/wwmca_tool/max_interp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/max_interp.h b/met/src/tools/other/wwmca_tool/max_interp.h index a4760c3062..f4c484440d 100644 --- a/met/src/tools/other/wwmca_tool/max_interp.h +++ b/met/src/tools/other/wwmca_tool/max_interp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/min_interp.cc b/met/src/tools/other/wwmca_tool/min_interp.cc index 3973ba011e..2b665f2b48 100644 --- a/met/src/tools/other/wwmca_tool/min_interp.cc +++ b/met/src/tools/other/wwmca_tool/min_interp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/min_interp.h b/met/src/tools/other/wwmca_tool/min_interp.h index fc301a6e16..5147653840 100644 --- a/met/src/tools/other/wwmca_tool/min_interp.h +++ b/met/src/tools/other/wwmca_tool/min_interp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/nc_output.cc b/met/src/tools/other/wwmca_tool/nc_output.cc index fb55d045b5..efe34200c9 100644 --- a/met/src/tools/other/wwmca_tool/nc_output.cc +++ b/met/src/tools/other/wwmca_tool/nc_output.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/nearest_interp.cc b/met/src/tools/other/wwmca_tool/nearest_interp.cc index 3b5cb14624..111d9a62d7 100644 --- a/met/src/tools/other/wwmca_tool/nearest_interp.cc +++ b/met/src/tools/other/wwmca_tool/nearest_interp.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/nearest_interp.h b/met/src/tools/other/wwmca_tool/nearest_interp.h index d4a3eb7c57..2fa1e7f0af 100644 --- a/met/src/tools/other/wwmca_tool/nearest_interp.h +++ b/met/src/tools/other/wwmca_tool/nearest_interp.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/wwmca_plot.cc b/met/src/tools/other/wwmca_tool/wwmca_plot.cc index b8705dfc84..839fbc2359 100644 --- a/met/src/tools/other/wwmca_tool/wwmca_plot.cc +++ b/met/src/tools/other/wwmca_tool/wwmca_plot.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/wwmca_ref.cc b/met/src/tools/other/wwmca_tool/wwmca_ref.cc index ab52792d8b..e10c0e6a91 100644 --- a/met/src/tools/other/wwmca_tool/wwmca_ref.cc +++ b/met/src/tools/other/wwmca_tool/wwmca_ref.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/wwmca_ref.h b/met/src/tools/other/wwmca_tool/wwmca_ref.h index 043669e11e..992ffda9ee 100644 --- a/met/src/tools/other/wwmca_tool/wwmca_ref.h +++ b/met/src/tools/other/wwmca_tool/wwmca_ref.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/wwmca_regrid.cc b/met/src/tools/other/wwmca_tool/wwmca_regrid.cc index df4c3324af..31261c00aa 100644 --- a/met/src/tools/other/wwmca_tool/wwmca_regrid.cc +++ b/met/src/tools/other/wwmca_tool/wwmca_regrid.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/wwmca_utils.cc b/met/src/tools/other/wwmca_tool/wwmca_utils.cc index 9d02297c60..103e03c497 100644 --- a/met/src/tools/other/wwmca_tool/wwmca_utils.cc +++ b/met/src/tools/other/wwmca_tool/wwmca_utils.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/other/wwmca_tool/wwmca_utils.h b/met/src/tools/other/wwmca_tool/wwmca_utils.h index 1070195941..9ae9ee6472 100644 --- a/met/src/tools/other/wwmca_tool/wwmca_utils.h +++ b/met/src/tools/other/wwmca_tool/wwmca_utils.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc index 5f02d8bb34..b885f3bf27 100644 --- a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc +++ b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.h b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.h index 2c00e1d609..541f069dc5 100644 --- a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.h +++ b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.cc b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.cc index 4e3c1cd734..28f6d0c864 100644 --- a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.cc +++ b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.h b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.h index 2fde1a15a0..ff1e1b7193 100644 --- a/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.h +++ b/met/src/tools/tc_utils/rmw_analysis/rmw_analysis_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_dland/tc_dland.cc b/met/src/tools/tc_utils/tc_dland/tc_dland.cc index 92195d7af1..34e8f262c8 100644 --- a/met/src/tools/tc_utils/tc_dland/tc_dland.cc +++ b/met/src/tools/tc_utils/tc_dland/tc_dland.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_dland/tc_poly.cc b/met/src/tools/tc_utils/tc_dland/tc_poly.cc index cd68ac1af7..d381d847ae 100644 --- a/met/src/tools/tc_utils/tc_dland/tc_poly.cc +++ b/met/src/tools/tc_utils/tc_dland/tc_poly.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_dland/tc_poly.h b/met/src/tools/tc_utils/tc_dland/tc_poly.h index 0d307f910f..35c9ab9428 100644 --- a/met/src/tools/tc_utils/tc_dland/tc_poly.h +++ b/met/src/tools/tc_utils/tc_dland/tc_poly.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen.cc b/met/src/tools/tc_utils/tc_gen/tc_gen.cc index 3325827b5c..d8a06b4346 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen.cc +++ b/met/src/tools/tc_utils/tc_gen/tc_gen.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen.h b/met/src/tools/tc_utils/tc_gen/tc_gen.h index eb45b4f70e..64cc8975c7 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen.h +++ b/met/src/tools/tc_utils/tc_gen/tc_gen.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc index a39a7fc06c..f4ac5a74cf 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h index 487ce9245b..8346846c7a 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h +++ b/met/src/tools/tc_utils/tc_gen/tc_gen_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc b/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc index 5bf073959e..f997c43524 100644 --- a/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc +++ b/met/src/tools/tc_utils/tc_pairs/tc_pairs.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_pairs/tc_pairs.h b/met/src/tools/tc_utils/tc_pairs/tc_pairs.h index 7a6d435715..2e1d2f17ea 100644 --- a/met/src/tools/tc_utils/tc_pairs/tc_pairs.h +++ b/met/src/tools/tc_utils/tc_pairs/tc_pairs.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.cc b/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.cc index 9e038226ee..a378bbbd1d 100644 --- a/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.cc +++ b/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.h b/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.h index cc2d218f9e..4b7b2e364f 100644 --- a/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.h +++ b/met/src/tools/tc_utils/tc_pairs/tc_pairs_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_rmw/tc_rmw.cc b/met/src/tools/tc_utils/tc_rmw/tc_rmw.cc index 27e224387c..45131a01c9 100644 --- a/met/src/tools/tc_utils/tc_rmw/tc_rmw.cc +++ b/met/src/tools/tc_utils/tc_rmw/tc_rmw.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_rmw/tc_rmw.h b/met/src/tools/tc_utils/tc_rmw/tc_rmw.h index acc8e81513..dca72d44dd 100644 --- a/met/src/tools/tc_utils/tc_rmw/tc_rmw.h +++ b/met/src/tools/tc_utils/tc_rmw/tc_rmw.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.cc b/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.cc index e309e0e7f8..648b8f2e03 100644 --- a/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.cc +++ b/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.h b/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.h index f8fc48f276..dbbb7ad40b 100644 --- a/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.h +++ b/met/src/tools/tc_utils/tc_rmw/tc_rmw_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat.cc b/met/src/tools/tc_utils/tc_stat/tc_stat.cc index e1793ec194..73865d4d9f 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat.cc +++ b/met/src/tools/tc_utils/tc_stat/tc_stat.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat.h b/met/src/tools/tc_utils/tc_stat/tc_stat.h index 4addd94508..0e526f46ee 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat.h +++ b/met/src/tools/tc_utils/tc_stat/tc_stat.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.cc b/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.cc index 6305732e18..d2edb908df 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.cc +++ b/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.h b/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.h index e6a40e3ee3..e441136d4c 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.h +++ b/met/src/tools/tc_utils/tc_stat/tc_stat_conf_info.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat_files.cc b/met/src/tools/tc_utils/tc_stat/tc_stat_files.cc index a70064d4b8..bd77dad0f4 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat_files.cc +++ b/met/src/tools/tc_utils/tc_stat/tc_stat_files.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat_files.h b/met/src/tools/tc_utils/tc_stat/tc_stat_files.h index 18edf7bf1b..39cda6edf2 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat_files.h +++ b/met/src/tools/tc_utils/tc_stat/tc_stat_files.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat_job.cc b/met/src/tools/tc_utils/tc_stat/tc_stat_job.cc index cc15f0d787..79e217ffa4 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat_job.cc +++ b/met/src/tools/tc_utils/tc_stat/tc_stat_job.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/tc_utils/tc_stat/tc_stat_job.h b/met/src/tools/tc_utils/tc_stat/tc_stat_job.h index 8eeb816241..8d35120a5d 100644 --- a/met/src/tools/tc_utils/tc_stat/tc_stat_job.h +++ b/met/src/tools/tc_utils/tc_stat/tc_stat_job.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2021 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) From 872e2e49c35fa199690dbca0e0d8130bfc45623f Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 8 Feb 2022 13:38:21 -0700 Subject: [PATCH 098/172] Feature 1055 read rot latlon (#2041) --- met/docs/Users_Guide/mode.rst | 8 +- met/docs/Users_Guide/tc-gen.rst | 2 +- met/src/libcode/vx_data2d/data_class.cc | 18 +- met/src/libcode/vx_data2d_nccf/nccf_file.cc | 221 +++++++++++++++++++- met/src/libcode/vx_data2d_nccf/nccf_file.h | 4 + met/src/libcode/vx_grid/gaussian_grid.cc | 8 +- met/src/libcode/vx_grid/gaussian_grid.h | 2 +- met/src/libcode/vx_grid/goes_grid.cc | 8 +- met/src/libcode/vx_grid/goes_grid.h | 2 +- met/src/libcode/vx_grid/grid_base.cc | 4 +- met/src/libcode/vx_grid/grid_base.h | 4 +- met/src/libcode/vx_grid/latlon_grid.cc | 18 +- met/src/libcode/vx_grid/latlon_grid.h | 2 +- met/src/libcode/vx_grid/lc_grid.cc | 22 +- met/src/libcode/vx_grid/lc_grid.h | 2 +- met/src/libcode/vx_grid/merc_grid.cc | 24 +-- met/src/libcode/vx_grid/merc_grid.h | 2 +- met/src/libcode/vx_grid/rot_latlon_grid.cc | 24 +-- met/src/libcode/vx_grid/rot_latlon_grid.h | 2 +- met/src/libcode/vx_grid/st_grid.cc | 18 +- met/src/libcode/vx_grid/st_grid.h | 2 +- test/xml/unit_regrid.xml | 16 ++ 22 files changed, 318 insertions(+), 95 deletions(-) diff --git a/met/docs/Users_Guide/mode.rst b/met/docs/Users_Guide/mode.rst index ac42611764..ab341e7cce 100644 --- a/met/docs/Users_Guide/mode.rst +++ b/met/docs/Users_Guide/mode.rst @@ -967,16 +967,16 @@ The dimensions and variables included in the mode NetCDF files are described in - Number of Forecast Simple Boundary Points * - fcst_simp_bdy :raw-html:`
` \_lat - fcst_simp_bdy - - Forecast Simple Boundary PoLatitude + - Forecast Simple Boundary Latitude * - fcst_simp_bdy :raw-html:`
` \_lon - fcst_simp_bdy - - Forecast Simple Boundary PoLongitude + - Forecast Simple Boundary Longitude * - fcst_simp_bdy_x - fcst_simp_bdy - - Forecast Simple Boundary PoX-Coordinate + - Forecast Simple Boundary X-Coordinate * - fcst_simp_bdy_y - fcst_simp_bdy - - Forecast Simple Boundary PoY-Coordinate + - Forecast Simple Boundary Y-Coordinate * - fcst_simp_hull :raw-html:`
` \_start - fcst_simp - Forecast Simple Convex Hull Starting Index diff --git a/met/docs/Users_Guide/tc-gen.rst b/met/docs/Users_Guide/tc-gen.rst index 74271ec9e1..bf91572fcc 100644 --- a/met/docs/Users_Guide/tc-gen.rst +++ b/met/docs/Users_Guide/tc-gen.rst @@ -64,7 +64,7 @@ Required arguments for tc_gen 3. The **-shape source** argument is the path to one or more NHC genesis warning area shapefiles, an ASCII file list containing them, or a top-level directory with files matching the regular expression "gtwo_areas.*.shp". The genesis warning areas and corresponding 2, 5, and 7 day probability values area verified against the **-track** data. -Note: The **-genesis**, **-edeck**, or **-shape** options must be used at least once. +Note: At least one of the **-genesis**, **-edeck**, or **-shape** command line options are required. 4. The **-track source** argument is one or more ATCF reference track files or an ASCII file list or top-level directory containing them, with files ending in ".dat". This tool processes either Best track data from bdeck files, or operational track data (e.g. CARQ) from adeck files, or both. Providing both bdeck and adeck files will result in a richer dataset to match with the **-genesis** files. Both adeck and bdeck data should be provided using the **-track** option. The **-track** option must be used at least once. diff --git a/met/src/libcode/vx_data2d/data_class.cc b/met/src/libcode/vx_data2d/data_class.cc index 09b09684a9..8cd65f8322 100644 --- a/met/src/libcode/vx_data2d/data_class.cc +++ b/met/src/libcode/vx_data2d/data_class.cc @@ -361,21 +361,25 @@ if ( vinfo->grid_attr().nxy() > 0 ) { } // - // Print a data summary + // Print the grid information and data summary // if ( mlog.verbosity_level() >= 4 ) { + mlog << Debug(4) << "\n" + << "Grid information:\n " + << Dest_Grid->serialize("\n ") << "\n"; + double min_v, max_v; dp.data_range(min_v, max_v); mlog << Debug(4) << "\n" << "Data plane information:\n" - << " plane min: " << min_v << "\n" - << " plane max: " << max_v << "\n" - << " valid time: " << unix_to_yyyymmdd_hhmmss(dp.valid()) << "\n" - << " lead time: " << sec_to_hhmmss(dp.lead()) << "\n" - << " init time: " << unix_to_yyyymmdd_hhmmss(dp.init()) << "\n" - << " accum time: " << sec_to_hhmmss(dp.accum()) << "\n\n"; + << " plane min: " << min_v << "\n" + << " plane max: " << max_v << "\n" + << " valid time: " << unix_to_yyyymmdd_hhmmss(dp.valid()) << "\n" + << " lead time: " << sec_to_hhmmss(dp.lead()) << "\n" + << " init time: " << unix_to_yyyymmdd_hhmmss(dp.init()) << "\n" + << " accum time: " << sec_to_hhmmss(dp.accum()) << "\n\n"; } diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.cc b/met/src/libcode/vx_data2d_nccf/nccf_file.cc index 651129239b..53880b043c 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.cc +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.cc @@ -179,8 +179,8 @@ bool NcCfFile::open(const char * filepath) // calling program. In the case of this example, we just exit with // an NC_ERR error code. - //FIXME: Commented out with NetcDf4 enabling - //NcError err(NcError::silent_nonfatal); + // FIXME: Commented out with NetCDF4 enabling + // NcError err(NcError::silent_nonfatal); // Open the file @@ -2266,6 +2266,11 @@ void NcCfFile::get_grid_mapping_polar_stereographic(const NcVar *grid_mapping_va } +//////////////////////////////////////////////////////////////////////// +// +// Reference: +// https://cfconventions.org/Data/cf-conventions/cf-conventions-1.9/cf-conventions.html#_rotated_pole +// //////////////////////////////////////////////////////////////////////// @@ -2273,9 +2278,179 @@ void NcCfFile::get_grid_mapping_rotated_latitude_longitude(const NcVar *grid_map { static const string method_name = "NcCfFile::get_grid_mapping_rotated_latitude_longitude()"; - mlog << Error << "\n" << method_name << " -> " - << "Rotated latitude longitude grid not handled in MET.\n\n"; - exit(1); + // grid_north_pole_latitude + + NcVarAtt *grid_np_lat_att = get_nc_att( + grid_mapping_var, (string)"grid_north_pole_latitude"); + if (IS_INVALID_NC_P(grid_np_lat_att)) + { + mlog << Error << "\n" << method_name << " -> " + << "Cannot get grid_north_pole_latitude attribute from " + << GET_NC_NAME_P(grid_mapping_var) << " variable.\n\n"; + exit(1); + } + + // grid_north_pole_longitude + + NcVarAtt *grid_np_lon_att = get_nc_att( + grid_mapping_var, (string)"grid_north_pole_longitude"); + if (IS_INVALID_NC_P(grid_np_lon_att)) + { + mlog << Error << "\n" << method_name << " -> " + << "Cannot get grid_north_pole_longitude attribute from " + << GET_NC_NAME_P(grid_mapping_var) << " variable.\n\n"; + exit(1); + } + + // Look for the grid_latitude and grid_longitude dimensions + + for (int dim_num = 0; dim_num < _numDims; ++dim_num) + { + // These dimensions are identified by the standard_name attribute + + const NcVar coord_var = get_var(_ncFile, _dims[dim_num]->getName().c_str()); + if (IS_INVALID_NC(coord_var)) + continue; + + const NcVarAtt *std_name_att = get_nc_att(&coord_var, (string)"standard_name"); + if (IS_INVALID_NC_P(std_name_att)) { + if (std_name_att) delete std_name_att; + continue; + } + + ConcatString dim_standard_name; + if (!get_att_value_chars(std_name_att, dim_standard_name)) { + if (std_name_att) delete std_name_att; + continue; + } + + if (std_name_att) delete std_name_att; + + // See if this is a grid_latitude or grid_longitude dimension + + if (dim_standard_name == "grid_latitude") + { + if (_yDim == 0) + { + _yDim = _dims[dim_num]; + + y_dim_var_name = GET_NC_NAME_P(_yDim).c_str(); + + for (int var_num = 0; var_num < Nvars; ++var_num) + { + if ( Var[var_num].name == GET_NC_NAME_P(_yDim)) + { + _yCoordVar = Var[var_num].var; + break; + } + } + } + else + { + mlog << Warning << "\n" << method_name << " -> " + << "Found multiple variables for grid_latitude, using \"" + << GET_NC_NAME_P(_yCoordVar) << "\".\n\n"; + } + } + + if (dim_standard_name == "grid_longitude") + { + if (_xDim == 0) + { + _xDim = _dims[dim_num]; + + x_dim_var_name = GET_NC_NAME_P(_xDim).c_str(); + for (int var_num = 0; var_num < Nvars; ++var_num) + { + if ( Var[var_num].name == GET_NC_NAME_P(_xDim)) + { + _xCoordVar = Var[var_num].var; + break; + } + } + } + else + { + mlog << Warning << "\n" << method_name << " -> " + << "Found multiple variables for grid_longitude, using \"" + << GET_NC_NAME_P(_xCoordVar) << "\".\n\n"; + } + } + + } + + if (_xDim == 0) + { + mlog << Error << "\n" << method_name << " -> " + << "Didn't find X dimension (degrees_east) in netCDF file.\n\n"; + exit(1); + } + + if (_yDim == 0) + { + mlog << Error << "\n" << method_name << " -> " + << "Didn't find Y dimension (degrees_north) in netCDF file.\n\n"; + exit(1); + } + + if (_xCoordVar == 0) + { + mlog << Error << "\n" << method_name << " -> " + << "Didn't find X coord variable (" << GET_NC_NAME_P(_xDim) + << ") in netCDF file.\n\n"; + exit(1); + } + + if (_yCoordVar == 0) + { + mlog << Error << "\n" << method_name << " -> " + << "Didn't find Y coord variable (" << GET_NC_NAME_P(_yDim) + << ") in netCDF file.\n\n"; + exit(1); + } + + long lon_counts = _xDim->getSize(); + long lat_counts = _yDim->getSize(); + if (get_data_size(_xCoordVar) != lon_counts || + get_data_size(_yCoordVar) != lat_counts) + { + mlog << Error << "\n" << method_name << " -> " + << "Coordinate variables don't match dimension sizes in netCDF file.\n\n"; + exit(1); + } + + // Store spacing in LatLon data structure + bool swap_to_north; + LatLonData ll_data = get_data_from_lat_lon_vars(_yCoordVar, _xCoordVar, + lat_counts, lon_counts, + swap_to_north); + + // Fill in the Rotated LatLon data structure + RotatedLatLonData data; + + data.name = rotated_latlon_proj_type; + + // Derive south pole location from the north pole + data.true_lat_south_pole = -1.0 * get_att_value_double(grid_np_lat_att); + double np_lon = rescale_lon(get_att_value_double(grid_np_lon_att)); + data.true_lon_south_pole = rescale_lon(-1.0 * (180.0 - fabs(np_lon))); + + // Copied from the LatLon data structure + data.rot_lat_ll = ll_data.lat_ll; + data.rot_lon_ll = ll_data.lon_ll; + data.delta_rot_lat = ll_data.delta_lat; + data.delta_rot_lon = ll_data.delta_lon; + + // Grid dimension + data.Nlon = _xDim->getSize(); + data.Nlat = _yDim->getSize(); + + data.aux_rotation = 0; + + grid.set(data); + + if(grid_np_lat_att) delete grid_np_lat_att; + if(grid_np_lon_att) delete grid_np_lon_att; } @@ -2865,17 +3040,36 @@ bool NcCfFile::get_grid_from_dimensions() //////////////////////////////////////////////////////////////////////// + void NcCfFile::get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var, const long lat_counts, const long lon_counts) { static const string method_name = "NcCfFile::get_grid_from_lat_lon_vars()"; + bool swap_to_north; + LatLonData data = get_data_from_lat_lon_vars(lat_var, lon_var, + lat_counts, lon_counts, + swap_to_north); + + grid.set(data); // resets swap_to_north to false + if (swap_to_north) grid.set_swap_to_north(true); +} + + +//////////////////////////////////////////////////////////////////////// + + +LatLonData NcCfFile::get_data_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var, + const long lat_counts, const long lon_counts, + bool &swap_to_north) { + static const string method_name = "get_data_from_lat_lon_vars()"; + // Figure out the dlat/dlon values from the dimension variables long x_size = get_data_size(lon_var); long y_size = get_data_size(lat_var); long latlon_counts = lon_counts*lat_counts; - bool two_dim_corrd = (x_size == latlon_counts) && (y_size == latlon_counts ); - if( !two_dim_corrd && (x_size != lon_counts || y_size != lat_counts)) + bool two_dim_coord = (x_size == latlon_counts) && (y_size == latlon_counts ); + if( !two_dim_coord && (x_size != lon_counts || y_size != lat_counts)) { mlog << Error << "\n" << method_name << " -> " << "Coordinate variables don't match dimension sizes in netCDF file.\n\n"; @@ -2885,7 +3079,7 @@ void NcCfFile::get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var, double lat_values[lat_counts]; double lon_values[lon_counts]; bool lat_first = false; - if (two_dim_corrd) { + if (two_dim_coord) { lat_first = (lat_counts == get_dim_size(lat_var, 0)); long cur[2], length[2]; cur[0] = cur[1] = 0; @@ -2992,19 +3186,24 @@ void NcCfFile::get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var, data.name = latlon_proj_type; data.lat_ll = lat_values[0]; - data.lon_ll = -lon_values[0]; + data.lon_ll = rescale_lon(-lon_values[0]); data.delta_lat = dlat; data.delta_lon = dlon; data.Nlat = lat_counts; data.Nlon = lon_counts; + if (dlat < 0) { + swap_to_north = true; data.delta_lat = -dlat; data.lat_ll = lat_values[lat_counts-1]; } + else { + swap_to_north = false; + } - grid.set(data); // resets swap_to_north to false - if (dlat < 0) grid.set_swap_to_north(true); + return(data); } + //////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.h b/met/src/libcode/vx_data2d_nccf/nccf_file.h index e3c2ecd0fe..e2acf3ee64 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.h +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.h @@ -181,6 +181,10 @@ class NcCfFile { bool get_grid_from_dimensions(); void get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var, const long lat_counts, const long lon_counts); + + LatLonData get_data_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var, + const long lat_counts, const long lon_counts, + bool &swap_to_north); }; diff --git a/met/src/libcode/vx_grid/gaussian_grid.cc b/met/src/libcode/vx_grid/gaussian_grid.cc index 9c1be2ff25..f6b1925f8e 100644 --- a/met/src/libcode/vx_grid/gaussian_grid.cc +++ b/met/src/libcode/vx_grid/gaussian_grid.cc @@ -370,19 +370,19 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString GaussianGrid::serialize() const +ConcatString GaussianGrid::serialize(const char *sep) const { ConcatString a; char junk[256]; -a << "Projection: Gaussian"; +a << "Projection: Gaussian" << sep; snprintf(junk, sizeof(junk), " Lon_Zero: %.4f", Lon_Zero); a << junk; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny; // // done diff --git a/met/src/libcode/vx_grid/gaussian_grid.h b/met/src/libcode/vx_grid/gaussian_grid.h index c45f7a6d06..d8d28d16f1 100644 --- a/met/src/libcode/vx_grid/gaussian_grid.h +++ b/met/src/libcode/vx_grid/gaussian_grid.h @@ -75,7 +75,7 @@ class GaussianGrid : public GridRep { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info() const; diff --git a/met/src/libcode/vx_grid/goes_grid.cc b/met/src/libcode/vx_grid/goes_grid.cc index c6cd53cdaa..12116ac429 100644 --- a/met/src/libcode/vx_grid/goes_grid.cc +++ b/met/src/libcode/vx_grid/goes_grid.cc @@ -307,17 +307,17 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString GoesImagerGrid::serialize() const +ConcatString GoesImagerGrid::serialize(const char *sep) const { ConcatString a; char junk[256]; -a << "Projection: GoesImager"; +a << "Projection: GoesImager" << sep; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny; //snprintf(junk, sizeof(junk), " Lat_LL: %.3f", Lat_LL); a << junk; //snprintf(junk, sizeof(junk), " Lon_LL: %.3f", Lon_LL); a << junk; diff --git a/met/src/libcode/vx_grid/goes_grid.h b/met/src/libcode/vx_grid/goes_grid.h index 9be97d95bb..899d0746d8 100644 --- a/met/src/libcode/vx_grid/goes_grid.h +++ b/met/src/libcode/vx_grid/goes_grid.h @@ -66,7 +66,7 @@ class GoesImagerGrid : public GridRep { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info () const; diff --git a/met/src/libcode/vx_grid/grid_base.cc b/met/src/libcode/vx_grid/grid_base.cc index 34b84484e4..07f06f890b 100644 --- a/met/src/libcode/vx_grid/grid_base.cc +++ b/met/src/libcode/vx_grid/grid_base.cc @@ -900,13 +900,13 @@ return ( rep->name() ); //////////////////////////////////////////////////////////////////////// -ConcatString Grid::serialize() const +ConcatString Grid::serialize(const char *sep) const { ConcatString s; -if ( rep ) s = rep->serialize(); +if ( rep ) s = rep->serialize(sep); return ( s ); diff --git a/met/src/libcode/vx_grid/grid_base.h b/met/src/libcode/vx_grid/grid_base.h index 4fdab9354e..eb77e04b4b 100644 --- a/met/src/libcode/vx_grid/grid_base.h +++ b/met/src/libcode/vx_grid/grid_base.h @@ -162,7 +162,7 @@ class GridRep : public GridInterface { virtual void dump(ostream &, int = 0) const = 0; - virtual ConcatString serialize() const = 0; + virtual ConcatString serialize(const char *sep=" ") const = 0; virtual GridInfo info() const = 0; @@ -240,7 +240,7 @@ class Grid : public GridInterface { ConcatString name() const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info() const; diff --git a/met/src/libcode/vx_grid/latlon_grid.cc b/met/src/libcode/vx_grid/latlon_grid.cc index 585a490b03..116d2274f2 100644 --- a/met/src/libcode/vx_grid/latlon_grid.cc +++ b/met/src/libcode/vx_grid/latlon_grid.cc @@ -286,7 +286,7 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString LatLonGrid::serialize() const +ConcatString LatLonGrid::serialize(const char *sep) const { @@ -294,18 +294,18 @@ ConcatString a; char junk[256]; -a << "Projection: Lat/Lon"; +a << "Projection: Lat/Lon" << sep; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny << sep; -snprintf(junk, sizeof(junk), " lat_ll: %.3f", lat_ll); a << junk; -snprintf(junk, sizeof(junk), " lon_ll: %.3f", lon_ll); a << junk; +snprintf(junk, sizeof(junk), "lat_ll: %.3f", lat_ll); a << junk << sep; +snprintf(junk, sizeof(junk), "lon_ll: %.3f", lon_ll); a << junk << sep; -snprintf(junk, sizeof(junk), " delta_lat: %.3f", delta_lat); a << junk; -snprintf(junk, sizeof(junk), " delta_lon: %.3f", delta_lon); a << junk; +snprintf(junk, sizeof(junk), "delta_lat: %.3f", delta_lat); a << junk << sep; +snprintf(junk, sizeof(junk), "delta_lon: %.3f", delta_lon); a << junk << sep; -snprintf(junk, sizeof(junk), " wrapLon: %s", bool_to_string(wrapLon)); a << junk; +snprintf(junk, sizeof(junk), "wrapLon: %s", bool_to_string(wrapLon)); a << junk; // // done diff --git a/met/src/libcode/vx_grid/latlon_grid.h b/met/src/libcode/vx_grid/latlon_grid.h index 3b2124ee8a..646e6df0c4 100644 --- a/met/src/libcode/vx_grid/latlon_grid.h +++ b/met/src/libcode/vx_grid/latlon_grid.h @@ -71,7 +71,7 @@ class LatLonGrid : public GridRep { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info() const; diff --git a/met/src/libcode/vx_grid/lc_grid.cc b/met/src/libcode/vx_grid/lc_grid.cc index b4ea96393d..9bd06ec71f 100644 --- a/met/src/libcode/vx_grid/lc_grid.cc +++ b/met/src/libcode/vx_grid/lc_grid.cc @@ -551,29 +551,29 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString LambertGrid::serialize() const +ConcatString LambertGrid::serialize(const char *sep) const { ConcatString a; char junk[256]; -a << "Projection: Lambert Conformal"; +a << "Projection: Lambert Conformal" << sep; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny << sep; -snprintf(junk, sizeof(junk), " Lat_LL: %.3f", Lat_LL); a << junk; -snprintf(junk, sizeof(junk), " Lon_LL: %.3f", Lon_LL); a << junk; +snprintf(junk, sizeof(junk), "Lat_LL: %.3f", Lat_LL); a << junk << sep; +snprintf(junk, sizeof(junk), "Lon_LL: %.3f", Lon_LL); a << junk << sep; -snprintf(junk, sizeof(junk), " Lon_orient: %.3f", Lon_orient); a << junk; +snprintf(junk, sizeof(junk), "Lon_orient: %.3f", Lon_orient); a << junk << sep; -snprintf(junk, sizeof(junk), " Alpha: %.3f", Alpha); a << junk; +snprintf(junk, sizeof(junk), "Alpha: %.3f", Alpha); a << junk << sep; -snprintf(junk, sizeof(junk), " Cone: %.3f", Cone); a << junk; +snprintf(junk, sizeof(junk), "Cone: %.3f", Cone); a << junk << sep; -snprintf(junk, sizeof(junk), " Bx: %.4f", Bx); a << junk; -snprintf(junk, sizeof(junk), " By: %.4f", By); a << junk; +snprintf(junk, sizeof(junk), "Bx: %.4f", Bx); a << junk << sep; +snprintf(junk, sizeof(junk), "By: %.4f", By); a << junk; // // done diff --git a/met/src/libcode/vx_grid/lc_grid.h b/met/src/libcode/vx_grid/lc_grid.h index 981b0cc80f..3d9ffc4f27 100644 --- a/met/src/libcode/vx_grid/lc_grid.h +++ b/met/src/libcode/vx_grid/lc_grid.h @@ -112,7 +112,7 @@ class LambertGrid : public GridRep { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info () const; diff --git a/met/src/libcode/vx_grid/merc_grid.cc b/met/src/libcode/vx_grid/merc_grid.cc index ac2f7c368b..1a20b022f6 100644 --- a/met/src/libcode/vx_grid/merc_grid.cc +++ b/met/src/libcode/vx_grid/merc_grid.cc @@ -503,29 +503,29 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString MercatorGrid::serialize() const +ConcatString MercatorGrid::serialize(const char *sep) const { ConcatString a; char junk[256]; -a << "Projection: Mercator"; +a << "Projection: Mercator" << sep; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny << sep; -snprintf(junk, sizeof(junk), " Lat_LL_radians: %.4f", Lat_LL_radians); a << junk; -snprintf(junk, sizeof(junk), " Lon_LL_radians: %.4f", Lon_LL_radians); a << junk; +snprintf(junk, sizeof(junk), "Lat_LL_radians: %.4f", Lat_LL_radians); a << junk << sep; +snprintf(junk, sizeof(junk), "Lon_LL_radians: %.4f", Lon_LL_radians); a << junk << sep; -snprintf(junk, sizeof(junk), " Lat_UR_radians: %.4f", Lat_UR_radians); a << junk; -snprintf(junk, sizeof(junk), " Lon_UR_radians: %.4f", Lon_UR_radians); a << junk; +snprintf(junk, sizeof(junk), "Lat_UR_radians: %.4f", Lat_UR_radians); a << junk << sep; +snprintf(junk, sizeof(junk), "Lon_UR_radians: %.4f", Lon_UR_radians); a << junk << sep; -snprintf(junk, sizeof(junk), " Mx: %.4f", Mx); a << junk; -snprintf(junk, sizeof(junk), " My: %.4f", My); a << junk; +snprintf(junk, sizeof(junk), "Mx: %.4f", Mx); a << junk << sep; +snprintf(junk, sizeof(junk), "My: %.4f", My); a << junk << sep; -snprintf(junk, sizeof(junk), " Bx: %.4f", Bx); a << junk; -snprintf(junk, sizeof(junk), " By: %.4f", By); a << junk; +snprintf(junk, sizeof(junk), "Bx: %.4f", Bx); a << junk << sep; +snprintf(junk, sizeof(junk), "By: %.4f", By); a << junk; // // done diff --git a/met/src/libcode/vx_grid/merc_grid.h b/met/src/libcode/vx_grid/merc_grid.h index b4c22cf661..c262cd9ebe 100644 --- a/met/src/libcode/vx_grid/merc_grid.h +++ b/met/src/libcode/vx_grid/merc_grid.h @@ -95,7 +95,7 @@ class MercatorGrid : public GridRep { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info() const; diff --git a/met/src/libcode/vx_grid/rot_latlon_grid.cc b/met/src/libcode/vx_grid/rot_latlon_grid.cc index d13f9ac2cd..b5a16ec227 100644 --- a/met/src/libcode/vx_grid/rot_latlon_grid.cc +++ b/met/src/libcode/vx_grid/rot_latlon_grid.cc @@ -300,7 +300,7 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString RotatedLatLonGrid::serialize() const +ConcatString RotatedLatLonGrid::serialize(const char *sep) const { @@ -308,23 +308,23 @@ ConcatString a; char junk[256]; -a << "Projection: Rotated Lat/Lon"; +a << "Projection: Rotated Lat/Lon" << sep; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny << sep; -snprintf(junk, sizeof(junk), " rot_lat_ll: %.3f", RData.rot_lat_ll); a << junk; -snprintf(junk, sizeof(junk), " rot_lon_ll: %.3f", RData.rot_lon_ll); a << junk; +snprintf(junk, sizeof(junk), "rot_lat_ll: %.3f", RData.rot_lat_ll); a << junk << sep; +snprintf(junk, sizeof(junk), "rot_lon_ll: %.3f", RData.rot_lon_ll); a << junk << sep; -snprintf(junk, sizeof(junk), " delta_rot_lat: %.3f", RData.delta_rot_lat); a << junk; -snprintf(junk, sizeof(junk), " delta_rot_lon: %.3f", RData.delta_rot_lon); a << junk; +snprintf(junk, sizeof(junk), "delta_rot_lat: %.3f", RData.delta_rot_lat); a << junk << sep; +snprintf(junk, sizeof(junk), "delta_rot_lon: %.3f", RData.delta_rot_lon); a << junk << sep; -snprintf(junk, sizeof(junk), " wrapLon: %s", bool_to_string(wrapLon)); a << junk; +snprintf(junk, sizeof(junk), "wrapLon: %s", bool_to_string(wrapLon)); a << junk << sep; -snprintf(junk, sizeof(junk), " true_lat_south_pole: %.3f", RData.true_lat_south_pole); a << junk; -snprintf(junk, sizeof(junk), " true_lon_south_pole: %.3f", RData.true_lon_south_pole); a << junk; +snprintf(junk, sizeof(junk), "true_lat_south_pole: %.3f", RData.true_lat_south_pole); a << junk << sep; +snprintf(junk, sizeof(junk), "true_lon_south_pole: %.3f", RData.true_lon_south_pole); a << junk << sep; -snprintf(junk, sizeof(junk), " aux_rotation: %.3f", RData.aux_rotation); a << junk; +snprintf(junk, sizeof(junk), "aux_rotation: %.3f", RData.aux_rotation); a << junk; // // done diff --git a/met/src/libcode/vx_grid/rot_latlon_grid.h b/met/src/libcode/vx_grid/rot_latlon_grid.h index 456b505dc1..b6eb9e8442 100644 --- a/met/src/libcode/vx_grid/rot_latlon_grid.h +++ b/met/src/libcode/vx_grid/rot_latlon_grid.h @@ -64,7 +64,7 @@ class RotatedLatLonGrid : public LatLonGrid { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info() const; diff --git a/met/src/libcode/vx_grid/st_grid.cc b/met/src/libcode/vx_grid/st_grid.cc index 5ed2ed9cf6..b0b79bd12d 100644 --- a/met/src/libcode/vx_grid/st_grid.cc +++ b/met/src/libcode/vx_grid/st_grid.cc @@ -483,26 +483,26 @@ return; //////////////////////////////////////////////////////////////////////// -ConcatString StereographicGrid::serialize() const +ConcatString StereographicGrid::serialize(const char *sep) const { ConcatString a; char junk[256]; -a << "Projection: Stereographic"; +a << "Projection: Stereographic" << sep; -a << " Nx: " << Nx; -a << " Ny: " << Ny; +a << "Nx: " << Nx << sep; +a << "Ny: " << Ny << sep; -a << " IsNorthHemisphere: " << ( IsNorthHemisphere ? "true" : "false"); +a << "IsNorthHemisphere: " << ( IsNorthHemisphere ? "true" : "false") << sep; -snprintf(junk, sizeof(junk), " Lon_orient: %.3f", Lon_orient); a << junk; +snprintf(junk, sizeof(junk), "Lon_orient: %.3f", Lon_orient); a << junk << sep; -snprintf(junk, sizeof(junk), " Bx: %.3f", Bx); a << junk; -snprintf(junk, sizeof(junk), " By: %.3f", By); a << junk; +snprintf(junk, sizeof(junk), "Bx: %.3f", Bx); a << junk << sep; +snprintf(junk, sizeof(junk), "By: %.3f", By); a << junk << sep; -snprintf(junk, sizeof(junk), " Alpha: %.4f", Alpha); a << junk; +snprintf(junk, sizeof(junk), "Alpha: %.4f", Alpha); a << junk; // // done diff --git a/met/src/libcode/vx_grid/st_grid.h b/met/src/libcode/vx_grid/st_grid.h index c0d6b28a86..5ee9747f5b 100644 --- a/met/src/libcode/vx_grid/st_grid.h +++ b/met/src/libcode/vx_grid/st_grid.h @@ -93,7 +93,7 @@ class StereographicGrid : public GridRep { void dump(ostream &, int = 0) const; - ConcatString serialize() const; + ConcatString serialize(const char *sep=" ") const; GridInfo info() const; diff --git a/test/xml/unit_regrid.xml b/test/xml/unit_regrid.xml index 512b4f0a6c..869be79a53 100644 --- a/test/xml/unit_regrid.xml +++ b/test/xml/unit_regrid.xml @@ -373,4 +373,20 @@
+ + + + &MET_BIN;/regrid_data_plane + \ + &DATA_DIR_MODEL;/nccf/india_rotated_unrotated_grid.nc \ + "latlon 250 220 -10 54 0.25 0.25" \ + &OUTPUT_DIR;/regrid/regrid_data_plane_NC_ROT_LAT_LON.nc \ + -field 'name="number_of_lightning_flashes"; level="(*,*)";' \ + -method MAX -width 5 + + + &OUTPUT_DIR;/regrid/regrid_data_plane_NC_ROT_LAT_LON.nc + + +
From 6ec6e71393748133fbb2eef7968a6edb303c2b47 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 9 Feb 2022 11:37:22 -0700 Subject: [PATCH 099/172] #2044 Renamed obs_prefbufr_map to obs_prepbufr_map (typo) --- met/data/config/PB2NCConfig_default | 2 +- met/docs/Users_Guide/config_options.rst | 6 +++--- met/src/basic/vx_config/config_constants.h | 2 +- met/src/libcode/vx_nc_obs/nc_obs_util.h | 2 +- test/config/PB2NCConfig_airnow | 2 +- test/config/PB2NCConfig_pbl | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/met/data/config/PB2NCConfig_default b/met/data/config/PB2NCConfig_default index 82750e9912..e11fa94e30 100644 --- a/met/data/config/PB2NCConfig_default +++ b/met/data/config/PB2NCConfig_default @@ -107,7 +107,7 @@ obs_bufr_map = []; // abbreviations in the output. This default map is appended to obs_bufr_map. // This should not typically be overridden. // -obs_prefbufr_map = [ +obs_prepbufr_map = [ { key = "POB"; val = "PRES"; }, { key = "QOB"; val = "SPFH"; }, { key = "TOB"; val = "TMP"; }, diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index 9f568932bd..8fcff91730 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -3542,9 +3542,9 @@ of the forecast the observation is used to verify. obs_bufr_map = []; -.. _obs_prefbufr_map: +.. _obs_prepbufr_map: -:ref:`obs_prefbufr_map ` +:ref:`obs_prepbufr_map ` Default mapping for PREPBUFR. Replace input BUFR variable names with GRIB abbreviations in the output. This default map is appended to obs_bufr_map. @@ -3554,7 +3554,7 @@ abbreviations to the output. .. code-block:: none - obs_prefbufr_map = [ + obs_prepbufr_map = [ { key = "POB"; val = "PRES"; }, { key = "QOB"; val = "SPFH"; }, { key = "TOB"; val = "TMP"; }, diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index 4649c555a4..f3c5550f02 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -571,7 +571,7 @@ static const char conf_key_message_type_group_map[] = "message_type_group_map"; static const char conf_key_obs_bufr_map[] = "obs_bufr_map"; static const char conf_key_obs_bufr_var[] = "obs_bufr_var"; static const char conf_key_obs_name_map[] = "obs_name_map"; -static const char conf_key_obs_prefbufr_map[] = "obs_prefbufr_map"; +static const char conf_key_obs_prepbufr_map[] = "obs_prepbufr_map"; static const char conf_key_key[] = "key"; static const char conf_key_val[] = "val"; static const char conf_key_boot_interval[] = "boot.interval"; diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.h b/met/src/libcode/vx_nc_obs/nc_obs_util.h index b6d25bf1af..2d8a06ca2c 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.h +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.h @@ -98,7 +98,7 @@ struct NetcdfObsVars { NcDim obs_arr_dim ; // Observation array width (V1.0, not used from V1.2) NcDim obs_dim ; // Observation array length (V1.0) NcDim hdr_dim ; // Header array length (V1.0) - NcDim pb_hdr_dim ; // PrefBufr Header array length (V1.2) + NcDim pb_hdr_dim ; // PrepfBufr Header array length (V1.2) NcVar hdr_typ_tbl_var ; // Message type (string) (V1.1) NcVar hdr_sid_tbl_var ; // Station ID (string) (V1.1) diff --git a/test/config/PB2NCConfig_airnow b/test/config/PB2NCConfig_airnow index f9cba2c0bb..5fd9a2b01d 100644 --- a/test/config/PB2NCConfig_airnow +++ b/test/config/PB2NCConfig_airnow @@ -94,7 +94,7 @@ obs_bufr_map = []; // This map is for PREPBUFR. It will be added into obs_bufr_map. // Please do not override this map. // -obs_prefbufr_map = [ +obs_prepbufr_map = [ { key = "POB"; val = "PRES"; }, { key = "QOB"; val = "SPFH"; }, { key = "TOB"; val = "TMP"; }, diff --git a/test/config/PB2NCConfig_pbl b/test/config/PB2NCConfig_pbl index eeedd7a3e4..924c06a54c 100644 --- a/test/config/PB2NCConfig_pbl +++ b/test/config/PB2NCConfig_pbl @@ -106,7 +106,7 @@ obs_bufr_map = []; // abbreviations in the output. This default map is appended to obs_bufr_map. // This should not typically be overridden. // -obs_prefbufr_map = [ +obs_prepbufr_map = [ { key = "POB"; val = "PRES"; }, { key = "QOB"; val = "SPFH"; }, { key = "TOB"; val = "TMP"; }, From b4ec7b8201b4b917a51e6c0dec7631d093bd3c71 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Wed, 9 Feb 2022 11:42:15 -0700 Subject: [PATCH 100/172] #1996 Initialize i_point --- met/src/tools/core/series_analysis/series_analysis.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/met/src/tools/core/series_analysis/series_analysis.cc b/met/src/tools/core/series_analysis/series_analysis.cc index 6a33eefd73..72a897fa02 100644 --- a/met/src/tools/core/series_analysis/series_analysis.cc +++ b/met/src/tools/core/series_analysis/series_analysis.cc @@ -670,9 +670,10 @@ void process_scores() { // Number of points skipped due to valid data threshold int n_skip_zero = 0; int n_skip_pos = 0; - + // Loop over the data reads for(i_read=0; i_read Date: Wed, 9 Feb 2022 17:31:14 -0700 Subject: [PATCH 101/172] #2044 Corrected config key for obs_prefbufr_map and give a warning for using the old key --- met/src/basic/vx_config/config_util.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index bfdeef07b2..1b655034ac 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -24,6 +24,7 @@ using namespace std; /////////////////////////////////////////////////////////////////////////////// static const double default_vld_thresh = 1.0; +static const char conf_key_prepbufr_map_typo[] = "obs_prefbufr_map"; // for backward compatibility /////////////////////////////////////////////////////////////////////////////// @@ -1089,7 +1090,13 @@ map parse_conf_metadata_map(Dictionary *dict) { /////////////////////////////////////////////////////////////////////////////// map parse_conf_obs_bufr_map(Dictionary *dict) { - map m = parse_conf_key_value_map(dict, conf_key_obs_prefbufr_map); + map m = parse_conf_key_value_map(dict, conf_key_obs_prepbufr_map); + if (m.empty()) { + //kludge: there was a typo in the config name + m = parse_conf_key_value_map(dict, conf_key_prepbufr_map_typo); + mlog << Warning << "\nPlease rename the configuration name \"" << conf_key_prepbufr_map_typo + << "\" to \"" << conf_key_obs_prepbufr_map << "\" at the customized PB2NC config file\n\n"; + } parse_add_conf_key_value_map(dict, conf_key_obs_bufr_map, &m); return m; } From 9c45689439be6b1eaff6fd47b320cb5a511b05e6 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 10 Feb 2022 11:30:51 -0700 Subject: [PATCH 102/172] CI: output summary of differences in GHA log to easily see results without having to download the log artifact --- .github/jobs/copy_diff_files.py | 19 ++++++++++++++++--- .github/jobs/run_diff_docker.sh | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/jobs/copy_diff_files.py b/.github/jobs/copy_diff_files.py index eed5b6a339..213f99709e 100755 --- a/.github/jobs/copy_diff_files.py +++ b/.github/jobs/copy_diff_files.py @@ -9,18 +9,22 @@ LOG_DIR = '/met/logs' +LINE_BREAK = '# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #' + def get_files_with_diffs(log_file): files_to_copy = set() + error_text_list = [] with open(log_file, 'r') as file_handle: file_content = file_handle.read() missing_section, *test_sections = file_content.split( - '\n# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n' + f'\n{LINE_BREAK}\n' ) # parse list of missing files if 'ERROR:' in missing_section: + error_text_list.append(missing_section) for missing_group in missing_section.split('ERROR:')[1:]: dir_str, *rel_paths = missing_group.splitlines() dir_str = dir_str.split()[1] @@ -36,13 +40,14 @@ def get_files_with_diffs(log_file): # parse file paths out of sections that have errors error_sections = [item for item in test_sections if 'ERROR:' in item] + error_text_list.extend(error_sections) for error_section in error_sections: for line in error_section.splitlines(): for item in line.split(): if OUTPUT_DIR in item or TRUTH_DIR in item: files_to_copy.add(item) - return files_to_copy + return files_to_copy, error_text_list def copy_files_to_diff_dir(files_to_copy): @@ -69,12 +74,20 @@ def copy_files_to_diff_dir(files_to_copy): os.makedirs(output_dir) shutil.copyfile(filename, output_path) + def main(): log_file = os.path.join(LOG_DIR, 'comp_dir.log') print(f"Parsing {log_file}") - all_files_to_copy = get_files_with_diffs(log_file) + all_files_to_copy, error_text_list = get_files_with_diffs(log_file) copy_files_to_diff_dir(all_files_to_copy) + # print error summary + if error_text_list: + print("\n\n**************\nERROR SUMMARY:\n**************\n") + + print(f'\n{LINE_BREAK}\n'.join(error_text_list)) + + if __name__ == "__main__": main() diff --git a/.github/jobs/run_diff_docker.sh b/.github/jobs/run_diff_docker.sh index b4095fb21e..7aa1b4c1f8 100755 --- a/.github/jobs/run_diff_docker.sh +++ b/.github/jobs/run_diff_docker.sh @@ -36,6 +36,8 @@ if [ $? != 0 ]; then fi if [ "$(ls -A ${LOCAL_DIFF_DIR})" ]; then + cat ${LOCAL_LOG_DIR}/copy_diff_files.log + echo "ERROR: Differences exist in the output" # only exit non-zero (job fails) if not updating truth data From b2e7276127204c7967179e47c3684ddbdbe6d736 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 11:52:58 -0700 Subject: [PATCH 103/172] #2027 Added a debug message --- met/src/libcode/vx_statistics/met_stats.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index a5eae44574..3501c1e02c 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1534,6 +1534,7 @@ void VL1L2Info::assign(const VL1L2Info &c) { void VL1L2Info::calc_ncep_stats() { double u_diff, v_diff; int n = vcount; + const char *method_name = "VL1L2Info::calc_ncep_stats() -> "; u_diff = uf_bar - uo_bar; v_diff = vf_bar - vo_bar; @@ -1569,6 +1570,11 @@ void VL1L2Info::calc_ncep_stats() { DIR_ABSERR = fabs(DIR_ERR); + mlog << Debug(9) << method_name << "DIR_ERR=" << DIR_ERR + << " from vf_bar=" << vf_bar << ", uo_bar=" << uo_bar + << ", uf_bar=" << uf_bar << ", vo_bar=" << vo_bar + << "\n"; + return; } From c9ba6f150ff352b96cf441d081cf424780dd3c7e Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 11:56:20 -0700 Subject: [PATCH 104/172] #2027 ci-run-unit Changed wind thres --- test/config/GridStatConfig_fourier | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config/GridStatConfig_fourier b/test/config/GridStatConfig_fourier index ad8c121b23..ae4e33c118 100644 --- a/test/config/GridStatConfig_fourier +++ b/test/config/GridStatConfig_fourier @@ -47,7 +47,7 @@ mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; -wind_thresh = [ NA ]; +wind_thresh = [ >5.0 ]; wind_logic = UNION; eclv_points = 0.05; nc_pairs_var_name = ""; From c1b2022c4ee479f70172c8803b3e6b32e7ac5629 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 13:37:41 -0700 Subject: [PATCH 105/172] #2027 ci-run-unit Increased the precision to debug message --- met/src/libcode/vx_statistics/met_stats.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 3501c1e02c..5c2063a504 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1570,10 +1570,11 @@ void VL1L2Info::calc_ncep_stats() { DIR_ABSERR = fabs(DIR_ERR); + char buffer [512]; + int buf_len = sprintf(buffer, "vf_bar=%25.18e, uo_bar=%25.18e, uf_bar=%25.18e, vo_bar=%25.18e", + vf_bar, uo_bar, uf_bar, vo_bar); mlog << Debug(9) << method_name << "DIR_ERR=" << DIR_ERR - << " from vf_bar=" << vf_bar << ", uo_bar=" << uo_bar - << ", uf_bar=" << uf_bar << ", vo_bar=" << vo_bar - << "\n"; + << " from " << buffer << "\n"; return; } From 47bfef6dc5ddf8ec5a48388a99be29d856ee7d14 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 10 Feb 2022 14:49:23 -0700 Subject: [PATCH 106/172] print end of script after error summary, ci-run-unit --- .github/jobs/copy_diff_files.py | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/jobs/copy_diff_files.py b/.github/jobs/copy_diff_files.py index 213f99709e..40ddd68fbc 100755 --- a/.github/jobs/copy_diff_files.py +++ b/.github/jobs/copy_diff_files.py @@ -88,6 +88,7 @@ def main(): print(f'\n{LINE_BREAK}\n'.join(error_text_list)) + print("End of script") if __name__ == "__main__": main() From 348d05e32782320108c901fbcf65e6751d5712c1 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 15:31:43 -0700 Subject: [PATCH 107/172] #2027 Increased the buffer and cheking the status of sprintf --- met/src/libcode/vx_statistics/met_stats.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 5c2063a504..90bbcde460 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1570,11 +1570,11 @@ void VL1L2Info::calc_ncep_stats() { DIR_ABSERR = fabs(DIR_ERR); - char buffer [512]; - int buf_len = sprintf(buffer, "vf_bar=%25.18e, uo_bar=%25.18e, uf_bar=%25.18e, vo_bar=%25.18e", - vf_bar, uo_bar, uf_bar, vo_bar); - mlog << Debug(9) << method_name << "DIR_ERR=" << DIR_ERR - << " from " << buffer << "\n"; + char buffer[1024]; + int buf_len = sprintf(buffer, "DIR_ERR=%25.18e from uf_bar=%25.18e, vf_bar=%25.18e, uo_bar=%25.18e, vo_bar=%25.18e", + DIR_ERR, uf_bar, vf_bar, uo_bar, vo_bar); + if (buf_len > 0) mlog << Debug(9) << method_name << buffer<< "\n"; + else mlog << Warning << "\n" << method_name << "Please increase buffer for sprintf\n\n"; return; } From a79cd9bed5844a8557b72feca756f3c11ad7b78a Mon Sep 17 00:00:00 2001 From: lisagoodrich <33230218+lisagoodrich@users.noreply.github.com> Date: Thu, 10 Feb 2022 17:15:22 -0700 Subject: [PATCH 108/172] Feature 1998 standard sections (#2038) * fixing section headers to be consistent with METplus #1998 * fixing section headers to be consistent with METplus #1998 * fixing section headers to be consistent with METplus #1998 missed one * fixing section headers to be consistent with METplus #1998 try again * fixing section headers to be consistent with METplus #1998 I had it right the first time * fixing section headers to be consistent with METplus #1998 * fixing section headers to be consistent with METplus #1998 fixing mistake * fixing section headers to be consistent with METplus #1998 * fixing section headers to be consistent with METplus #1998 * fixing section headers to be consistent with METplus #1998 * fixing section headers to be consistent with METplus #1998 * fixing section header underscore to dash #1998 * updating TOC vs ref 1998 * updating TOC vs ref 1998 completed * trying to fix link #1998 * trying to fix link adding reference back in #1998 * updating TOC again underscore vs dash #1998 * updating TOC again underscore vs dash #1998 * updating TOC vs ref 1998 try * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 take 2 * standardizing TOC sections #1998 take 3 * re-standardizing TOC sections #1998 * re-standardizing TOC sections #1998 * re-standardizing TOC sections #1998 * re-standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 * updating questions into the TOC. test #1998 * updating questions into the TOC. #1998 * standardizing TOC sections #1998 * standardizing TOC sections #1998 fixing typo * standardizing TOC sections #1998 fixing typo * standardizing TOC sections #1998 fixing typo * standardizing TOC sections #1998 fixing typo * standardizing TOC sections #1998 fixing typo * standardizing TOC sections #1998 fixing typo * cleaning up questions. removing section title from questions. * adding a period #1989. * adding the line breaks back in to match other formatting within MET #1989. * Changed some "^^^" to "----" * Changed "###" to "***" Co-authored-by: jprestop --- met/docs/Users_Guide/appendixA.rst | 279 +++++++----- met/docs/Users_Guide/appendixB.rst | 11 +- met/docs/Users_Guide/appendixC.rst | 191 +++++---- met/docs/Users_Guide/appendixD.rst | 3 +- met/docs/Users_Guide/appendixE.rst | 3 +- met/docs/Users_Guide/appendixF.rst | 17 +- met/docs/Users_Guide/appendixG.rst | 3 +- met/docs/Users_Guide/config_options.rst | 477 +++++++++------------ met/docs/Users_Guide/config_options_tc.rst | 326 ++++++-------- met/docs/Users_Guide/data_io.rst | 17 +- met/docs/Users_Guide/ensemble-stat.rst | 23 +- met/docs/Users_Guide/gen-ens-prod.rst | 23 +- met/docs/Users_Guide/grid-diag.rst | 13 +- met/docs/Users_Guide/grid-stat.rst | 31 +- met/docs/Users_Guide/gsi-tools.rst | 15 +- met/docs/Users_Guide/index.rst | 4 +- met/docs/Users_Guide/installation.rst | 51 +-- met/docs/Users_Guide/masking.rst | 11 +- met/docs/Users_Guide/met-tc_overview.rst | 11 +- met/docs/Users_Guide/mode-analysis.rst | 15 +- met/docs/Users_Guide/mode-td.rst | 31 +- met/docs/Users_Guide/mode.rst | 23 +- met/docs/Users_Guide/overview.rst | 17 +- met/docs/Users_Guide/plotting.rst | 21 +- met/docs/Users_Guide/point-stat.rst | 23 +- met/docs/Users_Guide/reformat_grid.rst | 31 +- met/docs/Users_Guide/reformat_point.rst | 104 +++-- met/docs/Users_Guide/refs.rst | 3 +- met/docs/Users_Guide/release-notes.rst | 16 +- met/docs/Users_Guide/rmw-analysis.rst | 13 +- met/docs/Users_Guide/series-analysis.rst | 13 +- met/docs/Users_Guide/stat-analysis.rst | 33 +- met/docs/Users_Guide/tc-dland.rst | 11 +- met/docs/Users_Guide/tc-gen.rst | 15 +- met/docs/Users_Guide/tc-pairs.rst | 13 +- met/docs/Users_Guide/tc-rmw.rst | 13 +- met/docs/Users_Guide/tc-stat.rst | 21 +- met/docs/Users_Guide/wavelet-stat.rst | 21 +- 38 files changed, 935 insertions(+), 1011 deletions(-) diff --git a/met/docs/Users_Guide/appendixA.rst b/met/docs/Users_Guide/appendixA.rst index d5e3752ecf..7bf41e810b 100644 --- a/met/docs/Users_Guide/appendixA.rst +++ b/met/docs/Users_Guide/appendixA.rst @@ -1,15 +1,17 @@ .. _appendixA: +******************************** Appendix A FAQs & How do I ... ? -================================ +******************************** Frequently Asked Questions -__________________________ +========================== File-IO -~~~~~~~ +------- -**Q. File-IO - How do I improve the speed of MET tools using Gen-Vx-Mask?** +Q. How do I improve the speed of MET tools using Gen-Vx-Mask? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. The main reason to run gen_vx_mask is to make the MET @@ -23,7 +25,8 @@ recomputing the mask when each MET statistics tool is run. If the polyline only contains a small number of points or the grid is sparse running gen_vx_mask first would only save a second or two. -**Q. File-IO - How do I use map_data?** +Q. How do I use map_data? +^^^^^^^^^^^^^^^^^^^^^^^^^ A. The MET repository includes several map data files. Users can modify which @@ -64,7 +67,8 @@ in the configuration string on the command line: "${MET_BUILD_BASE}/data/map/admin_by_country/admin_China_data"; } \ ]; }' -**Q. FILE-IO - How can I understand the number of matched pairs?** +Q. How can I understand the number of matched pairs? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Statistics are computed on matched forecast/observation pairs data. @@ -113,7 +117,8 @@ none of the point observations match the variable name requested in the configuration file. So all of the 1166 observations are rejected for the same reason. -**Q. FILE-IO - What types of NetCDF files can MET read?** +Q. What types of NetCDF files can MET read? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. There are three flavors of NetCDF that MET can read directly. @@ -137,7 +142,8 @@ While MET's point2grid tool does support some satellite data inputs, it is limited. Using python embedding is another option for handling new datasets not supported natively by MET. -**Q. FILE-IO - How do I choose a time slice in a NetCDF file?** +Q. How do I choose a time slice in a NetCDF file? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. When processing NetCDF files, the level information needs to be @@ -157,7 +163,8 @@ Let's use plot_data_plane as an example: Assuming that the first array is the time, this will select the 6-th time slice of the APCP data and plot it since these indices are 0-based. -**Q. FILE-IO - How do I use the UNIX time conversion?** +Q. How do I use the UNIX time conversion? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Regarding the timing information in the NetCDF variable attributes: @@ -195,7 +202,8 @@ subset the TRMM data if needed. Look for the section of it titled "Output domain specification" and define the lat/lon's that needs to be included in the output. -**Q. Does MET use a fixed-width output format for its ASCII output files?** +Q. Does MET use a fixed-width output format for its ASCII output files? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. MET does not use the Fortran-like fixed width format in its @@ -218,7 +226,8 @@ If a fixed-width format is needed, the easiest option would be writing a script to post-process the MET output into the fixed-width format that is needed or that the code expects. -**Q. Do the ASCII output files created by MET use scientific notation?** +Q. Do the ASCII output files created by MET use scientific notation? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. By default, the ASCII output files created by MET make use of @@ -233,12 +242,11 @@ MET to disable the use of scientific notation. That enhancement is planned for a future release. Gen-Vx-Mask -~~~~~~~~~~~ +----------- -**Q. Gen-Vx-Mask - I have a list of stations to use for verification. -I also have a poly region defined. If I specify both of these should -the result be a union of them?** - +Q. I have a list of stations to use for verification. I also have a poly region defined. If I specify both of these should the result be a union of them? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. These settings are defined in the "mask" section of the Point-Stat configuration file. You can define masking regions in one of 3 ways, @@ -266,7 +274,8 @@ If so, your options are: Then aggregate the results together by running a Stat-Analysis job. -**Q. Gen-Vx-Mask - How do I define a masking region with a GFS file?** +Q. How do I define a masking region with a GFS file? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Grab a sample GFS file: @@ -301,9 +310,10 @@ are obvious problems with the latitude and longitude values used to define that mask for Poland. Grid-Stat -~~~~~~~~~ +--------- -**Q. Grid-Stat - How do I define a complex masking region?** +Q. How do I define a complex masking region? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. A user can define intersections and unions of multiple fields to define masks. @@ -359,8 +369,8 @@ apply complex masking logic and then pass the output mask file to Grid-Stat in its configuration file. -**Q. Grid-Stat - How do I use neighborhood methods to compute fraction -skill score?** +Q. How do I use neighborhood methods to compute fraction skill score? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. A common application of fraction skill score (FSS) is comparing forecast @@ -400,7 +410,8 @@ Setting vld_thresh = 1.0 will ensure that FSS will only be computed at points where all NxN values contain valid data. Setting it to 0.5 only requires half of them. -**Q. Grid-Stat - Is an example of verifying forecast probabilities?** +Q. Is an example of verifying forecast probabilities? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. There is an example of verifying probabilities in the test scripts @@ -443,8 +454,8 @@ values between 0 and 1. Note that if the probability data contains values from 0 to 100, MET automatically divides by 100 to rescale to the 0 to 1 range. -**Q. What is an example of using Grid-Stat with regridding and masking -turned on?** +Q. What is an example of using Grid-Stat with regridding and masking turned on? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Run Grid-Stat using the following commands and the attached config file @@ -503,9 +514,9 @@ gen_vx_mask tool and pass the NetCDF output of that tool to grid_stat. The advantage to gen_vx_mask is that it will make grid_stat run a bit faster. It can be used to construct much more complex masking areas. -**Q. How do I use one mask for the forecast field and a different -mask for the observation field??** - +Q. How do I use one mask for the forecast field and a different mask for the observation field? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. You can't define different masks for the forecast and observation fields in MET tools. MET only lets you @@ -577,9 +588,10 @@ In the resulting plot, anywhere you see the pink value of 10, that's where gen_vx_mask has masked out the grid point. Pcp-Combine -~~~~~~~~~~~ +----------- -**Q. Pcp-Combine - How do I add and subtract with Pcp-Combine?** +Q. How do I add and subtract with Pcp-Combine? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. An example of running the MET pcp_combine tool to put NAM 3-hourly @@ -616,8 +628,8 @@ same file format, and can use the same configuration file settings for the other MET tools (grid_stat, mode, etc.). If the NAM files are a mix of GRIB and NetCDF, the logic would need to be a bit more complicated. -**Q. Pcp-Combine - How do I combine 12-hour accumulated precipitation -from two different initialization times?** +Q. How do I combine 12-hour accumulated precipitation from two different initialization times? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. The "-sum" command assumes the same initialization time. Use the "-add" @@ -658,7 +670,8 @@ Here are 3 commands you could use to plot these data files: plot_data_plane sum.nc sum.ps 'name="APCP_24"; level="(*,*)";' -**Q. Pcp-Combine - How do I correct a precipitation time range?** +Q. How do I correct a precipitation time range? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Typically, accumulated precipitation is stored in GRIB files using an @@ -707,8 +720,8 @@ Here is an example: The resulting file should have the accumulation listed at 24h rather than 0-24. -**Pcp-Combine - How do I use Pcp-Combine as a pass-through to simply reformat -from GRIB to NetCDF or to change output variable name?** +Q. How do I use Pcp-Combine as a pass-through to simply reformat from GRIB to NetCDF or to change output variable name? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. The pcp_combine tool is typically used to modify the accumulation interval @@ -745,7 +758,8 @@ appear in the output of downstream tools: 'name="REFC"; level="L0"; GRIB1_ptv=129; lead_time="120000";' \ forecast.nc -name CompositeReflectivity -**Q. Pcp-Combine - How do I use “-pcprx" to run a project faster?** +Q. How do I use “-pcprx" to run a project faster? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. To run a project faster, the “-pcprx” option may be used to narrow the @@ -765,7 +779,8 @@ examples: -pcpdir /scratch4/BMC/shout/ptmp/Andrew.Kren/pre2016c3_corr/temp \ -pcprx 'pgbq[0-9][0-9].gfs.2016022118' -v 3 -**Q. Pcp-Combine - How do I enter the time format correctly?** +Q. How do I enter the time format correctly? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Here is an **incorrect example** of running pcp_combine with sub-hourly @@ -796,9 +811,9 @@ time strings, like this: pcp_combine -subtract forecast.grb 005500 \ forecast2.grb 000500 forecast.nc -field APCP -**Q. Pcp-Combine - How do I use Pcp-Combine when my GRIB data doesn't have the -appropriate accumulation interval time range indicator?** - +Q. How do I use Pcp-Combine when my GRIB data doesn't have the appropriate accumulation interval time range indicator? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Run wgrib on the data files and the output is listed below: @@ -855,9 +870,9 @@ Some things to point out here: chosen will be used in the Grid-Stat, Point-Stat, or MODE config file to tell that tool what variable to process. -**Q. Pcp_Combine - How do I use “-sum”, “-add”, and “-subtract“ to achieve -the same accumulation interval?** - +Q. How do I use “-sum”, “-add”, and “-subtract“ to achieve the same accumulation interval? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Here is an example of using pcp_combine to put GFS into 24- hour intervals for comparison against 24-hourly StageIV precipitation with GFS data @@ -921,14 +936,16 @@ This example explicitly tells pcp_combine which files to read and what accumulation interval (6 hours) to extract from them. The resulting output should be identical to the output of the "-sum" command. -**Q. Pcp-Combine - What is the difference between “-sum” vs. “-add”?** +Q. What is the difference between “-sum” vs. “-add”? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. The -sum and -add options both do the same thing. It's just that '-sum' could find files more quickly with the use of the -pcprx flag. This could also be accomplished by using a calling script. -**Q. Pcp-Combine - How do I select a specific GRIB record?** +Q. How do I select a specific GRIB record? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. In this example, record 735 needs to be selected. @@ -943,9 +960,10 @@ Instead of having the level as "L0", tell it to use "R735" to select grib record 735. Plot-Data-Plane -~~~~~~~~~~~~~~~ +--------------- -**Q. Plot-Data-Plane - How do I inspect Gen-Vx-Mask output?** +Q. How do I inspect Gen-Vx-Mask output? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Check to see if the call to Gen-Vx-Mask actually did create good output @@ -971,8 +989,9 @@ file is what the user expects. It always a good idea to start with plot_data_plane when working with data to make sure MET is plotting the data correctly and in the expected location. -**Q. Plot-Data-Plane - How do I specify the GRIB version?** - +Q. How do I specify the GRIB version? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. When MET reads Gridded data files, it must determine the type of file it's reading. The first thing it checks is the suffix of the file. @@ -1002,8 +1021,8 @@ MET configuration files (i.e. Grid-Stat, MODE, and so on) that you use: -plot_range 0 100 -**Q. Plot-Data-Plane - How do I test the variable naming convention? -(Record number example)** +Q. How do I test the variable naming convention? (Record number example.) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. Make sure MET can read GRIB2 data. Plot the data from that GRIB2 file @@ -1022,8 +1041,9 @@ contain temperature data and 2-meters. Here's some wgrib2 output: The GRIB id info has been the same between records 1 and 2. -**Q. Plot-Data-Plane - How do I compute and verify wind speed?** - +Q. How do I compute and verify wind speed? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Here's how to compute and verify wind speed using MET. Good news, MET already includes logic for deriving wind speed on the fly. The GRIB @@ -1053,10 +1073,11 @@ In the second one, this won't appear since wind speed already exists in the RTMA file. Stat-Analysis -~~~~~~~~~~~~~ - -**Q. Stat-Analysis - How does '-aggregate_stat' work?** +------------- +Q. How does '-aggregate_stat' work? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. In Stat-Analysis, there is a "-vx_mask" job filtering option. That option reads the VX_MASK column from the input STAT lines and applies string @@ -1098,10 +1119,9 @@ of the unique values found in that column. Presumably, all the input VX_MASK columns say "FULL" so that's what the output would say. Use "-set_hdr" to explicitly set the output value. -**Q. Stat-Analysis - What is the best way to average the FSS scores -within several days or even several months using -'Aggregate to Average Scores'?** - +Q. What is the best way to average the FSS scores within several days or even several months using 'Aggregate to Average Scores'? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Below is the best way to aggregate together the Neighborhood Continuous (NBRCNT) lines across multiple days, specifically the fractions skill @@ -1129,8 +1149,9 @@ combination of those header column entries. The output is printed to the screen, or use the "-out_stat" option to also write the aggregated output to a file named "agg_nbrcnt.txt". -**Q. Stat-Analysis - How do I use '-by' to capture unique entries?** - +Q. How do I use '-by' to capture unique entries? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Here is a stat-analysis job that could be used to run, read the MPR lines, define the probabilistic forecast thresholds, define the single observation @@ -1149,8 +1170,9 @@ to run the job separately for each unique entry found in the FCST_VAR column. The output statistics are written to "out_pstd.txt". -**Q. Stat-Analysis - How do I use '-filter' to refine my output?** - +Q. How do I use '-filter' to refine my output? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Here is an example of running a Stat-Analysis filter job to discard any CNT lines (continuous statistics) where the forecast rate and observation @@ -1180,8 +1202,9 @@ cases without having to modify the source code. This job reads find 56 CTS lines, but only keeps 36 of them where both the BASER and FMEAN columns are at least 0.05. -**Q. Stat-Analysis - How do I use the “-by” flag to stratify results?** - +Q. How do I use the “-by” flag to stratify results? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Adding "-by FCST_VAR" is a great way to associate a single value, of say RMSE, with each of the forecast variables (UGRD,VGRD and WIND). @@ -1199,8 +1222,9 @@ Run the following job on the output from Grid-Stat generated when the The resulting cnt.txt file includes separate output for 6 different FCST_VAR values at different levels. -**Q. Stat-Analysis - How do I speed up run times?** - +Q. How do I speed up run times? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. By default, Stat-Analysis has two options enabled which slow it down. Disabling these two options will create quicker run times: @@ -1234,10 +1258,11 @@ Adding the "-by FCST_VAR" option to compute stats for all variables and runs quickly. TC-Stat -~~~~~~~ - -**Q. TC-Stat - How do I use the “-by” flag to stratify results?** +------- +Q. How do I use the “-by” flag to stratify results? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. To perform tropical cyclone evaluations for multiple models use the "-by AMODEL" option with the tc_stat tool. Here is an example. @@ -1257,8 +1282,9 @@ all grouped together. This will result in all 48 hour HWFI and H3WI track forecasts to be aggregated (statistics and scores computed) for each model separately. -**Q. TC-Stat - How do I use rapid intensification verification?** - +Q. How do I use rapid intensification verification? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. To get the most output, run something like this: @@ -1297,10 +1323,11 @@ To stratify your results by lead time, you could add the "-by LEAD" option. -out_line_type CTC,CTS,MPR Utilities -~~~~~~~~~ - -**Q. Utilities - What would be an example of scripting to call MET?** +--------- +Q. What would be an example of scripting to call MET? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. The following is an example of how to call MET from a bash script including passing in variables. This shell script is listed below to run @@ -1322,8 +1349,9 @@ and call convert to reformat from PostScript to PNG. done -**Q. Utility - How do I convert TRMM data files?** - +Q. How do I convert TRMM data files? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Here is an example of NetCDF that the MET software is not expecting. Here is an option for accessing that same TRMM data, following links from the @@ -1371,8 +1399,9 @@ It may be possible that the domain of the data is smaller. Here are some options That tells Grid-Stat to automatically regrid the TRMM observations to the model domain. -**Q. Other Utilities - How do I convert a PostScript to png?** - +Q. How do I convert a PostScript to png? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Use the linux “convert” tool to convert a Plot-Data-Plane PostScript file to a png: @@ -1392,8 +1421,9 @@ seperate .png with the following naming convention: mode_out-0.png, mode_out-1.png, mode_out-2.png, etc. -**Q. Utility - How does pairwise differences using plot_tcmpr.R work?** - +Q. How does pairwise differences using plot_tcmpr.R work? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. One necessary step in computing pairwise differences is "event equalizing" the data. This means extracting a subset of cases that are common to @@ -1426,10 +1456,11 @@ pairwise differences that are needed. Miscellaneous -~~~~~~~~~~~~~ - -**Q. Regrid-Data-Plane - How do I define a LatLon grid?** +------------- +Q. Regrid-Data-Plane - How do I define a LatLon grid? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Here is an example of the NetCDF variable attributes that MET uses to define a LatLon grid: @@ -1457,9 +1488,9 @@ Use ncdump to look at the attributes. As an exercise, try defining these global attributes (and removing the other projection-related ones) and then try again. -**Q. Pre-processing - How do I use wgrib2, pcp_combine regrid and -reformat to format NetCDF files?** - +Q. Pre-processing - How do I use wgrib2, pcp_combine regrid and reformat to format NetCDF files? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. If you are extracting only one or two fields from a file, using MET's Regrid-Data-Plane can be used to generate a Lat-Lon projection. If @@ -1488,9 +1519,9 @@ Then the output NetCDF file does not have this problem: :lat_ll = "25.000000 degrees_north" ; :lon_ll = "112.000000 degrees_east" ; -**Q. TC-Pairs - How do I get rid of WARNING: TrackInfo Using Specify -Model Suffix?** - +Q. TC-Pairs - How do I get rid of WARNING: TrackInfo Using Specify Model Suffix? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Below is a command example to run: @@ -1574,8 +1605,9 @@ model on the same set of storms. They might be using the same ATCF ID in all their output. But this enables them to distinguish the output in tc_pairs. -**Q. Why is the grid upside down?** - +Q. Why is the grid upside down? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. The user provides a gridded data file to MET and it runs without error, but the data is packed upside down. @@ -1601,7 +1633,7 @@ entry is a dictionary containing information about how to handle input gridded data files. The "regird" entry specifies regridding logic and has a "to_grid" entry that can be set to NONE, FCST, OBS, a named grid, the path to a gridded data file defining the grid, or an explicit grid -specification string. See the :ref:`regrid` entry in +specification string. See the :ref:`regrid` entry in the Configuration File Overview in the MET User's Guide for a more detailed description of the configuration file entries that control automated regridding. @@ -1610,28 +1642,31 @@ A single model level can be plotted using the plot_data_plane utility. This tool can assist the user by showing the data to be verified to ensure that times and locations matchup as expected. -**Q. Why was the MET written largely in C++ instead of FORTRAN?** - +Q. Why was the MET written largely in C++ instead of FORTRAN? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. MET relies upon the object-oriented aspects of C++, particularly in using the MODE tool. Due to time and budget constraints, it also makes use of a pre-existing forecast verification library that was developed at NCAR. -**Q. How does MET differ from the previously mentioned existing -verification packages?** +Q. How does MET differ from the previously mentioned existing verification packages? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. MET is an actively maintained, evolving software package that is being made freely available to the public through controlled version releases. -**Q. Will the MET work on data in native model coordinates?** - +Q. Will the MET work on data in native model coordinates? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. No - it will not. In the future, we may add options to allow additional model grid coordinate systems. -**Q. How do I get help if my questions are not answered in the User's Guide?** +Q. How do I get help if my questions are not answered in the User's Guide? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A. First, look on our @@ -1640,8 +1675,9 @@ If that doesn't answer your question, create a post in the `METplus GitHub Discussions Forum `_. -**Q. What graphical features does MET provide?** - +Q. What graphical features does MET provide? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. MET provides some :ref:`plotting and graphics support`. The plotting tools, including plot_point_obs, plot_data_plane, and plot_mode_field, can @@ -1667,15 +1703,16 @@ you create your own scripts, we encourage you to submit them to us through the `METplus GitHub Discussions Forum `_ so that we can post them for other users. -**Q. How do I find the version of the tool I am using?** - +Q. How do I find the version of the tool I am using? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. Type the name of the tool followed by **-version**. For example, type “pb2nc **-version**”. -**Q. What are MET's conventions for latitude, longitude, azimuth and -bearing angles?** - +Q. What are MET's conventions for latitude, longitude, azimuth and bearing angles? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A. MET considers north latitude and east longitude positive. Latitudes have range from :math:`-90^\circ` to :math:`+90^\circ`. Longitudes have @@ -1687,7 +1724,7 @@ from the north. .. _Troubleshooting: Troubleshooting -_______________ +=============== The first place to look for help with individual commands is this User's Guide or the usage statements that are provided with the tools. @@ -1697,7 +1734,8 @@ scripts available in the MET's *scripts/* directory show examples of how one might use these commands on example datasets. Here are suggestions on other things to check if you are having problems installing or running MET. -**MET won't compile** +MET won't compile +----------------- * Have you specified the locations of NetCDF, GNU Scientific Library, and BUFRLIB, and optional additional libraries using corresponding @@ -1709,7 +1747,8 @@ on other things to check if you are having problems installing or running MET. * Are you using NetCDF version 3.4 or version 4? Currently, only NetCDF version 3.6 can be used with MET. -**BUFRLIB Errors during MET installation** +BUFRLIB Errors during MET installation +-------------------------------------- .. code-block:: none @@ -1742,7 +1781,8 @@ After doing that, please try recompiling MET. If it fails, please send met_help@ucar.edu the following log files. "make_install.log" as well as "config.log". -**Command line double quotes** +Command line double quotes +-------------------------- Single quotes, double quotes, and escape characters can be difficult for MET to parse. If there are problems, especially in Python code, try @@ -1755,7 +1795,8 @@ breaking the command up like the below example. 'G003', '/h/data/global/WXQC/data/met/nc_mdl/umm/1701150006', '- field', '\'name="HGT"; level="P500";\'', '-v', '6'] -**Environment variable settings** +Environment variable settings +----------------------------- In the below incorrect example for many environment variables have both the main variable set and the INC and LIB variables set: @@ -1786,7 +1827,8 @@ Our online tutorial can help figure out what should be set and what the value should be: https://met.readthedocs.io/en/latest/Users_Guide/installation.html -**NetCDF install issues** +NetCDF install issues +--------------------- This example shows a problem with NetCDF in the make_install.log file: @@ -1811,8 +1853,8 @@ NetCDF library files are in */home/username/local/lib*, unset the MET_NETCDF environment variable, then run "make clean", reconfigure, and then run "make install" and "make test" again. -**Error while loading shared libraries** - +Error while loading shared libraries +------------------------------------ * Add the lib dir to your LD_LIBRARY_PATH. For example, if you receive the following error: "./mode_analysis: error while loading shared @@ -1821,7 +1863,8 @@ and then run "make install" and "make test" again. gsl lib (for example, */home/user/MET/gsl-2.1/lib*) to your LD_LIBRARY_PATH. -**General troubleshooting** +General troubleshooting +----------------------- * For configuration files used, make certain to use empty square brackets (e.g. [ ]) to indicate no stratification is desired. Do NOT use empty @@ -1833,7 +1876,7 @@ and then run "make install" and "make test" again. level to 4 or 5 prints much more diagnostic information to the screen. Where to get help -_________________ +================= If none of the above suggestions have helped solve your problem, help is available through the @@ -1841,7 +1884,7 @@ is available through the How to contribute code -______________________ +====================== If you have code you would like to contribute, we will gladly consider your contribution. Please create a post in the diff --git a/met/docs/Users_Guide/appendixB.rst b/met/docs/Users_Guide/appendixB.rst index 605712ca43..2fb620adf5 100644 --- a/met/docs/Users_Guide/appendixB.rst +++ b/met/docs/Users_Guide/appendixB.rst @@ -1,10 +1,11 @@ .. _appendixB: +************************************************ Appendix B Map Projections, Grids, and Polylines -================================================ +************************************************ Map Projections -_______________ +=============== The following map projections are currently supported in MET: @@ -23,7 +24,7 @@ The following map projections are currently supported in MET: * Gaussian Projection Grid Specification Strings -__________________________ +========================== Several configuration file and command line options support the definition of grids as a grid specification string. A description of the that string for each of the supported grid types is provided below. @@ -82,14 +83,14 @@ For a Gaussian grid, the syntax is The parameters **Nx** and **Ny** are as before, while **lon_zero** defines the first longitude. Grids -_____ +===== The majority of NCEP's pre-defined grids that reside on one of the projections listed above are implemented in MET. The user may specify one of these NCEP grids in the configuration files as "GNNN" where NNN is the 3-digit NCEP grid number. Defining a new masking grid in MET would involve modifying the vx_data_grids library and recompiling. Please see `NCEP's website for a description and plot of these predefined grids `_. Polylines for NCEP Regions -__________________________ +========================== Many of NCEP's pre-defined verification regions are implemented in MET as lat/lon polyline files. The user may specify one of these NCEP verification regions in the configuration files by pointing to the lat/lon polyline file in the installed *share/met/poly* directory. Users may also easily define their own lat/lon polyline files. diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index d6523fb1c2..c912032647 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1,13 +1,14 @@ .. _appendixC: +******************************** Appendix C Verification Measures -================================ +******************************** This appendix provides specific information about the many verification statistics and measures that are computed by MET. These measures are categorized into measures for categorical (dichotomous) variables; measures for continuous variables; measures for probabilistic forecasts and measures for neighborhood methods. While the continuous, categorical, and probabilistic statistics are computed by both the Point-Stat and Grid-Stat tools, the neighborhood verification measures are only provided by the Grid-Stat tool. Which statistics are the same, but with different names? -________________________________________________________ +======================================================== .. list-table:: Statistics in MET and other names they have been published under. :widths: auto @@ -52,7 +53,7 @@ ________________________________________________________ .. _categorical variables: MET verification measures for categorical (dichotomous) variables -_________________________________________________________________ +================================================================= The verification statistics for dichotomous variables are formulated using a contingency table such as the one shown in :numref:`table_2X2`. In this table f represents the forecasts and o represents the observations; the two possible forecast and observation values are represented by the values 0 and 1. The values in :numref:`table_2X2` are counts of the number of occurrences of the four possible combinations of forecasts and observations. @@ -94,12 +95,12 @@ The values in :numref:`table_2X2` can also be used to compute the F, O, and H re The categorical verification measures produced by the Point-Stat and Grid-Stat tools are described in the following subsections. They are presented in the order shown in :numref:`table_PS_format_info_FHO` through :numref:`table_PS_format_info_CTS_cont`. TOTAL -~~~~~ +----- The total number of forecast-observation pairs, **T**. Base rate -~~~~~~~~~ +--------- Called "O_RATE" in FHO output :numref:`table_PS_format_info_FHO` @@ -108,7 +109,7 @@ Called "BASER" in CTS output :numref:`table_PS_format_info_CTS` The base rate is defined as :math:`\bar{o} = \frac{n_{11} + n_{01}}{T} = \frac{n_{.1}}{T}.` This value is also known as the sample climatology, and is the relative frequency of occurrence of the event (i.e., o = 1). The base rate is equivalent to the "O" value produced by the NCEP Verification System. Mean forecast -~~~~~~~~~~~~~ +------------- Called "F_RATE" in FHO output :numref:`table_PS_format_info_FHO` @@ -119,7 +120,7 @@ The mean forecast value is defined as :math:`\bar{f} = \frac{n_{11} + n_{10}}{T} This statistic is comparable to the base rate and is the relative frequency of occurrence of a forecast of the event (i.e., **f = 1**). The mean forecast is equivalent to the "F" value computed by the NCEP Verification System. Accuracy -~~~~~~~~ +-------- Called "ACC" in CTS output :numref:`table_PS_format_info_CTS` @@ -130,7 +131,7 @@ Accuracy for a 2x2 contingency table is defined as That is, it is the proportion of forecasts that were either hits or correct rejections - the fraction that were correct. Accuracy ranges from 0 to 1; a perfect forecast would have an accuracy value of 1. Accuracy should be used with caution, especially for rare events, because it can be strongly influenced by large values of :math:`\mathbf{n_{00}}`. Frequency Bias -~~~~~~~~~~~~~~ +-------------- Called "FBIAS" in CTS output :numref:`table_PS_format_info_CTS` @@ -141,7 +142,7 @@ Frequency Bias is the ratio of the total number of forecasts of an event to the A "good" value of Frequency Bias is close to 1; a value greater than 1 indicates the event was forecasted too frequently and a value less than 1 indicates the event was not forecasted frequently enough. H_RATE -~~~~~~ +------ Called "H_RATE" in FHO output :numref:`table_PS_format_info_FHO` @@ -158,7 +159,7 @@ H_RATE is defined as H_RATE is equivalent to the H value computed by the NCEP verification system. H_RATE ranges from 0 to 1; a perfect forecast would have H_RATE = 1. Probability of Detection (POD) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "PODY" in CTS output :numref:`table_PS_format_info_CTS` @@ -170,7 +171,7 @@ POD is defined as It is the fraction of events that were correctly forecasted to occur. POD is also known as the hit rate. POD ranges from 0 to 1; a perfect forecast would have POD = 1. Probability of False Detection (POFD) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------- Called "POFD" in CTS output :numref:`table_PS_format_info_CTS` @@ -182,7 +183,7 @@ POFD is defined as It is the proportion of non-events that were forecast to be events. POFD is also often called the False Alarm Rate. POFD ranges from 0 to 1; a perfect forecast would have POFD = 0. Probability of Detection of the non-event (PODn) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------ Called "PODN" in CTS output :numref:`table_PS_format_info_CTS` @@ -193,7 +194,7 @@ PODn is defined as It is the proportion of non-events that were correctly forecasted to be non-events. Note that PODn = 1 - POFD. PODn ranges from 0 to 1. Like POD, a perfect forecast would have PODn = 1. False Alarm Ratio (FAR) -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- Called "FAR" in CTS output :numref:`table_PS_format_info_CTS` @@ -204,7 +205,7 @@ FAR is defined as It is the proportion of forecasts of the event occurring for which the event did not occur. FAR ranges from 0 to 1; a perfect forecast would have FAR = 0. Critical Success Index (CSI) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- Called "CSI" in CTS output :numref:`table_PS_format_info_CTS` @@ -215,7 +216,7 @@ CSI is defined as It is the ratio of the number of times the event was correctly forecasted to occur to the number of times it was either forecasted or occurred. CSI ignores the "correct rejections" category (i.e., :math:`\mathbf{n_{00}}`). CSI is also known as the Threat Score (TS). CSI can also be written as a nonlinear combination of POD and FAR, and is strongly related to Frequency Bias and the Base Rate. Gilbert Skill Score (GSS) -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- Called "GSS" in CTS output :numref:`table_PS_format_info_CTS` @@ -230,7 +231,7 @@ where GSS is also known as the Equitable Threat Score (ETS). GSS values range from -1/3 to 1. A no-skill forecast would have GSS = 0; a perfect forecast would have GSS = 1. Hanssen-Kuipers Discriminant (HK) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------- Called "HK" in CTS output :numref:`table_PS_format_info_CTS` @@ -243,7 +244,7 @@ More simply, HK = POD :math:`-` POFD. HK is also known as the True Skill Statistic (TSS) and less commonly (although perhaps more properly) as the Peirce Skill Score. HK measures the ability of the forecast to discriminate between (or correctly classify) events and non-events. HK values range between -1 and 1. A value of 0 indicates no skill; a perfect forecast would have HK = 1. Heidke Skill Score (HSS) -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ Called "HSS" in CTS output :numref:`table_PS_format_info_CTS` and "HSS" in MCTS output :numref:`table_PS_format_info_MCTS` @@ -270,7 +271,7 @@ where H is the number of forecasts in the correct category and E is the expected HSS can range from minus infinity to 1. A perfect forecast would have HSS = 1. Heidke Skill Score - Expected Correct (HSS_EC) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------------------- Called "HSS_EC" in MCTS output :numref:`table_PS_format_info_MCTS` @@ -283,7 +284,7 @@ The C_2 value is user-configurable with a default value of T divided by the numb HSS_EC can range from minus infinity to 1. A perfect forecast would have HSS_EC = 1. Odds Ratio (OR) -~~~~~~~~~~~~~~~ +--------------- Called "ODDS" in CTS output :numref:`table_PS_format_info_CTS` @@ -294,14 +295,14 @@ OR measures the ratio of the odds of a forecast of the event being correct to th OR can range from 0 to :math:`\infty`. A perfect forecast would have a value of OR = infinity. OR is often expressed as the log Odds Ratio or as the Odds Ratio Skill Score (:ref:`Stephenson, 2000 `). Logarithm of the Odds Ratio (LODDS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------- Called "LODDS" in CTS output :numref:`table_PS_format_info_CTS` LODDS transforms the odds ratio via the logarithm, which tends to normalize the statistic for rare events (:ref:`Stephenson, 2000 `). However, it can take values of :math:`\pm\infty` when any of the contingency table counts is 0. LODDS is defined as :math:`\text{LODDS} = ln(OR)`. Odds Ratio Skill Score (ORSS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- Called "ORSS" in CTS output :numref:`table_PS_format_info_CTS` @@ -312,7 +313,7 @@ ORSS is a skill score based on the odds ratio. ORSS is defined as ORSS is sometimes also referred to as Yule's Q. (:ref:`Stephenson, 2000 `). Extreme Dependency Score (EDS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "EDS" in CTS output :numref:`table_PS_format_info_CTS` @@ -323,7 +324,7 @@ The extreme dependency score measures the association between forecast and obser EDS can range from -1 to 1, with 0 representing no skill. A perfect forecast would have a value of EDS = 1. EDS is independent of bias, so should be presented along with the frequency bias statistic (:ref:`Stephenson et al., 2008 `). Extreme Dependency Index (EDI) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "EDI" in CTS output :numref:`table_PS_format_info_CTS` @@ -336,7 +337,7 @@ where *H* and *F* are the Hit Rate and False Alarm Rate, respectively. EDI can range from :math:`-\infty` to 1, with 0 representing no skill. A perfect forecast would have a value of EDI = 1 (:ref:`Ferro and Stephenson, 2011 `). Symmetric Extreme Dependency Score (SEDS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------- Called "SEDS" in CTS output :numref:`table_PS_format_info_CTS` @@ -347,7 +348,7 @@ The symmetric extreme dependency score measures the association between forecast SEDS can range from :math:`-\infty` to 1, with 0 representing no skill. A perfect forecast would have a value of SEDS = 1 (:ref:`Ferro and Stephenson, 2011 `). Symmetric Extremal Dependency Index (SEDI) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------ Called "SEDI" in CTS output :numref:`table_PS_format_info_CTS` @@ -360,14 +361,14 @@ where :math:`H = \frac{n_{11}}{n_{11} + n_{01}}` and :math:`F = \frac{n_{10}}{n_ SEDI can range from :math:`-\infty` to 1, with 0 representing no skill. A perfect forecast would have a value of SEDI = 1. SEDI approaches 1 only as the forecast approaches perfection (:ref:`Ferro and Stephenson, 2011 `). Bias Adjusted Gilbert Skill Score (GSS) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------------- Called "BAGSS" in CTS output :numref:`table_PS_format_info_CTS` BAGSS is based on the GSS, but is corrected as much as possible for forecast bias (:ref:`Brill and Mesinger, 2009 `). Economic Cost Loss Relative Value (ECLV) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------------- Included in ECLV output :numref:`table_PS_format_info_ECLV` @@ -382,14 +383,14 @@ For cost / loss ratio above the base rate, the ECLV is defined as: .. math:: \text{ECLV } = \frac{(cl \ast (h + f)) + m - b}{b \ast (cl - 1)}. MET verification measures for continuous variables -__________________________________________________ +================================================== For continuous variables, many verification measures are based on the forecast error (i.e., **f - o**). However, it also is of interest to investigate characteristics of the forecasts, and the observations, as well as their relationship. These concepts are consistent with the general framework for verification outlined by :ref:`Murphy and Winkler, (1987) `. The statistics produced by MET for continuous forecasts represent this philosophy of verification, which focuses on a variety of aspects of performance rather than a single measure. The verification measures currently evaluated by the Point-Stat tool are defined and described in the subsections below. In these definitions, **f** represents the forecasts, **o** represents the observation, and **n** is the number of forecast-observation pairs. Mean forecast -~~~~~~~~~~~~~ +------------- Called "FBAR" in CNT output :numref:`table_PS_format_info_CNT` @@ -398,7 +399,7 @@ Called "FBAR" in SL1L2 output :numref:`table_PS_format_info_SL1L2` The sample mean forecast, FBAR, is defined as :math:`\bar{f} = \frac{1}{n} \sum_{i=1}^{n} f_i`. Mean observation -~~~~~~~~~~~~~~~~ +---------------- Called "OBAR" in CNT output :numref:`table_PS_format_info_CNT` @@ -407,7 +408,7 @@ Called "OBAR" in SL1L2 output :numref:`table_PS_format_info_SL1L2` The sample mean observation is defined as :math:`\bar{o} = \frac{1}{n} \sum_{i=1}^{n} o_i`. Forecast standard deviation -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- Called "FSTDEV" in CNT output :numref:`table_PS_format_info_CNT` @@ -418,7 +419,7 @@ The sample variance of the forecasts is defined as The forecast standard deviation is defined as :math:`s_f = \sqrt{s_f^2}`. Observation standard deviation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "OSTDEV" in CNT output :numref:`table_PS_format_info_CNT` @@ -429,7 +430,7 @@ The sample variance of the observations is defined as The observed standard deviation is defined as :math:`s_o = \sqrt{s_o^2}`. Pearson Correlation Coefficient -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- Called "PR_CORR" in CNT output :numref:`table_PS_format_info_CNT` @@ -440,7 +441,7 @@ The Pearson correlation coefficient, **r**, measures the strength of linear asso **r** can range between -1 and 1; a value of 1 indicates perfect correlation and a value of -1 indicates perfect negative correlation. A value of 0 indicates that the forecasts and observations are not correlated. Spearman rank correlation coefficient :math:`(\rho_{s})` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------------------------------- Called "SP_CORR" in CNT :numref:`table_PS_format_info_CNT` @@ -453,7 +454,7 @@ A simpler formulation of the Spearman-rank correlation is based on differences b Like **r**, the Spearman rank correlation coefficient ranges between -1 and 1; a value of 1 indicates perfect correlation and a value of -1 indicates perfect negative correlation. A value of 0 indicates that the forecasts and observations are not correlated. Kendall's Tau statistic ( :math:`\tau`) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------------- Called "KT_CORR" in CNT output :numref:`table_PS_format_info_CNT` @@ -466,7 +467,7 @@ where :math:`N_C` is the number of "concordant" pairs and :math:`N_D` is the num Like **r** and :math:`\rho_{s}`, Kendall's Tau ( :math:`\tau`) ranges between -1 and 1; a value of 1 indicates perfect association (concordance) and a value of -1 indicates perfect negative association. A value of 0 indicates that the forecasts and observations are not associated. Mean Error (ME) -~~~~~~~~~~~~~~~ +--------------- Called "ME" in CNT output :numref:`table_PS_format_info_CNT` @@ -477,7 +478,7 @@ The Mean Error, ME, is a measure of overall bias for continuous variables; in pa A perfect forecast has ME = 0. Mean Error Squared (ME2) -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ Called "ME2" in CNT output :numref:`table_PS_format_info_CNT` @@ -486,21 +487,21 @@ The Mean Error Squared, ME2, is provided to give a complete breakdown of MSE in A perfect forecast has ME2 = 0. Multiplicative Bias -~~~~~~~~~~~~~~~~~~~ +------------------- Called "MBIAS" in CNT output :numref:`table_PS_format_info_CNT` Multiplicative bias is simply the ratio of the means of the forecasts and the observations: :math:`\text{MBIAS} = \bar{f} / \bar{o}` Mean-squared error (MSE) -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ Called "MSE" in CNT output :numref:`table_PS_format_info_CNT` MSE measures the average squared error of the forecasts. Specifically, :math:`\text{MSE} = \frac{1}{n}\sum (f_{i} - o_{i})^{2}`. Root-mean-squared error (RMSE) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "RMSE" in CNT output :numref:`table_PS_format_info_CNT` @@ -508,7 +509,7 @@ RMSE is simply the square root of the MSE, :math:`\text{RMSE} = \sqrt{\text{MSE} Scatter Index (SI) -~~~~~~~~~~~~~~~~~~ +------------------ Called "SI" in CNT output :numref:`table_PS_format_info_CNT` @@ -517,12 +518,12 @@ SI is the ratio of the root mean squared error to the average observation value, Smaller values of SI indicate better agreement between the model and observations (less scatter on scatter plot). Standard deviation of the error -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- Called "ESTDEV" in CNT output :numref:`table_PS_format_info_CNT` Bias-Corrected MSE -~~~~~~~~~~~~~~~~~~ +------------------ Called "BCMSE" in CNT output :numref:`table_PS_format_info_CNT` @@ -535,7 +536,7 @@ The standard deviation of the error, :math:`s_{f-o}`, is :math:`s_{f-o} = \sqrt{ Note that the square of the standard deviation of the error (ESTDEV2) is sometimes called the "Bias-corrected MSE" (BCMSE) because it removes the effect of overall bias from the forecast-observation squared differences. Mean Absolute Error (MAE) -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- Called "MAE" in CNT output :numref:`table_PS_format_info_CNT` @@ -544,7 +545,7 @@ The Mean Absolute Error (MAE) is defined as :math:`\text{MAE} = \frac{1}{n} \sum MAE is less influenced by large errors and also does not depend on the mean error. A perfect forecast would have MAE = 0. InterQuartile Range of the Errors (IQR) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------------- Called "IQR" in CNT output :numref:`table_PS_format_info_CNT` @@ -553,7 +554,7 @@ The InterQuartile Range of the Errors (IQR) is the difference between the 75th a IQR is another estimate of spread, similar to standard error, but is less influenced by large errors and also does not depend on the mean error. A perfect forecast would have IQR = 0. Median Absolute Deviation (MAD) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- Called "MAD" in CNT output :numref:`table_PS_format_info_CNT` @@ -562,7 +563,7 @@ The Median Absolute Deviation (MAD) is defined as :math:`\text{MAD} = \text{medi MAD is an estimate of spread, similar to standard error, but is less influenced by large errors and also does not depend on the mean error. A perfect forecast would have MAD = 0. Mean Squared Error Skill Score -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "MSESS" in CNT output :numref:`table_PS_format_info_CNT` @@ -571,27 +572,28 @@ The Mean Squared Error Skill Score is one minus the ratio of the forecast MSE to .. math:: \text{MSESS} = 1 - \frac{\text{MSE}_f}{\text{MSE}_r} Root-mean-squared Forecast Anomaly -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------- Called "RMSFA" in CNT output :numref:`table_PS_format_info_CNT` RMSFA is the square root of the average squared forecast anomaly. Specifically, :math:`\text{RMSFA} = \sqrt{\frac{1}{n} \sum(f_{i} - c_{i})^2}`. Root-mean-squared Observation Anomaly -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------- Called "RMSOA" in CNT output :numref:`table_PS_format_info_CNT` RMSOA is the square root of the average squared observation anomaly. Specifically, :math:`\text{RMSOA} = \sqrt{\frac{1}{n} \sum(o_{i} - c_{i})^2}`. Percentiles of the errors -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- + Called "E10", "E25", "E50", "E75", "E90" in CNT output :numref:`table_PS_format_info_CNT` Percentiles of the errors provide more information about the distribution of errors than can be obtained from the mean and standard deviations of the errors. Percentiles are computed by ordering the errors from smallest to largest and computing the rank location of each percentile in the ordering, and matching the rank to the actual value. Percentiles can also be used to create box plots of the errors. In MET, the 0.10th, 0.25th, 0.50th, 0.75th, and 0.90th quantile values of the errors are computed. Anomaly Correlation Coefficient -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- Called "ANOM_CORR" and "ANOM_CORR_UNCNTR" for centered and uncentered versions in CNT output :numref:`table_PS_format_info_CNT` @@ -616,7 +618,7 @@ The uncentered anomaly correlation coefficient (ANOM_CORR_UNCNTR) which does not Anomaly correlation can range between -1 and 1; a value of 1 indicates perfect correlation and a value of -1 indicates perfect negative correlation. A value of 0 indicates that the forecast and observed anomalies are not correlated. Partial Sums lines (SL1L2, SAL1L2, VL1L2, VAL1L2) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- :numref:`table_PS_format_info_SL1L2`, :numref:`table_PS_format_info_SAL1L2`, :numref:`table_PS_format_info_VL1L2`, and :numref:`table_PS_format_info_VAL1L2` @@ -627,7 +629,7 @@ The partial sums can be accumulated over individual cases to produce statistics *Minimally sufficient* statistics are those that condense the data most, with no loss of information. Statistics based on L1 and L2 norms allow for good compression of information. Statistics based on other norms, such as order statistics, do not result in good compression of information. For this reason, statistics such as RMSE are often preferred to statistics such as the median absolute deviation. The partial sums are not sufficient for order statistics, such as the median or quartiles. Scalar L1 and L2 values -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- Called "FBAR", "OBAR", "FOBAR", "FFBAR", and "OOBAR" in SL1L2 output :numref:`table_PS_format_info_SL1L2` @@ -647,7 +649,7 @@ These statistics are simply the 1st and 2nd moments of the forecasts, observatio Some of the other statistics for continuous forecasts (e.g., RMSE) can be derived from these moments. Scalar anomaly L1 and L2 values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- Called "FABAR", "OABAR", "FOABAR", "FFABAR", "OOABAR" in SAL1L2 output :numref:`table_PS_format_info_SAL1L2` @@ -665,7 +667,7 @@ Computation of these statistics requires a climatological value, c. These statis \text{OOABAR} = \text{Mean}[(o - c)^2] = \bar{(o - c)}^2 = \frac{1}{n} \sum_{i=1}^n (o_i - c)^2 Vector L1 and L2 values -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- Called "UFBAR", "VFBAR", "UOBAR", "VOBAR", "UVFOBAR", "UVFFBAR", "UVOOBAR" in VL1L2 output :numref:`table_PS_format_info_VL1L2` @@ -687,7 +689,7 @@ These statistics are the moments for wind vector values, where **u** is the E-W \text{UVOOBAR} = \text{Mean}(u_o^2 + v_o^2) = \frac{1}{n} \sum_{i=1}^n (u_{oi}^2 + v_{oi}^2) Vector anomaly L1 and L2 values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- Called "UFABAR", "VFABAR", "UOABAR", "VOABAR", "UVFOABAR", "UVFFABAR", "UVOOABAR" in VAL1L2 output :numref:`table_PS_format_info_VAL1L2` @@ -710,7 +712,7 @@ These statistics require climatological values for the wind vector components, : \text{UVOOABAR} = \text{Mean}[(u_o - u_c)^2 + (v_o - v_c)^2] = \frac{1}{n} \sum_{i=1}^n ((u_{oi} - u_c)^2 + (v_{oi} - v_c)^2) Gradient values -~~~~~~~~~~~~~~~ +--------------- Called "TOTAL", "FGBAR", "OGBAR", "MGBAR", "EGBAR", "S1", "S1_OG", and "FGOG_RATIO" in GRAD output :numref:`table_GS_format_info_GRAD` @@ -752,7 +754,7 @@ where the weights are applied at each grid location, with values assigned accord MET verification measures for probabilistic forecasts -_____________________________________________________ +===================================================== The results of the probabilistic verification methods that are included in the Point-Stat, Grid-Stat, and Stat-Analysis tools are summarized using a variety of measures. MET treats probabilistic forecasts as categorical, divided into bins by user-defined thresholds between zero and one. For the categorical measures, if a forecast probability is specified in a formula, the midpoint value of the bin is used. These measures include the Brier Score (BS) with confidence bounds (:ref:`Bradley, 2008 `); the joint distribution, calibration-refinement, likelihood-base rate (:ref:`Wilks, 2011 `); and receiver operating characteristic information. Using these statistics, reliability and discrimination diagrams can be produced. @@ -795,7 +797,7 @@ The verification statistics for probabilistic forecasts of dichotomous variables Reliability -~~~~~~~~~~~ +----------- Called "RELIABILITY" in PSTD output :numref:`table_PS_format_info_PSTD` @@ -804,7 +806,8 @@ A component of the Brier score. Reliability measures the average difference betw .. math:: \text{Reliability} = \frac{1}{T} \sum n_i (p_i - \bar{o}_i)^2 Resolution -~~~~~~~~~~ +---------- + Called "RESOLUTION" in PSTD output :numref:`table_PS_format_info_PSTD` A component of the Brier score that measures how well forecasts divide events into subsets with different outcomes. Larger values of resolution are best since it is desirable for event frequencies in the subsets to be different than the overall event frequency. @@ -812,7 +815,7 @@ A component of the Brier score that measures how well forecasts divide events in .. math:: \text{Resolution} = \frac{1}{T} n_{i.}(\bar{o}_i - \bar{o})^2 Uncertainty -~~~~~~~~~~~ +----------- Called "UNCERTAINTY" in PSTD output :numref:`table_PS_format_info_PSTD` @@ -821,7 +824,7 @@ A component of the Brier score. For probabilistic forecasts, uncertainty is a fu .. math:: \text{Uncertainty} = \frac{n_{.1}}{T}(1 - \frac{n_{.1}}{T}) Brier score -~~~~~~~~~~~ +----------- Called "BRIER" in PSTD output :numref:`table_PS_format_info_PSTD` @@ -838,7 +841,7 @@ BS can be partitioned into three terms: (1) reliability, (2) resolution, and (3) This score is sensitive to the base rate or climatological frequency of the event. Forecasts of rare events can have a good BS without having any actual skill. Since Brier score is a measure of error, smaller values are better. Brier Skill Score (BSS) -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- Called "BSS" and "BSS_SMPL" in PSTD output :numref:`table_PS_format_info_PSTD` @@ -849,7 +852,7 @@ BSS is a skill score based on the Brier Scores of the forecast and a reference f BSS is computed using the climatology specified in the configuration file while BSS_SMPL is computed using the sample climatology of the current set of observations. OY_TP - Observed Yes Total Proportion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------- Called "OY_TP" in PJC output :numref:`table_PS_format_info_PJC` @@ -858,7 +861,7 @@ This is the cell probability for row **i**, column **j=1** (observed event), a p .. math:: \text{OYTP}(i) = \frac{n_{i1}}{T} = \text{probability}(o_{i1}) ON_TP - Observed No Total Proportion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------ Called "ON_TP" in PJC output :numref:`table_PS_format_info_PJC` @@ -867,7 +870,7 @@ This is the cell probability for row **i**, column **j=0** (observed non-event), .. math:: \text{ONTP}(i) = \frac{n_{i0}}{T} = \text{probability}(o_{i0}) Calibration -~~~~~~~~~~~ +----------- Called "CALIBRATION" in PJC output :numref:`table_PS_format_info_PJC` @@ -876,7 +879,7 @@ Calibration is the conditional probability of an event given each probability fo .. math:: \text{Calibration}(i) = \frac{n_{i1}}{n_{1.}} = \text{probability}(o_1|p_i) Refinement -~~~~~~~~~~ +---------- Called "REFINEMENT" in PJC output :numref:`table_PS_format_info_PJC` @@ -885,7 +888,7 @@ The relative frequency associated with each forecast probability, sometimes call .. math:: \text{Refinement}(i) = \frac{n_{i.}}{T} = \text{probability}(p_i) Likelihood -~~~~~~~~~~ +---------- Called "LIKELIHOOD" in PJC output :numref:`table_PS_format_info_PJC` @@ -896,7 +899,7 @@ Likelihood is the conditional probability for each forecast category (row) given Likelihood values are also used to create "discrimination" plots that compare the distribution of forecast values for events to the distribution of forecast values for non-events. These plots show how well the forecasts categorize events and non-events. The distribution of forecast values for non-events can be derived from the POFD values computed by MET for the user-specified thresholds. Base Rate -~~~~~~~~~ +--------- Called "BASER" in PJC output :numref:`table_PS_format_info_PJC` @@ -905,7 +908,7 @@ This is the probability of an event for each forecast category :math:`p_i` (row) .. math:: \text{Base Rate}(i) = \frac{n_{i1}}{n_{i.}} = \text{probability}(o_{i1}) Reliability diagram -~~~~~~~~~~~~~~~~~~~ +------------------- The reliability diagram is a plot of the observed frequency of events versus the forecast probability of those events, with the range of forecast probabilities divided into categories. @@ -918,7 +921,7 @@ The ideal forecast (i.e., one with perfect reliability) has conditional observed Example of Reliability Diagram Receiver operating characteristic -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------- MET produces hit rate (POD) and false alarm rate (POFD) values for each user-specified threshold. This information can be used to create a scatter plot of POFD vs. POD. When the points are connected, the plot is generally referred to as the receiver operating characteristic (ROC) curve (also called the "relative operating characteristic" curve). See the area under the ROC curve (AUC) entry for related information. @@ -933,7 +936,7 @@ A ROC curve shows how well the forecast discriminates between two outcomes, so i Example of ROC Curve Area Under the ROC curve (AUC) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ Called "ROC_AUC" in PSTD output :numref:`table_PS_format_info_PSTD` @@ -946,10 +949,10 @@ The area under the curve can be estimated in a variety of ways. In MET, the simp .. _App_C-ensemble: MET verification measures for ensemble forecasts -________________________________________________ +================================================ RPS -~~~ +--- Called "RPS" in RPS output :numref:`table_ES_header_info_es_out_ECNT` @@ -967,7 +970,7 @@ To clarify, :math:`F_1 = f_1` is the first component of :math:`F_m`, :math:`F_2 where :math:`BS_m` is the Brier score for the m-th category (:ref:`Tödter and Ahrens, 2012`). Subsequently, the RPS lends itself to a decomposition into reliability, resolution and uncertainty components, noting that each component is aggregated over the different categories; these are written to the columns named "RPS_REL", "RPS_RES" and "RPS_UNC" in RPS output :numref:`table_ES_header_info_es_out_ECNT`. CRPS -~~~~ +---- Called "CRPS", "CRPSCL", "CRPS_EMP", and "CRPSCL_EMP" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` @@ -986,7 +989,7 @@ The overall CRPS is calculated as the average of the individual measures. In equ The score can be interpreted as a continuous version of the mean absolute error (MAE). Thus, the score is negatively oriented, so smaller is better. Further, similar to MAE, bias will inflate the CRPS. Thus, bias should also be calculated and considered when judging forecast quality using CRPS. CRPS Skill Score -~~~~~~~~~~~~~~~~ +---------------- Called "CRPSS" and "CRPSS_EMP" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` @@ -997,7 +1000,7 @@ The continuous ranked probability skill score (CRPSS) is similar to the MSESS an For the normal distribution fit (CRPSS), the reference CRPS is computed using the climatological mean and standard deviation. For the empirical distribution (CRPSS_EMP), the reference CRPS is computed by sampling from the assumed normal climatological distribution defined by the mean and standard deviation. IGN -~~~ +--- Called "IGN" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` @@ -1008,14 +1011,14 @@ The ignorance score (IGN) is the negative logarithm of a predictive probability Accumulation of the ignorance score for many forecasts is via the average of individual ignorance scores. This average ignorance score is the value output by the MET software. Like many error statistics, the IGN is negatively oriented, so smaller numbers indicate better forecasts. PIT -~~~ +--- Called "PIT" in ORANK output :numref:`table_ES_header_info_es_out_ORANK` The probability integral transform (PIT) is the analog of the rank histogram for a probability distribution forecast (:ref:`Dawid, 1984 `). Its interpretation is the same as that of the verification rank histogram: Calibrated probabilistic forecasts yield PIT histograms that are flat, or uniform. Under-dispersed (not enough spread in the ensemble) forecasts have U-shaped PIT histograms while over-dispersed forecasts have bell-shaped histograms. In MET, the PIT calculation uses a normal distribution fit to the ensemble forecasts. In many cases, use of other distributions would be better. RANK -~~~~ +---- Called "RANK" in ORANK output :numref:`table_ES_header_info_es_out_ORANK` @@ -1024,7 +1027,7 @@ The rank of an observation, compared to all members of an ensemble forecast, is The rank histogram does not provide information about the accuracy of ensemble forecasts. Further, examination of "rank" only makes sense for ensembles of a fixed size. Thus, if ensemble members are occasionally unavailable, the rank histogram should not be used. The PIT may be used instead. SPREAD -~~~~~~ +------ Called "SPREAD" in ECNT output :numref:`table_ES_header_info_es_out_ECNT` @@ -1035,7 +1038,7 @@ The ensemble spread for a single observation is the standard deviation of the en Note that prior to met-9.0.1, the ensemble spread of a spatial masking region was computed as the average of the spread values within that region. This algorithm was corrected in met-9.0.1 to average the ensemble variance values prior to computing the square root. MET verification measures for neighborhood methods -__________________________________________________ +================================================== The results of the neighborhood verification approaches that are included in the Grid-Stat tool are summarized using a variety of measures. These measures include the Fractions Skill Score (FSS) and the Fractions Brier Score (FBS). MET also computes traditional contingency table statistics for each combination of threshold and neighborhood window size. @@ -1072,14 +1075,14 @@ All of these measures are defined in :numref:`categorical variables`. In addition to these standard statistics, the neighborhood analysis provides additional continuous measures, the Fractions Brier Score and the Fractions Skill Score. For reference, the Asymptotic Fractions Skill Score and Uniform Fractions Skill Score are also calculated. These measures are defined here, but are explained in much greater detail in :ref:`Ebert (2008) ` and :ref:`Roberts and Lean (2008) `. :ref:`Roberts and Lean (2008) ` also present an application of the methodology. Fractions Brier Score -~~~~~~~~~~~~~~~~~~~~~ +--------------------- Called "FBS" in NBRCNT output :numref:`table_GS_format_info_NBRCNT` The Fractions Brier Score (FBS) is defined as :math:`\text{FBS} = \frac{1}{N} \sum_N [\langle P_f\rangle_s - \langle P_o\rangle_s]^2`, where N is the number of neighborhoods; :math:`\langle P_{f} \rangle_{s}` is the proportion of grid boxes within a forecast neighborhood where the prescribed threshold was exceeded (i.e., the proportion of grid boxes that have forecast events); and :math:`\langle P_{o}\rangle_{s}` is the proportion of grid boxes within an observed neighborhood where the prescribed threshold was exceeded (i.e., the proportion of grid boxes that have observed events). Fractions Skill Score -~~~~~~~~~~~~~~~~~~~~~ +--------------------- Called "FSS" in NBRCNT output :numref:`table_GS_format_info_NBRCNT` @@ -1090,28 +1093,28 @@ The Fractions Skill Score (FSS) is defined as where the denominator represents the worst possible forecast (i.e., with no overlap between forecast and observed events). FSS ranges between 0 and 1, with 0 representing no overlap and 1 representing complete overlap between forecast and observed events, respectively. Asymptotic Fractions Skill Score -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- Called "AFSS" in NBRCNT output :numref:`table_GS_format_info_NBRCNT` The Asymptotic Fractions Skill Score (AFSS) is a special case of the Fractions Skill score where the entire domain is used as the single neighborhood. This provides the user with information about the overall frequency bias of forecasts versus observations. The formula is the same as for FSS above, but with N=1 and the neighborhood size equal to the domain. Uniform Fractions Skill Score -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- Called "UFSS" in NBRCNT output :numref:`table_GS_format_info_NBRCNT` The Uniform Fractions Skill Score (UFSS) is a reference statistic for the Fractions Skill score based on a uniform distribution of the total observed events across the grid. UFSS represents the FSS that would be obtained at the grid scale from a forecast with a fraction/probability equal to the total observed event proportion at every point. The formula is :math:`UFSS = (1 + f_o)/2` (i.e., halfway between perfect skill and random forecast skill) where :math:`f_o` is the total observed event proportion (i.e. observation rate). Forecast Rate -~~~~~~~~~~~~~ +------------- Called "F_rate" in NBRCNT output :numref:`table_GS_format_info_NBRCNT` The overall proportion of grid points with forecast events to total grid points in the domain. The forecast rate will match the observation rate in unbiased forecasts. Observation Rate -~~~~~~~~~~~~~~~~ +---------------- Called "O_rate" in NBRCNT output :numref:`table_GS_format_info_NBRCNT` @@ -1120,7 +1123,7 @@ The overall proportion of grid points with observed events to total grid points .. _App_C-distance_maps: MET verification measures for distance map methods -__________________________________________________ +================================================== The distance map statistics include Baddeley's :math:`\Delta` Metric, a statistic which is a true mathematical metric. The definition of a mathematical metric is included below. @@ -1139,7 +1142,7 @@ It has been argued in :ref:`Gilleland (2017) ` that the second p The results of the distance map verification approaches that are included in the Grid-Stat tool are summarized using a variety of measures. These measures include Baddeley's :math:`\Delta` Metric, the Hausdorff Distance, the Mean-error Distance, Pratt's Figure of Merit, and Zhu's Measure. Their equations are listed below. Baddeley's :math:`\Delta` Metric and Hausdorff Distance -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------------- Called "BADDELEY" and "HAUSDORFF" in the DMAP output :numref:`table_GS_format_info_DMAP` @@ -1155,7 +1158,7 @@ In terms of distance maps, Baddeley's :math:`\Delta` is the :math:`L_{p}` norm o The range for BADDELEY and HAUSDORFF is 0 to infinity, with a score of 0 indicating a perfect forecast. Mean-error Distance -~~~~~~~~~~~~~~~~~~~ +------------------- Called "MED_FO", "MED_OF", "MED_MIN", "MED_MAX", and "MED_MEAN" in the DMAP output :numref:`table_GS_format_info_DMAP` @@ -1178,7 +1181,7 @@ From the distance map perspective, MED *(A,B)* is the average of the values in : The range for MED is 0 to infinity, with a score of 0 indicating a perfect forecast. Pratt's Figure of Merit -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- Called "FOM_FO", "FOM_OF", "FOM_MIN", "FOM_MAX", and "FOM_MEAN" in the DMAP output :numref:`table_GS_format_info_DMAP` @@ -1193,7 +1196,7 @@ Note that :math:`d(s,A)` in the denominator is summed only over the grid squares The range for FOM is 0 to 1, with a score of 1 indicating a perfect forecast. Zhu's Measure -~~~~~~~~~~~~~ +------------- Called "ZHU_FO", "ZHU_OF", "ZHU_MIN", "ZHU_MAX", and "ZHU_MEAN" in the DMAP output :numref:`table_GS_format_info_DMAP` @@ -1208,7 +1211,7 @@ The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forec .. _App_C-gbeta: :math:`G` and :math:`G_\beta` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` @@ -1229,7 +1232,7 @@ where :math:`\beta > 0` is a user-chosen parameter with a default value of :math The range for :math:`G_\beta` is 0 to 1, with a score of 1 indicating a perfect forecast. Calculating Percentiles -_______________________ +======================= Several of the MET tools make use of percentiles in one way or another. Percentiles can be used as part of the internal computations of a tool, or can be written out as elements of some of the standard verification statistics. There are several widely-used conventions for calculating percentiles however, so in this section we describe how percentiles are calculated in MET. diff --git a/met/docs/Users_Guide/appendixD.rst b/met/docs/Users_Guide/appendixD.rst index 66c578e91a..0c53652e59 100644 --- a/met/docs/Users_Guide/appendixD.rst +++ b/met/docs/Users_Guide/appendixD.rst @@ -2,8 +2,9 @@ .. _App_D-Confidence-Intervals: +******************************* Appendix D Confidence Intervals -=============================== +******************************* A single verification statistic is statistically meaningless without associated uncertainty information in accompaniment. There can be numerous sources of uncertainty associated with such a statistic including observational, physical uncertainties about the underlying processes governing the equation, sample uncertainty, etc. Although all of the sources of uncertainty can be important, the most heavily researched, and easiest to calculate, is that of sampling uncertainty. It is this source of uncertainty that can presently be obtained with MET, and the techniques for deriving these estimates are described here. Sampling uncertainty through MET is gleaned by way of confidence intervals (CIs) as these are generally most informative. A :math:`(1 - \alpha) \cdot 100\%` confidence interval is interpreted, somewhat awkwardly, in the following way. If the test were repeated 100 times (so that we have 100 such intervals), then we expect the true value of the statistics to fall inside :math:`(1-\alpha)\cdot 100` of these intervals. For example, if :math:`\alpha=0.05` then we expect the true value to fall within 95 of the intervals. diff --git a/met/docs/Users_Guide/appendixE.rst b/met/docs/Users_Guide/appendixE.rst index a50afe1703..4ec8ff2a9a 100644 --- a/met/docs/Users_Guide/appendixE.rst +++ b/met/docs/Users_Guide/appendixE.rst @@ -1,7 +1,8 @@ .. _appendixE: +********************** Appendix E WWMCA Tools -====================== +********************** There are two WWMCA tools available. The WWMCA-Plot tool makes a PostScript plot of one or more WWMCA cloud percent files and the WWMCA-Regrid tool regrids WWMCA cloud percent files and reformats them into netCDF files that the other MET tools can read. diff --git a/met/docs/Users_Guide/appendixF.rst b/met/docs/Users_Guide/appendixF.rst index 586c264c9e..2649fb4072 100644 --- a/met/docs/Users_Guide/appendixF.rst +++ b/met/docs/Users_Guide/appendixF.rst @@ -1,15 +1,16 @@ .. _appendixF: +*************************** Appendix F Python Embedding -=========================== +*************************** Introduction -____________ +============ MET includes the ability to embed Python to a limited degree. Users may use Python scripts and whatever associated Python packages they wish in order to prepare 2D gridded data fields, point observations, and matched pairs as input to the MET tools. We fully expect that this degree of embedding will increase in the future. In addition, plans are in place to extend Python with MET in upcoming releases, allowing users to invoke MET tools directly from their Python script. While MET version 8.0 was built on Python 2.x, MET versions 9.0 and beyond are built on Python 3.6+. Compiling Python Support -________________________ +======================== In order to use Python embedding, the user's local Python installation must have the C-language Python header files and libraries. Sometimes when Python is installed locally, these header files and libraries are deleted at the end of the installation process, leaving only the binary executable and run-time shared object files. But the Python header files and libraries must be present to compile support in MET for Python embedding. Assuming the requisite Python files are present, and that Python embedding is enabled when building MET (which is done by passing the **--enable-python** option to the **configure** command line), the MET C++ code will use these in the compilation process to link directly to the Python libraries. @@ -25,7 +26,7 @@ Make sure that these are set as environment variables or that you have included MET_PYTHON_EXE -______________ +============== When Python embedding support is compiled, MET instantiates the Python interpreter directly. However, for users of highly configurable Conda environments, the Python instance set at compilation time may not be sufficient. Users may want to switch between Conda environments for which different packages are available. MET version 9.0 has been enhanced to address this need. @@ -48,7 +49,7 @@ With this approach, users should be able to execute Python scripts in their own .. _pyembed-2d-data: Python Embedding for 2D data -____________________________ +============================ We now describe how to write Python scripts so that the MET tools may extract 2D gridded data fields from them. Currently, MET offers two ways to interact with Python scripts: by using NumPy N-dimensional arrays (ndarrays) or by using Xarray DataArrays. The interface to be used (NumPy or Xarray) is specified on the command line (more on this later). The user's scripts can use any Python libraries that are supported by the local Python installation, or any personal or institutional libraries or code that are desired in order to implement the Python script, so long as the data has been loaded into either a NumPy ndarray or an Xarray DataArray by the end of the script. This offers advantages when using data file formats that MET does not directly support. If there is Python code to read the data format, the user can use those tools to read the data, and then copy the data into a NumPy ndarray or an Xarray DataArray. MET can then ingest the data via the Python script. Note that whether a NumPy ndarray or an Xarray DataArray is used, the data should be stored as double precision floating point numbers. Using different data types, such as integers or single precision floating point numbers, will lead to unexpected results in MET. @@ -236,7 +237,7 @@ The Ensemble-Stat, Series-Analysis, and MTD tools support the use of file lists -title "Python enabled plot_data_plane" Python Embedding for Point Observations -_______________________________________ +======================================= The ASCII2NC tool supports the "-format python" option. With this option, point observations may be passed as input. An example of this is provided in :numref:`ascii2nc-pyembed`. That example uses the **read_ascii_point.py** sample script which is included with the MET code. It reads ASCII data in MET's 11-column point observation format and stores it in a Pandas dataframe to be read by the ASCII2NC tool with Python. @@ -248,7 +249,7 @@ The **read_ascii_point.py** sample script can be found in: • `MET GitHub repository `_ in *met/scripts/python*. Python Embedding for MPR data -_____________________________ +============================= The Stat-Analysis tool supports the "-lookin python" option. With this option, matched pair (MPR) data may be passed as input. An example of this is provided in :numref:`StA-pyembed`. That example uses the **read_ascii_mpr.py** sample script which is included with the MET code. It reads MPR data and stores it in a Pandas dataframe to be read by the Stat-Analysis tool with Python. @@ -260,7 +261,7 @@ The **read_ascii_mpr.py** sample script can be found in: Python Embedding for Point Observations as input -________________________________________________ +================================================ The point2grid, plot_point_obs, ensemble_stat, and point_stat tools use MET point observation NetCDF. They support the python embedding by the prefix 'PYTHON_NUMPY=" and followed by a python script name instead of the MET point observastion NetCDF filename. The customized python script is expected to extend MET_BASE/python/met_point_obs.py and to produce the python variable, **met_point_data**, which is the dictionary of the MET point observation data. They are defined at MET_BASE/python/met_point_obs.py. diff --git a/met/docs/Users_Guide/appendixG.rst b/met/docs/Users_Guide/appendixG.rst index 8c46641ced..c2811fe4fa 100644 --- a/met/docs/Users_Guide/appendixG.rst +++ b/met/docs/Users_Guide/appendixG.rst @@ -1,7 +1,8 @@ .. _appendixG: +**************************************** Appendix G Vectors and Vector Statistics -======================================== +**************************************** In this appendix, we discuss some basic properties of vectors, concentrating on the two-dimensional case. To keep the discussion simple, we will assume we are using a Cartesian coordinate system. diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index 9f568932bd..7f96a62d46 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -1,8 +1,8 @@ .. _config_options: - +*************************** Configuration File Overview -=========================== +*************************** The configuration files that control many of the MET tools contain formatted ASCII text. This format has been updated for MET version |version| and @@ -392,9 +392,8 @@ into any relevant scripting. Settings common to multiple tools --------------------------------- -.. _exit_on_warning: - -:ref:`exit_on_warning ` +exit_on_warning +^^^^^^^^^^^^^^^ The "exit_on_warning" entry in ConfigConstants may be set to true or false. If set to true and a MET tool encounters a warning, it will immediately exit @@ -404,9 +403,8 @@ with bad status after writing the warning message. exit_on_warning = FALSE; -.. _nc_compression: - -:ref:`nc_compression ` +nc_compression +^^^^^^^^^^^^^^ The "nc_compression" entry in ConfigConstants defines the compression level for the NetCDF variables. Setting this option in the config file of one of @@ -427,9 +425,8 @@ writing of NetCDF files within MET significantly. nc_compression = 0; -.. _output_precision: - -:ref:`output_precision ` +output_precision +^^^^^^^^^^^^^^^^ The "output_precision" entry in ConfigConstants defines the precision (number of significant decimal places) to be written to the ASCII output @@ -440,9 +437,8 @@ override the default value set in ConfigConstants. output_precision = 5; -.. _tmp_dir_1: - -:ref:`tmp_dir ` +tmp_dir_1 +^^^^^^^^^ The "tmp_dir" entry in ConfigConstants defines the directory for the temporary files. The directory must exist and be writable. The environment @@ -454,9 +450,8 @@ Some tools override the temporary directory by the command line argument tmp_dir = "/tmp"; -.. _message_type_group_map_1: - -:ref:`message_type_group_map ` +message_type_group_map_1 +^^^^^^^^^^^^^^^^^^^^^^^^ The "message_type_group_map" entry is an array of dictionaries, each containing a "key" string and "val" string. This defines a mapping of @@ -475,9 +470,8 @@ which surface verification logic should be applied. { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } ]; -.. _message_type_map: - -:ref:`message_type_map ` +message_type_map +^^^^^^^^^^^^^^^^ The "message_type_map" entry is an array of dictionaries, each containing a "key" string and "val" string. This defines a mapping of input strings @@ -500,9 +494,8 @@ types. { key = "FM-97 ACARS"; val = "AIRCFT"; } ]; -.. _model: - -:ref:`model ` +model +^^^^^ The "model" entry specifies a name for the model being verified. This name is written to the MODEL column of the ASCII output generated. If you're @@ -514,9 +507,8 @@ e.g. model = "GFS"; model = "WRF"; -.. _desc: - -:ref:`desc ` +desc +^^^^ The "desc" entry specifies a user-specified description for each verification task. This string is written to the DESC column of the ASCII output @@ -531,9 +523,8 @@ e.g. desc = "QC_9"; desc = "NA"; -.. _obtype: - -:ref:`obtype ` +obtype +^^^^^^ The "obtype" entry specifies a name to describe the type of verifying gridded observation used. This name is written to the OBTYPE column in the ASCII @@ -548,8 +539,9 @@ the configuration file obtype value is written. obtype = "ANALYS"; .. _regrid: - -:ref:`regrid ` + +regrid +^^^^^^ The "regrid" entry is a dictionary containing information about how to handle input gridded data files. The "regrid" entry specifies regridding logic @@ -569,7 +561,8 @@ using the following entries: * to_grid = "path"; To regrid both to a grid defined by a file. - * to_grid = "spec"; To define a grid specification string, as described in :ref:`appendixB`. + * to_grid = "spec"; To define a grid specification string, as + described in :ref:`appendixB`. * The "vld_thresh" entry specifies a proportion between 0 and 1 to define the required ratio of valid data points. When regridding, compute @@ -656,9 +649,8 @@ using the following entries: censor_val = []; } -.. _fcst: - -:ref:`fcst ` +fcst +^^^^ The "fcst" entry is a dictionary containing information about the field(s) to be verified. This dictionary may include the following entries: @@ -1085,9 +1077,8 @@ File-format specific settings for the "field" entry: ]; } -.. _obs: - -:ref:`obs ` +obs +^^^ The "obs" entry specifies the same type of information as "fcst", but for the observation data. It will often be set to the same things as "fcst", @@ -1210,9 +1201,8 @@ or obs = fcst; -.. _climo_mean: - -:ref:`climo_mean ` +climo_mean +^^^^^^^^^^ The "climo_mean" dictionary specifies climatology mean data to be read by the Grid-Stat, Point-Stat, Ensemble-Stat, and Series-Analysis tools. It consists @@ -1268,9 +1258,8 @@ of several entires defining the climatology file names and fields to be used. hour_interval = 6; } -.. _climo_stdev: - -:ref:`climo_stdev ` +climo_stdev +^^^^^^^^^^^ The "climo_stdev" dictionary specifies climatology standard deviation data to be read by the Grid-Stat, Point-Stat, Ensemble-Stat, and Series-Analysis @@ -1300,9 +1289,8 @@ over the "climo_mean" setting and then updating the "file_name" entry. file_name = [ "/path/to/climatological/standard/deviation/files" ]; } -.. _climo_cdf: - -:ref:`climo_cdf ` +climo_cdf +^^^^^^^^^ The "climo_cdf" dictionary specifies how the the climatological mean ("climo_mean") and standard deviation ("climo_stdev") data are used to @@ -1368,9 +1356,8 @@ all pairs into a single climatological bin. direct_prob = FALSE; or TRUE } -.. _climato_data: - -:ref:`climatology data for probability forecasts ` +climato_data +^^^^^^^^^^^^ When specifying climatology data for probability forecasts, either supply a probabilistic "climo_mean" field or non-probabilistic "climo_mean" and @@ -1397,9 +1384,8 @@ In this way, the number of bins impacts the resolution of the climatological probabilities. These derived probability values are used to compute the climatological Brier Score and Brier Skill Score. -.. _mask_missing_flag: - -:ref:`mask_missing_flag ` +mask_missing_flag +^^^^^^^^^^^^^^^^^ The "mask_missing_flag" entry specifies how missing data should be handled in the Wavelet-Stat and MODE tools: @@ -1417,9 +1403,8 @@ in the Wavelet-Stat and MODE tools: mask_missing_flag = BOTH; -.. _obs_window: - -:ref:`obs_window ` +obs_window +^^^^^^^^^^ The "obs_window" entry is a dictionary specifying a beginning ("beg" entry) and ending ("end" entry) time offset values in seconds. It defines @@ -1435,9 +1420,8 @@ Point-Stat and Ensemble-Stat, the reference time is the forecast valid time. end = 5400; } -.. _mask: - -:ref:`mask ` +mask +^^^^ The "mask" entry is a dictionary that specifies the verification masking regions to be used when computing statistics. Each mask defines a @@ -1547,9 +1531,8 @@ is included in the mask. } -.. _ci_alpha: - -:ref:`ci_alpha ` +ci_alpha +^^^^^^^^ The "ci_alpha" entry is an array of floats specifying the values for alpha to be used when computing confidence intervals. Values of alpha must be @@ -1561,9 +1544,8 @@ interval. ci_alpha = [ 0.05, 0.10 ]; -.. _boot: - -:ref:`boot ` +boot +^^^^ The "boot" entry defines the parameters to be used in calculation of bootstrap confidence intervals. The interval variable indicates what method @@ -1625,9 +1607,8 @@ should be used for computing bootstrap confidence intervals: seed = ""; } -.. _interp: - -:ref:`interp ` +interp +^^^^^^ The "interp" entry is a dictionary that specifies what interpolation or smoothing (for the Grid-Stat tool) methods should be applied. @@ -1730,9 +1711,8 @@ This dictionary may include the following entries: ]; } -.. _land_mask: - -:ref:`land_mask ` +land_mask +^^^^^^^^^ The "land_mask" dictionary defines the land/sea mask field which is used when verifying at the surface. For point observations whose message type @@ -1759,9 +1739,8 @@ land_mask.flag may be set separately in each "obs.field" entry. thresh = eq1; } -.. _topo_mask: - -:ref:`topo_mask ` +topo_mask +^^^^^^^^^ The "topo_mask" dictionary defines the model topography field which is used when verifying at the surface. This logic is applied to point observations @@ -1790,9 +1769,8 @@ topo_mask.flag may be set separately in each "obs.field" entry. interp_fcst_thresh = ge-50&&le50; } -.. _hira: - -:ref:`hira ` +hira +^^^^ The "hira" entry is a dictionary that is very similar to the "interp" and "nbrhd" entries. It specifies information for applying the High Resolution @@ -1844,9 +1822,8 @@ This dictionary may include the following entries: prob_cat_thresh = []; } -.. _output_flag: - -:ref:`output_flag ` +output_flag +^^^^^^^^^^^ The "output_flag" entry is a dictionary that specifies what verification methods should be applied to the input data. Options exist for each @@ -1896,9 +1873,8 @@ output line type from the MET tools. Each line type may be set to one of: grad = NONE; Gradient statistics (S1 score) } -.. _nc_pairs_flag: - -:ref:`nc_pairs_flag ` +nc_pairs_flag +^^^^^^^^^^^^^ The "nc_pairs_flag" can be set either to a boolean value or a dictionary in either Grid-Stat, Wavelet-Stat or MODE. The dictionary (with slightly @@ -1928,9 +1904,8 @@ netcdf output will be generated. apply_mask = TRUE; } -.. _nc_pairs_var_name: - -:ref:`nc_pairs_var_name ` +nc_pairs_var_name +^^^^^^^^^^^^^^^^^ The "nc_pairs_var_name" entry specifies a string for each verification task in Grid-Stat. This string is parsed from each "obs.field" dictionary entry @@ -1949,9 +1924,8 @@ For example: nc_pairs_var_name = ""; -.. _nc_pairs_var_suffix: - -:ref:`nc_pairs_var_suffix ` +nc_pairs_var_suffix +^^^^^^^^^^^^^^^^^^^ The "nc_pairs_var_suffix" entry is similar to the "nc_pairs_var_name" entry described above. It is also parsed from each "obs.field" dictionary entry. @@ -1973,9 +1947,8 @@ now deprecated. nc_pairs_var_suffix = ""; -.. _ps_plot_flag: - -:ref:`ps_plot_flag ` +ps_plot_flag +^^^^^^^^^^^^ The "ps_plot_flag" entry is a boolean value for Wavelet-Stat and MODE indicating whether a PostScript plot should be generated summarizing @@ -1985,9 +1958,8 @@ the verification. ps_plot_flag = TRUE; -.. _grid_weight_flag: - -:ref:`grid_weight_flag ` +grid_weight_flag +^^^^^^^^^^^^^^^^ The "grid_weight_flag" specifies how grid weighting should be applied during the computation of continuous statistics and partial sums. It is @@ -2010,9 +1982,8 @@ by the sum of the weights for the current masking region. grid_weight_flag = NONE; -.. _hss_ec_value: - -ref:`hss_ec_value ` +hss_ec_value +^^^^^^^^^^^^ The "hss_ec_value" entry is a floating point number used in the computation of the HSS_EC statistic in the MCTS line type. It specifies the expected @@ -2028,9 +1999,8 @@ It set, it must greater than or equal to 0.0 and less than 1.0. A value of hss_ec_value = NA; -.. _rank_corr_flag: - -ref:`rank_corr_flag ` +rank_corr_flag +^^^^^^^^^^^^^^ The "rank_corr_flag" entry is a boolean to indicate whether Kendall's Tau and Spearman's Rank Correlation Coefficients (in the CNT line type) should @@ -2041,9 +2011,8 @@ intensive and slows down the runtime significantly. rank_corr_flag = FALSE; -.. _duplicate_flag: - -:ref:`duplicate_flag ` +duplicate_flag +^^^^^^^^^^^^^^ The "duplicate_flag" entry specifies how to handle duplicate point observations in Point-Stat and Ensemble-Stat: @@ -2064,9 +2033,8 @@ in those cases. duplicate_flag = NONE; -.. _obs_summary: - -:ref:`obs_summary ` +obs_summary +^^^^^^^^^^^ The "obs_summary" entry specifies how to compute statistics on observations that appear at a single location (lat,lon,level,elev) @@ -2101,9 +2069,8 @@ in those cases. obs_summary = NONE; -.. _obs_perc_value: - -:ref:`obs_perc_value ` +obs_perc_value +^^^^^^^^^^^^^^ Percentile value to use when obs_summary = PERC @@ -2112,9 +2079,8 @@ Percentile value to use when obs_summary = PERC obs_perc_value = 50; -.. _obs_quality_inc: - -:ref:`obs_quality_inc ` +obs_quality_inc +^^^^^^^^^^^^^^^ The "obs_quality_inc" entry specifies the quality flag values that are to be retained and used for verification. An empty list signifies that all @@ -2129,9 +2095,8 @@ Note "obs_quality_inc" replaces the older option "obs_quality". obs_quality_inc = [ "1", "2", "3", "9" ]; -.. _obs_quality_exc: - -:ref:`obs_quality_exc ` +obs_quality_exc +^^^^^^^^^^^^^^^ The "obs_quality_exc" entry specifies the quality flag values that are to be ignored and not used for verification. An empty list signifies that all @@ -2145,9 +2110,8 @@ an array of strings, even if the values themselves are numeric. obs_quality_exc = [ "1", "2", "3", "9" ]; -.. _met_data_dir: - -:ref:`met_data_dir ` +met_data_dir +^^^^^^^^^^^^ The "met_data_dir" entry specifies the location of the internal MET data sub-directory which contains data files used when generating plots. It @@ -2158,9 +2122,8 @@ locate the static data files they need at run time. met_data_dir = "MET_BASE"; -.. _many_plots: - -:ref:`fcst_raw_plot, obs_raw_plot, wvlt_plot, object_plot ` +many_plots +^^^^^^^^^^ The "fcst_raw_plot" entry is a dictionary used by Wavelet-Stat and MODE containing colortable plotting information for the plotting of the raw @@ -2191,9 +2154,8 @@ forecast field: The "obs_raw_plot", "wvlt_plot", and "object_plot" entries are dictionaries similar to the "fcst_raw_plot" described above. -.. _tmp_dir_2: - -:ref:`tmp_dir ` +tmp_dir_2 +^^^^^^^^^ The "tmp_dir" entry is a string specifying the location where temporary files should be written. @@ -2203,9 +2165,8 @@ files should be written. tmp_dir = "/tmp"; -.. _output_prefix: - -:ref:`output_prefix ` +output_prefix +^^^^^^^^^^^^^ The "output_prefix" entry specifies a string to be included in the output file name. The MET statistics tools construct output file names that @@ -2217,9 +2178,8 @@ of the same tool. output_prefix = ""; -.. _version: - -:ref:`version ` +version +^^^^^^^ The "version" entry specifies the version number of the configuration file. The configuration file version number should match the version number of @@ -2229,9 +2189,8 @@ the MET code being run. This value should generally not be modified. version = "VN.N"; -.. _time_summary: - -:ref:`time_summary ` +time_summary +^^^^^^^^^^^^ This feature was implemented to allow additional processing of observations with high temporal resolution. The "flag" entry toggles the "time_summary" @@ -2308,9 +2267,8 @@ Settings specific to individual tools EnsembleStatConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _ens: - -:ref:`ens ` +ens +""" The "ens" entry is a dictionary that specifies the fields for which ensemble products should be generated. This is very similar to the "fcst" and "obs" @@ -2352,9 +2310,8 @@ entries. This dictionary may include the following entries: ]; } -.. _nbrhd_prob: - -:ref:`nbrhd_prob ` +nbrhd_prob +"""""""""" The nbrhd_prob dictionary defines the neighborhoods used to compute NEP and NMEP output. The neighborhood shape is a SQUARE or CIRCLE centered on @@ -2375,9 +2332,8 @@ specified. vld_thresh = 0.0; } -.. _nmep_smooth: - -:ref:`nmep_smooth ` +nmep_smooth +""""""""""" Similar to the interp dictionary, the nmep_smooth dictionary includes a type array of dictionaries to define one or more methods for smoothing the NMEP @@ -2403,9 +2359,8 @@ combination of the categorical threshold (cat_thresh), neighborhood width ]; } -.. _fcst, obs_1: - -:ref:`fcst, obs ` +fcst, obs_1 +""""""""""" The fcst and obs entries define the fields for which Ensemble-Stat should compute rank histograms, probability integral transform histograms, @@ -2443,9 +2398,8 @@ data is provided, the climo_cdf thresholds will be used instead. } -.. _nc_var_str: - -:ref:`nc_var_str ` +nc_var_str +"""""""""" The "nc_var_str" entry specifies a string for each ensemble field and verification task in Ensemble-Stat. This string is parsed from each @@ -2461,9 +2415,8 @@ e.g. nc_var_str = "MIN"; nc_var_str = ""; -.. _obs_thresh: - -:ref:`obs_thresh ` +obs_thresh +"""""""""" The "obs_thresh" entry is an array of thresholds for filtering observation values prior to applying ensemble verification logic. They specify the values @@ -2476,9 +2429,8 @@ This option may be set separately for each obs.field entry. obs_thresh = [ NA ]; -.. _skip_const: - -:ref:`skip_const ` +skip_const +"""""""""" Setting "skip_const" to true tells Ensemble-Stat to exclude pairs where all the ensemble members and the observation have a constant value. For example, @@ -2491,9 +2443,8 @@ random. skip_const = FALSE; -.. _obs_error: - -:ref:`obs_error ` +obs_error +""""""""" Observation error options @@ -2550,9 +2501,8 @@ levels, and range of values. max = NA; } -.. _ensemble_flag: - -:ref:`ensemble_flag ` +ensemble_flag +""""""""""""" The "ensemble_flag" entry is a dictionary of boolean value indicating which ensemble products should be generated: @@ -2603,9 +2553,8 @@ which ensemble products should be generated: weight = FALSE; } -.. _rng: - -:ref:`rng ` +rng +""" See: `Random Number Generator Performance `_ used for random assignment of ranks when they are tied. @@ -2958,9 +2907,8 @@ MET User's Guide for a description of these attributes. MODEConfig_default ^^^^^^^^^^^^^^^^^^ -.. _quilt: - -:ref:`quilt ` +quilt +""""" The "quilt" entry is a boolean to indicate whether all permutations of convolution radii and thresholds should be run. If set to false, the number @@ -2975,9 +2923,8 @@ MODE will be run. quilt = false; -.. _fcst, obs_2: - -:ref:`fcst, obs ` +fcst, obs_2 +""""""""""" The object definition settings for MODE are contained within the "fcst" and "obs" entries: @@ -3061,9 +3008,8 @@ The object definition settings for MODE are contained within the "fcst" and merge_flag = THRESH; } -.. _grid_res: - -:ref:`grid_res ` +grid_res +"""""""" The "grid_res" entry is the nominal spacing for each grid square in kilometers. The variable is not used directly in the code, but subsequent @@ -3075,9 +3021,8 @@ are used for these variables. grid_res = 4; -.. _match_flag: - -:ref:`match_flag ` +match_flag +"""""""""" The "match_flag" entry specifies the matching method to be applied: @@ -3095,9 +3040,8 @@ The "match_flag" entry specifies the matching method to be applied: match_flag = MERGE_BOTH; -.. _max_centroid_dist: - -:ref:`max_centroid_dist ` +max_centroid_dist +""""""""""""""""" The "max_centroid_dist" entry specifies the maximum allowable distance in grid squares between the centroids of objects for them to be compared. @@ -3108,9 +3052,8 @@ skip unreasonable object comparisons. max_centroid_dist = 800.0/grid_res; -.. _weight: - -:ref:`weight ` +weight +"""""" The weight variables control how much weight is assigned to each pairwise attribute when computing a total interest value for object pairs. The weights @@ -3132,9 +3075,8 @@ sum of the weights listed. inten_perc_value = 50; } -.. _interest_function: - -:ref:`interest_function ` +interest_function +""""""""""""""""" The set of interest function variables listed define which values are of interest for each pairwise attribute measured. The interest functions may be @@ -3190,9 +3132,8 @@ mathematical functions. inten_perc_ratio = ratio_if; } -.. _total_interest_thresh: - -:ref:`total_interest_thresh ` +total_interest_thresh +""""""""""""""""""""" The total_interest_thresh variable should be set between 0 and 1. This threshold is applied to the total interest values computed for each pair of @@ -3202,9 +3143,8 @@ objects and is used in determining matches. total_interest_thresh = 0.7; -.. _print_interest_thresh: - -:ref:`print_interest_thresh ` +print_interest_thresh +""""""""""""""""""""" The print_interest_thresh variable determines which pairs of object attributes will be written to the output object attribute ASCII file. The @@ -3218,9 +3158,8 @@ the max_centroid_dist variable. print_interest_thresh = 0.0; -.. _plot_valid_flag: - -:ref:`plot_valid_flag ` +plot_valid_flag +""""""""""""""" When applied, the plot_valid_flag variable indicates that only the region containing valid data after masking is applied should be plotted. TRUE @@ -3231,9 +3170,8 @@ region containing valid data after masking should be plotted. plot_valid_flag = FALSE; -.. _plot_gcarc_flag: - -:ref:`plot_gcarc_flag ` +plot_gcarc_flag +""""""""""""""" When applied, the plot_gcarc_flag variable indicates that the edges of polylines should be plotted using great circle arcs as opposed to straight @@ -3243,9 +3181,8 @@ lines in the grid. plot_gcarc_flag = FALSE; -.. _ct_stats_flag: - -:ref:`ct_stats_flag ` +ct_stats_flag +""""""""""""" The ct_stats_flag can be set to TRUE or FALSE to produce additional output, in the form of contingency table counts and statistics. @@ -3254,9 +3191,8 @@ in the form of contingency table counts and statistics. ct_stats_flag = TRUE; -.. _shift_right: - -:ref:`shift_right ` +shift_right +""""""""""" When MODE is run on global grids, this parameter specifies how many grid squares to shift the grid to the right. MODE does not currently connect @@ -3331,9 +3267,8 @@ following criteria: 7 - Auxiliary levels generated via interpolation from spanning levels (upper-air profile reports) -.. _message_type: - -:ref:`message_type ` +message_type +"""""""""""" In the PB2NC tool, the "message_type" entry is an array of message types to be retained. An empty list indicates that all should be retained. @@ -3354,9 +3289,8 @@ For example: message_type = []; -.. _message_type_group_map_2: - -:ref:`message_type_group_map ` +message_type_group_map_2 +"""""""""""""""""""""""" Mapping of message type group name to comma-separated list of values. The default setting defines ANYAIR, ANYSFC, and ONLYSF as groups. @@ -3371,9 +3305,8 @@ Derive PRMSL only for SURFACE message types. { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } ]; -.. _station_id: - -:ref:`station_id ` +station_id +"""""""""" The "station_id" entry is an array of station ids to be retained or the filename which contains station ids. An array of station ids @@ -3386,9 +3319,8 @@ For example: station_id = [ "KDEN" ]; station_id = []; -.. _elevation_range: - -:ref:`elevation_range ` +elevation_range +""""""""""""""" The "elevation_range" entry is a dictionary which contains "beg" and "end" entries specifying the range of observing locations elevations to be @@ -3401,9 +3333,8 @@ retained. end = 100000; } -.. _pb_report_type: - -:ref:`pb_report_type ` +pb_report_type +"""""""""""""" The "pb_report_type" entry is an array of PREPBUFR report types to be retained. The numeric "pb_report_type" entry allows for further @@ -3423,9 +3354,8 @@ For example: pb_report_type = []; -.. _in_report_type: - -:ref:`in_report_type ` +in_report_type +"""""""""""""" The "in_report_type" entry is an array of input report type values to be retained. The numeric "in_report_type" entry provides additional @@ -3444,9 +3374,8 @@ For example: in_report_type = []; -.. _instrument_type: - -:ref:`instrument_type ` +instrument_type +""""""""""""""" The "instrument_type" entry is an array of instrument types to be retained. An empty list indicates that all should be retained. @@ -3455,9 +3384,8 @@ An empty list indicates that all should be retained. instrument_type = []; -.. _level_range: - -:ref:`level_range ` +level_range +""""""""""" The "level_range" entry is a dictionary which contains "beg" and "end" entries specifying the range of vertical levels (1 to 255) to be retained. @@ -3469,9 +3397,8 @@ entries specifying the range of vertical levels (1 to 255) to be retained. end = 255; } -.. _level_category: - -:ref:`level_category ` +level_category +"""""""""""""" The "level_category" entry is an array of integers specifying which level categories should be retained: @@ -3507,9 +3434,8 @@ See: `Current Table A Entries in PREPBUFR mnemonic table ` +obs_bufr_var +"""""""""""" The "obs_bufr_var" entry is an array of strings containing BUFR variable names to be retained or derived. This replaces the "obs_grib_code" setting @@ -3529,9 +3455,8 @@ command line option to see the list of available observation variables. obs_bufr_var = [ "QOB", "TOB", "ZOB", "UOB", "VOB" ]; -.. _obs_bufr_map: - -:ref:`obs_bufr_map ` +obs_bufr_map +"""""""""""" Mapping of input BUFR variable names to output variables names. The default PREPBUFR map, obs_prepbufr_map, is appended to this map. @@ -3542,9 +3467,8 @@ of the forecast the observation is used to verify. obs_bufr_map = []; -.. _obs_prefbufr_map: - -:ref:`obs_prefbufr_map ` +obs_prefbufr_map +"""""""""""""""" Default mapping for PREPBUFR. Replace input BUFR variable names with GRIB abbreviations in the output. This default map is appended to obs_bufr_map. @@ -3569,9 +3493,8 @@ abbreviations to the output. { key = "D_PRMSL"; val = "PRMSL"; } ]; -.. _quality_mark_thresh: - -:ref:`quality_mark_thresh ` +quality_mark_thresh +""""""""""""""""""" The "quality_mark_thresh" entry specifies the maximum quality mark value to be retained. Observations with a quality mark LESS THAN OR EQUAL TO @@ -3584,9 +3507,8 @@ See `Code table for observation quality markers ` +event_stack_flag +"""""""""""""""" The "event_stack_flag" entry is set to "TOP" or "BOTTOM" to specify whether observations should be drawn from the top of the event @@ -3599,9 +3521,8 @@ stack (most quality controlled) or the bottom of the event stack (most raw). SeriesAnalysisConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _block_size: - -:ref:`block_size ` +block_size +"""""""""" Computation may be memory intensive, especially for large grids. The "block_size" entry sets the number of grid points to be processed @@ -3614,9 +3535,8 @@ of grid points, and they are all processed concurrently. block_size = 1024; -.. _vld_thresh: - -:ref:`vld_thresh ` +vld_thresh +"""""""""" Ratio of valid matched pairs to total length of series for a grid point. If valid threshold is exceeded at that grid point the statistics @@ -3628,9 +3548,8 @@ setting requires all data in the series to be valid. vld_thresh = 1.0; -.. _output_stats: - -:ref:`output_stats ` +output_stats +"""""""""""" Statistical output types need to be specified explicitly. Refer to User's Guide for available output types. To keep output file size reasonable, @@ -3656,9 +3575,8 @@ grid is large. STATAnalysisConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _jobs: - -:ref:`jobs ` +jobs +"""" The "jobs" entry is an array of STAT-Analysis jobs to be performed. Each element in the array contains the specifications for a single analysis @@ -4125,9 +4043,8 @@ confidence intervals computed for the aggregated statistics. WaveletStatConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _grid_decomp_flag: - -:ref:`grid_decomp_flag ` +grid_decomp_flag +"""""""""""""""" The "grid_decomp_flag" entry specifies how the grid should be decomposed in Wavelet-Stat into dyadic (2^n x 2^n) tiles: @@ -4142,9 +4059,8 @@ Wavelet-Stat into dyadic (2^n x 2^n) tiles: grid_decomp_flag = AUTO; -.. _tile: - -:ref:`tile ` +tile +"""" The "tile" entry is a dictionary that specifies how tiles should be defined in Wavelet-Stat when the "grid_decomp_flag" is set to "TILE": @@ -4168,9 +4084,8 @@ in Wavelet-Stat when the "grid_decomp_flag" is set to "TILE": ]; } -.. _wavelet: - -:ref:`wavelet ` +wavelet +""""""" The "wavelet" entry is a dictionary in Wavelet-Stat that specifies how the wavelet decomposition should be performed: @@ -4205,9 +4120,8 @@ wavelet decomposition should be performed: member = 2; } -.. _obs_raw_wvlt_object_plots: - -:ref:`obs_raw_plot, wvlt_plot, object_plot ` +obs_raw_wvlt_object_plots +""""""""""""""""""""""""" The "obs_raw_plot", "wvlt_plot", and "object_plot" entries are dictionaries similar to the "fcst_raw_plot" described in the "Settings common to multiple @@ -4216,15 +4130,13 @@ tools" section. WWMCARegridConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _to_grid: - -:ref:`to_grid ` +to_grid +""""""" Please see the description of the "to_grid" entry in the "regrid" dictionary above. -.. _NetCDF output information: - -:ref:`NetCDF output information ` +NetCDF output information +""""""""""""""""""""""""" Supply the NetCDF output information. For example: @@ -4242,9 +4154,8 @@ Supply the NetCDF output information. For example: long_name = ""; level = ""; -.. _max_minutes (pixel age): - -:ref:`max_minutes (pixel age) ` +max_minutes (pixel age) +""""""""""""""""""""""" Maximum pixel age in minutes @@ -4252,9 +4163,8 @@ Maximum pixel age in minutes max_minutes = 120; -.. _swap_endian: - -:ref:`swap_endian ` +swap_endian +""""""""""" The WWMCA pixel age data is stored in binary data files in 4-byte blocks. The swap_endian option indicates whether the endian-ness of the data should @@ -4264,9 +4174,8 @@ be swapped after reading. swap_endian = TRUE; -.. _write_pixel_age: - -:ref:`write_pixel_age ` +write_pixel_age +""""""""""""""" By default, wwmca_regrid writes the cloud percent data specified on the command line to the output file. This option writes the pixel age data, diff --git a/met/docs/Users_Guide/config_options_tc.rst b/met/docs/Users_Guide/config_options_tc.rst index b9542a878d..17b1c266c4 100644 --- a/met/docs/Users_Guide/config_options_tc.rst +++ b/met/docs/Users_Guide/config_options_tc.rst @@ -1,16 +1,16 @@ .. _config_options_tc: +************************************** Tropical Cyclone Configuration Options -====================================== +************************************** See :numref:`config_options` for a description of the configuration file syntax. Configuration settings common to multiple tools -_______________________________________________ +=============================================== -.. _storm_id_1: - -:ref:`storm_id ` +storm_id_1 +---------- Specify a comma-separated list of storm id's to be used: @@ -30,9 +30,8 @@ This may also be set using basin, cyclone, and timing information below. storm_id = []; -.. _basin: - -:ref:`basin ` +basin +----- Specify a comma-separated list of basins to be used. Expected format is a 2-letter basin identifier. An empty list indicates that all should be used. @@ -50,9 +49,8 @@ For example: basin = []; -.. _cyclone: - -:ref:`cyclone ` +cyclone +------- Specify a comma-separated list of cyclone numbers (01-99) to be used. An empty list indicates that all should be used. @@ -66,9 +64,8 @@ For example: cyclone = []; -.. _storm_name_1: - -:ref:`storm_name ` +storm_name_1 +------------ Specify a comma-separated list of storm names to be used. An empty list indicates that all should be used. @@ -82,9 +79,8 @@ For example: storm_name = []; -.. _init_beg end inc exc: - -:ref:`init_beg, init_end, init_inc, init_exc ` +init_beg end inc exc +-------------------- Specify a model initialization time window in YYYYMMDD[_HH[MMSS]] format or provide a list of specific initialization times to include (inc) @@ -109,9 +105,8 @@ For example: init_inc = []; init_exc = []; -.. _valid_beg end inc exc_1: - - ref:`valid_beg, valid_end, valid_inc, valid_exc ` +valid_beg end inc exc_1 +----------------------- Specify a model valid time window YYYYMMDD[_HH[MMSS]] format or provide a list of specific valid times to include (inc) or exclude (exc). If a time @@ -138,9 +133,8 @@ For example: valid_inc = []; valid_exc = []; -.. _init_hour_1: - -:ref:`init_hour ` +init_hour_1 +----------- Specify a comma-separated list of model initialization hours to be used in HH[MMSS] format. An empty list indicates that all hours should be used. @@ -154,9 +148,8 @@ For example: init_hour = []; -.. _lead_req: - -:ref:`lead_req ` +lead_req +-------- Specify the required lead time in HH[MMSS] format. Tracks that contain all of these required times will be @@ -169,9 +162,8 @@ all lead times will be used. lead_req = []; -.. _init_mask, valid_mask: - -:ref:`init_mask, valid_mask ` +init_mask, valid_mask +--------------------- Specify lat/lon polylines defining masking regions to be applied. Tracks whose initial location falls within init_mask will be used. @@ -187,9 +179,8 @@ For example: init_mask = ""; valid_mask = ""; -.. _version: - -:ref:`version ` +version +------- Indicate the version number for the contents of this configuration file. The value should generally not be modified. @@ -200,15 +191,14 @@ The value should generally not be modified. Settings specific to individual tools -_____________________________________ +===================================== TCPairsConfig_default -~~~~~~~~~~~~~~~~~~~~~ +--------------------- -.. _model_1: - -:ref:`model ` +model_1 +^^^^^^^ The "model" entry specifies an array of model names to be verified. If verifying multiple models, choose descriptive model names (no whitespace) @@ -223,9 +213,8 @@ For example: model = []; -.. _check_dup: - -:ref:`check_dup ` +check_dup +^^^^^^^^^ Specify whether the code should check for duplicate ATCF lines when building tracks. Setting this to FALSE makes the parsing of tracks quicker. @@ -239,9 +228,8 @@ For example: check_dup = FALSE; -.. _interp12: - -:ref:`interp12 ` +interp12 +^^^^^^^^ Specify whether special processing should be performed for interpolated model names ending in 'I' (e.g. AHWI). Search for corresponding tracks whose model @@ -259,9 +247,8 @@ name ends in '2' (e.g. AHW2) and apply the following logic: interp12 = REPLACE; -.. _consensus: - -:ref:`consensus ` +consensus +^^^^^^^^^ Specify how consensus forecasts should be defined: @@ -288,9 +275,8 @@ For example: consensus = []; -.. _lag_time: - -:ref:`lag_time ` +lag_time +^^^^^^^^ Specify a comma-separated list of forecast lag times to be used in HH[MMSS] format. For each ADECK track identified, a lagged track will be derived @@ -306,9 +292,8 @@ For example: lag_time = []; -.. _best: - -:ref:`best_technique, best_baseline, oper_technique, oper_baseline ` +best +^^^^ Specify comma-separated lists of CLIPER/SHIFOR baseline forecasts to be derived from the BEST and operational tracks, as defined by the @@ -333,9 +318,8 @@ For example: oper_baseline = []; -.. _anly_track: - -:ref:`anly_track ` +anly_track +^^^^^^^^^^ Analysis tracks consist of multiple track points with a lead time of zero for the same storm. An analysis track may be generated by running model @@ -353,9 +337,8 @@ For example: anly_track = BDECK; -.. _match_points: - -:ref:`match_points ` +match_points +^^^^^^^^^^^^ Specify whether only those track points common to both the ADECK and BDECK tracks should be written out. @@ -371,9 +354,8 @@ For example: match_points = FALSE; -.. _dland_file: - -:ref:`dland_file ` +dland_file +^^^^^^^^^^ Specify the NetCDF output of the gen_dland tool containing a gridded representation of the minimum distance to land. @@ -384,9 +366,8 @@ representation of the minimum distance to land. dland_file = "MET_BASE/tc_data/dland_nw_hem_tenth_degree.nc"; -.. _watch_warn: - -:ref:`watch_warn ` +watch_warn +^^^^^^^^^^ Specify watch/warning information. Specify an ASCII file containing watch/warning information to be used. At each track point, the most severe @@ -404,9 +385,8 @@ occurring 4 hours (-14400 second) prior to the watch/warning time. } -.. _basin_map: - -:ref:`basin_map ` +basin_map +^^^^^^^^^ The basin_map entry defines a mapping of input names to output values. Whenever the basin string matches "key" in the input ATCF files, it is @@ -443,11 +423,10 @@ parameter will result in missed matches. ]; TCStatConfig_default -____________________ - -.. _amodel, bmodel: +==================== -:ref:`amodel, bmodel ` +amodel, bmodel +-------------- Stratify by the AMODEL or BMODEL columns. Specify comma-separated lists of model names to be used for all analyses @@ -465,9 +444,8 @@ For example: amodel = []; bmodel = []; -.. _valid_beg end inc exc: - - ref:`valid_beg, valid_end, valid_inc, valid_exc ` +valid_beg end inc exc +--------------------- Stratify by the VALID times. Define beginning and ending time windows in YYYYMMDD[_HH[MMSS]] @@ -490,9 +468,8 @@ For example: valid_inc = []; valid_exc = []; -.. _init valid_hour lead req: - -:ref:`init_hour, valid_hour, lead, lead_req ` +init valid_hour lead req +------------------------ Stratify by the initialization and valid hours and lead time. Specify a comma-separated list of initialization hours, @@ -516,9 +493,8 @@ For example: lead_req = []; -.. _line_type: - -:ref:`line_type ` +line_type +--------- Stratify by the LINE_TYPE column. May add using the "-line_type" job command option. @@ -532,9 +508,8 @@ For example: line_type = []; -.. _track_watch_warn: - -:ref:`track_watch_warn ` +track_watch_warn +---------------- Stratify by checking the watch/warning status for each track point common to both the ADECK and BDECK tracks. If the watch/warning status @@ -554,9 +529,8 @@ For example: track_watch_warn = []; -.. _column_thresh_name_and_val: - -:ref:`column_thresh_name, column_thresh_val ` +column_thresh_name_and_val +-------------------------- Stratify by applying thresholds to numeric data columns. Specify a comma-separated list of columns names and thresholds @@ -574,9 +548,8 @@ For example: column_thresh_name = []; column_thresh_val = []; -.. _column_str_name, column_str_val: - -:ref:`column_str_name, column_str_val ` +column_str_name, column_str_val +------------------------------- Stratify by performing string matching on non-numeric data columns. Specify a comma-separated list of columns names and values @@ -594,9 +567,8 @@ For example: column_str_name = []; column_str_val = []; -.. _column_str_name val: - -:ref:`column_str_exc_name, column_str_exc_val ` +column_str_name val +------------------- Stratify by performing string matching on non-numeric data columns. Specify a comma-separated list of columns names and values @@ -614,9 +586,8 @@ For example: column_str_exc_name = []; column_str_exc_val = []; -.. _init_thresh_name, init_thresh_val: - -:ref:`init_thresh_name, init_thresh_val ` +init_thresh_name, init_thresh_val +--------------------------------- Just like the column_thresh options above, but apply the threshold only when lead = 0. If lead = 0 value does not meet the threshold, discard @@ -633,9 +604,9 @@ For example: init_thresh_name = []; init_thresh_val = []; -.. _init_str_name, init_str_val: - -:ref:`init_str_name, init_str_val ` + +init_str_name, init_str_val +--------------------------- Just like the column_str options above, but apply the string matching only when lead = 0. If lead = 0 string does not match, discard the entire track. @@ -652,9 +623,8 @@ For example: init_str_name = []; init_str_val = []; -.. _init_str_exc_name and _exc_val: - -:ref:`init_str_exc_name, init_str_exc_val ` +init_str_exc_name and _exc_val +------------------------------ Just like the column_str_exc options above, but apply the string matching only when lead = 0. If lead = 0 string does match, discard the entire track. @@ -671,9 +641,8 @@ For example: init_str_exc_name = []; init_str_exc_val = []; -.. _water_only: - -:ref:`water_only ` +water_only +---------- Stratify by the ADECK and BDECK distances to land. Once either the ADECK or BDECK track encounters land, discard the remainder of the track. @@ -687,9 +656,8 @@ For example: water_only = FALSE; -.. _rirw: - -:ref:`rirw ` +rirw +---- Specify whether only those track points for which rapid intensification or weakening of the maximum wind speed occurred in the previous time @@ -721,9 +689,8 @@ May modify using the following job command options: bdeck = adeck; Copy settings to the BDECK or specify different logic. } -.. _landfall beg end: - -:ref:`landfall, landfall_beg, landfall_end ` +landfall beg end +---------------- Specify whether only those track points occurring near landfall should be retained, and define the landfall retention window as a time string in HH[MMSS] @@ -754,9 +721,8 @@ For example: landfall_beg = "-24"; landfall_end = "00"; -.. _event_equal: - -:ref:`event_equal ` +event_equal +----------- Specify whether only those cases common to all models in the dataset should be retained. May modify using the "-event_equal" job command option. @@ -771,9 +737,8 @@ For example: event_equal = FALSE; -.. _event_equal_lead: - -:ref:`event_equal_lead ` +event_equal_lead +---------------- Specify lead times that must be present for a track to be included in the event equalization logic. @@ -783,9 +748,8 @@ event equalization logic. event_equal_lead = [ "12", "24", "36" ]; -.. _out_int_mask: - -:ref:`out_int_mask ` +out_int_mask +------------ Apply polyline masking logic to the location of the ADECK track at the initialization time. If it falls outside the mask, discard the entire track. @@ -801,9 +765,8 @@ For example: out_init_mask = ""; -.. _out_valid_mask: - -:ref:`out_valid_mask ` +out_valid_mask +-------------- Apply polyline masking logic to the location of the ADECK track at the valid time. If it falls outside the mask, discard only the current track @@ -818,9 +781,8 @@ For example: out_valid_mask = ""; -.. _job: - -:ref:`job ` +job +--- The "jobs" entry is an array of TCStat jobs to be performed. Each element in the array contains the specifications for a single analysis @@ -937,7 +899,8 @@ Where "job_name" is set to one of the following: Default search time window is 0 0, requiring exact match -rirw_time or -rirw_time_adeck and -rirw_time_bdeck to override defaults -rirw_exact or -rirw_exact_adeck and -rirw_exact_bdeck to override defaults - -rirw_thresh or -rirw_thresh_adeck and -rirw_thresh_bdeck to override defaults + -rirw_thresh or -rirw_thresh_adeck and -rirw_thresh_bdeck to override + defaults -by column_name to specify case information -out_alpha to override default alpha value -out_line_type to specify output line types (CTC, CTS, and MPR) @@ -1004,11 +967,10 @@ Where "job_name" is set to one of the following: jobs = []; TCGenConfig_default -___________________ +=================== -.. _int_freq: - -:ref:`int_freq ` +int_freq +-------- Model initialization frequency in hours, starting at 0. @@ -1016,9 +978,8 @@ Model initialization frequency in hours, starting at 0. init_freq = 6; -.. _lead_window: - -:ref:`lead_window ` +lead_window +----------- Lead times in hours to be searched for genesis events. @@ -1030,9 +991,8 @@ Lead times in hours to be searched for genesis events. end = 120; } -.. _min_duration: - -:ref:`min_duration ` +min_duration +------------ Minimum track duration for genesis event in hours. @@ -1040,9 +1000,8 @@ Minimum track duration for genesis event in hours. min_duration = 12; -.. _fcst_genesis: - -:ref:`fcst_genesis ` +fcst_genesis +------------ Forecast genesis event criteria. Defined as tracks reaching the specified intensity category, maximum wind speed threshold, and minimum sea-level @@ -1057,9 +1016,8 @@ track point where all of these criteria are met. mslp_thresh = NA; } -.. _best_genesis: - -:ref:`best_genesis ` +best_genesis +------------ BEST track genesis event criteria. Defined as tracks reaching the specified intensity category, maximum wind speed threshold, and minimum sea-level @@ -1075,9 +1033,8 @@ first track point where all of these criteria are met. mslp_thresh = NA; } -.. _oper_genesis: - -:ref:`oper_genesis ` +oper_genesis +------------ Operational track genesis event criteria. Defined as tracks reaching the specified intensity category, maximum wind speed threshold, and minimum @@ -1094,11 +1051,10 @@ time of the first track point where all of these criteria are met. } Track filtering options which may be specified separately in each filter array entry -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------------------------------------------ -.. _filter: - -:ref:`filter ` +filter +^^^^^^ Filter is an array of dictionaries containing the track filtering options listed below. If empty, a single filter is defined using the top-level @@ -1108,9 +1064,8 @@ settings. filter = []; -.. _desc: - -:ref:`desc ` +desc +^^^^ Description written to output DESC column @@ -1118,9 +1073,8 @@ Description written to output DESC column desc = "NA"; -.. _model_2: - -:ref:`model ` +model_2 +^^^^^^^ Forecast ATCF ID's If empty, all ATCF ID's found will be processed. @@ -1131,9 +1085,8 @@ Statistics will be generated separately for each ATCF ID. model = []; -.. _storm_id_2: - -:ref:`storm_id ` +storm_id_2 +^^^^^^^^^^ BEST and operational track storm identifiers @@ -1141,9 +1094,8 @@ BEST and operational track storm identifiers storm_id = []; -.. _storm_name_2: - -:ref:`storm_name ` +storm_name_2 +^^^^^^^^^^^^ BEST and operational track storm names @@ -1151,9 +1103,8 @@ BEST and operational track storm names storm_name = []; -.. _init_beg, init_end2: - -:ref:`init_beg, init_end ` +init_beg, init_end2 +^^^^^^^^^^^^^^^^^^^ Forecast and operational initialization time window @@ -1162,9 +1113,8 @@ Forecast and operational initialization time window init_beg = ""; init_end = ""; -.. _valid_beg, valid_end_2: - -:ref:`valid_beg, valid_end ` +valid_beg, valid_end_2 +^^^^^^^^^^^^^^^^^^^^^^ Forecast, BEST, and operational valid time window @@ -1173,9 +1123,8 @@ Forecast, BEST, and operational valid time window valid_beg = ""; valid_end = ""; -.. _init_hour_2: - -:ref:`init_hour ` +init_hour_2 +^^^^^^^^^^^ Forecast and operational initialization hours @@ -1183,9 +1132,8 @@ Forecast and operational initialization hours init_hour = []; -.. _lead: - -:ref:`lead ` +lead +^^^^ Forecast and operational lead times in hours @@ -1193,9 +1141,8 @@ Forecast and operational lead times in hours lead = []; -.. _vx_mask: - -:ref:`vx_mask ` +vx_mask +^^^^^^^ Spatial masking region (path to gridded data file or polyline file) @@ -1203,9 +1150,8 @@ Spatial masking region (path to gridded data file or polyline file) vx_mask = ""; -.. _dland_thresh: - -:ref:`dland_thresh ` +dland_thresh +^^^^^^^^^^^^ Distance to land threshold @@ -1213,9 +1159,8 @@ Distance to land threshold dland_thresh = NA; -.. _genesis_window: - -:ref:`genesis_window ` +genesis_window +^^^^^^^^^^^^^^ Genesis matching time window, in hours relative to the forecast genesis time @@ -1226,9 +1171,8 @@ Genesis matching time window, in hours relative to the forecast genesis time end = 24; } -.. _genesis_radius: - -:ref:`genesis_radius ` +genesis_radius +^^^^^^^^^^^^^^ Genesis matching search radius in km. @@ -1237,11 +1181,10 @@ Genesis matching search radius in km. genesis_radius = 300; Global settings -_______________ - -.. _ci_alpha: +=============== -:ref:`ci_alpha ` +ci_alpha +-------- Confidence interval alpha value @@ -1249,9 +1192,8 @@ Confidence interval alpha value ci_alpha = 0.05; -.. _output_flag: - -:ref:`output_flag ` +output_flag +----------- Statistical output types diff --git a/met/docs/Users_Guide/data_io.rst b/met/docs/Users_Guide/data_io.rst index dcca8763f9..6c05461f43 100644 --- a/met/docs/Users_Guide/data_io.rst +++ b/met/docs/Users_Guide/data_io.rst @@ -1,14 +1,15 @@ .. _data_io: +************ MET Data I/O -============ +************ Data must often be preprocessed prior to using it for verification. Several MET tools exist for this purpose. In addition to preprocessing observations, some plotting utilities for data checking are also provided and described at the end of this section. Both the input and output file formats are described in this section. :numref:`Input data formats` and :numref:`Intermediate data formats` are primarily concerned with re-formatting input files into the intermediate files required by some MET modules. These steps are represented by the first three columns in the MET flowchart depicted in :numref:`overview-figure`. Output data formats are described in :numref:`Output data formats`. Common configuration files options are described in :numref:`Configuration File Details`. Description of software modules used to reformat the data may now be found in :numref:`reformat_point` and :numref:`reformat_grid`. .. _Input data formats: Input data formats -__________________ +================== The MET package can handle multiple gridded input data formats: GRIB version 1, GRIB version 2, and NetCDF files following the Climate and Forecast (CF) conventions, containing WRF output post-processed using wrf_interp, or produced by the MET tools themselves. MET supports standard NCEP, USAF, UKMet Office and ECMWF GRIB tables along with custom, user-defined GRIB tables and the extended PDS including ensemble member metadata. See :numref:`Configuration File Details` for more information. Point observation files may be supplied in either PrepBUFR, ASCII, or MADIS format. Note that MET does not require the Unified Post-Processor to be used, but does require that the input GRIB data be on a standard, de-staggered grid on pressure or regular levels in the vertical. While the Grid-Stat, Wavelet-Stat, MODE, and MTD tools can be run on a gridded field at virtually any level, the Point-Stat tool can only be used to verify forecasts at the surface or on pressure or height levels. MET does not interpolate between native model vertical levels. @@ -19,7 +20,7 @@ Input point observation files in PrepBUFR format are available through NCEP. The Tropical cyclone forecasts and observations are typically provided in a specific ATCF (Automated Tropical Cyclone Forecasting) ASCII format, in A-deck, B-deck, and E-deck files. Requirements for CF Compliant NetCDF -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------ The MET tools use following attributes and variables for input CF Compliant NetCDF data. @@ -124,7 +125,7 @@ MET gets the valid time from the time variable and the "forecast_reference_time" "degreesE" Performance with NetCDF input data -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------- There is no limitation on the NetCDF file size. The size of the data variables matters more than the file size. The NetCDF API loads the metadata first upon opening the NetCDF file. It's similar for accessing data variables. There are two API calls: getting the metadata and getting the actual data. The memory is allocated and consumed at the second API call (getting the actual data). @@ -133,14 +134,14 @@ The dimensions of the data variables matter. MET requests the NetCDF data needs .. _Intermediate data formats: Intermediate data formats -_________________________ +========================= MET uses NetCDF as an intermediate file format. The MET tools which write gridded output files write to a common gridded NetCDF file format. The MET tools which write point output files write to a common point observation NetCDF file format. .. _Output data formats: Output data formats -___________________ +=================== The MET package currently produces output in the following basic file formats: STAT files, ASCII files, NetCDF files, PostScript plots, and png plots from the Plot-Mode-Field utility. @@ -161,7 +162,7 @@ Users can use the optional plotting utilities Plot-Data-Plane, Plot-Point-Obs, a .. _Data format summary: Data format summary -___________________ +=================== The following is a summary of the input and output formats for each of the tools currently in MET. The output listed is the maximum number of possible output files. Generally, the type of output files generated can be controlled by the configuration files and/or the command line options: @@ -367,7 +368,7 @@ The following is a summary of the input and output formats for each of the tools .. _Configuration File Details: Configuration File Details -__________________________ +========================== Part of the strength of MET is the leveraging of capability across tools. There are several configuration options that are common to many of the tools. diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index fd1dbf535a..ca449cdd9c 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -1,18 +1,19 @@ .. _ensemble-stat: +****************** Ensemble-Stat Tool -================== +****************** Introduction -____________ +============ The Ensemble-Stat tool may be run to create simple ensemble forecasts (mean, probability, spread, etc) from a set of several forecast model files to be used by the MET statistics tools. If observations are also included, ensemble statistics such as rank histograms, probability integral transform histograms, spread/skill variance, relative position and continuous ranked probability score are produced. Climatological mean and standard deviation data may also be provided, and will be used as a reference forecast in several of the output statistics. Finally, observation error perturbations can be included prior to calculation of statistics. Details about and equations for the statistics produced for ensembles are given in :numref:`Appendix C, Section %s `. Scientific and statistical aspects -__________________________________ +================================== Ensemble forecasts derived from a set of deterministic ensemble members -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------------------------------------- Ensemble forecasts are often created as a set of deterministic forecasts. The ensemble members are rarely used separately. Instead, they can be combined in various ways to produce a forecast. MET can combine the ensemble members into some type of summary forecast according to user specifications. Ensemble means are the most common, and can be paired with the ensemble variance or spread. Maximum, minimum and other summary values are also available, with details in the practical information section. @@ -23,7 +24,7 @@ The neighborhood ensemble probability (NEP) and neighborhood maximum ensemble pr The Ensemble-Stat tool writes the gridded relative frequencies, NEP, and NMEP fields to a NetCDF output file. Probabilistic verification methods can then be applied to those fields by evaluating them with the Grid-Stat and/or Point-Stat tools. Ensemble statistics -~~~~~~~~~~~~~~~~~~~ +------------------- Rank histograms and probability integral transform (PIT) histograms are used to determine if the distribution of ensemble values is the same as the distribution of observed values for any forecast field (:ref:`Hamill, 2001 `). The rank histogram is a tally of the rank of the observed value when placed in order with each of the ensemble values from the same location. If the distributions are identical, then the rank of the observation will be uniformly distributed. In other words, it will fall among the ensemble members randomly in equal likelihood. The PIT histogram applies this same concept, but transforms the actual rank into a probability to facilitate ensembles of differing sizes or with missing members. @@ -34,7 +35,7 @@ The relative position (RELP) is a count of the number of times each ensemble mem The ranked probability score (RPS) is included in the Ranked Probability Score (RPS) line type. It is the mean of the Brier scores computed from ensemble probabilities derived for each probability category threshold (prob_cat_thresh) specified in the configuration file. The continuous ranked probability score (CRPS) is the average the distance between the forecast (ensemble) cumulative distribution function and the observation cumulative distribution function. It is an analog of the Brier score, but for continuous forecast and observation fields. The CRPS statistic is computed using two methods: assuming a normal distribution defined by the ensemble mean and spread (:ref:`Gneiting et al., 2004 `) and using the empirical ensemble distribution (:ref:`Hersbach, 2000 `). The CRPS statistic is included in the Ensemble Continuous Statistics (ECNT) line type, along with other statistics quantifying the ensemble spread and ensemble mean skill. Climatology data -~~~~~~~~~~~~~~~~ +---------------- The Ensemble-Stat output includes at least three statistics computed relative to external climatology data. The climatology is defined by mean and standard deviation fields, and typically both are required in the computation of ensemble skill score statistics. MET assumes that the climatology follows a normal distribution, defined by the mean and standard deviation at each point. @@ -43,7 +44,7 @@ When computing the CRPS skill score for (:ref:`Gneiting et al., 2004 `. can be replicated using the appropriate options. The user selects a distribution for the observation error, along with parameters for that distribution. Rescaling and bias correction can also be specified prior to the perturbation. Random draws from the distribution can then be added to either, or both, of the forecast and observed fields, including ensemble members. Details about the effects of the choices on verification statistics should be considered, with many details provided in the literature (*e.g.* :ref:`Candille and Talagrand, 2008 `; :ref:`Saetra et al., 2004 `; :ref:`Santos and Ghelli, 2012 `). Generally, perturbation makes verification statistics better when applied to ensemble members, and worse when applied to the observations themselves. @@ -52,12 +53,12 @@ Normal and uniform are common choices for the observation error distribution. Th Observation errors differ according to instrument, temporal and spatial representation, and variable type. Unfortunately, many observation errors have not been examined or documented in the literature. Those that have usually lack information regarding their distributions and approximate parameters. Instead, a range or typical value of observation error is often reported and these are often used as an estimate of the standard deviation of some distribution. Where possible, it is recommended to use the appropriate type and size of perturbation for the observation to prevent spurious results. Practical Information -_____________________ +===================== This section contains information about configuring and running the Ensemble-Stat tool. The Ensemble-Stat tool creates or verifies gridded model data. For verification, this tool can accept either gridded or point observations. If provided, the climatology data files must be gridded. The input gridded model, observation, and climatology datasets must be on the same grid prior to calculation of any statistics, and in one of the MET supported gridded file formats. If gridded files are not on the same grid, MET will do the regridding for you if you specify the desired output grid. The point observations must be formatted as the NetCDF output of the point reformatting tools described in :numref:`reformat_point`. ensemble_stat usage -~~~~~~~~~~~~~~~~~~~ +------------------- The usage statement for the Ensemble Stat tool is shown below: @@ -125,7 +126,7 @@ An example of the ensemble_stat calling sequence is shown below: In this example, the Ensemble-Stat tool will process six forecast files specified in the file list into an ensemble forecast. Observations in both point and grid format will be included, and be used to compute ensemble statistics separately. Ensemble Stat will create a NetCDF file containing requested ensemble fields and an output STAT file. ensemble_stat configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- The default configuration file for the Ensemble-Stat tool named **EnsembleStatConfig_default** can be found in the installed *share/met/config* directory. Another version is located in *scripts/config*. We encourage users to make a copy of these files prior to modifying their contents. Each configuration file (both the default and sample) contains many comments describing its contents. The contents of the configuration file are also described in the subsections below. @@ -455,7 +456,7 @@ Refer to the description of the **boot** entry in :numref:`config_options` for m ensemble_stat output -~~~~~~~~~~~~~~~~~~~~ +-------------------- ensemble_stat can produce output in STAT, ASCII, and NetCDF formats. The ASCII output duplicates the STAT output but has the data organized by line type. The output files are written to the default output directory or the directory specified by the -outdir command line option. diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index 6d6e562ee0..cd6f963b4f 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -1,20 +1,21 @@ .. _gen-ens-prod: +***************** Gen-Ens-Prod Tool -================= +***************** Introduction -____________ +============ The Gen-Ens-Prod tool generates simple ensemble products (mean, spread, probability, etc) from gridded ensemble member input files. While it processes model inputs, but it does not compare them to observations or compute statistics. However, the output products can be passed as input to the MET statistics tools for comparison against observations. Climatological mean and standard deviation data may also be provided to define thresholds based on the climatological distribution at each grid point. Note that this ensemble product generation step was provided by the Ensemble-Stat tool in earlier versions of MET. The Gen-Ens-Prod tool replaces and extends that functionality. Users are strongly encouraged to migrate ensemble product generation from Ensemble-Stat to Gen-Ens-Prod, as new features will only be added to Gen-Ens-Prod and the existing Ensemble-Stat functionality will be deprecated in a future version. Scientific and statistical aspects -__________________________________ +================================== Ensemble forecasts derived from a set of deterministic ensemble members -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------------------------------------------------- Ensemble forecasts are often created as a set of deterministic forecasts. The ensemble members are rarely used separately. Instead, they can be combined in various ways to produce a forecast. MET can combine the ensemble members into some type of summary forecast according to user specifications. Ensemble means are the most common, and can be paired with the ensemble variance or spread. Maximum, minimum and other summary values are also available, with details in the practical information section. @@ -27,17 +28,17 @@ The neighborhood ensemble probability (NEP) and neighborhood maximum ensemble pr The Gen-Ens-Prod tool writes the gridded relative frequencies, NEP, and NMEP fields to a NetCDF output file. Probabilistic verification methods can then be applied to those fields by evaluating them with the Grid-Stat and/or Point-Stat tools. Climatology data -~~~~~~~~~~~~~~~~ +---------------- The ensemble relative frequencies derived by Gen-Ens-Prod are computed by applying threshold(s) to the input ensemble member data. Those thresholds can be simple and remain constant over the entire domain (e.g. >0) or can be defined relative to the climatological distribution at each grid point (e.g. >CDP90, for exceeding the 90-th percentile of climatology). When using climatological distribution percentile (CDP) thresholds, the climatological mean and standard deviation must be provided in the configuration file. Practical Information -_____________________ +===================== This section contains information about configuring and running the Gen-Ens-Prod tool. The Gen-Ens-Prod tool writes a NetCDF output file containing the requested ensemble product fields for each input field specified. If provided, the climatology data files must be gridded. All input gridded model and climatology datasets must be on the same grid. However, users may leverage the automated regridding feature in MET if the desired output grid is specified in the configuration file. gen_ens_prod usage -~~~~~~~~~~~~~~~~~~~ +------------------ The usage statement for the Ensemble Stat tool is shown below: @@ -54,7 +55,7 @@ The usage statement for the Ensemble Stat tool is shown below: gen_ens_prod has three required arguments and accepts several optional ones. Required arguments gen_ens_prod -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------- 1. The **-ens file_1 ... file_n** option specifies the ensemble member file names. This argument is not required when ensemble files are specified in the **ens_file_list**, detailed below. @@ -65,7 +66,7 @@ Required arguments gen_ens_prod 4. The **-config file** option is a **GenEnsProdConfig** file containing the desired configuration settings. Optional arguments for gen_ens_prod -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------------------- 4. The **-ctrl file** option specifies the input file for the ensemble control member. Data for this member is included in the computation of the ensemble mean, but excluded from the spread. The control file should not appear in the **-ens** list of ensemble member files (unless processing a single file that contains all ensemble members). @@ -85,7 +86,7 @@ An example of the gen_ens_prod calling sequence is shown below: In this example, the Gen-Ens-Prod tool derives products from the input ensemble members listed on the command line. gen_ens_prod configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- The default configuration file for the Gen-Ens-Prod tool named **GenEnsProdConfig_default** can be found in the installed *share/met/config* directory. Another version is located in *scripts/config*. We encourage users to make a copy of these files prior to modifying their contents. The contents of the configuration file are described in the subsections below. @@ -265,7 +266,7 @@ The **ensemble_flag** specifies which derived ensemble fields should be calculat 14. Climatological Distribution Percentile field for each CDP threshold specified gen_ens_prod output -~~~~~~~~~~~~~~~~~~~~ +------------------- The Gen-Ens-Prod tools writes a gridded NetCDF output file whose file name is specified using the -out command line option. The contents of that file depend on the contents of the **ens.field** array, the **ensemble_flag** options selected, and the presence of climatology data. The NetCDF variable names are self-describing and include the name/level of the field being processed, the type of ensemble product, and any relevant threshold information. If **nc_var_str** is defined for an **ens.field** array entry, that string is included in the corresponding NetCDF output variable names. diff --git a/met/docs/Users_Guide/grid-diag.rst b/met/docs/Users_Guide/grid-diag.rst index 22200ad0e2..96ec66375a 100644 --- a/met/docs/Users_Guide/grid-diag.rst +++ b/met/docs/Users_Guide/grid-diag.rst @@ -1,18 +1,19 @@ .. _grid-diag: +************** Grid-Diag Tool -============== +************** Introduction -____________ +============ The Grid-Diag tool creates histograms (probability distributions when normalized) for an arbitrary collection of data fields and levels. Joint histograms will be created for all possible pairs of variables. Masks can be used to subset the data fields spatially. The histograms are accumulated over a time series of input data files, similar to Series-Analysis. Practical information -_____________________ +===================== grid_diag usage -~~~~~~~~~~~~~~~ +--------------- The following sections describe the usage statement, required arguments, and optional arguments for **grid_diag**. @@ -53,7 +54,7 @@ Optional arguments for grid_diag 6. The **-compress level** option indicates the desired level of compression (deflate level) for NetCDF variables. The valid level is between 0 and 9. The value of "level" will override the default setting of 0 from the configuration file or the environment variable MET_NC_COMPRESS. Setting the compression level to 0 will make no compression for the NetCDF output. Lower number is for fast compression and higher number is for better compression. grid_diag configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- The default configuration file for the Grid-Diag tool named **GridDiagConfig_default** can be found in the installed *share/met/config/* directory. It is encouraged for users to copy these default files before modifying their contents. The contents of the configuration file are described in the subsections below. @@ -96,7 +97,7 @@ The **name** and **level** entries in the **data** dictionary define the data to Grid-Diag prints a warning message if the actual range of data values falls outside the range defined for that variable in the configuration file. Any data values less than the configured range are counted in the first bin, while values greater than the configured range are counted in the last bin. grid_diag output file -~~~~~~~~~~~~~~~~~~~~~ +--------------------- The NetCDF file has a dimension for each of the specified data variable and level combinations, e.g. APCP_L0 and PWAT_L0. The bin minimum, midpoint, and maximum values are indicated with an _min, _mid, or _max appended to the variable/level. diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index b96ed7a724..2e0716f505 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -1,21 +1,22 @@ .. _grid-stat: +************** Grid-Stat Tool -============== +************** Introduction -____________ +============ The Grid-Stat tool provides verification statistics for a matched forecast and observation grid. All of the forecast grid points in the region of interest are matched to observation grid points on the same grid. All the matched grid points are used to compute the verification statistics. The Grid-Stat tool functions in much the same way as the Point-Stat tool, except that no interpolation is required because the forecasts and observations are on the same grid. However, the interpolation parameters may be used to perform a smoothing operation on the forecast and observation fields prior to verification. In addition to traditional verification approaches, the Grid-Stat tool includes Fourier decompositions, gradient statistics, distance metrics, and neighborhood methods, designed to examine forecast performance as a function of spatial scale. Scientific and statistical aspects of the Grid-Stat tool are briefly described in this section, followed by practical details regarding usage and output from the tool. Scientific and statistical aspects -__________________________________ +================================== Statistical measures -~~~~~~~~~~~~~~~~~~~~ +-------------------- The Grid-Stat tool computes a wide variety of verification statistics. Broadly speaking, these statistics can be subdivided into three types of statistics: measures for categorical variables, measures for continuous variables, and measures for probabilistic forecasts. Further, when a climatology file is included, reference statistics for the forecasts compared to the climatology can be calculated. These categories of measures are briefly described here; specific descriptions of all measures are provided in :numref:`Appendix C, Section %s `. Additional information can be found in :ref:`Wilks (2011) ` and :ref:`Jolliffe and Stephenson (2012) `, and on the Collaboration for Australian Weather and Climate Research Forecast Verification - `Issues, Methods and FAQ web page `_. @@ -53,17 +54,17 @@ Use of analysis fields for verification The Grid-Stat tool allows evaluation of model forecasts using model analysis fields. However, users are cautioned that an analysis field is not independent of its parent model; for this reason verification of model output using an analysis field from the same model is generally not recommended and is not likely to yield meaningful information about model performance. Statistical confidence intervals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- The confidence intervals for the Grid-Stat tool are the same as those provided for the Point-Stat tool except that the scores are based on pairing grid points with grid points so that there are likely more values for each field making any assumptions based on the central limit theorem more likely to be valid. However, it should be noted that spatial (and temporal) correlations are not presently taken into account in the confidence interval calculations. Therefore, confidence intervals reported may be somewhat too narrow (e.g., :ref:`Efron, 2007 `). See :numref:`Appendix D, Section %s ` for details regarding confidence intervals provided by MET. Grid weighting -~~~~~~~~~~~~~~ +-------------- When computing continuous statistics on a regular large scale or global latitude-longitude grid, weighting may be applied in order to compensate for the meridian convergence toward higher latitudes. Grid square area weighting or weighting based on the cosine of the latitude are two configuration options in both point-stat and grid-stat. See :numref:`config_options` for more information. Neighborhood methods -~~~~~~~~~~~~~~~~~~~~ +-------------------- MET also incorporates several neighborhood methods to give credit to forecasts that are close to the observations, but not necessarily exactly matched up in space. Also referred to as "fuzzy" verification methods, these methods do not just compare a single forecast at each grid point to a single observation at each grid point; they compare the forecasts and observations in a neighborhood surrounding the point of interest. With the neighborhood method, the user chooses a distance within which the forecast event can fall from the observed event and still be considered a hit. In MET this is implemented by defining a square search window around each grid point. Within the search window, the number of observed events is compared to the number of forecast events. In this way, credit is given to forecasts that are close to the observations without requiring a strict match between forecasted events and observed events at any particular grid point. The neighborhood methods allow the user to see how forecast skill varies with neighborhood size and can help determine the smallest neighborhood size that can be used to give sufficiently accurate forecasts. @@ -72,7 +73,7 @@ There are several ways to present the results of the neighborhood approaches, su The user must specify several parameters in the grid_stat configuration file to utilize the neighborhood approach, such as the interpolation method, size of the smoothing window, and required fraction of valid data points within the smoothing window. For FSS-specific results, the user must specify the size of the neighborhood window, the required fraction of valid data points within the window, and the fractional coverage threshold from which the contingency tables are defined. These parameters are described further in the practical information section below. Fourier Decomposition -~~~~~~~~~~~~~~~~~~~~~ +--------------------- The MET software will compute the full one-dimensional Fourier transform, then do a partial inverse transform based on the two user-defined wave numbers. These two wave numbers define a band pass filter in the Fourier domain. This process is conceptually similar to the operation of projecting onto subspace in linear algebra. If one were to sum up all possible wave numbers the result would be to simply reproduce the raw data. @@ -81,14 +82,14 @@ Decomposition via Fourier transform allows the user to evaluate the model separa Wavelets, and in particular the MET wavelet tool, can also be used to define a band pass filter (:ref:`Casati et al., 2004 `; :ref:`Weniger et al., 2016 `). Both the Fourier and wavelet methods can be used to look at different spatial scales. Gradient Statistics -~~~~~~~~~~~~~~~~~~~ +------------------- The S1 score has been in historical use for verification of forecasts, particularly for variables such as pressure and geopotential height. This score compares differences between adjacent grid points in the forecast and observed fields. When the adjacent points in both forecast and observed fields exhibit the same differences, the S1 score will be the perfect value of 0. Larger differences will result in a larger score. Differences are computed in both of the horizontal grid directions and is not a true mathematical gradient. Because the S1 score focuses on differences only, any bias in the forecast will not be measured. Further, the score depends on the domain and spacing of the grid, so can only be compared on forecasts with identical grids. Distance Maps -~~~~~~~~~~~~~ +------------- The following methods can all be computed efficiently by utilizing fast algorithms developed for calculating distance maps. A distance map results from calculating the shortest distance from every grid point, **s=(x,y)**, in the domain, **D**, to the nearest one-valued grid point. In each of the following, it is understood that they are calculated between event areas **A**, from one field and observation event areas **B** from another. If the measure is applied to a feature within a field, then the distance map is still calculated over the entire original domain. Some of the distance map statistics are computed over the entire distance map, while others use only parts of it. @@ -125,7 +126,7 @@ The statistics derived from these distance maps are described in :numref:`Append .. _grid-stat_gbeta: :math:`\beta` and :math:`G_\beta` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------- See :numref:`App_C-gbeta` for the :math:`G` and :math:`G_\beta` equations. @@ -146,14 +147,14 @@ In some cases, a user may be interested in a much higher threshold than :math:`2 Since :math:`G_\beta` is so sensitive to the choice of :math:`\beta`, which is defined relative to the number of points in the verification domain, :math:`G_\beta` is only computed for the full verification domain. :math:`G_\beta` is reported as a bad data value for any masking region subsets of the full verification domain. Practical information -_____________________ +===================== This section contains information about configuring and running the Grid-Stat tool. The Grid-Stat tool verifies gridded model data using gridded observations. The input gridded model and observation datasets must be in one of the MET supported file formats. The requirement of having all gridded fields using the same grid specification was removed in METv5.1. There is a regrid option in the configuration file that allows the user to define the grid upon which the scores will be computed. The gridded observation data may be a gridded analysis based on observations such as Stage II or Stage IV data for verifying accumulated precipitation, or a model analysis field may be used. The Grid-Stat tool provides the capability of verifying one or more model variables/levels using multiple thresholds for each model variable/level. The Grid-Stat tool performs no interpolation when the input model, observation, and climatology datasets must be on a common grid. MET will interpolate these files to a common grid if one is specified. The interpolation parameters may be used to perform a smoothing operation on the forecast field prior to verifying it to investigate how the scale of the forecast affects the verification statistics. The Grid-Stat tool computes a number of continuous statistics for the forecast minus observation differences, discrete statistics once the data have been thresholded, or statistics for probabilistic forecasts. All types of statistics can incorporate a climatological reference. grid_stat usage -~~~~~~~~~~~~~~~ +--------------- The usage statement for the Grid-Stat tool is listed below: @@ -217,7 +218,7 @@ In the second example, the Grid-Stat tool will verify the model data in the samp .. _grid_stat-configuration-file: grid_stat configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- The default configuration file for the Grid-Stat tool, named **GridStatConfig_default**, can be found in the installed *share/met/config* directory. Other versions of the configuration file are included in *scripts/config*. We recommend that users make a copy of the default (or other) configuration file prior to modifying it. The contents are described in more detail below. @@ -457,7 +458,7 @@ The **nc_pairs_var_suffix** entry is similar to the **nc_pairs_var_name** entry. .. _grid_stat-output: grid_stat output -~~~~~~~~~~~~~~~~ +---------------- grid_stat produces output in STAT and, optionally, ASCII and NetCDF formats. The ASCII output duplicates the STAT output but has the data organized by line type. The output files are written to the default output directory or the directory specified by the -outdir command line option. diff --git a/met/docs/Users_Guide/gsi-tools.rst b/met/docs/Users_Guide/gsi-tools.rst index 019e5c3f7b..b5bde4f9a7 100644 --- a/met/docs/Users_Guide/gsi-tools.rst +++ b/met/docs/Users_Guide/gsi-tools.rst @@ -1,7 +1,8 @@ .. _gsi_tools: +********* GSI Tools -========= +********* Gridpoint Statistical Interpolation (GSI) diagnostic files are binary files written out from the data assimilation code before the first and after each outer loop. The files contain useful information about how a single observation was used in the analysis by providing details such as the innovation (O-B), observation values, observation error, adjusted observation error, and quality control information. @@ -12,12 +13,12 @@ When MET reads GSI diagnostic files, the innovation (O-B; generated prior to the MET includes two tools for processing GSI diagnostic files. The GSID2MPR tool reformats individual GSI diagnostic files into the MET matched pair (MPR) format, similar to the output of the Point-Stat tool. The GSIDENS2ORANK tool processes an ensemble of GSI diagnostic files and reformats them into the MET observation rank (ORANK) line type, similar to the output of the Ensemble-Stat tool. The output of both tools may be passed to the Stat-Analysis tool to compute a wide variety of continuous, categorical, and ensemble statistics. GSID2MPR tool -_____________ +============= This section describes how to run the GSID2MPR tool. The GSID2MPR tool reformats one or more GSI diagnostic files into an ASCII matched pair (MPR) format, similar to the MPR output of the Point-Stat tool. The output MPR data may be passed to the Stat-Analysis tool to compute a wide variety of continuous or categorical statistics. gsid2mpr usage -~~~~~~~~~~~~~~ +-------------- The usage statement for the GSID2MPR tool is shown below: @@ -71,7 +72,7 @@ An example of the gsid2mpr calling sequence is shown below: In this example, the GSID2MPR tool will process a single input file named **diag_conv_ges.mem001** file, set the output **MODEL** header column to **GSI_MEM001**, and write output to the **out** directory. The output file is named the same as the input file but a **.stat** suffix is added to indicate its format. gsid2mpr output -~~~~~~~~~~~~~~~ +--------------- The GSID2MPR tool performs a simple reformatting step and thus requires no configuration file. It can read both conventional and radiance binary GSI diagnostic files. Support for additional GSI diagnostic file type may be added in future releases. Conventional files are determined by the presence of the string **conv** in the filename. Files that are not conventional are assumed to contain radiance data. Multiple files of either type may be passed in a single call to the GSID2MPR tool. For each input file, an output file will be generated containing the corresponding matched pair data. @@ -243,12 +244,12 @@ An example of the Stat-Analysis calling sequence is shown below: In this example, the Stat-Analysis tool will read MPR lines from the input file named **diag_conv_ges.mem001.stat**, retain only those lines where the **FCST_VAR** column indicates temperature (**t**) and where the **ANLY_USE** column has a value of 1.0, and derive continuous statistics. GSIDENS2ORANK tool -__________________ +================== This section describes how to run the GSIDENS2ORANK tool. The GSIDENS2ORANK tool processes an ensemble of GSI diagnostic files and reformats them into the MET observation rank (ORANK) line type, similar to the output of the Ensemble-Stat tool. The ORANK line type contains ensemble matched pair information and is analogous to the MPR line type for a deterministic model. The output ORANK data may be passed to the Stat-Analysis tool to compute ensemble statistics. gsidens2orank usage -~~~~~~~~~~~~~~~~~~~ +------------------- The usage statement for the GSIDENS2ORANK tool is shown below: @@ -306,7 +307,7 @@ An example of the gsidens2orank calling sequence is shown below: In this example, the GSIDENS2ORANK tool will process all of the ensemble members whose file name **matches diag_conv_ges.mem\*,** write output to the file named **diag_conv_ges_ens_mean_orank.txt**, and populate the output **ENS_MEAN** column with the values found in the **diag_conv_ges.ensmean** file rather than computing the ensemble mean values from the ensemble members on the fly. gsidens2orank output -~~~~~~~~~~~~~~~~~~~~ +-------------------- The GSIDENS2ORANK tool performs a simple reformatting step and thus requires no configuration file. The multiple files passed to it are interpreted as members of the same ensemble. Therefore, each call to the tool processes exactly one ensemble. All input ensemble GSI diagnostic files must be of the same type. Mixing conventional and radiance files together will result in a runtime error. The GSIDENS2ORANK tool processes each ensemble member and keeps track of the observations it encounters. It constructs a list of the ensemble values corresponding to each observation and writes an output ORANK line listing the observation value, its rank, and all the ensemble values. The random number generator is used by the GSIDENS2ORANK tool to randomly assign a rank value in the case of ties. diff --git a/met/docs/Users_Guide/index.rst b/met/docs/Users_Guide/index.rst index 5ee52862e0..9c17bc0a19 100644 --- a/met/docs/Users_Guide/index.rst +++ b/met/docs/Users_Guide/index.rst @@ -1,6 +1,6 @@ -============ +############ User's Guide -============ +############ **Foreword: A note to MET users** diff --git a/met/docs/Users_Guide/installation.rst b/met/docs/Users_Guide/installation.rst index b4459fed0d..04ecd35b9f 100644 --- a/met/docs/Users_Guide/installation.rst +++ b/met/docs/Users_Guide/installation.rst @@ -1,22 +1,23 @@ .. _installation: +************************************* Software Installation/Getting Started -===================================== +************************************* Introduction -____________ +============ This section describes how to install the MET package. MET has been developed and tested on Linux operating systems. Support for additional platforms and compilers may be added in future releases. The MET package requires many external libraries to be available on the user's computer prior to installation. Required and recommended libraries, how to install MET, the MET directory structure, and sample cases are described in the following sections. -Supported architectures -_______________________ +Supported Architectures +======================= The MET package was developed on Debian Linux using the GNU compilers and the Portland Group (PGI) compilers. The MET package has also been built on several other Linux distributions using the GNU, PGI, and Intel compilers. Past versions of MET have also been ported to IBM machines using the IBM compilers, but we are currently unable to support this option as the development team lacks access to an IBM machine for testing. Other machines may be added to this list in future releases as they are tested. In particular, the goal is to support those architectures supported by the WRF model itself. The MET tools run on a single processor. Therefore, none of the utilities necessary for running WRF on multiple processors are necessary for running MET. Individual calls to the MET tools have relatively low computing and memory requirements. However users will likely be making many calls to the tools and passing those individual calls to several processors will accomplish the verification task more efficiently. -Programming languages -_____________________ +Programming Languages +===================== The MET package, including MET-TC, is written primarily in C/C++ in order to be compatible with an extensive verification code base in C/C++ already in existence. In addition, the object-based MODE and MODE-TD verification tools rely heavily on the object-oriented aspects of C++. Knowledge of C/C++ is not necessary to use the MET package. The MET package has been designed to be highly configurable through the use of ASCII configuration files, enabling a great deal of flexibility without the need for source code modifications. @@ -24,8 +25,8 @@ NCEP's BUFRLIB is written entirely in Fortran. The portion of MET that handles t The MET package is intended to be a tool for the modeling community to use and adapt. As users make upgrades and improvements to the tools, they are encouraged to offer those upgrades to the broader community by offering feedback to the developers. -Required compilers and scripting languages -__________________________________________ +Required Compilers and Acripting Languages +========================================== The MET package was developed and tested using the GNU g++/gfortran compilers and the Intel icc/ifort compilers. As additional compilers are successfully tested, they will be added to the list of supported platforms/compilers. @@ -37,8 +38,8 @@ In order to control the desired flow through MET, users are encouraged to run th .. _Install_Required-libraries-and: -Required libraries and optional utilities -_________________________________________ +Required Libraries and Optional U1tilities +========================================== Three external libraries are required for compiling/building MET and should be downloaded and installed before attempting to install MET. Additional external libraries required for building advanced features in MET are discussed in :numref:`Installation-of-required` : @@ -58,8 +59,8 @@ Two additional utilities are strongly recommended for use with MET: .. _Installation-of-required: -Installation of required libraries -__________________________________ +Installation of Required Libraries +================================== As described in :numref:`Install_Required-libraries-and`, some external libraries are required for building the MET: @@ -105,8 +106,8 @@ In the directions above, the static library file that is created will be named l .. _Installation-of-optional: -Installation of optional utilities -__________________________________ +Installation of Optional Utilities +================================== As described in the introduction to this section, two additional utilities are strongly recommended for use with MET. @@ -116,8 +117,8 @@ As described in the introduction to this section, two additional utilities are s .. _met_directory_structure: -MET directory structure -_______________________ +MET Directory Structure +======================= The top-level MET directory consists of Makefiles, configuration files, and several subdirectories. The top-level Makefile and configuration files control how the entire toolkit is built. Instructions for using these files to build MET can be found in :numref:`Install_Building-the-MET`. @@ -137,20 +138,20 @@ The *share/met/Rscripts* directory contains a handful of sample R scripts, inclu .. _Install_Building-the-MET: -Building the MET package -________________________ +Building the MET Package +======================== Building the MET package consists of three main steps: (1) install the required libraries, (2) configure the environment variables, and (3) configure and execute the build. Users can follow the instructions below or use a sample installation script. Users can find the script and its instructions under on the `Downloads `_ page of the MET website. Install the Required Libraries -______________________________ +============================== • Please refer to :numref:`Installation-of-required` and :numref:`Installation-of-optional` on how to install the required and optional libraries. • If installing the required and optional libraries in a non-standard location, the user may need to tell MET where to find them. This can be done by setting or adding to the LD_LIBRARY PATH to include the path to the library files. Set Environment Variables -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- The MET build uses environment variables to specify the locations of the needed external libraries. For each library, there is a set of three environment variables to describe the locations: $MET_, $MET_INC and $MET_LIB. @@ -188,8 +189,8 @@ The following environment variables should also be set: For ease of use, you should define these in your .cshrc or equivalent file. -Configure and execute the build -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Configure and Execute the Build +------------------------------- Example: To configure MET to install all of the available tools in the "bin" subdirectory of your current directory, you would use the following commands: @@ -301,7 +302,7 @@ regions to benefit from thread-parallel execution. Runtime environment variable Run the configure script with the **-help** argument to see the full list of configuration options. Make Targets -~~~~~~~~~~~~ +------------ The autoconf utility provides some standard make targets for the users. In MET, the following standard targets have been implemented and tested: @@ -319,8 +320,8 @@ MET also has the following non-standard targets: .. _Sample Test cases: -Sample test cases -_________________ +Sample Test Cases +================= Once the MET package has been built successfully, the user is encouraged to run the sample test scripts provided. They are run using make test in the top-level directory. Execute the following commands: diff --git a/met/docs/Users_Guide/masking.rst b/met/docs/Users_Guide/masking.rst index db695f97f1..1f03ff2bce 100644 --- a/met/docs/Users_Guide/masking.rst +++ b/met/docs/Users_Guide/masking.rst @@ -1,17 +1,18 @@ .. _masking: +******************************************* Regional Verification using Spatial Masking -=========================================== +******************************************* Verification over a particular region or area of interest may be performed using "masking". Defining a masking region is simply selecting the desired set of grid points to be used. The Gen-Vx-Mask tool automates this process and replaces the Gen-Poly-Mask and Gen-Circle-Mask tools from previous releases. It may be run to create a bitmap verification masking region to be used by many of the statistical tools. This tool enables the user to generate a masking region once for a domain and apply it to many cases. It has been enhanced to support additional types of masking region definition (e.g. tropical-cyclone track over water only). An iterative approach may be used to define complex areas by combining multiple masking regions together. Gen-Vx-Mask tool -________________ +================ The Gen-Vx-Mask tool may be run to create a bitmap verification masking region to be used by the MET statistics tools. This tool enables the user to generate a masking region once for a domain and apply it to many cases. While the MET statistics tools can define some masking regions on the fly using polylines, doing so can be slow, especially for complex polylines containing hundreds of vertices. Using the Gen-Vx-Mask tool to create a bitmap masking region before running the other MET tools will make them run more efficiently. gen_vx_mask usage -~~~~~~~~~~~~~~~~~ +----------------- The usage statement for the Gen-Vx-Mask tool is shown below: @@ -162,6 +163,6 @@ An example of the gen_vx_mask calling sequence is shown below: In this example, the Gen-Vx-Mask tool will read the ASCII Lat/Lon file named **CONUS.poly** and apply the default polyline masking method to the domain on which the data in the file **sample_fcst.grib** resides. It will create a NetCDF file containing a bitmap for the domain with a value of 1 for all grid points inside the CONUS polyline and a value of 0 for all grid points outside. It will write an output NetCDF file named **CONUS_poly.nc**. Feature-Relative Methods -________________________ +======================== -This section contains a description of several methods that may be used to perform feature-relative (or event -based) evaluation. The methodology pertains to examining the environment surrounding a particular feature or event such as a tropical, extra-tropical cyclone, convective cell, snow-band, etc. Several approaches are available for these types of investigations including applying masking described above (e.g. circle or box) or using the "FORCE" interpolation method in the regrid configuration option (see :numref:`config_options`). These methods generally require additional scripting, including potentially storm-track identification, outside of MET to be paired with the features of the MET tools. METplus may be used to execute this type of analysis. Please refer to the `METplus User's Guide `__. +This section contains a description of several methods that may be used to perform feature-relative (or event -based) evaluation. The methodology pertains to examining the environment surrounding a particular feature or event such as a tropical, extra-tropical cyclone, convective cell, snow-band, etc. Several approaches are available for these types of investigations including applying masking described above (e.g. circle or box) or using the "FORCE" interpolation method in the regrid configuration option (see :numref:`config_options`). These methods generally require additional scripting, including potentially storm-track identification, outside of MET to be paired with the features of the MET tools. METplus may be used to execute this type of analysis. Please refer to the `METplus User's Guide `_. diff --git a/met/docs/Users_Guide/met-tc_overview.rst b/met/docs/Users_Guide/met-tc_overview.rst index 859e3e2efa..41ad7e5fc0 100644 --- a/met/docs/Users_Guide/met-tc_overview.rst +++ b/met/docs/Users_Guide/met-tc_overview.rst @@ -1,24 +1,25 @@ .. _met-tc_overview: +*************** MET-TC Overview -=============== +*************** Introduction -____________ +============ The purpose of this User's Guide is to provide basic information to the users of the Model Evaluation Tools - Tropical Cyclone (MET-TC) to enable users to apply MET-TC to their tropical cyclone datasets and evaluation studies. MET-TC is intended for use with model forecasts run through a vortex tracking software or with operational model forecasts in Automated Tropical Cyclone Forecast (ATCF) file format. The following sections provide an overview of MET-TC and its components, as well as basic information on the software build. The required input, including file format and the MET-TC are discussed followed by a description of the TC-Dland tool, TC-Pairs, and TC-Stat tools. Each section covers the input, output and practical usage including a description of the configuration files. This is followed by a short overview of graphical utilities available within the MET-TC release. MET-TC components -_________________ +================= The MET tools used in the verification of Tropical Cyclones are referred to as MET-TC. These tools are shown across the bottom of the flowchart in :numref:`overview-figure`. The MET-TC tools are described in more detail in later sections. The TC-Dland tool is used to generate a gridded file that determines the location of coastlines and islands, and is used as input to the TC-Pairs tool to determine the distance from land of a particular track point. The TC-Pairs tool matches pairs of input model data and BEST track (or any reference forecast) and calculates position errors. The TC-Stat tool uses the TC-Pairs output to perform filter and summary jobs over the matched pair dataset. The TC-Gen tool performs a categorical analysis for tropical cyclone genesis forecasts. The TC-RMW tool performs a coordinate transformation of gridded model data, centered on the storm's location. The RMW-Analysis tool aggregates TC-RMW output across multiple cases. Input data format -_________________ +================= This section discusses the input and output file formats expected and produced by MET-TC. When discussing the input data, it is expected that users have run model output through vortex tracking software in order to obtain position and intensity information in Automated Tropical Cyclone Forecasting System (ATCF) file format. Best track and aids files in Automated Tropical Cyclone Forecasting System (ATCF) format (hereafter referred to as ATCF format) are necessary for model data input into the TC-Pairs tool. The ATCF format was first developed at the Naval Oceanographic and Atmospheric Research Laboratory (NRL), and is currently used for the National Hurricane Center (NHC) operations. ATCF format must be adhered to in order for the MET-TC tools to properly parse the input data. @@ -109,6 +110,6 @@ All operational model aids and the BEST can be obtained from the `NHC ftp server If a user has gridded model output, the model data must be run through a vortex tracking algorithm in order to obtain the ATCF-formatted input that MET-TC requires. Many vortex tracking algorithms have been developed in order to obtain basic position, maximum wind, and minimum sea level pressure information from model forecasts. One vortex tracking algorithm that is supported and freely available is the `GFDL vortex tracker package. `_ Output data format -__________________ +================== The MET package produces output in four basic file formats: STAT files, ASCII files, NetCDF files, and Postscript plots. The MET-TC tool produces output in TCSTAT, which stands for Tropical Cyclone - STAT. This output format consists of tabular ASCII data that can be easily read by many analysis tools and software packages, making the output from MET-TC very versatile. Like STAT, TCSTAT is a specialized ASCII format containing one record on each line. Currently, the only line type available in MET-TC is TCMPR (Tropical Cyclone Matched Pairs). As more line types are included in future releases, all line types will be included in a single TCSTAT file. MET-TC also outputs a NetCDF format file in the TC-Dland tool, as input to the TC-Pairs tool. diff --git a/met/docs/Users_Guide/mode-analysis.rst b/met/docs/Users_Guide/mode-analysis.rst index c641f8b8e6..c37db8ac8b 100644 --- a/met/docs/Users_Guide/mode-analysis.rst +++ b/met/docs/Users_Guide/mode-analysis.rst @@ -1,31 +1,32 @@ .. _mode-analysis: +****************** MODE-Analysis Tool -================== +****************** Introduction -____________ +============ Users may wish to summarize multiple ASCII files produced by MODE across many cases. The MODE output files contain many output columns making it very difficult to interpret the results by simply browsing the files. Furthermore, for particular applications some data fields in the MODE output files may not be of interest. The MODE-Analysis tool provides a simple way to compute basic summary statistics and filtering capabilities for these files. Users who are not proficient at writing scripts can use the tool directly, and even those using their own scripts can use this tool as a filter, to extract only the MODE output lines that are relevant for their application. .. _MODE_A-Scientific-and-statistical: Scientific and statistical aspects -__________________________________ +================================== The MODE-Analysis tool operates in two modes, called "summary" and "bycase". In summary mode, the user specifies on the command line the MODE output columns of interest as well as filtering criteria that determine which input lines should be used. For example, a user may be interested in forecast object areas, but only if the object was matched, and only if the object centroid is inside a particular region. The summary statistics generated for each specified column of data are the minimum, maximum, mean, standard deviation, and the 10th, 25th, 50th, 75th and 90th percentiles. In addition, the user may specify a "dump'" file: the individual MODE lines used to produce the statistics will be written to this file. This option provides the user with a filtering capability. The dump file will consist only of lines that match the specified criteria. The other option for operating the analysis tool is "bycase". Given initial and final values for forecast lead time, the tool will output, for each valid time in the interval, the matched area, unmatched area, and the number of forecast and observed objects that were matched or unmatched. For the areas, the user can specify forecast or observed objects, and also simple or cluster objects. A dump file may also be specified in this mode. Practical information -_____________________ +===================== The MODE-Analysis tool reads lines from MODE ASCII output files and applies filtering and computes basic statistics on the object attribute values. For each job type, filter parameters can be set to determine which MODE output lines are used. The following sections describe the mode_analysis usage statement, required arguments, and optional arguments. .. _mode_analysis-usage: mode_analysis usage -~~~~~~~~~~~~~~~~~~~ +------------------- The usage statement for the MODE-Analysis tool is shown below: @@ -587,13 +588,13 @@ This option prints the usage message. .. _mode_analysis-configuration-file: mode_analysis configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- To use the MODE-Analysis tool, the user must un-comment the options in the configuration file to apply them and comment out unwanted options. The options in the configuration file for the MODE-Analysis tools are the same as the MODE command line options described in :numref:`mode_analysis-usage`. The parameters that are set in the configuration file either add to or override parameters that are set on the command line. For the "set string" and "set integer type" options enclosed in brackets, the values specified in the configuration file are added to any values set on the command line. For the "toggle" and "min/max type" options, the values specified in the configuration file override those set on the command line. mode_analysis output -~~~~~~~~~~~~~~~~~~~~ +-------------------- The output of the MODE-Analysis tool is a self-describing tabular format written to standard output. The length and contents of the table vary depending on whether **-summary** or **-bycase** is selected. The contents also change for **-summary** depending on the number of columns specified by the user. diff --git a/met/docs/Users_Guide/mode-td.rst b/met/docs/Users_Guide/mode-td.rst index b646410835..bbda4dc315 100644 --- a/met/docs/Users_Guide/mode-td.rst +++ b/met/docs/Users_Guide/mode-td.rst @@ -1,13 +1,14 @@ .. _mode-td: +********************* MODE Time Domain Tool -===================== +********************* Introduction -____________ +============ Motivation -~~~~~~~~~~ +---------- MODE Time Domain (MTD) is an extension of the MODE object-based approach to verification. In addition to incorporating spatial information, MTD utilizes the time dimension to get at temporal aspects of forecast verification. Since the two spatial dimensions of traditional meteorological forecasts are retained in addition to the time dimension, the method is inherently three dimensional. Given that, however, the overall methodology has deliberately been kept as similar as possible to that of traditional MODE. @@ -28,17 +29,17 @@ At first glance, the addition of a third dimension would seem to entail no diffi In this section, we will assume that the reader has a basic familiarity with traditional MODE, its internal operation, (convolution thresholding, fuzzy logic matching and merging) and its output. We will not review these things here. Instead, we will point out differences in MTD from the way traditional MODE does things when they come up. This release is a beta version of MTD, intended mostly to encourage users to experiment with it and give us feedback and suggestions to be used in a more robust MTD release in the future. Scientific and statistical aspects -__________________________________ +================================== Attributes -~~~~~~~~~~ +---------- Object attributes are, for the most part, calculated in much the same way in MTD as they are in MODE, although the fact that one of the dimensions is non-spatial introduces a few quirks. Several of the object attributes that traditional MODE calculates assume that distances, angles and areas can be calculated in grid coordinates via the usual Euclidean/Cartesian methods. That is no longer the case in spacetime, since there is no distance function (more precisely, no *metric*) there. Given two points in this spacetime, say :math:`(x_1, y_1, t_1)` and :math:`(x_2, y_2, t_2)`, there is no way to measure their separation with a single nonnegative number in a physically meaningful way. If all three of our dimensions were spatial, there would be no difficulties. This means that some care must be taken both in determining how to generalize the calculation of a geometric attribute to three-dimensional spacetime, and also in interpreting the attributes even in the case where the generalization is straightforward. Convolution -~~~~~~~~~~~ +----------- As in MODE, MTD applies a convolution filter to the raw data as a preliminary step in resolving the field into objects. The convolution step in MTD differs in several respects from that performed in MODE, however. @@ -57,7 +58,7 @@ The most basic change is to use a square convolution filter rather than the circ Another change is that we do not allow any bad data in the convolution square. In MODE, the user may specify what percentage of bad data in the convolution region is permissible, and it will rescale the value of the filter accordingly for each data point. For the sake of speed, MTD requires that there be no bad data in the convolution region. If any bad data exists in the region, the convolved value there is set to a bad data flag. 3D Single Attributes -~~~~~~~~~~~~~~~~~~~~ +-------------------- MTD calculates several 3D attributes for single objects. The object could come from either the forecast field or the observed field. @@ -90,7 +91,7 @@ The **start time** and **end time** of an object are attributes as well. These a Finally, MTD calculates several **intensity percentiles** of the raw data values inside each object. Not all of the attributes are purely geometrical. 3D Pair Attributes -~~~~~~~~~~~~~~~~~~ +------------------ The next category of spatial attributes is for pairs of objects - one of the pair coming from the collection of forecast objects, the other coming from the observation objects. @@ -124,7 +125,7 @@ Finally, the **total interest** gives the result of the fuzzy-logic matching an 2D Constant-Time Attributes -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- The final category of object attributes calculated by MTD are two-dimensional spatial attributes for horizontal (*i.e.*, constant-time) slices of a spacetime object. This is so that the behavior of these attributes over time can be examined. These 2D constant-time attributes are written out for both simple and cluster objects. @@ -141,7 +142,7 @@ For such reasons, having 2D spatial attributes (as in MODE) for each object at e ◦ Axis Angle Matching and Merging -~~~~~~~~~~~~~~~~~~~~ +-------------------- Matching and merging operations in MTD are done in a simpler fashion than in MODE. In order to understand this operation, it is necessary to discuss some very basic notions of graph theory. @@ -177,17 +178,17 @@ To summarize: Any forecast simple objects that find themselves in the same equiv Practical information -_____________________ +===================== MTD input -~~~~~~~~~ +--------- The formats for two-dimensional data files used as input to MTD are the same ones supported by most of the MET tools. Generally speaking, if MODE can use a forecast or observation data file as input, then that file can also be used by MTD. The only difference is that while MODE takes only one forecast and one observed data file as input, MTD takes a series of files. As shown in the next section, filenames for each time used must be given. Thus, for example, if MTD is being used for verification over a period of 24 hours, and the data file valid times are separated by one hour, then a total of 48 filenames must be specified on the MTD command line - 24 filenames for the forecast files, and 24 for the observation files. Further, the filenames must be given in order of increasing valid time. Many users will prefer to write scripts to automate this, rather than type in a lengthy command line by hand. MTD usage -~~~~~~~~~ +--------- The usage statement for the MODE-TD tool is listed below: The command line switches may be given in any order. @@ -237,7 +238,7 @@ An example of the mtd calling sequence is listed below: In this example, the MODE-TD tool will read in a list of forecast GRIB files in the fcst_files directory and similarly spaced observation GRIB files in the obs_files directory. It uses a configuration file called **MTDConfig_default** and writes the output to the *out_dir/mtd* directory. MTD configuration file -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- The default configuration file for the MODE tool, **MODEConfig_default**, can be found in the installed *share/met/config* directory. Another version of the configuration file is provided in *scripts/config*. We encourage users to make a copy of the configuration files prior to modifying their contents.Most of the entries in the MTD configuration file should be familiar from the corresponding file for MODE. This initial beta release of MTD does not offer all the tunable options that MODE has accumulated over the years, however. In this section, we will not bother to repeat explanations of config file details that are exactly the same as those in MODE; we will only explain those elements that are different from MODE, and those that are unique to MTD. @@ -351,7 +352,7 @@ ______________________ The **txt_output** dictionary also contains a collection of boolean flags, in this case controlling the output of ASCII attribute files. The **attributes_2d** flag controls the output of the 2D object attributes for constant-time slices of 3D objects, while the **attributes_3d** flag controls the output of single and pair 3D spacetime object attributes. mtd output -~~~~~~~~~~ +---------- MTD creates several output files after each run in ASCII and NetCDF formats. There are text files giving 2D and 3D attributes of spacetime objects and information on matches and merges, as well as a NetCDF file giving the objects themselves, in case any further or specialized analysis of the objects needs to be done. diff --git a/met/docs/Users_Guide/mode.rst b/met/docs/Users_Guide/mode.rst index ab341e7cce..a0df6932da 100644 --- a/met/docs/Users_Guide/mode.rst +++ b/met/docs/Users_Guide/mode.rst @@ -1,12 +1,13 @@ .. _mode: +********* MODE Tool -========= +********* .. _MODE_Introduction: Introduction -____________ +============ This section provides a description of the Method for Object-Based Diagnostic Evaluation (MODE) tool, which was developed at the Research Applications Laboratory, NCAR/Boulder, USA. More information about MODE can be found in :ref:`Davis et al. (2006a,b) `, :ref:`Brown et al. (2007) ` and :ref:`Bullock et al. (2016) `. @@ -17,12 +18,12 @@ MODE may be used in a generalized way to compare any two fields. For simplicity, .. _MODE_Scientific-and-statistical: Scientific and statistical aspects -__________________________________ +================================== The methods used by the MODE tool to identify and match forecast and observed objects are briefly described in this section. Resolving objects -~~~~~~~~~~~~~~~~~ +----------------- The process used for resolving objects in a raw data field is called *convolution thresholding*. The raw data field is first convolved with a simple filter function as follows: @@ -58,7 +59,7 @@ An example of the steps involved in resolving objects is shown in :numref:`mode- Attributes -~~~~~~~~~~ +---------- Object attributes are defined both for single objects and for object pairs. One of the objects in a pair is from the forecast field and the other is taken from the observed field. @@ -81,7 +82,7 @@ All the attributes discussed so far are defined for single objects. Once these a Several area measures are also used for pair attributes. **Union Area** is the total area that is in either one (or both) of the two objects. **Intersection Area** is the area that is inside both objects simultaneously. **Symmetric Difference** is the area inside at least one object, but not inside both. Fuzzy logic -~~~~~~~~~~~ +----------- Once object attributes :math:`\alpha_1,\alpha_2,\ldots,\alpha_n` are estimated, some of them are used as input to a fuzzy logic engine that performs the matching and merging steps. **Merging** refers to grouping together objects in a single field, while **matching** refers to grouping together objects in different fields, typically the forecast and observed fields. Interest maps :math:`I_i` are applied to the individual attributes :math:`\alpha_i` to convert them into interest values, which range from zero (representing no interest) to one (high interest). For example, the default interest map for centroid difference is one for small distances, and falls to zero as the distance increases. For other attributes (*e.g.*, intersection area), low values indicate low interest, and high values indicate more interest. @@ -98,19 +99,19 @@ This total interest value is then thresholded, and pairs of objects that have to Another merging method is available in MODE, which can be used instead of, or along with, the fuzzy logic based merging just described. Recall that the convolved field is thresholded to produce the mask field. A second (lower) threshold can be specified so that objects that are separated at the higher threshold but joined at the lower threshold are merged. Summary statistics -~~~~~~~~~~~~~~~~~~ +------------------ Once MODE has been run, summary statistics are written to an output file. These files contain information about all single and cluster objects and their attributes. Total interest for object pairs is also output, as are percentiles of intensity inside the objects. The output file is in a simple flat ASCII tabular format (with one header line) and thus should be easily readable by just about any programming language, scripting language, or statistics package. Refer to :numref:`MODE-output` for lists of the statistics included in the MODE output files. Example scripts will be posted on the MET website in the future. Practical information -_____________________ +===================== This section contains a description of how MODE can be configured and run. The MODE tool is used to perform a features-based verification of gridded model data using gridded observations. The input gridded model and observation datasets must be in one of the MET supported gridded file formats. The requirement of having all gridded fields using the same grid specification has been removed with METv5.1. The Grid-Stat tool performs no interpolation when the input model, observation, and climatology datasets must be on a common grid. MET will interpolate these files to a common grid if one is specified. There is a regrid option in the configuration file that allows the user to define the grid upon which the scores will be computed. The gridded analysis data may be based on observations, such as Stage II or Stage IV data for verifying accumulated precipitation, or a model analysis field may be used. However, users are cautioned that it is generally unwise to verify model output using an analysis field produced by the same model. MODE provides the capability to select a single model variable/level from which to derive objects to be analyzed. MODE was developed and tested using accumulated precipitation. However, the code has been generalized to allow the use of any gridded model and observation field. Based on the options specified in the configuration file, MODE will define a set of simple objects in the model and observation fields. It will then compute an interest value for each pair of objects across the fields using a fuzzy engine approach. Those interest values are thresholded, and any pairs of objects above the threshold will be matched/merged. Through the configuration file, MODE offers a wide range of flexibility in how the objects are defined, processed, matched, and merged. mode usage -~~~~~~~~~~ +---------- The usage statement for the MODE tool is listed below: @@ -177,7 +178,7 @@ In Example 2, the MODE tool will verify the model data in the sample_fcst.nc Net .. _MODE-configuration-file: mode configuration file -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- The default configuration file for the MODE tool, **MODEConfig_default**, can be found in the installed *share/met/config* directory. Another version of the configuration file is provided in *scripts/config*. We encourage users to make a copy of the configuration files prior to modifying their contents. Descriptions of **MODEConfig_default** and the required variables for any MODE configuration file are also provided below. While the configuration file contains many entries, most users will only need to change a few for their use. Specific options are described in the following subsections. @@ -493,7 +494,7 @@ When MODE is run on global grids, this parameter specifies how many grid squares .. _MODE-output: mode output -~~~~~~~~~~~ +----------- MODE produces output in ASCII, NetCDF, and PostScript formats. diff --git a/met/docs/Users_Guide/overview.rst b/met/docs/Users_Guide/overview.rst index ac1d55c067..8eed622ede 100644 --- a/met/docs/Users_Guide/overview.rst +++ b/met/docs/Users_Guide/overview.rst @@ -1,10 +1,11 @@ .. _overview: +*************** Overview of MET -=============== +*************** Purpose and organization of the User's Guide -____________________________________________ +============================================ The goal of this User's Guide is to provide basic information for users of the Model Evaluation Tools (MET) to enable them to apply MET to their datasets and evaluation studies. MET was originally designed for application to the post-processed output of the `Weather Research and Forecasting (WRF) `_ model. However, MET may also be used for the evaluation of forecasts from other models or applications, including the `Unified Forecast System (UFS) `_, and the `System for Integrated Modeling of the Atmosphere (SIMA) `_ if certain file format definitions (described in this document) are followed. @@ -13,7 +14,7 @@ The MET User's Guide is organized as follows. :numref:`overview` provides an ove The remainder of this section includes information about the context for MET development, as well as information on the design principles used in developing MET. In addition, this section includes an overview of the MET package and its specific modules. The Developmental Testbed Center (DTC) -______________________________________ +====================================== MET has been developed, and will be maintained and enhanced, by the `Developmental Testbed Center (DTC) `_. The main goal of the DTC is to serve as a bridge between operations and research, to facilitate the activities of these two important components of the numerical weather prediction (NWP) community. The DTC provides an environment that is functionally equivalent to the operational environment in which the research community can test model enhancements; the operational community benefits from DTC testing and evaluation of models before new models are implemented operationally. MET serves both the research and operational communities in this way - offering capabilities for researchers to test their own enhancements to models and providing a capability for the DTC to evaluate the strengths and weaknesses of advances in NWP prior to operational implementation. @@ -22,7 +23,7 @@ The MET package is available to DTC staff, visitors, and collaborators, as well .. _MET-goals: MET goals and design philosophy -_______________________________ +=============================== The primary goal of MET development is to provide a state-of-the-art verification package to the NWP community. By "state-of-the-art" we mean that MET will incorporate newly developed and advanced verification methodologies, including new methods for diagnostic and spatial verification and new techniques provided by the verification and modeling communities. MET also utilizes and replicates the capabilities of existing systems for verification of NWP forecasts. For example, the MET package replicates existing National Center for Environmental Prediction (NCEP) operational verification capabilities (e.g., I/O, methods, statistics, data types). MET development will take into account the needs of the NWP community - including operational centers and the research and development community. Some of the MET capabilities include traditional verification approaches for standard surface and upper air variables (e.g., Equitable Threat Score, Mean Squared Error), confidence intervals for verification measures, and spatial forecast verification methods. In the future, MET will include additional state-of-the-art and new methodologies. @@ -31,7 +32,7 @@ The MET package has been designed to be modular and adaptable. For example, indi The MET code and documentation is maintained by the DTC in Boulder, Colorado. The MET package is freely available to the modeling, verification, and operational communities, including universities, governments, the private sector, and operational modeling and prediction centers. MET components -______________ +============== The major components of the MET package are represented in :numref:`overview-figure`. The main stages represented are input, reformatting, plotting, intermediate output, statistical analyses, and output and aggregation/analysis. The MET-TC package functions independently of the other MET modules, as indicated in the Figure. Each of these stages is described further in later sections. For example, the input and output formats are discussed in :numref:`data_io` as well as in the sections associated with each of the statistics modules. MET input files are represented on the far left. @@ -74,12 +75,12 @@ The following sections of this MET User's Guide contain usage statements for eac .. include:: release-notes.rst Future development plans -________________________ +======================== MET is an evolving verification software package. New capabilities are planned in controlled, successive version releases. Bug fixes and user-identified problems will be addressed as they are found and posted to the known issues section of the `MET User Support web page `_. Plans are also in place to incorporate many new capabilities and options in future releases of MET. Please refer to the issues listed in the `MET GitHub repository `_ to see our development priorities for upcoming releases. Code support -____________ +============ MET support is provided through the `METplus GitHub Discussions Forum `_. We will endeavor to respond to requests for help in a timely fashion. In addition, information about MET and tools that can be used with MET are provided on the `MET web page `_. @@ -90,7 +91,7 @@ We welcome comments and suggestions for improvements to MET, especially informat The MET package is a "living" set of tools. Our goal is to continually enhance it and add to its capabilities. Because our time, resources, and talents are limited, we welcome contributed code for future versions of MET. These contributions may represent new verification methodologies, new analysis tools, or new plotting functions. For more information on contributing code to MET, please create a post in the `METplus GitHub Discussions Forum `_. Fortify -_______ +======= Requirements from various government agencies that use MET have resulted in our code being analyzed by Fortify, a proprietary static source code analyzer owned by HP Enterprise Security Products. Fortify analyzes source code to identify for security risks, memory leaks, uninitialized variables, and other such weaknesses and bad coding practices. Fortify categorizes any issues it finds as low priority, high priority, or critical, and reports these issues back to the developers for them to address. A development cycle is thus established, with Fortify analyzing code and reporting back to the developers, who then make changes in the source code to address these issues, and hand the new code off to Fortify again for re-analysis. The goal is to drive the counts of both high priority and critical issues down to zero. diff --git a/met/docs/Users_Guide/plotting.rst b/met/docs/Users_Guide/plotting.rst index a96dca605a..9b08a2be7e 100644 --- a/met/docs/Users_Guide/plotting.rst +++ b/met/docs/Users_Guide/plotting.rst @@ -1,10 +1,11 @@ .. _plotting: +***************************** Plotting and Graphics Support -============================= +***************************** Plotting Utilities -__________________ +================== This section describes how to check your data files using plotting utilities. Point observations can be plotted using the Plot-Point-Obs utility. A single model level can be plotted using the plot_data_plane utility. For object based evaluations, the MODE objects can be plotted using plot_mode_field. Occasionally, a post-processing or timing error can lead to errors in MET. These tools can assist the user by showing the data to be verified to ensure that times and locations match up as expected. @@ -12,7 +13,7 @@ MET version 10.1 adds support for the passing point observations to plot_point_o plot_point_obs usage -~~~~~~~~~~~~~~~~~~~~ +-------------------- The usage statement for the Plot-Point-Obs utility is shown below: @@ -82,7 +83,7 @@ Please refer to :numref:`Appendix F, Section %s ` for more details ab plot_point_obs configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------- The default configuration file for the Plot-Point-Obs tool named **PlotPointObsConfig_default** can be found in the installed *share/met/config* directory. The contents of the configuration file are described in the subsections below. @@ -219,7 +220,7 @@ For each observation, this tool stores the observation latitude, longitude, and .. _plot_data_plane-usage: plot_data_plane usage -~~~~~~~~~~~~~~~~~~~~~ +--------------------- The usage statement for the plot_data_plane utility is shown below: @@ -274,7 +275,7 @@ A second example of the plot_data_plane calling sequence is shown below: In the first example, the Plot-Data-Plane tool will process the input test.grb file and write a PostScript image to a file named test.ps showing temperature at 2 meters. The second example plots downward shortwave radiation flux at the surface. The second example is run at verbosity level 4 so that the user can inspect the output and make sure its plotting the intended record. plot_mode_field usage -~~~~~~~~~~~~~~~~~~~~~ +--------------------- The usage statement for the plot_mode_field utility is shown below: @@ -326,10 +327,10 @@ In this example, the plot_mode_field tool will plot simple objects from an obser Once MET has been applied to forecast and observed fields (or observing locations), and the output has been sorted through the Analysis Tool, numerous graphical and summary analyses can be performed depending on a specific user's needs. Here we give some examples of graphics and summary scores that one might wish to compute with the given output of MET and MET-TC. Any computing language could be used for this stage; some scripts will be provided on the `MET users web page `_ as examples to assist users. Examples of plotting MET output -_______________________________ +=============================== Grid-Stat tool examples -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- The plots in :numref:`plotting_Gilbert_skill_score` show time series of frequency bias and Gilbert Skill Score, stratified according to time of day. This type of figure is particularly useful for diagnosing problems that are tied to the diurnal cycle. In this case, two of the models (green dash-dotted and black dotted lines) show an especially high Bias (near 3) during the afternoon (15-21 UTC; left panel), while the skill (GSS; right panel) appears to be best for the models represented by the solid black line and green dashed lines in the morning (09-15 UTC). Note that any judgment of skill based on GSS should be restricted to times when the Bias is close to one. @@ -340,7 +341,7 @@ The plots in :numref:`plotting_Gilbert_skill_score` show time series of frequenc Time series of forecast area bias and Gilbert Skill Score for four model configurations (different lines) stratified by time-of-day. MODE tool examples -~~~~~~~~~~~~~~~~~~ +------------------ When using the MODE tool, it is possible to think of matched objects as hits and unmatched objects as false alarms or misses depending on whether the unmatched object is from the forecast or observed field, respectively. Because the objects can have greatly differing sizes, it is useful to weight the statistics by the areas, which are given in the output as numbers of grid squares. When doing this, it is possible to have different matched observed object areas from matched forecast object areas so that the number of hits will be different depending on which is chosen to be a hit. When comparing multiple forecasts to the same observed field, it is perhaps wise to always use the observed field for the hits so that there is consistency for subsequent comparisons. Defining hits, misses and false alarms in this way allows one to compute many traditional verification scores without the problem of small-scale discrepancies; the matched objects are defined as being matched because they are "close" by the fuzzy logic criteria. Note that scores involving the number of correct negatives may be more difficult to interpret as it is not clear how to define a correct negative in this context. It is also important to evaluate the number and area attributes for these objects in order to provide a more complete picture of how the forecast is performing. @@ -363,7 +364,7 @@ In addition to the traditional scores, MODE output allows more information to be .. _TC-Stat-tool-example: TC-Stat tool example -~~~~~~~~~~~~~~~~~~~~ +-------------------- There is a basic R script located in the MET installation, *share/met/Rscripts/plot_tcmpr.R*. The usage statement with a short description of the options for *plot_tcmpr.R* can be obtained by typing: Rscript *plot_tcmpr.R* with no additional arguments. The only required argument is the **-lookin** source, which is the path to the TC-Pairs TCST output files. The R script reads directly from the TC-Pairs output, and calls TC-Stat directly for filter jobs specified in the *"-filter options"* argument. diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index ce7b74e905..5c89be5d6d 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -1,24 +1,25 @@ .. _point-stat: +*************** Point-Stat Tool -=============== +*************** Introduction -____________ +============ The Point-Stat tool provides verification statistics for forecasts at observation points (as opposed to over gridded analyses). The Point-Stat tool matches gridded forecasts to point observation locations and supports several different interpolation options. The tool then computes continuous, categorical, spatial, and probabilistic verification statistics. The categorical and probabilistic statistics generally are derived by applying a threshold to the forecast and observation values. Confidence intervals - representing the uncertainty in the verification measures - are computed for the verification statistics. Scientific and statistical aspects of the Point-Stat tool are discussed in the following section. Practical aspects of the Point-Stat tool are described in :numref:`tc-stat_practical-information`. Scientific and statistical aspects -__________________________________ +================================== The statistical methods and measures computed by the Point-Stat tool are described briefly in this section. In addition, :numref:`matching-methods` discusses the various interpolation options available for matching the forecast grid point values to the observation points. The statistical measures computed by the Point-Stat tool are described briefly in :numref:`PS_Statistical-measures` and in more detail in :numref:`Appendix C, Section %s `. :numref:`PS_Statistical-confidence-intervals` describes the methods for computing confidence intervals that are applied to some of the measures computed by the Point-Stat tool; more detail on confidence intervals is provided in :numref:`Appendix D, Section %s `. .. _matching-methods: Interpolation/matching methods -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ This section provides information about the various methods available in MET to match gridded model output to point observations. Matching in the vertical and horizontal are completed separately using different methods. @@ -119,7 +120,7 @@ The forecast value at P is chosen as the grid point inside the interpolation are .. _PS_HiRA_framework: HiRA framework -~~~~~~~~~~~~~~ +-------------- The Point-Stat tool has been enhanced to include the High Resolution Assessment (HiRA) verification logic (:ref:`Mittermaier, 2014 `). HiRA is analogous to neighborhood verification but for point observations. The HiRA logic interprets the forecast values surrounding each point observation as an ensemble forecast. These ensemble values are processed in three ways. First, the ensemble continuous statistics (ECNT), the observation rank statistics (ORANK) and the ranked probability score (RPS) line types are computed directly from the ensemble values. Second, for each categorical threshold specified, a fractional coverage value is computed as the ratio of the nearby forecast values that meet the threshold criteria. Point-Stat evaluates those fractional coverage values as if they were a probability forecast. When applying HiRA, users should enable the matched pair (MPR), probabilistic (PCT, PSTD, PJC, or PRC), continuous ensemble statistics (ECNT), observation rank statistics (ORANK) or ranked probability score (RPS) line types in the **output_flag** dictionary. The number of probabilistic HiRA output lines is determined by the number of categorical forecast thresholds and HiRA neighborhood widths chosen. @@ -138,7 +139,7 @@ Often, the neighborhood size is chosen so that multiple models to be compared ha .. _PS_Statistical-measures: Statistical measures -~~~~~~~~~~~~~~~~~~~~ +-------------------- The Point-Stat tool computes a wide variety of verification statistics. Broadly speaking, these statistics can be subdivided into statistics for categorical variables and statistics for continuous variables. The categories of measures are briefly described here; specific descriptions of the measures are provided in :numref:`Appendix C, Section %s `. Additional information can be found in :ref:`Wilks (2011) ` and :ref:`Jolliffe and Stephenson (2012) `, and at Collaboration for Australian Weather and Climate Research. Forecast Verification - `Issues, Methods and FAQ web page. `_ @@ -177,7 +178,7 @@ Often, the sample climatology is used as a reference by a skill score. The sampl .. _PS_Statistical-confidence-intervals: Statistical confidence intervals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- A single summary score gives an indication of the forecast performance, but it is a single realization from a random process that neglects uncertainty in the score's estimate. That is, it is possible to obtain a good score, but it may be that the "good" score was achieved by chance and does not reflect the "true" score. Therefore, when interpreting results from a verification analysis, it is imperative to analyze the uncertainty in the realized scores. One good way to do this is to utilize confidence intervals. A confidence interval indicates that if the process were repeated many times, say 100, then the true score would fall within the interval :math:`100(1-\alpha)\%` of the time. Typical values of :math:`\alpha` are 0.01, 0.05, and 0.10. The Point-Stat tool allows the user to select one or more specific :math:`\alpha`-values to use. @@ -248,14 +249,14 @@ For more information on confidence intervals pertaining to verification measures .. _tc-stat_practical-information: Practical information -_____________________ +===================== The Point-Stat tool is used to perform verification of a gridded model field using point observations. The gridded model field to be verified must be in one of the supported file formats. The point observations must be formatted as the NetCDF output of the point reformatting tools described in :numref:`reformat_point`. The Point-Stat tool provides the capability of interpolating the gridded forecast data to the observation points using a variety of methods as described in :numref:`matching-methods`. The Point-Stat tool computes a number of continuous statistics on the matched pair data as well as discrete statistics once the matched pair data have been thresholded. If no matched pairs are found for a particular verification task, a report listing counts for reasons why the observations were not used is written to the log output at the default verbosity level of 2. If matched pairs are found, this report is written at verbosity level 3. Inspecting these rejection reason counts is the first step in determining why Point-Stat found no matched pairs. The order of the log messages matches the order in which the processing logic is applied. Start from the last log message and work your way up, considering each of the non-zero rejection reason counts. point_stat usage -~~~~~~~~~~~~~~~~ +---------------- The usage statement for the Point-Stat tool is shown below: @@ -309,7 +310,7 @@ An example of the point_stat calling sequence is shown below: In this example, the Point-Stat tool evaluates the model data in the sample_fcst.grb GRIB file using the observations in the NetCDF output of PB2NC, sample_pb.nc, applying the configuration options specified in the **PointStatConfig file**. point_stat configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- The default configuration file for the Point-Stat tool named **PointStatConfig_default** can be found in the installed *share/met/config* directory. Another version is located in *scripts/config*. We encourage users to make a copy of these files prior to modifying their contents. The contents of the configuration file are described in the subsections below. @@ -483,7 +484,7 @@ If all line types corresponding to a particular verification method are set to N .. _point_stat-output: point_stat output -~~~~~~~~~~~~~~~~~ +----------------- point_stat produces output in STAT and, optionally, ASCII format. The ASCII output duplicates the STAT output but has the data organized by line type. The output files will be written to the default output directory or the directory specified using the "-outdir" command line option. diff --git a/met/docs/Users_Guide/reformat_grid.rst b/met/docs/Users_Guide/reformat_grid.rst index 3f67a377a7..c3a1e438ee 100644 --- a/met/docs/Users_Guide/reformat_grid.rst +++ b/met/docs/Users_Guide/reformat_grid.rst @@ -1,12 +1,13 @@ .. _reformat_grid: +******************************* Re-Formatting of Gridded Fields -=============================== +******************************* Several MET tools exist for the purpose of reformatting gridded fields, and they are described in this section. These tools are represented by the reformatting column of MET flowchart depicted in :numref:`overview-figure`. Pcp-Combine tool -________________ +================ This section describes the Pcp-Combine tool which summarizes data across multiple input gridded data files and writes the results to a single NetCDF output file. It is often used to modify precipitation accumulation intervals in the forecast and/or observation datasets to make them comparable. However it can also be used to derive summary fields, such as daily min/max temperature or average precipitation rate. @@ -23,7 +24,7 @@ The Pcp-Combine tool supports four types of commands ("sum", "add", "subtract", By default, the Pcp-Combine tool processes data for **APCP**, the GRIB string for accumulated precipitation. When requesting data using time strings (i.e. [HH]MMSS), Pcp-Combine searches for accumulated precipitation for that accumulation interval. Alternatively, use the "-field" option to process fields other than **APCP** or for non-GRIB files. The "-field" option may be used multiple times to process multiple fields in a single run. Since the Pcp-Combine tool does not support automated regridding, all input data must be on the same grid. In general the input files should have the same initialization time unless the user has indicated that it should ignore the initialization time for the "sum" command. The "subtract" command produces a warning when the input initialization times differ or the subtraction results in a negative accumulation interval. pcp_combine usage -~~~~~~~~~~~~~~~~~ +----------------- The usage statement for the Pcp-Combine tool is shown below: @@ -161,7 +162,7 @@ The Pcp-Combine tool will search for 24 files containing 1-hourly accumulation i This command would grab the first level of the TT variable from a pinterp NetCDF file and write it to the output tt_10.nc file. pcp_combine output -~~~~~~~~~~~~~~~~~~ +------------------ The output NetCDF files contain the requested accumulation intervals as well as information about the grid on which the data lie. That grid projection information will be parsed out and used by the MET statistics tools in subsequent steps. One may use NetCDF utilities such as ncdump or ncview to view the contents of the output file. Alternatively, the MET Plot-Data-Plane tool described in :numref:`plot_data_plane-usage` may be run to create a PostScript image of the data. @@ -204,12 +205,12 @@ Each NetCDF file generated by the Pcp-Combine tool contains the dimensions and v .. _regrid-data-plane: Regrid-Data-Plane tool -______________________ +====================== This section contains a description of running the Regrid-Data-Plane tool. This tool may be run to read data from any gridded file MET supports, interpolate to a user-specified grid, and writes the field(s) out in NetCDF format. The user may specify the method of interpolation used for regridding as well as which fields to regrid. This tool is particularly useful when dealing with GRIB2 and NetCDF input files that need to be regridded. For GRIB1 files, it has also been tested for compatibility with the copygb regridding utility mentioned in :numref:`Installation-of-optional`. regrid_data_plane usage -~~~~~~~~~~~~~~~~~~~~~~~ +----------------------- The usage statement for the regrid_data_plane utility is shown below: @@ -283,17 +284,17 @@ For more details on setting the **to_grid, -method, -width,** and **-vld_thresh* In this example, the Regrid-Data-Plane tool will regrid data from the **input.grb** file to the grid on which the first record of the **togrid.grb** file resides using Bilinear Interpolation with a width of 2 and write the output in NetCDF format to a file named **regridded.nc**. The variables in **regridded.nc** will include 6-hour accumulated precipitation, 2m temperature, 10m U and V components of the wind, and the 500mb geopotential height. Automated regridding within tools -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------------- While the Regrid-Data-Plane tool is useful as a stand-alone tool, the capability is also included to automatically **regrid** one or both fields in most of the MET tools that handle gridded data. See the regrid entry in :numref:`Configuration File Details` for a description of the configuration file entries that control automated regridding. Shift-Data-Plane tool -_____________________ +===================== The Shift-Data-Plane tool performs a rigid shift of the entire grid based on user-defined specifications and writes the field(s) out in NetCDF format. This tool was originally designed to account for track error when comparing fields associated with tropical cyclones. The user specifies the latitude and longitude of the source and destination points to define the shift. Both points must fall within the domain and are used to define the X and Y direction grid unit shift. The shift is then applied to all grid points. The user may specify the method of interpolation and the field to be shifted. The effects of topography and land/water masks are ignored. shift_data_plane usage -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- The usage statement for the shift_data_plane utility is shown below: @@ -357,12 +358,12 @@ For more details on setting the **-method** and **-width** options, see the **re In this example, the Shift-Data-Plane tool reads 12-hour accumulated precipitation from the **nam.grb** file, applies a rigid shift defined by (38.6272, -90.1978) to (40.1717, -105.1092) and writes the output in NetCDF format to a file named **nam_shift_APCP_12.nc**. These **-from** and **-to** locations result in a grid shift of -108.30 units in the x-direction and 16.67 units in the y-direction. MODIS regrid tool -_________________ +================= This section contains a description of running the MODIS regrid tool. This tool may be run to create a NetCDF file for use in other MET tools from `MODIS level 2 cloud product from NASA. `_ modis_regrid usage -~~~~~~~~~~~~~~~~~~ +------------------ The usage statement for the modis_regrid utility is shown below: @@ -427,14 +428,14 @@ In this example, the Modis-Regrid tool will process the Cloud_Fraction field fro Example plot showing surface temperature from a MODIS file. WWMCA Tool Documentation -________________________ +======================== There are two WWMCA tools available. The WWMCA-Plot tool makes a PostScript plot of one or more WWMCA cloud percent files and the WWMCA-Regrid tool regrids binary WWMCA data files and reformats them into NetCDF files that the other MET tools can read. The WWMCA-Regrid tool has been generalized to more broadly support any data stored in the WWMCA binary format. The WWMCA tools attempt to parse timing and hemisphere information from the file names. They tokenize the filename using underscores (_) and dots (.) and examine each element which need be in no particular order. A string of 10 or more numbers is interpreted as the valid time in YYYYMMDDHH[MMSS] format. The string NH indicates the northern hemisphere while SH indicates the southern hemisphere. While WWMCA data is an analysis and has no forecast lead time, other datasets following this format may. Therefore, a string of 1 to 4 numbers is interpreted as the forecast lead time in hours. While parsing the filename provides default values for this timing information, they can be overridden by explicitly setting their values in the WWMCA-Regrid configuration file. wwmca_plot usage -~~~~~~~~~~~~~~~~ +---------------- The usage statement for the WWMCA-Plot tool is shown below: @@ -470,7 +471,7 @@ Optional arguments for wwmca_plot Example output of WWMCA-Plot tool. wwmca_regrid usage -~~~~~~~~~~~~~~~~~~ +------------------ The usage statement for the WWMCA-Regrid tool is shown below: @@ -510,7 +511,7 @@ Optional arguments for wwmca_regrid In any regridding problem, there are two grids involved: the "From" grid, which is the grid the input data are on, and the "To" grid, which is the grid the data are to be moved onto. In **WWMCA-Regrid** the "From" grid is pre-defined by the hemisphere of the WWMCA binary files being processed. The "To" grid and corresponding regridding logic are specified using the **regrid** section of the configuration file. If the "To" grid is entirely confined to one hemisphere, then only the WWMCA data file for that hemisphere needs to be given. If the "To" grid or the interpolation box used straddles the equator, the data files for both hemispheres need to be given. Once the "To" grid is specified in the config file, the WWMCA-Regrid tool will know which input data files it needs and will complain if it is not given the right ones. wwmca_regrid configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- The default configuration file for the WWMCA-Regrid tool named **WWMCARegridConfig_default** can be found in the installed *share/met/config* directory. We encourage users to make a copy of this file prior to modifying its contents. The contents of the configuration file are described in the subsections below. diff --git a/met/docs/Users_Guide/reformat_point.rst b/met/docs/Users_Guide/reformat_point.rst index 9e41ca80dc..7a3fce768f 100644 --- a/met/docs/Users_Guide/reformat_point.rst +++ b/met/docs/Users_Guide/reformat_point.rst @@ -1,21 +1,22 @@ .. _reformat_point: +*********************************** Re-Formatting of Point Observations -=================================== +*********************************** There are several formats of point observations that may be preprocessed using the suite of reformatting tools in MET. These include PrepBUFR data from NCEP, SURFRAD data from NOAA, AERONET data from NASA, MADIS data from NOAA, little_r from WRF simulations, and user-defined data in a generic ASCII format. These steps are represented by the first columns in the MET flowchart depicted in :numref:`overview`. The software tools used to reformat point data are described in this section. .. _PB2NC tool: PB2NC tool -__________ +========== This section describes how to configure and run the PB2NC tool. The PB2NC tool is used to stratify the contents of an input PrepBUFR point observation file and reformat it into NetCDF format for use by other MET tools. The PB2NC tool must be run on the input PrepBUFR point observation file prior to performing verification with the MET statistics tools. .. _pb2nc usage: pb2nc usage -~~~~~~~~~~~ +----------- The usage statement for the PB2NC tool is shown below: @@ -91,7 +92,7 @@ In this example, the PB2NC tool will process the input **sample_pb.blk** file ap .. _pb2nc configuration file: pb2nc configuration file -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ The default configuration file for the PB2NC tool named **PB2NCConfig_default** can be found in the installed *share/met/config* directory. The version used for the example run in :numref:`Sample test cases` is available in *scripts/config*. It is recommended that users make a copy of configuration files prior to modifying their contents. @@ -103,7 +104,7 @@ For example, using an environment variable to set the **message_type** (see belo \* In the configuration file: **message_type = [ ${MSG_TYP} ];** - The contents of the default pb2nc configuration file are described below. +The contents of the default pb2nc configuration file are described below. ____________________ @@ -124,7 +125,7 @@ _____________________ Each PrepBUFR message is tagged with one of eighteen message types as listed in the :numref:`config_options` file. The **message_type** refers to the type of observation from which the observation value (or 'report') was derived. The user may specify a comma-separated list of message types to be retained. Providing an empty list indicates that all message types should be retained. -___________________ +_____________________ .. code-block:: none @@ -132,7 +133,7 @@ ___________________ The **message_type_map** entry is an array of dictionaries, each containing a **key** string and **val** string. This defines a mapping of input PrepBUFR message types to output message types. This provides a method for renaming input PrepBUFR message types. -______________________ +_____________________ .. code-block:: none @@ -146,7 +147,7 @@ ______________________ 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 must be present to define message types for which surface verification logic should be applied. -______________ +_____________________ .. code-block:: none @@ -154,7 +155,7 @@ ______________ Each PrepBUFR message has a station identification string associated with it. The user may specify a comma-separated list of station IDs to be retained. Providing an empty list indicates that messages from all station IDs will be retained. It can be a file name containing a list of stations. -_______________ +_____________________ .. code-block:: none @@ -163,7 +164,7 @@ _______________ The **beg** and **end** variables are used to stratify the elevation (in meters) of the observations to be retained. The range shown above is set to -1000 to 100000 meters, which essentially retains every observation. -__________________ +_____________________ .. code-block:: none @@ -178,7 +179,7 @@ The **pb_report_type, in_report_type**, and **instrument_type** variables are us `PrepBUFR Code table for input report types. `_ -_________________ +_____________________ .. code-block:: none @@ -219,8 +220,8 @@ The **level_category** variable is used to specify a comma-separated list of Pre * - 7 - Auxiliary levels generated via interpolation from spanning levels -_______________ - +_____________________ + .. code-block:: none obs_bufr_var = [ 'QOB', 'TOB', 'ZOB', 'UOB', 'VOB' ]; @@ -228,7 +229,7 @@ _______________ Each PrepBUFR message will likely contain multiple observation variables. The **obs_bufr_var** variable is used to specify which observation variables should be retained or derived. The variable name comes from BUFR file which includes BUFR table. The following BUFR names may be retained: QOB, TOB, ZOB, UOB, and VOB for specific humidity, temperature, height, and the u and v components of winds. The following BUFR names may be derived: D_DPT, D_WIND, D_RH, D_MIXR, D_PRMSL, D_PBL, and D_CAPE for dew point, wind speed, relative humidity, mixing ratio, pressure reduced to MSL, planetary boundary layer height, and convective available potential energy. This configuration replaces **obs_grib_code**. If the list is empty, all BUFR variables are retained. -________________ +_____________________ .. code-block:: none @@ -252,7 +253,7 @@ ________________ The BUFR variable names are not shared with other forecast data. This map is used to convert the BUFR name to the common name, like GRIB2. It allows to share the configuration for forecast data with PB2NC observation data. If there is no mapping, the BUFR variable name will be saved to output NetCDF file. -______________ +_____________________ .. code-block:: none @@ -261,7 +262,7 @@ ______________ Each observation has a quality mark value associated with it. The **quality_mark_thresh** is used to stratify out which quality marks will be retained. The value shown above indicates that only observations with quality marks less than or equal to 2 will be retained. -_________________ +_____________________ .. code-block:: none @@ -270,7 +271,7 @@ _________________ A PrepBUFR message may contain duplicate observations with different quality mark values. The **event_stack_flag** indicates whether to use the observations at the top of the event stack (observation values have had more quality control processing applied) or the bottom of the event stack (observation values have had no quality control processing applied). The flag value of **TOP** listed above indicates the observations with the most amount of quality control processing should be used, the **BOTTOM** option uses the data closest to raw values. -___________________ +_____________________ .. code-block:: none @@ -311,7 +312,7 @@ The **vld_freq** and **vld_thresh** entries specify the required ratio of valid .. _pb2nc output: pb2nc output -~~~~~~~~~~~~ +------------ Each NetCDF file generated by the PB2NC tool contains the dimensions and variables shown in :numref:`table_reform-point_pb2nc_output_dim` and :numref:`table_reform-point_pb2nc_output_vars`. @@ -416,7 +417,7 @@ Each NetCDF file generated by the PB2NC tool contains the dimensions and variabl ASCII2NC tool -_____________ +============= This section describes how to run the ASCII2NC tool. The ASCII2NC tool is used to reformat ASCII point observations into the NetCDF format expected by the Point-Stat tool. For those users wishing to verify against point observations that are not available in PrepBUFR format, the ASCII2NC tool provides a way of incorporating those observations into MET. If the ASCII2NC tool is used to perform a reformatting step, no configuration file is needed. However, for more complex processing, such as summarizing time series observations, a configuration file may be specified. For details on the configuration file options, see :numref:`config_options` and example configuration files distributed with the MET code. @@ -473,7 +474,7 @@ The default ASCII point observation format consists of one row of data per obser - Observation value in units consistent with the GRIB code definition. ascii2nc usage -~~~~~~~~~~~~~~ +-------------- Once the ASCII point observations have been formatted as expected, the ASCII file is ready to be processed by the ASCII2NC tool. The usage statement for ASCII2NC tool is shown below: @@ -544,13 +545,13 @@ Here is an example of processing the same set of observations but using Python e Please refer to :numref:`Appendix F, Section %s ` for more details about Python embedding in MET. ascii2nc configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- The default configuration file for the ASCII2NC tool named **Ascii2NcConfig_default** can be found in the installed *share/met/config* directory. It is recommended that users make a copy of this file prior to modifying its contents. The ASCII2NC configuration file is optional and only necessary when defining time summaries or message type mapping for little_r data. The contents of the default ASCII2NC configuration file are described below. -__________________ +_____________________ .. code-block:: none @@ -558,7 +559,7 @@ __________________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. -_________________ +_____________________ .. code-block:: none @@ -567,7 +568,7 @@ _________________ The **time_summary** feature was implemented to allow additional processing of observations with high temporal resolution, such as SURFRAD data every 5 minutes. This option is described in :numref:`pb2nc configuration file`. -_________________ +_____________________ .. code-block:: none @@ -588,7 +589,7 @@ This entry is an array of dictionaries, each containing a **key** string and **v ascii2nc output -~~~~~~~~~~~~~~~ +--------------- The NetCDF output of the ASCII2NC tool is structured in the same way as the output of the PB2NC tool described in :numref:`pb2nc output`. @@ -596,14 +597,14 @@ The NetCDF output of the ASCII2NC tool is structured in the same way as the outp MADIS2NC tool -_____________ +============= This section describes how to run the MADIS2NC tool. The MADIS2NC tool is used to reformat `Meteorological Assimilation Data Ingest System (MADIS) `_ point observations into the NetCDF format expected by the MET statistics tools. An optional configuration file controls the processing of the point observations. The MADIS2NC tool supports many of the MADIS data types, as listed in the usage statement below. Support for additional MADIS data types may be added in the future based on user feedback. madis2nc usage -~~~~~~~~~~~~~~ +-------------- The usage statement for the MADIS2NC tool is shown below: @@ -686,7 +687,7 @@ In this example, the MADIS2NC tool will reformat the input sample_madis_obs.nc f madis2nc configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- The default configuration file for the MADIS2NC tool named **Madis2NcConfig_default** can be found in the installed *share/met/config* directory. It is recommended that users make a copy of this file prior to modifying its contents. @@ -694,8 +695,7 @@ The default configuration file for the MADIS2NC tool named **Madis2NcConfig_defa The MADIS2NC configuration file is optional and only necessary when defining time summaries. The contents of the default MADIS2NC configuration file are described below. -_________________ - +_____________________ .. code-block:: none @@ -704,8 +704,7 @@ _________________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. -__________________ - +_____________________ .. code-block:: none @@ -716,7 +715,7 @@ The **time_summary** dictionary is described in :numref:`pb2nc configuration fil madis2nc output -~~~~~~~~~~~~~~~ +--------------- The NetCDF output of the MADIS2NC tool is structured in the same way as the output of the PB2NC tool described in :numref:`pb2nc output`. @@ -724,14 +723,14 @@ The NetCDF output of the MADIS2NC tool is structured in the same way as the outp LIDAR2NC tool -_____________ +============= The LIDAR2NC tool creates a NetCDF point observation file from a CALIPSO HDF data file. Not all of the data present in the CALIPSO file is reproduced in the output, however. Instead, the output focuses mostly on information about clouds (as opposed to aerosols) as seen by the satellite along its ground track. lidar2nc usage -~~~~~~~~~~~~~~ +-------------- The usage statement for LIDAR2NC tool is shown below: @@ -767,7 +766,7 @@ Optional arguments for lidar2nc 5. The **-compress level** option indicates the desired level of compression (deflate level) for NetCDF variables. The valid level is between 0 and 9. The value of "level" will override the default setting of 0 from the configuration file or the environment variable MET_NC_COMPRESS. Setting the compression level to 0 will make no compression for the NetCDF output. Lower number is for fast compression and higher number is for better compression. lidar2nc output -~~~~~~~~~~~~~~~ +--------------- Each observation type in the lidar2nc output is assigned a GRIB code. These are outlined in :numref:`lidar2nc_grib_code_table`. GRIB codes were assigned to these fields arbitrarily, with GRIB codes in the 600s denoting individual bit fields taken from the feature classification flag field in the CALIPSO file. @@ -839,14 +838,14 @@ We will not give a detailed description of each CALIPSO data product that lidar2 IODA2NC tool -____________ +============ This section describes the IODA2NC tool which is used to reformat IODA (Interface for Observation Data Access) point observations from the `Joint Center for Satellite Data Assimilation (JCSDA) `_ into the NetCDF format expected by the MET statistics tools. An optional configuration file controls the processing of the point observations. The IODA2NC tool reads NetCDF point observation files created by the `IODA Converters `_. Support for interfacing with data from IODA may be added in the future based on user feedback. ioda2nc usage -~~~~~~~~~~~~~ +------------- The usage statement for the IODA2NC tool is shown below: @@ -905,13 +904,13 @@ In this example, the IODA2NC tool will reformat the data in the input ioda.NC001 ioda2nc configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------- The default configuration file for the IODA2NC tool named **IODA2NcConfig_default** can be found in the installed *share/met/config* directory. It is recommended that users make a copy of this file prior to modifying its contents. The IODA2NC configuration file is optional and only necessary when defining filtering the input observations or defining time summaries. The contents of the default IODA2NC configuration file are described below. -__________________ +_____________________ .. code-block:: none @@ -922,8 +921,7 @@ __________________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. -_________________ - +_____________________ .. code-block:: none @@ -939,7 +937,7 @@ _________________ The configuration options listed above are supported by other point observation pre-processing tools and are described in :numref:`pb2nc configuration file`. -_________________ +_____________________ .. code-block:: none @@ -947,7 +945,7 @@ _________________ This entry is an array of dictionaries, each containing a **key** string and **val** string which define a mapping of input IODA variable names to output variable names. The default IODA map, obs_var_map, is appended to this map. -_________________ +_____________________ .. code-block:: none @@ -961,7 +959,7 @@ _________________ This entry is an array of dictionaries, each containing a **key** string and **val** string which define a mapping of metadata for IODA data files. -_________________ +_____________________ .. code-block:: none @@ -971,13 +969,13 @@ The **missing_thresh** option is an array of thresholds. Any data values which m ioda2nc output -~~~~~~~~~~~~~~ +-------------- The NetCDF output of the IODA2NC tool is structured in the same way as the output of the PB2NC tool described in :numref:`pb2nc output`. Point2Grid tool -_______________ +=============== The Point2Grid tool takes point observations from a NetCDF output file from one of the four previously mentioned MET tools (ascii2nc, madis2nc, pb2nc, lidar2nc) and creates a gridded NetCDF file. The other point observations are GOES-16/17 input files in NetCDF format (especially, Aerosol Optical Depth. Future development will include support for reading input files not produced from MET tools. @@ -985,7 +983,7 @@ MET version 10.1 adds support for the passing point observations to point2grid u point2grid usage -~~~~~~~~~~~~~~~~ +---------------- The usage statement for the Point2Grid tool is shown below: @@ -1085,7 +1083,7 @@ Please refer to :numref:`Appendix F, Section %s ` for more details ab point2grid output -~~~~~~~~~~~~~~~~~ +----------------- The point2grid tool will output a gridded NetCDF file containing the following: @@ -1113,15 +1111,14 @@ The point2grid tool will output a gridded NetCDF file containing the following: For MET observation input and CF complaint NetCDF input with 2D time variable: The latest observation time within the target grid is saved as the observation time. If the "valid_time" is configured at the configuration file, the valid_time from the configuration file is saved into the output file. point2grid configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----------------------------- The default configuration file for the point2grid tool named **Point2GridConfig_default** can be found in the installed *share/met/config* directory. It is recommended that users make a copy of this file prior to modifying its contents. The point2grid configuration file is optional and only necessary when defining the variable name instead of GRIB code or filtering by time. The contents of the default MADIS2NC configuration file are described below. -_______________ - +_____________________ .. code-block:: none @@ -1130,8 +1127,7 @@ _______________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. -__________________ - +_____________________ .. code-block:: none diff --git a/met/docs/Users_Guide/refs.rst b/met/docs/Users_Guide/refs.rst index 647e3591bf..423be1a479 100644 --- a/met/docs/Users_Guide/refs.rst +++ b/met/docs/Users_Guide/refs.rst @@ -1,7 +1,8 @@ .. _refs: +********** References -========== +********** .. _Aberson-1998: diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index 5cac6e7006..1f11648ec9 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -1,12 +1,12 @@ -MET release notes -_________________ +MET Release Notes +================= When applicable, release notes are followed by the GitHub issue number which describes the bugfix, enhancement, or new feature: `MET GitHub issues. `_ MET Version 10.1.0-beta5 release notes (20220114) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- * Enhancements: @@ -27,7 +27,7 @@ MET Version 10.1.0-beta5 release notes (20220114) * Fix IODA2NC to handle the same input file being provided multiple times (`#1965 `_). MET Version 10.1.0-beta4 release notes (20211117) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- * Enhancements: @@ -48,7 +48,7 @@ MET Version 10.1.0-beta4 release notes (20211117) * Enhance the documentation with meta-data that is expected by MET for netCDF (`#1949 `_). MET Version 10.1.0-beta3 release notes (20211006) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- * New tools: @@ -79,7 +79,7 @@ MET Version 10.1.0-beta3 release notes (20211006) * Reduce the Security hotspots from SonarQube (`#1903 `_). MET Version 10.1.0-beta2 release notes (20210901) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- * New output: @@ -116,7 +116,7 @@ MET Version 10.1.0-beta2 release notes (20210901) * Update FAQ in User's Guide with info from webpage FAQ (`#1834 `_). MET Version 10.1.0-beta1 release notes (20210613) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------- * Add the HSS_EC statistic to the MCTS line type and a configurable option for its computation (`#1749 `_). * Implement a common API for reading and writing the common NetCDF point observation file format (`#1402 `_ and `#1581 `_). @@ -127,7 +127,7 @@ MET Version 10.1.0-beta1 release notes (20210613) * Add anchors to link directly to configuration items in the MET User's Guide (`#1811 `_). MET Version 10.0.0 release notes (20210510) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------- * Repository and build: diff --git a/met/docs/Users_Guide/rmw-analysis.rst b/met/docs/Users_Guide/rmw-analysis.rst index 9ae27fe82f..6b0a849de9 100644 --- a/met/docs/Users_Guide/rmw-analysis.rst +++ b/met/docs/Users_Guide/rmw-analysis.rst @@ -1,18 +1,19 @@ .. _rmw-analysis: +***************** RMW-Analysis Tool -================= +***************** Introduction -____________ +============ The RMW-Analysis tool analyzes a set of output files generated by the TC-RMW tool. For each grid cell it aggregates variable statistics across the set and across the track points of the tc_rmw output files. The statistics are mean, standard deviation, minimum and maximum. Note that tc_rmw should be set to use the same scale factor of the radius of maximum winds (RMW) as the unit of range for its range-azimuth grid. The specified data variables on the range-azimuth-vertical grid then share a common range scale of RMW before aggregation by rmw_analysis. Practical information -_____________________ +===================== rmw_analysis usage -~~~~~~~~~~~~~~~~~~ +------------------ The following sections describe the usage statement, required arguments, and optional arguments for **rmw_analysis**. @@ -46,7 +47,7 @@ Optional arguments for rmw_analysis 5. The **-v level** option indicates the desired level of verbosity. The contents of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity above 1 will increase the amount of logging. rmw_analysis configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- The default configuration file for the RMW-Analysis tool named **RMWAnalysisConfig_default** can be found in the installed *share/met/config/* directory. It is encouraged for users to copy these default files before modifying their contents. The contents of the configuration file are described in the subsections below. @@ -86,6 +87,6 @@ The track filter options available in rmw_analysis and listed above are describe rmw_analysis output file -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ The NetCDF output file will inherit the spatial grid from the first tc_rmw output file in the output file list. All tc_rmw files in this list must have the same grid dimension sizes. A NetCDF output error will result if that is not the case. For each data variable specified in the config file, four corresponding NetCDF variables will be written, e.g. TMP_mean, TMP_stdev, TMP_min, TMP_max. No track point dimension is retained in the rmw_analysis output. diff --git a/met/docs/Users_Guide/series-analysis.rst b/met/docs/Users_Guide/series-analysis.rst index 640d948012..95766ae35b 100644 --- a/met/docs/Users_Guide/series-analysis.rst +++ b/met/docs/Users_Guide/series-analysis.rst @@ -1,15 +1,16 @@ .. _series-analysis: +******************** Series-Analysis Tool -==================== +******************** Introduction -____________ +============ The Series-Analysis Tool accumulates statistics separately for each horizontal grid location over a series. Often, this series is over time or height, though any type of series is possible. This differs from the Grid-Stat tool in that Grid-Stat verifies all grid locations together as a group. Thus, the Series-Analysis Tool can be used to find verification information specific to certain locations or see how model performance varies over the domain. Practical Information -_____________________ +===================== This Series-Analysis tool performs verification of gridded model fields using matching gridded observation fields. It computes a variety of user-selected statistics. These statistics are a subset of those produced by the Grid-Stat tool, with options for statistic types, thresholds, and conditional verification options as discussed in :numref:`grid-stat`. However, these statistics are computed separately for each grid location and accumulated over some series such as time or height, rather than accumulated over the whole domain for a single time or height as is done by Grid-Stat. @@ -22,7 +23,7 @@ To define a time series of forecasts that all have the same valid time, set the To define a series of vertical levels all contained in a single input file, set the forecast and observation fields to a list of the vertical levels to be used. Pass the tool single forecast and observation files containing the vertical level data. The tool will loop over the forecast field entries, extract that field from the input forecast file, and then search the observation file for a matching record. series_analysis usage -~~~~~~~~~~~~~~~~~~~~~ +--------------------- The usage statement for the Series-Analysis tool is shown below: @@ -78,7 +79,7 @@ An example of the series_analysis calling sequence is shown below: In this example, the Series-Analysis tool will process the list of forecast and observation files specified in the text file lists into statistics for each grid location using settings specified in the configuration file. Series-Analysis will create an output NetCDF file containing requested statistics. series_analysis output -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- The Series-Analysis tool produces NetCDF files containing output statistics for each grid location from the input files. The details about the output statistics available from each output line type are detailed in Chapter 5 since they are also produced by the Grid-Stat Tool. A subset of these can be produced by this tool, with the most notable exceptions being the wind vector and neighborhood statistics. Users can inventory the contents of the Series-Analysis output files using the ncdump -h command to view header information. Additionally, ncview or the Plot-Data-Plane tool can be used to visualize the output. An example of Series-Analysis output is shown in :numref:`series-analysis_Glibert_precip` below. @@ -89,7 +90,7 @@ The Series-Analysis tool produces NetCDF files containing output statistics for An example of the Gilbert Skill Score for precipitation forecasts at each grid location for a month of files. series_analysis configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------------- The default configuration file for the Series-Analysis tool named **SeriesAnalysisConfig_default** can be found in the installed *share/met/config* directory. The contents of the configuration file are described in the subsections below. Note that environment variables may be used when editing configuration files, as described in the :numref:`pb2nc configuration file` for the PB2NC tool. diff --git a/met/docs/Users_Guide/stat-analysis.rst b/met/docs/Users_Guide/stat-analysis.rst index 80c843b9a3..b398827234 100644 --- a/met/docs/Users_Guide/stat-analysis.rst +++ b/met/docs/Users_Guide/stat-analysis.rst @@ -1,28 +1,29 @@ .. _stat-analysis: +****************** Stat-Analysis Tool -================== +****************** Introduction -____________ +============ The Stat-Analysis tool ties together results from the Point-Stat, Grid-Stat, Ensemble-Stat, Wavelet-Stat, and TC-Gen tools by providing summary statistical information and a way to filter their STAT output files. It processes the STAT output created by the other MET tools in a variety of ways which are described in this section. MET version 9.0 adds support for the passing matched pair data (MPR) into Stat-Analysis using a Python script with the "-lookin python ..." option. An example of running Stat-Analysis with Python embedding is shown in :numref:`stat_analysis-usage`. Scientific and statistical aspects -__________________________________ +================================== The Stat-Analysis tool can perform a variety of analyses, and each type of analysis is called a "job". The job types include the ability to (i) aggregate results over a user-specified time; (ii) stratify statistics based on time of day, model initialization time, lead-time, model run identifier, output filename, or wavelet decomposition scale; and (iii) compute specific verification indices such as the GO Index [1]_ and wind direction statistics. Future functionality may include information about time-trends and/or calculations based on climatology (e.g., anomaly correlation). This section summarizes the capabilities of the supported Stat-Analysis jobs. Filter STAT lines -~~~~~~~~~~~~~~~~~ +----------------- The Stat-Analysis "filter" job simply filters out specific STAT lines based on user-specified search criteria. All of the STAT lines that are retained from one or many files are written to a single output file. The output file for filtered STAT lines must be specified using the **-dump_row** job command option. Summary statistics for columns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ The Stat-Analysis "summary" job produces summary information for columns of data. After the user specifies the column(s) of interest and any other relevant search criteria, summary information is produced from values in those column(s) of data. The summary statistics produced are: mean, standard deviation, minimum, maximum, the 10th, 25th, 50th, 75th, and 90th percentiles, the interquartile range, the range, and both weighted and unweighted means using the logic prescribed by the World Meteorological Organization (WMO). @@ -37,12 +38,12 @@ The **-derive** job command option can be used to perform the derivation of stat .. _StA_Aggregated-values-from: Aggregated values from multiple STAT lines -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------ The Stat-Analysis "aggregate" job aggregates values from multiple STAT lines of the same type. The user may specify the specific line type of interest and any other relevant search criteria. The Stat-Analysis tool then creates sums of each of the values in all lines matching the search criteria. The aggregated data are output as the same line type as the user specified. The STAT line types which may be aggregated in this way are the contingency table (FHO, CTC, PCT, MCTC, NBRCTC), partial sums (SL1L2, SAL1L2, VL1L2, and VAL1L2), and other (ISC, ECNT, RPS, RHIST, PHIST, RELP, NBRCNT, SSVAR, and GRAD) line types. Aggregate STAT lines and produce aggregated statistics -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------------------ The Stat-Analysis "aggregate-stat" job aggregates multiple STAT lines of the same type together and produces relevant statistics from the aggregated line. This may be done in the same manner listed above in :numref:`StA_Aggregated-values-from`. However, rather than writing out the aggregated STAT line itself, the relevant statistics generated from that aggregated line are provided in the output. Specifically, if a contingency table line type (FHO, CTC, PCT, MCTC, or NBRCTC) has been aggregated, contingency table statistics (CTS, ECLV, PSTD, MCTS, or NBRCTS) line types can be computed. If a partial sums line type (SL1L2 or SAL1L2) has been aggregated, the continuous statistics (CNT) line type can be computed. If a vector partial sums line type (VL1L2) has been aggregated, the vector continuous statistics (VCNT) line type can be computed. For ensembles, the ORANK line type can be accumulated into ECNT, RPS, RHIST, PHIST, RELP, or SSVAR output. If the matched pair line type (MPR) has been aggregated, may output line types (FHO, CTC, CTS, CNT, MCTC, MCTS, SL1L2, SAL1L2, VL1L2, VCNT, WDIR, PCT, PSTD, PJC, PRC, or ECLV) can be computed. Multiple output line types may be specified for each "aggregate-stat" job, as long as each output is derivable from the input. @@ -53,7 +54,7 @@ When aggregating the matched pair line type (MPR) and computing an output contin .. _StA_Skill-Score-Index: Skill Score Index -~~~~~~~~~~~~~~~~~ +----------------- The Stat-Analysis "ss_index", "go_index", and "cbs_index" jobs calculate skill score indices by weighting scores for meteorological fields at different levels and lead times. Pre-defined configuration files are provided for the GO Index and CBS Index which are special cases of the highly configurable skill score index job. @@ -92,7 +93,7 @@ When running a skill score index job using the "-out_stat" job command option, a .. _StA_Go-Index: GO Index -~~~~~~~~ +-------- The "go_index" job is a special case of the "ss_index" job, described in :numref:`StA_Skill-Score-Index`. The GO Index is a weighted average of 48 skill scores of RMSE statistics for wind speed, dew point temperature, temperature, height, and pressure at several levels in the atmosphere. The variables, levels, and lead times included in the index are listed in :numref:`compute_GO_Index` and are defined by the default "STATAnalysisConfig_GO_Index" configuration file. The partial sums (SL1L2 lines in the STAT output) for each of these variables at each level and lead time must have been computed in a previous step. The Stat-Analysis tool then uses the weights in :numref:`compute_GO_Index` to compute values for the GO Index. @@ -190,7 +191,7 @@ The "go_index" job is a special case of the "ss_index" job, described in :numref .. _StA_CBS-Index: CBS Index -~~~~~~~~~ +--------- The "cbs_index" job is a special case of the "ss_index" job, described in :numref:`StA_Skill-Score-Index`. The CBS Index is a weighted average of 40 skill scores of RMSE statistics for mean sea level pressure, height, and wind speed at multiple levels computed over the northern hemisphere, southern hemisphere and the tropics. The variables, levels, lead times, and regions included in the index are listed in :numref:`compute_CBS_Index` and are defined by the default "STATAnalysisConfig_CBS_Index" configuration file. The partial sums (SL1L2 lines in the STAT output) for each of these variables for each level, lead time, and masking region must have been computed in a previous step. The Stat-Analysis tool then uses the weights in :numref:`compute_CBS_Index` to compute values for the CBS Index. @@ -232,12 +233,12 @@ The "cbs_index" job is a special case of the "ss_index" job, described in :numre - x Ramp Events -~~~~~~~~~~~ +----------- The Stat-Analysis "ramp" job identifies ramp events (large increases or decreases in values over a time window) in both the forecast and observation data. It categorizes these events as hits, misses, false alarms, or correct negatives by applying a configurable matching time window and computes the corresponding categorical statistics. Wind Direction Statistics -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- The Stat-Analysis "aggregate_stat" job can read vector partial sums and derive wind direction error statistics (WDIR). The vector partial sums (VL1L2 or VAL1L2) or matched pairs (MPR) for the UGRD and VGRD must have been computed in a previous step, i.e. by Point-Stat or Grid-Stat tools. This job computes an average forecast wind direction and an average observed wind direction along with their difference. The output is in degrees. In Point-Stat and Grid-Stat, the UGRD and VGRD can be verified using thresholds on their values or on the calculated wind speed. If thresholds have been applied, the wind direction statistics are calculated for each threshold. @@ -258,14 +259,14 @@ Once the appropriate lines have been generated for each verification time of int 2. For the "AGGR_WDIR" line, the input VL1L2 lines are first aggregated into a single line of partial sums where the weight for each line is determined by the number of points it represents. From this aggregated line, the mean forecast wind direction, observation wind direction, and the associated error are computed and written out. Practical information -_____________________ +===================== The following sections describe the usage statement, required arguments and optional arguments for the Stat-Analysis tool. .. _stat_analysis-usage: stat_analysis usage -~~~~~~~~~~~~~~~~~~~ +------------------- The usage statement for the Stat-Analysis tool is shown below: @@ -331,7 +332,7 @@ In this example, rather than passing the MPR output lines from Point-Stat direct .. _stat_analysis-configuration-file: stat_analysis configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-------------------------------- The default configuration file for the Stat-Analysis tool named **STATAnalysisConfig_default** can be found in the installed *share/met/config* directory. The version used for the example run in :numref:`installation` is also available in *scripts/config*. Like the other configuration files described in this document, it is recommended that users make a copy of these files prior to modifying their contents. @@ -692,7 +693,7 @@ These job command options are analogous to the options listed above but apply wh When processing input ORANK lines and writing output RHIST or PHIST lines, this option defines the output histogram bin width to be used. stat-analysis tool output -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- The output generated by the Stat-Analysis tool contains statistics produced by the analysis. It also records information about the analysis job that produced the output for each line. Generally, the output is printed to the screen. However, it can be redirected to an output file using the "**-out**" option. The format of output from each STAT job command is described below. diff --git a/met/docs/Users_Guide/tc-dland.rst b/met/docs/Users_Guide/tc-dland.rst index 163c732968..078d4d3a9e 100644 --- a/met/docs/Users_Guide/tc-dland.rst +++ b/met/docs/Users_Guide/tc-dland.rst @@ -1,17 +1,18 @@ .. _tc-dland: +************* TC-Dland Tool -============= +************* Introduction -____________ +============ Many filtering criteria within the MET-TC tools depend on the distinction between when a storm is over land or water. The TC-dland tool was developed to aid in quickly parsing data for filter jobs that only verify over water, threshold verification based on distance to land, and exclusion of forecasts outside a specified time window of landfall. For each grid point in the user-specified grid, it computes the great circle arc distance to the nearest coast line. Compared to the simple Euclidean distances, great circle arc distances are more accurate but take considerably longer to compute. Grid points over water have distances greater than zero while points over land have distances less than zero. While the TC-dland tool is available to be run, most users will find the precomputed distance to land files distributed with the release sufficient. Therefore, the typical user will not actually need to run this tool. Input/output format -___________________ +=================== The input for the TC-dland tool is a file containing the longitude (degrees east) and latitude (degrees north) of all the coastlines and islands considered to be a significant landmass. The default input is to use all three land data files (**aland.dat, shland.dat, wland.dat**) found in the installed *share/met/tc_data/* directory. The use of all three files produces a global land data file. The **aland.dat** file contains the longitude and latitude distinctions used by NHC for the Atlantic and eastern North Pacific basins, the **shland.dat** contains longitude and latitude distinctions for the Southern Hemisphere (south Pacific and South Indian Ocean), and the **wland.dat** contains the remainder of the Northern Hemisphere (western North Pacific and North Indian Ocean). Users may supply their own input file in order to refine the definition of coastlines and a significant landmass. @@ -22,12 +23,12 @@ The output file from TC-dland is a NetCDF format file containing a gridded field **dland_global_tenth_degree.nc:** TC-dland output from all three land data files (global coverage) using a 1/10th degree grid. Practical information -_____________________ +===================== This section briefly describes how to run tc_dland. The default grid is set to 1/10th degree Northwest (NW) hemispheric quadrant (over North America) grid. tc_dland usage -~~~~~~~~~~~~~~ +-------------- .. code-block:: none diff --git a/met/docs/Users_Guide/tc-gen.rst b/met/docs/Users_Guide/tc-gen.rst index bf91572fcc..d69036a603 100644 --- a/met/docs/Users_Guide/tc-gen.rst +++ b/met/docs/Users_Guide/tc-gen.rst @@ -1,17 +1,18 @@ .. _tc-gen: +*********** TC-Gen Tool -=========== +*********** Introduction -____________ +============ The TC-Gen tool provides verification of deterministic and probabilistic tropical cyclone genesis forecasts in the ATCF file and shapefile formats. Producing reliable tropical cyclone genesis forecasts is an important metric for global numerical weather prediction models. This tool ingests deterministic model output post-processed by genesis tracking software (e.g. GFDL vortex tracker), ATCF edeck files containing probability of genesis forecasts, operational shapefile warning areas, and ATCF reference track dataset(s) (e.g. Best Track analysis and CARQ operational tracks). It writes categorical counts and statistics. The capability to modify the spatial and temporal tolerances when matching forecasts to reference genesis events, as well as scoring those matched pairs, gives users the ability to condition the criteria based on model performance and/or conduct sensitivity analyses. Statistical aspects are outlined in :numref:`tc-gen_stat_aspects` and practical aspects of the TC-Gen tool are described in :numref:`tc-gen_practical_info`. .. _tc-gen_stat_aspects: Statistical aspects -___________________ +=================== The TC-Gen tool processes both deterministic and probabilistic forecasts. @@ -32,12 +33,12 @@ Care should be taken when interpreting the statistics for filtered data. In some .. _tc-gen_practical_info: Practical information -_____________________ +===================== This section describes how to configure and run the TC-Gen tool. The following sections describe the usage statement, required arguments, and optional arguments for tc_gen. tc_gen usage -~~~~~~~~~~~~ +------------ The usage statement for tc_gen is shown below: @@ -157,7 +158,7 @@ The TC-Gen tool implements the following logic: * Report the Nx2 probabilistic contingency table counts and statistics for each lead time. These counts and statistics are identified in the output files as *GENESIS_SHAPE*. tc_gen configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- The default configuration file for the **TC-Gen** tool named **TCGenConfig_default** can be found in the installed *share/met/config* directory. Like the other configuration files described in this document, it is recommended that users make a copy of these files prior to modifying their contents. @@ -481,7 +482,7 @@ ______________________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. TC-Gen writes output for 2x2 contingency tables to the **FHO**, **CTC**, and **CTS** line types when verifying deterministic genesis forecasts specified using the **-track** command line option. TC-Gen writes output for Nx2 probabilistic contingency tables to the **PCT**, **PSTD**, **PJC**, and **PRC** line types when verifying the probability of genesis forecasts specified using the **-edeck** command line option and probabilistic shapefiles using the **-shape** command line option. Note that the **genmpr** line type is specific to TC-Gen and describes individual genesis matched pairs. tc_gen output -~~~~~~~~~~~~~ +------------- TC-Gen produces output in STAT and, optionally, ASCII and NetCDF formats. The ASCII output duplicates the STAT output but has the data organized by line type. The output files are created based on the **-out** command line argument. The default output base name, **./tc_gen** writes output files in the current working directory named **tc_gen.stat** and, optionally, **tc_gen_pairs.nc** and **tc_gen_{TYPE}.txt** for each of the supported output line types. These output files can easily be redirected to another location using the **-out** command line option. The format of the STAT and ASCII output of the TC-Gen tool matches the output of other MET tools with the exception of the genesis matched pair line type. Please refer to the tables in :numref:`point_stat-output` for a description of the common output line types. The genesis matched pair line type and NetCDF output file are described below. diff --git a/met/docs/Users_Guide/tc-pairs.rst b/met/docs/Users_Guide/tc-pairs.rst index b32cbc15b1..3de6d0b470 100644 --- a/met/docs/Users_Guide/tc-pairs.rst +++ b/met/docs/Users_Guide/tc-pairs.rst @@ -1,22 +1,23 @@ .. _tc-pairs: +************* TC-Pairs Tool -============= +************* Introduction -____________ +============ The TC-Pairs tool provides verification for tropical cyclone forecasts in ATCF file format. It matches an ATCF format tropical cyclone (TC) forecast with a second ATCF format reference TC dataset (most commonly the Best Track analysis). The TC-Pairs tool processes both track and intensity adeck data and probabilistic edeck data. The adeck matched pairs contain position errors, as well as wind, sea level pressure, and distance to land values for each TC dataset. The edeck matched pairs contain probabilistic forecast values and the verifying observation values. The pair generation can be subset based on user-defined filtering criteria. Practical aspects of the TC-Pairs tool are described in :numref:`TC-Pairs_Practical-information`. .. _TC-Pairs_Practical-information: Practical information -_____________________ +===================== This section describes how to configure and run the TC-Pairs tool. The TC-Pairs tool is used to match a tropical cyclone model forecast to a corresponding reference dataset. Both tropical cyclone forecast/reference data must be in ATCF format. Output from the TC-dland tool (NetCDF gridded distance file) is also a required input for the TC-Pairs tool. It is recommended to run tc_pairs on a storm-by-storm basis, rather than over multiple storms or seasons to avoid memory issues. tc_pairs usage -~~~~~~~~~~~~~~ +-------------- The usage statement for tc_pairs is shown below: @@ -79,7 +80,7 @@ The TC-Pairs tool implements the following logic: • For each edeck/bdeck pair, write paired edeck probabilities and matching bdeck values to output PROBRIRW lines. tc_pairs configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--------------------------- The default configuration file for the TC-Pairs tool named **TCPairsConfig_default** can be found in the installed *share/met/config/* directory. Users are encouraged to copy these default files before modifying their contents. The contents of the configuration file are described in the subsections below. @@ -271,7 +272,7 @@ parameter will result in missed matches. .. _tc_pairs-output: tc_pairs output -~~~~~~~~~~~~~~~ +--------------- TC-Pairs produces output in TCST format. The default output file name can be overwritten using the -out file argument in the usage statement. The TCST file output from TC-Pairs may be used as input into the TC-Stat tool. The header column in the TC-Pairs output is described in :numref:`TCST Header`. diff --git a/met/docs/Users_Guide/tc-rmw.rst b/met/docs/Users_Guide/tc-rmw.rst index 852973b0f1..8e11d70798 100644 --- a/met/docs/Users_Guide/tc-rmw.rst +++ b/met/docs/Users_Guide/tc-rmw.rst @@ -1,18 +1,19 @@ .. _tc-rmw: +*********** TC-RMW Tool -=========== +*********** Introduction -____________ +============ The TC-RMW tool regrids tropical cyclone model data onto a moving range-azimuth grid centered on points along the storm track provided in ATCF format, most likely the adeck generated from the file. The radial grid spacing may be set as a factor of the radius of maximum winds (RMW). If wind fields are specified in the configuration file the radial and tangential wind components will be computed. Any regridding method available in MET can be used to interpolate data on the model output grid to the specified range-azimuth grid. The regridding will be done separately on each vertical level. The model data files must coincide with track points in a user provided ATCF formatted track file. Practical information -_____________________ +===================== tc_rmw usage -~~~~~~~~~~~~ +------------ The following sections describe the usage statement, required arguments, and optional arguments for tc_rmw. @@ -47,7 +48,7 @@ Optional arguments for tc_rmw 6. The **-v level** option indicates the desired level of verbosity. The contents of "level" will override the default setting of 2. Setting the verbosity to 0 will make the tool run with no log messages, while increasing the verbosity above 1 will increase the amount of logging. tc_rmw configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- The default configuration file for the TC-RMW tool named **TCRMWConfig_default** can be found in the installed *share/met/config/* directory. It is encouraged for users to copy these default files before modifying their contents. The contents of the configuration file are described in the subsections below. @@ -123,7 +124,7 @@ _______________________ The **rmw_scale** parameter overrides the **max_range_km** parameter. When this is set the radial grid spacing will be **rmw_scale** in units of the RMW, which varies along the storm track. tc_rmw output file -~~~~~~~~~~~~~~~~~~ +------------------ The NetCDF output file contains the following dimensions: diff --git a/met/docs/Users_Guide/tc-stat.rst b/met/docs/Users_Guide/tc-stat.rst index 7052e80958..6db00f3160 100644 --- a/met/docs/Users_Guide/tc-stat.rst +++ b/met/docs/Users_Guide/tc-stat.rst @@ -1,27 +1,28 @@ .. _tc-stat: +************ TC-Stat Tool -============ +************ Introduction -____________ +============ The TC-Stat tool ties together results from the TC-Pairs tool by providing summary statistics and filtering jobs on TCST output files. The TC-Stat tool requires TCST output from the TC-Pairs tool. See :numref:`tc_stat-output` of this user's guide for information on the TCST output format of the TC-Pairs tool. The TC-Stat tool supports several analysis job types. The **filter** job stratifies the TCST data using various conditions and thresholds described in :numref:`tc_stat-configuration-file`. The **summary** job produces summary statistics including frequency of superior performance, time-series independence calculations, and confidence intervals on the mean. The **rirw** job processes TCMPR lines, identifies adeck and bdeck rapid intensification or weakening events, populates a 2x2 contingency table, and derives contingency table statistics. The **probrirw job** processes PROBRIRW lines, populates an Nx2 probabilistic contingency table, and derives probabilistic statistics. The statistical aspects are described in :numref:`Statistical-aspects`, and practical use information for the TC-Stat tool is described in :numref:`Practical-information-1`. .. _Statistical-aspects: Statistical aspects -___________________ +=================== Filter TCST lines -~~~~~~~~~~~~~~~~~ +----------------- The TC-Stat tool can be used to simply filter specific lines of the TCST file based on user-defined filtering criteria. All of the TCST lines that are retained from one or more files are written out to a single output file. The output file is also in TCST format. Filtering options are outlined below in :numref:`tc_stat-configuration-file` (configuration file). If multiple filtering options are listed, the job will be performed on their intersection. Summary statistics for columns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ The TC-Stat tool can be used to produce summary information for a single column of data. After the user specifies the specific column of interest, and any other relevant search criteria, summary information is produced from values in that column of data. The summary statistics produced are listed in :numref:`table_columnar_output_summary_tc_stat`. @@ -52,14 +53,14 @@ Time-Series Independence The time-series independence evaluates effective forecast separation time using the Siegel method, by comparing the number of runs above and below the mean error to an expected value. This calculation expects the columns in the summary job to be a time series. The output includes the forecast hour interval and the number of hours to independence. Rapid Intensification/Weakening -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- The TC-Stat tool can be used to read TCMPR lines and compare the occurrence of rapid intensification (i.e. increase in intensity) or weakening (i.e. decrease in intensity) between the adeck and bdeck. The rapid intensification or weakening is defined by the change of maximum wind speed (i.e. **AMAX_WIND** and **BMAX_WIND** columns) over a specified amount of time. Accurately forecasting large changes in intensity is a challenging problem and this job helps quantify a model's ability to do so. Users may specify several job command options to configure the behavior of this job. Using these configurable options, the TC-Stat tool analyzes paired tracks and for each track point (i.e. each TCMPR line) determines whether rapid intensification or weakening occurred. For each point in time, it uses the forecast and BEST track event occurrence to populate a 2x2 contingency table. The job may be configured to require that forecast and BEST track events occur at exactly the same time to be considered a hit. Alternatively, the job may be configured to define a hit as long as the forecast and BEST track events occurred within a configurable time window. Using this relaxed matching criteria false alarms may be considered hits and misses may be considered correct negatives as long as the adeck and bdeck events were close enough in time. Each rirw job applies a single intensity change threshold. Therefore, assessing a model's performance with rapid intensification and weakening requires that two separate jobs be run. Probability of Rapid Intensification -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------ The TC-Stat tool can be used to accumulate multiple PROBRIRW lines and derive probabilistic statistics summarizing performance. The PROBRIRW line contains a probabilistic forecast for a specified intensity change along with the actual intensity change that occurred in the BEST track. Accurately forecasting the likelihood of large changes in intensity is a challenging problem and this job helps quantify a model's ability to do so. @@ -68,12 +69,12 @@ Users may specify several job command options to configure the behavior of this .. _Practical-information-1: Practical information -_____________________ +===================== The following sections describe the usage statement, required arguments, and optional arguments for tc_stat. tc_stat usage -~~~~~~~~~~~~~ +------------- The usage statement for tc_stat is shown below: @@ -370,7 +371,7 @@ _________________________ .. _tc_stat-output: tc_stat output -~~~~~~~~~~~~~~ +-------------- The output generated from the TC-Stat tool contains statistics produced by the analysis. Additionally, it includes information about the analysis job that produced the output for each line. The output can be redirected to an output file using the **-out** option. The format of output from each tc_stat job command is listed below. diff --git a/met/docs/Users_Guide/wavelet-stat.rst b/met/docs/Users_Guide/wavelet-stat.rst index 2b9a39291b..15d68616e5 100644 --- a/met/docs/Users_Guide/wavelet-stat.rst +++ b/met/docs/Users_Guide/wavelet-stat.rst @@ -1,12 +1,13 @@ .. _wavelet-stat: +***************** Wavelet-Stat Tool -================= +***************** .. _WS_Introduction: Introduction -____________ +============ The Wavelet-Stat tool decomposes two-dimensional forecasts and observations according to intensity and scale. This section describes the Wavelet-Stat tool, which enables users to apply the Intensity-Scale verification technique described by :ref:`Casati et al. (2004) `. @@ -21,10 +22,10 @@ The spatial scale components are obtained usually by applying a single band spat The Intensity-Scale technique evaluates the forecast skill as a function of the intensity values and of the spatial scale of the error. The scale components are obtained by applying a two dimensional Haar wavelet filter. Note that wavelets, because of their locality, are suitable for representing discontinuous fields characterized by few sparse non-zero features, such as precipitation. Moreover, the technique is based on a categorical approach, which is a robust and resistant approach, suitable for non-normally distributed variables, such as precipitation. The intensity-scale technique was specifically designed to cope with the difficult characteristics of precipitation fields, and for the verification of spatial precipitation forecasts. However, the intensity-scale technique can also be applied to verify other variables, such as cloud fraction. Scientific and statistical aspects -__________________________________ +================================== The method -~~~~~~~~~~ +---------- :ref:`Casati et al. (2004) ` applied the Intensity-Scale verification to preprocessed and re-calibrated (unbiased) data. The preprocessing was aimed to mainly normalize the data, and defined categorical thresholds so that each categorical bin had a similar sample size. The recalibration was performed to eliminate the forecast bias. Preprocessing and recalibration are not strictly necessary for the application of the Intensity-Scale technique. The MET Intensity-Scale Tool does not perform either, and applies the Intensity-Scale approach to biased forecasts, for categorical thresholds defined by the user. @@ -126,7 +127,7 @@ Note that the energy squared of the observation binary field is identical to the The spatial domain constraints -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ The Intensity-Scale technique is constrained by the fact that orthogonal wavelets (discrete wavelet transforms) are usually performed dyadic domains, square domains of :math:`\mathbf{2^n} **x** :math:`\mathbf{2^n} grid-points. The Wavelet-Stat tool handles this issue based on settings in the configuration file by defining tiles of dimensions :math:`\mathbf{2^n} **x** :math:`\mathbf{2^n} over the input domain in the following ways: @@ -137,19 +138,19 @@ The Intensity-Scale technique is constrained by the fact that orthogonal wavelet 3. Padding: If the domain size is only slightly smaller than :math:`\mathbf{2^n} **x** :math:`\mathbf{2^n}, for certain variables (e.g. precipitation), it is advisable to expand the domain out to :math:`\mathbf{2^n} **x** :math:`\mathbf{2^n} grid-points by adding extra rows and/or columns of fill data. For precipitation variables, a fill value of zero is used. For continuous variables, such as temperature, the fill value is defined as the mean of the valid data in the rest of the field. A drawback to the padding method is the introduction of artificial data into the original field. Padding should only be used when a very small number of rows and/or columns need to be added. Aggregation of statistics on multiple cases -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------------------- The Stat-Analysis tool aggregates the intensity scale technique results. Since the results are scale-dependent, it is sensible to aggregate results from multiple model runs (e.g. daily runs for a season) on the same spatial domain, so that the scale components for each singular case will be the same number, and the domain, if not a square domain of :math:`\mathbf{2^n} **x** :math:`\mathbf{2^n} grid-points, will be treated in the same fashion. Similarly, the intensity thresholds for each run should all be the same. The MSE and forecast and observation squared energy for each scale and thresholds are aggregated simply with a weighted average, where weights are proportional to the number of grid-points used in each single run to evaluate the statistics. If the same domain is always used (and it should) the weights result all the same, and the weighted averaging is a simple mean. For each threshold, the aggregated Br is equal to the aggregated squared energy of the binary observation field, and the aggregated FBI is obtained as the ratio of the aggregated squared energies of the forecast and observation binary fields. From aggregated Br and FBI, the MSErandom for the aggregated runs can be evaluated using the same formula as for the single run. Finally, the Intensity-Scale Skill Score is evaluated by using the aggregated statistics within the same formula used for the single case. Practical information -_____________________ +===================== The following sections describe the usage statement, required arguments and optional arguments for the Stat-Analysis tool. wavelet_stat usage -~~~~~~~~~~~~~~~~~~ +------------------ The usage statement for the Wavelet-Stat tool is shown below: @@ -200,7 +201,7 @@ In the example, the Wavelet-Stat tool will verify the model data in the **sample .. _wavelet_stat-configuration-file: wavelet_stat configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- The default configuration file for the Wavelet-Stat tool, **WaveletStatConfig_default**, can be found in the installed *share/met/config* directory. Another version of the configuration file is provided in *scripts/config*. We recommend that users make a copy of the default (or other) configuration file prior to modifying it. The contents are described in more detail below. Note that environment variables may be used when editing configuration files, as described in the :numref:`pb2nc configuration file` for the PB2NC tool. @@ -311,7 +312,7 @@ The nc_pairs_flag is described in :numref:`grid_stat-configuration-file` .. _wavelet_stat-output: wavelet_stat output -~~~~~~~~~~~~~~~~~~~ +------------------- wavelet_stat produces output in STAT and, optionally, ASCII and NetCDF and PostScript formats. The ASCII output duplicates the STAT output but has the data organized by line type. While the Wavelet-Stat tool currently only outputs one STAT line type, additional line types may be added in future releases. The output files are written to the default output directory or the directory specified by the -outdir command line option. From f4e1f7f79910425b0f8b95f92b3be5b6d5569da5 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 21:12:17 -0700 Subject: [PATCH 109/172] #2044 parse_conf_obs_bufr_map is moved to pb2nc_conf_info.c --- met/src/basic/vx_config/config_util.cc | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index 1b655034ac..c466a9f2de 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -24,7 +24,7 @@ using namespace std; /////////////////////////////////////////////////////////////////////////////// static const double default_vld_thresh = 1.0; -static const char conf_key_prepbufr_map_typo[] = "obs_prefbufr_map"; // for backward compatibility +static const char conf_key_prepbufr_map_bad[] = "obs_prefbufr_map"; // for backward compatibility /////////////////////////////////////////////////////////////////////////////// @@ -1089,20 +1089,6 @@ map parse_conf_metadata_map(Dictionary *dict) { /////////////////////////////////////////////////////////////////////////////// -map parse_conf_obs_bufr_map(Dictionary *dict) { - map m = parse_conf_key_value_map(dict, conf_key_obs_prepbufr_map); - if (m.empty()) { - //kludge: there was a typo in the config name - m = parse_conf_key_value_map(dict, conf_key_prepbufr_map_typo); - mlog << Warning << "\nPlease rename the configuration name \"" << conf_key_prepbufr_map_typo - << "\" to \"" << conf_key_obs_prepbufr_map << "\" at the customized PB2NC config file\n\n"; - } - parse_add_conf_key_value_map(dict, conf_key_obs_bufr_map, &m); - return m; -} - -/////////////////////////////////////////////////////////////////////////////// - map parse_conf_obs_name_map(Dictionary *dict) { const char *method_name = "parse_conf_obs_name_map() -> "; return parse_conf_key_value_map(dict, conf_key_obs_name_map); From 3b88ab184a943545ee31c921b180253c78aa2d80 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 21:12:36 -0700 Subject: [PATCH 110/172] #2044 parse_conf_obs_bufr_map is moved to pb2nc_conf_info.c --- met/src/basic/vx_config/config_util.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/met/src/basic/vx_config/config_util.h b/met/src/basic/vx_config/config_util.h index f9750e0212..5afcc974a1 100644 --- a/met/src/basic/vx_config/config_util.h +++ b/met/src/basic/vx_config/config_util.h @@ -25,6 +25,10 @@ //////////////////////////////////////////////////////////////////////// +static const char conf_key_old_prepbufr_map[] = "obs_prefbufr_map"; // for backward compatibility + +//////////////////////////////////////////////////////////////////////// + extern ConcatString parse_conf_version(Dictionary *dict); extern ConcatString parse_conf_string(Dictionary *dict, const char *, bool check_empty = true); extern GrdFileType parse_conf_file_type(Dictionary *dict); @@ -48,13 +52,13 @@ extern ClimoCDFInfo parse_conf_climo_cdf(Dictionary *dict); extern TimeSummaryInfo parse_conf_time_summary(Dictionary *dict); extern map parse_conf_key_value_map( Dictionary *dict, const char *conf_key_map_name, const char *caller=0); +extern void parse_add_conf_key_value_map( + Dictionary *dict, const char *conf_key_map_name, map *m); extern map parse_conf_message_type_map(Dictionary *dict); extern map parse_conf_message_type_group_map(Dictionary *dict); extern map parse_conf_metadata_map(Dictionary *dict); -extern map - parse_conf_obs_bufr_map(Dictionary *dict); extern map parse_conf_obs_name_map(Dictionary *dict); extern BootInfo parse_conf_boot(Dictionary *dict); From 4020d3525dc0d31e8746869c3f9a7add06eb0cea Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 21:14:41 -0700 Subject: [PATCH 111/172] #2044 Changed debiug level for PBL --- met/src/tools/other/pb2nc/pb2nc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index 7df4d754eb..cff540d107 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -3057,7 +3057,7 @@ float compute_pbl(map pqtzuv_map_tq, pbl_data_hgt[index] = pqtzuv[3]; pbl_data_ugrd[index] = pqtzuv[4]; pbl_data_vgrd[index] = pqtzuv[5]; - mlog << Debug(5) << method_name << "Force to add " + mlog << Debug(6) << method_name << "Force to add " << pres_level << " into " << index << "\n"; index--; } @@ -3077,11 +3077,11 @@ float compute_pbl(map pqtzuv_map_tq, if (hgt_cnt < pbl_level) { hgt_cnt += interpolate_by_pressure(pbl_level, pbl_data_pres, pbl_data_hgt); - mlog << Debug(4) << method_name << "interpolate Z (HGT)\n"; + mlog << Debug(6) << method_name << "interpolate Z (HGT)\n"; } if (spfh_cnt < pbl_level) { spfh_cnt += interpolate_by_pressure(pbl_level, pbl_data_pres, pbl_data_spfh); - mlog << Debug(4) << method_name << "interpolate Q (SPFH)\n"; + mlog << Debug(6) << method_name << "interpolate Q (SPFH)\n"; } if ((spfh_cnt>0) && (pbl_level>0)) { From 42aad8af444a6aec2d30c0fcf536e3ffd8c1e6ee Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 10 Feb 2022 21:17:01 -0700 Subject: [PATCH 112/172] #2044 ci-run-unit Give warning if bad connfig key is used --- met/src/tools/other/pb2nc/pb2nc_conf_info.cc | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/met/src/tools/other/pb2nc/pb2nc_conf_info.cc b/met/src/tools/other/pb2nc/pb2nc_conf_info.cc index d940939072..3c3a53c74a 100644 --- a/met/src/tools/other/pb2nc/pb2nc_conf_info.cc +++ b/met/src/tools/other/pb2nc/pb2nc_conf_info.cc @@ -25,6 +25,18 @@ using namespace std; #include "grib_strings.h" #include "vx_log.h" + +//////////////////////////////////////////////////////////////////////// + +map parse_conf_obs_bufr_map(Dictionary *dict) { + + const char *key_name = (0 != dict->lookup_array(conf_key_obs_prepbufr_map, false, false)) + ? conf_key_obs_prepbufr_map : conf_key_old_prepbufr_map; + map m = parse_conf_key_value_map(dict, (const char *)key_name); + parse_add_conf_key_value_map(dict, conf_key_obs_bufr_map, &m); + return m; +} + //////////////////////////////////////////////////////////////////////// // // Code for class PB2NCConfInfo @@ -85,14 +97,42 @@ void PB2NCConfInfo::clear() { void PB2NCConfInfo::read_config(const char *default_file_name, const char *user_file_name) { + int warning_code = 0; + bool use_bad_one = true; + string bad_file_names; + // Read the config file constants conf.read(replace_path(config_const_filename).c_str()); // Read the default config file conf.read(default_file_name); + if (0 != conf.lookup_array(conf_key_old_prepbufr_map, false, false)) { + warning_code = 1; + bad_file_names = default_file_name; + if (0 != conf.lookup_array(conf_key_obs_prepbufr_map, false, false)) use_bad_one = false; + } // Read the user-specified config file conf.read(user_file_name); + if (0 != conf.lookup_array(conf_key_old_prepbufr_map, false, false)) { + warning_code = 2; + if (0 < bad_file_names.length()) bad_file_names += " and "; + bad_file_names += user_file_name; + if (0 != conf.lookup_array(conf_key_obs_prepbufr_map, false, false)) use_bad_one = false; + } + + if (0 < warning_code) { + string ignored_message = " "; + + if (!use_bad_one) { + ignored_message = " (Ignored \""; + ignored_message += conf_key_old_prepbufr_map; + ignored_message += "\" key)"; + } + mlog << Warning << "\nPlease rename the configuration key \"" + << conf_key_old_prepbufr_map << "\" to \"" << conf_key_obs_prepbufr_map + << "\" at " << bad_file_names << ignored_message << "\n\n"; + } return; } From ceacf2a2370e1a9e07bc4f6bb4787a5278c325e8 Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Fri, 11 Feb 2022 11:44:53 -0700 Subject: [PATCH 113/172] Update met_stats.cc #2047 Removed the debug message --- met/src/libcode/vx_statistics/met_stats.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 90bbcde460..955e7988d8 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1570,12 +1570,6 @@ void VL1L2Info::calc_ncep_stats() { DIR_ABSERR = fabs(DIR_ERR); - char buffer[1024]; - int buf_len = sprintf(buffer, "DIR_ERR=%25.18e from uf_bar=%25.18e, vf_bar=%25.18e, uo_bar=%25.18e, vo_bar=%25.18e", - DIR_ERR, uf_bar, vf_bar, uo_bar, vo_bar); - if (buf_len > 0) mlog << Debug(9) << method_name << buffer<< "\n"; - else mlog << Warning << "\n" << method_name << "Please increase buffer for sprintf\n\n"; - return; } From 5437e5f8a63ec1cad25306309a5f4cef5a1efd53 Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 11 Feb 2022 11:52:55 -0700 Subject: [PATCH 114/172] Update met_stats.cc Removing variable that was set but never used because SonarQube might complain about that, like Fortify does. --- met/src/libcode/vx_statistics/met_stats.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 955e7988d8..a5eae44574 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1534,7 +1534,6 @@ void VL1L2Info::assign(const VL1L2Info &c) { void VL1L2Info::calc_ncep_stats() { double u_diff, v_diff; int n = vcount; - const char *method_name = "VL1L2Info::calc_ncep_stats() -> "; u_diff = uf_bar - uo_bar; v_diff = vf_bar - vo_bar; From 67b484c1f01b12845606d0156af0c6a247b89bfd Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 11 Feb 2022 15:45:57 -0700 Subject: [PATCH 115/172] Feature 2040 parse timing (#2048) Co-authored-by: Julie Prestopnik --- .../libcode/vx_data2d_nc_met/data2d_nc_met.cc | 23 ++++++------- .../libcode/vx_data2d_nc_met/data2d_nc_met.h | 2 -- met/src/libcode/vx_data2d_nc_met/met_file.cc | 32 +++---------------- met/src/libcode/vx_data2d_nc_met/met_file.h | 12 ------- met/src/libcode/vx_nc_util/nc_var_info.cc | 27 +++++++++++++++- met/src/libcode/vx_nc_util/nc_var_info.h | 6 ++++ 6 files changed, 49 insertions(+), 53 deletions(-) diff --git a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc index 0bbb55c718..23c038e5d1 100644 --- a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc +++ b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.cc @@ -121,10 +121,7 @@ void MetNcMetDataFile::dump(ostream & out, int depth) const { //////////////////////////////////////////////////////////////////////// -bool MetNcMetDataFile::data_plane(VarInfo &vinfo, DataPlane &plane) - -{ - +bool MetNcMetDataFile::data_plane(VarInfo &vinfo, DataPlane &plane) { bool status = false; ConcatString req_time_str, data_time_str; VarInfoNcMet * vinfo_nc = (VarInfoNcMet *) &vinfo; @@ -221,14 +218,18 @@ int MetNcMetDataFile::data_plane_array(VarInfo &vinfo, //////////////////////////////////////////////////////////////////////// -int MetNcMetDataFile::index(VarInfo &vinfo){ +int MetNcMetDataFile::index(VarInfo &vinfo) { + + NcVarInfo *ncinfo = MetNc->find_var_name( vinfo.name().c_str() ); - if( NULL == MetNc->find_var_name( vinfo.name().c_str() ) ) return -1; + if( !ncinfo ) return(-1); - if( ( vinfo.valid() && MetNc->ValidTime != vinfo.valid() ) || - ( vinfo.init() && MetNc->InitTime != vinfo.init() ) || - ( !is_bad_data(vinfo.lead()) && MetNc->lead_time() != vinfo.lead() ) ) - return -1; + if( ( vinfo.valid() != 0 && ncinfo->ValidTime != vinfo.valid() ) || + ( vinfo.init() != 0 && ncinfo->InitTime != vinfo.init() ) || + ( !is_bad_data(vinfo.lead()) && ncinfo->lead_time() != vinfo.lead() ) ) + return(-1); - return 0; + return(0); } + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h index 0153d16467..eb72f67605 100644 --- a/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h +++ b/met/src/libcode/vx_data2d_nc_met/data2d_nc_met.h @@ -50,7 +50,6 @@ class MetNcMetDataFile : public Met2dDataFile { MetNcFile * MetNc; // allocated - // // set stuff // @@ -73,7 +72,6 @@ class MetNcMetDataFile : public Met2dDataFile { int index(VarInfo &); - // // do stuff // diff --git a/met/src/libcode/vx_data2d_nc_met/met_file.cc b/met/src/libcode/vx_data2d_nc_met/met_file.cc index 8abf239884..dd8f599c48 100644 --- a/met/src/libcode/vx_data2d_nc_met/met_file.cc +++ b/met/src/libcode/vx_data2d_nc_met/met_file.cc @@ -201,9 +201,6 @@ Nvars = 0; if ( Var ) { delete [] Var; Var = (NcVarInfo *) 0; } -ValidTime = (unixtime) 0; -InitTime = (unixtime) 0; - // // done // @@ -298,9 +295,8 @@ for (j=0; jvar, a, plane); // store the times // -plane.set_init ( ValidTime - lead_time() ); -plane.set_valid ( ValidTime ); -plane.set_lead ( lead_time() ); +plane.set_init ( info->InitTime ); +plane.set_valid ( info->ValidTime ); +plane.set_lead ( info->lead_time() ); plane.set_accum ( info->AccumTime ); // diff --git a/met/src/libcode/vx_data2d_nc_met/met_file.h b/met/src/libcode/vx_data2d_nc_met/met_file.h index 513cb0c49f..8510aa3159 100644 --- a/met/src/libcode/vx_data2d_nc_met/met_file.h +++ b/met/src/libcode/vx_data2d_nc_met/met_file.h @@ -59,20 +59,8 @@ class MetNcFile { void dump(ostream &, int = 0) const; - NcFile * Nc; // allocated - // - // time - // - - unixtime ValidTime; - - unixtime InitTime; - - int lead_time () const; // seconds - - // // dimensions // diff --git a/met/src/libcode/vx_nc_util/nc_var_info.cc b/met/src/libcode/vx_nc_util/nc_var_info.cc index b8acf6228f..d41d7c8762 100644 --- a/met/src/libcode/vx_nc_util/nc_var_info.cc +++ b/met/src/libcode/vx_nc_util/nc_var_info.cc @@ -58,7 +58,7 @@ unixtime get_att_value_unixtime(const NcAtt *att) { // - // Code for class NcNcVarInfo + // Code for class NcVarInfo // @@ -151,6 +151,10 @@ level_att.clear(); units_att.clear(); +ValidTime = (unixtime) 0; + +InitTime = (unixtime) 0; + AccumTime = 0; Ndims = 0; @@ -199,6 +203,12 @@ else out << "(nul)"; if ( units_att.length() > 0 ) out << '\"' << units_att << '\"'; else out << "(nul)"; +out << prefix << "ValidTime = " << unix_to_yyyymmdd_hhmmss(ValidTime) + << " (" << ValidTime << ")\n"; + +out << prefix << "InitTime = " << unix_to_yyyymmdd_hhmmss(InitTime) + << " (" << InitTime << ")\n"; + out << prefix << "AccumTime = " << AccumTime; out << "\n"; @@ -232,6 +242,17 @@ return; } +//////////////////////////////////////////////////////////////////////// + + +int NcVarInfo::lead_time() const + +{ + +return ( (int) (ValidTime - InitTime) ); + +} + //////////////////////////////////////////////////////////////////////// @@ -254,6 +275,10 @@ level_att = i.level_att; units_att = i.units_att; +ValidTime = i.ValidTime; + +InitTime = i.InitTime; + AccumTime = i.AccumTime; Ndims = i.Ndims; diff --git a/met/src/libcode/vx_nc_util/nc_var_info.h b/met/src/libcode/vx_nc_util/nc_var_info.h index ba86dcd011..594677734b 100644 --- a/met/src/libcode/vx_nc_util/nc_var_info.h +++ b/met/src/libcode/vx_nc_util/nc_var_info.h @@ -63,8 +63,14 @@ class NcVarInfo { ConcatString units_att; + unixtime ValidTime; + + unixtime InitTime; + int AccumTime; // seconds + int lead_time () const; // seconds + int Ndims; NcDim ** Dims; // allocated From 1d56b26067a3f3c962f57265fbdbc7290a145897 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 11 Feb 2022 16:15:52 -0700 Subject: [PATCH 116/172] CI: Add logic to auto update input data (#2046) --- .github/workflows/testing.yml | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index e07673b21b..61f2c43840 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -88,10 +88,26 @@ jobs: path: ${{ runner.workspace }}/logs if-no-files-found: ignore + update_input_data: + name: Update input data volumes + runs-on: ubuntu-latest + needs: [job_control] + if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} + steps: + - uses: dtcenter/metplus-action-data-update@v1 + with: + docker_name: ${{ secrets.DOCKER_USERNAME }} + docker_pass: ${{ secrets.DOCKER_PASSWORD }} + repo_name: ${{ github.repository }} + data_prefix: unit_test + branch_name: ${{ needs.job_control.outputs.branch_name }} + docker_data_dir: /data/input/MET_test_data + data_repo_dev: met-data-dev + unit_1a: name: Unit 1a runs-on: ubuntu-latest - needs: [job_control, compile] + needs: [job_control, update_input_data, compile] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} strategy: matrix: @@ -107,7 +123,7 @@ jobs: env: SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} TESTS: ${{ matrix.tests }} - INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact uses: actions/upload-artifact@v2 @@ -126,7 +142,7 @@ jobs: unit_1b: name: Unit 1b runs-on: ubuntu-latest - needs: [job_control, compile] + needs: [job_control, update_input_data, compile] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} strategy: matrix: @@ -142,7 +158,7 @@ jobs: env: SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} TESTS: ${{ matrix.tests }} - INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact uses: actions/upload-artifact@v2 @@ -161,7 +177,7 @@ jobs: unit_rc_leads: name: Unit RC leads runs-on: ubuntu-latest - needs: [job_control, compile] + needs: [job_control, update_input_data, compile] if: ${{ needs.job_control.outputs.run_unit_tests == 'true' }} strategy: matrix: @@ -178,7 +194,7 @@ jobs: env: SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} TESTS: ${{ matrix.tests }} - INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact uses: actions/upload-artifact@v2 @@ -261,7 +277,7 @@ jobs: env: SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} TESTS: ${{ matrix.tests }} - INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact uses: actions/upload-artifact@v2 @@ -304,7 +320,7 @@ jobs: env: SOURCE_BRANCH: ${{ needs.job_control.outputs.branch_name }} TESTS: ${{ matrix.tests }} - INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }} + INPUT_DATA_VERSION: ${{ needs.job_control.outputs.input_data_version }}-all - name: Upload output as artifact uses: actions/upload-artifact@v2 From 39a50c1393134f58bda6cab44ca7ca539b7eda2f Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 11 Feb 2022 16:16:34 -0700 Subject: [PATCH 117/172] Bugfix 2045 develop hira (#2049) --- met/src/tools/core/point_stat/point_stat.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 0bf1b5fe0c..edc3c02f1a 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -99,6 +99,7 @@ // 048 09/13/21 Seth Linden Changed obs_qty to obs_qty_inc. // Added code for obs_qty_exc. // 049 12/11/21 Halley Gotway MET #1991 Fix VCNT output. +// 050 02/11/22 Halley Gotway MET #2045 Fix HiRA output. // //////////////////////////////////////////////////////////////////////// @@ -1797,11 +1798,13 @@ void do_hira_ens(int i_vx, const PairDataPoint *pd_ptr) { continue; } + // Compute the pair values + hira_pd.compute_pair_vals(rng_ptr); + // Write out the ECNT line if(conf_info.vx_opt[i_vx].output_flag[i_ecnt] != STATOutputType_None) { // Compute ensemble statistics - hira_pd.compute_pair_vals(rng_ptr); ECNTInfo ecnt_info; ecnt_info.set(hira_pd); @@ -1814,9 +1817,6 @@ void do_hira_ens(int i_vx, const PairDataPoint *pd_ptr) { // Write out the ORANK line if(conf_info.vx_opt[i_vx].output_flag[i_orank] != STATOutputType_None) { - // Compute ensemble statistics - hira_pd.compute_pair_vals(rng_ptr); - write_orank_row(shc, &hira_pd, conf_info.vx_opt[i_vx].output_flag[i_orank], stat_at, i_stat_row, From ce3582d5cd225f7030bb8f456e8f29edbe3a4ab9 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Fri, 11 Feb 2022 16:31:39 -0700 Subject: [PATCH 118/172] #2044 ci-run-test merge again --- met/docs/Users_Guide/config_options.rst | 477 ++++++++++-------------- 1 file changed, 193 insertions(+), 284 deletions(-) diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index 8fcff91730..627415ffec 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -1,8 +1,8 @@ .. _config_options: - +*************************** Configuration File Overview -=========================== +*************************** The configuration files that control many of the MET tools contain formatted ASCII text. This format has been updated for MET version |version| and @@ -392,9 +392,8 @@ into any relevant scripting. Settings common to multiple tools --------------------------------- -.. _exit_on_warning: - -:ref:`exit_on_warning ` +exit_on_warning +^^^^^^^^^^^^^^^ The "exit_on_warning" entry in ConfigConstants may be set to true or false. If set to true and a MET tool encounters a warning, it will immediately exit @@ -404,9 +403,8 @@ with bad status after writing the warning message. exit_on_warning = FALSE; -.. _nc_compression: - -:ref:`nc_compression ` +nc_compression +^^^^^^^^^^^^^^ The "nc_compression" entry in ConfigConstants defines the compression level for the NetCDF variables. Setting this option in the config file of one of @@ -427,9 +425,8 @@ writing of NetCDF files within MET significantly. nc_compression = 0; -.. _output_precision: - -:ref:`output_precision ` +output_precision +^^^^^^^^^^^^^^^^ The "output_precision" entry in ConfigConstants defines the precision (number of significant decimal places) to be written to the ASCII output @@ -440,9 +437,8 @@ override the default value set in ConfigConstants. output_precision = 5; -.. _tmp_dir_1: - -:ref:`tmp_dir ` +tmp_dir_1 +^^^^^^^^^ The "tmp_dir" entry in ConfigConstants defines the directory for the temporary files. The directory must exist and be writable. The environment @@ -454,9 +450,8 @@ Some tools override the temporary directory by the command line argument tmp_dir = "/tmp"; -.. _message_type_group_map_1: - -:ref:`message_type_group_map ` +message_type_group_map_1 +^^^^^^^^^^^^^^^^^^^^^^^^ The "message_type_group_map" entry is an array of dictionaries, each containing a "key" string and "val" string. This defines a mapping of @@ -475,9 +470,8 @@ which surface verification logic should be applied. { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } ]; -.. _message_type_map: - -:ref:`message_type_map ` +message_type_map +^^^^^^^^^^^^^^^^ The "message_type_map" entry is an array of dictionaries, each containing a "key" string and "val" string. This defines a mapping of input strings @@ -500,9 +494,8 @@ types. { key = "FM-97 ACARS"; val = "AIRCFT"; } ]; -.. _model: - -:ref:`model ` +model +^^^^^ The "model" entry specifies a name for the model being verified. This name is written to the MODEL column of the ASCII output generated. If you're @@ -514,9 +507,8 @@ e.g. model = "GFS"; model = "WRF"; -.. _desc: - -:ref:`desc ` +desc +^^^^ The "desc" entry specifies a user-specified description for each verification task. This string is written to the DESC column of the ASCII output @@ -531,9 +523,8 @@ e.g. desc = "QC_9"; desc = "NA"; -.. _obtype: - -:ref:`obtype ` +obtype +^^^^^^ The "obtype" entry specifies a name to describe the type of verifying gridded observation used. This name is written to the OBTYPE column in the ASCII @@ -548,8 +539,9 @@ the configuration file obtype value is written. obtype = "ANALYS"; .. _regrid: - -:ref:`regrid ` + +regrid +^^^^^^ The "regrid" entry is a dictionary containing information about how to handle input gridded data files. The "regrid" entry specifies regridding logic @@ -569,7 +561,8 @@ using the following entries: * to_grid = "path"; To regrid both to a grid defined by a file. - * to_grid = "spec"; To define a grid specification string, as described in :ref:`appendixB`. + * to_grid = "spec"; To define a grid specification string, as + described in :ref:`appendixB`. * The "vld_thresh" entry specifies a proportion between 0 and 1 to define the required ratio of valid data points. When regridding, compute @@ -656,9 +649,8 @@ using the following entries: censor_val = []; } -.. _fcst: - -:ref:`fcst ` +fcst +^^^^ The "fcst" entry is a dictionary containing information about the field(s) to be verified. This dictionary may include the following entries: @@ -1085,9 +1077,8 @@ File-format specific settings for the "field" entry: ]; } -.. _obs: - -:ref:`obs ` +obs +^^^ The "obs" entry specifies the same type of information as "fcst", but for the observation data. It will often be set to the same things as "fcst", @@ -1210,9 +1201,8 @@ or obs = fcst; -.. _climo_mean: - -:ref:`climo_mean ` +climo_mean +^^^^^^^^^^ The "climo_mean" dictionary specifies climatology mean data to be read by the Grid-Stat, Point-Stat, Ensemble-Stat, and Series-Analysis tools. It consists @@ -1268,9 +1258,8 @@ of several entires defining the climatology file names and fields to be used. hour_interval = 6; } -.. _climo_stdev: - -:ref:`climo_stdev ` +climo_stdev +^^^^^^^^^^^ The "climo_stdev" dictionary specifies climatology standard deviation data to be read by the Grid-Stat, Point-Stat, Ensemble-Stat, and Series-Analysis @@ -1300,9 +1289,8 @@ over the "climo_mean" setting and then updating the "file_name" entry. file_name = [ "/path/to/climatological/standard/deviation/files" ]; } -.. _climo_cdf: - -:ref:`climo_cdf ` +climo_cdf +^^^^^^^^^ The "climo_cdf" dictionary specifies how the the climatological mean ("climo_mean") and standard deviation ("climo_stdev") data are used to @@ -1368,9 +1356,8 @@ all pairs into a single climatological bin. direct_prob = FALSE; or TRUE } -.. _climato_data: - -:ref:`climatology data for probability forecasts ` +climato_data +^^^^^^^^^^^^ When specifying climatology data for probability forecasts, either supply a probabilistic "climo_mean" field or non-probabilistic "climo_mean" and @@ -1397,9 +1384,8 @@ In this way, the number of bins impacts the resolution of the climatological probabilities. These derived probability values are used to compute the climatological Brier Score and Brier Skill Score. -.. _mask_missing_flag: - -:ref:`mask_missing_flag ` +mask_missing_flag +^^^^^^^^^^^^^^^^^ The "mask_missing_flag" entry specifies how missing data should be handled in the Wavelet-Stat and MODE tools: @@ -1417,9 +1403,8 @@ in the Wavelet-Stat and MODE tools: mask_missing_flag = BOTH; -.. _obs_window: - -:ref:`obs_window ` +obs_window +^^^^^^^^^^ The "obs_window" entry is a dictionary specifying a beginning ("beg" entry) and ending ("end" entry) time offset values in seconds. It defines @@ -1435,9 +1420,8 @@ Point-Stat and Ensemble-Stat, the reference time is the forecast valid time. end = 5400; } -.. _mask: - -:ref:`mask ` +mask +^^^^ The "mask" entry is a dictionary that specifies the verification masking regions to be used when computing statistics. Each mask defines a @@ -1547,9 +1531,8 @@ is included in the mask. } -.. _ci_alpha: - -:ref:`ci_alpha ` +ci_alpha +^^^^^^^^ The "ci_alpha" entry is an array of floats specifying the values for alpha to be used when computing confidence intervals. Values of alpha must be @@ -1561,9 +1544,8 @@ interval. ci_alpha = [ 0.05, 0.10 ]; -.. _boot: - -:ref:`boot ` +boot +^^^^ The "boot" entry defines the parameters to be used in calculation of bootstrap confidence intervals. The interval variable indicates what method @@ -1625,9 +1607,8 @@ should be used for computing bootstrap confidence intervals: seed = ""; } -.. _interp: - -:ref:`interp ` +interp +^^^^^^ The "interp" entry is a dictionary that specifies what interpolation or smoothing (for the Grid-Stat tool) methods should be applied. @@ -1730,9 +1711,8 @@ This dictionary may include the following entries: ]; } -.. _land_mask: - -:ref:`land_mask ` +land_mask +^^^^^^^^^ The "land_mask" dictionary defines the land/sea mask field which is used when verifying at the surface. For point observations whose message type @@ -1759,9 +1739,8 @@ land_mask.flag may be set separately in each "obs.field" entry. thresh = eq1; } -.. _topo_mask: - -:ref:`topo_mask ` +topo_mask +^^^^^^^^^ The "topo_mask" dictionary defines the model topography field which is used when verifying at the surface. This logic is applied to point observations @@ -1790,9 +1769,8 @@ topo_mask.flag may be set separately in each "obs.field" entry. interp_fcst_thresh = ge-50&&le50; } -.. _hira: - -:ref:`hira ` +hira +^^^^ The "hira" entry is a dictionary that is very similar to the "interp" and "nbrhd" entries. It specifies information for applying the High Resolution @@ -1844,9 +1822,8 @@ This dictionary may include the following entries: prob_cat_thresh = []; } -.. _output_flag: - -:ref:`output_flag ` +output_flag +^^^^^^^^^^^ The "output_flag" entry is a dictionary that specifies what verification methods should be applied to the input data. Options exist for each @@ -1896,9 +1873,8 @@ output line type from the MET tools. Each line type may be set to one of: grad = NONE; Gradient statistics (S1 score) } -.. _nc_pairs_flag: - -:ref:`nc_pairs_flag ` +nc_pairs_flag +^^^^^^^^^^^^^ The "nc_pairs_flag" can be set either to a boolean value or a dictionary in either Grid-Stat, Wavelet-Stat or MODE. The dictionary (with slightly @@ -1928,9 +1904,8 @@ netcdf output will be generated. apply_mask = TRUE; } -.. _nc_pairs_var_name: - -:ref:`nc_pairs_var_name ` +nc_pairs_var_name +^^^^^^^^^^^^^^^^^ The "nc_pairs_var_name" entry specifies a string for each verification task in Grid-Stat. This string is parsed from each "obs.field" dictionary entry @@ -1949,9 +1924,8 @@ For example: nc_pairs_var_name = ""; -.. _nc_pairs_var_suffix: - -:ref:`nc_pairs_var_suffix ` +nc_pairs_var_suffix +^^^^^^^^^^^^^^^^^^^ The "nc_pairs_var_suffix" entry is similar to the "nc_pairs_var_name" entry described above. It is also parsed from each "obs.field" dictionary entry. @@ -1973,9 +1947,8 @@ now deprecated. nc_pairs_var_suffix = ""; -.. _ps_plot_flag: - -:ref:`ps_plot_flag ` +ps_plot_flag +^^^^^^^^^^^^ The "ps_plot_flag" entry is a boolean value for Wavelet-Stat and MODE indicating whether a PostScript plot should be generated summarizing @@ -1985,9 +1958,8 @@ the verification. ps_plot_flag = TRUE; -.. _grid_weight_flag: - -:ref:`grid_weight_flag ` +grid_weight_flag +^^^^^^^^^^^^^^^^ The "grid_weight_flag" specifies how grid weighting should be applied during the computation of continuous statistics and partial sums. It is @@ -2010,9 +1982,8 @@ by the sum of the weights for the current masking region. grid_weight_flag = NONE; -.. _hss_ec_value: - -ref:`hss_ec_value ` +hss_ec_value +^^^^^^^^^^^^ The "hss_ec_value" entry is a floating point number used in the computation of the HSS_EC statistic in the MCTS line type. It specifies the expected @@ -2028,9 +1999,8 @@ It set, it must greater than or equal to 0.0 and less than 1.0. A value of hss_ec_value = NA; -.. _rank_corr_flag: - -ref:`rank_corr_flag ` +rank_corr_flag +^^^^^^^^^^^^^^ The "rank_corr_flag" entry is a boolean to indicate whether Kendall's Tau and Spearman's Rank Correlation Coefficients (in the CNT line type) should @@ -2041,9 +2011,8 @@ intensive and slows down the runtime significantly. rank_corr_flag = FALSE; -.. _duplicate_flag: - -:ref:`duplicate_flag ` +duplicate_flag +^^^^^^^^^^^^^^ The "duplicate_flag" entry specifies how to handle duplicate point observations in Point-Stat and Ensemble-Stat: @@ -2064,9 +2033,8 @@ in those cases. duplicate_flag = NONE; -.. _obs_summary: - -:ref:`obs_summary ` +obs_summary +^^^^^^^^^^^ The "obs_summary" entry specifies how to compute statistics on observations that appear at a single location (lat,lon,level,elev) @@ -2101,9 +2069,8 @@ in those cases. obs_summary = NONE; -.. _obs_perc_value: - -:ref:`obs_perc_value ` +obs_perc_value +^^^^^^^^^^^^^^ Percentile value to use when obs_summary = PERC @@ -2112,9 +2079,8 @@ Percentile value to use when obs_summary = PERC obs_perc_value = 50; -.. _obs_quality_inc: - -:ref:`obs_quality_inc ` +obs_quality_inc +^^^^^^^^^^^^^^^ The "obs_quality_inc" entry specifies the quality flag values that are to be retained and used for verification. An empty list signifies that all @@ -2129,9 +2095,8 @@ Note "obs_quality_inc" replaces the older option "obs_quality". obs_quality_inc = [ "1", "2", "3", "9" ]; -.. _obs_quality_exc: - -:ref:`obs_quality_exc ` +obs_quality_exc +^^^^^^^^^^^^^^^ The "obs_quality_exc" entry specifies the quality flag values that are to be ignored and not used for verification. An empty list signifies that all @@ -2145,9 +2110,8 @@ an array of strings, even if the values themselves are numeric. obs_quality_exc = [ "1", "2", "3", "9" ]; -.. _met_data_dir: - -:ref:`met_data_dir ` +met_data_dir +^^^^^^^^^^^^ The "met_data_dir" entry specifies the location of the internal MET data sub-directory which contains data files used when generating plots. It @@ -2158,9 +2122,8 @@ locate the static data files they need at run time. met_data_dir = "MET_BASE"; -.. _many_plots: - -:ref:`fcst_raw_plot, obs_raw_plot, wvlt_plot, object_plot ` +many_plots +^^^^^^^^^^ The "fcst_raw_plot" entry is a dictionary used by Wavelet-Stat and MODE containing colortable plotting information for the plotting of the raw @@ -2191,9 +2154,8 @@ forecast field: The "obs_raw_plot", "wvlt_plot", and "object_plot" entries are dictionaries similar to the "fcst_raw_plot" described above. -.. _tmp_dir_2: - -:ref:`tmp_dir ` +tmp_dir_2 +^^^^^^^^^ The "tmp_dir" entry is a string specifying the location where temporary files should be written. @@ -2203,9 +2165,8 @@ files should be written. tmp_dir = "/tmp"; -.. _output_prefix: - -:ref:`output_prefix ` +output_prefix +^^^^^^^^^^^^^ The "output_prefix" entry specifies a string to be included in the output file name. The MET statistics tools construct output file names that @@ -2217,9 +2178,8 @@ of the same tool. output_prefix = ""; -.. _version: - -:ref:`version ` +version +^^^^^^^ The "version" entry specifies the version number of the configuration file. The configuration file version number should match the version number of @@ -2229,9 +2189,8 @@ the MET code being run. This value should generally not be modified. version = "VN.N"; -.. _time_summary: - -:ref:`time_summary ` +time_summary +^^^^^^^^^^^^ This feature was implemented to allow additional processing of observations with high temporal resolution. The "flag" entry toggles the "time_summary" @@ -2308,9 +2267,8 @@ Settings specific to individual tools EnsembleStatConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _ens: - -:ref:`ens ` +ens +""" The "ens" entry is a dictionary that specifies the fields for which ensemble products should be generated. This is very similar to the "fcst" and "obs" @@ -2352,9 +2310,8 @@ entries. This dictionary may include the following entries: ]; } -.. _nbrhd_prob: - -:ref:`nbrhd_prob ` +nbrhd_prob +"""""""""" The nbrhd_prob dictionary defines the neighborhoods used to compute NEP and NMEP output. The neighborhood shape is a SQUARE or CIRCLE centered on @@ -2375,9 +2332,8 @@ specified. vld_thresh = 0.0; } -.. _nmep_smooth: - -:ref:`nmep_smooth ` +nmep_smooth +""""""""""" Similar to the interp dictionary, the nmep_smooth dictionary includes a type array of dictionaries to define one or more methods for smoothing the NMEP @@ -2403,9 +2359,8 @@ combination of the categorical threshold (cat_thresh), neighborhood width ]; } -.. _fcst, obs_1: - -:ref:`fcst, obs ` +fcst, obs_1 +""""""""""" The fcst and obs entries define the fields for which Ensemble-Stat should compute rank histograms, probability integral transform histograms, @@ -2443,9 +2398,8 @@ data is provided, the climo_cdf thresholds will be used instead. } -.. _nc_var_str: - -:ref:`nc_var_str ` +nc_var_str +"""""""""" The "nc_var_str" entry specifies a string for each ensemble field and verification task in Ensemble-Stat. This string is parsed from each @@ -2461,9 +2415,8 @@ e.g. nc_var_str = "MIN"; nc_var_str = ""; -.. _obs_thresh: - -:ref:`obs_thresh ` +obs_thresh +"""""""""" The "obs_thresh" entry is an array of thresholds for filtering observation values prior to applying ensemble verification logic. They specify the values @@ -2476,9 +2429,8 @@ This option may be set separately for each obs.field entry. obs_thresh = [ NA ]; -.. _skip_const: - -:ref:`skip_const ` +skip_const +"""""""""" Setting "skip_const" to true tells Ensemble-Stat to exclude pairs where all the ensemble members and the observation have a constant value. For example, @@ -2491,9 +2443,8 @@ random. skip_const = FALSE; -.. _obs_error: - -:ref:`obs_error ` +obs_error +""""""""" Observation error options @@ -2550,9 +2501,8 @@ levels, and range of values. max = NA; } -.. _ensemble_flag: - -:ref:`ensemble_flag ` +ensemble_flag +""""""""""""" The "ensemble_flag" entry is a dictionary of boolean value indicating which ensemble products should be generated: @@ -2603,9 +2553,8 @@ which ensemble products should be generated: weight = FALSE; } -.. _rng: - -:ref:`rng ` +rng +""" See: `Random Number Generator Performance `_ used for random assignment of ranks when they are tied. @@ -2958,9 +2907,8 @@ MET User's Guide for a description of these attributes. MODEConfig_default ^^^^^^^^^^^^^^^^^^ -.. _quilt: - -:ref:`quilt ` +quilt +""""" The "quilt" entry is a boolean to indicate whether all permutations of convolution radii and thresholds should be run. If set to false, the number @@ -2975,9 +2923,8 @@ MODE will be run. quilt = false; -.. _fcst, obs_2: - -:ref:`fcst, obs ` +fcst, obs_2 +""""""""""" The object definition settings for MODE are contained within the "fcst" and "obs" entries: @@ -3061,9 +3008,8 @@ The object definition settings for MODE are contained within the "fcst" and merge_flag = THRESH; } -.. _grid_res: - -:ref:`grid_res ` +grid_res +"""""""" The "grid_res" entry is the nominal spacing for each grid square in kilometers. The variable is not used directly in the code, but subsequent @@ -3075,9 +3021,8 @@ are used for these variables. grid_res = 4; -.. _match_flag: - -:ref:`match_flag ` +match_flag +"""""""""" The "match_flag" entry specifies the matching method to be applied: @@ -3095,9 +3040,8 @@ The "match_flag" entry specifies the matching method to be applied: match_flag = MERGE_BOTH; -.. _max_centroid_dist: - -:ref:`max_centroid_dist ` +max_centroid_dist +""""""""""""""""" The "max_centroid_dist" entry specifies the maximum allowable distance in grid squares between the centroids of objects for them to be compared. @@ -3108,9 +3052,8 @@ skip unreasonable object comparisons. max_centroid_dist = 800.0/grid_res; -.. _weight: - -:ref:`weight ` +weight +"""""" The weight variables control how much weight is assigned to each pairwise attribute when computing a total interest value for object pairs. The weights @@ -3132,9 +3075,8 @@ sum of the weights listed. inten_perc_value = 50; } -.. _interest_function: - -:ref:`interest_function ` +interest_function +""""""""""""""""" The set of interest function variables listed define which values are of interest for each pairwise attribute measured. The interest functions may be @@ -3190,9 +3132,8 @@ mathematical functions. inten_perc_ratio = ratio_if; } -.. _total_interest_thresh: - -:ref:`total_interest_thresh ` +total_interest_thresh +""""""""""""""""""""" The total_interest_thresh variable should be set between 0 and 1. This threshold is applied to the total interest values computed for each pair of @@ -3202,9 +3143,8 @@ objects and is used in determining matches. total_interest_thresh = 0.7; -.. _print_interest_thresh: - -:ref:`print_interest_thresh ` +print_interest_thresh +""""""""""""""""""""" The print_interest_thresh variable determines which pairs of object attributes will be written to the output object attribute ASCII file. The @@ -3218,9 +3158,8 @@ the max_centroid_dist variable. print_interest_thresh = 0.0; -.. _plot_valid_flag: - -:ref:`plot_valid_flag ` +plot_valid_flag +""""""""""""""" When applied, the plot_valid_flag variable indicates that only the region containing valid data after masking is applied should be plotted. TRUE @@ -3231,9 +3170,8 @@ region containing valid data after masking should be plotted. plot_valid_flag = FALSE; -.. _plot_gcarc_flag: - -:ref:`plot_gcarc_flag ` +plot_gcarc_flag +""""""""""""""" When applied, the plot_gcarc_flag variable indicates that the edges of polylines should be plotted using great circle arcs as opposed to straight @@ -3243,9 +3181,8 @@ lines in the grid. plot_gcarc_flag = FALSE; -.. _ct_stats_flag: - -:ref:`ct_stats_flag ` +ct_stats_flag +""""""""""""" The ct_stats_flag can be set to TRUE or FALSE to produce additional output, in the form of contingency table counts and statistics. @@ -3254,9 +3191,8 @@ in the form of contingency table counts and statistics. ct_stats_flag = TRUE; -.. _shift_right: - -:ref:`shift_right ` +shift_right +""""""""""" When MODE is run on global grids, this parameter specifies how many grid squares to shift the grid to the right. MODE does not currently connect @@ -3331,9 +3267,8 @@ following criteria: 7 - Auxiliary levels generated via interpolation from spanning levels (upper-air profile reports) -.. _message_type: - -:ref:`message_type ` +message_type +"""""""""""" In the PB2NC tool, the "message_type" entry is an array of message types to be retained. An empty list indicates that all should be retained. @@ -3354,9 +3289,8 @@ For example: message_type = []; -.. _message_type_group_map_2: - -:ref:`message_type_group_map ` +message_type_group_map_2 +"""""""""""""""""""""""" Mapping of message type group name to comma-separated list of values. The default setting defines ANYAIR, ANYSFC, and ONLYSF as groups. @@ -3371,9 +3305,8 @@ Derive PRMSL only for SURFACE message types. { key = "ONLYSF"; val = "ADPSFC,SFCSHP"; } ]; -.. _station_id: - -:ref:`station_id ` +station_id +"""""""""" The "station_id" entry is an array of station ids to be retained or the filename which contains station ids. An array of station ids @@ -3386,9 +3319,8 @@ For example: station_id = [ "KDEN" ]; station_id = []; -.. _elevation_range: - -:ref:`elevation_range ` +elevation_range +""""""""""""""" The "elevation_range" entry is a dictionary which contains "beg" and "end" entries specifying the range of observing locations elevations to be @@ -3401,9 +3333,8 @@ retained. end = 100000; } -.. _pb_report_type: - -:ref:`pb_report_type ` +pb_report_type +"""""""""""""" The "pb_report_type" entry is an array of PREPBUFR report types to be retained. The numeric "pb_report_type" entry allows for further @@ -3423,9 +3354,8 @@ For example: pb_report_type = []; -.. _in_report_type: - -:ref:`in_report_type ` +in_report_type +"""""""""""""" The "in_report_type" entry is an array of input report type values to be retained. The numeric "in_report_type" entry provides additional @@ -3444,9 +3374,8 @@ For example: in_report_type = []; -.. _instrument_type: - -:ref:`instrument_type ` +instrument_type +""""""""""""""" The "instrument_type" entry is an array of instrument types to be retained. An empty list indicates that all should be retained. @@ -3455,9 +3384,8 @@ An empty list indicates that all should be retained. instrument_type = []; -.. _level_range: - -:ref:`level_range ` +level_range +""""""""""" The "level_range" entry is a dictionary which contains "beg" and "end" entries specifying the range of vertical levels (1 to 255) to be retained. @@ -3469,9 +3397,8 @@ entries specifying the range of vertical levels (1 to 255) to be retained. end = 255; } -.. _level_category: - -:ref:`level_category ` +level_category +"""""""""""""" The "level_category" entry is an array of integers specifying which level categories should be retained: @@ -3507,9 +3434,8 @@ See: `Current Table A Entries in PREPBUFR mnemonic table ` +obs_bufr_var +"""""""""""" The "obs_bufr_var" entry is an array of strings containing BUFR variable names to be retained or derived. This replaces the "obs_grib_code" setting @@ -3529,9 +3455,8 @@ command line option to see the list of available observation variables. obs_bufr_var = [ "QOB", "TOB", "ZOB", "UOB", "VOB" ]; -.. _obs_bufr_map: - -:ref:`obs_bufr_map ` +obs_bufr_map +"""""""""""" Mapping of input BUFR variable names to output variables names. The default PREPBUFR map, obs_prepbufr_map, is appended to this map. @@ -3542,9 +3467,8 @@ of the forecast the observation is used to verify. obs_bufr_map = []; -.. _obs_prepbufr_map: - -:ref:`obs_prepbufr_map ` +obs_prepbufr_map +"""""""""""""""" Default mapping for PREPBUFR. Replace input BUFR variable names with GRIB abbreviations in the output. This default map is appended to obs_bufr_map. @@ -3569,9 +3493,8 @@ abbreviations to the output. { key = "D_PRMSL"; val = "PRMSL"; } ]; -.. _quality_mark_thresh: - -:ref:`quality_mark_thresh ` +quality_mark_thresh +""""""""""""""""""" The "quality_mark_thresh" entry specifies the maximum quality mark value to be retained. Observations with a quality mark LESS THAN OR EQUAL TO @@ -3584,9 +3507,8 @@ See `Code table for observation quality markers ` +event_stack_flag +"""""""""""""""" The "event_stack_flag" entry is set to "TOP" or "BOTTOM" to specify whether observations should be drawn from the top of the event @@ -3599,9 +3521,8 @@ stack (most quality controlled) or the bottom of the event stack (most raw). SeriesAnalysisConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _block_size: - -:ref:`block_size ` +block_size +"""""""""" Computation may be memory intensive, especially for large grids. The "block_size" entry sets the number of grid points to be processed @@ -3614,9 +3535,8 @@ of grid points, and they are all processed concurrently. block_size = 1024; -.. _vld_thresh: - -:ref:`vld_thresh ` +vld_thresh +"""""""""" Ratio of valid matched pairs to total length of series for a grid point. If valid threshold is exceeded at that grid point the statistics @@ -3628,9 +3548,8 @@ setting requires all data in the series to be valid. vld_thresh = 1.0; -.. _output_stats: - -:ref:`output_stats ` +output_stats +"""""""""""" Statistical output types need to be specified explicitly. Refer to User's Guide for available output types. To keep output file size reasonable, @@ -3656,9 +3575,8 @@ grid is large. STATAnalysisConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _jobs: - -:ref:`jobs ` +jobs +"""" The "jobs" entry is an array of STAT-Analysis jobs to be performed. Each element in the array contains the specifications for a single analysis @@ -4125,9 +4043,8 @@ confidence intervals computed for the aggregated statistics. WaveletStatConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _grid_decomp_flag: - -:ref:`grid_decomp_flag ` +grid_decomp_flag +"""""""""""""""" The "grid_decomp_flag" entry specifies how the grid should be decomposed in Wavelet-Stat into dyadic (2^n x 2^n) tiles: @@ -4142,9 +4059,8 @@ Wavelet-Stat into dyadic (2^n x 2^n) tiles: grid_decomp_flag = AUTO; -.. _tile: - -:ref:`tile ` +tile +"""" The "tile" entry is a dictionary that specifies how tiles should be defined in Wavelet-Stat when the "grid_decomp_flag" is set to "TILE": @@ -4168,9 +4084,8 @@ in Wavelet-Stat when the "grid_decomp_flag" is set to "TILE": ]; } -.. _wavelet: - -:ref:`wavelet ` +wavelet +""""""" The "wavelet" entry is a dictionary in Wavelet-Stat that specifies how the wavelet decomposition should be performed: @@ -4205,9 +4120,8 @@ wavelet decomposition should be performed: member = 2; } -.. _obs_raw_wvlt_object_plots: - -:ref:`obs_raw_plot, wvlt_plot, object_plot ` +obs_raw_wvlt_object_plots +""""""""""""""""""""""""" The "obs_raw_plot", "wvlt_plot", and "object_plot" entries are dictionaries similar to the "fcst_raw_plot" described in the "Settings common to multiple @@ -4216,15 +4130,13 @@ tools" section. WWMCARegridConfig_default ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _to_grid: - -:ref:`to_grid ` +to_grid +""""""" Please see the description of the "to_grid" entry in the "regrid" dictionary above. -.. _NetCDF output information: - -:ref:`NetCDF output information ` +NetCDF output information +""""""""""""""""""""""""" Supply the NetCDF output information. For example: @@ -4242,9 +4154,8 @@ Supply the NetCDF output information. For example: long_name = ""; level = ""; -.. _max_minutes (pixel age): - -:ref:`max_minutes (pixel age) ` +max_minutes (pixel age) +""""""""""""""""""""""" Maximum pixel age in minutes @@ -4252,9 +4163,8 @@ Maximum pixel age in minutes max_minutes = 120; -.. _swap_endian: - -:ref:`swap_endian ` +swap_endian +""""""""""" The WWMCA pixel age data is stored in binary data files in 4-byte blocks. The swap_endian option indicates whether the endian-ness of the data should @@ -4264,9 +4174,8 @@ be swapped after reading. swap_endian = TRUE; -.. _write_pixel_age: - -:ref:`write_pixel_age ` +write_pixel_age +""""""""""""""" By default, wwmca_regrid writes the cloud percent data specified on the command line to the output file. This option writes the pixel age data, From fd953011082b8b783f8b540487a95c3d7eae85a1 Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 15 Feb 2022 12:07:40 -0700 Subject: [PATCH 119/172] Feature 2040 patch (#2053) --- met/src/libcode/vx_data2d_nc_met/met_file.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/met/src/libcode/vx_data2d_nc_met/met_file.cc b/met/src/libcode/vx_data2d_nc_met/met_file.cc index dd8f599c48..14a41b64d1 100644 --- a/met/src/libcode/vx_data2d_nc_met/met_file.cc +++ b/met/src/libcode/vx_data2d_nc_met/met_file.cc @@ -330,8 +330,6 @@ void MetNcFile::dump(ostream & out, int depth) const { int j, k; -int month, day, year, hour, minute, second; -char junk[256]; Indent prefix(depth); Indent p2(depth + 1); Indent p3(depth + 2); @@ -362,12 +360,6 @@ out << prefix << "Ydim = " << (Ydim ? GET_NC_NAME_P(Ydim) : "(nul)") << "\n"; out << prefix << "\n"; -snprintf(junk, sizeof(junk), "%s %d, %d %2d:%02d:%02d", short_month_name[month], day, year, hour, minute, second); - -out << junk << "\n"; - -out << prefix << "\n"; - out << prefix << "Nvars = " << Nvars << "\n"; for (j=0; j Date: Wed, 16 Feb 2022 22:01:56 -0700 Subject: [PATCH 120/172] For #2044, fix a typo in PB2NCConfig_G212. A commented out obs_bufr_var entry should really be obs_bufr_map and not commented out. --- met/scripts/config/PB2NCConfig_G212 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/scripts/config/PB2NCConfig_G212 b/met/scripts/config/PB2NCConfig_G212 index d5fbe9c141..0edaddf6e6 100644 --- a/met/scripts/config/PB2NCConfig_G212 +++ b/met/scripts/config/PB2NCConfig_G212 @@ -84,7 +84,7 @@ obs_bufr_var = [ "QOB", "TOB", "ZOB", "UOB", "VOB", // Mapping of BUFR variable name to GRIB name. The default map is defined at // obs_prepbufr_map. This replaces/expends the default map. // -//obs_bufr_var = []; +obs_bufr_map = []; //////////////////////////////////////////////////////////////////////////////// From 418ebe745a05781f093e45833af9c5d876a46347 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 18 Feb 2022 09:46:45 -0700 Subject: [PATCH 121/172] print docker build log to GHA log if build fails --- .github/jobs/build_docker_image.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/jobs/build_docker_image.sh b/.github/jobs/build_docker_image.sh index 5a9b2e8cf7..cefe962fc2 100755 --- a/.github/jobs/build_docker_image.sh +++ b/.github/jobs/build_docker_image.sh @@ -12,3 +12,7 @@ time_command docker build -t ${DOCKERHUB_TAG} \ --build-arg SOURCE_BRANCH \ --build-arg MET_BASE_IMAGE \ -f $DOCKERFILE_PATH ${GITHUB_WORKSPACE} +if [ $? != 0 ]; then + cat ${GITHUB_WORKSPACE}/docker_build.log + exit 1 +fi From 0d04d0d7c1d5a1549d3df89a00d2f92aad88ef48 Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Fri, 18 Feb 2022 16:31:06 -0700 Subject: [PATCH 122/172] Feature 1824 pb2nc mlcape (#2057) Co-authored-by: Howard Soh --- met/data/config/PB2NCConfig_default | 3 +- met/docs/Users_Guide/reformat_point.rst | 3 +- met/src/tools/other/pb2nc/calcape.f | 28 ----- met/src/tools/other/pb2nc/pb2nc.cc | 147 ++++++++++++++++-------- test/config/PB2NCConfig_pbl | 3 +- 5 files changed, 105 insertions(+), 79 deletions(-) diff --git a/met/data/config/PB2NCConfig_default b/met/data/config/PB2NCConfig_default index e11fa94e30..13110d221d 100644 --- a/met/data/config/PB2NCConfig_default +++ b/met/data/config/PB2NCConfig_default @@ -121,7 +121,8 @@ obs_prepbufr_map = [ { key = "D_MIXR"; val = "MIXR"; }, { key = "D_PRMSL"; val = "PRMSL"; }, { key = "D_PBL"; val = "PBL"; }, - { key = "D_CAPE"; val = "CAPE"; } + { key = "D_CAPE"; val = "CAPE"; }, + { key = "D_MLCAPE"; val = "MLCAPE"; } ]; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/docs/Users_Guide/reformat_point.rst b/met/docs/Users_Guide/reformat_point.rst index 7a3fce768f..0953afdd7c 100644 --- a/met/docs/Users_Guide/reformat_point.rst +++ b/met/docs/Users_Guide/reformat_point.rst @@ -227,7 +227,7 @@ _____________________ obs_bufr_var = [ 'QOB', 'TOB', 'ZOB', 'UOB', 'VOB' ]; -Each PrepBUFR message will likely contain multiple observation variables. The **obs_bufr_var** variable is used to specify which observation variables should be retained or derived. The variable name comes from BUFR file which includes BUFR table. The following BUFR names may be retained: QOB, TOB, ZOB, UOB, and VOB for specific humidity, temperature, height, and the u and v components of winds. The following BUFR names may be derived: D_DPT, D_WIND, D_RH, D_MIXR, D_PRMSL, D_PBL, and D_CAPE for dew point, wind speed, relative humidity, mixing ratio, pressure reduced to MSL, planetary boundary layer height, and convective available potential energy. This configuration replaces **obs_grib_code**. If the list is empty, all BUFR variables are retained. +Each PrepBUFR message will likely contain multiple observation variables. The **obs_bufr_var** variable is used to specify which observation variables should be retained or derived. The variable name comes from BUFR file which includes BUFR table. The following BUFR names may be retained: QOB, TOB, ZOB, UOB, and VOB for specific humidity, temperature, height, and the u and v components of winds. The following BUFR names may be derived: D_DPT, D_WIND, D_RH, D_MIXR, D_PRMSL, D_PBL, D_CAPE, and D_MLCAPE for dew point, wind speed, relative humidity, mixing ratio, pressure reduced to MSL, planetary boundary layer height, convective available potential energy, and mixed layer convective available potential energy. This configuration replaces **obs_grib_code**. If the list is empty, all BUFR variables are retained. _____________________ @@ -248,6 +248,7 @@ _____________________ { key = 'D_PRMSL'; val = 'PRMSL'; }, { key = 'D_PBL'; val = 'PBL'; }, { key = 'D_CAPE'; val = 'CAPE'; } + { key = 'D_MLCAPE'; val = 'MLCAPE'; } ]; diff --git a/met/src/tools/other/pb2nc/calcape.f b/met/src/tools/other/pb2nc/calcape.f index e8d3a60b9d..d833246671 100644 --- a/met/src/tools/other/pb2nc/calcape.f +++ b/met/src/tools/other/pb2nc/calcape.f @@ -130,8 +130,6 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, CINS(I,J) = 0.0 THESP(I,J)= 0.0 IEQL(I,J) = LM+1 -C print*,' DEBUG HS calcape IEQL(I,J): by LM+1: ',IEQL(I,J) -C print*,' DEBUG HS calcape LCL(I,J) to 0 ' LCL(I,J)=0 ENDDO @@ -233,11 +231,8 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, APESPK=(H10E5/TPSPK)**CAPA TTHESK=TTHBTK*EXP(ELOCP*QBTK*APESPK/TTHBTK) C--------------CHECK FOR MAXIMUM THETA E-------------------------------- -C print*,' DEBUG HS calcape PTBL(IQ ,IT )',PTBL(IQ ,IT ), C 2 PTBL(IQ+1 ,IT ),PTBL(IQ ,IT+1 ),PTBL(IQ+1 ,IT+1 ) -C print*,' DEBUG HS calcape TTHESK.GT.THESP(I,J:',TTHESK,THESP(I,J) IF(TTHESK.GT.THESP(I,J)) THEN -C print*,' DEBUG HS calcape Update PSP:',TPSPK,' LMM:',LMM PSP (I,J)=TPSPK THESP(I,J)=TTHESK ENDIF @@ -253,9 +248,7 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, DO J=1,JM DO I=1,IM IF (L.LT.LMH(I,J)) THEN -C print*,' DEBUG HS calcape L.LT.LMH(I,J):',L,LMH(I,J) PKL = P(I,J,L) -C print*,' DEBUG HS calcape L,PKL.LT.PSP(I,J)',L,PKL,PSP(I,J) IF (PKL.LT.PSP(I,J)) THEN LCL(I,J)=L+1 PLCL(I,J)=P(I,J,L+1) @@ -276,7 +269,6 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, DO J=1,JM DO I=1,IM PKL = P(I,J,L) -C print*,' DEBUG HS calcape L.LE.LCL(I,J):',L,LCL(I,J) IF(L.LE.LCL(I,J)) THEN IF(PKL.LT.PLQ)THEN KNUML=KNUML+1 @@ -311,23 +303,19 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, ENDIF C------------SEARCH FOR EQ LEVEL---------------------------------------- -C print*,' DEBUG HS calcape SEARCH FOR EQ LEVEL, KNUMH:',KNUMH DO N=1,KNUMH I=IHRES(N) J=JHRES(N) IF(TPAR(I,J,L).GT.T(I,J,L)) THEN IEQL(I,J)=L -C print*,' DEBUG HS calcape 111 IEQL(I,J):',IEQL(I,J) PEQL(I,J)=P(I,J,L) ENDIF ENDDO -C print*,' DEBUG HS calcape SEARCH FOR EQ LEVEL, KNUML:',KNUML DO N=1,KNUML I=ILRES(N) J=JLRES(N) IF(TPAR(I,J,L).GT.T(I,J,L)) THEN IEQL(I,J)=L -C print*,' DEBUG HS calcape 222 IEQL(I,J):',IEQL(I,J) PEQL(I,J)=P(I,J,L) ENDIF ENDDO @@ -339,7 +327,6 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, DO I=1,IM LCLK=LCL(I,J) IEQK=IEQL(I,J) -C print*,' DEBUG HS calcape IEQK,LCLK:',IEQK,LCLK DO L=IEQK,LCLK c print*,'l=',l c print*,'p(i,j,l)=',p(i,j,l) @@ -369,12 +356,10 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, C print*,'virtual thetap=',thetap C print*,'virtual thetaa=',thetaa endif -C print*,' DEBUG HS calcape before CAPE(I,J)=',CAPE(I,J) IF (THETAP.LT.THETAA) & CINS(I,J)=CINS(I,J)+G*(ALOG(THETAP)-ALOG(THETAA))*DZKL IF (THETAP.GT.THETAA) & CAPE(I,J)=CAPE(I,J)+G*(ALOG(THETAP)-ALOG(THETAA))*DZKL -C print*,' DEBUG HS calcape after CAPE(I,J)=',CAPE(I,J) ENDDO ENDDO ENDDO @@ -389,7 +374,6 @@ SUBROUTINE CALCAPE(ivirt,itype,T,Q,P,p1d,t1d,q1d,PINT,LMH, DO I = 1,IM CAPE(I,J) = AMAX1(0.0,CAPE(I,J)) CINS(I,J) = AMIN1(CINS(I,J),0.0) -C print*,' DEBUG HS calcape final CAPE(I,J)=',CAPE(I,J) ENDDO ENDDO c if(itype.eq.2) print*,'CAPE,CINS=',CAPE,CINS @@ -791,19 +775,7 @@ SUBROUTINE SPLINE(JTB,NOLD,XOLD,YOLD,Y2,NNEW,XNEW,YNEW,P,Q) 600 K1=K1+1 IF(K1.LE.NNEW) GO TO 300 C----------------------------------------------------------------------- -C print*,' DEBUG HS calcape NOLD,NNEW: ',NOLD,NNEW -CC print*,' DEBUG HS calcape XOLD: ',XOLD -CC print*,' DEBUG HS calcape YOLD: ',YOLD -C print*,' DEBUG HS calcape XOLD(1)->: XNEW(1)',XOLD(1),XNEW(1) -C print*,' DEBUG HS calcape XOLD(2)->: XNEW(2)',XOLD(2),XNEW(2) -CC print*,' DEBUG HS calcape XNEW: ',XNEW -CC print*,' DEBUG HS calcape YNEW: ',YNEW -C print*,' DEBUG HS calcape YOLD(1)->: YNEW(1)',YOLD(1),YNEW(1) -C print*,' DEBUG HS calcape YOLD(2)->: YNEW(2)',YOLD(2),YNEW(2) -C print*,' DEBUG HS calcape YOLD(3)->: YNEW(3)',YOLD(3),YNEW(3) -C print*,' DEBUG HS calcape YOLD(-2)->: YNEW(-2)', C 2 YOLD(NOLD-1),YNEW(NNEW-1) -C print*,' DEBUG HS calcape YOLD(-1)->: YNEW(-1)', C 2 YOLD(NOLD),YNEW(NNEW) RETURN END diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index cff540d107..0b914b3198 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -260,8 +260,10 @@ static const char *airnow_aux_vars = "TPHR QCIND"; // Pick the latter one if exists multiuple variables static const char *bufr_avail_sid_names = "SID SAID RPID"; static const char *bufr_avail_latlon_names = "XOB CLON CLONH YOB CLAT CLATH"; +static const char *derived_mlcape = "D_MLCAPE"; static const char *derived_cape = "D_CAPE"; static const char *derived_pbl = "D_PBL"; +static const float MLCAPE_INTERVAL = 3000.; static double bufr_obs[mxr8lv][mxr8pm]; static double bufr_obs_extra[mxr8lv][mxr8pm]; @@ -511,6 +513,7 @@ void initialize() { prepbufr_derive_vars.add("D_MIXR"); prepbufr_derive_vars.add("D_PRMSL"); prepbufr_derive_vars.add("D_CAPE"); + prepbufr_derive_vars.add("D_MLCAPE"); prepbufr_derive_vars.add("D_PBL"); for (int idx=0; idx<(sizeof(hdr) / sizeof(hdr[0])); idx++) { @@ -982,10 +985,13 @@ void process_pbfile(int i_pb) { int itype = 1; // itype 1: where a parcel is lifted from the ground // itype 2: Where the "best cape" in a number of parcels int cape_code = -1; + int mlcape_code = -1; float p1d,t1d,q1d; int IMM, JMM; - int cape_level=0, cape_count=0, cape_cnt_too_big=0, cape_cnt_surface_msgs=0; - int cape_cnt_no_levels=0, cape_cnt_missing_values=0, cape_cnt_zero_values=0; + int cape_level, cape_count, cape_cnt_too_big, cape_cnt_surface_msgs; + int cape_cnt_no_levels, cape_cnt_missing_values, cape_cnt_zero_values; + int mlcape_count, mlcape_cnt_too_big; + int mlcape_cnt_missing_values, mlcape_cnt_zero_values; float cape_p, cape_h; float cape_qm = bad_data_float; @@ -997,8 +1003,9 @@ void process_pbfile(int i_pb) { bool has_pbl_data; bool do_pbl = false; - bool cal_cape = bufr_obs_name_arr.has(derived_cape, cape_code, false); bool cal_pbl = bufr_obs_name_arr.has(derived_pbl, pbl_code, false); + bool cal_cape = bufr_obs_name_arr.has(derived_cape, cape_code, false); + bool cal_mlcape = bufr_obs_name_arr.has(derived_mlcape, mlcape_code, false); bool is_same_header; unixtime prev_hdr_vld_ut = (unixtime) 0; @@ -1010,6 +1017,10 @@ void process_pbfile(int i_pb) { // Initialize prev_hdr_lat = prev_hdr_lon = prev_hdr_elv = bad_data_double; + cape_level = cape_count = cape_cnt_too_big = 0; + cape_cnt_no_levels = cape_cnt_missing_values = cape_cnt_zero_values = 0; + mlcape_count = mlcape_cnt_too_big = 0; + mlcape_cnt_missing_values = mlcape_cnt_zero_values = 0; if (cal_pbl) { is_same_header = false; @@ -1327,7 +1338,7 @@ void process_pbfile(int i_pb) { } } - if (cal_cape) { + if (cal_cape || cal_mlcape) { cape_level = 0; } @@ -1471,7 +1482,7 @@ void process_pbfile(int i_pb) { obs_arr[4] += c_to_k; } - if (cal_cape) { + if (cal_cape || cal_mlcape) { if(grib_code == pres_grib_code) { is_cape_input = true; if (cape_level < MAX_CAPE_LEVEL) cape_data_pres[cape_level] = obs_arr[4]; @@ -1567,7 +1578,7 @@ void process_pbfile(int i_pb) { } // end for i } - if (cal_cape) { + if (cal_cape || cal_mlcape) { if (cape_member_cnt >= 3) cape_level++; } @@ -1603,7 +1614,7 @@ void process_pbfile(int i_pb) { } } // end for lv - if (cal_cape) { + if (cal_cape || cal_mlcape) { if (1 < cape_level) { bool reverse_levels; float cape_val, cin_val, PLCL,PEQL; @@ -1646,14 +1657,6 @@ void process_pbfile(int i_pb) { } } - //p1d = cape_p; - //t1d = cape_data_temp[cape_level-1]; - //q1d = cape_data_spfh[cape_level-1]; - calcape_(&ivirt,&itype, cape_data_temp, cape_data_spfh, cape_data_pres, - &p1d,&t1d,&q1d, static_dummy_201, - &cape_level, &IMM,&JMM, &cape_level, - &cape_val, &cin_val, &PLCL, &PEQL, static_dummy_200); - if(mlog.verbosity_level() >= 7) { mlog << Debug(7) << method_name << " index,P,T,Q to compute CAPE from " << i_read << "-th message\n" ; @@ -1661,37 +1664,81 @@ void process_pbfile(int i_pb) { mlog << Debug(7) << method_name << " " << idx << ", " << cape_data_pres[idx] << ", " << cape_data_temp[idx] << ", " << cape_data_spfh[idx] << "\n"; } - mlog << Debug(7) << method_name - << " calcape_(" << ivirt << "," << itype << ") cape_val: " - << cape_val << " cape_level: " << cape_level - << ", cin_val: " << cin_val - << ", PLCL: " << PLCL << ", PEQL: " << PEQL - << " lat: " << hdr_lat << ", lon: " << hdr_lon - << " valid_time: " << unix_to_yyyymmdd_hhmmss(hdr_vld_ut) - << " " << hdr_typ << " " << hdr_sid - << "\n\n" ; } - if (cape_val > MAX_CAPE_VALUE) { - cape_cnt_too_big++; - mlog << Debug(5) << method_name - << " Ignored cape_value: " << cape_val << " cape_level: " << cape_level - << ", cin_val: " << cin_val - << ", PLCL: " << PLCL << ", PEQL: " << PEQL << "\n"; + if (cal_cape) { + calcape_(&ivirt,&itype, cape_data_temp, cape_data_spfh, cape_data_pres, + &p1d,&t1d,&q1d, static_dummy_201, + &cape_level, &IMM,&JMM, &cape_level, + &cape_val, &cin_val, &PLCL, &PEQL, static_dummy_200); + + if(mlog.verbosity_level() >= 7) { + mlog << Debug(7) << method_name + << " calcape_(" << ivirt << "," << itype << ") cape_val: " + << cape_val << " cape_level: " << cape_level + << ", cin_val: " << cin_val + << ", PLCL: " << PLCL << ", PEQL: " << PEQL + << " lat: " << hdr_lat << ", lon: " << hdr_lon + << " valid_time: " << unix_to_yyyymmdd_hhmmss(hdr_vld_ut) + << " " << hdr_typ << " " << hdr_sid + << "\n\n" ; + } + + if (cape_val > MAX_CAPE_VALUE) { + cape_cnt_too_big++; + mlog << Debug(5) << method_name + << " Ignored cape_value: " << cape_val << " cape_level: " << cape_level + << ", cin_val: " << cin_val + << ", PLCL: " << PLCL << ", PEQL: " << PEQL << "\n"; + } + else if (cape_val >= 0) { + obs_arr[1] = cape_code; + obs_arr[2] = cape_p; + obs_arr[3] = cape_h; + obs_arr[4] = cape_val; // observation value + addObservation(obs_arr, (string)hdr_typ, (string)hdr_sid, hdr_vld_ut, + hdr_lat, hdr_lon, hdr_elv, cape_qm, + OBS_BUFFER_SIZE); + cape_count++; + n_derived_obs++; + if (is_eq(cape_val, 0.)) cape_cnt_zero_values++; + } + else cape_cnt_missing_values++; } - else if (cape_val >= 0) { - obs_arr[1] = cape_code; - obs_arr[2] = cape_p; - obs_arr[3] = cape_h; - obs_arr[4] = cape_val; // observation value - addObservation(obs_arr, (string)hdr_typ, (string)hdr_sid, hdr_vld_ut, - hdr_lat, hdr_lon, hdr_elv, cape_qm, - OBS_BUFFER_SIZE); - cape_count++; - n_derived_obs++; - if (is_eq(cape_val, 0.)) cape_cnt_zero_values++; + + if (cal_mlcape) { + float mlcape_val = bad_data_float; + + ivirt = 1; + itype = 2; + // The second last seems to be better than the average of last two or three + p1d = cape_data_pres[cape_level-2]; + t1d = cape_data_temp[cape_level-2]; + q1d = cape_data_spfh[cape_level-2]; + calcape_(&ivirt,&itype, cape_data_temp, cape_data_spfh, cape_data_pres, + &p1d,&t1d,&q1d, static_dummy_201, + &cape_level, &IMM,&JMM, &cape_level, + &mlcape_val, &cin_val, &PLCL, &PEQL, static_dummy_200); + if (mlcape_val > MAX_CAPE_VALUE) { + mlcape_cnt_too_big++; + mlog << Debug(5) << method_name + << " Ignored ML_cape: " << mlcape_val << " cape_level: " + << cape_level << "\n"; + } + else if (mlcape_val >= 0) { + obs_arr[1] = mlcape_code; + obs_arr[2] = cape_p; + obs_arr[3] = cape_h; + obs_arr[4] = mlcape_val; // observation value + addObservation(obs_arr, (string)hdr_typ, (string)hdr_sid, hdr_vld_ut, + hdr_lat, hdr_lon, hdr_elv, cape_qm, + OBS_BUFFER_SIZE); + mlcape_count++; + n_derived_obs++; + if (is_eq(mlcape_val, 0.)) mlcape_cnt_zero_values++; + } + else mlcape_cnt_missing_values++; } - else cape_cnt_missing_values++; } else if (1 < buf_nlev) cape_cnt_no_levels++; else cape_cnt_surface_msgs++; @@ -1948,13 +1995,13 @@ void process_pbfile(int i_pb) { << "Total observations retained or derived\t= " << (n_file_obs + n_derived_obs) << "\n"; - if (cal_cape) { - mlog << Debug(3) << "\nDerived CAPE = " << cape_count - << "\tZero = " << cape_cnt_zero_values + if (cal_cape || cal_mlcape) { + mlog << Debug(3) << "\nDerived CAPE = " << (cape_count + mlcape_count) + << "\tZero = " << (cape_cnt_zero_values + mlcape_cnt_zero_values) << "\n\tnot derived: No cape inputs = " << (cape_cnt_no_levels) << "\tNo vertical levels = " << (cape_cnt_surface_msgs) - << "\n\tfiltered: " << cape_cnt_missing_values << ", " - << cape_cnt_too_big + << "\n\tfiltered: " << (cape_cnt_missing_values + mlcape_cnt_missing_values) << ", " + << (cape_cnt_too_big + mlcape_cnt_too_big) << "\n"; } @@ -3003,7 +3050,11 @@ float compute_pbl(map pqtzuv_map_tq, if (pbl_level <= 0) { mlog << Debug(4) << method_name - << "Skip CALPBL because an empty list after combining TQZ and UV\n"; + << "Skip CALPBL because of an empty list after combining TQZ and UV\n"; + } + else if (pbl_level == 1) { + mlog << Debug(4) << method_name + << "Skip CALPBL because of only one available record after combining TQZ and UV\n"; } else { // Order all observations by pressure from bottom to top diff --git a/test/config/PB2NCConfig_pbl b/test/config/PB2NCConfig_pbl index 924c06a54c..ac48b5850f 100644 --- a/test/config/PB2NCConfig_pbl +++ b/test/config/PB2NCConfig_pbl @@ -92,7 +92,7 @@ level_category = [0, 1, 4, 5, 6]; // Use obs_bufr_map to rename variables in the output. // If empty, process all available variables. // -obs_bufr_var = ["D_CAPE", "D_PBL"]; +obs_bufr_var = ["D_CAPE", "D_PBL", "D_MLCAPE"]; //////////////////////////////////////////////////////////////////////////////// // @@ -120,6 +120,7 @@ obs_prepbufr_map = [ { key = "D_PBL"; val = "HPBL"; }, { key = "D_PRMSL"; val = "PRMSL"; }, { key = "D_CAPE"; val = "CAPE"; }, + { key = "D_MLCAPE"; val = "MLCAPE"; }, { key = "TDO"; val = "DPT"; }, { key = "PMO"; val = "PRMSL"; }, { key = "TOCC"; val = "TCDC"; }, From a2a737225485592986450b28c63c99634fe20d95 Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 18 Feb 2022 16:33:37 -0700 Subject: [PATCH 123/172] Feature 1583 es hira (#2056) --- met/data/config/ConfigConstants | 1 + met/docs/Users_Guide/config_options.rst | 7 +- met/docs/Users_Guide/ensemble-stat.rst | 4 + met/scripts/config/EnsembleStatConfig | 4 + met/scripts/config/STATAnalysisConfig | 2 +- met/src/basic/vx_config/config_util.cc | 6 +- met/src/basic/vx_util/interp_mthd.cc | 2 + met/src/basic/vx_util/interp_mthd.h | 4 +- met/src/basic/vx_util/interp_util.cc | 1 + met/src/libcode/vx_data2d/var_info.h | 50 +++--- met/src/libcode/vx_statistics/ens_stats.cc | 82 +++++----- .../vx_statistics/pair_data_ensemble.cc | 144 +++++++++++++----- .../tools/core/ensemble_stat/ensemble_stat.cc | 59 ++++--- .../ensemble_stat/ensemble_stat_conf_info.cc | 88 ++++++----- .../ensemble_stat/ensemble_stat_conf_info.h | 44 +++--- met/src/tools/core/point_stat/point_stat.cc | 2 +- .../core/point_stat/point_stat_conf_info.cc | 13 +- 17 files changed, 324 insertions(+), 189 deletions(-) diff --git a/met/data/config/ConfigConstants b/met/data/config/ConfigConstants index ee0d4855c0..29b2590ada 100644 --- a/met/data/config/ConfigConstants +++ b/met/data/config/ConfigConstants @@ -88,6 +88,7 @@ AW_MEAN = 20; GAUSSIAN = 21; MAXGAUSS = 22; GEOG_MATCH = 23; +HIRA = 24; // Interpolation types NONE = 1; diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index 627415ffec..ae5ca26a40 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -610,7 +610,7 @@ using the following entries: * MAXGAUSS to compute the maximum value in the neighborhood and apply a Gaussian smoother to the result - The BEST and GEOG_MATCH interpolation options are not valid for regridding. + The BEST, GEOG_MATCH, and HIRA options are not valid for regridding. * The "width" entry specifies a regridding width, when applicable. - width = 4; To regrid using a 4x4 box or circle with diameter 4. @@ -1689,7 +1689,10 @@ This dictionary may include the following entries: * MAXGAUSS for the maximum value followed by a Gaussian smoother * GEOG_MATCH for the nearest grid point where the land/sea mask - and geography criteria are satisfied. + and geography criteria are satisfied + + * HIRA for all neighborhood points to define a spatial + ensemble (only in Ensemble-Stat) The BUDGET, FORCE, GAUSSIAN, and MAXGAUSS methods are not valid for interpolating to point locations. For grid-to-grid comparisons, the diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index ca449cdd9c..f063e23f52 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -17,6 +17,8 @@ Ensemble forecasts derived from a set of deterministic ensemble members Ensemble forecasts are often created as a set of deterministic forecasts. The ensemble members are rarely used separately. Instead, they can be combined in various ways to produce a forecast. MET can combine the ensemble members into some type of summary forecast according to user specifications. Ensemble means are the most common, and can be paired with the ensemble variance or spread. Maximum, minimum and other summary values are also available, with details in the practical information section. +Typically an ensemble is constructed by selecting a single forecast value from each member for each observation. When the High Resolution Assessment (HiRA) interpolation method is chosen, all of the nearby neighborhood points surrounding each observation from each member are used. Therefore, processing an N-member ensemble using a HiRA neighborhood of size M produces ensemble output with size N*M. This approach fully leverages information from all nearby grid points to evaluate the ensemble quality. + The ensemble relative frequency is the simplest method for turning a set of deterministic forecasts into something resembling a probability forecast. MET will create the ensemble relative frequency as the proportion of ensemble members forecasting some event. For example, if 5 out of 10 ensemble members predict measurable precipitation at a grid location, then the ensemble relative frequency of precipitation will be :math:`5/10=0.5`. If the ensemble relative frequency is calibrated (unlikely) then this could be thought of as a probability of precipitation. The neighborhood ensemble probability (NEP) and neighborhood maximum ensemble probability (NMEP) methods are described in :ref:`Schwartz and Sobash (2017) `. They are an extension of the ensemble relative frequencies described above. The NEP value is computed by averaging the relative frequency of the event within the neighborhood over all ensemble members. The NMEP value is computed as the fraction of ensemble members for which the event is occurring somewhere within the surrounding neighborhood. The NMEP output is typically smoothed using a Gaussian kernel filter. The neighborhood sizes and smoothing options can be customized in the configuration file. @@ -161,6 +163,8 @@ ____________________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. +Note that the **HIRA** interpolation method is only supported in Ensemble-Stat. + _____________________ .. code-block:: none diff --git a/met/scripts/config/EnsembleStatConfig b/met/scripts/config/EnsembleStatConfig index 91d4cab5d0..64367110ea 100644 --- a/met/scripts/config/EnsembleStatConfig +++ b/met/scripts/config/EnsembleStatConfig @@ -249,6 +249,10 @@ interp = { { method = NEAREST; width = 1; + }, + { + method = HIRA; + width = 2; } ]; } diff --git a/met/scripts/config/STATAnalysisConfig b/met/scripts/config/STATAnalysisConfig index 5f81208f5a..712813c57e 100644 --- a/met/scripts/config/STATAnalysisConfig +++ b/met/scripts/config/STATAnalysisConfig @@ -84,7 +84,7 @@ jobs = [ "-job aggregate -line_type GRAD -vx_mask DTC165 -vx_mask DTC166 -by FCST_VAR -dump_row ${TEST_OUT_DIR}/stat_analysis/job_aggregate_GRAD.stat", "-job aggregate -line_type ISC -fcst_thresh >0.0 -vx_mask TILE_TOT -fcst_var APCP_12 -dump_row ${TEST_OUT_DIR}/stat_analysis/job_aggregate_ISC.stat", "-job aggregate -line_type RHIST -obtype MC_PCP -vx_mask HUC4_1605 -vx_mask HUC4_1803 -vx_mask HUC4_1804 -vx_mask HUC4_1805 -vx_mask HUC4_1806 -dump_row ${TEST_OUT_DIR}/stat_analysis/job_aggregate_RHIST.stat", - "-job aggregate_stat -line_type ORANK -out_line_type RHIST -obtype ADPSFC -vx_mask HUC4_1605 -vx_mask HUC4_1803 -vx_mask HUC4_1804 -vx_mask HUC4_1805 -vx_mask HUC4_1806 -dump_row ${TEST_OUT_DIR}/stat_analysis/job_aggregate_stat_ORANK_RHIST.stat" + "-job aggregate_stat -line_type ORANK -out_line_type RHIST -obtype ADPSFC -vx_mask HUC4_1605,HUC4_1803,HUC4_1804,HUC4_1805,HUC4_1806 -by INTERP_MTHD,INTERP_PNTS -dump_row ${TEST_OUT_DIR}/stat_analysis/job_aggregate_stat_ORANK_RHIST.stat" ]; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index c466a9f2de..edeabb649a 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -141,9 +141,10 @@ RegridInfo::RegridInfo() { void RegridInfo::validate() { // Check for unsupported regridding options - if(method == InterpMthd_Best || + if(method == InterpMthd_Best || method == InterpMthd_Geog_Match || - method == InterpMthd_Gaussian) { + method == InterpMthd_Gaussian || + method == InterpMthd_HiRA) { mlog << Error << "\nRegridInfo::validate() -> " << "\"" << interpmthd_to_string(method) << "\" not valid for regridding, only interpolating.\n\n"; @@ -2272,6 +2273,7 @@ InterpMthd int_to_interpmthd(int i) { else if(i == conf_const.lookup_int(interpmthd_gaussian_str)) m = InterpMthd_Gaussian; else if(i == conf_const.lookup_int(interpmthd_maxgauss_str)) m = InterpMthd_MaxGauss; else if(i == conf_const.lookup_int(interpmthd_geog_match_str)) m = InterpMthd_Geog_Match; + else if(i == conf_const.lookup_int(interpmthd_hira_str)) m = InterpMthd_HiRA; else { mlog << Error << "\nconf_int_to_interpmthd() -> " << "Unexpected value of " << i diff --git a/met/src/basic/vx_util/interp_mthd.cc b/met/src/basic/vx_util/interp_mthd.cc index dcd9ff5ac4..d84bf9c4ab 100644 --- a/met/src/basic/vx_util/interp_mthd.cc +++ b/met/src/basic/vx_util/interp_mthd.cc @@ -44,6 +44,7 @@ ConcatString interpmthd_to_string(const InterpMthd m) { case(InterpMthd_Gaussian): out = interpmthd_gaussian_str; break; case(InterpMthd_MaxGauss): out = interpmthd_maxgauss_str; break; case(InterpMthd_Geog_Match): out = interpmthd_geog_match_str; break; + case(InterpMthd_HiRA): out = interpmthd_hira_str; break; case(InterpMthd_None): default: out = interpmthd_none_str; break; @@ -77,6 +78,7 @@ InterpMthd string_to_interpmthd(const char *mthd_str) { else if(strcmp(mthd_str, interpmthd_gaussian_str ) == 0) m = InterpMthd_Gaussian; else if(strcmp(mthd_str, interpmthd_maxgauss_str ) == 0) m = InterpMthd_MaxGauss; else if(strcmp(mthd_str, interpmthd_geog_match_str) == 0) m = InterpMthd_Geog_Match; + else if(strcmp(mthd_str, interpmthd_hira_str) == 0) m = InterpMthd_HiRA; else m = InterpMthd_None; return(m); diff --git a/met/src/basic/vx_util/interp_mthd.h b/met/src/basic/vx_util/interp_mthd.h index e65be8f7ef..39c4b23e87 100644 --- a/met/src/basic/vx_util/interp_mthd.h +++ b/met/src/basic/vx_util/interp_mthd.h @@ -42,7 +42,8 @@ enum InterpMthd { InterpMthd_Lower_Left, InterpMthd_Gaussian, InterpMthd_MaxGauss, - InterpMthd_Geog_Match + InterpMthd_Geog_Match, + InterpMthd_HiRA }; // @@ -69,6 +70,7 @@ static const char interpmthd_lower_left_str[] = "LOWER_LEFT"; static const char interpmthd_gaussian_str[] = "GAUSSIAN"; static const char interpmthd_maxgauss_str[] = "MAXGAUSS"; static const char interpmthd_geog_match_str[] = "GEOG_MATCH"; +static const char interpmthd_hira_str[] = "HIRA"; /////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/interp_util.cc b/met/src/basic/vx_util/interp_util.cc index 631b88d265..bdaf7a573d 100644 --- a/met/src/basic/vx_util/interp_util.cc +++ b/met/src/basic/vx_util/interp_util.cc @@ -1020,6 +1020,7 @@ double compute_sfc_interp(const DataPlane &dp, mlog << Error << "\ncompute_sfc_interp() -> " << "unsupported interpolation method encountered: " << interpmthd_to_string(mthd) << "(" << mthd << ")\n\n"; + exit(1); } delete gt; diff --git a/met/src/libcode/vx_data2d/var_info.h b/met/src/libcode/vx_data2d/var_info.h index 382f25aded..3661b07ee3 100644 --- a/met/src/libcode/vx_data2d/var_info.h +++ b/met/src/libcode/vx_data2d/var_info.h @@ -258,9 +258,9 @@ inline int VarInfo::accum_attr() const { return(SetAttrAccum); } // struct InputInfo { - VarInfo * var_info; // Variable information to read - int file_index; // Index in file_list of file to read - StringArray * file_list; // Array of files (unallocated) + VarInfo * var_info; // Variable information to read + int file_index; // Index in file_list of file to read + StringArray * file_list; // Array of files (unallocated) }; //////////////////////////////////////////////////////////////////////// @@ -270,33 +270,37 @@ struct InputInfo { // class EnsVarInfo { -private: - vector inputs; // Vector of InputInfo - VarInfo * ctrl_info; // Field info for control member -public: - EnsVarInfo(); - ~EnsVarInfo(); - EnsVarInfo(const EnsVarInfo &); + private: + vector inputs; // Vector of InputInfo + VarInfo * ctrl_info; // Field info for control member - void clear(); - void assign(const EnsVarInfo &); + public: + EnsVarInfo(); + ~EnsVarInfo(); + EnsVarInfo(const EnsVarInfo &); + + void clear(); + void assign(const EnsVarInfo &); - void add_input(InputInfo); - int inputs_n(); + void add_input(InputInfo); + int inputs_n(); - void set_ctrl(VarInfo *); - VarInfo * get_ctrl(int); + void set_ctrl(VarInfo *); + VarInfo * get_ctrl(int); - // Get VarInfo from first InputInfo if requested VarInfo is NULL - VarInfo * get_var_info(int index=0); - ConcatString get_file(int index=0); - int get_file_index(int index=0); + // Get VarInfo from first InputInfo if requested VarInfo is NULL + VarInfo * get_var_info(int index=0); + ConcatString get_file(int index=0); + int get_file_index(int index=0); + + ConcatString nc_var_str; // Ensemble variable name strings + ThreshArray cat_ta; // Ensemble categorical thresholds + ConcatString raw_magic_str; // Magic string w/o var substitution - ConcatString nc_var_str; // Ensemble variable name strings - ThreshArray cat_ta; // Ensemble categorical thresholds - ConcatString raw_magic_str; // Magic string w/o var substitution }; +//////////////////////////////////////////////////////////////////////// + ConcatString raw_magic_str(Dictionary i_edict, GrdFileType file_type); /////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_statistics/ens_stats.cc b/met/src/libcode/vx_statistics/ens_stats.cc index 4b273294a6..65cda9aca1 100644 --- a/met/src/libcode/vx_statistics/ens_stats.cc +++ b/met/src/libcode/vx_statistics/ens_stats.cc @@ -177,8 +177,8 @@ void ECNTInfo::clear() { othresh.clear(); n_ens = n_pair = 0; - crps_emp = crpscl_emp = crpss_emp = bad_data_double; - crps_gaus = crpscl_gaus = crpss_gaus = bad_data_double; + crps_emp = crpscl_emp = crpss_emp = bad_data_double; + crps_gaus = crpscl_gaus = crpss_gaus = bad_data_double; ign = bad_data_double; me = rmse = spread = bad_data_double; me_oerr = rmse_oerr = spread_oerr = bad_data_double; @@ -228,6 +228,9 @@ void ECNTInfo::set(const PairDataEnsemble &pd) { // Store the number of ensemble members n_ens = pd.n_ens; + // HiRA data has no ensemble mean + bool skip_mean = pd.mn_na.has(bad_data_double); + // Compute empirical CRPS scores crps_emp = pd.crps_emp_na.wmean(pd.wgt_na); crpscl_emp = pd.crpscl_emp_na.wmean(pd.wgt_na); @@ -257,31 +260,10 @@ void ECNTInfo::set(const PairDataEnsemble &pd) { } } - // Compute ME and RMSE values - fbar = obar = ffbar = oobar = fobar = 0.0; - for(i=0; i " @@ -1276,7 +1280,7 @@ void VxPairDataEnsemble::set_interp(int i_interp, //////////////////////////////////////////////////////////////////////// void VxPairDataEnsemble::set_interp(int i_interp, InterpMthd mthd, - int width, GridTemplateFactory::GridTemplates shape) { + int width, GridTemplateFactory::GridTemplates shape) { for(int i=0; isize()); + } + else { + pd[i][j][k].set_ens_size(n); + } } } } @@ -1624,9 +1639,10 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, //////////////////////////////////////////////////////////////////////// void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { - int i, j, k, l; - int f_lvl_blw, f_lvl_abv; + int i, j, k, l, m; + int f_lvl_blw, f_lvl_abv, i_mem; double to_lvl, fcst_v; + NumArray fcst_na; // Set flag for specific humidity bool spfh_flag = fcst_info->get_var_info()->is_specific_humidity() && @@ -1637,9 +1653,24 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { for(j=0; j " + << "the \"" << interpmthd_to_string(pd[0][0][k].interp_mthd) + << "\" interpolation method only applies when verifying a " + << "single level, not " << fcst_dpa.n_planes() + << " levels.\n\n"; + continue; + } + // Process each of the observations for(l=0; lget_var_info()->level().type() == LevelType_Pres ? pd[i][j][k].lvl_na[l] : pd[i][j][k].elv_na[l]); @@ -1655,46 +1686,83 @@ void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { find_vert_lvl(fcst_dpa, to_lvl, f_lvl_blw, f_lvl_abv); } - // Compute the interpolated ensemble value - fcst_v = compute_interp(fcst_dpa, - pd[i][j][k].x_na[l], - pd[i][j][k].y_na[l], - pd[i][j][k].o_na[l], - pd[i][j][k].cmn_na[l], - pd[i][j][k].csd_na[l], - pd[0][0][k].interp_mthd, - pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, - gr.wrap_lon(), - interp_thresh, spfh_flag, - fcst_info->get_var_info()->level().type(), - to_lvl, f_lvl_blw, f_lvl_abv); - - // Store the ensemble mean - if(mn) { - pd[i][j][k].mn_na.add(fcst_v); + // Extract the HiRA neighborhood of values + if(pd[0][0][k].interp_mthd == InterpMthd_HiRA) { + + // For HiRA, set the ensemble mean to bad data + if(mn) { + fcst_na.erase(); + fcst_na.add(bad_data_double); + } + // Otherwise, retrieve all the neighborhood values + // using a valid threshold of 0 + else { + get_interp_points(fcst_dpa, + pd[i][j][k].x_na[l], + pd[i][j][k].y_na[l], + pd[0][0][k].interp_mthd, + pd[0][0][k].interp_wdth, + pd[0][0][k].interp_shape, + gr.wrap_lon(), + 0, spfh_flag, + fcst_info->get_var_info()->level().type(), + to_lvl, f_lvl_blw, f_lvl_abv, + fcst_na); + } } - // Store the ensemble member values + // Otherwise, get a single interpolated ensemble value else { + fcst_na.add(compute_interp(fcst_dpa, + pd[i][j][k].x_na[l], + pd[i][j][k].y_na[l], + pd[i][j][k].o_na[l], + pd[i][j][k].cmn_na[l], + pd[i][j][k].csd_na[l], + pd[0][0][k].interp_mthd, + pd[0][0][k].interp_wdth, + pd[0][0][k].interp_shape, + gr.wrap_lon(), + interp_thresh, spfh_flag, + fcst_info->get_var_info()->level().type(), + to_lvl, f_lvl_blw, f_lvl_abv)); + } - // Track unperturbed ensemble variance sums - // Exclude the control member from the variance - if(member != pd[i][j][k].ctrl_index) { - pd[i][j][k].add_ens_var_sums(l, fcst_v); - } + // Store the single ensemble value or HiRA neighborhood + for(m=0; mflag) { - fcst_v = add_obs_error_inc( - obs_error_info->rng_ptr, FieldType_Fcst, - pd[i][j][k].obs_error_entry[l], - pd[i][j][k].o_na[l], fcst_v); + // Store the ensemble mean + if(mn) { + pd[i][j][k].mn_na.add(fcst_na[m]); + } + // Store the ensemble member values + else { + + // Track unperturbed ensemble variance sums + // Exclude the control member from the variance + if(member != pd[i][j][k].ctrl_index) { + pd[i][j][k].add_ens_var_sums(l, fcst_na[m]); + } + + // Apply observation error perturbation, if requested + if(obs_error_info->flag) { + fcst_v = add_obs_error_inc( + obs_error_info->rng_ptr, FieldType_Fcst, + pd[i][j][k].obs_error_entry[l], + pd[i][j][k].o_na[l], fcst_na[m]); + } + else { + fcst_v = fcst_na[m]; + } + + // Determine index of ensemble member + i_mem = member * fcst_na.n() + m; + + // Store perturbed ensemble member value + pd[i][j][k].add_ens(i_mem, fcst_v); } - // Store perturbed ensemble member value - pd[i][j][k].add_ens(member, fcst_v); - } - } + } // end for m - fcst_na + } // end for l - n_obs } // end for k - n_interp } // end for j - n_mask } // end for i - n_msg_typ diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 078c547e8a..ce0784e84e 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -64,6 +64,7 @@ // 032 10/07/21 Halley Gotway MET #1905 Add -ctrl option. // 033 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. // 034 01/14/21 McCabe MET #1695 All members in one file. +// 035 02/15/22 Halley Gotway MET #1583 Add HiRA option. // //////////////////////////////////////////////////////////////////////// @@ -617,15 +618,20 @@ void process_n_vld() { n_vx_vld.clear(); // Loop through the ensemble fields to be processed - var_it = conf_info.ens_input.begin(); - n_ens_inputs = (*var_it)->inputs_n(); + if(conf_info.ens_input.size() > 0) { + var_it = conf_info.ens_input.begin(); + n_ens_inputs = (*var_it)->inputs_n(); + } + else { + n_ens_inputs = 0; + } for(i_var=0; var_it != conf_info.ens_input.end(); var_it++, i_var++) { // Loop through the ensemble inputs for(i_ens=n_vld=0; i_ens < n_ens_inputs; i_ens++) { - // get file and VarInfo to process + // Get file and VarInfo to process ens_file = (*var_it)->get_file(i_ens); var_info = (*var_it)->get_var_info(i_ens); @@ -1276,7 +1282,7 @@ int process_point_ens(int i_ens, int &n_miss) { info = conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info(i_ens); } - // if not processing mean, get file based on current vx and ensemble index + // If not processing mean, get file based on current vx and ensemble index if(!is_ens_mean) ens_file = conf_info.vx_opt[i].vx_pd.fcst_info->get_file(i_ens); // Read the gridded data from the input forecast file @@ -1381,9 +1387,11 @@ void process_point_scores() { for(l=0; l " - << mthd_str << " smoothing option not supported for " - << "gridded observations.\n\n"; + << mthd_str << " option not supported for " + << "smoothing gridded observations.\n\n"; continue; } @@ -2306,7 +2314,7 @@ void setup_nc_file(unixtime valid_ut, const char *suffix) { //////////////////////////////////////////////////////////////////////// void setup_txt_files() { - int i, n, n_phist_bin, n_vld, max_col; + int i, n, n_phist_bin, max_n_ens, max_col; ConcatString tmp_str; // Check to see if the text files have already been set up @@ -2327,16 +2335,19 @@ void setup_txt_files() { n_phist_bin = (n > n_phist_bin ? n : n_phist_bin); } - // Store the maximum number of valid verification fields - n_vld = n_vx_vld.max(); + // Get the maximum number of ensemble members, including HiRA + max_n_ens = n_vx_vld.max(); + if(conf_info.get_max_hira_size() > 0) { + max_n_ens *= conf_info.get_max_hira_size(); + } // Get the maximum number of data columns - max_col = max(get_n_orank_columns(n_vld+1), - get_n_rhist_columns(n_vld)); + max_col = max(get_n_orank_columns(max_n_ens+1), + get_n_rhist_columns(max_n_ens)); max_col = max(max_col, get_n_phist_columns(n_phist_bin)); max_col = max(max_col, n_ecnt_columns); max_col = max(max_col, n_ssvar_columns); - max_col = max(max_col, get_n_relp_columns(n_vld)); + max_col = max(max_col, get_n_relp_columns(max_n_ens)); max_col += n_header_columns; // Initialize file stream @@ -2387,7 +2398,7 @@ void setup_txt_files() { switch(i) { case(i_rhist): - max_col = get_n_rhist_columns(n_vld+1) + n_header_columns + 1; + max_col = get_n_rhist_columns(max_n_ens+1) + n_header_columns + 1; break; case(i_phist): @@ -2395,11 +2406,11 @@ void setup_txt_files() { break; case(i_relp): - max_col = get_n_relp_columns(n_vld) + n_header_columns + 1; + max_col = get_n_relp_columns(max_n_ens) + n_header_columns + 1; break; case(i_orank): - max_col = get_n_orank_columns(n_vld) + n_header_columns + 1; + max_col = get_n_orank_columns(max_n_ens) + n_header_columns + 1; break; default: @@ -2415,7 +2426,7 @@ void setup_txt_files() { switch(i) { case(i_rhist): - write_rhist_header_row(1, n_vld+1, txt_at[i], 0, 0); + write_rhist_header_row(1, max_n_ens+1, txt_at[i], 0, 0); break; case(i_phist): @@ -2423,11 +2434,11 @@ void setup_txt_files() { break; case(i_relp): - write_relp_header_row(1, n_vld, txt_at[i], 0, 0); + write_relp_header_row(1, max_n_ens, txt_at[i], 0, 0); break; case(i_orank): - write_orank_header_row(1, n_vld, txt_at[i], 0, 0); + write_orank_header_row(1, max_n_ens, txt_at[i], 0, 0); break; default: diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index e9aa6a2765..252d7eaeb9 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -98,10 +98,11 @@ void EnsembleStatConfInfo::clear() { ens_input.clear(); // Reset counts - n_ens_var = 0; - max_n_thresh = 0; - n_nbrhd = 0; - n_vx = 0; + n_ens_var = 0; + n_nbrhd = 0; + n_vx = 0; + max_n_thresh = 0; + max_hira_size = 0; return; } @@ -132,7 +133,7 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, StringArray * ens_files, StringArray * fcst_files, bool use_ctrl) { - int i,j, n_ens_files; + int i, j, n_ens_files; VarInfoFactory info_factory; mapoutput_map; Dictionary *edict = (Dictionary *) 0; @@ -230,14 +231,11 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, } // If no ensemble member IDs were provided, add an empty string - if(ens_member_ids.n() == 0) { - ens_member_ids.add(""); - } + if(ens_member_ids.n() == 0) ens_member_ids.add(""); // Conf: ens.field edict = conf.lookup_array(conf_key_ens_field); - // Determine the number of ensemble fields to be processed n_ens_var = parse_conf_n_vx(edict); @@ -251,7 +249,7 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, } // Parse the ensemble field information - for(i=0,max_n_thresh=0; iset_dict(i_edict); - // Dump the contents of the current VarInfo if(mlog.verbosity_level() >= 5) { mlog << Debug(5) @@ -296,7 +293,6 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, input_info.file_list = ens_files; ens_info->add_input(input_info); } // end for k - } // end for j // Get field info for control member if set @@ -315,7 +311,7 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, } // Conf: ens_nc_var_str - ens_info->nc_var_str =parse_conf_string(&i_edict, conf_key_nc_var_str, false); + ens_info->nc_var_str = parse_conf_string(&i_edict, conf_key_nc_var_str, false); // Conf: ens_nc_pairs // Only parse thresholds if probabilities are requested @@ -332,8 +328,8 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, } // Keep track of the maximum number of thresholds - if(ens_info->cat_ta.n_elements() > max_n_thresh) { - max_n_thresh = ens_info->cat_ta.n_elements(); + if(ens_info->cat_ta.n() > max_n_thresh) { + max_n_thresh = ens_info->cat_ta.n(); } } @@ -366,11 +362,11 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, } // Conf: nbrhd_prob - nbrhd_prob = parse_conf_nbrhd(edict, conf_key_nbrhd_prob); + nbrhd_prob = parse_conf_nbrhd(&conf, conf_key_nbrhd_prob); n_nbrhd = nbrhd_prob.width.n(); // Conf: nmep_smooth - nmep_smooth = parse_conf_interp(edict, conf_key_nmep_smooth); + nmep_smooth = parse_conf_interp(&conf, conf_key_nmep_smooth); // Loop through the neighborhood probability smoothing options for(i=0; isize()); + } + } } // Summarize output flags across all verification tasks @@ -580,7 +587,7 @@ void EnsembleStatConfInfo::process_masks(const Grid &grid) { vx_opt[i].mask_name_area.clear(); // Parse the masking grids - for(j=0; j " << "At least one grid, polyline or station ID masking " << "region must be provided for verification task number " @@ -740,15 +747,18 @@ void EnsembleStatVxOpt::clear() { vx_pd.clear(); var_str.clear(); beg_ds = end_ds = bad_data_int; + mask_grid.clear(); mask_poly.clear(); mask_sid.clear(); mask_llpnt.clear(); mask_name.clear(); mask_name_area.clear(); + msg_typ.clear(); othr_ta.clear(); cdf_info.clear(); + ci_alpha.clear(); interp_info.clear(); @@ -992,9 +1002,9 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, //////////////////////////////////////////////////////////////////////// void EnsembleStatVxOpt::set_vx_pd(EnsembleStatConfInfo *conf_info, int ctrl_index) { - int i, n; - int n_msg_typ = msg_typ.n_elements(); - int n_mask = mask_name.n_elements(); + int i, j, n; + int n_msg_typ = msg_typ.n(); + int n_mask = mask_name.n(); int n_interp = interp_info.n_interp; StringArray sa; @@ -1041,41 +1051,41 @@ void EnsembleStatVxOpt::set_vx_pd(EnsembleStatConfInfo *conf_info, int ctrl_inde for(i=0; imsg_typ_group_map[msg_typ[i]]; - if(sa.n_elements() == 0) sa.add(msg_typ[i]); + if(sa.n() == 0) sa.add(msg_typ[i]); vx_pd.set_msg_typ_vals(i, sa); } // Define the masking information: grid, poly, sid // Define the grid masks - for(i=0; imask_area_map[mask_name[n]])); } // Define the poly masks - for(i=0; imask_area_map[mask_name[n]])); } // Define the station ID masks - for(i=0; imask_sid_map[mask_name[n]])); } // Define the Lat/Lon point masks for(i=0; i<(int) mask_llpnt.size(); i++) { - n = i + mask_grid.n_elements() + mask_poly.n_elements() + mask_sid.n_elements(); + n = i + mask_grid.n() + mask_poly.n() + mask_sid.n(); vx_pd.set_mask_llpnt(n, mask_name[n].c_str(), &mask_llpnt[i]); } // Define the interpolation methods - for(i=0; i ens_input; // Vector of EnsVarInfo pointers (allocated) StringArray ens_member_ids; // Array of ensemble member ID strings ConcatString control_id; // Control ID - NbrhdInfo nbrhd_prob; // Neighborhood probability definition - int n_nbrhd; // Number of neighborhood sizes - InterpInfo nmep_smooth; // Neighborhood maximum smoothing information + NbrhdInfo nbrhd_prob; // Neighborhood probability definition + int n_nbrhd; // Number of neighborhood sizes + InterpInfo nmep_smooth; // Neighborhood maximum smoothing information - EnsembleStatVxOpt * vx_opt; // Array of vx task options [n_vx] (allocated) + EnsembleStatVxOpt * vx_opt; // Array of vx task options [n_vx] (allocated) - double vld_ens_thresh; // Required ratio of valid input files - double vld_data_thresh; // Required ratio of valid data for each point + double vld_ens_thresh; // Required ratio of valid input files + double vld_data_thresh; // Required ratio of valid data for each point // Message type groups that should be processed together map msg_typ_group_map; @@ -245,25 +246,30 @@ class EnsembleStatConfInfo { void set_vx_pd (const IntArray &, int); // Dump out the counts - int get_n_ens_var() const; - int get_max_n_thresh() const; - int get_n_nbrhd() const; - int get_n_vx() const; + int get_n_ens_var() const; + int get_n_nbrhd() const; + int get_n_vx() const; // Compute the maximum number of output lines possible based // on the contents of the configuration file int n_txt_row(int i) const; int n_stat_row() const; + + // Maximum across all verification tasks + int get_max_n_thresh() const; + int get_max_hira_size() const; + int get_compression_level(); }; //////////////////////////////////////////////////////////////////////// -inline int EnsembleStatConfInfo::get_n_ens_var() const { return(n_ens_var); } -inline int EnsembleStatConfInfo::get_max_n_thresh() const { return(max_n_thresh); } -inline int EnsembleStatConfInfo::get_n_nbrhd() const { return(n_nbrhd); } -inline int EnsembleStatConfInfo::get_n_vx() const { return(n_vx); } -inline int EnsembleStatConfInfo::get_compression_level() { return(conf.nc_compression()); } +inline int EnsembleStatConfInfo::get_n_ens_var() const { return(n_ens_var); } +inline int EnsembleStatConfInfo::get_n_nbrhd() const { return(n_nbrhd); } +inline int EnsembleStatConfInfo::get_n_vx() const { return(n_vx); } +inline int EnsembleStatConfInfo::get_max_n_thresh() const { return(max_n_thresh); } +inline int EnsembleStatConfInfo::get_max_hira_size() const { return(max_hira_size); } +inline int EnsembleStatConfInfo::get_compression_level() { return(conf.nc_compression()); } //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index edc3c02f1a..73dfa2af24 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -1221,7 +1221,7 @@ void process_scores() { // Appy HiRA verification and write ensemble output do_hira_ens(i, pd_ptr); - } // end HiRA for probabilities + } // end HiRA for ensembles // Apply HiRA probabilistic verification logic if(!conf_info.vx_opt[i].vx_pd.fcst_info->is_prob() && diff --git a/met/src/tools/core/point_stat/point_stat_conf_info.cc b/met/src/tools/core/point_stat/point_stat_conf_info.cc index 2d639a20d6..49f1de8a9c 100644 --- a/met/src/tools/core/point_stat/point_stat_conf_info.cc +++ b/met/src/tools/core/point_stat/point_stat_conf_info.cc @@ -1189,8 +1189,7 @@ int PointStatVxOpt::n_txt_row(int i_txt_row) const { n = (!prob_flag ? 0 : n_pd * get_n_oprob_thresh() * n_bin); // Number of HiRA PCT, PJC, or PRC lines = - // Message Types * Masks * Interpolations * Thresholds * - // HiRA widths + // Message Types * Masks * HiRA widths * Thresholds if(hira_info.flag) { n += (prob_flag ? 0 : n_pd * get_n_cat_thresh() * hira_info.width.n()); @@ -1206,8 +1205,8 @@ int PointStatVxOpt::n_txt_row(int i_txt_row) const { get_n_oprob_thresh() * get_n_ci_alpha() * n_bin); // Number of HiRA PSTD lines = - // Message Types * Masks * Interpolations * Thresholds * - // HiRA widths * Alphas + // Message Types * Masks * HiRA widths * Thresholds * + // Alphas if(hira_info.flag) { n += (prob_flag ? 0 : n_pd * get_n_cat_thresh() * hira_info.width.n() * @@ -1218,8 +1217,8 @@ int PointStatVxOpt::n_txt_row(int i_txt_row) const { case(i_ecnt): case(i_rps): - // Number of HiRA ECNT, ORANK and RPS lines = - // Message Types * Masks * Interpolations * HiRA widths * + // Number of HiRA ECNT and RPS lines = + // Message Types * Masks * HiRA widths * // Alphas if(hira_info.flag) { n = n_pd * hira_info.width.n() * get_n_ci_alpha(); @@ -1231,7 +1230,7 @@ int PointStatVxOpt::n_txt_row(int i_txt_row) const { break; case(i_orank): - // Number HiRA ORANK lines possible = + // Number of HiRA ORANK lines possible = // Number of pairs * Categorical Thresholds * // HiRA widths if(hira_info.flag) { From 10ca15c98182e10823cccc1321fd8a5ec678b093 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Fri, 18 Feb 2022 20:57:53 -0700 Subject: [PATCH 124/172] #1824 ci-run-test Reset itype to 1 for regular CAPE --- met/src/tools/other/pb2nc/pb2nc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index 0b914b3198..f08fca1038 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -1667,6 +1667,8 @@ void process_pbfile(int i_pb) { } if (cal_cape) { + ivirt = 1; + itype = 1; calcape_(&ivirt,&itype, cape_data_temp, cape_data_spfh, cape_data_pres, &p1d,&t1d,&q1d, static_dummy_201, &cape_level, &IMM,&JMM, &cape_level, From 6b78a896eb9bb7bf0da006b570a190c2b53ddf60 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 22 Feb 2022 11:14:36 -0700 Subject: [PATCH 125/172] SonarQube: check if pd_ptr is null --- met/src/tools/core/series_analysis/series_analysis.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/met/src/tools/core/series_analysis/series_analysis.cc b/met/src/tools/core/series_analysis/series_analysis.cc index 72a897fa02..da1fd2e0ff 100644 --- a/met/src/tools/core/series_analysis/series_analysis.cc +++ b/met/src/tools/core/series_analysis/series_analysis.cc @@ -662,6 +662,7 @@ void process_scores() { VarInfo *obs_info = (VarInfo *) 0; PairDataPoint *pd_ptr = (PairDataPoint *) 0; DataPlane fcst_dp, obs_dp; + const char *method_name = "process_scores() "; // Climatology mean and standard deviation DataPlane cmn_dp, csd_dp; @@ -763,6 +764,12 @@ void process_scores() { } // end for i_series + if(0 == pd_ptr) { + mlog << Debug(3) << method_name + << "PairDataPoint is not set. Skip computing statistics for each grid point in the block.\n"; + continue; + } + // Compute statistics for each grid point in the block for(i=0; i Date: Tue, 22 Feb 2022 11:16:53 -0700 Subject: [PATCH 126/172] #1824 Initialize cape_cnt_surface_msgs --- met/src/tools/other/pb2nc/pb2nc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index f08fca1038..64cbf77e3f 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -1017,7 +1017,7 @@ void process_pbfile(int i_pb) { // Initialize prev_hdr_lat = prev_hdr_lon = prev_hdr_elv = bad_data_double; - cape_level = cape_count = cape_cnt_too_big = 0; + cape_level = cape_count = cape_cnt_too_big = cape_cnt_surface_msgs = 0; cape_cnt_no_levels = cape_cnt_missing_values = cape_cnt_zero_values = 0; mlcape_count = mlcape_cnt_too_big = 0; mlcape_cnt_missing_values = mlcape_cnt_zero_values = 0; From 946e4ec4fb3b247d9bea2dcc06908f2232715567 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Tue, 22 Feb 2022 11:17:05 -0700 Subject: [PATCH 127/172] ci-run-test Removed trailing spaces --- met/src/tools/core/series_analysis/series_analysis.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/core/series_analysis/series_analysis.cc b/met/src/tools/core/series_analysis/series_analysis.cc index da1fd2e0ff..fc4c9d802b 100644 --- a/met/src/tools/core/series_analysis/series_analysis.cc +++ b/met/src/tools/core/series_analysis/series_analysis.cc @@ -769,7 +769,7 @@ void process_scores() { << "PairDataPoint is not set. Skip computing statistics for each grid point in the block.\n"; continue; } - + // Compute statistics for each grid point in the block for(i=0; i Date: Tue, 22 Feb 2022 14:14:42 -0700 Subject: [PATCH 128/172] Modified the PR template to add review of the source issue metadata ci-skip-all --- .github/pull_request_template.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c2984bffdf..7d99be08c6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -23,6 +23,7 @@ If **yes**, describe the new output and/or changes to the existing output:
## Pull Request Checklist ## See the [METplus Workflow](https://metplus.readthedocs.io/en/latest/Contributors_Guide/github_workflow.html) for details. +- [ ] Review the source issue metadata (required labels, projects, and milestone). - [ ] Complete the PR definition above. - [ ] Ensure the PR title matches the feature or bugfix branch name. - [ ] Define the PR metadata, as permissions allow. From 2c4e4afab21b6aea7926a208b26d5d71cc433425 Mon Sep 17 00:00:00 2001 From: davidalbo Date: Tue, 22 Feb 2022 17:01:23 -0700 Subject: [PATCH 129/172] feature_2054_helpEmailChanges (#2064) * found and made three changes replacing met_help@ucar.edu with the MetPlus gitub discussions page * Update met/docs/Users_Guide/appendixA.rst Thanks, a typo plus I am completely neutral as to the exact wording. Co-authored-by: jprestop * Update met/src/libcode/vx_data2d_grib2/data2d_grib2.cc Co-authored-by: jprestop * Update met/README Co-authored-by: jprestop Co-authored-by: jprestop --- met/README | 2 +- met/docs/Users_Guide/appendixA.rst | 5 ++--- met/src/libcode/vx_data2d_grib2/data2d_grib2.cc | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/met/README b/met/README index d05da60c0e..9ea770c2bf 100644 --- a/met/README +++ b/met/README @@ -22,7 +22,7 @@ This is the main directory for the Model Evaluation Tools source code release. For questions, please: - Refer to the MET User's Guide: https://met.readthedocs.io/en/latest - Refer to the MET website: http://dtcenter.org/community-code/model-evaluation-tools-met -- Send mail to met_help@ucar.edu. +- Create a post in the METplus GitHub Discussions forum: https://github.com/dtcenter/METplus/discussions Dependencies ------------ diff --git a/met/docs/Users_Guide/appendixA.rst b/met/docs/Users_Guide/appendixA.rst index 7bf41e810b..9b47a535bd 100644 --- a/met/docs/Users_Guide/appendixA.rst +++ b/met/docs/Users_Guide/appendixA.rst @@ -1777,9 +1777,8 @@ Try the following 2 things: MET_BUFRLIB=/home/username/BUFRLIB_v10.2.3 -After doing that, please try recompiling MET. If it fails, -please send met_help@ucar.edu the following log files. -"make_install.log" as well as "config.log". +After doing that, please try recompiling MET. If it fails, please submit the following log files: "make_install.log" as well as "config.log" with a new post in the `METplus GitHub Discussions Forum `_. + Command line double quotes -------------------------- diff --git a/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc b/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc index 5646a2f13c..0061d2fd00 100644 --- a/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc +++ b/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc @@ -704,7 +704,7 @@ void MetGrib2DataFile::read_grib2_record_list() { mlog << Error << "\nMetGrib2DataFile::data_plane() -> " << "PDS template number (" << gfld->ipdtnum << ") is not supported. " - << "Please email met_help@ucar.edu.\n\n"; + << "Please create a new post with this information in the METplus GitHub Discussions forum at https://github.com/dtcenter/METplus/discussions\n\n"; exit(1); } From 36bdf26943cb4baaf4cf4115634210e564452e3a Mon Sep 17 00:00:00 2001 From: jprestop Date: Wed, 23 Feb 2022 09:59:53 -0700 Subject: [PATCH 130/172] Feature set job controls (#2066) * Updated set_job_controls.sh to add a check for the skip all keyword * Added a space to check keyword ci-skip-all Co-authored-by: Julie Prestopnik --- .github/jobs/set_job_controls.sh | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh index e6605f959c..14f85ddb93 100755 --- a/.github/jobs/set_job_controls.sh +++ b/.github/jobs/set_job_controls.sh @@ -10,8 +10,8 @@ input_data_version=develop truth_data_version=develop if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then - - # only run diff logic if pull request INTO + + # only run diff logic if pull request INTO # branches not ending with -ref if [ "${GITHUB_BASE_REF: -4}" != "-ref" ]; then @@ -36,25 +36,37 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then if [ "$branch_name" == "develop" ] || [ "${branch_name:0:6}" == "main_v" ]; then - run_diff=true - truth_data_version=${branch_name} + run_diff=true + truth_data_version=${branch_name} fi + # check commit messages for skip or force keywords + if grep -q "ci-skip-all" <<< "$commit_msg"; then + + run_compile=false + run_push=false + run_unit_tests=false + run_diff=false + run_update_truth=false + + fi + # check commit messages for ci-skip or ci-run keywords if grep -q "ci-skip-compile" <<< "$commit_msg"; then - run_compile=false + run_compile=false fi if grep -q "ci-run-unit" <<< "$commit_msg"; then - run_diff=true + run_diff=true fi + fi - + fi # if updating truth or running diff, run unit tests From ab26b48bbbde523ad1459c50616be63976594ed0 Mon Sep 17 00:00:00 2001 From: johnhg Date: Wed, 23 Feb 2022 15:53:48 -0700 Subject: [PATCH 131/172] Feature 1918 std climo (#2061) --- met/data/config/ConfigConstants | 7 + met/data/config/GenEnsProdConfig_default | 1 + met/docs/Users_Guide/gen-ens-prod.rst | 20 ++ met/src/basic/vx_config/config_constants.h | 6 + met/src/basic/vx_config/config_util.cc | 30 ++ met/src/basic/vx_config/config_util.h | 2 + met/src/basic/vx_util/Makefile.am | 1 + met/src/basic/vx_util/data_plane.cc | 62 +++- met/src/basic/vx_util/data_plane.h | 11 +- met/src/basic/vx_util/normalize.cc | 125 +++++++ met/src/basic/vx_util/normalize.h | 56 ++++ met/src/basic/vx_util/vx_util.h | 1 + .../tools/other/gen_ens_prod/gen_ens_prod.cc | 305 ++++++++++++++---- .../gen_ens_prod/gen_ens_prod_conf_info.cc | 6 +- .../gen_ens_prod/gen_ens_prod_conf_info.h | 3 +- test/config/GenEnsProdConfig | 1 + test/config/GenEnsProdConfig_normalize | 152 +++++++++ test/config/GenEnsProdConfig_single_file_grib | 1 + test/config/GenEnsProdConfig_single_file_nc | 1 + test/xml/unit_gen_ens_prod.xml | 28 ++ 20 files changed, 737 insertions(+), 82 deletions(-) create mode 100644 met/src/basic/vx_util/normalize.cc create mode 100644 met/src/basic/vx_util/normalize.h create mode 100644 test/config/GenEnsProdConfig_normalize diff --git a/met/data/config/ConfigConstants b/met/data/config/ConfigConstants index 29b2590ada..8cbbeef1e9 100644 --- a/met/data/config/ConfigConstants +++ b/met/data/config/ConfigConstants @@ -170,3 +170,10 @@ BETA = 8; TOP = TRUE; BOTTOM = FALSE; +// Normalization types +NONE = 1; +CLIMO_ANOM = 2; +CLIMO_STD_ANOM = 3; +FCST_ANOM = 4; +FCST_STD_ANOM = 5; + diff --git a/met/data/config/GenEnsProdConfig_default b/met/data/config/GenEnsProdConfig_default index 09746b626e..7a3db915cd 100644 --- a/met/data/config/GenEnsProdConfig_default +++ b/met/data/config/GenEnsProdConfig_default @@ -38,6 +38,7 @@ regrid = { // censor_thresh = []; censor_val = []; +normalize = NONE; cat_thresh = []; nc_var_str = ""; diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index cd6f963b4f..e697dd5e1d 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -177,6 +177,26 @@ Each value in the array will replace the text **MET_ENS_MEMBER_ID**. to read a control member. This value is only used when the **-ctrl** command line argument is used. The value should not be found in the **ens_member_ids** array. +_____________________ + +.. code-block:: none + + normalize = NONE; + +The **normalize** option defines if and how the input ensemble member data should be normalized. Options are provided to normalize relative to an external climatology, specified using the **climo_mean** and **climo_stdev** dictionaries, or relative to current ensemble forecast being processed. The anomaly is computed by subtracting the (climatological or ensemble) mean from each ensemble memeber. The standard anomaly is computed by dividing the anomaly by the (climatological or ensemble) standard deviation. Values for the **normalize** option are described below: + +• **NONE** (default) to skip the normalization step and process the raw ensemble member data. + +• **CLIMO_ANOM** to subtract the climatological mean field. + +• **CLIMO_STD_ANOM** to subtract the climatological mean field and divide by the climatological standard deviation. + +• **FCST_ANOM** to subtract the current ensemble mean field. + +• **FCST_STD_ANOM** to subtract the current ensemble mean field and divide by the current ensemble standard deviation. + +Note that the **normalize** option may be specified separately for each entry in the **ens.field** array. + _______________________ .. code-block:: none diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index f3c5550f02..ae88c78d3e 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -752,6 +752,12 @@ static const char conf_key_dist_parm[] = "dist_parm"; static const char conf_key_inst_bias_scale[] = "inst_bias_scale"; static const char conf_key_inst_bias_offset[] = "inst_bias_offset"; +// +// Gen-Ens-Prod specific parameter key names +// + +static const char conf_key_normalize[] = "normalize"; + // Distribution options static const char conf_val_normal[] = "NORMAL"; static const char conf_val_exponential[] = "EXPONENTIAL"; diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index edeabb649a..e08ef7d19b 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -2981,3 +2981,33 @@ StringArray parse_conf_ens_member_ids(Dictionary *dict) { } /////////////////////////////////////////////////////////////////////////////// + +NormalizeType parse_conf_normalize(Dictionary *dict) { + NormalizeType t = NormalizeType_None; + int v; + + if(!dict) { + mlog << Error << "\nparse_conf_normalize() -> " + << "empty dictionary!\n\n"; + exit(1); + } + + // Get the integer flag value for the current entry + v = dict->lookup_int(conf_key_normalize); + + // Convert integer to enumerated NormalizeType + if(v == conf_const.lookup_int(normalizetype_none_str)) t = NormalizeType_None; + else if(v == conf_const.lookup_int(normalizetype_climo_anom_str)) t = NormalizeType_ClimoAnom; + else if(v == conf_const.lookup_int(normalizetype_climo_std_anom_str)) t = NormalizeType_ClimoStdAnom; + else if(v == conf_const.lookup_int(normalizetype_fcst_anom_str)) t = NormalizeType_FcstAnom; + else if(v == conf_const.lookup_int(normalizetype_fcst_std_anom_str)) t = NormalizeType_FcstStdAnom; + else { + mlog << Error << "\nparse_conf_normalize() -> " + << "Unexpected value of " << v << ".\n\n"; + exit(1); + } + + return(t); +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_config/config_util.h b/met/src/basic/vx_config/config_util.h index 5afcc974a1..d39d08b615 100644 --- a/met/src/basic/vx_config/config_util.h +++ b/met/src/basic/vx_config/config_util.h @@ -22,6 +22,7 @@ #include "config_file.h" #include "data_file_type.h" #include "config_gaussian.h" +#include "normalize.h" //////////////////////////////////////////////////////////////////////// @@ -78,6 +79,7 @@ extern map extern void parse_conf_range_int(Dictionary *dict, int &beg, int &end); extern void parse_conf_range_double(Dictionary *dict, double &beg, double &end); extern StringArray parse_conf_ens_member_ids(Dictionary *dict); +extern NormalizeType parse_conf_normalize(Dictionary *dict); extern void check_mask_names(const StringArray &); diff --git a/met/src/basic/vx_util/Makefile.am b/met/src/basic/vx_util/Makefile.am index ae466f0963..d0ab31bce7 100644 --- a/met/src/basic/vx_util/Makefile.am +++ b/met/src/basic/vx_util/Makefile.am @@ -37,6 +37,7 @@ libvx_util_a_SOURCES = ascii_table.cc ascii_table.h \ thresh_array.cc thresh_array.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 \ diff --git a/met/src/basic/vx_util/data_plane.cc b/met/src/basic/vx_util/data_plane.cc index 994c988029..618627dd63 100644 --- a/met/src/basic/vx_util/data_plane.cc +++ b/met/src/basic/vx_util/data_plane.cc @@ -406,23 +406,71 @@ void DataPlane::censor(const ThreshArray &censor_thresh, /////////////////////////////////////////////////////////////////////////////// +void DataPlane::anomaly(const DataPlane &mn) { + + // Check dimensions + if(Nxy != mn.Nxy) { + mlog << Error << "\nDataPlane::anomaly() -> " + << "the data dimensions do not match: (" + << Nx << ", " << Ny << ") != (" + << mn.Nx << ", " << mn.Ny << ")!\n\n"; + exit(1); + } -void DataPlane::replace_bad_data(const double value) + // Subtract the mean + for(int i=0; i " + << "the data dimensions do not match: (" + << Nx << ", " << Ny << ") != (" + << mn.Nx << ", " << mn.Ny << ") != (" + << sd.Nx << ", " << sd.Ny << ")!\n\n"; + exit(1); + } - if ( is_bad_data(Data[j]) ) Data[j] = value; + // Subtract the mean and divide by the standard deviation + for(int i=0; i +#include +#include +#include +#include + +#include "normalize.h" + +/////////////////////////////////////////////////////////////////////////////// + +ConcatString normalizetype_to_string(const NormalizeType type) { + ConcatString s; + + // Convert enumerated NormalizeType to string + switch(type) { + + case NormalizeType_None: + s = normalizetype_none_str; + break; + + case NormalizeType_ClimoAnom: + s = normalizetype_climo_anom_str; + break; + + case NormalizeType_ClimoStdAnom: + s = normalizetype_climo_std_anom_str; + break; + + case NormalizeType_FcstAnom: + s = normalizetype_fcst_anom_str; + break; + + case NormalizeType_FcstStdAnom: + s = normalizetype_fcst_std_anom_str; + break; + + default: + mlog << Error << "\nnormalizetype_to_string() -> " + << "Unexpected NormalizeType value of " << type << ".\n\n"; + exit(1); + } + + return(s); +} + +/////////////////////////////////////////////////////////////////////////////// + +void normalize_data(DataPlane &dp, const NormalizeType type, + const DataPlane *cmn_ptr, const DataPlane *csd_ptr, + const DataPlane *fmn_ptr, const DataPlane *fsd_ptr) { + + mlog << Debug(3) << "Normalizing input data using " + << normalizetype_to_string(type) << ".\n"; + + // Supported types + switch(type) { + + case NormalizeType_None: + break; + + case NormalizeType_ClimoAnom: + if(!cmn_ptr || dp.nxy() != cmn_ptr->nxy()) { + mlog << Error << "\nnormalize_data() -> " + << "the climatology mean is required for " + << normalizetype_to_string(type) << ".\n\n"; + exit(1); + } + dp.anomaly(*cmn_ptr); + break; + + case NormalizeType_ClimoStdAnom: + if(!cmn_ptr || dp.nxy() != cmn_ptr->nxy() || + !csd_ptr || dp.nxy() != csd_ptr->nxy()) { + mlog << Error << "\nnormalize_data() -> " + << "the climatology mean and standard deviation are required for " + << normalizetype_to_string(type) << ".\n\n"; + exit(1); + } + dp.standard_anomaly(*cmn_ptr, *csd_ptr); + break; + + case NormalizeType_FcstAnom: + if(!fmn_ptr || dp.nxy() != fmn_ptr->nxy()) { + mlog << Error << "\nnormalize_data() -> " + << "the forecast mean is required for " + << normalizetype_to_string(type) << ".\n\n"; + exit(1); + } + dp.anomaly(*fmn_ptr); + break; + + case NormalizeType_FcstStdAnom: + if(!fmn_ptr || dp.nxy() != fmn_ptr->nxy() || + !fsd_ptr || dp.nxy() != fsd_ptr->nxy()) { + mlog << Error << "\nnormalize_data() -> " + << "the forecast mean and standard deviation are required for " + << normalizetype_to_string(type) << ".\n\n"; + exit(1); + } + dp.standard_anomaly(*fmn_ptr, *fsd_ptr); + break; + + default: + mlog << Error << "\nnormalize_data() -> " + << "unexpected NormalizeType value (" + << type << ")\n\n"; + exit(1); + } // end switch + + return; +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/normalize.h b/met/src/basic/vx_util/normalize.h new file mode 100644 index 0000000000..90eff14999 --- /dev/null +++ b/met/src/basic/vx_util/normalize.h @@ -0,0 +1,56 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2022 +// ** 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 __NORMALIZE_H__ +#define __NORMALIZE_H__ + +/////////////////////////////////////////////////////////////////////////////// + +#include "concat_string.h" +#include "data_plane.h" + +/////////////////////////////////////////////////////////////////////////////// + +// +// Enumeration for normalization types +// + +enum NormalizeType { + NormalizeType_None, // No normalization + NormalizeType_ClimoAnom, // Subtract climo mean + NormalizeType_ClimoStdAnom, // Subtract climo mean and divide stdev + NormalizeType_FcstAnom, // Subtract fcst mean + NormalizeType_FcstStdAnom // Subtract fcst mean and divide stdev +}; + +/////////////////////////////////////////////////////////////////////////////// + +// +// String corresponding to the enumerated values above +// +static const char normalizetype_none_str[] = "NONE"; +static const char normalizetype_climo_anom_str[] = "CLIMO_ANOM"; +static const char normalizetype_climo_std_anom_str[] = "CLIMO_STD_ANOM"; +static const char normalizetype_fcst_anom_str[] = "FCST_ANOM"; +static const char normalizetype_fcst_std_anom_str[] = "FCST_STD_ANOM"; + +/////////////////////////////////////////////////////////////////////////////// + +extern ConcatString normalizetype_to_string(const NormalizeType); + +extern void normalize_data(DataPlane &, const NormalizeType, + const DataPlane *, const DataPlane *, + const DataPlane *, const DataPlane *); + +/////////////////////////////////////////////////////////////////////////////// + +#endif // __NORMALIZE_H__ + +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/vx_util.h b/met/src/basic/vx_util/vx_util.h index dceeaa62c1..e818c06da1 100644 --- a/met/src/basic/vx_util/vx_util.h +++ b/met/src/basic/vx_util/vx_util.h @@ -44,6 +44,7 @@ #include "long_array.h" #include "make_path.h" #include "memory.h" +#include "normalize.h" #include "num_array.h" #include "ordinal.h" #include "roman_numeral.h" diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 32f77cbf5c..83c4e5d1a4 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -17,6 +17,7 @@ // 000 09/10/21 Halley Gotway MET #1904 Initial version. // 001 11/15/21 Halley Gotway MET #1968 Ensemble -ctrl error check. // 002 01/14/21 McCabe MET #1695 All members in one file. +// 003 02/17/22 Halley Gotway MET #1918 Add normalize config option. // //////////////////////////////////////////////////////////////////////// @@ -53,6 +54,8 @@ using namespace std; static void process_command_line(int, char **); static void process_grid(const Grid &); static void process_ensemble(); + +static void get_ens_mean_stdev(GenEnsProdVarInfo *, DataPlane &, DataPlane &); static bool get_data_plane(const char *, GrdFileType, VarInfo *, DataPlane &); static void clear_counts(); @@ -69,7 +72,7 @@ static void write_ens_var_int(GenEnsProdVarInfo *, int *, const DataPlane &, static void write_ens_data_plane(GenEnsProdVarInfo *, const DataPlane &, const DataPlane &, const char *, const char *); -static void add_var_att_local(VarInfo *, NcVar *, bool is_int, +static void add_var_att_local(GenEnsProdVarInfo *, NcVar *, bool is_int, const DataPlane &, const char *, const char *); static void clean_up(); @@ -267,65 +270,15 @@ void process_grid(const Grid &fcst_grid) { //////////////////////////////////////////////////////////////////////// -bool get_data_plane(const char *infile, GrdFileType ftype, - VarInfo *info, DataPlane &dp) { - bool found; - Met2dDataFile *mtddf = (Met2dDataFile *) 0; - - // Read the current ensemble file - if(!(mtddf = mtddf_factory.new_met_2d_data_file(infile, ftype))) { - mlog << Error << "\nget_data_plane() -> " - << "trouble reading file \"" << infile << "\"\n\n"; - exit(1); - } - - // Read the gridded data field - if((found = mtddf->data_plane(*info, dp))) { - - // Setup the verification grid, if necessary - if(nxy == 0) process_grid(mtddf->grid()); - - // Create the output file, if necessary - if(nc_out == (NcFile *) 0) setup_nc_file(); - - // Regrid, if requested and necessary - if(!(mtddf->grid() == grid)) { - mlog << Debug(1) - << "Regridding field \"" << info->magic_str() - << "\" to the verification grid.\n"; - dp = met_regrid(dp, mtddf->grid(), grid, info->regrid()); - } - - // Store the valid time, if not already set - if(ens_valid_ut == (unixtime) 0) { - ens_valid_ut = dp.valid(); - } - // Check to make sure that the valid time doesn't change - else if(ens_valid_ut != dp.valid()) { - mlog << Warning << "\nget_data_plane() -> " - << "The valid time has changed, " - << unix_to_yyyymmdd_hhmmss(ens_valid_ut) - << " != " << unix_to_yyyymmdd_hhmmss(dp.valid()) - << " in \"" << infile << "\"\n\n"; - } - - } // end if found - - // Deallocate the data file pointer, if necessary - if(mtddf) { delete mtddf; mtddf = (Met2dDataFile *) 0; } - - return(found); -} - -//////////////////////////////////////////////////////////////////////// - void process_ensemble() { int i_var, i_ens, n_ens_vld, n_ens_inputs; bool need_reset; - DataPlane ens_dp, ctrl_dp, cmn_dp, csd_dp; + DataPlane ens_dp, ctrl_dp; + DataPlane cmn_dp, csd_dp; + DataPlane emn_dp, esd_dp; unixtime max_init_ut = bad_data_ll; - VarInfo * var_info; - ConcatString ens_file; + VarInfo *var_info; + ConcatString cs, ens_file; // Loop through each of the ensemble fields to be processed vector::const_iterator var_it = conf_info.ens_input.begin(); @@ -334,15 +287,23 @@ void process_ensemble() { // Need to reinitialize counts and sums for each ensemble field need_reset = true; + // Print out the normalization flag + cs << cs_erase; + if((*var_it)->normalize != NormalizeType_None) { + cs << " with normalize = " + << normalizetype_to_string((*var_it)->normalize); + } + cs << "\n"; + var_info = (*var_it)->get_var_info(); mlog << Debug(2) << "\n" << sep_str << "\n\n" << "Processing ensemble field: " - << (*var_it)->raw_magic_str << "\n"; + << (*var_it)->raw_magic_str << cs; n_ens_inputs = (*var_it)->inputs_n(); for(i_ens=n_ens_vld=0; i_ens < n_ens_inputs; i_ens++) { - // get file and VarInfo to process + // Get file and VarInfo to process ens_file = (*var_it)->get_file(i_ens); var_info = (*var_it)->get_var_info(i_ens); @@ -382,9 +343,19 @@ void process_ensemble() { conf_info.conf.lookup_array(conf_key_climo_stdev_field, false), i_var, ens_valid_ut, grid); + // Compute the ensemble summary data, if needed + if((*var_it)->normalize == NormalizeType_FcstAnom || + (*var_it)->normalize == NormalizeType_FcstStdAnom ) { + get_ens_mean_stdev((*var_it), emn_dp, esd_dp); + } + else { + emn_dp.erase(); + esd_dp.erase(); + } + // Read ensemble control member data, if provided if(ctrl_file.nonempty()) { - VarInfo * ctrl_info = (*var_it)->get_ctrl(i_ens); + VarInfo *ctrl_info = (*var_it)->get_ctrl(i_ens); mlog << Debug(3) << "\n" << "Reading control field: " @@ -400,6 +371,12 @@ void process_ensemble() { exit(1); } + // Normalize, if requested + if((*var_it)->normalize != NormalizeType_None) { + normalize_data(ctrl_dp, (*var_it)->normalize, + &cmn_dp, &csd_dp, &emn_dp, &esd_dp); + } + // Apply current data to the running sums and counts track_counts(*var_it, ctrl_dp, true, cmn_dp, csd_dp); @@ -414,6 +391,12 @@ void process_ensemble() { } // end if need_reset + // Normalize, if requested + if((*var_it)->normalize != NormalizeType_None) { + normalize_data(ens_dp, (*var_it)->normalize, + &cmn_dp, &csd_dp, &emn_dp, &esd_dp); + } + // Apply current data to the running sums and counts track_counts(*var_it, ens_dp, false, cmn_dp, csd_dp); @@ -447,6 +430,188 @@ void process_ensemble() { //////////////////////////////////////////////////////////////////////// +void get_ens_mean_stdev(GenEnsProdVarInfo *ens_info, + DataPlane &emn_dp, DataPlane &esd_dp) { + int i_ens, nxy, j; + double ens; + NumArray emn_cnt_na, emn_sum_na; + NumArray esd_cnt_na, esd_sum_na, esd_ssq_na; + VarInfo *var_info; + ConcatString ens_file; + DataPlane ens_dp; + + // Check for null pointer + if(!ens_info) { + mlog << Error << "\nget_ens_mean_stdev() -> " + << "null pointer!\n\n"; + exit(1); + } + + mlog << Debug(2) + << "Computing the ensemble mean and standard deviation for " + << ens_info->raw_magic_str << ".\n"; + + // Loop over the ensemble inputs + for(i_ens=0; i_ens < ens_info->inputs_n(); i_ens++) { + + // Get file and VarInfo to process + ens_file = ens_info->get_file(i_ens); + var_info = ens_info->get_var_info(i_ens); + + // Skip bad data files + if(!ens_file_vld[ens_info->get_file_index(i_ens)]) continue; + + // Read data and track the valid data count + if(!get_data_plane(ens_file.c_str(), etype, + var_info, ens_dp)) { + mlog << Warning << "\nget_ens_mean_stdev() -> " + << "ensemble field \"" << var_info->magic_str() + << "\" not found in file \"" << ens_file << "\"\n\n"; + continue; + } + + // Initialize sums, if needed + if(emn_cnt_na.n() == 0) { + nxy = ens_dp.nx()*ens_dp.ny(); + emn_cnt_na.set_const(0.0, nxy); + emn_sum_na = emn_cnt_na; + esd_cnt_na = emn_cnt_na; + esd_sum_na = emn_cnt_na; + esd_ssq_na = emn_cnt_na; + } + + // Update the counts and sums + for(j=0; jget_ctrl(0); + + // Error out if missing + if(!get_data_plane(ctrl_file.c_str(), etype, + var_info, ens_dp)) { + mlog << Error << "\nget_ens_mean_stdev() -> " + << "control member ensemble field \"" + << var_info->magic_str() + << "\" not found in file \"" << ctrl_file << "\"\n\n"; + exit(1); + } + + // Update counts and sums + for(j=0; j " + << "trouble reading file \"" << infile << "\"\n\n"; + exit(1); + } + + // Read the gridded data field + if((found = mtddf->data_plane(*info, dp))) { + + // Setup the verification grid, if necessary + if(nxy == 0) process_grid(mtddf->grid()); + + // Create the output file, if necessary + if(nc_out == (NcFile *) 0) setup_nc_file(); + + // Regrid, if requested and necessary + if(!(mtddf->grid() == grid)) { + mlog << Debug(1) + << "Regridding field \"" << info->magic_str() + << "\" to the verification grid.\n"; + dp = met_regrid(dp, mtddf->grid(), grid, info->regrid()); + } + + // Store the valid time, if not already set + if(ens_valid_ut == (unixtime) 0) { + ens_valid_ut = dp.valid(); + } + // Check to make sure that the valid time doesn't change + else if(ens_valid_ut != dp.valid()) { + mlog << Warning << "\nget_data_plane() -> " + << "The valid time has changed, " + << unix_to_yyyymmdd_hhmmss(ens_valid_ut) + << " != " << unix_to_yyyymmdd_hhmmss(dp.valid()) + << " in \"" << infile << "\"\n\n"; + } + + } // end if found + + // Deallocate the data file pointer, if necessary + if(mtddf) { delete mtddf; mtddf = (Met2dDataFile *) 0; } + + return(found); +} + +//////////////////////////////////////////////////////////////////////// + void clear_counts() { int i, j; @@ -471,7 +636,7 @@ void clear_counts() { //////////////////////////////////////////////////////////////////////// -void track_counts(GenEnsProdVarInfo * ens_info, const DataPlane &ens_dp, bool is_ctrl, +void track_counts(GenEnsProdVarInfo *ens_info, const DataPlane &ens_dp, bool is_ctrl, const DataPlane &cmn_dp, const DataPlane &csd_dp) { int i, j, k; double ens, cmn, csd; @@ -582,7 +747,7 @@ void setup_nc_file() { //////////////////////////////////////////////////////////////////////// -void write_ens_nc(GenEnsProdVarInfo * ens_info, int n_ens_vld, +void write_ens_nc(GenEnsProdVarInfo *ens_info, int n_ens_vld, const DataPlane &ens_dp, const DataPlane &cmn_dp, const DataPlane &csd_dp) { @@ -839,13 +1004,13 @@ void write_ens_nc(GenEnsProdVarInfo * ens_info, int n_ens_vld, //////////////////////////////////////////////////////////////////////// -void write_ens_var_float(GenEnsProdVarInfo * ens_info, float *ens_data, const DataPlane &dp, +void write_ens_var_float(GenEnsProdVarInfo *ens_info, float *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; - // Append nc_var_str config file entry + // Append nc_var_str config file entry, if specified cs = ens_info->nc_var_str; if(cs.length() > 0) var_str << "_" << cs; @@ -879,7 +1044,7 @@ void write_ens_var_float(GenEnsProdVarInfo * ens_info, float *ens_data, const Da } // Add the variable attributes - add_var_att_local(ens_info->get_var_info(), &ens_var, false, dp, + add_var_att_local(ens_info, &ens_var, false, dp, name_str.c_str(), long_name_str); // Write the data @@ -895,13 +1060,13 @@ void write_ens_var_float(GenEnsProdVarInfo * ens_info, float *ens_data, const Da //////////////////////////////////////////////////////////////////////// -void write_ens_var_int(GenEnsProdVarInfo * ens_info, int *ens_data, const DataPlane &dp, +void write_ens_var_int(GenEnsProdVarInfo *ens_info, int *ens_data, const DataPlane &dp, const char *type_str, const char *long_name_str) { NcVar ens_var; ConcatString ens_var_name, var_str, name_str, cs; - // Append nc_var_str config file entry + // Append nc_var_str config file entry, if specified cs = ens_info->nc_var_str; if(cs.length() > 0) var_str << "_" << cs; @@ -926,7 +1091,7 @@ void write_ens_var_int(GenEnsProdVarInfo * ens_info, int *ens_data, const DataPl << type_str; // Add the variable attributes - add_var_att_local(ens_info->get_var_info(), &ens_var, true, dp, + add_var_att_local(ens_info, &ens_var, true, dp, name_str.c_str(), long_name_str); // Write the data @@ -942,7 +1107,7 @@ void write_ens_var_int(GenEnsProdVarInfo * ens_info, int *ens_data, const DataPl //////////////////////////////////////////////////////////////////////// -void write_ens_data_plane(GenEnsProdVarInfo * ens_info, const DataPlane &ens_dp, const DataPlane &dp, +void write_ens_data_plane(GenEnsProdVarInfo *ens_info, const DataPlane &ens_dp, const DataPlane &dp, const char *type_str, const char *long_name_str) { // Allocate memory for this data @@ -962,11 +1127,13 @@ void write_ens_data_plane(GenEnsProdVarInfo * ens_info, const DataPlane &ens_dp, //////////////////////////////////////////////////////////////////////// -void add_var_att_local(VarInfo *info, NcVar *nc_var, bool is_int, +void add_var_att_local(GenEnsProdVarInfo *ens_info, + NcVar *nc_var, bool is_int, const DataPlane &dp, const char *name_str, const char *long_name_str) { ConcatString att_str; + VarInfo *info = ens_info->get_var_info(); // Construct the long name att_str << cs_erase diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc index 917e66c76a..7c90036af7 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc @@ -62,10 +62,9 @@ void GenEnsProdConfInfo::clear() { desc.clear(); for(; var_it != ens_input.end(); var_it++) { - if(*var_it) { delete *var_it; } - } + ens_input.clear(); cdf_info.clear(); nbrhd_prob.clear(); @@ -258,6 +257,9 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_fil // Keep track of the maximum number of thresholds if(ens_info->cat_ta.n() > max_n_cat) max_n_cat = ens_info->cat_ta.n(); + // Conf: normalize + ens_info->normalize = parse_conf_normalize(&i_edict); + // Conf: ensemble_flag ens_info->nc_info = parse_nc_info(&i_edict); diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h index 657a908026..f92a49d153 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.h @@ -122,7 +122,8 @@ inline int GenEnsProdConfInfo::get_compression_level() { return(conf.nc_compress class GenEnsProdVarInfo: public EnsVarInfo { public: - GenEnsProdNcOutInfo nc_info; // Ensemble product outputs + NormalizeType normalize; // Ensemble normalization logic + GenEnsProdNcOutInfo nc_info; // Ensemble product outputs }; #endif /* __GEN_ENS_PROD_CONF_INFO_H__ */ diff --git a/test/config/GenEnsProdConfig b/test/config/GenEnsProdConfig index 3c4af297ef..9e0e07dedd 100644 --- a/test/config/GenEnsProdConfig +++ b/test/config/GenEnsProdConfig @@ -38,6 +38,7 @@ regrid = { // censor_thresh = []; censor_val = []; +normalize = NONE; cat_thresh = []; nc_var_str = ""; diff --git a/test/config/GenEnsProdConfig_normalize b/test/config/GenEnsProdConfig_normalize new file mode 100644 index 0000000000..d07328e973 --- /dev/null +++ b/test/config/GenEnsProdConfig_normalize @@ -0,0 +1,152 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Gen-Ens-Prod configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "WRF"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "NA"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// May be set separately in each "field" entry +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +normalize = NONE; +cat_thresh = []; +nc_var_str = ""; + +// +// Ensemble fields to be processed +// +ens = { + ens_thresh = 0.80; + vld_thresh = 1.0; + + name = "TMP"; + level = "Z2"; + + field = [ + { normalize = NONE; }, + { normalize = CLIMO_ANOM; nc_var_str = "CLIMO_ANOM"; }, + { normalize = CLIMO_STD_ANOM; nc_var_str = "CLIMO_STD_ANOM"; }, + { normalize = FCST_ANOM; nc_var_str = "FCST_ANOM"; }, + { normalize = FCST_STD_ANOM; nc_var_str = "FCST_STD_ANOM"; } + ]; +} + +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood ensemble probabilities +// +nbrhd_prob = { + width = [ 5 ]; + shape = CIRCLE; + vld_thresh = 0.0; +} + +// +// NMEP smoothing methods +// +nmep_smooth = { + vld_thresh = 0.0; + shape = CIRCLE; + gaussian_dx = 81.27; + gaussian_radius = 120; + type = [ + { + method = GAUSSIAN; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = ens; +climo_mean = { + + file_name = [ "${CLIMO_MEAN_FILE}" ]; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 1; + hour_interval = 6; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = [ "${CLIMO_STDEV_FILE}" ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Ensemble product output types +// May be set separately in each "ens.field" entry +// +ensemble_flag = { + latlon = TRUE; + mean = TRUE; + stdev = TRUE; + minus = FALSE; + plus = FALSE; + min = TRUE; + max = TRUE; + range = FALSE; + vld_count = FALSE; + frequency = FALSE; + nep = FALSE; + nmep = FALSE; + climo = TRUE; + climo_cdp = TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// + +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_single_file_grib b/test/config/GenEnsProdConfig_single_file_grib index cc5edda640..c46677ab41 100644 --- a/test/config/GenEnsProdConfig_single_file_grib +++ b/test/config/GenEnsProdConfig_single_file_grib @@ -38,6 +38,7 @@ regrid = { // censor_thresh = []; censor_val = []; +normalize = NONE; cat_thresh = []; nc_var_str = ""; diff --git a/test/config/GenEnsProdConfig_single_file_nc b/test/config/GenEnsProdConfig_single_file_nc index 1049dc6a3a..d8e6e5aa6a 100644 --- a/test/config/GenEnsProdConfig_single_file_nc +++ b/test/config/GenEnsProdConfig_single_file_nc @@ -38,6 +38,7 @@ regrid = { // censor_thresh = []; censor_val = []; +normalize = NONE; cat_thresh = []; nc_var_str = ""; diff --git a/test/xml/unit_gen_ens_prod.xml b/test/xml/unit_gen_ens_prod.xml index 3c014a08f2..5aba6f154e 100644 --- a/test/xml/unit_gen_ens_prod.xml +++ b/test/xml/unit_gen_ens_prod.xml @@ -130,4 +130,32 @@
+ + echo "&DATA_DIR_MODEL;/grib1/arw-fer-gep1/arw-fer-gep1_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep2/arw-sch-gep2_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep3/arw-tom-gep3_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/nmm-fer-gep4/nmm-fer-gep4_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-fer-gep5/arw-fer-gep5_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-sch-gep6/arw-sch-gep6_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/arw-tom-gep7/arw-tom-gep7_2012040912_F024.grib \ + &DATA_DIR_MODEL;/grib1/nmm-fer-gep8/nmm-fer-gep8_2012040912_F024.grib" \ + > &OUTPUT_DIR;/gen_ens_prod/input_file_list; \ + &MET_BIN;/gen_ens_prod + + CLIMO_MEAN_FILE &DATA_DIR_CLIMO;/NCEP_1.0deg/cmean_1d.19790410 + CLIMO_STDEV_FILE &DATA_DIR_CLIMO;/NCEP_1.0deg/cstdv_1d.19790410 + + \ + -ens &OUTPUT_DIR;/gen_ens_prod/input_file_list \ + -ctrl &DATA_DIR_MODEL;/grib1/arw-tom-gep0/arw-tom-gep0_2012040912_F024.grib \ + -config &CONFIG_DIR;/GenEnsProdConfig_normalize \ + -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_NORMALIZE.nc \ + -v 2 + + + &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_NORMALIZE.nc + + + +
From 30ad6b6ee017542a3fae30ae9f62cde84e3ab236 Mon Sep 17 00:00:00 2001 From: johnhg Date: Thu, 24 Feb 2022 14:39:15 -0700 Subject: [PATCH 132/172] Feature 2070 obs_prepbufr_map (#2071) --- met/data/config/PB2NCConfig_default | 32 +++++++++++++++-------------- met/scripts/config/PB2NCConfig_G212 | 4 ++-- test/config/PB2NCConfig | 6 +++--- test/config/PB2NCConfig_airnow | 23 ++------------------- test/config/PB2NCConfig_all | 6 +++--- test/config/PB2NCConfig_pbl | 25 ++-------------------- test/config/PB2NCConfig_summary | 6 +++--- test/config/PB2NCConfig_vlevel | 7 +++---- 8 files changed, 35 insertions(+), 74 deletions(-) diff --git a/met/data/config/PB2NCConfig_default b/met/data/config/PB2NCConfig_default index 13110d221d..edbd17b6fc 100644 --- a/met/data/config/PB2NCConfig_default +++ b/met/data/config/PB2NCConfig_default @@ -108,21 +108,23 @@ obs_bufr_map = []; // This should not typically be overridden. // obs_prepbufr_map = [ - { key = "POB"; val = "PRES"; }, - { key = "QOB"; val = "SPFH"; }, - { key = "TOB"; val = "TMP"; }, - { key = "ZOB"; val = "HGT"; }, - { key = "UOB"; val = "UGRD"; }, - { key = "VOB"; val = "VGRD"; }, - { key = "D_DPT"; val = "DPT"; }, - { key = "D_WDIR"; val = "WDIR"; }, - { key = "D_WIND"; val = "WIND"; }, - { key = "D_RH"; val = "RH"; }, - { key = "D_MIXR"; val = "MIXR"; }, - { key = "D_PRMSL"; val = "PRMSL"; }, - { key = "D_PBL"; val = "PBL"; }, - { key = "D_CAPE"; val = "CAPE"; }, - { key = "D_MLCAPE"; val = "MLCAPE"; } + { key = "POB"; val = "PRES"; }, + { key = "QOB"; val = "SPFH"; }, + { key = "TOB"; val = "TMP"; }, + { key = "ZOB"; val = "HGT"; }, + { key = "UOB"; val = "UGRD"; }, + { key = "VOB"; val = "VGRD"; }, + { key = "HOVI"; val = "VIS"; }, + { key = "TOCC"; val = "TCDC"; }, + { key = "D_DPT"; val = "DPT"; }, + { key = "D_WDIR"; val = "WDIR"; }, + { key = "D_WIND"; val = "WIND"; }, + { key = "D_RH"; val = "RH"; }, + { key = "D_MIXR"; val = "MIXR"; }, + { key = "D_PRMSL"; val = "PRMSL"; }, + { key = "D_PBL"; val = "PBL"; }, + { key = "D_CAPE"; val = "CAPE"; }, + { key = "D_MLCAPE"; val = "MLCAPE"; } ]; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/PB2NCConfig_G212 b/met/scripts/config/PB2NCConfig_G212 index 0edaddf6e6..25108a011a 100644 --- a/met/scripts/config/PB2NCConfig_G212 +++ b/met/scripts/config/PB2NCConfig_G212 @@ -81,8 +81,8 @@ obs_bufr_var = [ "QOB", "TOB", "ZOB", "UOB", "VOB", //////////////////////////////////////////////////////////////////////////////// // -// Mapping of BUFR variable name to GRIB name. The default map is defined at -// obs_prepbufr_map. This replaces/expends the default map. +// Mapping of input BUFR variable names to output variables names. +// The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // obs_bufr_map = []; diff --git a/test/config/PB2NCConfig b/test/config/PB2NCConfig index fbd4b0418c..a75189ec01 100644 --- a/test/config/PB2NCConfig +++ b/test/config/PB2NCConfig @@ -81,10 +81,10 @@ obs_bufr_var = [ "QOB", "TOB", "ZOB", "UOB", "VOB", //////////////////////////////////////////////////////////////////////////////// // -// Mapping of BUFR variable name to GRIB name. The default map is defined at -// obs_prepbufr_map. It will be replaced/expended by obs_bufr_map. +// Mapping of input BUFR variable names to output variables names. +// The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // -//obs_bufr_map = []; +obs_bufr_map = []; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_airnow b/test/config/PB2NCConfig_airnow index 5fd9a2b01d..2a0a74ca08 100644 --- a/test/config/PB2NCConfig_airnow +++ b/test/config/PB2NCConfig_airnow @@ -85,30 +85,11 @@ obs_bufr_var = [ "COPO" ]; //////////////////////////////////////////////////////////////////////////////// // -// Mapping of BUFR variable name to GRIB name. The default map is defined at -// obs_prepbufr_map. This replaces/expends the default map. +// Mapping of input BUFR variable names to output variables names. +// The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // obs_bufr_map = []; -// -// This map is for PREPBUFR. It will be added into obs_bufr_map. -// Please do not override this map. -// -obs_prepbufr_map = [ - { key = "POB"; val = "PRES"; }, - { key = "QOB"; val = "SPFH"; }, - { key = "TOB"; val = "TMP"; }, - { key = "ZOB"; val = "HGT"; }, - { key = "UOB"; val = "UGRD"; }, - { key = "VOB"; val = "VGRD"; }, - { key = "D_DPT"; val = "DPT"; }, - { key = "D_WDIR"; val = "WDIR"; }, - { key = "D_WIND"; val = "WIND"; }, - { key = "D_RH"; val = "RH"; }, - { key = "D_MIXR"; val = "MIXR"; }, - { key = "D_PRMSL"; val = "PRMSL"; } -]; - //////////////////////////////////////////////////////////////////////////////// quality_mark_thresh = 2; diff --git a/test/config/PB2NCConfig_all b/test/config/PB2NCConfig_all index de74b934fe..7679b23413 100644 --- a/test/config/PB2NCConfig_all +++ b/test/config/PB2NCConfig_all @@ -80,10 +80,10 @@ obs_bufr_var = []; //////////////////////////////////////////////////////////////////////////////// // -// Mapping of BUFR variable name to GRIB name. The default map is defined at -// obs_prepbufr_map. This replaces/expends the default map. +// Mapping of input BUFR variable names to output variables names. +// The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // -//obs_bufr_map = []; +obs_bufr_map = []; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_pbl b/test/config/PB2NCConfig_pbl index ac48b5850f..a70d560df6 100644 --- a/test/config/PB2NCConfig_pbl +++ b/test/config/PB2NCConfig_pbl @@ -93,38 +93,17 @@ level_category = [0, 1, 4, 5, 6]; // If empty, process all available variables. // obs_bufr_var = ["D_CAPE", "D_PBL", "D_MLCAPE"]; + //////////////////////////////////////////////////////////////////////////////// // // Mapping of input BUFR variable names to output variables names. // The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // -obs_bufr_map = []; - -// -// Default mapping for PREPBUFR. Replace input BUFR variable names with GRIB -// abbreviations in the output. This default map is appended to obs_bufr_map. -// This should not typically be overridden. -// -obs_prepbufr_map = [ - { key = "POB"; val = "PRES"; }, - { key = "QOB"; val = "SPFH"; }, - { key = "TOB"; val = "TMP"; }, - { key = "UOB"; val = "UGRD"; }, - { key = "VOB"; val = "VGRD"; }, - { key = "D_DPT"; val = "DPT"; }, - { key = "D_WDIR"; val = "WDIR"; }, - { key = "D_WIND"; val = "WIND"; }, - { key = "D_RH"; val = "RH"; }, - { key = "D_MIXR"; val = "MIXR"; }, +obs_bufr_map = [ { key = "D_PBL"; val = "HPBL"; }, - { key = "D_PRMSL"; val = "PRMSL"; }, - { key = "D_CAPE"; val = "CAPE"; }, - { key = "D_MLCAPE"; val = "MLCAPE"; }, { key = "TDO"; val = "DPT"; }, { key = "PMO"; val = "PRMSL"; }, - { key = "TOCC"; val = "TCDC"; }, - { key = "HOVI"; val = "VIS"; }, { key = "CEILING"; val = "HGT"; }, { key = "MXGS"; val = "GUST"; } ]; diff --git a/test/config/PB2NCConfig_summary b/test/config/PB2NCConfig_summary index e2825f289e..af236e212f 100644 --- a/test/config/PB2NCConfig_summary +++ b/test/config/PB2NCConfig_summary @@ -81,10 +81,10 @@ obs_bufr_var = [ "QOB", "TOB", "ZOB", "UOB", "VOB", //////////////////////////////////////////////////////////////////////////////// // -// Mapping of BUFR variable name to GRIB name. The default map is defined at -// obs_prepbufr_map. It will be replaced/expended by obs_bufr_map. +// Mapping of input BUFR variable names to output variables names. +// The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // -//obs_bufr_map = []; +obs_bufr_map = []; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_vlevel b/test/config/PB2NCConfig_vlevel index 68a8d47925..011f37e9f9 100644 --- a/test/config/PB2NCConfig_vlevel +++ b/test/config/PB2NCConfig_vlevel @@ -80,11 +80,10 @@ obs_bufr_var = [ "RSTD", "RWAZ","RWND" ]; //////////////////////////////////////////////////////////////////////////////// // -// Mapping of BUFR variable name to GRIB name. The default map is defined at -// obs_prepbufr_map. This replaces/expends the default map. +// Mapping of input BUFR variable names to output variables names. +// The default PREPBUFR map, obs_prepbufr_map, is appended to this map. // -//obs_bufr_map = []; - +obs_bufr_map = []; //////////////////////////////////////////////////////////////////////////////// From eccbb38e94e4dbadd7124b167ef5fcc34265ffd7 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 24 Feb 2022 22:27:15 -0700 Subject: [PATCH 133/172] #1996 simplify the retrun statement (no effect with tf_left at the second return --- met/src/basic/vx_config/threshold.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/basic/vx_config/threshold.cc b/met/src/basic/vx_config/threshold.cc index 214cecaf94..5fd41723b0 100644 --- a/met/src/basic/vx_config/threshold.cc +++ b/met/src/basic/vx_config/threshold.cc @@ -139,7 +139,7 @@ if ( tf_left ) return ( true ); const bool tf_right = right_child->check(x, cmn, csd); -return ( tf_left || tf_right ); +return ( tf_right ); } From 37aef739982c936410df941e3141daea1ea3dbb8 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 24 Feb 2022 22:28:27 -0700 Subject: [PATCH 134/172] #1996 Add null terminator only if the pointer is not NULL --- met/src/basic/vx_util/ascii_table.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/met/src/basic/vx_util/ascii_table.cc b/met/src/basic/vx_util/ascii_table.cc index fa6845521f..0074c28071 100644 --- a/met/src/basic/vx_util/ascii_table.cc +++ b/met/src/basic/vx_util/ascii_table.cc @@ -1002,9 +1002,10 @@ if ( DoCommaString ) { p = strchr(junk, '.'); - if ( p ) *p = (char) 0; - - ++p; + if ( p ) { + *p = (char) 0; + ++p; + } X = atol(junk); @@ -1014,7 +1015,7 @@ if ( DoCommaString ) { s << j2; - if ( Precision > 0 ) s << '.' << p; + if ( Precision > 0 && p ) s << '.' << p; set_entry(r, c, s.string()); From 543370eae7a5367d739120622c05102e9fb6dac8 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 24 Feb 2022 22:30:50 -0700 Subject: [PATCH 135/172] #1996 Reduced duplicated for loops --- met/src/libcode/vx_shapedata/interest.cc | 33 ++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/met/src/libcode/vx_shapedata/interest.cc b/met/src/libcode/vx_shapedata/interest.cc index e3072a842d..c3557f33f5 100644 --- a/met/src/libcode/vx_shapedata/interest.cc +++ b/met/src/libcode/vx_shapedata/interest.cc @@ -601,23 +601,33 @@ void get_percentiles(DistributionPercentiles &ptile, const int perc, const bool precip_flag) { - int i, x, y, count, n_values; + int i, x, y, n_values; int nx, ny; double *v = (double *) 0; + double *v_tmp = (double *) 0; + const char *method_name = "get_percentiles() -> "; nx = raw.data.nx(); ny = raw.data.ny(); + v_tmp = new double[nx*ny]; + if(!v_tmp) { + mlog << Error << "\n" << method_name << "memory allocation error, v_tmp\n\n"; + exit(1); + } + // // Count values. - // Only check precipitation for values greater than zero. + // Only collect precipitation values greater than zero. // n_values = 0; for(x=0; x 0))) ++n_values; + (!precip_flag || (precip_flag && raw.data(x, y) > 0))) { + v_tmp[n_values++] = (double)(raw.data(x, y)); + } } } @@ -627,25 +637,15 @@ void get_percentiles(DistributionPercentiles &ptile, v = new double [n_values]; if(!v) { - mlog << Error << "\nget_percentiles() -> " - << "memory allocation error\n\n"; + mlog << Error << "\n" << method_name << "memory allocation error\n\n"; exit(1); } // // Fill values // - count = 0; - for(x=0; x 0))) { - - v[count++] = (double) (raw.data(x, y)); - } - } - } + for(x=0; x Date: Thu, 24 Feb 2022 22:31:45 -0700 Subject: [PATCH 136/172] #1996 Removed IsSet which is defined at the base class --- met/src/libcode/vx_tc_util/genesis_info.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/met/src/libcode/vx_tc_util/genesis_info.h b/met/src/libcode/vx_tc_util/genesis_info.h index c203334c3d..36e36b0d18 100644 --- a/met/src/libcode/vx_tc_util/genesis_info.h +++ b/met/src/libcode/vx_tc_util/genesis_info.h @@ -53,8 +53,6 @@ class GenesisInfo : public TrackInfo { void assign(const GenesisInfo &); - bool IsSet; - // Genesis Information int GenesisIndex; unixtime GenesisTime; From c5a80d57992124499471ec8c40b2d8d8cfef509f Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 24 Feb 2022 22:32:24 -0700 Subject: [PATCH 137/172] #1996 Initialize the variable --- met/src/libcode/vx_nc_obs/met_point_data.cc | 1 + met/src/libcode/vx_nc_obs/nc_obs_util.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc index 8eb762b008..d512fd8d91 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.cc +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -403,6 +403,7 @@ void MetPointHeader::reset_counters() { strl_len = 0; strll_len = 0; hdr_count = 0; + hdr_type_count = 0; min_vld_time = -1; max_vld_time = -1; diff --git a/met/src/libcode/vx_nc_obs/nc_obs_util.cc b/met/src/libcode/vx_nc_obs/nc_obs_util.cc index 42c14fd747..036122b8a3 100644 --- a/met/src/libcode/vx_nc_obs/nc_obs_util.cc +++ b/met/src/libcode/vx_nc_obs/nc_obs_util.cc @@ -63,6 +63,7 @@ void NcDataBuffer::reset_counters() { hdr_data_offset = 0; pb_hdr_count = 0; pb_hdr_data_offset = 0; + prev_hdr_vld = 0; } /////////////////////////////////////////////////////////////////////////////// @@ -988,6 +989,7 @@ void NetcdfObsVars::reset(bool _use_var_id) { deflate_level = 0; hdr_cnt = 0; // header array length (fixed dimension if hdr_cnt > 0) obs_cnt = 0; // obs. array length (fixed dimension if obs_cnt > 0) + raw_hdr_cnt = 0; //hdr_str_len = 0; // string length for header (message) type header } From 40569fff3f2859277c942a1d5cfc8e85ceaa3691 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Thu, 24 Feb 2022 22:32:58 -0700 Subject: [PATCH 138/172] #1996 ci-run-test Initialize the variable, nxy --- met/src/tools/other/gen_ens_prod/gen_ens_prod.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index 83c4e5d1a4..e0c16fc022 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -451,6 +451,7 @@ void get_ens_mean_stdev(GenEnsProdVarInfo *ens_info, << "Computing the ensemble mean and standard deviation for " << ens_info->raw_magic_str << ".\n"; + nxy = 0; // Loop over the ensemble inputs for(i_ens=0; i_ens < ens_info->inputs_n(); i_ens++) { From 107ac3208cc247f4d5ef7fa9e4e30978b148cf8c Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 1 Mar 2022 21:09:34 -0700 Subject: [PATCH 139/172] Feature 1918 climo_ens_member_id (#2075) * Per #1918, store the ensemble_member_id string in the EnsVarInfo class so that we can use it later, if needed, when reading climatological data which may also make use of that string. * Per #1918, update gen_ens_prod to set the MET_ENS_MEMBER_ID environment variable when reading climatology data if the ens_member_ids config option has been set and the normalizing relative to climatology has been requested. * Per #1918, add log messages to read_climo.cc and gen_ens_prod.cc to clarify what data is being read from which climo data files. * Added documentation on MET_ENS_MEMBER_ID usage in climo file name * updated usage langauge * Per #1918, adding gen_ens_prod unit test to demonstrate using ENS_MEMBER_ID to read climo data separately for each member. * Per #1918, adding gen_ens_prod unit test to demonstrate using ENS_MEMBER_ID to read climo data separately for each member. Co-authored-by: j-opatz <59586397+j-opatz@users.noreply.github.com> --- met/docs/Users_Guide/gen-ens-prod.rst | 12 ++ met/src/libcode/vx_data2d/var_info.cc | 6 + met/src/libcode/vx_data2d/var_info.h | 8 +- met/src/libcode/vx_statistics/read_climo.cc | 6 + .../tools/other/gen_ens_prod/gen_ens_prod.cc | 80 +++++++-- .../tools/other/gen_ens_prod/gen_ens_prod.h | 2 +- .../gen_ens_prod/gen_ens_prod_conf_info.cc | 2 + .../GenEnsProdConfig_climo_anom_ens_member_id | 161 ++++++++++++++++++ test/config/GenEnsProdConfig_single_file_nc | 2 +- test/xml/unit_gen_ens_prod.xml | 16 ++ 10 files changed, 277 insertions(+), 18 deletions(-) create mode 100644 test/config/GenEnsProdConfig_climo_anom_ens_member_id diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index e697dd5e1d..be482edbcd 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -173,6 +173,18 @@ Each value in the array will replace the text **MET_ENS_MEMBER_ID**. ]; } +This replacement behavior can also be applied to climatology file name entry, in the +climo_mean and climo_stdev dictionaries. + +.. code-block:: none + + climo_mean = { + file_name = ["/path/to/file/memberMET_ENS_MEMBER_ID-mean.nc"]; + } + +This substitution method can only be used if **ens_member_ids** has at least one entry +and the **normalize** option is set to **CLIMO_ANOM** or **CLIMO_STD_ANOM**. + **control_id** is a string that is substituted in the same way as the **ens_member_ids** values to read a control member. This value is only used when the **-ctrl** command line argument is used. The value should not be found in the **ens_member_ids** array. diff --git a/met/src/libcode/vx_data2d/var_info.cc b/met/src/libcode/vx_data2d/var_info.cc index f80a0bee69..d8975033ed 100644 --- a/met/src/libcode/vx_data2d/var_info.cc +++ b/met/src/libcode/vx_data2d/var_info.cc @@ -892,6 +892,12 @@ int EnsVarInfo::get_file_index(int index) { //////////////////////////////////////////////////////////////////////// +ConcatString EnsVarInfo::get_ens_member_id(int index) { + return inputs[index].ens_member_id; +} + +//////////////////////////////////////////////////////////////////////// + ConcatString raw_magic_str(Dictionary i_edict, GrdFileType file_type) { ConcatString magic_str; diff --git a/met/src/libcode/vx_data2d/var_info.h b/met/src/libcode/vx_data2d/var_info.h index 3661b07ee3..d32715d130 100644 --- a/met/src/libcode/vx_data2d/var_info.h +++ b/met/src/libcode/vx_data2d/var_info.h @@ -258,9 +258,10 @@ inline int VarInfo::accum_attr() const { return(SetAttrAccum); } // struct InputInfo { - VarInfo * var_info; // Variable information to read - int file_index; // Index in file_list of file to read - StringArray * file_list; // Array of files (unallocated) + VarInfo * var_info; // Variable information to read + int file_index; // Index in file_list of file to read + StringArray * file_list; // Array of files (unallocated) + ConcatString ens_member_id; // MET_ENS_MEMBER_ID string }; //////////////////////////////////////////////////////////////////////// @@ -292,6 +293,7 @@ class EnsVarInfo { VarInfo * get_var_info(int index=0); ConcatString get_file(int index=0); int get_file_index(int index=0); + ConcatString get_ens_member_id(int index=0); ConcatString nc_var_str; // Ensemble variable name strings ThreshArray cat_ta; // Ensemble categorical thresholds diff --git a/met/src/libcode/vx_statistics/read_climo.cc b/met/src/libcode/vx_statistics/read_climo.cc index 57e5e575c2..cb6a0efb17 100644 --- a/met/src/libcode/vx_statistics/read_climo.cc +++ b/met/src/libcode/vx_statistics/read_climo.cc @@ -243,6 +243,12 @@ void read_climo_file(const char *climo_file, GrdFileType ctype, } } + // Print log message for matching record + mlog << Debug(4) + << "Found matching " << cur_ut_cs << " \"" + << info->magic_str() << "\" climatology field in file \"" + << climo_file << "\".\n"; + // Regrid, if needed if(!(mtddf->grid() == vx_grid)) { mlog << Debug(2) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index e0c16fc022..eb04d6f38c 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -55,6 +55,8 @@ static void process_command_line(int, char **); static void process_grid(const Grid &); static void process_ensemble(); +static void get_climo_mean_stdev(GenEnsProdVarInfo *, int, + bool, int, DataPlane &, DataPlane &); static void get_ens_mean_stdev(GenEnsProdVarInfo *, DataPlane &, DataPlane &); static bool get_data_plane(const char *, GrdFileType, VarInfo *, DataPlane &); @@ -272,7 +274,7 @@ void process_grid(const Grid &fcst_grid) { void process_ensemble() { int i_var, i_ens, n_ens_vld, n_ens_inputs; - bool need_reset; + bool need_reset, set_climo_ens_mem_id; DataPlane ens_dp, ctrl_dp; DataPlane cmn_dp, csd_dp; DataPlane emn_dp, esd_dp; @@ -287,6 +289,13 @@ void process_ensemble() { // Need to reinitialize counts and sums for each ensemble field need_reset = true; + // When normalizing relative to climatology with MET_ENS_MEMBER_ID set, + // read climatology separately for each member + set_climo_ens_mem_id = + (conf_info.ens_member_ids.n() > 1) && + ((*var_it)->normalize == NormalizeType_ClimoAnom || + (*var_it)->normalize == NormalizeType_ClimoStdAnom); + // Print out the normalization flag cs << cs_erase; if((*var_it)->normalize != NormalizeType_None) { @@ -310,9 +319,9 @@ void process_ensemble() { // Skip bad data files if(!ens_file_vld[(*var_it)->get_file_index(i_ens)]) continue; - mlog << Debug(3) << "\n" - << "Reading field: " - << var_info->magic_str() << "\n"; + mlog << Debug(3) + << "\nReading ensemble field \"" + << var_info->magic_str() << "\".\n"; // Read data and track the valid data count if(!get_data_plane(ens_file.c_str(), etype, @@ -335,17 +344,13 @@ void process_ensemble() { clear_counts(); // Read climatology data for this field - cmn_dp = read_climo_data_plane( - conf_info.conf.lookup_array(conf_key_climo_mean_field, false), - i_var, ens_valid_ut, grid); - - csd_dp = read_climo_data_plane( - conf_info.conf.lookup_array(conf_key_climo_stdev_field, false), - i_var, ens_valid_ut, grid); + get_climo_mean_stdev((*var_it), i_var, + set_climo_ens_mem_id, + i_ens, cmn_dp, csd_dp); // Compute the ensemble summary data, if needed if((*var_it)->normalize == NormalizeType_FcstAnom || - (*var_it)->normalize == NormalizeType_FcstStdAnom ) { + (*var_it)->normalize == NormalizeType_FcstStdAnom) { get_ens_mean_stdev((*var_it), emn_dp, esd_dp); } else { @@ -371,6 +376,13 @@ void process_ensemble() { exit(1); } + // Read climo data with MET_ENS_MEMBER_ID set + if(set_climo_ens_mem_id) { + get_climo_mean_stdev((*var_it), i_var, + set_climo_ens_mem_id, i_ens, + cmn_dp, csd_dp); + } + // Normalize, if requested if((*var_it)->normalize != NormalizeType_None) { normalize_data(ctrl_dp, (*var_it)->normalize, @@ -391,6 +403,13 @@ void process_ensemble() { } // end if need_reset + // Read climo data with MET_ENS_MEMBER_ID set + if(set_climo_ens_mem_id) { + get_climo_mean_stdev((*var_it), i_var, + set_climo_ens_mem_id, i_ens, + cmn_dp, csd_dp); + } + // Normalize, if requested if((*var_it)->normalize != NormalizeType_None) { normalize_data(ens_dp, (*var_it)->normalize, @@ -411,7 +430,7 @@ void process_ensemble() { if(((double) n_ens_vld/n_ens_inputs) < conf_info.vld_ens_thresh) { mlog << Error << "\nprocess_ensemble() -> " << n_ens_vld << " of " << n_ens_inputs - << " (" << (double)n_ens_vld/n_ens_inputs << ")" + << " (" << (double)n_ens_vld/n_ens_inputs << ")" << " fields found for \"" << (*var_it)->get_var_info()->magic_str() << "\" does not meet the threshold specified by \"" << conf_key_ens_ens_thresh << "\" (" << conf_info.vld_ens_thresh @@ -430,6 +449,41 @@ void process_ensemble() { //////////////////////////////////////////////////////////////////////// +void get_climo_mean_stdev(GenEnsProdVarInfo *ens_info, int i_var, + bool set_ens_mem_id, int i_ens, + DataPlane &cmn_dp, DataPlane &csd_dp) { + + // Set the MET_ENS_MEMBER_ID environment variable + if(set_ens_mem_id) { + setenv(met_ens_member_id, ens_info->get_ens_member_id(i_ens).c_str(), 1); + } + + mlog << Debug(4) + << "Reading climatology mean data for ensemble field \"" + << ens_info->get_var_info(i_ens)->magic_str() << "\".\n"; + + cmn_dp = read_climo_data_plane( + conf_info.conf.lookup_array(conf_key_climo_mean_field, false), + i_var, ens_valid_ut, grid); + + mlog << Debug(4) + << "Reading climatology standard deviation data for ensemble field \"" + << ens_info->get_var_info(i_ens)->magic_str() << "\".\n"; + + csd_dp = read_climo_data_plane( + conf_info.conf.lookup_array(conf_key_climo_stdev_field, false), + i_var, ens_valid_ut, grid); + + // Unset the MET_ENS_MEMBER_ID environment variable + if(set_ens_mem_id) { + unsetenv(met_ens_member_id); + } + + return; +} + +//////////////////////////////////////////////////////////////////////// + void get_ens_mean_stdev(GenEnsProdVarInfo *ens_info, DataPlane &emn_dp, DataPlane &esd_dp) { int i_ens, nxy, j; diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.h b/met/src/tools/other/gen_ens_prod/gen_ens_prod.h index 8cfa4e5600..332c7594a7 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.h +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.h @@ -14,7 +14,7 @@ // // Mod# Date Name Description // ---- ---- ---- ----------- -// 000 09/10/21 Halley Gotway Initial version (MET #1904). +// 000 09/10/21 Halley Gotway MET #1904 Initial version. // //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc index 7c90036af7..2fa8f182b2 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod_conf_info.cc @@ -213,6 +213,7 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_fil input_info.var_info = next_var; input_info.file_index = 0; input_info.file_list = ens_files; + input_info.ens_member_id = ens_member_ids[j]; ens_info->add_input(input_info); // Add InputInfo to ens info list for each ensemble file provided @@ -221,6 +222,7 @@ void GenEnsProdConfInfo::process_config(GrdFileType etype, StringArray * ens_fil input_info.var_info = NULL; input_info.file_index = k; input_info.file_list = ens_files; + input_info.ens_member_id = ens_member_ids[j]; ens_info->add_input(input_info); } // end for k diff --git a/test/config/GenEnsProdConfig_climo_anom_ens_member_id b/test/config/GenEnsProdConfig_climo_anom_ens_member_id new file mode 100644 index 0000000000..de251a3445 --- /dev/null +++ b/test/config/GenEnsProdConfig_climo_anom_ens_member_id @@ -0,0 +1,161 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Gen-Ens-Prod configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "CFSv2"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "NA"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// May be set separately in each "field" entry +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// May be set separately in each "field" entry +// +censor_thresh = []; +censor_val = []; +normalize = CLIMO_STD_ANOM; +cat_thresh = []; +nc_var_str = ""; + +// +// Ensemble fields to be processed +// +ens = { + file_type = NETCDF_NCCF; + ens_thresh = 0.3; + vld_thresh = 0.3; + + field = [ + { + name = "fcst"; + level = "(MET_ENS_MEMBER_ID,0,*,*)"; + cat_thresh = [ <-0.43, >-0.43&&<=0.43, >0.43 ]; + } + ]; +} + +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = ["0","1","2"]; +control_id = ""; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood ensemble probabilities +// +nbrhd_prob = { + width = [ 5 ]; + shape = CIRCLE; + vld_thresh = 0.0; +} + +// +// NMEP smoothing methods +// +nmep_smooth = { + vld_thresh = 0.0; + shape = CIRCLE; + gaussian_dx = 81.27; + gaussian_radius = 120; + type = [ + { + method = GAUSSIAN; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology data +// +climo_mean = { + + file_name = [ "${CLIMO_MEAN_FILE}" ]; + field = [ + { + name = "series_cnt_FBAR"; + level = "(*,*)"; + } + ]; + + regrid = { + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = NA; + hour_interval = NA; +} + +climo_stdev = { + + file_name = [ "${CLIMO_STDEV_FILE}" ]; + field = [ + { + name = "series_cnt_FSTDEV"; + level = "(*,*)"; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Ensemble product output types +// May be set separately in each "ens.field" entry +// +ensemble_flag = { + latlon = TRUE; + mean = TRUE; + stdev = TRUE; + minus = FALSE; + plus = FALSE; + min = FALSE; + max = FALSE; + range = FALSE; + vld_count = FALSE; + frequency = TRUE; + nep = FALSE; + nmep = FALSE; + climo = FALSE; + climo_cdp = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_single_file_nc b/test/config/GenEnsProdConfig_single_file_nc index d8e6e5aa6a..f18517e2a7 100644 --- a/test/config/GenEnsProdConfig_single_file_nc +++ b/test/config/GenEnsProdConfig_single_file_nc @@ -9,7 +9,7 @@ // // Output model name to be written // -model = "WRF"; +model = "CFSv2"; // // Output description to be written diff --git a/test/xml/unit_gen_ens_prod.xml b/test/xml/unit_gen_ens_prod.xml index 5aba6f154e..c0bac636be 100644 --- a/test/xml/unit_gen_ens_prod.xml +++ b/test/xml/unit_gen_ens_prod.xml @@ -157,5 +157,21 @@ + + &MET_BIN;/gen_ens_prod + + CLIMO_MEAN_FILE &DATA_DIR_MODEL;/CPC_NMME/memberMET_ENS_MEMBER_ID-climo.nc + CLIMO_STDEV_FILE &DATA_DIR_MODEL;/CPC_NMME/memberMET_ENS_MEMBER_ID-climo.nc + + \ + -ens &DATA_DIR_MODEL;/CPC_NMME/CFSv2.tmp2m.198201.fcst.nc \ + -config &CONFIG_DIR;/GenEnsProdConfig_climo_anom_ens_member_id \ + -out &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_CLIMO_ANOM_ENS_MEMBER_ID.nc \ + -v 2 + + + &OUTPUT_DIR;/gen_ens_prod/gen_ens_prod_CLIMO_ANOM_ENS_MEMBER_ID.nc + +
From 514c0c3da00cb0c42b0f60e136b2e87e848953f8 Mon Sep 17 00:00:00 2001 From: johnhg Date: Wed, 2 Mar 2022 11:21:02 -0700 Subject: [PATCH 140/172] Feature 1259 es_prob_stats (#2067) --- met/data/config/EnsembleStatConfig_default | 53 +- met/docs/Users_Guide/ensemble-stat.rst | 71 +- met/scripts/config/EnsembleStatConfig | 75 +- met/src/basic/vx_config/config_constants.h | 1 + met/src/basic/vx_util/thresh_array.cc | 21 + met/src/basic/vx_util/thresh_array.h | 1 + .../libcode/vx_statistics/compute_stats.cc | 7 +- met/src/libcode/vx_statistics/compute_stats.h | 2 +- met/src/libcode/vx_statistics/ens_stats.cc | 17 +- .../tools/core/ensemble_stat/ensemble_stat.cc | 720 ++++++++++++------ .../tools/core/ensemble_stat/ensemble_stat.h | 18 +- .../ensemble_stat/ensemble_stat_conf_info.cc | 135 +++- .../ensemble_stat/ensemble_stat_conf_info.h | 72 +- met/src/tools/core/point_stat/point_stat.cc | 1 - test/config/EnsembleStatConfig | 70 +- test/config/EnsembleStatConfig_MASK_SID | 70 +- test/config/EnsembleStatConfig_climo | 127 +-- test/config/EnsembleStatConfig_grid_weight | 54 +- test/config/EnsembleStatConfig_one_cdf_bin | 118 ++- test/config/EnsembleStatConfig_python | 80 +- test/config/EnsembleStatConfig_qty_inc_exc | 66 +- .../EnsembleStatConfig_single_file_grib | 72 +- test/config/EnsembleStatConfig_single_file_nc | 54 +- test/xml/unit_climatology_1.0deg.xml | 5 + test/xml/unit_met_test_scripts.xml | 10 +- 25 files changed, 1327 insertions(+), 593 deletions(-) diff --git a/met/data/config/EnsembleStatConfig_default b/met/data/config/EnsembleStatConfig_default index 339ab939be..1cb84c3714 100644 --- a/met/data/config/EnsembleStatConfig_default +++ b/met/data/config/EnsembleStatConfig_default @@ -26,7 +26,6 @@ obtype = "ANALYS"; // // Verification grid -// May be set separately in each "field" entry // regrid = { to_grid = NONE; @@ -39,7 +38,7 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// // -// May be set separately in each "field" entry +// May be set separately in each "ens.field" entry // censor_thresh = []; censor_val = []; @@ -98,6 +97,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -117,16 +131,16 @@ obs = fcst; // Point observation filtering options // May be set separately in each "obs.field" entry // -message_type = [ "ADPUPA" ]; -sid_inc = []; -sid_exc = []; -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = [ "ADPUPA" ]; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -160,12 +174,6 @@ message_type_group_map = [ ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // @@ -199,6 +207,8 @@ climo_stdev = { climo_cdf = { cdf_bins = 10; center_bins = FALSE; + write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// @@ -238,7 +248,7 @@ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; - shape = SQUARE; + shape = SQUARE; type = [ { @@ -261,6 +271,11 @@ output_flag = { orank = NONE; ssvar = NONE; relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index f063e23f52..3ca0deb588 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -19,7 +19,7 @@ Ensemble forecasts are often created as a set of deterministic forecasts. The en Typically an ensemble is constructed by selecting a single forecast value from each member for each observation. When the High Resolution Assessment (HiRA) interpolation method is chosen, all of the nearby neighborhood points surrounding each observation from each member are used. Therefore, processing an N-member ensemble using a HiRA neighborhood of size M produces ensemble output with size N*M. This approach fully leverages information from all nearby grid points to evaluate the ensemble quality. -The ensemble relative frequency is the simplest method for turning a set of deterministic forecasts into something resembling a probability forecast. MET will create the ensemble relative frequency as the proportion of ensemble members forecasting some event. For example, if 5 out of 10 ensemble members predict measurable precipitation at a grid location, then the ensemble relative frequency of precipitation will be :math:`5/10=0.5`. If the ensemble relative frequency is calibrated (unlikely) then this could be thought of as a probability of precipitation. +The ensemble relative frequency is the simplest method for turning a set of deterministic forecasts into something resembling a probability forecast. For each categorical threshold (cat_thresh) listed for each field array entry of the ensemble dictionary (ens.field), MET will create the ensemble relative frequency as the proportion of ensemble members forecasting that event. For example, if 5 out of 10 ensemble members predict measurable precipitation at a grid location, then the ensemble relative frequency of precipitation will be :math:`5/10=0.5`. If the ensemble relative frequency is calibrated (unlikely) then this could be thought of as a probability of precipitation. The neighborhood ensemble probability (NEP) and neighborhood maximum ensemble probability (NMEP) methods are described in :ref:`Schwartz and Sobash (2017) `. They are an extension of the ensemble relative frequencies described above. The NEP value is computed by averaging the relative frequency of the event within the neighborhood over all ensemble members. The NMEP value is computed as the fraction of ensemble members for which the event is occurring somewhere within the surrounding neighborhood. The NMEP output is typically smoothed using a Gaussian kernel filter. The neighborhood sizes and smoothing options can be customized in the configuration file. @@ -36,6 +36,10 @@ The relative position (RELP) is a count of the number of times each ensemble mem The ranked probability score (RPS) is included in the Ranked Probability Score (RPS) line type. It is the mean of the Brier scores computed from ensemble probabilities derived for each probability category threshold (prob_cat_thresh) specified in the configuration file. The continuous ranked probability score (CRPS) is the average the distance between the forecast (ensemble) cumulative distribution function and the observation cumulative distribution function. It is an analog of the Brier score, but for continuous forecast and observation fields. The CRPS statistic is computed using two methods: assuming a normal distribution defined by the ensemble mean and spread (:ref:`Gneiting et al., 2004 `) and using the empirical ensemble distribution (:ref:`Hersbach, 2000 `). The CRPS statistic is included in the Ensemble Continuous Statistics (ECNT) line type, along with other statistics quantifying the ensemble spread and ensemble mean skill. +The Ensemble-Stat tool can derive ensemble relative frequencies and verify them as probability forecasts all in the same run. Note however that these simple ensemble relative frequencies are not actually calibrated probability forecasts. If probabilistic line types are requested (output_flag), this logic is applied to each pair of fields listed in the forecast (fcst) and observation (obs) dictionaries of the configuration file. Each probability category threshold (prob_cat_thresh) listed for the forecast field is applied to the input ensemble members to derive a relative frequency forecast. The probability category threshold (prob_cat_thresh) parsed from the corresponding observation entry is applied to the (gridded or point) observations to determine whether or not the event actually occurred. The paired ensemble relative freqencies and observation events are used to populate an Nx2 probabilistic contingency table. The dimension of that table is determined by the probability PCT threshold (prob_pct_thresh) configuration file option parsed from the forecast dictionary. All probabilistic output types requested are derived from the this Nx2 table and written to the ascii output files. Note that the FCST_VAR name header column is automatically reset as "PROB({FCST_VAR}{THRESH})" where {FCST_VAR} is the current field being evaluated and {THRESH} is the threshold that was applied. + +Note that if no probability category thresholds (prob_cat_thresh) are defined, but climatological mean and standard deviation data is provided along with climatological bins, climatological distribution percentile thresholds are automatically derived and used to compute probabilistic outputs. + Climatology data ---------------- @@ -150,6 +154,7 @@ ____________________ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; shape = SQUARE; type = [ { method = NEAREST; width = 1; } ]; } + eclv_points = []; sid_inc = []; sid_exc = []; duplicate_flag = NONE; @@ -301,33 +306,42 @@ ____________________ ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; - prob_cat_thresh = []; Setting up the **fcst** and **obs** dictionaries of the configuration file is described in :numref:`config_options`. The following are some special considerations for the Ensemble-Stat tool. - The **ens** and **fcst** dictionaries do not need to include the same fields. Users may specify any number of ensemble fields to be summarized, but generally there are many fewer fields with verifying observations available. The **ens** dictionary specifies the fields to be summarized while the **fcst** dictionary specifies the fields to be verified. - The **obs** dictionary looks very similar to the **fcst** dictionary. If verifying against point observations which are assigned GRIB1 codes, the observation section must be defined following GRIB1 conventions. When verifying GRIB1 forecast data, one can easily copy over the forecast settings to the observation dictionary using **obs = fcst;**. However, when verifying non-GRIB1 forecast data, users will need to specify the **fcst** and **obs** sections separately. - The **ens_ssvar_bin_size** and **ens_phist_bin_size** specify the width of the categorical bins used to accumulate frequencies for spread-skill-variance or probability integral transform statistics, respectively. +____________________ + +.. code-block:: none + + prob_cat_thresh = []; + prob_pct_thresh = []; + + +The **prob_cat_thresh** entry is an array of thresholds. It is applied both to the computation of the RPS line type as well as the when generating probabilistic output line types. Since these thresholds can change for each variable, they can be specified separately for each **fcst.field** entry. If left empty but climatological mean and standard deviation data is provided, the **climo_cdf** thresholds will be used instead. If no climatology data is provided, and the RPS output line type is requested, then the **prob_cat_thresh** array must be defined. When probabilistic output line types are requested, for each **prob_cat_thresh** threshold listed, ensemble relative frequencies are derived and verified against the point and/or gridded observations. -The **prob_cat_thresh** entry is an array of thresholds to be applied in the computation of the RPS line type. Since these thresholds can change for each variable, they can be specified separately for each **fcst.field** entry. If left empty but climatological mean and standard deviation data is provided, the **climo_cdf** thresholds will be used instead. If no climatology data is provided, and the RPS output line type is requested, then the **prob_cat_thresh** array must be defined. +The **prob_pct_thresh** entry is an array of thresholds which define the Nx2 probabilistic contingency table used to evaluate probability forecasts. It can be specified separately for each **fcst.field** entry. These thresholds must span the range [0, 1]. A shorthand notation to create equal bin widths is provided. For example, the following setting creates 4 probability bins of width 0.25 from 0 to 1. + +.. code-block:: none + + prob_cat_thresh = [ ==0.25 ]; __________________ .. code-block:: none obs_error = { - flag = FALSE; - dist_type = NONE; - dist_parm = []; - inst_bias_scale = 1.0; - inst_bias_offset = 0.0; + flag = FALSE; + dist_type = NONE; + dist_parm = []; + inst_bias_scale = 1.0; + inst_bias_offset = 0.0; } @@ -353,13 +367,18 @@ _________________ .. code-block:: none output_flag = { - ecnt = NONE; - rps = NONE; - rhist = NONE; - phist = NONE; - orank = NONE; - ssvar = NONE; - relp = NONE; + ecnt = NONE; + rps = NONE; + rhist = NONE; + phist = NONE; + orank = NONE; + ssvar = NONE; + relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } @@ -380,12 +399,22 @@ The **output_flag** array controls the type of output that is generated. Each fl 7. **RELP** for Relative Position Counts +8. **PCT** for Contingency Table counts for derived ensemble relative frequencies + +9. **PSTD** for Probabilistic statistics for dichotomous outcomes for derived ensemble relative frequencies + +10. **PJC** for Joint and Conditional factorization for derived ensemble relative frequencies + +11. **PRC** for Receiver Operating Characteristic for derived ensemble relative frequencies + +12. **ECLV** for Economic Cost/Loss Relative Value for derived ensemble relative frequencies + _____________________ .. code-block:: none - ensemble_flag = { - latlon = TRUE; + ensemble_flag = { + latlon = TRUE; mean = TRUE; stdev = TRUE; minus = TRUE; @@ -399,7 +428,7 @@ _____________________ nmep = FALSE; rank = TRUE; weight = FALSE; - } + } The **ensemble_flag** specifies which derived ensemble fields should be calculated and output. Setting the flag to TRUE produces output of the specified field, while FALSE produces no output for that field type. The flags correspond to the following output line types: diff --git a/met/scripts/config/EnsembleStatConfig b/met/scripts/config/EnsembleStatConfig index 64367110ea..9a1845555e 100644 --- a/met/scripts/config/EnsembleStatConfig +++ b/met/scripts/config/EnsembleStatConfig @@ -32,16 +32,18 @@ regrid = { method = NEAREST; width = 1; vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// // -// May be set separately in each "field" entry +// May be set separately in each "ens.field" entry // censor_thresh = []; censor_val = []; cat_thresh = []; +nc_var_str = ""; // // Ensemble product fields to be processed @@ -80,6 +82,13 @@ ens = { ]; } +// +// IDs for ensemble members +// Only set if processing a single file with all ensembles +// +ens_member_ids = []; +control_id = ""; + //////////////////////////////////////////////////////////////////////////////// // @@ -109,6 +118,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -133,15 +157,16 @@ obs = fcst; // Point observation filtering options // May be set separately in each "obs.field" entry // -sid_inc = []; -sid_exc = []; -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -154,8 +179,20 @@ obs_error = { dist_parm = []; inst_bias_scale = 1.0; inst_bias_offset = 0.0; + min = NA; + max = NA; } +// +// Mapping of message type group name to comma-separated list of values +// +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"; } +]; + // // Ensemble bin sizes // May be set separately in each "obs.field" entry @@ -163,16 +200,10 @@ obs_error = { ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // -// Climatology mean data +// Climatology data // climo_mean = { @@ -183,6 +214,7 @@ climo_mean = { method = NEAREST; width = 1; vld_thresh = 0.5; + shape = SQUARE; } time_interp_method = DW_MEAN; @@ -201,6 +233,8 @@ climo_stdev = { climo_cdf = { cdf_bins = 10; center_bins = FALSE; + write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// @@ -244,6 +278,7 @@ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -270,6 +305,11 @@ output_flag = { orank = BOTH; ssvar = BOTH; relp = BOTH; + pct = BOTH; + pstd = BOTH; + pjc = BOTH; + prc = BOTH; + eclv = BOTH; } //////////////////////////////////////////////////////////////////////////////// @@ -278,6 +318,7 @@ output_flag = { // Ensemble product output types // ensemble_flag = { + latlon = TRUE; mean = TRUE; stdev = TRUE; minus = TRUE; diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index ae88c78d3e..24d9517542 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -746,6 +746,7 @@ static const char conf_key_rank_flag[] = "rank"; static const char conf_key_ssvar_bin[] = "ens_ssvar_bin_size"; static const char conf_key_phist_bin[] = "ens_phist_bin_size"; static const char conf_key_prob_cat_thresh[] = "prob_cat_thresh"; +static const char conf_key_prob_pct_thresh[] = "prob_pct_thresh"; static const char conf_key_obs_error[] = "obs_error"; static const char conf_key_dist_type[] = "dist_type"; static const char conf_key_dist_parm[] = "dist_parm"; diff --git a/met/src/basic/vx_util/thresh_array.cc b/met/src/basic/vx_util/thresh_array.cc index 1575ef1f04..dd68d0578c 100644 --- a/met/src/basic/vx_util/thresh_array.cc +++ b/met/src/basic/vx_util/thresh_array.cc @@ -771,6 +771,27 @@ ThreshArray process_rps_cdp_thresh(const ThreshArray &ta) { //////////////////////////////////////////////////////////////////////// +ThreshArray derive_cdp_thresh(const ThreshArray &ta) { + SingleThresh st; + ThreshArray ta_out; + + for(int i=0; icompute_pair_vals(conf_info.rng_ptr); - // Process each filtering threshold - for(m=0; msubset_pairs_obs_thresh(conf_info.vx_opt[i].othr_ta[m]); - - // Continue if there are no points - if(pd.n_obs == 0) continue; - - // Compute ECNT scores - if(conf_info.output_flag[i_ecnt] != STATOutputType_None) { - do_ecnt(conf_info.vx_opt[i], - conf_info.vx_opt[i].othr_ta[m], &pd); - } - - // Compute RPS scores - if(conf_info.output_flag[i_rps] != STATOutputType_None) { - do_rps(conf_info.vx_opt[i], - conf_info.vx_opt[i].othr_ta[m], &pd); - } - - // Write RHIST counts - if(conf_info.output_flag[i_rhist] != STATOutputType_None) { - - pd.compute_rhist(); - - if(pd.rhist_na.sum() > 0) { - write_rhist_row(shc, &pd, - conf_info.output_flag[i_rhist], - stat_at, i_stat_row, - txt_at[i_rhist], i_txt_row[i_rhist]); - } - } - - // Write PHIST counts if greater than 0 - if(conf_info.output_flag[i_phist] != STATOutputType_None) { - - pd.compute_phist(); - - if(pd.phist_na.sum() > 0) { - write_phist_row(shc, &pd, - conf_info.output_flag[i_phist], - stat_at, i_stat_row, - txt_at[i_phist], i_txt_row[i_phist]); - } - } - - // Write RELP counts - if(conf_info.output_flag[i_relp] != STATOutputType_None) { - - pd.compute_relp(); - - if(pd.relp_na.sum() > 0) { - write_relp_row(shc, &pd, - conf_info.output_flag[i_relp], - stat_at, i_stat_row, - txt_at[i_relp], i_txt_row[i_relp]); - } - } - - // Write SSVAR scores - if(conf_info.output_flag[i_ssvar] != STATOutputType_None) { - - pd.compute_ssvar(); - - // Make sure there are bins to process - if(pd.ssvar_bins) { - - // Add rows to the output AsciiTables for SSVAR - stat_at.add_rows(pd.ssvar_bins[0].n_bin * - conf_info.vx_opt[i].ci_alpha.n()); - - if(conf_info.output_flag[i_ssvar] == STATOutputType_Both) { - txt_at[i_ssvar].add_rows(pd.ssvar_bins[0].n_bin * - conf_info.vx_opt[i].ci_alpha.n()); - } - - // Write the SSVAR data for each alpha value - for(n=0; n 0) { - write_rhist_row(shc, &pd, - conf_info.output_flag[i_rhist], - stat_at, i_stat_row, - txt_at[i_rhist], i_txt_row[i_rhist]); - } - } - - // Write PHIST counts if greater than 0 - if(conf_info.output_flag[i_phist] != STATOutputType_None) { - - pd.phist_bin_size = conf_info.vx_opt[i].vx_pd.pd[0][0][0].phist_bin_size; - pd.compute_phist(); - - if(pd.phist_na.sum() > 0) { - write_phist_row(shc, &pd, - conf_info.output_flag[i_phist], - stat_at, i_stat_row, - txt_at[i_phist], i_txt_row[i_phist]); - } - } - - // Write RELP counts - if(conf_info.output_flag[i_relp] != STATOutputType_None) { - - pd.compute_relp(); - - if(pd.relp_na.sum() > 0) { - write_relp_row(shc, &pd, - conf_info.output_flag[i_relp], - stat_at, i_stat_row, - txt_at[i_relp], i_txt_row[i_relp]); - } - } - - // Write SSVAR scores - if(conf_info.output_flag[i_ssvar] != STATOutputType_None) { - - pd.ssvar_bin_size = conf_info.vx_opt[i].vx_pd.pd[0][0][0].ssvar_bin_size; - pd.compute_ssvar(); - - // Make sure there are bins to process - if(pd.ssvar_bins) { - - // Add rows to the output AsciiTables for SSVAR - stat_at.add_rows(pd.ssvar_bins[0].n_bin * - conf_info.vx_opt[i].ci_alpha.n()); - - if(conf_info.output_flag[i_ssvar] == STATOutputType_Both) { - txt_at[i_ssvar].add_rows(pd.ssvar_bins[0].n_bin * - conf_info.vx_opt[i].ci_alpha.n()); - } - - // Write the SSVAR data for each alpha value - for(m=0; m 0) { + write_rhist_row(shc, &pd, + vx_opt.output_flag[i_rhist], + stat_at, i_stat_row, + txt_at[i_rhist], i_txt_row[i_rhist]); + } + } + + // Write PHIST counts if greater than 0 + if(vx_opt.output_flag[i_phist] != STATOutputType_None) { + + pd.phist_bin_size = vx_opt.vx_pd.pd[0][0][0].phist_bin_size; + pd.compute_phist(); + + if(pd.phist_na.sum() > 0) { + write_phist_row(shc, &pd, + vx_opt.output_flag[i_phist], + stat_at, i_stat_row, + txt_at[i_phist], i_txt_row[i_phist]); + } + } + + // Write RELP counts + if(vx_opt.output_flag[i_relp] != STATOutputType_None) { + + pd.compute_relp(); + + if(pd.relp_na.sum() > 0) { + write_relp_row(shc, &pd, + vx_opt.output_flag[i_relp], + stat_at, i_stat_row, + txt_at[i_relp], i_txt_row[i_relp]); + } + } + + // Write SSVAR scores + if(vx_opt.output_flag[i_ssvar] != STATOutputType_None) { + + pd.ssvar_bin_size = vx_opt.vx_pd.pd[0][0][0].ssvar_bin_size; + pd.compute_ssvar(); + + // Make sure there are bins to process + if(pd.ssvar_bins) { + + // Add rows to the output AsciiTables for SSVAR + stat_at.add_rows(pd.ssvar_bins[0].n_bin * + vx_opt.ci_alpha.n()); + + if(vx_opt.output_flag[i_ssvar] == STATOutputType_Both) { + txt_at[i_ssvar].add_rows(pd.ssvar_bins[0].n_bin * + vx_opt.ci_alpha.n()); + } + + // Write the SSVAR data for each alpha value + for(j=0; j 0 && + pd_ens.csd_na.n_valid() > 0); + + // If forecast probability thresholds were specified, use them. + if(vx_opt.fcat_ta.n() > 0) { + do_pct_cat_thresh(vx_opt, pd_ens); + } + // Otherwise, if climo data is available and bins were requested, + // use climo_cdf thresholds instead. + else if(have_climo && vx_opt.cdf_info.cdf_ta.n() > 0) { + do_pct_cdp_thresh(vx_opt, pd_ens); + } + + // Otherwise, no work to be done. + return; +} + +//////////////////////////////////////////////////////////////////////// + +void do_pct_cat_thresh(const EnsembleStatVxOpt &vx_opt, + const PairDataEnsemble &pd_ens) { + int i, i_thr, i_bin, i_obs, i_ens; + int n_vld, n_evt, n_bin; + PCTInfo *pct_info = (PCTInfo *) 0; + PairDataPoint pd_pnt, pd; + ConcatString fcst_var_cs, cs; + + mlog << Debug(2) + << "Computing Probabilistic Statistics for " + << vx_opt.fcat_ta.n() << " categorical thresholds.\n"; + + // Derive a PairDataPoint object from the PairDataEnsemble input + pd_pnt.extend(pd_ens.n_obs); + + // Determine the number of climo CDF bins + n_bin = (pd_ens.cmn_na.n_valid() > 0 && pd_ens.csd_na.n_valid() > 0 ? + vx_opt.get_n_cdf_bin() : 1); + + if(n_bin > 1) { + mlog << Debug(2) + << "Subsetting pairs into " << n_bin << " climatology bins.\n"; + } + + // Allocate memory + pct_info = new PCTInfo [n_bin]; + + // Store the current fcst_var value + fcst_var_cs = shc.get_fcst_var(); + + // Process each probability threshold + for(i_thr=0; i_thr 0 || (double) (n_vld/pd_ens.n_ens) >= conf_info.vld_data_thresh) { + pd_pnt.add_grid_pair((double) n_evt/n_vld, pd_ens.o_na[i_obs], + pd_ens.cmn_na[i_obs], pd_ens.csd_na[i_obs], + pd_ens.wgt_na[i_obs]); + } + + } // end for i_obs + + // Process the climo CDF bins + for(i_bin=0; i_bin 1) pd = subset_climo_cdf_bin(pd_pnt, + vx_opt.cdf_info.cdf_ta, i_bin); + else pd = pd_pnt; + + // Store thresholds + pct_info[i_bin].fthresh = vx_opt.fpct_ta; + pct_info[i_bin].othresh = vx_opt.ocat_ta[i_thr]; + pct_info[i_bin].allocate_n_alpha(vx_opt.get_n_ci_alpha()); + + for(i=0; i 0 || (double) (n_vld/pd_ens.n_ens) >= conf_info.vld_data_thresh) { + pd_pnt.add_grid_pair((double) n_evt/n_vld, pd_ens.o_na[i_obs], + pd_ens.cmn_na[i_obs], pd_ens.csd_na[i_obs], + pd_ens.wgt_na[i_obs]); + } + + } // end for i_obs + + // Initialize + pct_info[i_bin].clear(); + + // Store thresholds + pct_info[i_bin].fthresh = vx_opt.fpct_ta; + pct_info[i_bin].othresh = cdp_thresh[i_bin]; + pct_info[i_bin].allocate_n_alpha(vx_opt.get_n_ci_alpha()); + + for(i=0; i 1) { + + PCTInfo pct_mean; + compute_pct_mean(pct_info, n_bin, pct_mean, sum_total); + + // Write out PSTD + if(vx_opt.output_flag[i_pstd] != STATOutputType_None) { + write_pstd_row(shc, pct_mean, + vx_opt.output_flag[i_pstd], + -1, n_bin, stat_at, i_stat_row, + txt_at[i_pstd], i_txt_row[i_pstd]); + } + } // end if n_bin > 1 + + return; +} + +//////////////////////////////////////////////////////////////////////// + void write_ens_nc(EnsVarInfo * ens_info, int i_var, DataPlane &ens_dp) { int i, j, k, l; double t, v; @@ -3121,14 +3405,14 @@ void clean_up() { // Deallocate threshold count arrays if(thresh_cnt_na) { - for(i=0; icat_ta.n() > max_n_thresh) { - max_n_thresh = ens_info->cat_ta.n(); + if(ens_info->cat_ta.n() > max_n_ens_thresh) { + max_n_ens_thresh = ens_info->cat_ta.n(); } } @@ -430,7 +431,7 @@ void EnsembleStatConfInfo::process_config(GrdFileType etype, } // Parse settings for each verification task - for(i=0; i " + << "The number of forecast (" << fcat_ta.n() + << ") and observation (" << ocat_ta.n() + << ") probability category thresholds in \"" + << conf_key_prob_cat_thresh << "\" must match.\n\n"; + exit(1); + } + + // Conf: prob_pct_thresh + fpct_ta = fdict.lookup_thresh_array(conf_key_prob_pct_thresh); + fpct_ta = string_to_prob_thresh(fpct_ta.get_str().c_str()); // Conf: duplicate_flag duplicate_flag = parse_conf_duplicate_flag(&odict); @@ -1107,7 +1160,12 @@ void EnsembleStatVxOpt::set_vx_pd(EnsembleStatConfInfo *conf_info, int ctrl_inde void EnsembleStatVxOpt::set_perc_thresh(const PairDataEnsemble *pd_ptr) { - if(!othr_ta.need_perc()) return; + // + // Check if percentile thresholds were requested + // + if(!othr_ta.need_perc() && + !fcat_ta.need_perc() && + !ocat_ta.need_perc()) return; // // Sort the input arrays @@ -1121,10 +1179,12 @@ void EnsembleStatVxOpt::set_perc_thresh(const PairDataEnsemble *pd_ptr) { csort.sort_array(); // - // Compute percentiles, passing the observation thresholds in for - // the fcst and obs slots. + // Compute percentiles, passing the observation filtering + // thresholds in for the fcst and obs slots. // othr_ta.set_perc(&fsort, &osort, &csort, &othr_ta, &othr_ta); + fcat_ta.set_perc(&fsort, &osort, &csort, &fcat_ta, &ocat_ta); + ocat_ta.set_perc(&fsort, &osort, &csort, &fcat_ta, &ocat_ta); return; } @@ -1154,8 +1214,7 @@ int EnsembleStatVxOpt::n_txt_row(int i_txt_row) const { // Point Vx: Message Types * Masks * Interpolations * Obs Thresholds * Alphas // Grid Vx: Masks * Interpolations * Obs Thresholds * Alphas n = (get_n_msg_typ() + 1) * get_n_mask() * get_n_interp() * - get_n_o_thresh() * get_n_ci_alpha(); - + get_n_obs_thresh() * get_n_ci_alpha(); break; case(i_rhist): @@ -1166,8 +1225,7 @@ int EnsembleStatVxOpt::n_txt_row(int i_txt_row) const { // Point Vx: Message Types * Masks * Interpolations * Obs Thresholds // Grid Vx: Masks * Interpolations * Obs Thresholds n = (get_n_msg_typ() + 1) * get_n_mask() * get_n_interp() * - get_n_o_thresh(); - + get_n_obs_thresh(); break; case(i_orank): @@ -1177,8 +1235,7 @@ int EnsembleStatVxOpt::n_txt_row(int i_txt_row) const { // Number of ORANK lines possible = // Number of pairs * Obs Thresholds - n = vx_pd.get_n_pair() * get_n_o_thresh(); - + n = vx_pd.get_n_pair() * get_n_obs_thresh(); break; case(i_ssvar): @@ -1188,6 +1245,35 @@ int EnsembleStatVxOpt::n_txt_row(int i_txt_row) const { n = 0; break; + case(i_pct): + case(i_pjc): + case(i_prc): + + // Maximum number of PCT, PJC, and PRC lines possible = + // Point Vx: Message Types * Masks * Interpolations * Categorical Thresholds + // Grid Vx: Masks * Interpolations * Categorical Thresholds + n = (get_n_msg_typ() + 1) * get_n_mask() * get_n_interp() * + get_n_prob_cat_thresh(); + break; + + case(i_pstd): + + // Maximum number of PSTD lines possible = + // Point Vx: Message Types * Masks * Interpolations * Categorical Thresholds * Alphas + // Grid Vx: Masks * Interpolations * Categorical Thresholds * Alphas + n = (get_n_msg_typ() + 1) * get_n_mask() * get_n_interp() * + get_n_prob_cat_thresh() * get_n_ci_alpha(); + break; + + case(i_eclv): + + // Maximum number of ECLV lines possible = + // Point Vx: Message Types * Masks * Interpolations * Probability Thresholds + // Grid Vx: Masks * Interpolations * Probability Thresholds + n = (get_n_msg_typ() + 1) * get_n_mask() * get_n_interp() * + get_n_prob_cat_thresh() * get_n_prob_cat_thresh(); + break; + default: mlog << Error << "\nEnsembleStatVxOpt::n_txt_row(int) -> " << "unexpected output type index value: " << i_txt_row @@ -1198,6 +1284,15 @@ int EnsembleStatVxOpt::n_txt_row(int i_txt_row) const { return(n); } +//////////////////////////////////////////////////////////////////////// + +int EnsembleStatVxOpt::get_n_prob_cat_thresh() const { + + // Probability categories can be defined by the prob_cat_thresh or + // climo_cdf.bins configuration file options. + return(max(fcat_ta.n(), cdf_info.cdf_ta.n())); +} + //////////////////////////////////////////////////////////////////////// // // Code for struct EnsembleStatNcOutInfo diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h index ceaedf50d0..e2d823a504 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h +++ b/met/src/tools/core/ensemble_stat/ensemble_stat_conf_info.h @@ -34,12 +34,18 @@ static const int i_phist = 3; static const int i_orank = 4; static const int i_ssvar = 5; static const int i_relp = 6; -static const int n_txt = 7; +static const int i_pct = 7; +static const int i_pstd = 8; +static const int i_pjc = 9; +static const int i_prc = 10; +static const int i_eclv = 11; +static const int n_txt = 12; // Text file type static const STATLineType txt_file_type[n_txt] = { stat_ecnt, stat_rps, stat_rhist, stat_phist, - stat_orank, stat_ssvar, stat_relp + stat_orank, stat_ssvar, stat_relp, stat_pct, + stat_pstd, stat_pjc, stat_prc, stat_eclv }; //////////////////////////////////////////////////////////////////////// @@ -114,6 +120,8 @@ class EnsembleStatVxOpt { ThreshArray othr_ta; // Observation filtering thresholds + NumArray eclv_points; // ECLV points + ClimoCDFInfo cdf_info; // Climo CDF info NumArray ci_alpha; // Alpha value for confidence intervals @@ -122,7 +130,10 @@ class EnsembleStatVxOpt { double ssvar_bin_size; // SSVAR bin size double phist_bin_size; // PHIST bin size - ThreshArray prob_cat_ta; // Categorical thresholds for probabilities + + ThreshArray fcat_ta; // Forecast categorical probability-definition thresholds, including RPS + ThreshArray ocat_ta; // Observation categorical event-definition thresholds + ThreshArray fpct_ta; // Forecast PCT thresholds DuplicateType duplicate_flag; // Duplicate observations ObsSummary obs_summary; // Summarize observations @@ -154,20 +165,28 @@ class EnsembleStatVxOpt { int get_n_mask() const; int get_n_mask_area() const; - int get_n_o_thresh() const; - int get_n_cdf_bin() const; - int get_n_ci_alpha() const; + int get_n_obs_thresh() const; + int get_n_prob_cat_thresh() const; + int get_n_prob_pct_thresh() const; + + int get_n_eclv_points() const; + int get_n_cdf_bin() const; + int get_n_ci_alpha() const; }; //////////////////////////////////////////////////////////////////////// -inline int EnsembleStatVxOpt::get_n_msg_typ() const { return(msg_typ.n()); } -inline int EnsembleStatVxOpt::get_n_interp() const { return(interp_info.n_interp); } -inline int EnsembleStatVxOpt::get_n_mask() const { return(mask_name.n()); } -inline int EnsembleStatVxOpt::get_n_mask_area() const { return(mask_name_area.n()); } -inline int EnsembleStatVxOpt::get_n_o_thresh() const { return(othr_ta.n()); } -inline int EnsembleStatVxOpt::get_n_cdf_bin() const { return(cdf_info.n_bin); } -inline int EnsembleStatVxOpt::get_n_ci_alpha() const { return(ci_alpha.n()); } +inline int EnsembleStatVxOpt::get_n_msg_typ() const { return(msg_typ.n()); } +inline int EnsembleStatVxOpt::get_n_interp() const { return(interp_info.n_interp); } +inline int EnsembleStatVxOpt::get_n_mask() const { return(mask_name.n()); } +inline int EnsembleStatVxOpt::get_n_mask_area() const { return(mask_name_area.n()); } + +inline int EnsembleStatVxOpt::get_n_obs_thresh() const { return(othr_ta.n()); } +inline int EnsembleStatVxOpt::get_n_prob_pct_thresh() const { return(fpct_ta.n()); } + +inline int EnsembleStatVxOpt::get_n_eclv_points() const { return(eclv_points.n()); } +inline int EnsembleStatVxOpt::get_n_cdf_bin() const { return(cdf_info.n_bin); } +inline int EnsembleStatVxOpt::get_n_ci_alpha() const { return(ci_alpha.n()); } //////////////////////////////////////////////////////////////////////// @@ -178,12 +197,12 @@ class EnsembleStatConfInfo { void init_from_scratch(); // Ensemble processing - int n_ens_var; // Number of ensemble fields to be processed - int max_n_thresh; // Maximum number of ensemble thresholds - int max_hira_size; // Maximum size of a HiRA neighborhoods + int n_ens_var; // Number of ensemble fields to be processed + int max_n_ens_thresh; // Maximum number of ensemble thresholds // Ensemble verification - int n_vx; // Number of ensemble fields to be verified + int n_vx; // Number of ensemble fields to be verified + int max_hira_size; // Maximum size of a HiRA neighborhoods public: @@ -256,20 +275,23 @@ class EnsembleStatConfInfo { int n_stat_row() const; // Maximum across all verification tasks - int get_max_n_thresh() const; - int get_max_hira_size() const; + int get_max_n_ens_thresh() const; + int get_max_hira_size() const; + int get_max_n_prob_cat_thresh() const; + int get_max_n_prob_pct_thresh() const; + int get_max_n_eclv_points() const; int get_compression_level(); }; //////////////////////////////////////////////////////////////////////// -inline int EnsembleStatConfInfo::get_n_ens_var() const { return(n_ens_var); } -inline int EnsembleStatConfInfo::get_n_nbrhd() const { return(n_nbrhd); } -inline int EnsembleStatConfInfo::get_n_vx() const { return(n_vx); } -inline int EnsembleStatConfInfo::get_max_n_thresh() const { return(max_n_thresh); } -inline int EnsembleStatConfInfo::get_max_hira_size() const { return(max_hira_size); } -inline int EnsembleStatConfInfo::get_compression_level() { return(conf.nc_compression()); } +inline int EnsembleStatConfInfo::get_n_ens_var() const { return(n_ens_var); } +inline int EnsembleStatConfInfo::get_n_nbrhd() const { return(n_nbrhd); } +inline int EnsembleStatConfInfo::get_n_vx() const { return(n_vx); } +inline int EnsembleStatConfInfo::get_max_n_ens_thresh() const { return(max_n_ens_thresh); } +inline int EnsembleStatConfInfo::get_max_hira_size() const { return(max_hira_size); } +inline int EnsembleStatConfInfo::get_compression_level() { return(conf.nc_compression()); } //////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 73dfa2af24..5f40c314be 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -158,7 +158,6 @@ 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(); static void clean_up(); diff --git a/test/config/EnsembleStatConfig b/test/config/EnsembleStatConfig index 296555748e..1b12b3e973 100644 --- a/test/config/EnsembleStatConfig +++ b/test/config/EnsembleStatConfig @@ -28,13 +28,23 @@ obtype = "ANALYS"; // Verification grid // regrid = { - to_grid = NONE; - method = NEAREST; - width = 1; + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "ens.field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + // // Ensemble product fields to be processed // @@ -92,13 +102,26 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // fcst = { message_type = [ "ADPSFC" ]; - sid_inc = []; - sid_exc = []; obs_quality_inc = []; obs_quality_exc = []; @@ -111,7 +134,7 @@ fcst = { name = "APCP"; level = "A24"; obs_thresh = [ NA, >0, >=2.54 ]; - obs_error = { + obs_error = { flag = ${OBS_ERROR_FLAG}; dist_type = NONE; } @@ -126,11 +149,16 @@ obs = fcst; // Point observation filtering options // May be set separately in each "obs.field" entry // -obs_thresh = [ NA ]; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = ${SKIP_CONST}; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = ${SKIP_CONST}; // // Observation error options @@ -154,12 +182,6 @@ obs_error = { ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // @@ -185,12 +207,20 @@ mask = { //////////////////////////////////////////////////////////////////////////////// +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + // // Interpolation methods // interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -213,6 +243,11 @@ output_flag = { orank = BOTH; ssvar = BOTH; relp = BOTH; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// @@ -221,6 +256,7 @@ output_flag = { // Ensemble product output types // ensemble_flag = { + latlon = TRUE; mean = TRUE; stdev = TRUE; minus = TRUE; diff --git a/test/config/EnsembleStatConfig_MASK_SID b/test/config/EnsembleStatConfig_MASK_SID index 764ad8280c..76e4adb43f 100644 --- a/test/config/EnsembleStatConfig_MASK_SID +++ b/test/config/EnsembleStatConfig_MASK_SID @@ -28,13 +28,23 @@ obtype = "ANALYS"; // Verification grid // regrid = { - to_grid = NONE; - method = NEAREST; - width = 1; + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "ens.field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + // // Ensemble product fields to be processed // @@ -89,15 +99,26 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // fcst = { message_type = [ "ADPSFC" ]; - sid_inc = []; - sid_exc = []; - obs_quality_inc = []; - obs_quality_exc = []; field = [ { @@ -116,11 +137,16 @@ obs = fcst; // Point observation filtering options // May be set separately in each "obs.field" entry // -obs_thresh = [ NA ]; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -144,12 +170,6 @@ obs_error = { ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // @@ -176,12 +196,20 @@ mask = { //////////////////////////////////////////////////////////////////////////////// +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + // // Interpolation methods // interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -204,6 +232,11 @@ output_flag = { orank = BOTH; ssvar = STAT; relp = STAT; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// @@ -212,6 +245,7 @@ output_flag = { // Ensemble product output types // ensemble_flag = { + latlon = TRUE; mean = TRUE; stdev = TRUE; minus = FALSE; diff --git a/test/config/EnsembleStatConfig_climo b/test/config/EnsembleStatConfig_climo index 478ceb1552..fea0dc9180 100644 --- a/test/config/EnsembleStatConfig_climo +++ b/test/config/EnsembleStatConfig_climo @@ -28,13 +28,23 @@ obtype = "ANALYS"; // Verification grid // regrid = { - to_grid = NONE; - method = NEAREST; - width = 1; + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "ens.field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + // // Ensemble product fields to be processed // @@ -84,6 +94,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -97,6 +122,45 @@ obs = fcst; //////////////////////////////////////////////////////////////////////////////// +// +// Point observation filtering options +// May be set separately in each "obs.field" entry +// +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; + +// +// Observation error options +// Set dist_type to NONE to use the observation error table instead +// May be set separately in each "obs.field" entry +// +obs_error = { + flag = FALSE; + dist_type = NONE; + dist_parm = []; + inst_bias_scale = 1.0; + inst_bias_offset = 0.0; + min = NA; + max = NA; +} + +// +// Ensemble bin sizes +// May be set separately in each "obs.field" entry +// +ens_ssvar_bin_size = 1.0; +ens_phist_bin_size = 0.05; + +//////////////////////////////////////////////////////////////////////////////// + // // Climatology data // @@ -126,52 +190,12 @@ climo_stdev = { climo_cdf = { cdf_bins = 10; center_bins = FALSE; + write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// -// -// Point observation filtering options -// May be set separately in each "obs.field" entry -// -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; - -// -// Observation error options -// Set dist_type to NONE to use the observation error table instead -// May be set separately in each "obs.field" entry -// -obs_error = { - flag = FALSE; - dist_type = NONE; - dist_parm = []; - inst_bias_scale = 1.0; - inst_bias_offset = 0.0; - min = NA; - max = NA; -} - -// -// Ensemble bin sizes -// May be set separately in each "obs.field" entry -// -ens_ssvar_bin_size = 1.0; -ens_phist_bin_size = 0.05; - -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - -//////////////////////////////////////////////////////////////////////////////// - // // Point observation time window // @@ -195,12 +219,20 @@ mask = { //////////////////////////////////////////////////////////////////////////////// +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + // // Interpolation methods // interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -223,6 +255,11 @@ output_flag = { orank = BOTH; ssvar = STAT; relp = STAT; + pct = BOTH; + pstd = BOTH; + pjc = BOTH; + prc = BOTH; + eclv = BOTH; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_grid_weight b/test/config/EnsembleStatConfig_grid_weight index dbd72bc580..19325f310a 100644 --- a/test/config/EnsembleStatConfig_grid_weight +++ b/test/config/EnsembleStatConfig_grid_weight @@ -32,10 +32,19 @@ regrid = { method = NEAREST; width = 1; vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "ens.field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + tmp_field = [ { name = "TMP"; level = [ "Z2" ]; } ]; // @@ -83,6 +92,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -102,11 +126,16 @@ obs = fcst; // Point observation filtering options // May be set separately in each "obs.field" entry // -obs_thresh = [ NA ]; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -130,16 +159,10 @@ obs_error = { ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // -// Climatology mean data +// Climatology data // climo_mean = { @@ -194,6 +217,7 @@ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -216,6 +240,11 @@ output_flag = { orank = NONE; ssvar = STAT; relp = STAT; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// @@ -224,6 +253,7 @@ output_flag = { // Ensemble product output types // ensemble_flag = { + latlon = TRUE; mean = TRUE; stdev = FALSE; minus = FALSE; diff --git a/test/config/EnsembleStatConfig_one_cdf_bin b/test/config/EnsembleStatConfig_one_cdf_bin index 2a02b9475e..1197e77517 100644 --- a/test/config/EnsembleStatConfig_one_cdf_bin +++ b/test/config/EnsembleStatConfig_one_cdf_bin @@ -28,13 +28,23 @@ obtype = "ANALYS"; // Verification grid // regrid = { - to_grid = NONE; - method = NEAREST; - width = 1; + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "ens.field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + // // Ensemble product fields to be processed // @@ -85,43 +95,30 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// // -// Forecast and observation fields to be verified +// May be set separately in each "fcst.field" and "obs.field" entry // -fcst = { - field = [ - { name = "TMP"; level = "Z2"; message_type = [ "ADPSFC" ]; }, - { name = "TMP"; level = "P850"; message_type = [ "ADPUPA" ]; } - ]; -} -obs = fcst; - -//////////////////////////////////////////////////////////////////////////////// +prob_cat_thresh = []; // -// Climatology data +// May be set separately in each "fcst.field" entry // -climo_mean = fcst; -climo_mean = { - - file_name = [ ${CLIMO_MEAN_FILE_LIST} ]; - regrid = { - method = BILIN; - width = 2; - vld_thresh = 0.5; - } - - time_interp_method = DW_MEAN; - day_interval = 1; - hour_interval = 6; -} +prob_pct_thresh = [ ==0.25 ]; // // May be set separately in each "obs.field" entry // -climo_cdf = { - cdf_bins = 1; - center_bins = FALSE; +eclv_points = 0.05; + +// +// Forecast and observation fields to be verified +// +fcst = { + field = [ + { name = "TMP"; level = "Z2"; message_type = [ "ADPSFC" ]; }, + { name = "TMP"; level = "P850"; message_type = [ "ADPUPA" ]; } + ]; } +obs = fcst; //////////////////////////////////////////////////////////////////////////////// @@ -129,13 +126,16 @@ climo_cdf = { // Point observation filtering options // May be set separately in each "obs.field" entry // -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -159,11 +159,34 @@ obs_error = { ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; +//////////////////////////////////////////////////////////////////////////////// + // -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry +// Climatology data // -prob_cat_thresh = []; +climo_mean = fcst; +climo_mean = { + + file_name = [ ${CLIMO_MEAN_FILE_LIST} ]; + regrid = { + method = BILIN; + width = 2; + vld_thresh = 0.5; + shape = SQUARE; + } + + time_interp_method = DW_MEAN; + day_interval = 1; + hour_interval = 6; +} + +// +// May be set separately in each "obs.field" entry +// +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; +} //////////////////////////////////////////////////////////////////////////////// @@ -189,12 +212,20 @@ mask = { //////////////////////////////////////////////////////////////////////////////// +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + // // Interpolation methods // interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -217,6 +248,11 @@ output_flag = { orank = NONE; ssvar = NONE; relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_python b/test/config/EnsembleStatConfig_python index 59ae439495..b8261dcde3 100644 --- a/test/config/EnsembleStatConfig_python +++ b/test/config/EnsembleStatConfig_python @@ -26,7 +26,6 @@ obtype = "ANALYS"; // // Verification grid -// May be set separately in each "field" entry // regrid = { to_grid = NONE; @@ -39,7 +38,7 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// // -// May be set separately in each "field" entry +// May be set separately in each "ens.field" entry // censor_thresh = []; censor_val = []; @@ -92,6 +91,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -107,16 +121,16 @@ obs = { // Point observation filtering options // May be set separately in each "obs.field" entry // -message_type = []; -sid_inc = []; -sid_exc = []; -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -134,7 +148,7 @@ obs_error = { } // -// Mapping of message type group name to comma-separated list of values. +// Mapping of message type group name to comma-separated list of values // message_type_group_map = [ { key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; }, @@ -150,39 +164,6 @@ message_type_group_map = [ ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - -//////////////////////////////////////////////////////////////////////////////// - -// -// Climatology data -// -climo_mean = { - - file_name = []; - field = []; - - regrid = { - method = NEAREST; - width = 1; - vld_thresh = 0.5; - shape = SQUARE; - } - - time_interp_method = DW_MEAN; - day_interval = 31; - hour_interval = 6; -} - -climo_stdev = climo_mean; -climo_stdev = { - file_name = []; -} - //////////////////////////////////////////////////////////////////////////////// // @@ -220,7 +201,7 @@ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; - shape = SQUARE; + shape = SQUARE; type = [ { @@ -243,6 +224,11 @@ output_flag = { orank = NONE; ssvar = NONE; relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_qty_inc_exc b/test/config/EnsembleStatConfig_qty_inc_exc index 620511dd4c..62b42d75c2 100644 --- a/test/config/EnsembleStatConfig_qty_inc_exc +++ b/test/config/EnsembleStatConfig_qty_inc_exc @@ -28,13 +28,23 @@ obtype = "ANALYS"; // Verification grid // regrid = { - to_grid = NONE; - method = NEAREST; - width = 1; + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; } //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "ens.field" entry +// +censor_thresh = []; +censor_val = []; +cat_thresh = []; +nc_var_str = ""; + // // Ensemble product fields to be processed // @@ -87,6 +97,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -129,11 +154,16 @@ obs = fcst; // Point observation filtering options // May be set separately in each "obs.field" entry // -obs_thresh = [ NA ]; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = []; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -157,12 +187,6 @@ obs_error = { ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // @@ -187,12 +211,20 @@ mask = { //////////////////////////////////////////////////////////////////////////////// +// +// Confidence interval settings +// +ci_alpha = [ 0.05 ]; + +//////////////////////////////////////////////////////////////////////////////// + // // Interpolation methods // interp = { field = BOTH; vld_thresh = 1.0; + shape = SQUARE; type = [ { @@ -215,6 +247,11 @@ output_flag = { orank = BOTH; ssvar = NONE; relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// @@ -223,6 +260,7 @@ output_flag = { // Ensemble product output types // ensemble_flag = { + latlon = TRUE; mean = TRUE; stdev = TRUE; minus = TRUE; diff --git a/test/config/EnsembleStatConfig_single_file_grib b/test/config/EnsembleStatConfig_single_file_grib index 76bb0bf3b5..27c802e30a 100644 --- a/test/config/EnsembleStatConfig_single_file_grib +++ b/test/config/EnsembleStatConfig_single_file_grib @@ -26,7 +26,6 @@ obtype = "ANALYS"; // // Verification grid -// May be set separately in each "field" entry // regrid = { to_grid = NONE; @@ -39,7 +38,7 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// // -// May be set separately in each "field" entry +// May be set separately in each "ens.field" entry // censor_thresh = []; censor_val = []; @@ -56,9 +55,9 @@ ens = { field = [ { name = "PRMSL"; - level = "L0"; - lead_time = "06"; - GRIB_ens = "MET_ENS_MEMBER_ID"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "MET_ENS_MEMBER_ID"; } ]; } @@ -99,17 +98,31 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // fcst = { - field = [ { name = "PRMSL"; - level = "L0"; - lead_time = "06"; - GRIB_ens = "MET_ENS_MEMBER_ID"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "MET_ENS_MEMBER_ID"; } ]; } @@ -118,9 +131,9 @@ obs = { field = [ { name = "PRMSL"; - level = "L0"; - lead_time = "06"; - GRIB_ens = "hi_res_ctl"; + level = "L0"; + lead_time = "06"; + GRIB_ens = "hi_res_ctl"; } ]; } @@ -130,16 +143,16 @@ obs = { // Point observation filtering options // May be set separately in each "obs.field" entry // -message_type = [ "ADPUPA" ]; -sid_inc = []; -sid_exc = []; -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = [ "ADPUPA" ]; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -173,12 +186,6 @@ message_type_group_map = [ ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // @@ -212,6 +219,8 @@ climo_stdev = { climo_cdf = { cdf_bins = 10; center_bins = FALSE; + write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// @@ -251,7 +260,7 @@ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; - shape = SQUARE; + shape = SQUARE; type = [ { @@ -274,6 +283,11 @@ output_flag = { orank = NONE; ssvar = NONE; relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_single_file_nc b/test/config/EnsembleStatConfig_single_file_nc index 67bd0e3399..5f29e6c671 100644 --- a/test/config/EnsembleStatConfig_single_file_nc +++ b/test/config/EnsembleStatConfig_single_file_nc @@ -26,7 +26,6 @@ obtype = "ANALYS"; // // Verification grid -// May be set separately in each "field" entry // regrid = { to_grid = NONE; @@ -39,7 +38,7 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// // -// May be set separately in each "field" entry +// May be set separately in each "ens.field" entry // censor_thresh = []; censor_val = []; @@ -106,6 +105,21 @@ nmep_smooth = { //////////////////////////////////////////////////////////////////////////////// +// +// May be set separately in each "fcst.field" and "obs.field" entry +// +prob_cat_thresh = []; + +// +// May be set separately in each "fcst.field" entry +// +prob_pct_thresh = [ ==0.25 ]; + +// +// May be set separately in each "obs.field" entry +// +eclv_points = 0.05; + // // Forecast and observation fields to be verified // @@ -126,22 +140,23 @@ obs = { } ]; } + //////////////////////////////////////////////////////////////////////////////// // // Point observation filtering options // May be set separately in each "obs.field" entry // -message_type = [ "ADPUPA" ]; -sid_inc = []; -sid_exc = []; -obs_thresh = [ NA ]; -obs_quality_inc = []; -obs_quality_exc = []; -duplicate_flag = NONE; -obs_summary = NONE; -obs_perc_value = 50; -skip_const = FALSE; +message_type = [ "ADPUPA" ]; +sid_inc = []; +sid_exc = []; +obs_thresh = [ NA ]; +obs_quality_inc = []; +obs_quality_exc = []; +duplicate_flag = NONE; +obs_summary = NONE; +obs_perc_value = 50; +skip_const = FALSE; // // Observation error options @@ -175,12 +190,6 @@ message_type_group_map = [ ens_ssvar_bin_size = 1.0; ens_phist_bin_size = 0.05; -// -// Categorical thresholds to define ensemble probabilities -// May be set separately in each "fcst.field" entry -// -prob_cat_thresh = []; - //////////////////////////////////////////////////////////////////////////////// // @@ -214,6 +223,8 @@ climo_stdev = { climo_cdf = { cdf_bins = 10; center_bins = FALSE; + write_bins = TRUE; + direct_prob = FALSE; } //////////////////////////////////////////////////////////////////////////////// @@ -253,7 +264,7 @@ ci_alpha = [ 0.05 ]; interp = { field = BOTH; vld_thresh = 1.0; - shape = SQUARE; + shape = SQUARE; type = [ { @@ -276,6 +287,11 @@ output_flag = { orank = NONE; ssvar = NONE; relp = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + eclv = NONE; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/xml/unit_climatology_1.0deg.xml b/test/xml/unit_climatology_1.0deg.xml index 6f458f13c8..a357b5c8b1 100644 --- a/test/xml/unit_climatology_1.0deg.xml +++ b/test/xml/unit_climatology_1.0deg.xml @@ -264,6 +264,11 @@ &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V.stat &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_ecnt.txt &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_orank.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_pct.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_pstd.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_prc.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_pjc.txt + &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_eclv.txt &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_ens.nc &OUTPUT_DIR;/climatology_1.0deg/ensemble_stat_NCEP_1.0DEG_20120410_120000V_orank.nc diff --git a/test/xml/unit_met_test_scripts.xml b/test/xml/unit_met_test_scripts.xml index 80d05f9877..9d0176c561 100644 --- a/test/xml/unit_met_test_scripts.xml +++ b/test/xml/unit_met_test_scripts.xml @@ -461,10 +461,18 @@ -v 2 - &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_orank.txt &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_ecnt.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_rps.txt &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_rhist.txt &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_phist.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_orank.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_ssvar.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_relp.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_pct.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_pstd.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_pjc.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_prc.txt + &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_eclv.txt &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V.stat &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_ens.nc &OUTPUT_DIR;/ensemble_stat/ensemble_stat_20100101_120000V_orank.nc From ddb3a3b3b57e447811e842c884714c1a4f4d72da Mon Sep 17 00:00:00 2001 From: johnhg Date: Wed, 2 Mar 2022 13:04:43 -0700 Subject: [PATCH 141/172] Feature 2078 v10.1.0-beta6 (#2079) --- met/docs/Users_Guide/release-notes.rst | 43 ++++++++++++++++++++++++++ met/docs/conf.py | 4 +-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index 1f11648ec9..eca874f4b0 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -5,6 +5,49 @@ When applicable, release notes are followed by the GitHub issue number which describes the bugfix, enhancement, or new feature: `MET GitHub issues. `_ +MET Version 10.1.0-beta6 release notes (20220302) +------------------------------------------------- + +* Enhancements: + + * **Enhance Ensemble-Stat to compute probabilistic statistics for user-defined or climatology-based thresholds** (`#1259 `_). + * **Enhance Ensemble-Stat to apply the HiRA method to ensembles** (`#1583 `_ and `#2045 `_). + * **Enhance Ensemble-Stat, Point-Stat, Plot-Point-Obs, and Point2Grid to support python embedding of point observations** (`#1844 `_). + * **Enhance Gen-Ens-Prod to standardize ensemble members relative to climatology** (`#1918 `_). + * Enhance PB2NC to derive Mixed-Layer CAPE (MLCAPE) (`#1824 `_). + * Enhance Series-Analysis to compute the BRIERCL statistic from the PSTD line type (`#2003 `_). + * Enhance the MET library code to read Rotated Lat/Lon data from CF-compliant NetCDF files (`#1055 `_). + +* Configuration: + + * Update the PB2NC configuration to correct the obs_prefbufr_map name as obs_prepbufr_map (`#2044 `_). + * Add entries to the default obs_prepbufr_map setting (`#2070 `_). + +* Bugfixes: + + * Fix the MET library code to correclty parse timing information from Grid-Stat NetCDF matched pairs output files (`#2040 `_). + * Fix MADIS2NC to correctly parse MADIS profiler quality flag values (`#2028 `_). + +* Testing: + + * **Implement Continuous Integration with GH-Actions in MET** (`#1546 `_). + * Write a script to automate SonarQube static code analysis runs in the nightly build (`#2020 `_). + * Investigate nightly build output wind direction differences caused by machine precision (`#2027 `_). + +* Logging: + + * Enhance PB2NC to reduce redundant verbosity level 3 log messages (`#2015 `_). + * Print a warning message about switching from Ensemble-Stat to Gen-Ens-Prod (`#1907 `_). + * Update error messages to redirect users from the MET-Help desk to METplus Discussions (`#2054 `_). + +* Repository and installation: + + * Update the copyright year of the source code to 2022 (`#2013 `_). + +* Documentation: + + * Enhance the documentation to follow the standard for sections (`#1998 `_). + MET Version 10.1.0-beta5 release notes (20220114) ------------------------------------------------- diff --git a/met/docs/conf.py b/met/docs/conf.py index 775b1d88ea..4fc13cc8b5 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 = 'Halley Gotway, J., K. Newman, H. Soh, J. Opatz, T. Jensen, J. Prestopnik, L. Goodrich, D. Fillmore, B. Brown, R. Bullock, T. Fowler' -version = '10.1.0-beta5' +version = '10.1.0-beta6' verinfo = version release = f'{version}' release_year = '2022' -release_date = f'{release_year}-01-14' +release_date = f'{release_year}-03-02' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- From 591cbd26ff2f4e3df5ea0354df5ce626b050cad9 Mon Sep 17 00:00:00 2001 From: johnhg Date: Thu, 3 Mar 2022 11:52:46 -0700 Subject: [PATCH 142/172] Feature 1259 BIN_MEAN OBS_THRESH (#2082) --- .../tools/core/ensemble_stat/ensemble_stat.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index 2c9e87e356..11dd67670d 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -2618,7 +2618,7 @@ void do_pct_cat_thresh(const EnsembleStatVxOpt &vx_opt, } // end for i_bin // Write the probabilistic output - write_pct_info(vx_opt, pct_info, n_bin, true); + write_pct_info(vx_opt, pct_info, n_bin, false); } // end for i_ta @@ -2708,7 +2708,7 @@ void do_pct_cdp_thresh(const EnsembleStatVxOpt &vx_opt, } // end for i_bin // Write the probabilistic output - write_pct_info(vx_opt, pct_info, n_bin, false); + write_pct_info(vx_opt, pct_info, n_bin, true); // Dealloate memory if(pct_info) { delete [] pct_info; pct_info = (PCTInfo *) 0; } @@ -2720,7 +2720,7 @@ void do_pct_cdp_thresh(const EnsembleStatVxOpt &vx_opt, void write_pct_info(const EnsembleStatVxOpt &vx_opt, const PCTInfo *pct_info, int n_bin, - bool sum_total) { + bool cdp_thresh) { // Write output for each bin for(int i_bin=0; i_bin 1) { PCTInfo pct_mean; - compute_pct_mean(pct_info, n_bin, pct_mean, sum_total); + + // For non-CDP thresholds, sum the total counts + compute_pct_mean(pct_info, n_bin, pct_mean, !cdp_thresh); + + // For CDP thresholds, reset the OBS_THRESH column to ==1/n_bin + // to indicate the number of climatological bins used + if(cdp_thresh) { + pct_mean.othresh.set((double) 100.0/vx_opt.cdf_info.n_bin, + thresh_eq, perc_thresh_climo_dist); + } // Write out PSTD if(vx_opt.output_flag[i_pstd] != STATOutputType_None) { From de2f9b80d9da3ebe417f8884331a06be48c804e7 Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 7 Mar 2022 06:32:13 -0700 Subject: [PATCH 143/172] Per #1904, fixing a minor copy/paste bug in gen_ens_prod. We were checking the length of config_file instead of out_file. This became obvious when running gen_ens_prod without the -out option. That run segfaulted because it tried to create an output file using an empty string. (#2087) --- met/src/tools/other/gen_ens_prod/gen_ens_prod.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc index eb04d6f38c..ab489047f8 100644 --- a/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc +++ b/met/src/tools/other/gen_ens_prod/gen_ens_prod.cc @@ -154,7 +154,7 @@ void process_command_line(int argc, char **argv) { << "\"-ens\" option.\n\n"; exit(1); } - if(config_file.length() == 0) { + if(out_file.length() == 0) { mlog << Error << "\nprocess_command_line() -> " << "the output file must be set using the " << "\"-out\" option.\n\n"; From ed50ea41b5496aa741696975518eb6abf5596138 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 7 Mar 2022 14:12:00 -0700 Subject: [PATCH 144/172] Initialize tc --- met/src/libcode/vx_grid/grid_base.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/met/src/libcode/vx_grid/grid_base.cc b/met/src/libcode/vx_grid/grid_base.cc index 07f06f890b..fecf307804 100644 --- a/met/src/libcode/vx_grid/grid_base.cc +++ b/met/src/libcode/vx_grid/grid_base.cc @@ -299,6 +299,8 @@ rll = (const RotatedLatLonData *) 0; m = (const MercatorData *) 0; g = (const GaussianData *) 0; gi = (const GoesImagerData *) 0; +gi = (const GoesImagerData *) 0; +tc = (const TcrmwData *) 0; clear(); @@ -321,6 +323,7 @@ if ( rll ) { delete rll; rll = (const RotatedLatLonData *) 0; }; if ( m ) { delete m; m = (const MercatorData *) 0; }; if ( g ) { delete g; g = (const GaussianData *) 0; }; if ( gi ) { delete gi; gi = (const GoesImagerData *) 0; }; +if ( tc ) { delete tc; tc = (const TcrmwData *) 0; }; return; @@ -341,6 +344,7 @@ if ( info.rll ) set( *(info.rll) ); if ( info.m ) set( *(info.m ) ); if ( info.g ) set( *(info.g ) ); if ( info.gi ) set( *(info.gi ) ); +if ( info.tc ) set( *(info.tc ) ); return; @@ -363,6 +367,7 @@ if ( rll ) ++count; if ( m ) ++count; if ( g ) ++count; if ( gi ) ++count; +if ( tc ) ++count; return ( count == 1 ); @@ -391,6 +396,7 @@ else if ( rll ) gg.set( *rll ); else if ( m ) gg.set( *m ); else if ( g ) gg.set( *g ); else if ( gi ) gg.set( *gi ); +else if ( tc ) gg.set( *tc ); return; From 4e7b3939df83b045c15a721af66fc0e3b762b17f Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 7 Mar 2022 14:12:31 -0700 Subject: [PATCH 145/172] #1824 ci-run-test Separated log message for MLCAPE --- met/src/tools/other/pb2nc/pb2nc.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/met/src/tools/other/pb2nc/pb2nc.cc b/met/src/tools/other/pb2nc/pb2nc.cc index 64cbf77e3f..7dc9629403 100644 --- a/met/src/tools/other/pb2nc/pb2nc.cc +++ b/met/src/tools/other/pb2nc/pb2nc.cc @@ -1997,13 +1997,22 @@ void process_pbfile(int i_pb) { << "Total observations retained or derived\t= " << (n_file_obs + n_derived_obs) << "\n"; - if (cal_cape || cal_mlcape) { - mlog << Debug(3) << "\nDerived CAPE = " << (cape_count + mlcape_count) - << "\tZero = " << (cape_cnt_zero_values + mlcape_cnt_zero_values) + if (cal_cape) { + mlog << Debug(3) << "\nDerived CAPE = " << cape_count + << "\tZero = " << cape_cnt_zero_values << "\n\tnot derived: No cape inputs = " << (cape_cnt_no_levels) - << "\tNo vertical levels = " << (cape_cnt_surface_msgs) - << "\n\tfiltered: " << (cape_cnt_missing_values + mlcape_cnt_missing_values) << ", " - << (cape_cnt_too_big + mlcape_cnt_too_big) + << "\tNo vertical levels = " << cape_cnt_surface_msgs + << "\n\tfiltered: " << cape_cnt_missing_values << ", " + << cape_cnt_too_big + << "\n"; + } + if (cal_mlcape) { + mlog << Debug(3) << "\nDerived MLCAPE = " << mlcape_count + << "\tZero = " << mlcape_cnt_zero_values + << "\n\tnot derived: No cape inputs = " << cape_cnt_no_levels + << "\tNo vertical levels = " << cape_cnt_surface_msgs + << "\n\tfiltered: " << mlcape_cnt_missing_values << ", " + << mlcape_cnt_too_big << "\n"; } From bffb7e51e10e84bd9f946ac2507f19bfab2129e8 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 7 Mar 2022 14:27:32 -0700 Subject: [PATCH 146/172] ci-run-test Do not calls set(TcrmwData *) --- met/src/libcode/vx_grid/grid_base.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/met/src/libcode/vx_grid/grid_base.cc b/met/src/libcode/vx_grid/grid_base.cc index fecf307804..dfb1bb49ff 100644 --- a/met/src/libcode/vx_grid/grid_base.cc +++ b/met/src/libcode/vx_grid/grid_base.cc @@ -344,7 +344,6 @@ if ( info.rll ) set( *(info.rll) ); if ( info.m ) set( *(info.m ) ); if ( info.g ) set( *(info.g ) ); if ( info.gi ) set( *(info.gi ) ); -if ( info.tc ) set( *(info.tc ) ); return; @@ -367,7 +366,6 @@ if ( rll ) ++count; if ( m ) ++count; if ( g ) ++count; if ( gi ) ++count; -if ( tc ) ++count; return ( count == 1 ); @@ -396,7 +394,6 @@ else if ( rll ) gg.set( *rll ); else if ( m ) gg.set( *m ); else if ( g ) gg.set( *g ); else if ( gi ) gg.set( *gi ); -else if ( tc ) gg.set( *tc ); return; From ab0305140dab05ec5254119c37ce1c12f70ea202 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 7 Mar 2022 14:36:12 -0700 Subject: [PATCH 147/172] Initialze obs_data at constructor to avoid warninjg on building --- met/src/libcode/vx_nc_obs/met_point_data.cc | 1 + met/src/libcode/vx_nc_obs/met_point_data.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc index d512fd8d91..b22e3fe7b4 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.cc +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -38,6 +38,7 @@ using namespace std; MetPointData::MetPointData() { // Derived class should set obs_data + obs_data = (MetPointObsData *0; init_from_scratch(); } diff --git a/met/src/libcode/vx_nc_obs/met_point_data.h b/met/src/libcode/vx_nc_obs/met_point_data.h index a061d49741..8da98fe501 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.h +++ b/met/src/libcode/vx_nc_obs/met_point_data.h @@ -93,7 +93,7 @@ class MetPointData { bool use_arr_vars; MetPointHeader header_data; - MetPointObsData *obs_data = 0; + MetPointObsData *obs_data; void init_from_scratch(); From 4605a7799441f736bfc02cc4d20c14bce6c76ab9 Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 7 Mar 2022 14:42:11 -0700 Subject: [PATCH 148/172] Initialze obs_data at constructor to avoid a warning by compiler --- met/src/libcode/vx_nc_obs/met_point_data.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/libcode/vx_nc_obs/met_point_data.cc b/met/src/libcode/vx_nc_obs/met_point_data.cc index b22e3fe7b4..0f78e2be0a 100644 --- a/met/src/libcode/vx_nc_obs/met_point_data.cc +++ b/met/src/libcode/vx_nc_obs/met_point_data.cc @@ -38,7 +38,7 @@ using namespace std; MetPointData::MetPointData() { // Derived class should set obs_data - obs_data = (MetPointObsData *0; + obs_data = (MetPointObsData *)0; init_from_scratch(); } From 182f461aa7d60a01558c4fb1ac6e7184e389029f Mon Sep 17 00:00:00 2001 From: Howard Soh Date: Mon, 7 Mar 2022 14:42:56 -0700 Subject: [PATCH 149/172] #1824 ci-run-test Removed the duplicated code --- met/src/libcode/vx_grid/grid_base.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/met/src/libcode/vx_grid/grid_base.cc b/met/src/libcode/vx_grid/grid_base.cc index dfb1bb49ff..035d6765e0 100644 --- a/met/src/libcode/vx_grid/grid_base.cc +++ b/met/src/libcode/vx_grid/grid_base.cc @@ -299,7 +299,6 @@ rll = (const RotatedLatLonData *) 0; m = (const MercatorData *) 0; g = (const GaussianData *) 0; gi = (const GoesImagerData *) 0; -gi = (const GoesImagerData *) 0; tc = (const TcrmwData *) 0; clear(); From 04510c35fbe587abf4285b5d4a555e6a0d0ed6fc Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 7 Mar 2022 15:40:01 -0700 Subject: [PATCH 150/172] Feature 1810 expand asciitable (#2086) --- met/src/tools/tc_utils/tc_gen/tc_gen.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/met/src/tools/tc_utils/tc_gen/tc_gen.cc b/met/src/tools/tc_utils/tc_gen/tc_gen.cc index d8a06b4346..c6f136d5d5 100644 --- a/met/src/tools/tc_utils/tc_gen/tc_gen.cc +++ b/met/src/tools/tc_utils/tc_gen/tc_gen.cc @@ -1825,7 +1825,12 @@ void setup_txt_files(int n_model, int max_n_prob, int n_pair) { } // Otherwise, resize the existing table else { - txt_at[i].expand(n_rows, n_cols); + int need_rows = max(txt_at[i].nrows(), i_txt_row[i] + n_rows); + int need_cols = max(txt_at[i].ncols(), n_cols); + + if(need_rows > txt_at[i].nrows() || need_cols > txt_at[i].ncols()) { + txt_at[i].expand(need_rows, need_cols); + } } } // end if } // end for i @@ -1851,7 +1856,12 @@ void setup_txt_files(int n_model, int max_n_prob, int n_pair) { } // Otherwise, resize the existing table else { - stat_at.expand(stat_rows, stat_cols); + int need_rows = max(stat_at.nrows(), i_stat_row + stat_rows); + int need_cols = max(stat_at.ncols(), stat_cols); + + if(need_rows > stat_at.nrows() || need_cols > stat_at.ncols()) { + stat_at.expand(need_rows, need_cols); + } } return; From ee0be03969804fe0d4ffa2c9a44a84d4e330250b Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 8 Mar 2022 15:18:41 -0700 Subject: [PATCH 151/172] Feature 1583 skip_mean (#2090) --- met/src/basic/vx_util/num_array.cc | 21 +++++++++++++++++++ met/src/basic/vx_util/num_array.h | 2 ++ met/src/libcode/vx_statistics/ens_stats.cc | 8 +++---- .../vx_statistics/pair_data_ensemble.cc | 4 ++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/met/src/basic/vx_util/num_array.cc b/met/src/basic/vx_util/num_array.cc index fb4642d1a6..002e1b5b61 100644 --- a/met/src/basic/vx_util/num_array.cc +++ b/met/src/basic/vx_util/num_array.cc @@ -269,6 +269,27 @@ int NumArray::has(double d, bool forward) const //////////////////////////////////////////////////////////////////////// +bool NumArray::is_const(double d) const + +{ + + bool status = true; + + for (int j=0; j 0 ); + +} + + +//////////////////////////////////////////////////////////////////////// + + void NumArray::add(int k) { diff --git a/met/src/basic/vx_util/num_array.h b/met/src/basic/vx_util/num_array.h index c4a061f0f7..116d3a2db1 100644 --- a/met/src/basic/vx_util/num_array.h +++ b/met/src/basic/vx_util/num_array.h @@ -62,6 +62,8 @@ class NumArray { int has(int, bool forward=true) const; int has(double, bool forward=true) const; + bool is_const(double) const; + void add(int); void add(double); void add(const NumArray &); diff --git a/met/src/libcode/vx_statistics/ens_stats.cc b/met/src/libcode/vx_statistics/ens_stats.cc index 56857b084b..d0bcfde0bd 100644 --- a/met/src/libcode/vx_statistics/ens_stats.cc +++ b/met/src/libcode/vx_statistics/ens_stats.cc @@ -228,9 +228,6 @@ void ECNTInfo::set(const PairDataEnsemble &pd) { // Store the number of ensemble members n_ens = pd.n_ens; - // HiRA data has no ensemble mean - bool skip_mean = pd.mn_na.has(bad_data_double); - // Compute empirical CRPS scores crps_emp = pd.crps_emp_na.wmean(pd.wgt_na); crpscl_emp = pd.crpscl_emp_na.wmean(pd.wgt_na); @@ -260,8 +257,9 @@ void ECNTInfo::set(const PairDataEnsemble &pd) { } } - // Compute ensemble mean based statistics - if(!skip_mean) { + // Compute ensemble mean based statistics, if possible + // HiRA stores the ensemble mean as bad data + if(!pd.mn_na.is_const(bad_data_double)) { // Compute ME and RMSE values fbar = obar = ffbar = oobar = fobar = 0.0; diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 78517511d2..51b43d0c37 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -628,9 +628,9 @@ void PairDataEnsemble::compute_ssvar() { ssvar_bin_map bins; NumArray cur; + // SSVAR requires valid ensemble mean input // HiRA stores the ensemble mean as bad data - // Do not compute SSVAR when bad data is present - if(mn_na.has(bad_data_double)) return; + if(mn_na.is_const(bad_data_double)) return; // Check number of points if(o_na.n() != mn_na.n()) { From ef0162812823b342e7a482d8b81ed64dac0e356f Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 8 Mar 2022 20:55:43 -0700 Subject: [PATCH 152/172] Feature 1275 MODE Object Count (#2091) * for #1275, fix issue with more than 1000 object for mode, ci-run-unit * Per #1275, just deleting stale, commented-out code. Co-authored-by: Randy Bullock --- met/src/basic/vx_util/ascii_table.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/met/src/basic/vx_util/ascii_table.cc b/met/src/basic/vx_util/ascii_table.cc index 0074c28071..fccfede13b 100644 --- a/met/src/basic/vx_util/ascii_table.cc +++ b/met/src/basic/vx_util/ascii_table.cc @@ -1328,8 +1328,8 @@ if ( Nrows < 0 || Nrows >= INT_MAX ) { if ( Nrows <= 2 ) return; -int left[Nrows]; -int right[Nrows]; +int * left = new int [Nrows]; +int * right = new int [Nrows]; int r, c, n, k; int max_left, max_right; @@ -1378,6 +1378,9 @@ for (c=0; c Date: Wed, 9 Mar 2022 17:50:14 -0700 Subject: [PATCH 153/172] Feature 1184 dryline (#2088) Co-authored-by: davidfillmore Co-authored-by: rgbullock Co-authored-by: John Halley Gotway --- .github/workflows/testing.yml | 2 +- met/Make-include | 2 + met/configure.ac | 1 + met/data/config/MODEConfig_default | 1 - met/data/config/MODEMultivarConfig_default | 259 ++++++++ met/data/config/Makefile.am | 1 + met/docs/Users_Guide/mode.rst | 26 +- met/src/basic/vx_config/config_constants.h | 6 + met/src/basic/vx_config/dictionary.h | 4 + met/src/basic/vx_util/command_line.cc | 46 ++ met/src/basic/vx_util/command_line.h | 5 +- met/src/basic/vx_util/file_exists.cc | 40 ++ met/src/basic/vx_util/file_exists.h | 2 + met/src/basic/vx_util/two_d_array.h | 22 + met/src/libcode/Makefile.am | 3 +- met/src/libcode/vx_bool_calc/.gitignore | 7 + met/src/libcode/vx_bool_calc/Makefile.am | 31 + met/src/libcode/vx_bool_calc/bool_calc.cc | 219 +++++++ met/src/libcode/vx_bool_calc/bool_calc.h | 68 +++ met/src/libcode/vx_bool_calc/make_program.cc | 307 ++++++++++ met/src/libcode/vx_bool_calc/make_program.h | 45 ++ met/src/libcode/vx_bool_calc/token.cc | 390 ++++++++++++ met/src/libcode/vx_bool_calc/token.h | 192 ++++++ met/src/libcode/vx_bool_calc/token_stack.cc | 415 +++++++++++++ met/src/libcode/vx_bool_calc/token_stack.h | 98 +++ met/src/libcode/vx_bool_calc/tokenizer.cc | 244 ++++++++ met/src/libcode/vx_bool_calc/tokenizer.h | 53 ++ met/src/libcode/vx_shapedata/Makefile.am | 1 + met/src/libcode/vx_shapedata/engine.cc | 136 ++--- .../libcode/vx_shapedata/mode_conf_info.cc | 543 ++++++++++++----- met/src/libcode/vx_shapedata/mode_conf_info.h | 201 ++++--- .../libcode/vx_shapedata/mode_data_field.h | 64 ++ .../libcode/vx_shapedata/mode_field_info.cc | 301 ++++++++++ .../libcode/vx_shapedata/mode_field_info.h | 110 ++++ met/src/tools/core/mode/Makefile.am | 8 +- met/src/tools/core/mode/combine_boolplanes.cc | 111 ++++ met/src/tools/core/mode/combine_boolplanes.h | 62 ++ met/src/tools/core/mode/mode.cc | 257 +------- met/src/tools/core/mode/mode_exec.cc | 92 ++- met/src/tools/core/mode/mode_exec.h | 8 +- met/src/tools/core/mode/mode_frontend.cc | 345 +++++++++++ met/src/tools/core/mode/mode_multivar.cc | 335 +++++++++++ met/src/tools/core/mode/mode_ps_file.cc | 39 +- met/src/tools/core/mode/mode_ps_file.h | 2 - met/src/tools/core/mode/mode_ps_table_defs.h | 8 +- met/src/tools/core/mode/mode_singlevar.cc | 335 +++++++++++ met/src/tools/core/mode/mode_usage.cc | 156 +++++ met/src/tools/core/mode/mode_usage.h | 33 + met/src/tools/core/mode/multivar_frontend.cc | 568 ++++++++++++++++++ .../tools/core/mode/objects_from_netcdf.cc | 177 ++++++ met/src/tools/core/mode/objects_from_netcdf.h | 49 ++ met/src/tools/core/mode/page_1.cc | 40 +- test/bin/unit_test.sh | 1 + test/config/MODEConfig_multivar_fake_data | 259 ++++++++ test/xml/unit_mode_multivar.xml | 42 ++ 55 files changed, 6134 insertions(+), 638 deletions(-) create mode 100644 met/data/config/MODEMultivarConfig_default create mode 100644 met/src/libcode/vx_bool_calc/.gitignore create mode 100644 met/src/libcode/vx_bool_calc/Makefile.am create mode 100644 met/src/libcode/vx_bool_calc/bool_calc.cc create mode 100644 met/src/libcode/vx_bool_calc/bool_calc.h create mode 100644 met/src/libcode/vx_bool_calc/make_program.cc create mode 100644 met/src/libcode/vx_bool_calc/make_program.h create mode 100644 met/src/libcode/vx_bool_calc/token.cc create mode 100644 met/src/libcode/vx_bool_calc/token.h create mode 100644 met/src/libcode/vx_bool_calc/token_stack.cc create mode 100644 met/src/libcode/vx_bool_calc/token_stack.h create mode 100644 met/src/libcode/vx_bool_calc/tokenizer.cc create mode 100644 met/src/libcode/vx_bool_calc/tokenizer.h create mode 100644 met/src/libcode/vx_shapedata/mode_data_field.h create mode 100644 met/src/libcode/vx_shapedata/mode_field_info.cc create mode 100644 met/src/libcode/vx_shapedata/mode_field_info.h create mode 100644 met/src/tools/core/mode/combine_boolplanes.cc create mode 100644 met/src/tools/core/mode/combine_boolplanes.h create mode 100644 met/src/tools/core/mode/mode_frontend.cc create mode 100644 met/src/tools/core/mode/mode_multivar.cc create mode 100644 met/src/tools/core/mode/mode_singlevar.cc create mode 100644 met/src/tools/core/mode/mode_usage.cc create mode 100644 met/src/tools/core/mode/mode_usage.h create mode 100644 met/src/tools/core/mode/multivar_frontend.cc create mode 100644 met/src/tools/core/mode/objects_from_netcdf.cc create mode 100644 met/src/tools/core/mode/objects_from_netcdf.h create mode 100644 test/config/MODEConfig_multivar_fake_data create mode 100644 test/xml/unit_mode_multivar.xml diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 61f2c43840..88332b4da0 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -148,7 +148,7 @@ jobs: matrix: tests: - 'ascii2nc_indy pb2nc_indy tc_dland tc_pairs tc_stat plot_tc tc_rmw rmw_analysis tc_gen' - - 'met_test_scripts mode_graphics mtd regrid airnow gsi_tools netcdf modis series_analysis gen_ens_prod wwmca_regrid gen_vx_mask grid_weight interp_shape grid_diag grib_tables lidar2nc shift_data_plane trmm2nc aeronet wwmca_plot ioda2nc gaussian' + - 'met_test_scripts mode_multivar mode_graphics mtd regrid airnow gsi_tools netcdf modis series_analysis gen_ens_prod wwmca_regrid gen_vx_mask grid_weight interp_shape grid_diag grib_tables lidar2nc shift_data_plane trmm2nc aeronet wwmca_plot ioda2nc gaussian' fail-fast: false steps: - uses: actions/checkout@v2 diff --git a/met/Make-include b/met/Make-include index 42f1d5f3b3..784b2dcdd8 100644 --- a/met/Make-include +++ b/met/Make-include @@ -34,6 +34,7 @@ MET_CPPFLAGS = -I${top_builddir}/src/basic/vx_cal \ -I${top_builddir}/src/libcode/vx_solar \ -I${top_builddir}/src/libcode/vx_statistics \ -I${top_builddir}/src/libcode/vx_stat_out \ + -I${top_builddir}/src/libcode/vx_bool_calc \ -I${top_builddir}/src/libcode/vx_summary \ -I${top_builddir}/src/libcode/vx_time_series \ -I${top_builddir}/src/libcode/vx_series_data \ @@ -73,6 +74,7 @@ MET_LDFLAGS = -L${top_builddir}/src/basic/vx_cal \ -L${top_builddir}/src/libcode/vx_pxm \ -L${top_builddir}/src/libcode/vx_render \ -L${top_builddir}/src/libcode/vx_regrid \ + -L${top_builddir}/src/libcode/vx_bool_calc \ -L${top_builddir}/src/libcode/vx_shapedata \ -L${top_builddir}/src/libcode/vx_solar \ -L${top_builddir}/src/libcode/vx_statistics \ diff --git a/met/configure.ac b/met/configure.ac index df6a93a428..341c2f4592 100644 --- a/met/configure.ac +++ b/met/configure.ac @@ -1240,6 +1240,7 @@ AC_CONFIG_FILES([Makefile src/libcode/vx_summary/Makefile src/libcode/vx_python3_utils/Makefile src/libcode/vx_data2d_python/Makefile + src/libcode/vx_bool_calc/Makefile src/libcode/vx_pointdata_python/Makefile src/tools/Makefile src/tools/core/Makefile diff --git a/met/data/config/MODEConfig_default b/met/data/config/MODEConfig_default index 0b38827ef3..35090f770a 100644 --- a/met/data/config/MODEConfig_default +++ b/met/data/config/MODEConfig_default @@ -25,7 +25,6 @@ obtype = "ANALYS"; // // Verification grid -// May be set separately in each "field" entry // regrid = { to_grid = NONE; diff --git a/met/data/config/MODEMultivarConfig_default b/met/data/config/MODEMultivarConfig_default new file mode 100644 index 0000000000..dde6e5ca3b --- /dev/null +++ b/met/data/config/MODEMultivarConfig_default @@ -0,0 +1,259 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// MODE configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "WRF"; + +// +// Output description to be written +// +desc = "NA"; + +// +// Output observation type to be written +// +obtype = "ANALYS"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Approximate grid resolution (km) +// +grid_res = 20; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Run all permutations of radius and threshold +// +quilt = FALSE; + +// +// MODE Multivar boolean combination logic +// +multivar_logic = "#1 && #2 && #3"; + +// +// Forecast and observation fields to be verified +// +fcst = { + + field = [ + + { + name = "ALPHA"; + level = "(*,*)"; + }, + + { + name = "BETA"; + level = "(*,*)"; + }, + + { + name = "GAMMA"; + level = "(*,*)"; + } + + ]; + + conv_radius = 2; // in grid squares + conv_thresh = >=5.0; + vld_thresh = 0.5; + filter_attr_name = []; + filter_attr_thresh = []; + merge_thresh = >=3.5; + merge_flag = NONE; +} +obs = fcst; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Handle missing data +// +mask_missing_flag = NONE; + +// +// Match objects between the forecast and observation fields +// +match_flag = NONE; + +// +// Maximum centroid distance for objects to be compared +// +max_centroid_dist = 800.0/grid_res; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification masking regions +// +mask = { + grid = ""; + grid_flag = NONE; // Apply to NONE, FCST, OBS, or BOTH + poly = ""; + poly_flag = NONE; // Apply to NONE, FCST, OBS, or BOTH +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Fuzzy engine weights +// +weight = { + centroid_dist = 2.0; + boundary_dist = 4.0; + convex_hull_dist = 0.0; + angle_diff = 1.0; + aspect_diff = 0.0; + area_ratio = 1.0; + int_area_ratio = 2.0; + curvature_ratio = 0.0; + complexity_ratio = 0.0; + inten_perc_ratio = 0.0; + inten_perc_value = 50; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Fuzzy engine interest functions +// +interest_function = { + + centroid_dist = ( + ( 0.0, 1.0 ) + ( 60.0/grid_res, 1.0 ) + ( 600.0/grid_res, 0.0 ) + ); + + boundary_dist = ( + ( 0.0, 1.0 ) + ( 400.0/grid_res, 0.0 ) + ); + + convex_hull_dist = ( + ( 0.0, 1.0 ) + ( 400.0/grid_res, 0.0 ) + ); + + angle_diff = ( + ( 0.0, 1.0 ) + ( 30.0, 1.0 ) + ( 90.0, 0.0 ) + ); + + aspect_diff = ( + ( 0.00, 1.0 ) + ( 0.10, 1.0 ) + ( 0.75, 0.0 ) + ); + + corner = 0.8; + ratio_if = ( + ( 0.0, 0.0 ) + ( corner, 1.0 ) + ( 1.0, 1.0 ) + ); + + area_ratio = ratio_if; + + int_area_ratio = ( + ( 0.00, 0.00 ) + ( 0.10, 0.50 ) + ( 0.25, 1.00 ) + ( 1.00, 1.00 ) + ); + + curvature_ratio = ratio_if; + + complexity_ratio = ratio_if; + + inten_perc_ratio = ratio_if; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Total interest threshold for determining matches +// +total_interest_thresh = 0.7; + +// +// Interest threshold for printing output pair information +// +print_interest_thresh = 0.0; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Plotting information +// +met_data_dir = "MET_BASE"; + +fcst_raw_plot = { + color_table = "MET_BASE/colortables/met_default.ctable"; + plot_min = 0.0; + plot_max = 0.0; +} + +obs_raw_plot = { + color_table = "MET_BASE/colortables/met_default.ctable"; + plot_min = 0.0; + plot_max = 0.0; +} + +object_plot = { + color_table = "MET_BASE/colortables/mode_obj.ctable"; +} + +// +// Boolean for plotting on the region of valid data within the domain +// +plot_valid_flag = FALSE; + +// +// Plot polyline edges using great circle arcs instead of straight lines +// +plot_gcarc_flag = FALSE; + +//////////////////////////////////////////////////////////////////////////////// + +// +// NetCDF matched pairs, PostScript, and contingency table output files +// +ps_plot_flag = TRUE; +nc_pairs_flag = TRUE; +ct_stats_flag = TRUE; + +//////////////////////////////////////////////////////////////////////////////// + +shift_right = 0; // grid squares + +//////////////////////////////////////////////////////////////////////////////// + +output_prefix = ""; +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/Makefile.am b/met/data/config/Makefile.am index 5ab35344a9..6766b264dc 100644 --- a/met/data/config/Makefile.am +++ b/met/data/config/Makefile.am @@ -30,6 +30,7 @@ config_DATA = \ Madis2NcConfig_default \ MODEAnalysisConfig_default \ MODEConfig_default \ + MODEMultivarConfig_default \ MTDConfig_default \ PB2NCConfig_default \ PointStatConfig_default \ diff --git a/met/docs/Users_Guide/mode.rst b/met/docs/Users_Guide/mode.rst index a0df6932da..5413546077 100644 --- a/met/docs/Users_Guide/mode.rst +++ b/met/docs/Users_Guide/mode.rst @@ -103,10 +103,21 @@ Summary statistics Once MODE has been run, summary statistics are written to an output file. These files contain information about all single and cluster objects and their attributes. Total interest for object pairs is also output, as are percentiles of intensity inside the objects. The output file is in a simple flat ASCII tabular format (with one header line) and thus should be easily readable by just about any programming language, scripting language, or statistics package. Refer to :numref:`MODE-output` for lists of the statistics included in the MODE output files. Example scripts will be posted on the MET website in the future. +.. _MODE-multivar: + +Multi-Variate MODE +------------------ + +Traditionally, MODE defines objects by smoothing and thresholding data from a single input field. MET version 10.1.0 extends MODE by adding the option to define objects using multiple input fields. + +As described in :numref:`MODE-configuration-file`, the **field** entry in the forecast and observation dictionaries define the input data to be processed. If **field** is defined as a dictionary, the traditional method for running MODE is invoked, where objects are defined using a single input field. If **field** is defined as an array of dictionaries, each specifying a different input field, then the multi-variate MODE logic is invoked and requires the **multivar_logic** configuration entry to be set. Traditional MODE is run once for each input field to define objects for that field. Note that the object definition criteria can be defined separately for each field array entry. The objects from each input field are combined into a *super* object for both the forecast and observation data. + +The **multivar_logic** configuration entry, described in :numref:`MODE-configuration-file`, defines the boolean logic for combining objects from multiple fields into a *super* object. If this configuration option is set, there must be an equal or greater number of fields defined in an array of dictionaries for it define a *super* object of more than one field. Note that the multi-variate MODE forecast and observation input fields and combination logic do not need to match. The resulting forecast and observation *super* objects are written to NetCDF output files. Users can then configure and run traditional MODE to compare the forecast super object to the observed super object. + Practical information ===================== -This section contains a description of how MODE can be configured and run. The MODE tool is used to perform a features-based verification of gridded model data using gridded observations. The input gridded model and observation datasets must be in one of the MET supported gridded file formats. The requirement of having all gridded fields using the same grid specification has been removed with METv5.1. The Grid-Stat tool performs no interpolation when the input model, observation, and climatology datasets must be on a common grid. MET will interpolate these files to a common grid if one is specified. There is a regrid option in the configuration file that allows the user to define the grid upon which the scores will be computed. The gridded analysis data may be based on observations, such as Stage II or Stage IV data for verifying accumulated precipitation, or a model analysis field may be used. However, users are cautioned that it is generally unwise to verify model output using an analysis field produced by the same model. +This section contains a description of how MODE can be configured and run. The MODE tool is used to perform a features-based verification of gridded model data using gridded observations. The input gridded model and observation datasets must be in one of the MET supported gridded file formats. If the input datasets are not already on a common grid, MODE can interpolate them to a common grid. The regrid option in the configuration file enables the user to specify the grid upon which the scores will be computed. The gridded analysis data may be based on observations, such as Stage II or Stage IV data for verifying accumulated precipitation, or a model analysis field may be used. However, users are cautioned that it is generally unwise to verify model output using an analysis field produced by the same model. MODE provides the capability to select a single model variable/level from which to derive objects to be analyzed. MODE was developed and tested using accumulated precipitation. However, the code has been generalized to allow the use of any gridded model and observation field. Based on the options specified in the configuration file, MODE will define a set of simple objects in the model and observation fields. It will then compute an interest value for each pair of objects across the fields using a fuzzy engine approach. Those interest values are thresholded, and any pairs of objects above the threshold will be matched/merged. Through the configuration file, MODE offers a wide range of flexibility in how the objects are defined, processed, matched, and merged. @@ -198,7 +209,6 @@ _____________________ The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. - _____________________ .. code-block:: none @@ -221,6 +231,16 @@ The **quilt** entry indicates whether all permutations of convolution radii and _____________________ +.. code-block:: none + + multivar_logic = "#1 && #2 && #3"; + +The **multivar_logic** entry appears only in the **MODEMultivarConfig_default** file. This option applies to running multi-variate MODE by setting **field** to an array of dictionaries to define multiple input fields. Objects are defined separately for each input field based on the configuration settings specified for each field array entry. The **multivar_logic** entry is a string which defines how objects for each field are combined into a final *super* object. The objects for each field are referred to as '#N' where N is the N-th field array entry. The '&&' and '||' strings define intersection and union logic, respectively. For example, "#1 && #2" is the intersection of the objects from the first and second fields. "(#1 && #2) || #3" is the union of that intersection with the objects from the third field. + +The **multivar_logic** entry is parsed separately from the **fcst** and **obs** dictionaries and can be defined differently in each. + +_____________________ + .. code-block:: none fcst = { @@ -242,6 +262,8 @@ _____________________ The **field** entries in the forecast and observation dictionaries specify the model and observation variables and level to be compared. See a more complete description of them in :numref:`config_options`. In the above example, the forecast settings are copied into the observation dictionary using **obs = fcst;.** +When **field** is set to an array of dictionaries rather than a single one, the multi-variate MODE logic is invoked. Please see :numref:`MODE-multivar` for a description of that logic. + The **censor_thresh** and **censor_val** entries are used to censor the raw data as described in :numref:`config_options`. Their functionality replaces the **raw_thresh** entry, which is deprecated in met-6.1. Prior to defining objects, it is recommended that the raw fields should be made to look similar to each other. For example, if the model only predicts values for a variable above some threshold, the observations should be thresholded at that same level. The censor thresholds can be specified using symbols. By default, no censor thresholding is applied. The **conv_radius** entry defines the radius of the circular convolution applied to smooth the raw fields. The radii are specified in terms of grid units. The default convolution radii are defined in terms of the previously defined **grid_res** entry. Multiple convolution radii may be specified as an array (e.g. **conv_radius = [ 5, 10, 15 ];**). diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index 24d9517542..f95e9b0e44 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -657,6 +657,12 @@ static const char conf_key_is_wind_speed[] = "is_wind_speed"; static const char conf_key_is_wind_direction[] = "is_wind_direction"; static const char conf_key_is_prob[] = "is_prob"; +// +// for use with mode multivar +// + +static const char conf_key_multivar_logic [] = "multivar_logic"; + // // Climatology parameter key names // diff --git a/met/src/basic/vx_config/dictionary.h b/met/src/basic/vx_config/dictionary.h index 08f84191c3..6319e8d78c 100644 --- a/met/src/basic/vx_config/dictionary.h +++ b/met/src/basic/vx_config/dictionary.h @@ -127,6 +127,8 @@ class DictionaryEntry { const ConcatString string_value () const; + Dictionary * dict () const; // doesn't check for dict vs array + Dictionary * dict_value () const; Dictionary * array_value () const; @@ -165,6 +167,8 @@ inline int DictionaryEntry::n_args() const { return ( Nargs ); } inline const IcodeVector * DictionaryEntry::icv() const { return ( v ); } +inline Dictionary * DictionaryEntry::dict() const { return ( Dict ); } + //////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/command_line.cc b/met/src/basic/vx_util/command_line.cc index d1c1cefcfb..366123c78c 100644 --- a/met/src/basic/vx_util/command_line.cc +++ b/met/src/basic/vx_util/command_line.cc @@ -652,6 +652,52 @@ return; //////////////////////////////////////////////////////////////////////// +void CommandLine::set(const StringArray & a) + +{ + +clear(); + +int j; +ConcatString s; + + +ProgramName = get_short_name(a[0].c_str()); + +for (j=1; j<(a.n()); ++j) { // j starts at one here, not zero + + s = a[j]; + + args.add(s); + +} + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void CommandLine::set(const StringArray & a, UsageFunction uf) + +{ + +set(a); + +set_usage(uf); + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + void CommandLine::shift_down(int pos, int k) { diff --git a/met/src/basic/vx_util/command_line.h b/met/src/basic/vx_util/command_line.h index d992ed81ca..9acbc3fa9b 100644 --- a/met/src/basic/vx_util/command_line.h +++ b/met/src/basic/vx_util/command_line.h @@ -176,7 +176,10 @@ class CommandLine { // set stuff // - void set(int argc, char ** argv); // includes argv[0] + void set(int argc, char ** argv); // includes argv[0] + + void set(const StringArray &); // includes argv[0] + void set(const StringArray &, UsageFunction); // includes argv[0] void set_usage(UsageFunction); diff --git a/met/src/basic/vx_util/file_exists.cc b/met/src/basic/vx_util/file_exists.cc index 92473fe46d..a09f5cb715 100644 --- a/met/src/basic/vx_util/file_exists.cc +++ b/met/src/basic/vx_util/file_exists.cc @@ -20,8 +20,13 @@ using namespace std; #include #include #include +#include +#include +#include +#include #include "file_exists.h" +#include "empty_string.h" //////////////////////////////////////////////////////////////////////// @@ -45,3 +50,38 @@ return ( false ); //////////////////////////////////////////////////////////////////////// +bool directory_exists(const char * path) + +{ + +if ( empty(path) ) { + + cerr << "\n\n directory_exists(const char *) -> empty path!\n\n"; + + exit ( 1 ); + +} + +if ( ! file_exists(path) ) return ( false ); + +struct stat s; + +if ( stat(path, &s) < 0 ) { + + cerr << "\n\n directory_exists(const char *) -> unable to stat path \"" + << path << "\" ... " << strerror(errno) << "\n\n"; + + exit ( 1 ); + +} + +if ( S_ISDIR(s.st_mode) ) return ( true ); + +return ( false ); + +} + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/basic/vx_util/file_exists.h b/met/src/basic/vx_util/file_exists.h index 75bcf2879b..ed3d7db2ec 100644 --- a/met/src/basic/vx_util/file_exists.h +++ b/met/src/basic/vx_util/file_exists.h @@ -23,6 +23,8 @@ extern bool file_exists(const char * path); +extern bool directory_exists(const char * path); + //////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/two_d_array.h b/met/src/basic/vx_util/two_d_array.h index 8b1aba2203..ca683e13e8 100644 --- a/met/src/basic/vx_util/two_d_array.h +++ b/met/src/basic/vx_util/two_d_array.h @@ -95,6 +95,8 @@ class TwoD_Array { void put(const T &, int _x, int _y); + T get(int _x, int _y) const; // there are times when operator[] or operator() are inconvenient + bool s_is_on(int _x, int _y) const; bool f_is_on(int _x, int _y) const; @@ -279,6 +281,20 @@ return ( E[two_to_one(_x, _y)] ); //////////////////////////////////////////////////////////////////////// +template + +T TwoD_Array::get(int _x, int _y) const + +{ + +return ( E[two_to_one(_x, _y)] ); + +} + + +//////////////////////////////////////////////////////////////////////// + + template bool TwoD_Array::s_is_on(int _x, int _y) const @@ -379,6 +395,12 @@ return ( -1 ); //////////////////////////////////////////////////////////////////////// +typedef TwoD_Array BoolPlane; + + +//////////////////////////////////////////////////////////////////////// + + #endif /* __MET_TWO_D_ARRAY_H__ */ diff --git a/met/src/libcode/Makefile.am b/met/src/libcode/Makefile.am index 8ed5d82c73..7d6f82fb1e 100644 --- a/met/src/libcode/Makefile.am +++ b/met/src/libcode/Makefile.am @@ -59,6 +59,7 @@ SUBDIRS += vx_data2d_factory \ vx_series_data \ vx_regrid \ vx_nc_obs \ - vx_solar + vx_solar \ + vx_bool_calc MAINTAINERCLEANFILES = Makefile.in diff --git a/met/src/libcode/vx_bool_calc/.gitignore b/met/src/libcode/vx_bool_calc/.gitignore new file mode 100644 index 0000000000..92b269f31e --- /dev/null +++ b/met/src/libcode/vx_bool_calc/.gitignore @@ -0,0 +1,7 @@ +*_to_string.h +*_to_string.cc +*.o +*.a +.deps +Makefile +Makefile.in diff --git a/met/src/libcode/vx_bool_calc/Makefile.am b/met/src/libcode/vx_bool_calc/Makefile.am new file mode 100644 index 0000000000..0625684670 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/Makefile.am @@ -0,0 +1,31 @@ +## @start 1 +## Makefile.am -- Process this file with automake to produce Makefile.in +## @end 1 + +MAINTAINERCLEANFILES = Makefile.in + +# Include the project definitions + +include ${top_srcdir}/Make-include + +# The library + +noinst_LIBRARIES = libvx_bool_calc.a +libvx_bool_calc_a_SOURCES = \ + tokentype_to_string.cc tokentype_to_string.h \ + make_program.cc make_program.h \ + bool_calc.cc bool_calc.h \ + token.cc token.h \ + tokenizer.cc tokenizer.h \ + token_stack.cc token_stack.h +libvx_bool_calc_a_CPPFLAGS = ${MET_CPPFLAGS} + +if ENABLE_DEVELOPMENT +tokentype_to_string.cc tokentype_to_string.h: token.h + ${ENUM_TO_STRING} -concat_string -reverse token.h + +clean-local: + -rm -f tokentype_to_string.cc + -rm -f tokentype_to_string.h +endif + diff --git a/met/src/libcode/vx_bool_calc/bool_calc.cc b/met/src/libcode/vx_bool_calc/bool_calc.cc new file mode 100644 index 0000000000..bdd05c2c0a --- /dev/null +++ b/met/src/libcode/vx_bool_calc/bool_calc.cc @@ -0,0 +1,219 @@ + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include + +#include "bool_calc.h" +#include "make_program.h" + +#include "vx_log.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class BoolCalc + // + + +//////////////////////////////////////////////////////////////////////// + + +BoolCalc::BoolCalc() + +{ + +init_from_scratch(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +BoolCalc::~BoolCalc() { + +clear(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void BoolCalc::init_from_scratch() + +{ + +s = 0; + +program = 0; + +clear(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void BoolCalc::clear() + +{ + +if ( s ) { delete s; s = 0; } + +if ( program ) { delete program; program = 0; } + +Max_depth = Max_local = 0; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void BoolCalc::set(const char * algebraic) + +{ + +program = new Program; + +make_program(algebraic, *program); + +s = new stack; + +Max_depth = max_depth(*program); + +Max_local = max_local(*program); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void BoolCalc::dump_program(ostream & out) const + +{ + +int j; +const Program P = *program; + +for (j=0; j<(int) (program->size()); ++j) { + + out << "\nElement # " << j << " ... \n"; + + P[j].dump(out, 1); + +} // for j + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool BoolCalc::run(const vector arg) + +{ + +int j; +Token tok; +bool tf = false; +bool tf2 = false; +bool result = false; +Program & P = *program; + + +for (j=0; j<((int) P.size()); ++j) { + + tok = P[j]; + + switch ( tok.type ) { + + + case tok_local_var: + tf = arg[tok.number_1b - 1]; // don't forget the -1 + s->push(tf); + break; + + + case tok_negation: + tf = s->top(); + s->pop(); + s->push(!tf); + break; + + + case tok_union: + tf2 = s->top(); + s->pop(); + tf = s->top(); + s->pop(); + s->push(tf || tf2); + break; + + + case tok_intersection: + tf2 = s->top(); + s->pop(); + tf = s->top(); + s->pop(); + s->push(tf && tf2); + break; + + + default: + mlog << Error << "\nBoolCalc::run(const vector) -> " + << "bad token in program ... \n\n"; + tok.dump(cerr, 1); + exit ( 1 ); + break; + + } // switch + +} // for j + + +if ( s->size() != 1 ) { + + mlog << Error << "\nBoolCalc::run(const vector) -> " + << "too many elements left on stack! (" + << (s->size()) << ")\n\n"; + + exit ( 1 ); + +} + +result = s->top(); + +s->pop(); + +return ( result ); + +} + + +//////////////////////////////////////////////////////////////////////// + + + + diff --git a/met/src/libcode/vx_bool_calc/bool_calc.h b/met/src/libcode/vx_bool_calc/bool_calc.h new file mode 100644 index 0000000000..e55b746208 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/bool_calc.h @@ -0,0 +1,68 @@ + + +//////////////////////////////////////////////////////////////////////// + + +#ifndef __BOOL_CALC_H__ +#define __BOOL_CALC_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include +#include + +#include "token.h" + + +//////////////////////////////////////////////////////////////////////// + + +class BoolCalc { + + private: + + void init_from_scratch(); + + + stack * s; // allocated + + Program * program; // allocated + + + + public: + + BoolCalc(); + ~BoolCalc(); + + void clear(); + + void dump_program(ostream &) const; + + + + int Max_depth; // maximum stack depth needed to run the program + + int Max_local; // largest local variable number in program + + + + void set(const char *); // algebraic boolean expression + + bool run(const vector); + + +}; + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __BOOL_CALC_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/libcode/vx_bool_calc/make_program.cc b/met/src/libcode/vx_bool_calc/make_program.cc new file mode 100644 index 0000000000..0072a3f658 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/make_program.cc @@ -0,0 +1,307 @@ + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include + +#include "vx_util.h" + +#include "tokenizer.h" +#include "token_stack.h" +#include "make_program.h" + +#include "vx_log.h" + + +//////////////////////////////////////////////////////////////////////// + + +static bool balanced(const char *); // check balanced parentheses + +static void process(const Token &, TokenStack &, Program &); + + +//////////////////////////////////////////////////////////////////////// + + +void make_program(const char * input, Program & program) + +{ + +Tokenizer tiz; +Token tok; +TokenStack op; // operator + + +if ( ! balanced(input) ) { + + mlog << Error << "\nmake_program() -> " + << "unbalanced parentheses!\n\n"; + + exit ( 1 ); + +} + +program.clear(); + + +tiz.set(input); + + + //////////////// + +while ( 1 ) { + + tok = tiz.next_token(); + + if ( tok.is_eof() ) break; + + process(tok, op, program); + + // op.dump(cout); + +} // while + + + // + // there should be no marks left on the stack + // + +while ( op.nonempty() ) { + + tok = op.pop(); + + if ( tok.is_mark() ) { + + mlog << Error << "\nmake_program() -> " + << "extra paranthesis?\n\n"; + + exit ( 1 ); + + } + + program.push_back(tok); + +} + + +// cout << "\n\n"; +// +// cout << "Input \"" << input.text() << "\"\n\n"; +// +// cout << "Result \"" << result.text() << "\"\n\n"; + + // + // done + // + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool balanced(const char * text) + +{ + +int j = 0; +char c; +int count = 0; + +while ( (c = text[j++]) != 0 ) { + + if ( c == '(' ) ++count; + if ( c == ')' ) --count; + +} + + +return ( count == 0 ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void process(const Token & t, TokenStack & op, Program & program) + +{ + +Token tt; + + ////////////////////////////////////// + + +if ( t.is_mark() ) { op.push(t); return; } + + + ////////////////////////////////////// + + +if ( t.is_operand() ) { program.push_back(t); return; } + + + ////////////////////////////////////// + + +if ( t.is_operator() ) { + + + if ( op.empty() ) { op.push(t); } + else if ( t.prec() >= op.top_prec() ) { op.push(t); } + else if ( t.prec() < op.top_prec() ) { + + while ( op.nonempty() && (t.prec() <= op.top_prec()) ) { + // while ( op.nonempty() && (t.prec() < op.top_prec()) ) { + + if ( op.top_is_mark() ) break; + + tt = op.pop(); + + program.push_back(tt); + + } // while + + op.push(t); + + } else { + + cout << "\n\n this shouldn't happen!\n\n" << flush; + + exit ( 1 ); + + } + + // last_was_operator = true; + + return; + +} // if t.is_operator + + + ////////////////////////////////////// + + +bool mark_found = false; + + +if ( t.is_unmark() ) { + + while ( op.nonempty() ) { + + tt = op.pop(); + + if ( tt.is_mark() ) { mark_found = true; break; } + else program.push_back(tt); + + } + +} + +if ( ! mark_found ) { + + cout << "\n\n process() -> mark not found! ... unbalanced parentheses?\n\n"; + + exit ( 1 ); + +} + + + // + // done + // + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +int max_local(const Program & program) // largest local variable number in program + +{ + +int j, k, n; + +n = 0; + +for (j=0; j<(int) program.size(); ++j) { + + if ( program[j].type != tok_local_var ) continue; + + k = program[j].number_1b; + + if ( k > n ) n = k; + +} // for j + + +return ( n ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +int max_depth(const Program & program) // maximum stack depth needed to run the program + +{ + +int j, n, d; +Token tok; + + +n = d = 0; + + +for (j=0; j<(int) program.size(); ++j) { + + tok = program[j]; + + switch ( tok.type ) { + + case tok_local_var: d += 1; break; + + case tok_union: d -= 1; break; + case tok_intersection: d -= 1; break; + + + default: + d = 0; + break; + + } // switch + + if ( d > n ) n = d; + +} // for j + + + + + +return ( n ); + +} + + +//////////////////////////////////////////////////////////////////////// + + + + diff --git a/met/src/libcode/vx_bool_calc/make_program.h b/met/src/libcode/vx_bool_calc/make_program.h new file mode 100644 index 0000000000..de2e039d94 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/make_program.h @@ -0,0 +1,45 @@ + + +//////////////////////////////////////////////////////////////////////// + + +#ifndef __MAKE_BOOL_PROGRAM_H__ +#define __MAKE_BOOL_PROGRAM_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include + +#include "token.h" + + +//////////////////////////////////////////////////////////////////////// + + +extern void make_program(const char * input, Program &); + + +//////////////////////////////////////////////////////////////////////// + + + // maximum stack depth needed to run the program + +extern int max_depth(const Program &); + + + // largest local variable number in program + +extern int max_local(const Program &); + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MAKE_BOOL_PROGRAM_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/libcode/vx_bool_calc/token.cc b/met/src/libcode/vx_bool_calc/token.cc new file mode 100644 index 0000000000..d2bff4c067 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/token.cc @@ -0,0 +1,390 @@ + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + + +//////////////////////////////////////////////////////////////////////// + + +#include "indent.h" + +#include "token.h" +#include "tokentype_to_string.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class Token + // + + +//////////////////////////////////////////////////////////////////////// + + +Token::Token() + +{ + +init_from_scratch(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Token::~Token() + +{ + +// set_eof(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Token::Token(const Token & t) + +{ + +init_from_scratch(); + +assign(t); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Token & Token::operator=(const Token & t) + +{ + +if ( this == &t ) return ( * this ); + +assign(t); + +return ( * this ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::assign(const Token & t) + +{ + +clear(); + +type = t.type; + +text = t.text; + + in_prec = t.in_prec; +out_prec = t.out_prec; + +pos = t.pos; + +number_1b = t.number_1b; + +delta = t.delta; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::init_from_scratch() + +{ + +clear(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::clear() + +{ + +set_eof(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::dump(ostream & out, int depth) const + +{ + +Indent prefix(depth); + + +out << '\n'; + +out << prefix << "type = " << tokentype_to_string(type) << '\n'; + + +out << prefix << "text = "; + +if ( text.nonempty() ) out << '\"' << text << '\"'; + +out << '\n'; + +// out << prefix << "prec = (" << in_prec << ' ' << out_prec << ")\n"; + +// out << prefix << "pos = " << pos << '\n'; + +out << prefix << "number_1b = " << number_1b << '\n'; + +// out << prefix << "delta = " << delta << '\n'; + + + // + // done + // + +out.flush(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_eof() + +{ + +text.clear(); + +delta = 0; + +in_prec = out_prec = 0; + +pos = -1; + +number_1b = 0; + +type = tok_eof; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_union(int _pos) + +{ + +pos = _pos; + +type = tok_union; + +text = union_char; + + in_prec = union_in_prec; +out_prec = union_out_prec; + +number_1b = 0; + +delta = union_delta; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_intersection(int _pos) + +{ + +pos = _pos; + +type = tok_intersection; + +text = intersection_char; + + in_prec = intersection_in_prec; +out_prec = intersection_out_prec; + +number_1b = 0; + +delta = intersection_delta; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_mark(int _pos) + +{ + +type = tok_mark; + +text = mark_char; + +in_prec = out_prec = 100; + +pos = _pos; + +delta = 0; + +number_1b = 0; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_unmark(int _pos) + +{ + +type = tok_unmark; + +text = unmark_char; + +in_prec = out_prec = 100; + +pos = _pos; + +delta = 0; + +number_1b = 0; + +return; + +} + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_local_var(int _number_1b, int _pos) + +{ + +type = tok_local_var; + +number_1b = _number_1b; + +text.erase(); + +in_prec = out_prec = 0; + +pos = _pos; + +delta = 1; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Token::set_negation(int _pos) + +{ + +text = negation_char; + +type = tok_negation; + + in_prec = negation_in_prec; +out_prec = negation_out_prec; + +pos = _pos; + +delta = negation_delta; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool Token::is_operator() const + +{ + +const bool tf = (type == tok_union) + || (type == tok_intersection) + || (type == tok_negation); + + +return ( tf ); + +} + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for misc functions + // + + +//////////////////////////////////////////////////////////////////////// + + +ostream & operator<<(ostream & out, const Token & t) + +{ + +t.dump(out); + +return ( out ); + +} + +//////////////////////////////////////////////////////////////////////// + + + + diff --git a/met/src/libcode/vx_bool_calc/token.h b/met/src/libcode/vx_bool_calc/token.h new file mode 100644 index 0000000000..1ef22450b9 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/token.h @@ -0,0 +1,192 @@ + + +//////////////////////////////////////////////////////////////////////// + + +#ifndef __MY_BOOL_TOKEN_H__ +#define __MY_BOOL_TOKEN_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include +#include + +#include "concat_string.h" + + +//////////////////////////////////////////////////////////////////////// + + +static const char union_char[] = "||"; +static const char intersection_char[] = "&&"; +static const char negation_char = '!'; + +static const char mark_char = '('; +static const char unmark_char = ')'; + +static const char local_var_char = '#'; + + +//////////////////////////////////////////////////////////////////////// + + + // delta = net pushes minus pops + +static const int union_delta = -1; +static const int intersection_delta = -1; +static const int negation_delta = 0; +static const int local_var_delta = 1; + + // + +static const int union_in_prec = 2; +static const int union_out_prec = 1; + +static const int intersection_in_prec = 4; +static const int intersection_out_prec = 3; + +static const int negation_in_prec = 10; +static const int negation_out_prec = 10; + + +//////////////////////////////////////////////////////////////////////// + + +enum TokenType { + + tok_union, + tok_intersection, + tok_negation, + + tok_local_var, + + tok_mark, + tok_unmark, + + tok_eof, + + no_token_type, + +}; + + +//////////////////////////////////////////////////////////////////////// + + +class Token { + + void init_from_scratch(); + + void assign(const Token &); + + public: + + Token(); // defaults to eof + ~Token(); + Token(const Token &); + Token & operator=(const Token &); + + void clear(); + + void dump(ostream &, int = 0) const; + + + TokenType type; + + ConcatString text; + + int in_prec; + int out_prec; + + int pos; // 0-based + + int number_1b; // for local variables, 1-based + + int delta; // net pushes minus pops + + + + bool is_operand () const; // ie, a local variable + bool is_operator () const; + + bool is_mark () const; + bool is_unmark () const; + + bool is_eof () const; + + // + + void set_eof(); + + void set_mark (int = -1); + void set_unmark (int = -1); + + void set_local_var(int _number_1b, int _pos = -1); // local variable + + void set_negation(int _pos = -1); // negation (ie, logical not) + + void set_union(int _pos = -1); + void set_intersection(int _pos = -1); + + + + // void print() const; + + int prec() const; // the "out" prec + +}; + + +//////////////////////////////////////////////////////////////////////// + + +extern ostream & operator<<(ostream &, const Token &); + + +//////////////////////////////////////////////////////////////////////// + + +// inline void Token::print() const { +// +// if ( result.nonempty() ) result << ','; +// +// if ( type == tok_local_var ) result << local_var_char << number; +// else result << value; +// +// cout << value << '\n' << flush; +// +// return; +// +// } + + +//////////////////////////////////////////////////////////////////////// + + +inline int Token::prec () const { return ( out_prec ); } + +inline bool Token::is_mark () const { return ( type == tok_mark ); } +inline bool Token::is_unmark () const { return ( type == tok_unmark ); } + +inline bool Token::is_eof () const { return ( type == tok_eof ); } + +inline bool Token::is_operand () const { return ( type == tok_local_var ); } + + +//////////////////////////////////////////////////////////////////////// + + +typedef vector Program; + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MY_BOOL_TOKEN_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/libcode/vx_bool_calc/token_stack.cc b/met/src/libcode/vx_bool_calc/token_stack.cc new file mode 100644 index 0000000000..cdcdb2f039 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/token_stack.cc @@ -0,0 +1,415 @@ + + +//////////////////////////////////////////////////////////////////////// + + + // + // Warning: This file is machine generated + // + // Do not edit by hand + // + // + // Created by stackgen on August 20, 2019 3:12 pm MDT + // + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + + +#include +#include +#include +#include +#include + +#include "vx_util.h" + +#include "token_stack.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class TokenStack + // + + +//////////////////////////////////////////////////////////////////////// + + +TokenStack::TokenStack() + +{ + +init_from_scratch(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +TokenStack::~TokenStack() + +{ + +clear(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +TokenStack::TokenStack(const TokenStack & a) + +{ + +init_from_scratch(); + +assign(a); + +} + + +//////////////////////////////////////////////////////////////////////// + + +TokenStack & TokenStack::operator=(const TokenStack & a) + +{ + +if ( this == &a ) return ( * this ); + +assign(a); + +return ( * this ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void TokenStack::init_from_scratch() + +{ + +e = (Token *) 0; + +AllocInc = 50; // default value + +clear(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void TokenStack::clear() + +{ + +if ( e ) { delete [] e; e = (Token *) 0; } + + + +Nelements = 0; + +Nalloc = 0; + +// AllocInc = 50; // don't reset AllocInc + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void TokenStack::assign(const TokenStack & _a) + +{ + +clear(); + +if ( _a.depth() == 0 ) return; + +extend(_a.depth()); + +int j; + +for (j=0; j<(_a.depth()); ++j) { + + e[j] = _a.e[j]; + +} + +Nelements = _a.Nelements; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void TokenStack::extend(int n) + +{ + +if ( n <= Nalloc ) return; + +n = AllocInc*( (n + AllocInc - 1)/AllocInc ); + +int j; +Token * u = new Token [n]; + +if ( !u ) { + + cout << "TokenStack::extend(int) -> memory allocation error\n\n"; + + exit ( 1 ); + +} + +for(j=0; j bad value ... " << n << "\n\n"; + + exit ( 1 ); + +} + +if ( n == 0 ) AllocInc = 50; // default value +else AllocInc = n; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void TokenStack::push(const Token & a) + +{ + +extend(Nelements + 1); + +e[Nelements++] = a; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +Token TokenStack::pop() + +{ + +if ( Nelements <= 0 ) { + + cout << "TokenStack::pop() -> stack empty!\n\n"; + + exit ( 1 ); + +} + +Token _t = e[Nelements - 1]; + +--Nelements; + +return ( _t ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Token TokenStack::peek() const + +{ + +if ( Nelements <= 0 ) { + + cout << "TokenStack::pop() -> stack empty!\n\n"; + + exit ( 1 ); + +} + +Token _t = e[Nelements - 1]; + +return ( _t ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +int TokenStack::top_prec() const // the "in" prec + +{ + +if ( Nelements <= 0 ) { + + cout << "TokenStack::top_prec() -> stack empty!\n\n"; + + exit ( 1 ); + +} + +int k = e[Nelements - 1].in_prec; + +return ( k ); + +} + + +//////////////////////////////////////////////////////////////////////// + +/* +char TokenStack::top_value() const + +{ + +if ( Nelements <= 0 ) { + + cout << "TokenStack::top_value() -> stack empty!\n\n"; + + exit ( 1 ); + +} + +char c = e[Nelements - 1].value; + +return ( c ); + +} +*/ + + +//////////////////////////////////////////////////////////////////////// + + +bool TokenStack::top_is_mark() const + +{ + +if ( Nelements <= 0 ) { + + cout << "TokenStack::top_is_mark() -> stack empty!\n\n"; + + exit ( 1 ); + +} + +bool tf = e[Nelements - 1].is_mark(); + +return ( tf ); + +} + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for misc functions + // + + +//////////////////////////////////////////////////////////////////////// + + +ostream & operator<<(ostream & out, const TokenStack & ts) + +{ + +ts.dump(out); + +return ( out ); + +} + + +//////////////////////////////////////////////////////////////////////// + + + + diff --git a/met/src/libcode/vx_bool_calc/token_stack.h b/met/src/libcode/vx_bool_calc/token_stack.h new file mode 100644 index 0000000000..d1afbe1d18 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/token_stack.h @@ -0,0 +1,98 @@ + + +//////////////////////////////////////////////////////////////////////// + + +#ifndef __OPERAND_STACK_H__ +#define __OPERAND_STACK_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include + +#include "token.h" + + +//////////////////////////////////////////////////////////////////////// + + +class TokenStack { + + private: + + void init_from_scratch(); + + void assign(const TokenStack &); + + void extend(int); + + + int Nelements; + + int Nalloc; + + int AllocInc; + + Token * e; + + + public: + + TokenStack(); + ~TokenStack(); + TokenStack(const TokenStack &); + TokenStack & operator=(const TokenStack &); + + void clear(); + + void dump(ostream &, int = 0) const; + + void set_alloc_inc(int = 0); // 0 means default value (50) + + int depth() const; + + bool empty() const; + bool nonempty() const; + + void push(const Token &); + + Token pop(); + + Token peek() const; + + int top_prec() const; // the "in" prec + + // char top_value() const; + + bool top_is_mark() const; + +}; + + +//////////////////////////////////////////////////////////////////////// + + +inline int TokenStack::depth() const { return ( Nelements ); } + +inline bool TokenStack::empty() const { return ( Nelements == 0 ); } + +inline bool TokenStack::nonempty() const { return ( Nelements > 0 ); } + + +//////////////////////////////////////////////////////////////////////// + + +extern ostream & operator<<(ostream &, const TokenStack &); + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __OPERAND_STACK_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/libcode/vx_bool_calc/tokenizer.cc b/met/src/libcode/vx_bool_calc/tokenizer.cc new file mode 100644 index 0000000000..7b676f452e --- /dev/null +++ b/met/src/libcode/vx_bool_calc/tokenizer.cc @@ -0,0 +1,244 @@ + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include + +#include "empty_string.h" +#include "tokenizer.h" + +#include "vx_log.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class Tokenizer + // + + +//////////////////////////////////////////////////////////////////////// + + +Tokenizer::Tokenizer() + +{ + +init_from_scratch(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Tokenizer::~Tokenizer() + +{ + +clear(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Tokenizer::init_from_scratch() + +{ + +source = 0; + +clear(); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Tokenizer::clear() + +{ + +if ( source ) { delete [] source; source = 0; } + +pos = -1; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Tokenizer::set(const char * input) + +{ + +if ( empty(input) ) { + + mlog << Error << "\nTokenizer::set() -> " + << "empty input string!\n\n"; + + exit ( 1 ); + +} + +const int N = strlen(input); + +char * c = new char [N + 1]; + +memcpy(c, input, N); + +c[N] = (char) 0; + +source = c; + +pos = 0; + + + // + // done + // + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +int Tokenizer::get_number() + +{ + +int value = 0; +char c; + +// ++pos; + +while ( (c = source[pos]) != 0 ) { + + if ( isdigit(c) ) { value = 10*value + (c - '0'); ++pos; } + else break; + +} + +return ( value ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Token Tokenizer::next_token() + +{ + +int k, old_pos; +Token tok; +char c, c2; + + + // + // skip whitespace + // + +while ( 1 ) { + + c = source[pos]; + + if ( c == 0 ) { + + tok.set_eof(); + + return ( tok ); + + } + + if ( !isspace(c) ) break; + + ++pos; + +} // while + + +old_pos = pos; + +c = source[pos++]; + +if ( c == mark_char ) { + + tok.set_mark(old_pos); + +} +else if ( c == unmark_char ) { + + tok.set_unmark(old_pos); + +} +else if ( c == union_char[0] ) { + + c2 = source[pos++]; + if ( c2 == union_char[1]) tok.set_union(old_pos); + else { + mlog << Error << "\nTokenizer::next_token() -> " + << "unrecognized token: " << c << c2 << "\n\n"; + exit ( 1 ); + } + +} +else if ( c == intersection_char[0] ) { + + tok.set_intersection(old_pos); + c2 = source[pos++]; + if ( c2 == intersection_char[1]) tok.set_intersection(old_pos); + else { + mlog << Error << "\nTokenizer::next_token() -> " + << "unrecognized token: " << c << c2 << "\n\n"; + exit ( 1 ); + } + +} +else if ( c == negation_char ) { + + tok.set_negation(old_pos); + +} +else if ( c = local_var_char ) { + + k = get_number(); + tok.set_local_var(k, old_pos); + +} +else { + + mlog << Error << "\nTokenizer::next_token() -> " + << "unrecognized character: " << c << "\n\n"; + exit ( 1 ); + +} + + +return ( tok ); + +} + + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_bool_calc/tokenizer.h b/met/src/libcode/vx_bool_calc/tokenizer.h new file mode 100644 index 0000000000..dd3189b518 --- /dev/null +++ b/met/src/libcode/vx_bool_calc/tokenizer.h @@ -0,0 +1,53 @@ + + +//////////////////////////////////////////////////////////////////////// + + +#ifndef __TOKENIZER_H__ +#define __TOKENIZER_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include "token.h" + + +//////////////////////////////////////////////////////////////////////// + + +class Tokenizer { + + private: + + void init_from_scratch(); + + int get_number(); + + const char * source; // allocated, nul-terminated + + int pos; // next unread character + + public: + + Tokenizer(); + ~Tokenizer(); + + void clear(); + + void set(const char * input); + + Token next_token(); + +}; + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __TOKENIZER_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/libcode/vx_shapedata/Makefile.am b/met/src/libcode/vx_shapedata/Makefile.am index 234cba342a..f54e937535 100644 --- a/met/src/libcode/vx_shapedata/Makefile.am +++ b/met/src/libcode/vx_shapedata/Makefile.am @@ -19,6 +19,7 @@ libvx_shapedata_a_SOURCES = \ set.cc set.h \ interest.cc interest.h \ mode_columns.h \ + mode_field_info.cc mode_field_info.h \ mode_conf_info.cc mode_conf_info.h \ engine.cc engine.h \ ihull.cc ihull.h \ diff --git a/met/src/libcode/vx_shapedata/engine.cc b/met/src/libcode/vx_shapedata/engine.cc index a1ca40798e..e01de1d981 100644 --- a/met/src/libcode/vx_shapedata/engine.cc +++ b/met/src/libcode/vx_shapedata/engine.cc @@ -403,7 +403,7 @@ void ModeFuzzyEngine::do_fcst_convolution() { if(!need_fcst_conv) return; - r = conf_info.fcst_conv_radius; + r = conf_info.Fcst->conv_radius; *fcst_conv = *fcst_raw; @@ -413,7 +413,7 @@ void ModeFuzzyEngine::do_fcst_convolution() { // // Apply a circular convolution to the raw field // - if(r > 0) fcst_conv->conv_filter_circ(2*r + 1, conf_info.fcst_vld_thresh); + if(r > 0) fcst_conv->conv_filter_circ(2*r + 1, conf_info.Fcst->vld_thresh); need_fcst_conv = false; need_fcst_thresh = true; @@ -435,7 +435,7 @@ void ModeFuzzyEngine::do_obs_convolution() { if(!need_obs_conv) return; - r = conf_info.obs_conv_radius; + r = conf_info.Obs->conv_radius; *obs_conv = *obs_raw; @@ -445,7 +445,7 @@ void ModeFuzzyEngine::do_obs_convolution() { // // Apply a circular convolution to the raw field // - if(r > 0) obs_conv->conv_filter_circ(2*r + 1, conf_info.obs_vld_thresh); + if(r > 0) obs_conv->conv_filter_circ(2*r + 1, conf_info.Obs->vld_thresh); need_obs_conv = false; need_obs_thresh = true; @@ -469,15 +469,15 @@ void ModeFuzzyEngine::do_fcst_thresholding() { *fcst_mask = *fcst_conv; *fcst_thresh = *fcst_raw; - fcst_thresh->threshold(conf_info.fcst_conv_thresh); + fcst_thresh->threshold(conf_info.Fcst->conv_thresh); // // Threshold the convolved field // - fcst_mask->threshold(conf_info.fcst_conv_thresh); + fcst_mask->threshold(conf_info.Fcst->conv_thresh); mlog << Debug(3) << "Applying convolution threshold " - << conf_info.fcst_conv_thresh.get_str() + << conf_info.Fcst->conv_thresh.get_str() << " resulted in " << fcst_mask->n_objects() << " simple forecast objects.\n"; @@ -502,15 +502,15 @@ void ModeFuzzyEngine::do_obs_thresholding() { *obs_mask = *obs_conv; *obs_thresh = *obs_raw; - obs_thresh->threshold(conf_info.obs_conv_thresh); + obs_thresh->threshold(conf_info.Obs->conv_thresh); // // Threshold the convolved field // - obs_mask->threshold(conf_info.obs_conv_thresh); + obs_mask->threshold(conf_info.Obs->conv_thresh); mlog << Debug(3) << "Applying convolution threshold " - << conf_info.obs_conv_thresh.get_str() + << conf_info.Obs->conv_thresh.get_str() << " resulted in " << obs_mask->n_objects() << " simple observation objects.\n"; @@ -536,11 +536,11 @@ void ModeFuzzyEngine::do_fcst_filtering() { // // Apply object attribute filtering logic // - if(conf_info.fcst_filter_attr_map.size() > 0) { + if(conf_info.Fcst->filter_attr_map.size() > 0) { - fcst_mask->threshold_attr(conf_info.fcst_filter_attr_map, - fcst_raw, conf_info.fcst_conv_thresh, grid, - conf_info.fcst_info->is_precipitation()); + fcst_mask->threshold_attr(conf_info.Fcst->filter_attr_map, + fcst_raw, conf_info.Fcst->conv_thresh, grid, + conf_info.Fcst->var_info->is_precipitation()); mlog << Debug(3) << "Applying object attribute filtering" << " resulted in " << fcst_mask->n_objects() @@ -571,11 +571,11 @@ void ModeFuzzyEngine::do_obs_filtering() { // // Apply object attribute filtering logic // - if(conf_info.obs_filter_attr_map.size() > 0) { + if(conf_info.Obs->filter_attr_map.size() > 0) { - obs_mask->threshold_attr(conf_info.obs_filter_attr_map, - obs_raw, conf_info.obs_conv_thresh, grid, - conf_info.obs_info->is_precipitation()); + obs_mask->threshold_attr(conf_info.Obs->filter_attr_map, + obs_raw, conf_info.Obs->conv_thresh, grid, + conf_info.Obs->var_info->is_precipitation()); mlog << Debug(3) << "Applying object attribute filtering" << " resulted in " << obs_mask->n_objects() @@ -658,12 +658,12 @@ void ModeFuzzyEngine::do_fcst_merging(const char *default_config, if(!need_fcst_merge) return; - if(conf_info.fcst_merge_flag == MergeType_Both || - conf_info.fcst_merge_flag == MergeType_Thresh) + if(conf_info.Fcst->merge_flag == MergeType_Both || + conf_info.Fcst->merge_flag == MergeType_Thresh) do_fcst_merge_thresh(); - if(conf_info.fcst_merge_flag == MergeType_Both || - conf_info.fcst_merge_flag == MergeType_Engine) + if(conf_info.Fcst->merge_flag == MergeType_Both || + conf_info.Fcst->merge_flag == MergeType_Engine) do_fcst_merge_engine(default_config, merge_config); // @@ -686,12 +686,12 @@ void ModeFuzzyEngine::do_obs_merging(const char *default_config, if(!need_obs_merge) return; - if(conf_info.obs_merge_flag == MergeType_Both || - conf_info.obs_merge_flag == MergeType_Thresh) + if(conf_info.Obs->merge_flag == MergeType_Both || + conf_info.Obs->merge_flag == MergeType_Thresh) do_obs_merge_thresh(); - if(conf_info.obs_merge_flag == MergeType_Both || - conf_info.obs_merge_flag == MergeType_Engine) + if(conf_info.Obs->merge_flag == MergeType_Both || + conf_info.Obs->merge_flag == MergeType_Engine) do_obs_merge_engine(default_config, merge_config); // @@ -792,7 +792,7 @@ void ModeFuzzyEngine::do_no_match() { fcst_shape[j] = select(*fcst_split, j+1); fcst_single[j].set(*fcst_raw, *fcst_thresh, fcst_shape[j], conf_info.inten_perc_value, - conf_info.fcst_info->is_precipitation()); + conf_info.Fcst->var_info->is_precipitation()); fcst_single[j].object_number = j+1; } @@ -802,7 +802,7 @@ void ModeFuzzyEngine::do_no_match() { obs_shape[j] = select(*obs_split, j+1); obs_single[j].set(*obs_raw, *obs_thresh, obs_shape[j], conf_info.inten_perc_value, - conf_info.obs_info->is_precipitation()); + conf_info.Obs->var_info->is_precipitation()); obs_single[j].object_number = j+1; } @@ -882,7 +882,7 @@ void ModeFuzzyEngine::do_match_merge() { fcst_shape[j] = select(*fcst_split, j+1); fcst_single[j].set(*fcst_raw, *fcst_thresh, fcst_shape[j], conf_info.inten_perc_value, - conf_info.fcst_info->is_precipitation()); + conf_info.Fcst->var_info->is_precipitation()); fcst_single[j].object_number = j+1; } @@ -892,7 +892,7 @@ void ModeFuzzyEngine::do_match_merge() { obs_shape[j] = select(*obs_split, j+1); obs_single[j].set(*obs_raw, *obs_thresh, obs_shape[j], conf_info.inten_perc_value, - conf_info.obs_info->is_precipitation()); + conf_info.Obs->var_info->is_precipitation()); obs_single[j].object_number = j+1; } @@ -1042,7 +1042,7 @@ void ModeFuzzyEngine::do_fcst_merge_thresh() { // // Threshold the forecast merge field // - fcst_merge_mask.threshold(conf_info.fcst_merge_thresh); + fcst_merge_mask.threshold(conf_info.Fcst->merge_thresh); // // Split up the forecast merge field @@ -1165,7 +1165,7 @@ void ModeFuzzyEngine::do_obs_merge_thresh() { // // Threshold the forecast merge field // - obs_merge_mask.threshold(conf_info.obs_merge_thresh); + obs_merge_mask.threshold(conf_info.Obs->merge_thresh); // // Split up the forecast merge field @@ -1300,8 +1300,8 @@ void ModeFuzzyEngine::do_fcst_merge_engine(const char *default_config, fcst_engine->ctable = ctable; if(default_config && merge_config) { fcst_engine->conf_info.read_config(default_config, merge_config); - fcst_engine->conf_info.process_config(conf_info.fcst_info->file_type(), - conf_info.obs_info->file_type()); + fcst_engine->conf_info.process_config(conf_info.Fcst->var_info->file_type(), + conf_info.Obs->var_info->file_type()); path = replace_path(fcst_engine->conf_info.object_pi.color_table.c_str()); fcst_engine->ctable.read(path.c_str()); } @@ -1309,20 +1309,20 @@ void ModeFuzzyEngine::do_fcst_merge_engine(const char *default_config, // // Copy over fcst_info and obs_info // - *(fcst_engine->conf_info.fcst_info) = *(conf_info.fcst_info); - *(fcst_engine->conf_info.obs_info) = *(conf_info.fcst_info); + *(fcst_engine->conf_info.Fcst->var_info) = *(conf_info.Fcst->var_info); + *(fcst_engine->conf_info.Obs->var_info) = *(conf_info.Fcst->var_info); // // Copy over the forecast threshold values // - fcst_engine->conf_info.fcst_conv_thresh = conf_info.fcst_conv_thresh; - fcst_engine->conf_info.obs_conv_thresh = conf_info.fcst_conv_thresh; + fcst_engine->conf_info.Fcst->conv_thresh = conf_info.Fcst->conv_thresh; + fcst_engine->conf_info.Obs->conv_thresh = conf_info.Fcst->conv_thresh; - fcst_engine->conf_info.fcst_filter_attr_map = conf_info.fcst_filter_attr_map; - fcst_engine->conf_info.obs_filter_attr_map = conf_info.fcst_filter_attr_map; + fcst_engine->conf_info.Fcst->filter_attr_map = conf_info.Fcst->filter_attr_map; + fcst_engine->conf_info.Obs->filter_attr_map = conf_info.Fcst->filter_attr_map; - fcst_engine->conf_info.fcst_merge_thresh = conf_info.fcst_merge_thresh; - fcst_engine->conf_info.obs_merge_thresh = conf_info.fcst_merge_thresh; + fcst_engine->conf_info.Fcst->merge_thresh = conf_info.Fcst->merge_thresh; + fcst_engine->conf_info.Obs->merge_thresh = conf_info.Fcst->merge_thresh; // // Copy the previously defined fuzzy engine fields @@ -1467,8 +1467,8 @@ void ModeFuzzyEngine::do_obs_merge_engine(const char *default_config, obs_engine->ctable = ctable; if(default_config && merge_config) { obs_engine->conf_info.read_config(default_config, merge_config); - obs_engine->conf_info.process_config(conf_info.fcst_info->file_type(), - conf_info.obs_info->file_type()); + obs_engine->conf_info.process_config(conf_info.Fcst->var_info->file_type(), + conf_info.Obs->var_info->file_type()); path = replace_path(obs_engine->conf_info.object_pi.color_table.c_str()); obs_engine->ctable.read(path.c_str()); } @@ -1476,20 +1476,20 @@ void ModeFuzzyEngine::do_obs_merge_engine(const char *default_config, // // Copy over fcst_info and obs_info // - *(obs_engine->conf_info.fcst_info) = *(conf_info.obs_info); - *(obs_engine->conf_info.obs_info) = *(conf_info.obs_info); + *(obs_engine->conf_info.Fcst->var_info) = *(conf_info.Obs->var_info); + *(obs_engine->conf_info.Obs->var_info) = *(conf_info.Obs->var_info); // // Copy over the observation threshold values // - obs_engine->conf_info.fcst_conv_thresh = conf_info.obs_conv_thresh; - obs_engine->conf_info.obs_conv_thresh = conf_info.obs_conv_thresh; + obs_engine->conf_info.Fcst->conv_thresh = conf_info.Obs->conv_thresh; + obs_engine->conf_info.Obs->conv_thresh = conf_info.Obs->conv_thresh; - obs_engine->conf_info.fcst_filter_attr_map = conf_info.obs_filter_attr_map; - obs_engine->conf_info.obs_filter_attr_map = conf_info.obs_filter_attr_map; + obs_engine->conf_info.Fcst->filter_attr_map = conf_info.Obs->filter_attr_map; + obs_engine->conf_info.Obs->filter_attr_map = conf_info.Obs->filter_attr_map; - obs_engine->conf_info.fcst_merge_thresh = conf_info.obs_merge_thresh; - obs_engine->conf_info.obs_merge_thresh = conf_info.obs_merge_thresh; + obs_engine->conf_info.Fcst->merge_thresh = conf_info.Obs->merge_thresh; + obs_engine->conf_info.Obs->merge_thresh = conf_info.Obs->merge_thresh; // // Copy the previously defined fuzzy engine fields @@ -1634,7 +1634,7 @@ void ModeFuzzyEngine::do_match_fcst_merge() { fcst_shape[j] = select(*fcst_split, j+1); fcst_single[j].set(*fcst_raw, *fcst_thresh, fcst_shape[j], conf_info.inten_perc_value, - conf_info.fcst_info->is_precipitation()); + conf_info.Fcst->var_info->is_precipitation()); fcst_single[j].object_number = j+1; } @@ -1644,7 +1644,7 @@ void ModeFuzzyEngine::do_match_fcst_merge() { obs_shape[j] = select(*obs_split, j+1); obs_single[j].set(*obs_raw, *obs_thresh, obs_shape[j], conf_info.inten_perc_value, - conf_info.obs_info->is_precipitation()); + conf_info.Obs->var_info->is_precipitation()); obs_single[j].object_number = j+1; } @@ -1811,7 +1811,7 @@ void ModeFuzzyEngine::do_match_only() { fcst_shape[j] = select(*fcst_split, j+1); fcst_single[j].set(*fcst_raw, *fcst_thresh, fcst_shape[j], conf_info.inten_perc_value, - conf_info.fcst_info->is_precipitation()); + conf_info.Fcst->var_info->is_precipitation()); fcst_single[j].object_number = j+1; } @@ -1821,7 +1821,7 @@ void ModeFuzzyEngine::do_match_only() { obs_shape[j] = select(*obs_split, j+1); obs_single[j].set(*obs_raw, *obs_thresh, obs_shape[j], conf_info.inten_perc_value, - conf_info.obs_info->is_precipitation()); + conf_info.Obs->var_info->is_precipitation()); obs_single[j].object_number = j+1; } @@ -2062,13 +2062,13 @@ void ModeFuzzyEngine::do_cluster_features() { fcst_clus_shape[j] = select(*fcst_clus_split, j+1); fcst_cluster[j].set(*fcst_raw, *fcst_thresh, fcst_clus_shape[j], conf_info.inten_perc_value, - conf_info.fcst_info->is_precipitation()); + conf_info.Fcst->var_info->is_precipitation()); fcst_cluster[j].object_number = j+1; obs_clus_shape[j] = select(*obs_clus_split, j+1); obs_cluster[j].set(*obs_raw, *obs_thresh, obs_clus_shape[j], conf_info.inten_perc_value, - conf_info.obs_info->is_precipitation()); + conf_info.Obs->var_info->is_precipitation()); obs_cluster[j].object_number = j+1; } @@ -2817,48 +2817,48 @@ void write_header_columns(ModeFuzzyEngine & eng, const Grid & grid, AsciiTable & // Forecast convolution radius at.set_entry(row, c++, - eng.conf_info.fcst_conv_radius); + eng.conf_info.Fcst->conv_radius); // Forecast convolution threshold at.set_entry(row, c++, - eng.conf_info.fcst_conv_thresh.get_str()); + eng.conf_info.Fcst->conv_thresh.get_str()); // Observation convolution radius at.set_entry(row, c++, - eng.conf_info.obs_conv_radius); + eng.conf_info.Obs->conv_radius); // Observation convolution threshold at.set_entry(row, c++, - eng.conf_info.obs_conv_thresh.get_str()); + eng.conf_info.Obs->conv_thresh.get_str()); // Forecast Variable Name s = check_hdr_str(conf_key_fcst_var, - eng.conf_info.fcst_info->name_attr()); + eng.conf_info.Fcst->var_info->name_attr()); at.set_entry(row, c++, s.text()); // Forecast Variable Units s = check_hdr_str(conf_key_fcst_units, - eng.conf_info.fcst_info->units_attr(), true); + eng.conf_info.Fcst->var_info->units_attr(), true); at.set_entry(row, c++, s.text()); // Forecast Variable Level s = check_hdr_str(conf_key_fcst_lev, - eng.conf_info.fcst_info->level_attr(), true); + eng.conf_info.Fcst->var_info->level_attr(), true); at.set_entry(row, c++, s.text()); // Observation Variable Name s = check_hdr_str(conf_key_obs_var, - eng.conf_info.obs_info->name_attr()); + eng.conf_info.Obs->var_info->name_attr()); at.set_entry(row, c++, s.text()); // Observation Variable Units s = check_hdr_str(conf_key_obs_units, - eng.conf_info.obs_info->units_attr(), true); + eng.conf_info.Obs->var_info->units_attr(), true); at.set_entry(row, c++, s.text()); // Observation Variable Level s = check_hdr_str(conf_key_obs_lev, - eng.conf_info.obs_info->level_attr(), true); + eng.conf_info.Obs->var_info->level_attr(), true); at.set_entry(row, c++, s.text()); // Observation type diff --git a/met/src/libcode/vx_shapedata/mode_conf_info.cc b/met/src/libcode/vx_shapedata/mode_conf_info.cc index a145f9f6c4..9bae581a01 100644 --- a/met/src/libcode/vx_shapedata/mode_conf_info.cc +++ b/met/src/libcode/vx_shapedata/mode_conf_info.cc @@ -54,8 +54,18 @@ void ModeConfInfo::init_from_scratch() { // Initialize pointers - fcst_info = (VarInfo *) 0; - obs_info = (VarInfo *) 0; + // fcst_info = (VarInfo *) 0; + // obs_info = (VarInfo *) 0; + + N_fields = 0; + + Field_Index = 0; + + fcst_array = 0; + obs_array = 0; + + fcst_array = 0; + obs_array = 0; clear(); @@ -80,29 +90,34 @@ void ModeConfInfo::clear() grid_res = bad_data_double; - fcst_conv_radius_array.clear(); - obs_conv_radius_array.clear(); + Field_Index = 0; - fcst_conv_radius = bad_data_int; - obs_conv_radius = bad_data_int; + fcst_multivar_logic.clear(); + obs_multivar_logic.clear(); - fcst_conv_thresh_array.clear(); - obs_conv_thresh_array.clear(); + // fcst_conv_radius_array.clear(); + // obs_conv_radius_array.clear(); - fcst_merge_thresh_array.clear(); - obs_merge_thresh_array.clear(); + // fcst_conv_radius = bad_data_int; + // obs_conv_radius = bad_data_int; - fcst_conv_thresh.clear(); - obs_conv_thresh.clear(); + // fcst_conv_thresh_array.clear(); + // obs_conv_thresh_array.clear(); - fcst_vld_thresh = bad_data_double; - obs_vld_thresh = bad_data_double; + // fcst_merge_thresh_array.clear(); + // obs_merge_thresh_array.clear(); - fcst_filter_attr_map.clear(); - obs_filter_attr_map.clear(); + // fcst_conv_thresh.clear(); + // obs_conv_thresh.clear(); - fcst_merge_flag = MergeType_None; - obs_merge_flag = MergeType_None; + // fcst_vld_thresh = bad_data_double; + // obs_vld_thresh = bad_data_double; + + // fcst_filter_attr_map.clear(); + // obs_filter_attr_map.clear(); + + // fcst_merge_flag = MergeType_None; + // obs_merge_flag = MergeType_None; match_flag = MatchType_None; @@ -161,9 +176,18 @@ void ModeConfInfo::clear() quilt = false; + // Deallocate memory - if(fcst_info) { delete fcst_info; fcst_info = (VarInfo *) 0; } - if(obs_info) { delete obs_info; obs_info = (VarInfo *) 0; } + // if(fcst_info) { delete fcst_info; fcst_info = (VarInfo *) 0; } + // if(obs_info) { delete obs_info; obs_info = (VarInfo *) 0; } + + if ( fcst_array ) { delete [] fcst_array; fcst_array = 0; } + if ( obs_array ) { delete [] obs_array; obs_array = 0; } + + Fcst = 0; + Obs = 0; + + N_fields = 0; return; @@ -171,7 +195,7 @@ void ModeConfInfo::clear() //////////////////////////////////////////////////////////////////////// -void ModeConfInfo::read_config(const char *default_file_name, const char *user_file_name) +void ModeConfInfo::read_config(const char * default_file_name, const char * user_file_name) { @@ -185,6 +209,8 @@ void ModeConfInfo::read_config(const char *default_file_name, const char *user_f // Read the user-specified config file conf.read(user_file_name); + get_multivar_programs(); + nc_info.set_compress_level(conf.nc_compression()); return; @@ -198,11 +224,11 @@ void ModeConfInfo::process_config(GrdFileType ftype, GrdFileType otype) { -int j, n; -VarInfoFactory info_factory; -Dictionary *fcst_dict = (Dictionary *) 0; -Dictionary *obs_dict = (Dictionary *) 0; -Dictionary *dict = (Dictionary *) 0; +int j, k, n; +// VarInfoFactory info_factory; +Dictionary * fcst_dict = (Dictionary *) 0; +Dictionary * obs_dict = (Dictionary *) 0; +Dictionary * dict = (Dictionary *) 0; PlotInfo plot_info; // Dump the contents of the config file @@ -242,142 +268,184 @@ PlotInfo plot_info; fcst_dict = conf.lookup_dictionary(conf_key_fcst); obs_dict = conf.lookup_dictionary(conf_key_obs); + +// X + read_fields (fcst_array, fcst_dict, ftype, 'F'); // the order is important here + read_fields ( obs_array, obs_dict, otype, 'O'); // the order is important here + + Fcst = fcst_array; // + 0 + Obs = obs_array; // + 0 + // Allocate new VarInfo objects - fcst_info = info_factory.new_var_info(ftype); - obs_info = info_factory.new_var_info(otype); +// *X fcst_info = info_factory.new_var_info(ftype); +// *X obs_info = info_factory.new_var_info(otype); // Set the dictionaries - fcst_info->set_dict(*(fcst_dict->lookup_dictionary(conf_key_field))); - obs_info->set_dict(*(obs_dict->lookup_dictionary(conf_key_field))); +// *X fcst_info->set_dict(*(fcst_dict->lookup_dictionary(conf_key_field))); +// *X obs_info->set_dict(*(obs_dict->lookup_dictionary(conf_key_field))); // Dump the contents of the VarInfo objects if(mlog.verbosity_level() >= 5) { - mlog << Debug(5) - << "Parsed forecast field:\n"; - fcst_info->dump(cout); - mlog << Debug(5) - << "Parsed observation field:\n"; - obs_info->dump(cout); + for (j=0; jdump(cout); + mlog << Debug(5) + << "Parsed observation field:\n"; + obs_array[j].var_info->dump(cout); + } // for j } // No support for wind direction - if(fcst_info->is_wind_direction() || obs_info->is_wind_direction()) { - mlog << Error << "\nModeConfInfo::process_config() -> " - << "the wind direction field may not be verified " - << "using MODE.\n\n"; - exit(1); + for (j=0; jis_wind_direction() || obs_array[j].var_info->is_wind_direction()) { + mlog << Error << "\nModeConfInfo::process_config() -> " + << "the wind direction field may not be verified " + << "using MODE.\n\n"; + exit(1); + } } // Conf: fcst.raw_thresh and obs.raw_thresh are deprecated - if ( fcst_dict->lookup(conf_key_raw_thresh) || - obs_dict->lookup(conf_key_raw_thresh) ) { - mlog << Error << "\nModeConfInfo::process_config() -> " - << "the \"" << conf_key_raw_thresh << "\" entry is deprecated in MET " - << met_version << "! Use \"" << conf_key_censor_thresh << "\" and \"" - << conf_key_censor_val << "\" instead.\n\n"; - exit(1); - } +// *X if ( fcst_dict->lookup(conf_key_raw_thresh) || +// *X obs_dict->lookup(conf_key_raw_thresh) ) { +// *X mlog << Error << "\nModeConfInfo::process_config() -> " +// *X << "the \"" << conf_key_raw_thresh << "\" entry is deprecated in MET " +// *X << met_version << "! Use \"" << conf_key_censor_thresh << "\" and \"" +// *X << conf_key_censor_val << "\" instead.\n\n"; +// *X exit(1); +// *X } // Conf: fcst.conv_radius and obs.conv_radius - fcst_conv_radius_array = fcst_dict->lookup_int_array(conf_key_conv_radius); - obs_conv_radius_array = obs_dict->lookup_int_array(conf_key_conv_radius); +// *X fcst_conv_radius_array = fcst_dict->lookup_int_array(conf_key_conv_radius); +// *X obs_conv_radius_array = obs_dict->lookup_int_array(conf_key_conv_radius); - if ( fcst_conv_radius_array.n_elements() != obs_conv_radius_array.n_elements() ) { + for (j=0; j " - << "fcst and obs convolution radius arrays need to be the same size\n\n"; + if ( fcst_array[j].conv_radius_array.n_elements() != obs_array[j].conv_radius_array.n_elements() ) { - exit ( 1 ); + mlog << Error << "\nModeConfInfo::process_config() -> " + << "fcst and obs convolution radius arrays need to be the same size\n\n"; + + exit ( 1 ); + + } } // Check that fcst_conv_radius and obs_conv_radius are non-negative - n = fcst_conv_radius_array.n_elements(); // same as obs_conv_radius_array.n_elements() + for (j=0; j " - << "fcst_conv_radius (" << fcst_conv_radius_array[j] - << ") and obs_conv_radius (" << obs_conv_radius_array[j] - << ") must be non-negative\n\n"; + if(fcst_array[j].conv_radius_array[k] < 0 || obs_array[j].conv_radius_array[k] < 0) { - exit(1); + mlog << Error << "\nModeConfInfo::process_config() -> " + << "fcst_conv_radius (" << fcst_array[j].conv_radius_array[k] + << ") and obs_conv_radius (" << obs_array[j].conv_radius_array[k] + << ") must be non-negative\n\n"; - } + exit(1); - } + } - if ( fcst_conv_radius_array.n_elements() == 1 ) fcst_conv_radius = fcst_conv_radius_array[0]; - if ( obs_conv_radius_array.n_elements() == 1 ) obs_conv_radius = obs_conv_radius_array[0]; + } // for k + + } // for j + + + for (j=0; jlookup_thresh_array(conf_key_conv_thresh); - obs_conv_thresh_array = obs_dict->lookup_thresh_array(conf_key_conv_thresh); +// *X fcst_conv_thresh_array = fcst_dict->lookup_thresh_array(conf_key_conv_thresh); +// *X obs_conv_thresh_array = obs_dict->lookup_thresh_array(conf_key_conv_thresh); - if ( fcst_conv_thresh_array.n_elements() != obs_conv_thresh_array.n_elements() ) { + for (j=0; j " - << "fcst and obs convolution threshold arrays need to be the same size\n\n"; + if ( fcst_array[j].conv_thresh_array.n_elements() != obs_array[j].conv_thresh_array.n_elements() ) { - exit ( 1 ); + mlog << Error << "\nModeConfInfo::process_config() -> " + << "fcst and obs convolution threshold arrays need to be the same size\n\n"; + + exit ( 1 ); + + } } - if ( fcst_conv_thresh_array.n_elements() == 1 ) fcst_conv_thresh = fcst_conv_thresh_array[0]; - if ( obs_conv_thresh_array.n_elements() == 1 ) obs_conv_thresh = obs_conv_thresh_array[0]; + + for (j=0; jlookup_double(conf_key_vld_thresh); - obs_vld_thresh = obs_dict->lookup_double(conf_key_vld_thresh); +// *X fcst_vld_thresh = fcst_dict->lookup_double(conf_key_vld_thresh); +// *X obs_vld_thresh = obs_dict->lookup_double(conf_key_vld_thresh); // Conf: fcst.filter_attr_name and fcst.filter_attr_thresh // obs.filter_attr_name and obs.filter_attr_thresh - fcst_filter_attr_map = parse_conf_filter_attr_map(fcst_dict); - obs_filter_attr_map = parse_conf_filter_attr_map(obs_dict); +// *X fcst_filter_attr_map = parse_conf_filter_attr_map(fcst_dict); +// *X obs_filter_attr_map = parse_conf_filter_attr_map(obs_dict); // Conf: fcst.merge_flag and obs.merge_flag - fcst_merge_flag = int_to_mergetype(fcst_dict->lookup_int(conf_key_merge_flag)); - obs_merge_flag = int_to_mergetype(obs_dict->lookup_int(conf_key_merge_flag)); +// *X fcst_merge_flag = int_to_mergetype(fcst_dict->lookup_int(conf_key_merge_flag)); +// *X obs_merge_flag = int_to_mergetype(obs_dict->lookup_int(conf_key_merge_flag)); // Conf: fcst.merge_thresh and obs.merge_thresh - fcst_merge_thresh_array = fcst_dict->lookup_thresh_array(conf_key_merge_thresh); - obs_merge_thresh_array = obs_dict->lookup_thresh_array(conf_key_merge_thresh); +// *X fcst_merge_thresh_array = fcst_dict->lookup_thresh_array(conf_key_merge_thresh); +// *X obs_merge_thresh_array = obs_dict->lookup_thresh_array(conf_key_merge_thresh); - if ( need_fcst_merge_thresh() && (fcst_merge_thresh_array.n_elements() != fcst_conv_thresh_array.n_elements()) ) { + for (j=0; j " - << "fcst conv thresh and fcst merge thresh arrays need to be the same size\n\n"; + if ( fcst_array[j].need_merge_thresh() && (fcst_array[j].merge_thresh_array.n_elements() != fcst_array[j].conv_thresh_array.n_elements()) ) { - exit ( 1 ); + mlog << Error << "\nModeConfInfo::process_config() -> " + << "fcst conv thresh and fcst merge thresh arrays need to be the same size\n\n"; - } + exit ( 1 ); + } - if ( need_obs_merge_thresh() && (obs_merge_thresh_array.n_elements() != obs_conv_thresh_array.n_elements()) ) { - mlog << Error << "\nModeConfInfo::process_config() -> " - << "obs conv thresh and obs merge thresh arrays need to be the same size\n\n"; + if ( obs_array[j].need_merge_thresh() && (obs_array[j].merge_thresh_array.n_elements() != obs_array[j].conv_thresh_array.n_elements()) ) { - exit ( 1 ); + mlog << Error << "\nModeConfInfo::process_config() -> " + << "obs conv thresh and obs merge thresh arrays need to be the same size\n\n"; - } + exit ( 1 ); - if ( fcst_merge_thresh_array.n_elements() == 1 ) fcst_merge_thresh = fcst_merge_thresh_array[0]; - if ( obs_merge_thresh_array.n_elements() == 1 ) obs_merge_thresh = obs_merge_thresh_array[0]; + } + + } // for j + + for (j=0; j " - << "When matching is disabled (match_flag = " - << matchtype_to_string(match_flag) - << ") but merging is requested (fcst_merge_flag = " - << mergetype_to_string(fcst_merge_flag) - << ", obs_merge_flag = " - << mergetype_to_string(obs_merge_flag) - << ") any merging information will be discarded.\n\n"; + for (j=0; j " + << "When matching is disabled (match_flag = " + << matchtype_to_string(match_flag) + << ") but merging is requested (fcst_merge_flag = " + << mergetype_to_string(fcst_array[j].merge_flag) + << ", obs_merge_flag = " + << mergetype_to_string(obs_array[j].merge_flag) + << ") any merging information will be discarded.\n\n"; + } + } // Conf: max_centroid_dist @@ -525,11 +598,14 @@ PlotInfo plot_info; // Conf: fcst_raw_plot - fcst_raw_pi = parse_conf_plot_info(conf.lookup_dictionary(conf_key_fcst_raw_plot)); +// *X + fcst_array->raw_pi = parse_conf_plot_info(conf.lookup_dictionary(conf_key_fcst_raw_plot)); // Conf: obs_raw_plot - obs_raw_pi = parse_conf_plot_info(conf.lookup_dictionary(conf_key_obs_raw_plot)); +// *X + + obs_array->raw_pi = parse_conf_plot_info(conf.lookup_dictionary(conf_key_obs_raw_plot)); // Conf: object_plot @@ -561,7 +637,8 @@ PlotInfo plot_info; // Conf: shift_right - shift_right = fcst_dict->lookup_int(conf_key_shift_right); +// *X + shift_right = fcst_dict->lookup_int(conf_key_shift_right); return; @@ -571,18 +648,132 @@ PlotInfo plot_info; //////////////////////////////////////////////////////////////////////// +void ModeConfInfo::read_fields (Mode_Field_Info * & info_array, Dictionary * dict, GrdFileType type, char _fo) + +{ + +const DictionaryEntry * ee = dict->lookup(conf_key_field); + +if ( !ee ) { + + mlog << "\n\n ModeConfInfo::read_fields () -> \"field\" entry not found in dictionary!\n\n"; + + exit ( 1 ); + +} + +const Dictionary * field = ee->dict(); + +const int N = ( (field->is_array()) ? (field->n_entries()) : 1 ); + +info_array = new Mode_Field_Info [N]; + +N_fields = N; + + +if ( field->is_array() ) { + + int j, k; + const DictionaryEntry * e = 0; + const Dictionary & D = *field; + + if ( (N_fields > 0) && (N != N_fields) ) { + + mlog << Error + << "\n\n ModeConfInfo::read_field_dict() -> fcst and obs dictionaries have different number of entries\n\n"; + + exit ( 1 ); + + } + + for (j=0; jtype() != DictionaryType) && (e->type() != ArrayType) ) { + + mlog << Error + << "\n\n ModeConfInfo::read_field_dict() -> field entry # " << (j + 1) << " is not a dictionary!\n\n"; + + exit ( 1 ); + + } + + info_array[j].set(true, j, e->dict_value(), &conf, type, _fo, false); + + if ( j == 0 ) { + + for (k=1; k= N_fields) ) { + + mlog << Error + << "\n\n ModeConfInfo::set_field_index(int) -> range check error\n\n"; + + exit ( 1 ); + +} + +Field_Index = k; + +Fcst = fcst_array + k; + Obs = obs_array + k; + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + void ModeConfInfo::set_perc_thresh(const DataPlane &f_dp, const DataPlane &o_dp) + { // // Compute percentiles for forecast and observation thresholds. // - if( !fcst_conv_thresh_array.need_perc() && - !obs_conv_thresh_array.need_perc() && - !fcst_merge_thresh_array.need_perc() && - !obs_merge_thresh_array.need_perc() ) return; + if( !(Fcst->conv_thresh_array.need_perc() ) && + !(Obs->conv_thresh_array.need_perc() ) && + !(Fcst->merge_thresh_array.need_perc() ) && + !(Obs->merge_thresh_array.need_perc() ) ) return; // // Sort the input arrays @@ -604,18 +795,21 @@ void ModeConfInfo::set_perc_thresh(const DataPlane &f_dp, // // Compute percentiles // - fcst_conv_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, - &fcst_conv_thresh_array, - &obs_conv_thresh_array); - obs_conv_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, - &fcst_conv_thresh_array, - &obs_conv_thresh_array); - fcst_merge_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, - &fcst_merge_thresh_array, - &obs_merge_thresh_array); - obs_merge_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, - &fcst_merge_thresh_array, - &obs_merge_thresh_array); + Fcst->conv_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, + &(Fcst->conv_thresh_array), + &(Obs->conv_thresh_array)); + + Obs->conv_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, + &(Fcst->conv_thresh_array), + &(Obs->conv_thresh_array)); + + Fcst->merge_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, + &(Fcst->merge_thresh_array), + &(Obs->merge_thresh_array)); + + Obs->merge_thresh_array.set_perc(&fsort, &osort, (NumArray *) 0, + &(Fcst->merge_thresh_array), + &(Obs->merge_thresh_array)); return; @@ -703,17 +897,18 @@ void ModeConfInfo::set_conv_radius_by_index(int k) // the same number of elements // -if ( (k < 0) || (k >= fcst_conv_radius_array.n_elements()) ) { +if ( (k < 0) || (k >= Fcst->conv_radius_array.n_elements()) ) { - mlog << Error << "\nModeConfInfo::set_conv_radius_by_index(int) -> " + mlog << Error + << "\nModeConfInfo::set_conv_radius_by_index(int) -> " << "range check error\n\n"; exit ( 1 ); } -fcst_conv_radius = fcst_conv_radius_array[k]; - obs_conv_radius = obs_conv_radius_array[k]; +Fcst->conv_radius = Fcst->conv_radius_array[k]; + Obs->conv_radius = Obs->conv_radius_array[k]; return; @@ -732,17 +927,18 @@ void ModeConfInfo::set_conv_thresh_by_index(int k) // the same number of elements // -if ( (k < 0) || (k >= fcst_conv_thresh_array.n_elements()) ) { +if ( (k < 0) || (k >= Fcst->conv_thresh_array.n_elements()) ) { - mlog << Error << "\nModeConfInfo::set_conv_thresh_by_index(int) -> " + mlog << Error + << "\nModeConfInfo::set_conv_thresh_by_index(int) -> " << "range check error\n\n"; exit ( 1 ); } -fcst_conv_thresh = fcst_conv_thresh_array[k]; - obs_conv_thresh = obs_conv_thresh_array[k]; +Fcst->conv_thresh = Fcst->conv_thresh_array[k]; + Obs->conv_thresh = Obs->conv_thresh_array[k]; return; @@ -756,16 +952,21 @@ void ModeConfInfo::set_fcst_merge_thresh_by_index(int k) { -if ( (k < 0) || (k >= fcst_merge_thresh_array.n_elements()) ) { +Fcst->set_merge_thresh_by_index(k); - mlog << Error << "\nModeConfInfo::set_fcst_merge_thresh_by_index(int) -> " - << "range check error\n\n"; - - exit ( 1 ); +return; } -fcst_merge_thresh = fcst_merge_thresh_array[k]; + +//////////////////////////////////////////////////////////////////////// + + +void ModeConfInfo::set_obs_merge_thresh_by_index(int k) + +{ + +Obs->set_merge_thresh_by_index(k); return; @@ -775,22 +976,55 @@ return; //////////////////////////////////////////////////////////////////////// -void ModeConfInfo::set_obs_merge_thresh_by_index(int k) +int ModeConfInfo::n_runs() const { -if ( (k < 0) || (k >= obs_merge_thresh_array.n_elements()) ) { +const int nr = n_conv_radii(); +const int nt = n_conv_threshs(); - mlog << Error << "\nModeConfInfo::set_obs_merge_thresh_by_index(int) -> " - << "range check error\n\n"; +return ( nr*nt ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool ModeConfInfo::is_multivar() + +{ + +const DictionaryEntry * e = conf.lookup("fcst"); + +if ( e->type() != DictionaryType ) { + + mlog << Error + << "\n\n ModeConfInfo::is_multivar() const -> bad object type for entry \"fcst\"\n\n"; exit ( 1 ); } - obs_merge_thresh = obs_merge_thresh_array[k]; -return; +const DictionaryEntry * e2 = e->dict()->lookup("field"); +bool status = false; + +switch ( e2->type() ) { + + case ArrayType: status = true; break; + case DictionaryType: status = false; break; + + default: + mlog << Error + << "\n\n ModeConfInfo::is_multivar() const -> bad object type for entry \"fcst.field\"\n\n"; + exit ( 1 ); + break; + +} + + +return ( status ); } @@ -798,14 +1032,27 @@ return; //////////////////////////////////////////////////////////////////////// -int ModeConfInfo::n_runs() const +void ModeConfInfo::get_multivar_programs() { -const int nr = n_conv_radii(); -const int nt = n_conv_threshs(); +Dictionary * dict = (Dictionary *) 0; -return ( nr*nt ); +fcst_multivar_logic.clear(); + obs_multivar_logic.clear(); + + +dict = conf.lookup_dictionary(conf_key_fcst); + +if ( dict->lookup(conf_key_multivar_logic) ) fcst_multivar_logic = dict->lookup_string(conf_key_multivar_logic); + +dict = conf.lookup_dictionary(conf_key_obs); + +if ( dict->lookup(conf_key_multivar_logic) ) obs_multivar_logic = dict->lookup_string(conf_key_multivar_logic); + + + +return; } diff --git a/met/src/libcode/vx_shapedata/mode_conf_info.h b/met/src/libcode/vx_shapedata/mode_conf_info.h index 8e71a4f3c3..5e6c436f62 100644 --- a/met/src/libcode/vx_shapedata/mode_conf_info.h +++ b/met/src/libcode/vx_shapedata/mode_conf_info.h @@ -22,6 +22,8 @@ #include "vx_cal.h" #include "vx_math.h" +#include "mode_field_info.h" + //////////////////////////////////////////////////////////////////////// @@ -65,103 +67,75 @@ class ModeConfInfo { void init_from_scratch(); + int Field_Index; + + int N_fields; // = 1 for traditional MODE + // > 1 for multivar MODE + // should always be at least 1 + public: + ModeConfInfo(); ~ModeConfInfo(); void clear(); - void read_config (const char * default_filename, const char * user_filename); + void set_field_index(int); - void process_config (GrdFileType ftype, GrdFileType otype); + int field_index() const; - void set_perc_thresh(const DataPlane &, const DataPlane &); + bool is_multivar(); - void parse_nc_info (); + ConcatString fcst_multivar_logic; + ConcatString obs_multivar_logic; - void set_conv_radius_by_index (int); - void set_conv_thresh_by_index (int); + void get_multivar_programs(); - void set_fcst_merge_thresh_by_index (int); - void set_obs_merge_thresh_by_index (int); - int n_conv_threshs () const; - int n_conv_radii () const; + ///////////////////////////////////////////////////////////////////// - int n_fcst_merge_threshs () const; - int n_obs_merge_threshs () const; - int n_runs() const; // # threshs times # radii + Mode_Field_Info * fcst_array; // allocated + Mode_Field_Info * obs_array; // allocated - int get_compression_level(); - - // Store data parsed from the MODE configuration object + Mode_Field_Info * Fcst; // points to current field, not allocated + Mode_Field_Info * Obs; // points to current field, not allocated - MetConfig conf; // MODE configuration object - ConcatString model; // Model name - ConcatString desc; // Description - ConcatString obtype; // Observation type - - double grid_res; - - VarInfo * fcst_info; // allocated - VarInfo * obs_info; // allocated - - bool quilt; // default: false + ///////////////////////////////////////////////////////////////////// - IntArray fcst_conv_radius_array; // List of convolution radii in grid squares - IntArray obs_conv_radius_array; - int fcst_conv_radius; // Convolution radius in grid squares - int obs_conv_radius; + // + // configuration file + // - ThreshArray fcst_conv_thresh_array; // List of conv thresholds to use - ThreshArray obs_conv_thresh_array; - - SingleThresh fcst_conv_thresh; // Convolution threshold to define objects - SingleThresh obs_conv_thresh; - - double fcst_vld_thresh; // Minimum ratio of valid data points in the convolution area - double obs_vld_thresh; - - map fcst_filter_attr_map; // Discard objects that don't meet these attribute thresholds - map obs_filter_attr_map; - - ThreshArray fcst_merge_thresh_array; // Lower convolution threshold used for double merging method - ThreshArray obs_merge_thresh_array; - - SingleThresh fcst_merge_thresh; // Lower convolution threshold used for double merging method - SingleThresh obs_merge_thresh; - - MergeType fcst_merge_flag; // Define which merging methods should be employed - MergeType obs_merge_flag; - - FieldType mask_missing_flag; // Mask missing data between fcst and obs + MetConfig conf; // MODE configuration object - MatchType match_flag; // Define which matching methods should be employed + void read_config (const char * default_filename, const char * user_filename); + void process_config (GrdFileType ftype, GrdFileType otype); - double max_centroid_dist; // Only compare objects whose centroids are close enough (in grid squares) + void read_fields (Mode_Field_Info * &, Dictionary * dict, GrdFileType, char _fo); - ConcatString mask_grid_name; // Path for masking grid area - FieldType mask_grid_flag; // Define which fields should be masked out + // + // weights + // - ConcatString mask_poly_name; // Path for masking poly area - FieldType mask_poly_flag; // Define which fields should be masked out + double centroid_dist_wt; // Weights used as input to the fuzzy engine + double boundary_dist_wt; + double convex_hull_dist_wt; + double angle_diff_wt; + double aspect_diff_wt; + double area_ratio_wt; + double int_area_ratio_wt; + double curvature_ratio_wt; + double complexity_ratio_wt; + double inten_perc_ratio_wt; - double centroid_dist_wt; // Weights used as input to the fuzzy engine - double boundary_dist_wt; - double convex_hull_dist_wt; - double angle_diff_wt; - double aspect_diff_wt; - double area_ratio_wt; - double int_area_ratio_wt; - double curvature_ratio_wt; - double complexity_ratio_wt; - double inten_perc_ratio_wt; - int inten_perc_value; // Intensity percentile used for the intensity percentile ratio + // + // interest maps + // PiecewiseLinear * centroid_dist_if; // Interest functions used as input to the fuzzy engine PiecewiseLinear * boundary_dist_if; // not allocated @@ -174,30 +148,82 @@ class ModeConfInfo { PiecewiseLinear * complexity_ratio_if; PiecewiseLinear * inten_perc_ratio_if; - double total_interest_thresh; // Total interest threshold defining significance + // + // interest thresholds + // + double total_interest_thresh; // Total interest threshold defining significance double print_interest_thresh; // Only write output for pairs with this interest - ConcatString met_data_dir; // MET data directory + // + // limits + // - PlotInfo fcst_raw_pi; // Raw forecast plotting info - PlotInfo obs_raw_pi; // Raw observation plotting info - PlotInfo object_pi; // Object plotting info + double max_centroid_dist; // Only compare objects whose centroids are close enough (in grid squares) + + + // + // flags + // + bool quilt; // default: false bool plot_valid_flag; // Zoom up plot to the sub-region of valid data bool plot_gcarc_flag; // Plot lines as great-circle arcs bool ps_plot_flag; // Flag for the output PostScript image file // bool nc_pairs_flag; // output NetCDF file - ModeNcOutInfo nc_info; bool ct_stats_flag; // Flag for the output contingency table statistics file + FieldType mask_missing_flag; // Mask missing data between fcst and obs + MatchType match_flag; // Define which matching methods should be employed + FieldType mask_grid_flag; // Define which fields should be masked out + FieldType mask_poly_flag; // Define which fields should be masked out + + + // + // misc member data + // + + int inten_perc_value; // Intensity percentile used for the intensity percentile ratio + double grid_res; + + ConcatString model; // Model name + ConcatString desc; // Description + ConcatString obtype; // Observation type + + ConcatString mask_grid_name; // Path for masking grid area + ConcatString mask_poly_name; // Path for masking poly area + + ConcatString met_data_dir; // MET data directory + + PlotInfo object_pi; // Object plotting info + + ModeNcOutInfo nc_info; + int shift_right; // shift amount for global grids ConcatString output_prefix; // String to customize output file name ConcatString version; // Config file version - bool need_fcst_merge_thresh () const; // mergetype is both or thresh - bool need_obs_merge_thresh () const; // mergetype is both or thresh + // + // misc member functions + // + + void set_perc_thresh(const DataPlane &, const DataPlane &); + + void parse_nc_info (); + + void set_conv_radius_by_index (int); + void set_conv_thresh_by_index (int); + + int n_conv_threshs () const; + int n_conv_radii () const; + + int n_runs() const; // # threshs times # radii + + int get_compression_level(); + + void set_fcst_merge_thresh_by_index (int); + void set_obs_merge_thresh_by_index (int); }; @@ -205,23 +231,26 @@ class ModeConfInfo { //////////////////////////////////////////////////////////////////////// -inline int ModeConfInfo::n_conv_radii() const { return ( fcst_conv_radius_array.n_elements() ); } // should be the same as - // obs_conv_radius_array.n_elements() +inline int ModeConfInfo::n_conv_radii() const { return ( Fcst->conv_radius_array.n_elements() ); } // should be the same as + // obs_conv_radius_array.n_elements() -inline int ModeConfInfo::n_conv_threshs() const { return ( fcst_conv_thresh_array.n_elements() ); } // should be the same as - // obs_conv_thresh_array.n_elements() +inline int ModeConfInfo::n_conv_threshs() const { return ( Fcst->conv_thresh_array.n_elements() ); } // should be the same as + // obs_conv_thresh_array.n_elements() -inline int ModeConfInfo::n_fcst_merge_threshs () const { return ( fcst_merge_thresh_array.n_elements() ); } -inline int ModeConfInfo::n_obs_merge_threshs () const { return ( obs_merge_thresh_array.n_elements() ); } +// inline int ModeConfInfo::n_fcst_merge_threshs () const { return ( fcst->merge_thresh_array.n_elements() ); } +// inline int ModeConfInfo::n_obs_merge_threshs () const { return ( obs->merge_thresh_array.n_elements() ); } -inline bool ModeConfInfo::need_fcst_merge_thresh () const { return ( (fcst_merge_flag == MergeType_Both) || (fcst_merge_flag == MergeType_Thresh) ); } -inline bool ModeConfInfo::need_obs_merge_thresh () const { return ( ( obs_merge_flag == MergeType_Both) || ( obs_merge_flag == MergeType_Thresh) ); } +// inline bool ModeConfInfo::need_fcst_merge_thresh () const { return ( (fcst->merge_flag == MergeType_Both) || (fcst->merge_flag == MergeType_Thresh) ); } +// inline bool ModeConfInfo::need_obs_merge_thresh () const { return ( ( obs->merge_flag == MergeType_Both) || ( obs->merge_flag == MergeType_Thresh) ); } inline int ModeConfInfo::get_compression_level() { return conf.nc_compression(); } +inline int ModeConfInfo::field_index() const { return Field_Index; } + + //////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_shapedata/mode_data_field.h b/met/src/libcode/vx_shapedata/mode_data_field.h new file mode 100644 index 0000000000..7b5d7359a1 --- /dev/null +++ b/met/src/libcode/vx_shapedata/mode_data_field.h @@ -0,0 +1,64 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2019 +// ** 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 __MODE_DATA_FIELD_H__ +#define __MODE_DATA_FIELD_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include + + +//////////////////////////////////////////////////////////////////////// + + +class ModeDataField { + + private: + + void init_from_scratch(); + + void assign(const ModeDataField &); + + public: + + ModeDataField(); + ~ModeDataField(); + ModeDataField(const ModeDataField &); + ModeDataField & operator=(const ModeDataField &); + + void clear(); + + void dump(ostream &, int depth = 0) const; + + + + + + + + + +}; + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MODE_DATA_FIELD_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/libcode/vx_shapedata/mode_field_info.cc b/met/src/libcode/vx_shapedata/mode_field_info.cc new file mode 100644 index 0000000000..bd3a55fc65 --- /dev/null +++ b/met/src/libcode/vx_shapedata/mode_field_info.cc @@ -0,0 +1,301 @@ + + +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2019 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +//////////////////////////////////////////////////////////////////////// + + +#include "vx_config.h" +#include "vx_data2d.h" +#include "vx_grid.h" +#include "vx_util.h" +#include "vx_cal.h" +#include "vx_math.h" +#include "vx_data2d_factory.h" + +#include "mode_field_info.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // Code for class Mode_Field_Info + // + + +//////////////////////////////////////////////////////////////////////// + + +Mode_Field_Info::Mode_Field_Info() + +{ + +init_from_scratch(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Mode_Field_Info::~Mode_Field_Info() + +{ + +clear(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Mode_Field_Info::Mode_Field_Info(const Mode_Field_Info & i) + +{ + +init_from_scratch(); + +assign(i); + +} + + +//////////////////////////////////////////////////////////////////////// + + +Mode_Field_Info & Mode_Field_Info::operator=(const Mode_Field_Info & i) + +{ + +if ( this == &i ) return ( * this ); + +assign(i); + +return ( * this ); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Mode_Field_Info::init_from_scratch() + +{ + +dict = 0; + +conf = 0; + +var_info = 0; + +clear(); + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Mode_Field_Info::clear() + +{ + +index = -1; + +dict = 0; // not allocated, so don't delete + +conf = 0; // not allocated, so don't delete + +gft = FileType_None; + +Multivar = false; + +FO = (char) 0; + +conv_radius = 0; + +vld_thresh = 0.0; + +if ( var_info ) { delete var_info; var_info = 0; } + +conv_radius_array.clear(); + +conv_thresh_array.clear(); + +merge_thresh_array.clear(); + +conv_thresh.clear(); + +merge_thresh.clear(); + +merge_flag = MergeType_Engine; + +// raw_pi.clear(); + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Mode_Field_Info::assign(const Mode_Field_Info & i) + +{ + +set(i.Multivar, i.index, i.dict, i.conf, i.gft, i.FO, true); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Mode_Field_Info::set (const bool _multivar, int _index, Dictionary * _dict, MetConfig * _conf, GrdFileType type, char _fo, bool do_clear) + +{ + +VarInfoFactory info_factory; + +if ( do_clear ) clear(); + +Multivar = _multivar; + +index = _index; + +dict = _dict; + +conf = _conf; + +var_info = info_factory.new_var_info(type); + +if ( _multivar ) { + + var_info->set_dict(*dict); + +} else { + + var_info->set_dict(*(dict->lookup_dictionary(conf_key_field))); + +} + +FO = _fo; + +gft = type; + +if ( dict->lookup(conf_key_raw_thresh) ) { + + mlog << Error + << "\nMode_Field_Info::process_config() -> " + << "the \"" << conf_key_raw_thresh << "\" entry is deprecated in MET " + << met_version << "! Use \"" << conf_key_censor_thresh << "\" and \"" + << conf_key_censor_val << "\" instead.\n\n"; + + exit(1); + +} + +if ( dict->lookup(conf_key_conv_radius) ) { + + conv_radius_array = dict->lookup_int_array(conf_key_conv_radius); + +} + +if ( dict->lookup(conf_key_conv_thresh) ) { + + conv_thresh_array = dict->lookup_thresh_array(conf_key_conv_thresh); + +} + +if ( dict->lookup(conf_key_merge_thresh) ) { + + merge_thresh_array = dict->lookup_thresh_array(conf_key_merge_thresh); + +} + +if ( dict->lookup(conf_key_vld_thresh) ) { + + vld_thresh = dict->lookup_double(conf_key_vld_thresh); + +} + +if ( dict->lookup(conf_key_merge_flag) ) { + + merge_flag = int_to_mergetype(dict->lookup_int(conf_key_merge_flag)); + +} + + +filter_attr_map = parse_conf_filter_attr_map(dict); + +if ( FO == 'F' ) raw_pi = parse_conf_plot_info(conf->lookup_dictionary(conf_key_fcst_raw_plot)); +else raw_pi = parse_conf_plot_info(conf->lookup_dictionary(conf_key_obs_raw_plot)); + + + + + // + // done + // + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void Mode_Field_Info::set_merge_thresh_by_index (int k) + +{ + +if ( (k < 0) || (k >= merge_thresh_array.n_elements()) ) { + + mlog << Error << "\nMode_Field_Info::set_fcst_merge_thresh_by_index(int) -> " + << "range check error\n\n"; + + exit ( 1 ); + +} + +merge_thresh = merge_thresh_array[k]; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +bool Mode_Field_Info::need_merge_thresh () const + +{ + +bool status = (merge_flag == MergeType_Both) || (merge_flag == MergeType_Thresh); + +return ( status ); + +} + + +//////////////////////////////////////////////////////////////////////// + + + diff --git a/met/src/libcode/vx_shapedata/mode_field_info.h b/met/src/libcode/vx_shapedata/mode_field_info.h new file mode 100644 index 0000000000..800c396f13 --- /dev/null +++ b/met/src/libcode/vx_shapedata/mode_field_info.h @@ -0,0 +1,110 @@ + + +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2019 +// ** 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 __MODE_FIELD_INFO_H__ +#define __MODE_FIELD_INFO_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include "vx_config.h" +#include "vx_data2d.h" +#include "vx_grid.h" +#include "vx_util.h" +#include "vx_cal.h" +#include "vx_math.h" + + +//////////////////////////////////////////////////////////////////////// + + +typedef map AttrFilterMap; + + +//////////////////////////////////////////////////////////////////////// + + +class Mode_Field_Info { + + protected: + + void init_from_scratch(); + + void assign(const Mode_Field_Info &); + + + Dictionary * dict; // not allocated + + MetConfig * conf; // not allocated + + GrdFileType gft; + + char FO; // 'F' or 'O', for fcst or obs + + bool Multivar; + + public: + + Mode_Field_Info(); + ~Mode_Field_Info(); + Mode_Field_Info(const Mode_Field_Info &); + Mode_Field_Info & operator=(const Mode_Field_Info &); + + void clear(); + + void set (const bool _multivar, int _index, Dictionary *, MetConfig *, GrdFileType, char _fo, bool do_clear = false); + + int index; + + // + // member data + // + + int conv_radius; // Convolution radius in grid squares + double vld_thresh; // Minimum ratio of valid data points in the convolution area + + VarInfo * var_info; // allocated + IntArray conv_radius_array; // List of convolution radii in grid squares + + ThreshArray conv_thresh_array; // List of conv thresholds to use + ThreshArray merge_thresh_array; // Lower convolution threshold used for double merging method + SingleThresh conv_thresh; // Convolution threshold to define objects + SingleThresh merge_thresh; // Lower convolution threshold used for double merging method + + MergeType merge_flag; // Define which merging methods should be employed + + PlotInfo raw_pi; // Raw forecast plotting info + + // + // member functions + // + + void set_merge_thresh_by_index (int); + int n_merge_threshs () const; + bool need_merge_thresh () const; // mergetype is both or thresh + AttrFilterMap filter_attr_map; // Discard objects that don't meet these attribute thresholds + +}; + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MODE_FIELD_INFO_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/tools/core/mode/Makefile.am b/met/src/tools/core/mode/Makefile.am index 662dee58ef..14df6b0ca8 100644 --- a/met/src/tools/core/mode/Makefile.am +++ b/met/src/tools/core/mode/Makefile.am @@ -11,7 +11,12 @@ include ${top_srcdir}/Make-include # The program bin_PROGRAMS = mode -mode_SOURCES = mode.cc \ +mode_SOURCES = mode_usage.cc \ + mode_frontend.cc \ + multivar_frontend.cc \ + mode.cc \ + combine_boolplanes.cc \ + objects_from_netcdf.cc \ mode_ps_file.cc \ plot_engine.cc \ page_1.cc \ @@ -45,6 +50,7 @@ mode_LDADD = -lvx_pxm \ -lvx_regrid \ -lvx_grid \ -lvx_config \ + -lvx_bool_calc \ -lvx_cal \ -lvx_util \ -lvx_math \ diff --git a/met/src/tools/core/mode/combine_boolplanes.cc b/met/src/tools/core/mode/combine_boolplanes.cc new file mode 100644 index 0000000000..3b9db02d39 --- /dev/null +++ b/met/src/tools/core/mode/combine_boolplanes.cc @@ -0,0 +1,111 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2022 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include + +#include "combine_boolplanes.h" + + +//////////////////////////////////////////////////////////////////////// + + // + // assumes all the input BoolPlanes (and the output BoolPlane) are the same size + // + +void combine_boolplanes(const BoolPlane * bpa, const int n_planes, + BoolCalc & calc, + BoolPlane & bp_out) + + +{ + +int j, x, y; +const int nx = bp_out.nx(); +const int ny = bp_out.ny(); +vector v(n_planes); +bool tf = false; + + +for (x=0; x @@ -71,7 +73,9 @@ using namespace std; #include #include -#include "mode_exec.h" +#include "string_array.h" +#include "mode_usage.h" +#include "mode_conf_info.h" #ifdef WITH_PYTHON #include "global_python.h" @@ -90,156 +94,65 @@ using namespace std; /////////////////////////////////////////////////////////////////////// -static const char program_name [] = "mode"; - -static ModeExecutive mode_exec; // gotta make this global ... not sure why - - -/////////////////////////////////////////////////////////////////////// - - -// static const char * default_out_dir = "MET_BASE/out/mode"; -static const char * default_out_dir = "."; +extern int mode_frontend(const StringArray &); +extern int multivar_frontend(const StringArray &); -static int compress_level = -1; +extern const char * const program_name; /////////////////////////////////////////////////////////////////////// -static void do_quilt (); -static void do_straight (); - -static void process_command_line(int, char **); - -static void usage(); - -static void set_config_merge_file (const StringArray &); -static void set_outdir (const StringArray &); -static void set_compress (const StringArray &); - - -/////////////////////////////////////////////////////////////////////// - - -int main(int argc, char * argv []) - -{ - - // - // Set handler to be called for memory allocation error - // - -set_new_handler(oom); - // - // Process the command line arguments + // these need external linkage // -process_command_line(argc, argv); - - // - // Process the forecast and observation files - // - -ModeConfInfo & conf = mode_exec.engine.conf_info; - -mode_exec.setup_fcst_obs_data(); +const char * const program_name = "mode"; -if (compress_level >= 0) conf.nc_info.set_compress_level(compress_level); +/////////////////////////////////////////////////////////////////////// -if ( conf.quilt ) { - - do_quilt(); - -} else { - - do_straight(); - -} - -mode_exec.clear(); - - // - // done - // - -#ifdef WITH_PYTHON - GP.finalize(); -#endif -return ( 0 ); - -} +static const char default_config_filename [] = "MET_BASE/config/MODEConfig_default"; /////////////////////////////////////////////////////////////////////// -void do_straight() +int main(int argc, char * argv []) { -const ModeConfInfo & conf = mode_exec.engine.conf_info; - -const int NCT = conf.n_conv_threshs(); -const int NCR = conf.n_conv_radii(); - -if ( NCT != NCR ) { - - mlog << Error - << "\n\n " - << program_name - << ": all convolution radius and threshold arrays must have the same number of elements!\n\n"; - - exit ( 1 ); - -} - -int index; +if ( argc == 1 ) both_usage(); -for (index=0; index #include #include @@ -223,29 +218,29 @@ void ModeExecutive::setup_fcst_obs_data() // Read the gridded data from the input forecast file - if ( !(fcst_mtddf->data_plane(*(engine.conf_info.fcst_info), Fcst_sd.data)) ) { + if ( !(fcst_mtddf->data_plane(*(engine.conf_info.Fcst->var_info), Fcst_sd.data)) ) { mlog << Error << "\nsetup_fcst_obs_data() -> " << "can't get forecast data \"" - << engine.conf_info.fcst_info->magic_str() + << engine.conf_info.Fcst->var_info->magic_str() << "\" from file \"" << fcst_file << "\"\n\n"; exit(1); } // Read the gridded data from the input observation file - if ( !(obs_mtddf->data_plane(*(engine.conf_info.obs_info), Obs_sd.data)) ) { + if ( !(obs_mtddf->data_plane(*(engine.conf_info.Obs->var_info), Obs_sd.data)) ) { mlog << Error << "\nsetup_fcst_obs_data() -> " << "can't get observation data \"" - << engine.conf_info.obs_info->magic_str() + << engine.conf_info.Obs->var_info->magic_str() << "\" from file \"" << obs_file << "\"\n\n"; exit(1); } // Determine the verification grid - grid = parse_vx_grid(engine.conf_info.fcst_info->regrid(), + grid = parse_vx_grid(engine.conf_info.Fcst->var_info->regrid(), &(fcst_mtddf->grid()), &(obs_mtddf->grid())); // Store the grid @@ -256,29 +251,29 @@ void ModeExecutive::setup_fcst_obs_data() if ( !(fcst_mtddf->grid() == grid) ) { mlog << Debug(1) - << "Regridding forecast " << engine.conf_info.fcst_info->magic_str() + << "Regridding forecast " << engine.conf_info.Fcst->var_info->magic_str() << " to the verification grid.\n"; Fcst_sd.data = met_regrid(Fcst_sd.data, fcst_mtddf->grid(), grid, - engine.conf_info.fcst_info->regrid()); + engine.conf_info.Fcst->var_info->regrid()); } // Regrid, if necessary if ( !(obs_mtddf->grid() == grid) ) { mlog << Debug(1) - << "Regridding observation " << engine.conf_info.obs_info->magic_str() + << "Regridding observation " << engine.conf_info.Obs->var_info->magic_str() << " to the verification grid.\n"; Obs_sd.data = met_regrid(Obs_sd.data, obs_mtddf->grid(), grid, - engine.conf_info.obs_info->regrid()); + engine.conf_info.Obs->var_info->regrid()); } // Rescale probabilites from [0, 100] to [0, 1] - if ( engine.conf_info.fcst_info->p_flag() ) rescale_probability(Fcst_sd.data); + if ( engine.conf_info.Fcst->var_info->p_flag() ) rescale_probability(Fcst_sd.data); // Rescale probabilites from [0, 100] to [0, 1] - if ( engine.conf_info.obs_info->p_flag() ) rescale_probability(Obs_sd.data); + if ( engine.conf_info.Obs->var_info->p_flag() ) rescale_probability(Obs_sd.data); // Print a warning if the valid times do not match @@ -288,32 +283,32 @@ void ModeExecutive::setup_fcst_obs_data() << "Forecast and observation valid times do not match " << unix_to_yyyymmdd_hhmmss(Fcst_sd.data.valid()) << " != " << unix_to_yyyymmdd_hhmmss(Obs_sd.data.valid()) << " for " - << engine.conf_info.fcst_info->magic_str() << " versus " - << engine.conf_info.obs_info->magic_str() << ".\n\n"; + << engine.conf_info.Fcst->var_info->magic_str() << " versus " + << engine.conf_info.Obs->var_info->magic_str() << ".\n\n"; } // Print a warning if the accumulation intervals do not match - if(engine.conf_info.fcst_info->level().type() == LevelType_Accum && - engine.conf_info.obs_info->level().type() == LevelType_Accum && + if(engine.conf_info.Fcst->var_info->level().type() == LevelType_Accum && + engine.conf_info.Obs->var_info->level().type() == LevelType_Accum && Fcst_sd.data.accum() != Obs_sd.data.accum()) { mlog << Warning << "\nsetup_fcst_obs_data() -> " << "Forecast and observation accumulation times do not match " << sec_to_hhmmss(Fcst_sd.data.valid()) << " != " << sec_to_hhmmss(Obs_sd.data.valid()) << " for " - << engine.conf_info.fcst_info->magic_str() << " versus " - << engine.conf_info.obs_info->magic_str() << ".\n\n"; + << engine.conf_info.Fcst->var_info->magic_str() << " versus " + << engine.conf_info.Obs->var_info->magic_str() << ".\n\n"; } mlog << Debug(1) << "Forecast Field: " - << engine.conf_info.fcst_info->name_attr() << " at " - << engine.conf_info.fcst_info->level_attr() + << engine.conf_info.Fcst->var_info->name_attr() << " at " + << engine.conf_info.Fcst->var_info->level_attr() << "\n" << "Observation Field: " - << engine.conf_info.obs_info->name_attr() << " at " - << engine.conf_info.obs_info->level_attr() + << engine.conf_info.Obs->var_info->name_attr() << " at " + << engine.conf_info.Obs->var_info->level_attr() << "\n"; // Mask out the missing data between fields @@ -374,8 +369,8 @@ T_index = t_index; conf.set_conv_radius_by_index (R_index); conf.set_conv_thresh_by_index (T_index); -if ( conf.need_fcst_merge_thresh () ) conf.set_fcst_merge_thresh_by_index (T_index); -if ( conf.need_obs_merge_thresh () ) conf.set_obs_merge_thresh_by_index (T_index); +if ( conf.Fcst->need_merge_thresh () ) conf.set_fcst_merge_thresh_by_index (T_index); +if ( conf.Obs->need_merge_thresh () ) conf.set_obs_merge_thresh_by_index (T_index); // // Set up the engine with these raw fields @@ -425,7 +420,7 @@ void ModeExecutive::do_match_merge() mlog << Debug(2) << "Performing merging (" - << mergetype_to_string(engine.conf_info.fcst_merge_flag) + << mergetype_to_string(engine.conf_info.Fcst->merge_flag) << ") in the forecast field.\n"; // Do the forecast merging @@ -434,7 +429,7 @@ void ModeExecutive::do_match_merge() mlog << Debug(2) << "Performing merging (" - << mergetype_to_string(engine.conf_info.obs_merge_flag) + << mergetype_to_string(engine.conf_info.Obs->merge_flag) << ") in the observation field.\n"; // Do the observation merging @@ -558,8 +553,8 @@ void ModeExecutive::compute_ct_stats() obs_mask = *engine.obs_raw; // Apply the thresholds specified in the config file - fcst_mask.threshold(engine.conf_info.fcst_conv_thresh); - obs_mask.threshold(engine.conf_info.obs_conv_thresh); + fcst_mask.threshold(engine.conf_info.Fcst->conv_thresh); + obs_mask.threshold(engine.conf_info.Obs->conv_thresh); } // Object fields else if(i == 1) { @@ -749,8 +744,8 @@ void ModeExecutive::write_obj_stats() out.close(); - if(engine.conf_info.fcst_merge_flag == MergeType_Both || - engine.conf_info.fcst_merge_flag == MergeType_Engine) { + if(engine.conf_info.Fcst->merge_flag == MergeType_Both || + engine.conf_info.Fcst->merge_flag == MergeType_Engine) { // // Create output stats file for forecast merging @@ -781,8 +776,8 @@ void ModeExecutive::write_obj_stats() out.close(); } - if(engine.conf_info.obs_merge_flag == MergeType_Both || - engine.conf_info.obs_merge_flag == MergeType_Engine) { + if(engine.conf_info.Obs->merge_flag == MergeType_Both || + engine.conf_info.Obs->merge_flag == MergeType_Engine) { // // Create output stats file for observation merging @@ -829,8 +824,8 @@ if ( info.all_false() ) return; int n, x, y; ConcatString out_file; ConcatString s; - const ConcatString fcst_thresh = engine.conf_info.fcst_conv_thresh.get_str(5); - const ConcatString obs_thresh = engine.conf_info.obs_conv_thresh.get_str(5); + const ConcatString fcst_thresh = engine.conf_info.Fcst->conv_thresh.get_str(5); + const ConcatString obs_thresh = engine.conf_info.Obs->conv_thresh.get_str(5); float *fcst_raw_data = (float *) 0; float *fcst_obj_raw_data = (float *) 0; @@ -963,8 +958,8 @@ if ( info.all_false() ) return; // write the radius and threshold values // - if ( !put_nc_data(&fcst_radius_var, &engine.conf_info.fcst_conv_radius) - || !put_nc_data(&obs_radius_var, &engine.conf_info.obs_conv_radius) ) { + if ( !put_nc_data(&fcst_radius_var, &engine.conf_info.Fcst->conv_radius) + || !put_nc_data(&obs_radius_var, &engine.conf_info.Obs->conv_radius) ) { mlog << Error << "write_obj_netcdf() -> " @@ -989,15 +984,14 @@ if ( info.all_false() ) return; // fcst and obs values for variable, level and units // - nc_add_string(f_out, engine.conf_info.fcst_info->name_attr().c_str(), "fcst_variable", "fcst_variable_length"); - nc_add_string(f_out, engine.conf_info.obs_info->name_attr().c_str(), "obs_variable", "obs_variable_length"); - - nc_add_string(f_out, engine.conf_info.fcst_info->level_attr().c_str(), "fcst_level", "fcst_level_length"); - nc_add_string(f_out, engine.conf_info.obs_info->level_attr().c_str(), "obs_level", "obs_level_length"); + nc_add_string(f_out, engine.conf_info.Fcst->var_info->name_attr().c_str(), "fcst_variable", "fcst_variable_length"); + nc_add_string(f_out, engine.conf_info.Obs->var_info->name_attr().c_str(), "obs_variable", "obs_variable_length"); - nc_add_string(f_out, engine.conf_info.fcst_info->units_attr().c_str(), "fcst_units", "fcst_units_length"); - nc_add_string(f_out, engine.conf_info.obs_info->units_attr().c_str(), "obs_units", "obs_units_length"); + nc_add_string(f_out, engine.conf_info.Fcst->var_info->level_attr().c_str(), "fcst_level", "fcst_level_length"); + nc_add_string(f_out, engine.conf_info.Obs->var_info->level_attr().c_str(), "obs_level", "obs_level_length"); + nc_add_string(f_out, engine.conf_info.Fcst->var_info->units_attr().c_str(), "fcst_units", "fcst_units_length"); + nc_add_string(f_out, engine.conf_info.Obs->var_info->units_attr().c_str(), "obs_units", "obs_units_length"); // Add forecast variable attributes diff --git a/met/src/tools/core/mode/mode_exec.h b/met/src/tools/core/mode/mode_exec.h index ee20a83795..934f674a30 100644 --- a/met/src/tools/core/mode/mode_exec.h +++ b/met/src/tools/core/mode/mode_exec.h @@ -1,8 +1,3 @@ - - -//////////////////////////////////////////////////////////////////////// - - // ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) @@ -10,6 +5,7 @@ // ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + //////////////////////////////////////////////////////////////////////// @@ -45,6 +41,7 @@ using namespace netCDF; #include "mode_ps_file.h" + //////////////////////////////////////////////////////////////////////// @@ -158,4 +155,3 @@ inline int ModeExecutive::n_runs () const { return ( engine.conf_info.n_runs () ///////////////////////////////////////////////////////////////////////// - diff --git a/met/src/tools/core/mode/mode_frontend.cc b/met/src/tools/core/mode/mode_frontend.cc new file mode 100644 index 0000000000..1b8ce2937d --- /dev/null +++ b/met/src/tools/core/mode/mode_frontend.cc @@ -0,0 +1,345 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2019 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +/////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "string_array.h" + +#include "mode_usage.h" +#include "mode_exec.h" + +#ifdef WITH_PYTHON +#include "global_python.h" +#endif + + +/////////////////////////////////////////////////////////////////////// +// +// Create output files using the following naming convention: +// +// mode_YYYYMMDDI_FHH_HHA.ps/.txt +// +// Where I indicates initilization time, L indicates lead time, +// and A indicates accumulation time. +// +/////////////////////////////////////////////////////////////////////// + + +extern const char * const program_name; + +static ModeExecutive * mode_exec = 0; + + +/////////////////////////////////////////////////////////////////////// + + +static const char * default_out_dir = "."; + +static int compress_level = -1; + +static int field_index = -1; + + +/////////////////////////////////////////////////////////////////////// + + +static void do_quilt (); +static void do_straight (); + +static void process_command_line(const StringArray &); + + +static void set_config_merge_file (const StringArray &); +static void set_outdir (const StringArray &); +static void set_logfile (const StringArray &); +static void set_verbosity (const StringArray &); +static void set_compress (const StringArray &); + +static void set_field_index (const StringArray &); // undocumented + + +/////////////////////////////////////////////////////////////////////// + + +int mode_frontend(const StringArray & Argv) + +{ + + // + // Set handler to be called for memory allocation error + // + +set_new_handler(oom); + + // + // Process the command line arguments + // + +mode_exec = new ModeExecutive; + +process_command_line(Argv); + + + + // + // Process the forecast and observation files + // + +ModeConfInfo & conf = mode_exec->engine.conf_info; + +if ( field_index >= 0 ) conf.set_field_index(field_index); + +mode_exec->setup_fcst_obs_data(); + +if (compress_level >= 0) conf.nc_info.set_compress_level(compress_level); + + +if ( conf.quilt ) { + + do_quilt(); + +} else { + + do_straight(); + +} + +// mode_exec.clear(); + + // + // done + // + +#ifdef WITH_PYTHON + GP.finalize(); +#endif + +if ( mode_exec ) { delete mode_exec; mode_exec = 0; } + +return ( 0 ); + +} + + +/////////////////////////////////////////////////////////////////////// + + +void do_straight() + +{ + +const ModeConfInfo & conf = mode_exec->engine.conf_info; + +const int NCT = conf.n_conv_threshs(); +const int NCR = conf.n_conv_radii(); + +if ( NCT != NCR ) { + + mlog << Error + << "\n\n " + << program_name + << ": all convolution radius and threshold arrays must have the same number of elements!\n\n"; + + exit ( 1 ); + +} + +int index; + +for (index=0; indexdo_conv_thresh(index, index); + + mode_exec->do_match_merge(); + + mode_exec->process_output(); + +} + + + // + // done + // + +return; + +} + + +/////////////////////////////////////////////////////////////////////// + + +void do_quilt() + +{ + +int t_index, r_index; // indices into the convolution threshold and radius arrays + + +for (r_index=0; r_index<(mode_exec->n_conv_radii()); ++r_index) { + + for (t_index=0; t_index<(mode_exec->n_conv_threshs()); ++t_index) { + + mode_exec->do_conv_thresh(r_index, t_index); + + mode_exec->do_match_merge(); + + mode_exec->process_output(); + + } + +} + + // + // done + // + +return; + +} + + +/////////////////////////////////////////////////////////////////////// + + +void process_command_line(const StringArray & argv) + +{ + + CommandLine cline; + ConcatString s; + const int argc = argv.n(); + + + // Set the default output directory + mode_exec->out_dir = replace_path(default_out_dir); + + // Check for zero arguments + if(argc == 1) singlevar_usage(); + + // Parse the command line into tokens + cline.set(argv); + + // Set the usage function + cline.set_usage(singlevar_usage); + + // Add the options function calls + cline.add(set_config_merge_file, "-config_merge", 1); + cline.add(set_outdir, "-outdir", 1); + cline.add(set_logfile, "-log", 1); + cline.add(set_verbosity, "-v", 1); + cline.add(set_compress, "-compress", 1); + + // + // add for mode multivar ... undocumented + // + + cline.add(set_field_index, "-field_index", 1); + + // Parse the command line + cline.parse(); + + // Check for error. There should be three arguments left: + // forecast, observation, and config filenames + if(cline.n() != 3) singlevar_usage(); + + // Store the input forecast and observation file names + mode_exec->fcst_file = cline[0]; + mode_exec->obs_file = cline[1]; + mode_exec->match_config_file = cline[2]; + + mode_exec->init(); + + return; + +} + +/////////////////////////////////////////////////////////////////////// + +void set_config_merge_file(const StringArray & a) +{ + mode_exec->merge_config_file = a[0]; +} + +//////////////////////////////////////////////////////////////////////// + +void set_outdir(const StringArray & a) +{ + mode_exec->out_dir = a[0]; +} + +//////////////////////////////////////////////////////////////////////// + +void set_logfile(const StringArray & a) +{ + ConcatString filename; + + filename = a[0]; + + mlog.open_log_file(filename); +} + +//////////////////////////////////////////////////////////////////////// + +void set_verbosity(const StringArray & a) +{ + mlog.set_verbosity_level(atoi(a[0].c_str())); +} + +//////////////////////////////////////////////////////////////////////// + +void set_compress(const StringArray & a) { + compress_level = atoi(a[0].c_str()); +} + +//////////////////////////////////////////////////////////////////////// + + +void set_field_index(const StringArray & a) + +{ + +field_index = atoi(a[0].c_str()); + +if ( field_index < 0 ) { + + mlog << Error + << program_name << ": bad index value ... " + << field_index << "\n\n"; + + exit ( 1 ); + +} + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + + diff --git a/met/src/tools/core/mode/mode_multivar.cc b/met/src/tools/core/mode/mode_multivar.cc new file mode 100644 index 0000000000..aa4174c6e7 --- /dev/null +++ b/met/src/tools/core/mode/mode_multivar.cc @@ -0,0 +1,335 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2019 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +/////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mode_usage.h" +#include "mode_exec.h" + +#ifdef WITH_PYTHON +#include "global_python.h" +#endif + + +/////////////////////////////////////////////////////////////////////// +// +// Create output files using the following naming convention: +// +// mode_YYYYMMDDI_FHH_HHA.ps/.txt +// +// Where I indicates initilization time, L indicates lead time, +// and A indicates accumulation time. +// +/////////////////////////////////////////////////////////////////////// + + +extern const char * const program_name; + +static ModeExecutive mode_exec; // gotta make this global ... not sure why + + +/////////////////////////////////////////////////////////////////////// + + +static const char * default_out_dir = "."; + +static int compress_level = -1; + +static int field_index = -1; + + +/////////////////////////////////////////////////////////////////////// + + +static void do_quilt (); +static void do_straight (); + +static void process_command_line(int, char **); + +static void set_config_merge_file (const StringArray &); +static void set_outdir (const StringArray &); +static void set_logfile (const StringArray &); +static void set_verbosity (const StringArray &); +static void set_compress (const StringArray &); + +static void set_field_index (const StringArray &); // undocumented + + +/////////////////////////////////////////////////////////////////////// + + +int main_multivar(int argc, char * argv []) + +{ + + // + // Set handler to be called for memory allocation error + // + +set_new_handler(oom); + + // + // Process the command line arguments + // + +process_command_line(argc, argv); + + // + // Process the forecast and observation files + // + +ModeConfInfo & conf = mode_exec.engine.conf_info; + +if ( field_index >= 0 ) conf.set_field_index(field_index); + +mode_exec.setup_fcst_obs_data(); + +if (compress_level >= 0) conf.nc_info.set_compress_level(compress_level); + + +if ( conf.quilt ) { + + do_quilt(); + +} else { + + do_straight(); + +} + +mode_exec.clear(); + + // + // done + // + +#ifdef WITH_PYTHON + GP.finalize(); +#endif + +return ( 0 ); + +} + + +/////////////////////////////////////////////////////////////////////// + + +void do_straight() + +{ + +const ModeConfInfo & conf = mode_exec.engine.conf_info; + +const int NCT = conf.n_conv_threshs(); +const int NCR = conf.n_conv_radii(); + +if ( NCT != NCR ) { + + mlog << Error + << "\n\n " + << program_name + << ": all convolution radius and threshold arrays must have the same number of elements!\n\n"; + + exit ( 1 ); + +} + +int index; + +for (index=0; indexmet_data_dir; ConcatString s; - s = replace_path(ConfInfo->fcst_raw_pi.color_table.c_str()); + s = replace_path(ConfInfo->Fcst->raw_pi.color_table.c_str()); mlog << Debug(1) << "Loading forecast raw color table: " << s << "\n"; FcstRawCtable.read(s.c_str()); - s = replace_path(ConfInfo->obs_raw_pi.color_table.c_str()); + s = replace_path(ConfInfo->Obs->raw_pi.color_table.c_str()); mlog << Debug(1) << "Loading observation raw color table: " << s << "\n"; @@ -208,7 +209,7 @@ mlog << Debug(1) << "Loading observation raw color table: " << s << "\n"; // data_min and data_max values // -if ( (ConfInfo->fcst_info->name_attr() == ConfInfo->obs_info->name_attr()) && +if ( (ConfInfo->Fcst->var_info->name_attr() == ConfInfo->Obs->var_info->name_attr()) && is_eq( FcstRawCtable.data_min (bad_data_double), 0.0) && is_eq( FcstRawCtable.data_max (bad_data_double), 1.0) && is_eq( ObsRawCtable.data_min (bad_data_double), 0.0) && @@ -249,11 +250,11 @@ if ( (ConfInfo->fcst_info->name_attr() == ConfInfo->obs_info->name_attr()) && // config file, rescale the forecast colortable to the requested range // -if ( !is_eq(ConfInfo->fcst_raw_pi.plot_min, 0.0) || - !is_eq(ConfInfo->fcst_raw_pi.plot_max, 0.0) ) { +if ( !is_eq(ConfInfo->Fcst->raw_pi.plot_min, 0.0) || + !is_eq(ConfInfo->Fcst->raw_pi.plot_max, 0.0) ) { - FcstRawCtable.rescale(ConfInfo->fcst_raw_pi.plot_min, - ConfInfo->fcst_raw_pi.plot_max, + FcstRawCtable.rescale(ConfInfo->Fcst->raw_pi.plot_min, + ConfInfo->Fcst->raw_pi.plot_max, bad_data_double); } @@ -263,11 +264,11 @@ if ( !is_eq(ConfInfo->fcst_raw_pi.plot_min, 0.0) || // config file, rescale the observation colortable to the requested range // -if ( !is_eq(ConfInfo->obs_raw_pi.plot_min, 0.0) || - !is_eq(ConfInfo->obs_raw_pi.plot_max, 0.0) ) { +if ( !is_eq(ConfInfo->Obs->raw_pi.plot_min, 0.0) || + !is_eq(ConfInfo->Obs->raw_pi.plot_max, 0.0) ) { - ObsRawCtable.rescale(ConfInfo->obs_raw_pi.plot_min, - ConfInfo->obs_raw_pi.plot_max, + ObsRawCtable.rescale(ConfInfo->Obs->raw_pi.plot_min, + ConfInfo->Obs->raw_pi.plot_max, bad_data_double); } @@ -541,15 +542,15 @@ void ModePsFile::make_plot() { -const MergeType fcst_merge_flag = ConfInfo->fcst_merge_flag; -const MergeType obs_merge_flag = ConfInfo->obs_merge_flag; +const MergeType fcst_merge_flag = ConfInfo->Fcst->merge_flag; +const MergeType obs_merge_flag = ConfInfo->Obs->merge_flag; ConcatString s; s << cs_erase - << "MODE: " << ConfInfo->fcst_info->name_attr() << " at " - << ConfInfo->fcst_info->level_attr() << " vs " - << ConfInfo->obs_info->name_attr() << " at " - << ConfInfo->obs_info->level_attr(); + << "MODE: " << ConfInfo->Fcst->var_info->name_attr() << " at " + << ConfInfo->Fcst->var_info->level_attr() << " vs " + << ConfInfo->Obs->var_info->name_attr() << " at " + << ConfInfo->Obs->var_info->level_attr(); plot_engine(*Engine, FOEng, s.c_str()); @@ -602,12 +603,12 @@ const double h_tab_cen = PageWidth/2.0; if ( fcst ) { merge_mask = *(eng.fcst_conv); - merge_mask.threshold(eng.conf_info.fcst_merge_thresh); + merge_mask.threshold(eng.conf_info.Fcst->merge_thresh); } else { merge_mask = *(eng.obs_conv); - merge_mask.threshold(eng.conf_info.obs_merge_thresh); + merge_mask.threshold(eng.conf_info.Obs->merge_thresh); } diff --git a/met/src/tools/core/mode/mode_ps_file.h b/met/src/tools/core/mode/mode_ps_file.h index 92749b9b46..4bcb213365 100644 --- a/met/src/tools/core/mode/mode_ps_file.h +++ b/met/src/tools/core/mode/mode_ps_file.h @@ -202,5 +202,3 @@ inline void ModePsFile::nextline() { text_y -= TextSep; return; } //////////////////////////////////////////////////////////////////////// - - diff --git a/met/src/tools/core/mode/mode_ps_table_defs.h b/met/src/tools/core/mode/mode_ps_table_defs.h index e60f90d764..35ebecf99b 100644 --- a/met/src/tools/core/mode/mode_ps_table_defs.h +++ b/met/src/tools/core/mode/mode_ps_table_defs.h @@ -1,8 +1,4 @@ - - -//////////////////////////////////////////////////////////////////////// - - +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) @@ -49,5 +45,3 @@ static Color dark_gray = blend_colors(white, black, 0.50); //////////////////////////////////////////////////////////////////////// - - diff --git a/met/src/tools/core/mode/mode_singlevar.cc b/met/src/tools/core/mode/mode_singlevar.cc new file mode 100644 index 0000000000..fc747ba499 --- /dev/null +++ b/met/src/tools/core/mode/mode_singlevar.cc @@ -0,0 +1,335 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2019 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mode_usage.h" +#include "mode_exec.h" + +#ifdef WITH_PYTHON +#include "global_python.h" +#endif + + +/////////////////////////////////////////////////////////////////////// +// +// Create output files using the following naming convention: +// +// mode_YYYYMMDDI_FHH_HHA.ps/.txt +// +// Where I indicates initilization time, L indicates lead time, +// and A indicates accumulation time. +// +/////////////////////////////////////////////////////////////////////// + + +extern const char * const program_name; + +static ModeExecutive mode_exec; // gotta make this global ... not sure why + + +/////////////////////////////////////////////////////////////////////// + + +static const char * default_out_dir = "."; + +static int compress_level = -1; + +static int field_index = -1; + + +/////////////////////////////////////////////////////////////////////// + + +static void do_quilt (); +static void do_straight (); + +static void process_command_line(int, char **); + +static void set_config_merge_file (const StringArray &); +static void set_outdir (const StringArray &); +static void set_logfile (const StringArray &); +static void set_verbosity (const StringArray &); +static void set_compress (const StringArray &); + +static void set_field_index (const StringArray &); // undocumented + + +/////////////////////////////////////////////////////////////////////// + + +int main_singlevar(int argc, char * argv []) + +{ + + // + // Set handler to be called for memory allocation error + // + +set_new_handler(oom); + + // + // Process the command line arguments + // + +process_command_line(argc, argv); + + // + // Process the forecast and observation files + // + +ModeConfInfo & conf = mode_exec.engine.conf_info; + +if ( field_index >= 0 ) conf.set_field_index(field_index); + +mode_exec.setup_fcst_obs_data(); + +if (compress_level >= 0) conf.nc_info.set_compress_level(compress_level); + + +if ( conf.quilt ) { + + do_quilt(); + +} else { + + do_straight(); + +} + +mode_exec.clear(); + + // + // done + // + +#ifdef WITH_PYTHON + GP.finalize(); +#endif + +return ( 0 ); + +} + + +/////////////////////////////////////////////////////////////////////// + + +void do_straight() + +{ + +const ModeConfInfo & conf = mode_exec.engine.conf_info; + +const int NCT = conf.n_conv_threshs(); +const int NCR = conf.n_conv_radii(); + +if ( NCT != NCR ) { + + mlog << Error + << "\n\n " + << program_name + << ": all convolution radius and threshold arrays must have the same number of elements!\n\n"; + + exit ( 1 ); + +} + +int index; + +for (index=0; index + +#include "mode_usage.h" +#include "mode_exec.h" + +#include "util_constants.h" +#include "logger.h" + + +//////////////////////////////////////////////////////////////////////// + + +extern const char * const program_name; + +extern ModeExecutive mode_exec; + + +//////////////////////////////////////////////////////////////////////// + + +void both_usage() + +{ + + +cout << "\n*** Model Evaluation Tools (MET" << met_version << ") ***\n\n"; + +cout << "Single Variable MODE:\n" + "=====================\n"; + +singlevar_usage(); + +cout << "Multi Variable MODE:\n" + << "====================\n"; + +multivar_usage(); + +exit ( 1 ); + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void singlevar_usage() + +{ + +cout << "\n\n" + << "Usage: " << program_name << "\n" + << "\tfcst_file\n" + << "\tobs_file\n" + << "\tconfig_file\n" + << "\t[-config_merge merge_config_file]\n" + << "\t[-outdir path]\n" + << "\t[-log file]\n" + << "\t[-v level]\n" + << "\t[-compress level]\n\n" + + << "\twhere\n" + + << "\t\t\"fcst_file\" is a gridded forecast file " + << "containing the field to be verified (required).\n" + + << "\t\t\"obs_file\" is a gridded observation file " + << "containing the verifying field (required).\n" + + << "\t\t\"config_file\" is a MODEConfig file " + << "containing the desired configuration settings (required).\n" + + << "\t\t\"-config_merge merge_config_file\" overrides the default " + << "fuzzy engine settings for merging within the fcst/obs fields " + << "(optional).\n" + + << "\t\t\"-outdir path\" overrides the default output directory " + << "(./) (optional).\n" + + << "\t\t\"-log file\" outputs log messages to the specified " + << "file (optional).\n" + + << "\t\t\"-v level\" overrides the default level of logging (" + << mlog.verbosity_level() << ") (optional).\n" + + << "\t\t\"-compress level\" overrides the compression level of " + << "NetCDF variable (optional).\n\n" + + << flush; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void multivar_usage() + +{ + +cout << "\n\n" + << "\tUsage: " << program_name << "\n" + << "\tfcst_file_list\n" + << "\tobs_file_list\n" + << "\tconfig_file\n" + << "\t[-outdir path]\n" + << "\t[-log file]\n" + << "\t[-v level]\n" + + << "\twhere\n" + + << "\t\t\"fcst_file_list\" is an ASCII file containing a list of " + << "forecast files to be used (required).\n" + + << "\t\t\"obs_file_list\" is an ASCII file containing a list of " + << "observation files to be used (required).\n" + + << "\t\t\"config\" is a MODEConfig file containing the desired " + << "configuration settings (required).\n" + + << "\t\t\"-outdir path\" overrides the default output directory " + << "(./) (optional).\n" + + << "\t\t\"-log file\" outputs log messages to the specified file " + << "(optional).\n" + + << "\t\t\"-v level\" overrides the default level of logging (" + << mlog.verbosity_level() << ") (optional).\n\n" + + << flush; + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/core/mode/mode_usage.h b/met/src/tools/core/mode/mode_usage.h new file mode 100644 index 0000000000..441c924a80 --- /dev/null +++ b/met/src/tools/core/mode/mode_usage.h @@ -0,0 +1,33 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2022 +// ** 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 __MODE_USAGE_H__ +#define __MODE_USAGE_H__ + + +//////////////////////////////////////////////////////////////////////// + + +extern void both_usage(); + +extern void singlevar_usage(); + +extern void multivar_usage(); + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MODE_USAGE_H__ */ + + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/tools/core/mode/multivar_frontend.cc b/met/src/tools/core/mode/multivar_frontend.cc new file mode 100644 index 0000000000..5d4e9b4bfc --- /dev/null +++ b/met/src/tools/core/mode/multivar_frontend.cc @@ -0,0 +1,568 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2022 +// ** 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 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +//////////////////////////////////////////////////////////////////////// + + +static const char fcst_super_nc_filename [] = "f_super.nc"; +static const char obs_super_nc_filename [] = "o_super.nc"; + +static const char mode_default_config [] = "MET_BASE/config/MODEConfig_default"; + +static const char super_object_var_name [] = "super"; + +static const int dir_creation_mode = 0755; + +static const float on_value = (float) 100.0; +static const float off_value = (float) 0.0; + + +//////////////////////////////////////////////////////////////////////// + + +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "vx_util.h" +#include "file_exists.h" +#include "two_d_array.h" +#include "get_filenames.h" +#include "mode_conf_info.h" +#include "shapedata.h" +#include "interest.h" +#include "met_file.h" +#include "mode_usage.h" +#include "mode_exec.h" + +#include "combine_boolplanes.h" +#include "objects_from_netcdf.h" +#include "parse_file_list.h" + + +using namespace netCDF; + + +//////////////////////////////////////////////////////////////////////// + + +extern int mode_frontend(const StringArray &); + + +//////////////////////////////////////////////////////////////////////// + + +extern const char * const program_name; + + +static const char sep [] = "===================================================="; + +static const char tab [] = " "; + +static const bool do_clusters = false; + +static ModeConfInfo config; + +static string mode_path; +static string fcst_fof; +static string obs_fof; +static string config_file; +static string outdir; + + +//////////////////////////////////////////////////////////////////////// + + +static void set_outdir (const StringArray &); +static void set_logfile (const StringArray &); +static void set_verbosity (const StringArray &); + + +static void read_config(const string & filename); + +static void run_command(const ConcatString & command); + +static void process_command_line(const StringArray &); + +static void write_output_nc_file(const char * path, const MetNcFile &, const BoolPlane &); + + +//////////////////////////////////////////////////////////////////////// + + +int multivar_frontend(const StringArray & Argv) + +{ + +const int Argc = Argv.n(); + +if ( Argc < 4 ) multivar_usage(); + +int j; +StringArray fcst_filenames; +StringArray obs_filenames; +ConcatString dir; + + +process_command_line(Argv); + + +read_config(config_file); + +if ( config.fcst_multivar_logic.empty() ) { + + mlog << Error << "\n" << program_name + << ": fcst multivar logic not specified!\n\n"; + + exit ( 1 ); + +} + + +if ( config.obs_multivar_logic.empty() ) { + + mlog << Error << "\n" << program_name + << ": obs multivar logic not specified!\n\n"; + + exit ( 1 ); + +} + + // + // make sure the multivar logic programs are in the config file + // + +fcst_filenames = parse_ascii_file_list(fcst_fof.c_str()); + obs_filenames = parse_ascii_file_list(obs_fof.c_str()); + +if ( fcst_filenames.n() != obs_filenames.n() ) { + + mlog << Error << "\n" << program_name + << ": number of fcst and obs files should be the same!\n\n"; + + exit ( 1 ); + +} + +const int n_files = fcst_filenames.n(); +ConcatString mode_args; +ConcatString command; +StringArray a, nc_files, mode_argv; +int status; +char junk [256]; + +mlog << Debug(2) << "\n" << sep << "\n"; + + // + // check for no inputs + // + +if ( n_files == 0 ) { + + mlog << Error << "\n" << program_name + << ": no input forecast files to process!\n\n"; + + exit ( 1 ); + +} + + // + // do the individual mode runs + // + +for (j=0; j 0 ) dir << outdir << '/'; + + snprintf(junk, sizeof(junk), "%02d", j); + + dir << junk; + + if ( ! directory_exists(dir.c_str()) ) { + + mlog << Debug(2) + << program_name << ": creating output directory \"" + << dir << "\"\n\n"; + + status = mkdir(dir.c_str(), dir_creation_mode); + + if ( status < 0 ) { + + mlog << Error << "\n" << program_name + << ": unable to create output directory \"" + << dir << "\"\n\n"; + + exit ( 1 ); + + } + + } + + // + // build the command for running mode + // + + mode_argv.clear(); + + mode_argv.add(mode_path); + mode_argv.add(fcst_filenames[j]); + mode_argv.add(obs_filenames[j]); + mode_argv.add(config_file); + + command << cs_erase + << mode_path << ' ' + << fcst_filenames[j] << ' ' + << obs_filenames[j] << ' ' + << config_file; + + mode_argv.add("-v"); + snprintf(junk, sizeof(junk), "%d", mlog.verbosity_level()); + mode_argv.add(junk); + + mode_argv.add("-outdir"); + mode_argv.add(dir); + + command << " -v " << mlog.verbosity_level(); + + command << " -outdir " << dir; + + mode_argv.add("-field_index"); + snprintf(junk, sizeof(junk), "%d", j); + mode_argv.add(junk); + + command << " -field_index " << j; + + // + // run mode + // + + mlog << Debug(1) << "Running mode command: \"" << command << "\"\n\n"; + + run_command(command); + + // [TODO] MET #1238: run MODE in memory instead of via system calls. + // (void) mode_frontend(mode_argv); + + mlog << Debug(2) << "\n finished mode run " << (j + 1) << " of " << n_files + << "\n" << sep << "\n"; + + a = get_filenames_from_dir(dir.text(), "mode_", ".nc"); + + nc_files.add(a); + +} // for j + +mlog << Debug(2) << "\n finished with individual mode runs " + << "\n" << sep << "\n"; + +BoolPlane * f_plane = new BoolPlane [n_files]; +BoolPlane * o_plane = new BoolPlane [n_files]; +BoolPlane f_result, o_result; +Pgm image; + + // + // load the objects from the mode output files + // + +for (j=0; j vdim(2); + + +for (x=0; x + +#include "objects_from_netcdf.h" + + +//////////////////////////////////////////////////////////////////////// + + +using namespace netCDF; + + +//////////////////////////////////////////////////////////////////////// + + + // + // these don't seem to be collected in any header file + // + // that I could find + // + + +static const string lat_dim_name = "lat"; +static const string lon_dim_name = "lon"; + +static const string fcst_simple_id_var_name = "fcst_obj_id"; +static const string obs_simple_id_var_name = "obs_obj_id"; + +static const string fcst_cluster_id_var_name = "fcst_clus_id"; +static const string obs_cluster_id_var_name = "obs_clus_id"; + + +//////////////////////////////////////////////////////////////////////// + + +static void populate_bool_plane(const int * buf, const int nx, const int ny, BoolPlane & bp_out); + + +//////////////////////////////////////////////////////////////////////// + + +void objects_from_netcdf(const char * netcdf_filename, + bool do_clusters, // do we look at cluster objects or simple objects? + BoolPlane & fcst_out, + BoolPlane & obs_out) + +{ + +int * buf = 0; +const string * fcst_var_name = 0; +const string * obs_var_name = 0; + +if ( do_clusters ) { + + fcst_var_name = &fcst_cluster_id_var_name; + obs_var_name = &obs_cluster_id_var_name; + +} else { + + fcst_var_name = &fcst_simple_id_var_name; + obs_var_name = &obs_simple_id_var_name; + +} + + + // + // open the netcdf file + // + +NcFile nc((std::string) netcdf_filename, NcFile::read); + + // + // grab the lat/lon dimensions + // + +NcDim lat_dim, lon_dim; + +lat_dim = nc.getDim(lat_dim_name); +lon_dim = nc.getDim(lon_dim_name); + + // + // use the lat/lon dimensions to set the size of the bool planes + // + +const int n_lat = (int) lat_dim.getSize(); +const int n_lon = (int) lon_dim.getSize(); +const int nx = n_lon; +const int ny = n_lat; + +buf = new int [nx*ny]; + + // + // grab the netcdf variables + // + +NcVar f_var, o_var; + +f_var = nc.getVar(*fcst_var_name); +o_var = nc.getVar( *obs_var_name); + + // + // populate the bool planes + // + +f_var.getVar(buf); + +populate_bool_plane(buf, nx, ny, fcst_out); + +o_var.getVar(buf); + +populate_bool_plane(buf, nx, ny, obs_out); + + // + // done + // + +if ( buf ) { delete [] buf; buf = 0; } + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + +void populate_bool_plane(const int * buf, const int nx, const int ny, BoolPlane & bp_out) + +{ + +int x, y, n, k; +bool tf; + +bp_out.set_size(nx, ny); + +for (x=0; x 0 ); + + bp_out.put(tf, x, y); + + } // for y + +} // for x + + + + +return; + +} + + +//////////////////////////////////////////////////////////////////////// + + + diff --git a/met/src/tools/core/mode/objects_from_netcdf.h b/met/src/tools/core/mode/objects_from_netcdf.h new file mode 100644 index 0000000000..aa6e8e1fb1 --- /dev/null +++ b/met/src/tools/core/mode/objects_from_netcdf.h @@ -0,0 +1,49 @@ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2022 +// ** 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 __MODE_OBJECTS_FROM_NETCDF_H__ +#define __MODE_OBJECTS_FROM_NETCDF_H__ + + +//////////////////////////////////////////////////////////////////////// + + +#include "two_d_array.h" + + +//////////////////////////////////////////////////////////////////////// + + + // + // grabs the objects from a MODE output netcdf file + // + + +//////////////////////////////////////////////////////////////////////// + + +extern void objects_from_netcdf(const char * netcdf_filename, + bool do_clusters, // do we look at cluster objects or simple objects? + BoolPlane & fcst_out, + BoolPlane & obs_out); + + + +//////////////////////////////////////////////////////////////////////// + + +#endif /* __MODE_OBJECTS_FROM_NETCDF_H__ */ + + +//////////////////////////////////////////////////////////////////////// + + diff --git a/met/src/tools/core/mode/page_1.cc b/met/src/tools/core/mode/page_1.cc index 4d1d23e636..a72442dc99 100644 --- a/met/src/tools/core/mode/page_1.cc +++ b/met/src/tools/core/mode/page_1.cc @@ -332,8 +332,8 @@ t1.write_xy1_to_cell(1, 2, 0.0, dy, 0.5, 0.0, eng.conf_info.model.c_str()); nextline(); -t1.write_xy1_to_cell(2, 1, dx, dy, 0.0, 0.0, eng.conf_info.fcst_info->name_attr().c_str()); -t1.write_xy1_to_cell(2, 2, dx, dy, 0.0, 0.0, eng.conf_info.obs_info->name_attr().c_str()); +t1.write_xy1_to_cell(2, 1, dx, dy, 0.0, 0.0, eng.conf_info.Fcst->var_info->name_attr().c_str()); +t1.write_xy1_to_cell(2, 2, dx, dy, 0.0, 0.0, eng.conf_info.Obs->var_info->name_attr().c_str()); // // Level Name @@ -341,8 +341,8 @@ t1.write_xy1_to_cell(2, 2, dx, dy, 0.0, 0.0, eng.conf_info.obs_info->name_attr() nextline(); -t1.write_xy1_to_cell(3, 1, dx, dy, 0.0, 0.0, eng.conf_info.fcst_info->level_attr().c_str()); -t1.write_xy1_to_cell(3, 2, dx, dy, 0.0, 0.0, eng.conf_info.obs_info->level_attr().c_str()); +t1.write_xy1_to_cell(3, 1, dx, dy, 0.0, 0.0, eng.conf_info.Fcst->var_info->level_attr().c_str()); +t1.write_xy1_to_cell(3, 2, dx, dy, 0.0, 0.0, eng.conf_info.Obs->var_info->level_attr().c_str()); // // Units @@ -350,8 +350,8 @@ t1.write_xy1_to_cell(3, 2, dx, dy, 0.0, 0.0, eng.conf_info.obs_info->level_attr( nextline(); -t1.write_xy1_to_cell(4, 1, dx, dy, 0.0, 0.0, eng.conf_info.fcst_info->units_attr().c_str()); -t1.write_xy1_to_cell(4, 2, dx, dy, 0.0, 0.0, eng.conf_info.obs_info->units_attr().c_str()); +t1.write_xy1_to_cell(4, 1, dx, dy, 0.0, 0.0, eng.conf_info.Fcst->var_info->units_attr().c_str()); +t1.write_xy1_to_cell(4, 2, dx, dy, 0.0, 0.0, eng.conf_info.Obs->var_info->units_attr().c_str()); // // Initialization Time @@ -720,10 +720,10 @@ roman(); // // Convolution Radius // - snprintf(junk, sizeof(junk), "%d", eng.conf_info.fcst_conv_radius); + snprintf(junk, sizeof(junk), "%d", eng.conf_info.Fcst->conv_radius); t.write_xy1_to_cell(r, 1, dx, dy, 0.0, 0.0, junk); - snprintf(junk, sizeof(junk), "%d", eng.conf_info.obs_conv_radius); + snprintf(junk, sizeof(junk), "%d", eng.conf_info.Obs->conv_radius); t.write_xy1_to_cell(r, 2, dx, dy, 0.0, 0.0, junk); ++r; @@ -732,10 +732,10 @@ roman(); // // Convolution Threshold // - thresh_str = eng.conf_info.fcst_conv_thresh.get_str(2); + thresh_str = eng.conf_info.Fcst->conv_thresh.get_str(2); t.write_xy1_to_cell(r, 1, dx, dy, 0.0, 0.0, thresh_str.c_str()); - thresh_str = eng.conf_info.obs_conv_thresh.get_str(2); + thresh_str = eng.conf_info.Obs->conv_thresh.get_str(2); t.write_xy1_to_cell(r, 2, dx, dy, 0.0, 0.0, thresh_str.c_str()); ++r; @@ -745,10 +745,10 @@ roman(); // Object Filters // - snprintf(junk, sizeof(junk), "%i", (int) eng.conf_info.fcst_filter_attr_map.size()); + snprintf(junk, sizeof(junk), "%i", (int) eng.conf_info.Fcst->filter_attr_map.size()); t.write_xy1_to_cell(r, 1, dx, dy, 0.0, 0.0, junk); - snprintf(junk, sizeof(junk), "%i", (int) eng.conf_info.obs_filter_attr_map.size()); + snprintf(junk, sizeof(junk), "%i", (int) eng.conf_info.Obs->filter_attr_map.size()); t.write_xy1_to_cell(r, 2, dx, dy, 0.0, 0.0, junk); ++r; @@ -773,10 +773,10 @@ roman(); // Merge Threshold // - thresh_str = eng.conf_info.fcst_merge_thresh.get_str(2); + thresh_str = eng.conf_info.Fcst->merge_thresh.get_str(2); t.write_xy1_to_cell(r, 1, dx, dy, 0.0, 0.0, thresh_str.c_str()); - thresh_str = eng.conf_info.obs_merge_thresh.get_str(2); + thresh_str = eng.conf_info.Obs->merge_thresh.get_str(2); t.write_xy1_to_cell(r, 2, dx, dy, 0.0, 0.0, thresh_str.c_str()); ++r; @@ -792,15 +792,15 @@ roman(); // Merging flag // - if(eng.conf_info.fcst_merge_flag == MergeType_Thresh) label = "thresh"; - else if(eng.conf_info.fcst_merge_flag == MergeType_Engine) label = "engine"; - else if(eng.conf_info.fcst_merge_flag == MergeType_Both) label = "thresh/engine"; + if(eng.conf_info.Fcst->merge_flag == MergeType_Thresh) label = "thresh"; + else if(eng.conf_info.Fcst->merge_flag == MergeType_Engine) label = "engine"; + else if(eng.conf_info.Fcst->merge_flag == MergeType_Both) label = "thresh/engine"; else label = "none"; t.write_xy1_to_cell(r, 1, dx, dy, 0.0, 0.0, label.c_str()); - if(eng.conf_info.obs_merge_flag == MergeType_Thresh) label = "thresh"; - else if(eng.conf_info.obs_merge_flag == MergeType_Engine) label = "engine"; - else if(eng.conf_info.obs_merge_flag == MergeType_Both) label = "thresh/engine"; + if(eng.conf_info.Obs->merge_flag == MergeType_Thresh) label = "thresh"; + else if(eng.conf_info.Obs->merge_flag == MergeType_Engine) label = "engine"; + else if(eng.conf_info.Obs->merge_flag == MergeType_Both) label = "thresh/engine"; else label = "none"; t.write_xy1_to_cell(r, 2, dx, dy, 0.0, 0.0, label.c_str()); diff --git a/test/bin/unit_test.sh b/test/bin/unit_test.sh index 0c95bba7ac..eff6bc65da 100755 --- a/test/bin/unit_test.sh +++ b/test/bin/unit_test.sh @@ -55,6 +55,7 @@ UNIT_XML="unit_ascii2nc.xml \ unit_ensemble_stat.xml \ unit_stat_analysis_es.xml \ unit_mode.xml \ + unit_mode_multivar.xml \ unit_mode_analysis.xml \ unit_plot_point_obs.xml \ unit_plot_data_plane.xml \ diff --git a/test/config/MODEConfig_multivar_fake_data b/test/config/MODEConfig_multivar_fake_data new file mode 100644 index 0000000000..282d7e7ec7 --- /dev/null +++ b/test/config/MODEConfig_multivar_fake_data @@ -0,0 +1,259 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// MODE configuration file. +// +// For additional information, please see the MET User's Guide. +// +//////////////////////////////////////////////////////////////////////////////// + +// +// Output model name to be written +// +model = "WRF"; + +// +// Output description to be written +// +desc = "NA"; + +// +// Output observation type to be written +// +obtype = "PRECIP"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; + shape = SQUARE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Approximate grid resolution (km) +// +grid_res = 20; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Run all permutations of radius and threshold +// +quilt = FALSE; + +// +// MODE Multivar boolean combination logic +// +multivar_logic = "#1 && #2 && #3"; + +// +// Forecast and observation fields to be verified +// +fcst = { + + field = [ + + { + name = "ALPHA"; + level = "(*,*)"; + }, + + { + name = "BETA"; + level = "(*,*)"; + }, + + { + name = "GAMMA"; + level = "(*,*)"; + } + + ]; + + conv_radius = 2; // in grid squares + conv_thresh = >=5.0; + vld_thresh = 0.5; + filter_attr_name = []; + filter_attr_thresh = []; + merge_thresh = >=3.5; + merge_flag = NONE; +} +obs = fcst; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Handle missing data +// +mask_missing_flag = NONE; + +// +// Match objects between the forecast and observation fields +// +match_flag = NONE; + +// +// Maximum centroid distance for objects to be compared +// +max_centroid_dist = 800.0/grid_res; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification masking regions +// +mask = { + grid = ""; + grid_flag = NONE; // Apply to NONE, FCST, OBS, or BOTH + poly = ""; + poly_flag = NONE; // Apply to NONE, FCST, OBS, or BOTH +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Fuzzy engine weights +// +weight = { + centroid_dist = 2.0; + boundary_dist = 4.0; + convex_hull_dist = 0.0; + angle_diff = 1.0; + aspect_diff = 0.0; + area_ratio = 1.0; + int_area_ratio = 2.0; + curvature_ratio = 0.0; + complexity_ratio = 0.0; + inten_perc_ratio = 0.0; + inten_perc_value = 50; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Fuzzy engine interest functions +// +interest_function = { + + centroid_dist = ( + ( 0.0, 1.0 ) + ( 60.0/grid_res, 1.0 ) + ( 600.0/grid_res, 0.0 ) + ); + + boundary_dist = ( + ( 0.0, 1.0 ) + ( 400.0/grid_res, 0.0 ) + ); + + convex_hull_dist = ( + ( 0.0, 1.0 ) + ( 400.0/grid_res, 0.0 ) + ); + + angle_diff = ( + ( 0.0, 1.0 ) + ( 30.0, 1.0 ) + ( 90.0, 0.0 ) + ); + + aspect_diff = ( + ( 0.00, 1.0 ) + ( 0.10, 1.0 ) + ( 0.75, 0.0 ) + ); + + corner = 0.8; + ratio_if = ( + ( 0.0, 0.0 ) + ( corner, 1.0 ) + ( 1.0, 1.0 ) + ); + + area_ratio = ratio_if; + + int_area_ratio = ( + ( 0.00, 0.00 ) + ( 0.10, 0.50 ) + ( 0.25, 1.00 ) + ( 1.00, 1.00 ) + ); + + curvature_ratio = ratio_if; + + complexity_ratio = ratio_if; + + inten_perc_ratio = ratio_if; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Total interest threshold for determining matches +// +total_interest_thresh = 0.7; + +// +// Interest threshold for printing output pair information +// +print_interest_thresh = 0.0; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Plotting information +// +met_data_dir = "MET_BASE"; + +fcst_raw_plot = { + color_table = "MET_BASE/colortables/met_default.ctable"; + plot_min = 0.0; + plot_max = 25.4; +} + +obs_raw_plot = { + color_table = "MET_BASE/colortables/met_default.ctable"; + plot_min = 0.0; + plot_max = 25.4; +} + +object_plot = { + color_table = "MET_BASE/colortables/mode_obj.ctable"; +} + +// +// Boolean for plotting on the region of valid data within the domain +// +plot_valid_flag = FALSE; + +// +// Plot polyline edges using great circle arcs instead of straight lines +// +plot_gcarc_flag = FALSE; + +//////////////////////////////////////////////////////////////////////////////// + +// +// NetCDF matched pairs, PostScript, and contingency table output files +// +ps_plot_flag = TRUE; +nc_pairs_flag = TRUE; +ct_stats_flag = TRUE; + +//////////////////////////////////////////////////////////////////////////////// + +shift_right = 0; // grid squares + +//////////////////////////////////////////////////////////////////////////////// + +output_prefix = ""; +version = "V10.1.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/xml/unit_mode_multivar.xml b/test/xml/unit_mode_multivar.xml new file mode 100644 index 0000000000..ebfcf179cb --- /dev/null +++ b/test/xml/unit_mode_multivar.xml @@ -0,0 +1,42 @@ + + + + + + + + + + +]> + + + + &TEST_DIR; + true + + + echo "&DATA_DIR_MODEL;/mode_multivar/alpha_fcst.nc \ + &DATA_DIR_MODEL;/mode_multivar/beta_fcst.nc \ + &DATA_DIR_MODEL;/mode_multivar/gamma_fcst.nc" \ + > &OUTPUT_DIR;/mode_multivar/input_fcst_file_list; \ + echo "&DATA_DIR_MODEL;/mode_multivar/alpha_obs.nc \ + &DATA_DIR_MODEL;/mode_multivar/beta_obs.nc \ + &DATA_DIR_MODEL;/mode_multivar/gamma_obs.nc" \ + > &OUTPUT_DIR;/mode_multivar/input_obs_file_list; \ + &MET_BIN;/mode + \ + &OUTPUT_DIR;/mode_multivar/input_fcst_file_list \ + &OUTPUT_DIR;/mode_multivar/input_obs_file_list \ + &CONFIG_DIR;/MODEConfig_multivar_fake_data \ + -outdir &OUTPUT_DIR;/mode_multivar \ + -v 2 + + + &OUTPUT_DIR;/mode_multivar/f_super.nc + &OUTPUT_DIR;/mode_multivar/o_super.nc + + + + From ce1cd992a2f5df3e960ece83b345768cb75dbbd2 Mon Sep 17 00:00:00 2001 From: johnhg Date: Thu, 10 Mar 2022 09:46:05 -0700 Subject: [PATCH 154/172] Feature 1184 replace_env (#2093) --- .../libcode/vx_shapedata/mode_conf_info.cc | 91 ------------------- met/src/libcode/vx_shapedata/mode_conf_info.h | 10 -- met/src/tools/core/mode/mode.cc | 33 ++++++- 3 files changed, 29 insertions(+), 105 deletions(-) diff --git a/met/src/libcode/vx_shapedata/mode_conf_info.cc b/met/src/libcode/vx_shapedata/mode_conf_info.cc index 9bae581a01..bdcd013331 100644 --- a/met/src/libcode/vx_shapedata/mode_conf_info.cc +++ b/met/src/libcode/vx_shapedata/mode_conf_info.cc @@ -53,10 +53,6 @@ void ModeConfInfo::init_from_scratch() { - // Initialize pointers - // fcst_info = (VarInfo *) 0; - // obs_info = (VarInfo *) 0; - N_fields = 0; Field_Index = 0; @@ -95,30 +91,6 @@ void ModeConfInfo::clear() fcst_multivar_logic.clear(); obs_multivar_logic.clear(); - // fcst_conv_radius_array.clear(); - // obs_conv_radius_array.clear(); - - // fcst_conv_radius = bad_data_int; - // obs_conv_radius = bad_data_int; - - // fcst_conv_thresh_array.clear(); - // obs_conv_thresh_array.clear(); - - // fcst_merge_thresh_array.clear(); - // obs_merge_thresh_array.clear(); - - // fcst_conv_thresh.clear(); - // obs_conv_thresh.clear(); - - // fcst_vld_thresh = bad_data_double; - // obs_vld_thresh = bad_data_double; - - // fcst_filter_attr_map.clear(); - // obs_filter_attr_map.clear(); - - // fcst_merge_flag = MergeType_None; - // obs_merge_flag = MergeType_None; - match_flag = MatchType_None; max_centroid_dist = bad_data_double; @@ -176,11 +148,7 @@ void ModeConfInfo::clear() quilt = false; - // Deallocate memory - // if(fcst_info) { delete fcst_info; fcst_info = (VarInfo *) 0; } - // if(obs_info) { delete obs_info; obs_info = (VarInfo *) 0; } - if ( fcst_array ) { delete [] fcst_array; fcst_array = 0; } if ( obs_array ) { delete [] obs_array; obs_array = 0; } @@ -268,24 +236,12 @@ PlotInfo plot_info; fcst_dict = conf.lookup_dictionary(conf_key_fcst); obs_dict = conf.lookup_dictionary(conf_key_obs); - -// X read_fields (fcst_array, fcst_dict, ftype, 'F'); // the order is important here read_fields ( obs_array, obs_dict, otype, 'O'); // the order is important here Fcst = fcst_array; // + 0 Obs = obs_array; // + 0 - // Allocate new VarInfo objects - -// *X fcst_info = info_factory.new_var_info(ftype); -// *X obs_info = info_factory.new_var_info(otype); - - // Set the dictionaries - -// *X fcst_info->set_dict(*(fcst_dict->lookup_dictionary(conf_key_field))); -// *X obs_info->set_dict(*(obs_dict->lookup_dictionary(conf_key_field))); - // Dump the contents of the VarInfo objects if(mlog.verbosity_level() >= 5) { @@ -310,22 +266,6 @@ PlotInfo plot_info; } } - // Conf: fcst.raw_thresh and obs.raw_thresh are deprecated - -// *X if ( fcst_dict->lookup(conf_key_raw_thresh) || -// *X obs_dict->lookup(conf_key_raw_thresh) ) { -// *X mlog << Error << "\nModeConfInfo::process_config() -> " -// *X << "the \"" << conf_key_raw_thresh << "\" entry is deprecated in MET " -// *X << met_version << "! Use \"" << conf_key_censor_thresh << "\" and \"" -// *X << conf_key_censor_val << "\" instead.\n\n"; -// *X exit(1); -// *X } - - // Conf: fcst.conv_radius and obs.conv_radius - -// *X fcst_conv_radius_array = fcst_dict->lookup_int_array(conf_key_conv_radius); -// *X obs_conv_radius_array = obs_dict->lookup_int_array(conf_key_conv_radius); - for (j=0; jlookup_thresh_array(conf_key_conv_thresh); -// *X obs_conv_thresh_array = obs_dict->lookup_thresh_array(conf_key_conv_thresh); - for (j=0; jlookup_double(conf_key_vld_thresh); -// *X obs_vld_thresh = obs_dict->lookup_double(conf_key_vld_thresh); - - // Conf: fcst.filter_attr_name and fcst.filter_attr_thresh - // obs.filter_attr_name and obs.filter_attr_thresh - -// *X fcst_filter_attr_map = parse_conf_filter_attr_map(fcst_dict); -// *X obs_filter_attr_map = parse_conf_filter_attr_map(obs_dict); - - // Conf: fcst.merge_flag and obs.merge_flag - -// *X fcst_merge_flag = int_to_mergetype(fcst_dict->lookup_int(conf_key_merge_flag)); -// *X obs_merge_flag = int_to_mergetype(obs_dict->lookup_int(conf_key_merge_flag)); - - // Conf: fcst.merge_thresh and obs.merge_thresh - -// *X fcst_merge_thresh_array = fcst_dict->lookup_thresh_array(conf_key_merge_thresh); -// *X obs_merge_thresh_array = obs_dict->lookup_thresh_array(conf_key_merge_thresh); - for (j=0; jraw_pi = parse_conf_plot_info(conf.lookup_dictionary(conf_key_fcst_raw_plot)); // Conf: obs_raw_plot -// *X - obs_array->raw_pi = parse_conf_plot_info(conf.lookup_dictionary(conf_key_obs_raw_plot)); // Conf: object_plot @@ -637,7 +547,6 @@ PlotInfo plot_info; // Conf: shift_right -// *X shift_right = fcst_dict->lookup_int(conf_key_shift_right); return; diff --git a/met/src/libcode/vx_shapedata/mode_conf_info.h b/met/src/libcode/vx_shapedata/mode_conf_info.h index 5e6c436f62..6460b12add 100644 --- a/met/src/libcode/vx_shapedata/mode_conf_info.h +++ b/met/src/libcode/vx_shapedata/mode_conf_info.h @@ -170,7 +170,6 @@ class ModeConfInfo { bool plot_valid_flag; // Zoom up plot to the sub-region of valid data bool plot_gcarc_flag; // Plot lines as great-circle arcs bool ps_plot_flag; // Flag for the output PostScript image file - // bool nc_pairs_flag; // output NetCDF file bool ct_stats_flag; // Flag for the output contingency table statistics file FieldType mask_missing_flag; // Mask missing data between fcst and obs @@ -234,18 +233,9 @@ class ModeConfInfo { inline int ModeConfInfo::n_conv_radii() const { return ( Fcst->conv_radius_array.n_elements() ); } // should be the same as // obs_conv_radius_array.n_elements() - inline int ModeConfInfo::n_conv_threshs() const { return ( Fcst->conv_thresh_array.n_elements() ); } // should be the same as // obs_conv_thresh_array.n_elements() - -// inline int ModeConfInfo::n_fcst_merge_threshs () const { return ( fcst->merge_thresh_array.n_elements() ); } -// inline int ModeConfInfo::n_obs_merge_threshs () const { return ( obs->merge_thresh_array.n_elements() ); } - - -// inline bool ModeConfInfo::need_fcst_merge_thresh () const { return ( (fcst->merge_flag == MergeType_Both) || (fcst->merge_flag == MergeType_Thresh) ); } -// inline bool ModeConfInfo::need_obs_merge_thresh () const { return ( ( obs->merge_flag == MergeType_Both) || ( obs->merge_flag == MergeType_Thresh) ); } - inline int ModeConfInfo::get_compression_level() { return conf.nc_compression(); } inline int ModeConfInfo::field_index() const { return Field_Index; } diff --git a/met/src/tools/core/mode/mode.cc b/met/src/tools/core/mode/mode.cc index 95c7235da6..3563cc3d82 100644 --- a/met/src/tools/core/mode/mode.cc +++ b/met/src/tools/core/mode/mode.cc @@ -123,16 +123,41 @@ int main(int argc, char * argv []) { -if ( argc == 1 ) both_usage(); - -int j; +int j, n; int status; ModeConfInfo config; StringArray Argv; string s; bool has_field_index = false; -const char * const user_config_filename = argv[3]; +const char * user_config_filename = 0; + +for (j=0,n=0; j Date: Thu, 10 Mar 2022 16:18:15 -0700 Subject: [PATCH 155/172] Feature 2092 v10.1.0-rc1 (#2094) --- met/docs/Flowchart/MET_flowchart.pptx | Bin 372615 -> 372533 bytes met/docs/Flowchart/MET_flowchart_v10.1.0.png | Bin 169821 -> 169527 bytes .../Users_Guide/figure/overview-figure.png | Bin 166779 -> 169527 bytes met/docs/Users_Guide/overview.rst | 10 +- met/docs/Users_Guide/release-notes.rst | 323 +++++++++--------- met/docs/conf.py | 6 +- 6 files changed, 179 insertions(+), 160 deletions(-) diff --git a/met/docs/Flowchart/MET_flowchart.pptx b/met/docs/Flowchart/MET_flowchart.pptx index 5e4f364225c200df84ce4410605c6935ec25474b..afb35fe7462ba5835b6cf40226562ed85065b913 100644 GIT binary patch delta 20585 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Ǔofs2*{TdNTu}=nE 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 YqP>KOh|G^FI$8;L3V?=KMlwL~4|tY6y#N3J delta 20446 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 diff --git a/met/docs/Flowchart/MET_flowchart_v10.1.0.png b/met/docs/Flowchart/MET_flowchart_v10.1.0.png index e9f287d189d29cc5cae6cff4521dc634dd10319d..5b26111a7f26fbcabd9e84cf7777e9ab46e0fc27 100644 GIT binary patch delta 67266 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 delta 67577 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 diff --git a/met/docs/Users_Guide/figure/overview-figure.png b/met/docs/Users_Guide/figure/overview-figure.png index a6def17819b10602c9c94e61094babef84c6320c..5b26111a7f26fbcabd9e84cf7777e9ab46e0fc27 100644 GIT binary patch literal 169527 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 z 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 R>GuKn$jK;4S4n;i`hWF7KB52s diff --git a/met/docs/Users_Guide/overview.rst b/met/docs/Users_Guide/overview.rst index 8eed622ede..e7dde0c1e0 100644 --- a/met/docs/Users_Guide/overview.rst +++ b/met/docs/Users_Guide/overview.rst @@ -36,7 +36,7 @@ MET components The major components of the MET package are represented in :numref:`overview-figure`. The main stages represented are input, reformatting, plotting, intermediate output, statistical analyses, and output and aggregation/analysis. The MET-TC package functions independently of the other MET modules, as indicated in the Figure. Each of these stages is described further in later sections. For example, the input and output formats are discussed in :numref:`data_io` as well as in the sections associated with each of the statistics modules. MET input files are represented on the far left. -The reformatting stage of MET consists of the Gen-Vx-Mask, PB2NC, ASCII2NC, Pcp-Combine, MADIS2NC, MODIS regrid, WWMCA Regrid, and Ensemble-Stat tools. The PB2NC tool is used to create NetCDF files from input PrepBUFR files containing point observations. Likewise, the ASCII2NC tool is used to create NetCDF files from input ASCII point observations. Many types of data from the MADIS network can be formatted for use in MET by the MADIS2NC tool. MODIS and WWMCA files are regridded and formatted into NetCDF files by their respective tools. These NetCDF files are then used in the statistical analysis step. The Gen-Vx-Mask and Pcp-Combine tools are optional. The Gen-Vx-Mask tool will create a bitmapped masking area in a variety of ways. The output mask can then be used to efficiently limit verification to the interior of a user specified region. The Pcp-Combine tool can be used to add, subtract, or derive fields across multiple time steps. Often it is run to accumulate precipitation amounts into the time interval selected by the user - if a user would like to verify over a different time interval than is included in their forecast or observational dataset. The Ensemble-Stat tool will combine many forecasts into an ensemble mean or probability forecast. Additionally, if gridded or point observations are included, ensemble verification statistics are produced. +The reformatting stage of MET consists of several tools which perform a variety of functions. The ASCII2NC, PB2NC, MADIS2NC, LIDAR2NC, and IODA2NC tools read a variety of point observation input file formats and, optionally, derive time summaries for each observing location. They all write to a common NetCDF point observation file format which can be read by the other MET tools. The Point2Grid tool reads that common NetCDF point observation file format and interpolates the point data onto a user-specified grid. The Regrid-Data-Plane, Shift-Data-Plane, MODIS-Regrid, and WWMCA-Regrid tools read a variety of gridded input file formats and interpolate user-requested input fields to a user-defined output grid. While the MET statistics tools can interpolate many input file formats in-memory and on-the-fly, manually regridding upstream is sometimes useful. The Pcp-Combine tool adds, subtracts, or derives fields across multiple time steps. It is often run to accumulate precipitation amounts into a user-specified time interval - if a user would like to verify over a different time interval than is included in their forecast or observational dataset. The Gen-Vx-Mask tool provides a variety of methods for creating bitmapped masking areas. Those masks can then be used to efficiently limit verification to the interior of a user-specified region in the downstream statistics tools. The Gen-Ens-Prod tool derives basic ensemble products (mean, spread, probabilities) from multiple gridded input ensemble members. The GSI tools reformat binary GSI diagnostic data to be read by the Stat-Analysis tool. .. _overview-figure: @@ -52,7 +52,7 @@ Sometimes it may be useful to verify a forecast against gridded fields (e.g., St Users wishing to accumulate statistics over a time, height, or other series separately for each grid location should use the Series-Analysis tool. Series-Analysis can read any gridded matched pair data produced by the other MET tools and accumulate them, keeping each spatial location separate. Maps of these statistics can be useful for diagnosing spatial differences in forecast quality. -Ensemble-Stat is a hybrid tool that provides based post-processing capability of the ensemble members as well as computing measures of ensemble characteristics. Basic post-processing capability includes computing the ensemble mean, min, max, standard deviation, and ensemble relative frequency or probability. These fields can then be used in other MET tools for additional evaluation. The ensemble characteristics include computation of rank and probability integral transform (PIT) histograms, the end-points for receiver operator curve (ROC) and reliability diagrams, and ranked probabilities scores (RPS) and the continuous version (CRPS). +Ensemble-Stat is a hybrid tool that provides based post-processing capability of the ensemble members as well as computing measures of ensemble characteristics. Basic post-processing capability includes computing the ensemble mean, min, max, standard deviation, and ensemble relative frequency or probability. These fields can then be used in other MET tools for additional evaluation. Note however that the Gen-Ens-Prod tool also performs ensemble product generation, and this functionality will be removed from Ensemble-Stat in future versions. The ensemble characteristics include computation of rank and probability integral transform (PIT) histograms, the end-points for receiver operator curve (ROC) and reliability diagrams, and ranked probabilities scores (RPS) and the continuous version (CRPS). The MODE (Method for Object-based Diagnostic Evaluation) tool also uses gridded fields as observational datasets. However, unlike the Grid-Stat tool, which applies traditional forecast verification techniques, MODE applies the object-based spatial verification technique described in :ref:`Davis et al. (2006a,b) ` and :ref:`Brown et al. (2007) `. This technique was developed in response to the "double penalty" problem in forecast verification. A forecast missed by even a small distance is effectively penalized twice by standard categorical verification scores: once for missing the event and a second time for producing a false alarm of the event elsewhere. As an alternative, MODE defines objects in both the forecast and observation fields. The objects in the forecast and observation fields are then matched and compared to one another. Applying this technique also provides diagnostic verification information that is difficult or even impossible to obtain using traditional verification measures. For example, the MODE tool can provide information about errors in location, size, and intensity. @@ -90,9 +90,9 @@ We welcome comments and suggestions for improvements to MET, especially informat The MET package is a "living" set of tools. Our goal is to continually enhance it and add to its capabilities. Because our time, resources, and talents are limited, we welcome contributed code for future versions of MET. These contributions may represent new verification methodologies, new analysis tools, or new plotting functions. For more information on contributing code to MET, please create a post in the `METplus GitHub Discussions Forum `_. -Fortify -======= +Fortify and SonarQube +===================== -Requirements from various government agencies that use MET have resulted in our code being analyzed by Fortify, a proprietary static source code analyzer owned by HP Enterprise Security Products. Fortify analyzes source code to identify for security risks, memory leaks, uninitialized variables, and other such weaknesses and bad coding practices. Fortify categorizes any issues it finds as low priority, high priority, or critical, and reports these issues back to the developers for them to address. A development cycle is thus established, with Fortify analyzing code and reporting back to the developers, who then make changes in the source code to address these issues, and hand the new code off to Fortify again for re-analysis. The goal is to drive the counts of both high priority and critical issues down to zero. +Requirements from various government agencies that use MET have resulted in our code being analyzed by both the Fortify and SonarQube static source code analysis tools. Fortify and SonarQube analyze source code to identify for security risks, memory leaks, uninitialized variables, and other such weaknesses and bad coding practices. They categorize issue as low priority, high priority, or critical, and report these issues back to the developers for them to address. The goal is to drive the counts of both high priority and critical issues down to zero. The MET developers are pleased to report that Fortify reports zero critical issues in the MET code. Users of the MET tools who work in high security environments can rest assured about the possibility of security risks when using MET, since the quality of the code has now been vetted by unbiased third-party experts. The MET developers continue using Fortify routinely to ensure that the critical counts remain at zero and to further reduce the counts for lower priority issues. diff --git a/met/docs/Users_Guide/release-notes.rst b/met/docs/Users_Guide/release-notes.rst index eca874f4b0..d5fa2e5ec7 100644 --- a/met/docs/Users_Guide/release-notes.rst +++ b/met/docs/Users_Guide/release-notes.rst @@ -1,173 +1,192 @@ MET Release Notes ================= -When applicable, release notes are followed by the GitHub issue number which -describes the bugfix, enhancement, or new feature: -`MET GitHub issues. `_ +When applicable, release notes are followed by the GitHub issue number which describes the bugfix, +enhancement, or new feature (`MET GitHub issues `_). +Important issues are listed **in bold** for emphasis. -MET Version 10.1.0-beta6 release notes (20220302) -------------------------------------------------- +MET Version 10.1.0 release notes (20220314) +------------------------------------------- -* Enhancements: +* Repository and build: - * **Enhance Ensemble-Stat to compute probabilistic statistics for user-defined or climatology-based thresholds** (`#1259 `_). - * **Enhance Ensemble-Stat to apply the HiRA method to ensembles** (`#1583 `_ and `#2045 `_). - * **Enhance Ensemble-Stat, Point-Stat, Plot-Point-Obs, and Point2Grid to support python embedding of point observations** (`#1844 `_). - * **Enhance Gen-Ens-Prod to standardize ensemble members relative to climatology** (`#1918 `_). - * Enhance PB2NC to derive Mixed-Layer CAPE (MLCAPE) (`#1824 `_). - * Enhance Series-Analysis to compute the BRIERCL statistic from the PSTD line type (`#2003 `_). - * Enhance the MET library code to read Rotated Lat/Lon data from CF-compliant NetCDF files (`#1055 `_). + * Installation: -* Configuration: + * **Enhance the MET compilation script and its documentation** (`#1395 `_). - * Update the PB2NC configuration to correct the obs_prefbufr_map name as obs_prepbufr_map (`#2044 `_). - * Add entries to the default obs_prepbufr_map setting (`#2070 `_). + * Static Code Analysis: -* Bugfixes: + * **Automate calls to the SonarQube static code analysis tool in the nightly build** (`#2020 `_). + * Fix Fortify High finding for src/libcode/vx_data2d_nccf/nccf_file.cc (`#1795 `_). + * Fix the findings from SonarQube (`#1855 `_). + * Reduce the Security hotspots from SonarQube (`#1903 `_). + * Address findings from the Cppcheck code analysis tool (`#1996 `_). - * Fix the MET library code to correclty parse timing information from Grid-Stat NetCDF matched pairs output files (`#2040 `_). - * Fix MADIS2NC to correctly parse MADIS profiler quality flag values (`#2028 `_). + * Testing: -* Testing: + * Review and revise the warning messages when running the MET unit tests (`#1921 `_). + * Investigate nightly build output wind direction differences caused by machine precision (`#2027 `_). + * Modify plot_tcmpr.R script to support plotting of extra-tropical cyclone tracks not verified against BEST tracks (`#1801 `_). + * Fix failure in plot_tcmpr.R script when a directory is passed in with -lookin (`#1872 `_). - * **Implement Continuous Integration with GH-Actions in MET** (`#1546 `_). - * Write a script to automate SonarQube static code analysis runs in the nightly build (`#2020 `_). - * Investigate nightly build output wind direction differences caused by machine precision (`#2027 `_). + * Continuous Integration: -* Logging: + * **Implement Continuous Integration with GitHub Actions in MET** (`#1546 `_). + * Treat warnings from the documentation as errors to facilitate continuous integration with GHA (`#1819 `_). - * Enhance PB2NC to reduce redundant verbosity level 3 log messages (`#2015 `_). - * Print a warning message about switching from Ensemble-Stat to Gen-Ens-Prod (`#1907 `_). - * Update error messages to redirect users from the MET-Help desk to METplus Discussions (`#2054 `_). +* Documentation: -* Repository and installation: + * **Create and publish a PDF of the MET User's Guide via Read-The-Docs** (`#1453 `_). + * **Enhance the MET documentation to follow the standard for sections** (`#1998 `_). + * Add anchors to link directly to configuration items in the MET User's Guide (`#1811 `_). + * Update FAQ in User's Guide with info from webpage FAQ (`#1834 `_). + * Document the statistics from the RPS line type in Appendix C (`#1853 `_). + * Enhance the documentation with meta-data that is expected by MET for netCDF (`#1949 `_). + * Update documentation to reference GitHub Discussions instead of MET Help (`#1833 `_). + * Fix broken URLs in default MET config files (`#1864 `_). - * Update the copyright year of the source code to 2022 (`#2013 `_). -* Documentation: +* Library code: - * Enhance the documentation to follow the standard for sections (`#1998 `_). + * Bugfixes: -MET Version 10.1.0-beta5 release notes (20220114) -------------------------------------------------- + * Add check for the start offset and data count are valid before calling NetCDF API (`#1852 `_). + * Fix the MET library code to correclty parse timing information from Grid-Stat NetCDF matched pairs output files (`#2040 `_). + * Fix bug with the incrementing of numbers in temporary file names (`#1906 `_). -* Enhancements: + * Python embedding enhancements: - * **Enhance GridStat to use OpenMP for efficient computation of neighborhood statistics by setting $OMP_NUM_THREADS** (`#1926 `_). - * **Enhance EnsembleStat and GenEnsProd to read all ensemble members from a single input file** (`#1695 `_). - * **Enhance TCGen to verify NHC tropical weather outlook shapefiles** (`#1810 `_). - * **Refine logic to prevent rounding shapefile points to the nearest grid point (affects GenVxMask -type shape masks)** (`#1810 `_). - * Enhance MADIS2NC to handle the 2016 updates to its format (`#1936 `_). - * Modify the interpretation of the message_type_group_map values to support the use of regular expressions (`#1974 `_). - * Address findings from the Cppcheck code analysis tool (`#1996 `_). - * Sort files read from directories to provide consistent behavior across platforms (`#1989 `_). + * **Enhance Ensemble-Stat, Point-Stat, Plot-Point-Obs, and Point2Grid to support python embedding of point observations** (`#1844 `_). + * Fix python embedding when using a named grid with MET_PYTHON_EXE set (`#1798 `_). -* Bugfixes: + * Miscellaneous: - * **Fix MTD to compute the CDIST_TRAVELLED value correctly** (`#1976 `_). - * Fix PointStat and GridStat to write VCNT output even if no VL1L2 or VAL1L2 output is requested (`#1991 `_). - * Fix GenVxMask to handle named grids and grid specification strings for -type grid (`#1993 `_). - * Fix IODA2NC to handle the same input file being provided multiple times (`#1965 `_). + * **Enhance MET to use point observations falling between the first and last columns of a global grid** (`#1823 `_). + * Support percentile thresholds for frequency bias not equal to 1 (e.g. ==FBIAS0.9) (`#1761 `_). + * Reimplement the NumArray class based on an STL template (`#1899 `_). + * Modify the interpretation of the message_type_group_map values to support the use of regular expressions (`#1974 `_). + * Sort files read from directories to provide consistent behavior across platforms (`#1989 `_). + * Print warning message for fields that contain no valid data (`#1912 `_). + * Update error messages to redirect users from the MET-Help desk to METplus Discussions (`#2054 `_). + * Update the copyright year of the source code to 2022 (`#2013 `_). -MET Version 10.1.0-beta4 release notes (20211117) -------------------------------------------------- + * NetCDF library: -* Enhancements: + * **Implement a common API for reading and writing the common NetCDF point observation file format** (`#1402 `_ and `#1581 `_). + * **Enhance the MET library code to read Rotated Lat/Lon data from CF-compliant NetCDF files** (`#1055 `_). - * **Add logic to Ensemble-Stat to handle an ensemble control member** (`#1905 `_). - * Enhance Ensemble-Stat and Gen-Ens-Prod to error out if the control member also appears in the list of ensemble members (`#1968 `_). - * **Enhance TC-Gen to verify genesis probabilities from ATCF e-deck files** (`#1809 `_). - * Modify the STAT-Analysis GO Index configuration file (`#1945 `_). - * **Support percentile thresholds for frequency bias not equal to 1 (e.g. ==FBIAS0.9)** (`#1761 `_). - * Reimplement the NumArray class based on an STL template (`#1899 `_). + * Statistics computations: -* Bugfixes: + * Add Scatter Index to the CNT line type (`#1843 `_). + * Add the HSS_EC statistic to the MCTS line type and a configurable option for its computation (`#1749 `_). - * Fix bug with the incrementing of numbers in temporary file names (`#1906 `_). - * Fix ascii2nc to check the return status when reading ASCII input files (`#1957 `_). +* Application code: -* Documentation: + * ASCII2NC Tool: - * Enhance the documentation with meta-data that is expected by MET for netCDF (`#1949 `_). + * Fix ASCII2NC to check the return status when reading ASCII input files (`#1957 `_). -MET Version 10.1.0-beta3 release notes (20211006) -------------------------------------------------- + * Ensemble-Stat Tool: -* New tools: + * **Enhance Ensemble-Stat to compute probabilistic statistics for user-defined or climatology-based thresholds** (`#1259 `_). + * **Enhance Ensemble-Stat to apply the HiRA method to ensembles** (`#1583 `_ and `#2045 `_). + * **Enhance Ensemble-Stat and Gen-Ens-Prod to read all ensemble members from a single input file** (`#1695 `_). + * **Add logic to Ensemble-Stat to handle an ensemble control member** (`#1905 `_). + * Enhance Ensemble-Stat and Gen-Ens-Prod to error out if the control member also appears in the list of ensemble members (`#1968 `_). + * Add Point-Stat and Ensemble-Stat obs_quality_exc configuration option to specify which quality flags should be excluded (`#1858 `_). + * Print a warning message about switching from Ensemble-Stat to Gen-Ens-Prod (`#1907 `_). + * Fix failure of Ensemble-Stat when verifying against gridded ECMWF GRIB1 files (`#1879 `_). - * **Create new Gen-Ens-Prod tool for ensemble product generation** (`#1904 `_). + * Gen-Ens-Prod Tool (NEW): -* Enhancements: + * **Create the new Gen-Ens-Prod tool for ensemble product generation** (`#1904 `_). + * **Enhance Ensemble-Stat and Gen-Ens-Prod to read all ensemble members from a single input file** (`#1695 `_). + * Enhance Gen-Ens-Prod to standardize ensemble members relative to climatology (`#1918 `_). - * **Enhance MET to use point observations falling between the first and last columns of a global grid** (`#1823 `_). - * **Enhance the PBL derivation logic in PB2NC** (`#1913 `_). - * **Add obs_quality_exc configuration option to specify which quality flags should be excluded** (`#1858 `_). + * Gen-Vx-Mask Tool: -* Bugfixes: + * **Refine logic to prevent rounding shapefile points to the nearest grid point** (affects GenVxMask -type shape masks) (`#1810 `_). + * Change -type for Gen-Vx-Mask from an optional argument to a required one (`#1792 `_). + * Fix Gen-Vx-Mask to handle named grids and grid specification strings for -type grid (`#1993 `_). + * Fix Gen-Vx-Mask so that the -input_field and -mask_field options are processed independently (`#1891 `_). - * Fix PB2NC to better inventory BUFR input data when processing all variables (`#1894 `_). - * Fix IODA2NC bug rejecting all input observations in unit tests (`#1922 `_). - * Fix Stat-Analysis skill score index job which always writes a dump row output file (`#1914 `_). - * Fix TC-Stat event equalization logic to include any model name requested using -amodel (`#1932 `_). + * Grid-Diag Tool: -* Logging: + * Fix integer overflow in Grid-Diag (`#1886 `_). - * Resolve PB2NC string truncation warning messages (`#1909 `_). - * Print warning message for fields that contain no valid data (`#1912 `_). - * Review and revise the warning messages when running the MET unit tests (`#1921 `_). + * Grid-Stat Tool: -* Repository and installation: + * **Enhance Grid-Stat to use OpenMP for efficient computation of neighborhood statistics by setting $OMP_NUM_THREADS** (`#1926 `_). + * **Add G and G-Beta to the DMAP line type from Grid-Stat** (`#1673 `_). + * Fix Point-Stat and Grid-Stat to write VCNT output even if no VL1L2 or VAL1L2 output is requested (`#1991 `_). - * Enhance compilation script and its documentation (`#1395 `_). - * Reduce the Security hotspots from SonarQube (`#1903 `_). + * IODA2NC Tool: -MET Version 10.1.0-beta2 release notes (20210901) -------------------------------------------------- + * Fix IODA2NC to handle the same input file being provided multiple times (`#1965 `_). + * Fix IODA2NC bug rejecting all input observations in unit tests (`#1922 `_). -* New output: + * MADIS2NC Tool: - * **Enhance MET to compute the CBS Index** (`#1031 `_). - * **Enhance Stat-Analysis to write the GO Index and CBS Index into a new SSIDX STAT line type** (`#1788 `_). - * **Add Scatter Index to the CNT line type** (`#1843 `_). - * **Add ORANK line type to the HiRA output from Point-Stat** (`#1764 `_). - * **Add G and G-Beta to the DMAP line type from Grid-Stat** (`#1673 `_). + * Enhance MADIS2NC to handle the 2016 updates to its format (`#1936 `_). + * Fix MADIS2NC to correctly parse MADIS profiler quality flag values (`#2028 `_). -* Configuration: + * MODE Tool: - * **Make the specification of a binary threshold in Wavelet-Stat optional** (`#1746 `_). - * **Enable TC-Pairs to only write output for a configurable list of valid times** (`#1870 `_). - * Fix broken URLs in default MET config files (`#1864 `_). + * **Add support for Multi-Variate MODE** (`#1184 `_). -* Bugfixes: + * MTD Tool: - * **Fix the findings from SonarQube** (`#1855 `_). - * Fix integer overflow in Grid-Diag (`#1886 `_). - * Fix Gen-Vx-Mask so that the -input_field and -mask_field options are processed independently (`#1891 `_). - * Enable Point2Grid to support double type latitude/longitude variables (`#1838 `_). - * Fix the output of Point2Grid which is flipped and rotated with lat/lon to lat/lon conversion (`#1817 `_). - * Fix failure of Ensemble-Stat when verifying against gridded ECMWF GRIB1 files (`#1879 `_). - * Fix consumption of too much memory by Stat-Analysis (`#1875 `_). - * Add check for the start offset and data count are valid before calling NetCDF API (`#1852 `_). - * Fix failure in plot_tcmpr.R script when a directory is passed in with -lookin (`#1872 `_). + * Fix MTD to compute the CDIST_TRAVELLED value correctly (`#1976 `_). -* Documentation: + * PB2NC Tool: - * **Create and publish a PDF of the MET User's Guide** (`#1453 `_). - * Document the statistics from the RPS line type in Appendix C (`#1853 `_). - * Treat warnings from the documentation as errors to facilitate continuous integration with GHA (`#1819 `_). - * Update documentation to reference GitHub Discussions instead of MET Help (`#1833 `_). - * Update FAQ in User's Guide with info from webpage FAQ (`#1834 `_). + * **Enhance PB2NC to derive Mixed-Layer CAPE (MLCAPE)** (`#1824 `_). + * Enhance the PBL derivation logic in PB2NC (`#1913 `_). + * Update the PB2NC configuration to correct the obs_prefbufr_map name as obs_prepbufr_map (`#2044 `_). + * Add entries to the default obs_prepbufr_map setting (`#2070 `_). + * Fix PB2NC to better inventory BUFR input data when processing all variables (`#1894 `_). + * Fix PB2NC to reduce redundant verbosity level 3 log messages (`#2015 `_). + * Resolve PB2NC string truncation warning messages (`#1909 `_). -MET Version 10.1.0-beta1 release notes (20210613) -------------------------------------------------- + * Point2Grid Tool: + + * Enhance Point2Grid to support double type latitude/longitude variables (`#1838 `_). + * Fix the output of Point2Grid which is flipped and rotated with lat/lon to lat/lon conversion (`#1817 `_). + + * Point-Stat Tool: + + * Add ORANK line type to the HiRA output from Point-Stat (`#1764 `_). + * Add Point-Stat and Ensemble-Stat obs_quality_exc configuration option to specify which quality flags should be excluded (`#1858 `_). + * Fix Point-Stat and Grid-Stat to write VCNT output even if no VL1L2 or VAL1L2 output is requested (`#1991 `_). + + * Series-Analysis Tool: + + * Enhance Series-Analysis to compute the BRIERCL statistic from the PSTD line type (`#2003 `_). + + * Stat-Analysis Tool: + + * **Enhance Stat-Analysis to compute the CBS Index** (`#1031 `_). + * **Enhance Stat-Analysis to write the GO Index and CBS Index into a new SSIDX STAT line type** (`#1788 `_). + * Modify the STAT-Analysis GO Index configuration file (`#1945 `_). + * Fix Stat-Analysis skill score index job which always writes a dump row output file (`#1914 `_). + * Fix consumption of too much memory by Stat-Analysis (`#1875 `_). + + * TC-Gen Tool: + + * **Enhance TC-Gen to verify genesis probabilities from ATCF e-deck files** (`#1809 `_). + * **Enhance TC-Gen to verify NHC tropical weather outlook shapefiles** (`#1810 `_). + + * TC-Pairs Tool: -* Add the HSS_EC statistic to the MCTS line type and a configurable option for its computation (`#1749 `_). -* Implement a common API for reading and writing the common NetCDF point observation file format (`#1402 `_ and `#1581 `_). -* Change -type for Gen-Vx-Mask from an optional argument to a required one (`#1792 `_). -* Fix python embedding when using a named grid with MET_PYTHON_EXE set (`#1798 `_). -* Fix Fortify High finding for src/libcode/vx_data2d_nccf/nccf_file.cc (`#1795 `_). -* Modify plot_tcmpr.R script to support plotting of extra-tropical cyclone tracks not verified against BEST tracks (`#1801 `_). -* Add anchors to link directly to configuration items in the MET User's Guide (`#1811 `_). + * Enhance TC-Pairs to only write output for a configurable list of valid times (`#1870 `_). + + * TC-Stat Tool: + + * Fix TC-Stat event equalization logic to include any model name requested using -amodel (`#1932 `_). + + * Wavelet-Stat Tool: + + * Make the specification of a binary threshold in Wavelet-Stat optional (`#1746 `_). MET Version 10.0.0 release notes (20210510) ------------------------------------------- @@ -262,14 +281,41 @@ MET Version 10.0.0 release notes (20210510) * Fix to handle bad records in little_r format (`#1737 `_). * Create empty output files for zero input observations instead of erroring out (`#1630 `_). + * GIS Tools: + + * Fix memory corruption bug in the gis_dump_dbf utility which causes it to abort at runtime (`#1777 `_). + + * Grid-Diag Tool: + + * Fix bug when reading the same variable name from multiple data sources (`#1694 `_). + + * Grid-Stat Tool: + + * **Add mpr_column and mpr_thresh configuration options to filter out matched pairs based on large fcst, obs, and climo differences** (`#1575 `_). + * Correct the climatological CDF values in the NetCDF matched pairs output files and correct the climatological probability values for climatgological distribution percentile (CDP) threshold types (`#1638 `_). + + * IODA2NC Tool (NEW): + + * **Add the new ioda2nc tool** (`#1355 `_). + * MADIS2NC Tool: * Clarify various error messages (`#1409 `_). + * MODE Tool: + + * **Update the MODE AREA_RATIO output column to list the forecast area divided by the observation area** (`#1643 `_). + * **Incremental development toward the Multivariate MODE tool** (`#1282 `_, `#1284 `_, and `#1290 `_). + * PB2NC Tool: * Fix intermittent segfault when deriving PBL (`#1715 `_). + * Plot-Point-Obs Tool: + + * **Overhaul Plot-Point-Obs to make it highly configurable** (`#213 `_, `#1528 `_, and `#1052 `_). + * Support regridding option in the config file (`#1627 `_). + * Point2Grid Tool: * **Support additional NetCDF point observation data sources** (`#1345 `_, `#1509 `_, and `#1511 `_). @@ -278,15 +324,6 @@ MET Version 10.0.0 release notes (20210510) * Improve the Point2Grid runtime performance (`#1421 `_). * Process point observations by variable name instead of GRIB code (`#1408 `_). - * GIS Tools: - - * Fix memory corruption bug in the gis_dump_dbf utility which causes it to abort at runtime (`#1777 `_). - - * Plot-Point-Obs Tool: - - * **Overhaul Plot-Point-Obs to make it highly configurable** (`#213 `_, `#1528 `_, and `#1052 `_). - * Support regridding option in the config file (`#1627 `_). - * Point-Stat Tool: * **Add mpr_column and mpr_thresh configuration options to filter out matched pairs based on large fcst, obs, and climo differences** (`#1575 `_). @@ -296,11 +333,6 @@ MET Version 10.0.0 release notes (20210510) * Enhance the validation of masking regions to check for non-unique masking region names (`#1439 `_). * Fix Point-Stat runtime error for some CF-complaint NetCDF files (`#1782 `_). - * Grid-Stat Tool: - - * **Add mpr_column and mpr_thresh configuration options to filter out matched pairs based on large fcst, obs, and climo differences** (`#1575 `_). - * Correct the climatological CDF values in the NetCDF matched pairs output files and correct the climatological probability values for climatgological distribution percentile (CDP) threshold types (`#1638 `_). - * Stat-Analysis Tool: * **Process multiple output thresholds and write multiple output line types in a single aggregate_stat job** (`#1735 `_). @@ -309,24 +341,6 @@ MET Version 10.0.0 release notes (20210510) * Add -column_exc job command option to exclude lines based on string values (`#1733 `_). * Fix Stat-Analysis failure when aggregating ECNT lines (`#1706 `_). - * Grid-Diag Tool: - - * Fix bug when reading the same variable name from multiple data sources (`#1694 `_). - - * MODE Tool: - - * **Update the MODE AREA_RATIO output column to list the forecast area divided by the observation area** (`#1643 `_). - * **Incremental development toward the Multivariate MODE tool** (`#1282 `_, `#1284 `_, and `#1290 `_). - - * TC-Pairs Tool: - - * Fix to report the correct number of lines read from input track data files (`#1725 `_). - * Fix to read supported RI edeck input lines and ignore unsupported edeck probability line types (`#1768 `_). - - * TC-Stat Tool: - - * Add -column_exc job command option to exclude lines based on string values (`#1733 `_). - * TC-Gen Tool: * **Overhaul the genesis matching logic, add the development and operational scoring algorithms, and add many config file options** (`#1448 `_). @@ -336,6 +350,11 @@ MET Version 10.0.0 release notes (20210510) * Enhance the matching logic and update several config options to support its S2S application (`#1714 `_). * Fix lead window filtering option (`#1465 `_). - * IODA2NC Tool: + * TC-Pairs Tool: - * **Add the new ioda2nc tool** (`#1355 `_). + * Fix to report the correct number of lines read from input track data files (`#1725 `_). + * Fix to read supported RI edeck input lines and ignore unsupported edeck probability line types (`#1768 `_). + + * TC-Stat Tool: + + * Add -column_exc job command option to exclude lines based on string values (`#1733 `_). diff --git a/met/docs/conf.py b/met/docs/conf.py index 4fc13cc8b5..44bbb2f91f 100644 --- a/met/docs/conf.py +++ b/met/docs/conf.py @@ -19,12 +19,12 @@ project = 'MET' author = 'UCAR/NCAR, NOAA, CSU/CIRA, and CU/CIRES' -author_list = 'Halley Gotway, J., K. Newman, H. Soh, J. Opatz, T. Jensen, J. Prestopnik, L. Goodrich, D. Fillmore, B. Brown, R. Bullock, T. Fowler' -version = '10.1.0-beta6' +author_list = 'Newman, K., J. Opatz, T. Jensen, J. Prestopnik, H. Soh, L. Goodrich, B. Brown, R. Bullock, J. Halley Gotway' +version = '10.1.0' verinfo = version release = f'{version}' release_year = '2022' -release_date = f'{release_year}-03-02' +release_date = f'{release_year}-03-14' copyright = f'{release_year}, {author}' # -- General configuration --------------------------------------------------- From db7762f46f0abd7a6cfc5c8124711d1b4244a5df Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 10 Mar 2022 17:51:10 -0700 Subject: [PATCH 156/172] Hotfix to the develop branch to fix the MODE Makefile for the MET-10.1.0-rc1 release. --- met/src/libcode/vx_data2d_nccf/nccf_file.cc | 2 +- met/src/tools/core/mode/Makefile.am | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.cc b/met/src/libcode/vx_data2d_nccf/nccf_file.cc index 53880b043c..7ccdd710ae 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.cc +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.cc @@ -2780,7 +2780,7 @@ bool NcCfFile::get_grid_from_coordinates(const NcVar *data_var) { // Get the dimensions from the coordinate variables. mlog << Debug(6) << "\n" << method_name << " -> " - << "collect GRID infor from \"" << GET_NC_NAME_P(data_var) << "\".\n\n"; + << "collect GRID info from \"" << GET_NC_NAME_P(data_var) << "\".\n\n"; NcVarAtt *coordinates_att = get_nc_att(data_var, (string)"coordinates"); diff --git a/met/src/tools/core/mode/Makefile.am b/met/src/tools/core/mode/Makefile.am index 14df6b0ca8..c1e243cf37 100644 --- a/met/src/tools/core/mode/Makefile.am +++ b/met/src/tools/core/mode/Makefile.am @@ -13,6 +13,8 @@ include ${top_srcdir}/Make-include bin_PROGRAMS = mode mode_SOURCES = mode_usage.cc \ mode_frontend.cc \ + mode_multivar.cc \ + mode_singlevar.cc \ multivar_frontend.cc \ mode.cc \ combine_boolplanes.cc \ @@ -60,4 +62,6 @@ mode_LDADD = -lvx_pxm \ EXTRA_DIST = mode_exec.h \ mode_ps_file.h \ - mode_ps_table_defs.h + mode_ps_table_defs.h \ + mode_usage.h \ + objects_from_netcdf.h \ No newline at end of file From a32b11b13c994814e9e8e0d2ab116ddc702e6c64 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 10 Mar 2022 18:28:33 -0700 Subject: [PATCH 157/172] Second hotfix for the MODE Makefile in the develop branch. --- met/src/tools/core/mode/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/met/src/tools/core/mode/Makefile.am b/met/src/tools/core/mode/Makefile.am index c1e243cf37..34fe475c05 100644 --- a/met/src/tools/core/mode/Makefile.am +++ b/met/src/tools/core/mode/Makefile.am @@ -64,4 +64,5 @@ EXTRA_DIST = mode_exec.h \ mode_ps_file.h \ mode_ps_table_defs.h \ mode_usage.h \ + combine_boolplanes.h \ objects_from_netcdf.h \ No newline at end of file From 6db4da7a13e3b68df0f7fc7c72dd16e7d8c0462b Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 11 Mar 2022 17:18:40 -0700 Subject: [PATCH 158/172] Feature 1844 docs (#2096) --- met/docs/Users_Guide/appendixF.rst | 38 ++++++++++--------------- met/docs/Users_Guide/ensemble-stat.rst | 2 +- met/docs/Users_Guide/plotting.rst | 13 ++------- met/docs/Users_Guide/point-stat.rst | 4 +-- met/docs/Users_Guide/reformat_point.rst | 11 ++----- 5 files changed, 24 insertions(+), 44 deletions(-) diff --git a/met/docs/Users_Guide/appendixF.rst b/met/docs/Users_Guide/appendixF.rst index 2649fb4072..28253bf357 100644 --- a/met/docs/Users_Guide/appendixF.rst +++ b/met/docs/Users_Guide/appendixF.rst @@ -236,10 +236,11 @@ The Ensemble-Stat, Series-Analysis, and MTD tools support the use of file lists file_type=PYTHON_NUMPY;' \ -title "Python enabled plot_data_plane" +.. _pyembed-point-obs-data: + Python Embedding for Point Observations ======================================= - The ASCII2NC tool supports the "-format python" option. With this option, point observations may be passed as input. An example of this is provided in :numref:`ascii2nc-pyembed`. That example uses the **read_ascii_point.py** sample script which is included with the MET code. It reads ASCII data in MET's 11-column point observation format and stores it in a Pandas dataframe to be read by the ASCII2NC tool with Python. The **read_ascii_point.py** sample script can be found in: @@ -248,33 +249,13 @@ The **read_ascii_point.py** sample script can be found in: • `MET GitHub repository `_ in *met/scripts/python*. -Python Embedding for MPR data -============================= - -The Stat-Analysis tool supports the "-lookin python" option. With this option, matched pair (MPR) data may be passed as input. An example of this is provided in :numref:`StA-pyembed`. That example uses the **read_ascii_mpr.py** sample script which is included with the MET code. It reads MPR data and stores it in a Pandas dataframe to be read by the Stat-Analysis tool with Python. - -The **read_ascii_mpr.py** sample script can be found in: - -• MET installation directory in *MET_BASE/python*. - -• `MET GitHub repository `_ in *met/scripts/python*. - - -Python Embedding for Point Observations as input -================================================ - - -The point2grid, plot_point_obs, ensemble_stat, and point_stat tools use MET point observation NetCDF. They support the python embedding by the prefix 'PYTHON_NUMPY=" and followed by a python script name instead of the MET point observastion NetCDF filename. The customized python script is expected to extend MET_BASE/python/met_point_obs.py and to produce the python variable, **met_point_data**, which is the dictionary of the MET point observation data. They are defined at MET_BASE/python/met_point_obs.py. - - -.. _pyembed-point-obs-data: - +The Point2Grid, Plot-Point-Obs, Ensemble-Stat, and Point-Stat tools also process point observations. They support python embedding of point observations directly on the command line by replacing the input MET NetCDF point observation file name with the python command to be run. The command must begin with the prefix 'PYTHON_NUMPY=' and be followed by the path to python script and any arguments. The full command should be enclosed in single quotes to prevent embedded whitespace from causing parsing errors. The customized python script is expected to extend MET_BASE/python/met_point_obs.py. That script creates a python variable named **met_point_data** which is a dictionary containing formatted point observation data. .. code-block:: none met_point_data = { - 'use_var_id': Trur/False, # obs_vid are variable index if True, otherwise GRIB codes + 'use_var_id': True/False, # obs_vid are variable index if True, otherwise GRIB codes # Header data 'nhdr': integer_value, # number of headers @@ -308,3 +289,14 @@ The point2grid, plot_point_obs, ensemble_stat, and point_stat tools use MET poin 'obs_qty_table': string_array, # quality marks 'obs_var_table': string_array, # variable names } + +Python Embedding for MPR data +============================= + +The Stat-Analysis tool supports the "-lookin python" option. With this option, matched pair (MPR) data may be passed as input. An example of this is provided in :numref:`StA-pyembed`. That example uses the **read_ascii_mpr.py** sample script which is included with the MET code. It reads MPR data and stores it in a Pandas dataframe to be read by the Stat-Analysis tool with Python. + +The **read_ascii_mpr.py** sample script can be found in: + +• MET installation directory in *MET_BASE/python*. + +• `MET GitHub repository `_ in *met/scripts/python*. diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index 3ca0deb588..d13d327cf1 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -100,7 +100,7 @@ Optional arguments for ensemble_stat 4. To produce ensemble statistics using gridded observations, use the **-grid_obs file** option to specify a gridded observation file. This option may be used multiple times if your observations are in several files. -5. To produce ensemble statistics using point observations, use the **-point_obs file** option to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. The python embedding will be activated if the **file** begines with 'PYTHON_NUMPY=" and followed by a python script name. +5. To produce ensemble statistics using point observations, use the **-point_obs file** option to specify a NetCDF point observation file. This option may be used multiple times if your observations are in several files. Python embedding for point observations is also supported, as described in :numref:`pyembed-point-obs-data`. 6. To override the simple ensemble mean value of the input ensemble members for the ECNT, SSVAR, and ORANK line types, the **-ens_mean file** option specifies an ensemble mean model data file. This option replaces the **-ssvar_mean file** option from earlier versions of MET. diff --git a/met/docs/Users_Guide/plotting.rst b/met/docs/Users_Guide/plotting.rst index 9b08a2be7e..172d99650b 100644 --- a/met/docs/Users_Guide/plotting.rst +++ b/met/docs/Users_Guide/plotting.rst @@ -9,9 +9,6 @@ Plotting Utilities This section describes how to check your data files using plotting utilities. Point observations can be plotted using the Plot-Point-Obs utility. A single model level can be plotted using the plot_data_plane utility. For object based evaluations, the MODE objects can be plotted using plot_mode_field. Occasionally, a post-processing or timing error can lead to errors in MET. These tools can assist the user by showing the data to be verified to ensure that times and locations match up as expected. -MET version 10.1 adds support for the passing point observations to plot_point_obs using a Python scriptAn example of running plot_point_obs with Python embedding is included below. - - plot_point_obs usage -------------------- @@ -37,7 +34,7 @@ plot_point_obs has two required arguments and can take optional ones. Required arguments for plot_point_obs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1. The **nc_file** argument indicates the name of the point observation file to be plotted. This file is the output from one of the point pre-processing tools, such as pb2nc. +1. The **nc_file** argument indicates the name of the point observation file to be plotted. This file is the output from one of the point pre-processing tools, such as pb2nc. Python embedding for point observations is also supported, as described in :numref:`pyembed-point-obs-data`. 2. The **ps_file** argument indicates the name given to the output file containing the plot. @@ -70,17 +67,13 @@ An example of the plot_point_obs calling sequence is shown below: In this example, the Plot-Point-Obs tool will process the input sample_pb.nc file and write a postscript file containing a plot to a file named sample_pb.ps. -This is an equivalent command with the python embedding. This is an example for the python embeddingt. +An equivalent command using python embedding for point observations is shown below. Note that the entire python command is enclosed in single quotes to prevent embedded whitespace for causing parsing errors: .. code-block:: none plot_point_obs 'PYTHON_NUMPY=MET_BASE/python/read_met_point_obs.py sample_pb.nc' sample_data.ps - -The user should replace the python script with the customized python script for the custom point observation data. - -Please refer to :numref:`Appendix F, Section %s ` for more details about Python embedding in MET. - +Please see section :numref:`pyembed-point-obs-data` for more details about Python embedding in MET. plot_point_obs configuration file --------------------------------- diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index 5c89be5d6d..8ee096b946 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -280,14 +280,14 @@ Required arguments for point_stat 1. The **fcst_file** argument names the gridded file in either GRIB or NetCDF containing the model data to be verified. -2. The **obs_file** argument indicates the NetCDF file (output of PB2NC or ASCII2NC) containing the point observations to be used for verifying the model. +2. The **obs_file** argument indicates the MET NetCDF point observation file to be used for verifying the model. Python embedding for point observations is also supported, as described in :numref:`pyembed-point-obs-data`. 3. The **config_file** argument indicates the name of the configuration file to be used. The contents of the configuration file are discussed below. Optional arguments for point_stat ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -4. The **-point_obs** file may be used to pass additional NetCDF point observation files to be used in the verification. The python embedding will be activated if the **file** begines with 'PYTHON_NUMPY=" and followed by a python script name. +4. The **-point_obs** file may be used to pass additional NetCDF point observation files to be used in the verification. Python embedding for point observations is also supported, as described in :numref:`pyembed-point-obs-data`. 5. The **-obs_valid_beg** time option in YYYYMMDD[_HH[MMSS]] format sets the beginning of the observation matching time window, overriding the configuration file setting. diff --git a/met/docs/Users_Guide/reformat_point.rst b/met/docs/Users_Guide/reformat_point.rst index 0953afdd7c..0494e866ee 100644 --- a/met/docs/Users_Guide/reformat_point.rst +++ b/met/docs/Users_Guide/reformat_point.rst @@ -978,10 +978,7 @@ The NetCDF output of the IODA2NC tool is structured in the same way as the outpu Point2Grid tool =============== -The Point2Grid tool takes point observations from a NetCDF output file from one of the four previously mentioned MET tools (ascii2nc, madis2nc, pb2nc, lidar2nc) and creates a gridded NetCDF file. The other point observations are GOES-16/17 input files in NetCDF format (especially, Aerosol Optical Depth. Future development will include support for reading input files not produced from MET tools. - -MET version 10.1 adds support for the passing point observations to point2grid using a Python script with "input_filename" which begins with the "PYTHON_NUMPY= [arguments]" instead of MET point observation NetCDF input. An example of running point2grid with Python embedding is included below. - +The Point2Grid tool reads point observations from a MET NetCDF point obseravtion file, via python embedding, or from GOES-16/17 input files in NetCDF format (especially, Aerosol Optical Depth) and creates a gridded NetCDF file. Future development may add support for additional input types. point2grid usage ---------------- @@ -1012,7 +1009,7 @@ The usage statement for the Point2Grid tool is shown below: Required arguments for point2grid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1. The **input_filename** argument indicates the name of the input NetCDF file to be processed. Currently, only NetCDF files produced from the ascii2nc, madis2nc, pb2nc, and lidar2nc are supported. And AOD dataset from GOES16/17 are supported, too. Support for additional file types will be added in future releases. +1. The **input_filename** argument indicates the name of the input file to be processed. The input can be a MET NetCDF point observation file generated by other MET tools or a NetCDF AOD dataset from GOES16/17. Python embedding for point observations is also supported, as described in :numref:`pyembed-point-obs-data`. The MET point observation NetCDF file name as **input_filename** argument is equivalent with "PYTHON_NUMPY=MET_BASE/python/read_met_point_obs.py netcdf_file name'. @@ -1067,9 +1064,7 @@ For the GOES-16 and GOES-17 data, the computing lat/long is time consuming. So t When processing GOES-16 data, the **-qc** option may also be used to specify the acceptable quality control flag values. The example above regrids the GOES-16 AOD values to NCEP Grid number 212 (which QC flags are high, medium, and low), writing to the output the maximum AOD value falling inside each grid box. - -Here is an example of processing the same set of observations but using Python embedding instead: - +Listed below is an example of processing the same set of observations but using python embedding instead: .. code-block:: none From eeefd91c85b7bd1a666805ed0a55c198f73a8dc9 Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 14 Mar 2022 12:20:24 -0600 Subject: [PATCH 159/172] Feature 2097 v10.1.0 (#2099) --- met/data/config/IODA2NCConfig_default | 2 +- met/src/libcode/vx_shapedata/mode_data_field.h | 2 +- met/src/libcode/vx_shapedata/mode_field_info.cc | 4 +--- met/src/libcode/vx_shapedata/mode_field_info.h | 4 +--- met/src/tools/core/mode/mode_frontend.cc | 2 +- met/src/tools/core/mode/mode_multivar.cc | 2 +- met/src/tools/core/mode/mode_singlevar.cc | 2 +- test/config/IODA2NCConfig_mask | 2 +- test/config/IODA2NCConfig_summary | 2 +- test/config/PB2NCConfig_pbl | 2 +- 10 files changed, 10 insertions(+), 14 deletions(-) diff --git a/met/data/config/IODA2NCConfig_default b/met/data/config/IODA2NCConfig_default index 12b99bcd35..090938210a 100644 --- a/met/data/config/IODA2NCConfig_default +++ b/met/data/config/IODA2NCConfig_default @@ -125,6 +125,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.0"; +version = "V10.1.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_shapedata/mode_data_field.h b/met/src/libcode/vx_shapedata/mode_data_field.h index 7b5d7359a1..19556edc5b 100644 --- a/met/src/libcode/vx_shapedata/mode_data_field.h +++ b/met/src/libcode/vx_shapedata/mode_data_field.h @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2019 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/mode_field_info.cc b/met/src/libcode/vx_shapedata/mode_field_info.cc index bd3a55fc65..b263f5f2e6 100644 --- a/met/src/libcode/vx_shapedata/mode_field_info.cc +++ b/met/src/libcode/vx_shapedata/mode_field_info.cc @@ -1,7 +1,5 @@ - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2019 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/libcode/vx_shapedata/mode_field_info.h b/met/src/libcode/vx_shapedata/mode_field_info.h index 800c396f13..2a4f298fbe 100644 --- a/met/src/libcode/vx_shapedata/mode_field_info.h +++ b/met/src/libcode/vx_shapedata/mode_field_info.h @@ -1,7 +1,5 @@ - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2019 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_frontend.cc b/met/src/tools/core/mode/mode_frontend.cc index 1b8ce2937d..3d140c8db6 100644 --- a/met/src/tools/core/mode/mode_frontend.cc +++ b/met/src/tools/core/mode/mode_frontend.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2019 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_multivar.cc b/met/src/tools/core/mode/mode_multivar.cc index aa4174c6e7..a80c8a5453 100644 --- a/met/src/tools/core/mode/mode_multivar.cc +++ b/met/src/tools/core/mode/mode_multivar.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2019 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/met/src/tools/core/mode/mode_singlevar.cc b/met/src/tools/core/mode/mode_singlevar.cc index fc747ba499..e541b5ee3b 100644 --- a/met/src/tools/core/mode/mode_singlevar.cc +++ b/met/src/tools/core/mode/mode_singlevar.cc @@ -1,5 +1,5 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1992 - 2019 +// ** Copyright UCAR (c) 1992 - 2022 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Research Applications Lab (RAL) diff --git a/test/config/IODA2NCConfig_mask b/test/config/IODA2NCConfig_mask index 69f1f3d282..8a603c0e21 100644 --- a/test/config/IODA2NCConfig_mask +++ b/test/config/IODA2NCConfig_mask @@ -117,6 +117,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.0"; +version = "V10.1.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/IODA2NCConfig_summary b/test/config/IODA2NCConfig_summary index e0a8b19879..b23b9b4df9 100644 --- a/test/config/IODA2NCConfig_summary +++ b/test/config/IODA2NCConfig_summary @@ -117,6 +117,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.0"; +version = "V10.1.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_pbl b/test/config/PB2NCConfig_pbl index a70d560df6..aeb272cfe3 100644 --- a/test/config/PB2NCConfig_pbl +++ b/test/config/PB2NCConfig_pbl @@ -137,6 +137,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.0"; +version = "V10.1.0"; //////////////////////////////////////////////////////////////////////////////// From 142820142c00062cf67c9bfd0862e692e08c96ad Mon Sep 17 00:00:00 2001 From: Dan Adriaansen Date: Mon, 14 Mar 2022 12:44:21 -0600 Subject: [PATCH 160/172] Feature 2098 gen ens prod doc (#2100) --- met/docs/Users_Guide/ensemble-stat.rst | 2 ++ met/docs/Users_Guide/gen-ens-prod.rst | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/ensemble-stat.rst b/met/docs/Users_Guide/ensemble-stat.rst index d13d327cf1..e989913062 100644 --- a/met/docs/Users_Guide/ensemble-stat.rst +++ b/met/docs/Users_Guide/ensemble-stat.rst @@ -9,6 +9,8 @@ Introduction The Ensemble-Stat tool may be run to create simple ensemble forecasts (mean, probability, spread, etc) from a set of several forecast model files to be used by the MET statistics tools. If observations are also included, ensemble statistics such as rank histograms, probability integral transform histograms, spread/skill variance, relative position and continuous ranked probability score are produced. Climatological mean and standard deviation data may also be provided, and will be used as a reference forecast in several of the output statistics. Finally, observation error perturbations can be included prior to calculation of statistics. Details about and equations for the statistics produced for ensembles are given in :numref:`Appendix C, Section %s `. +.. note:: This tool will be changing! The ensemble product generation step provided by Ensemble-Stat is now found within the :ref:`Gen-Ens-Prod Tool`. The Gen-Ens-Prod tool replaces and extends that functionality. Users are strongly encouraged to migrate ensemble product generation from Ensemble-Stat to Gen-Ens-Prod, as new features will only be added to Gen-Ens-Prod and the existing Ensemble-Stat functionality will be deprecated in a future version. + Scientific and statistical aspects ================================== diff --git a/met/docs/Users_Guide/gen-ens-prod.rst b/met/docs/Users_Guide/gen-ens-prod.rst index be482edbcd..4d697d5691 100644 --- a/met/docs/Users_Guide/gen-ens-prod.rst +++ b/met/docs/Users_Guide/gen-ens-prod.rst @@ -7,9 +7,9 @@ Gen-Ens-Prod Tool Introduction ============ -The Gen-Ens-Prod tool generates simple ensemble products (mean, spread, probability, etc) from gridded ensemble member input files. While it processes model inputs, but it does not compare them to observations or compute statistics. However, the output products can be passed as input to the MET statistics tools for comparison against observations. Climatological mean and standard deviation data may also be provided to define thresholds based on the climatological distribution at each grid point. +The Gen-Ens-Prod tool generates simple ensemble products (mean, spread, probability, etc) from gridded ensemble member input files. While it processes model inputs, it does not compare them to observations or compute statistics. However, the output products can be passed as input to the MET statistics tools for comparison against observations. Climatological mean and standard deviation data may also be provided to define thresholds based on the climatological distribution at each grid point. -Note that this ensemble product generation step was provided by the Ensemble-Stat tool in earlier versions of MET. The Gen-Ens-Prod tool replaces and extends that functionality. Users are strongly encouraged to migrate ensemble product generation from Ensemble-Stat to Gen-Ens-Prod, as new features will only be added to Gen-Ens-Prod and the existing Ensemble-Stat functionality will be deprecated in a future version. +.. note:: This ensemble product generation step was provided by the Ensemble-Stat tool in earlier versions of MET. The Gen-Ens-Prod tool replaces and extends that functionality. Users are strongly encouraged to migrate ensemble product generation from Ensemble-Stat to Gen-Ens-Prod, as new features will only be added to Gen-Ens-Prod and the existing Ensemble-Stat functionality will be deprecated in a future version. Scientific and statistical aspects ================================== From 3f40dfd837939990c79b70e8ff046af52dd001ad Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Mon, 14 Mar 2022 16:03:39 -0600 Subject: [PATCH 161/172] update job control rules for GHA testing workflow to use version specific input data if running tests on main_v branch --- .github/jobs/set_job_controls.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh index 14f85ddb93..9d0cbfe577 100755 --- a/.github/jobs/set_job_controls.sh +++ b/.github/jobs/set_job_controls.sh @@ -17,6 +17,11 @@ if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then run_diff=true + # if base branch starts with main_v, use that input data + if [ "${GITHUB_BASE_REF:0:6}" == "main_v" ]; then + input_data_version=${GITHUB_BASE_REF:6} + fi + fi elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then @@ -30,6 +35,11 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then run_diff=true truth_data_version=${branch_name:0: -4} + # if branch starts with main_v, use that input data + if [ "${branch_name:0:6}" == "main_v" ]; then + input_data_version=${branch_name:6:-4} + fi + else # if develop or main_vX.Y branch, run diff tests using branch's truth data @@ -39,6 +49,11 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then run_diff=true truth_data_version=${branch_name} + # if branch starts with main_v, use that input data + if [ "${branch_name:0:6}" == "main_v" ]; then + input_data_version=${branch_name:6} + fi + fi # check commit messages for skip or force keywords From b312b8151b260651835d1b872f26d38915695104 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 15 Mar 2022 13:30:20 -0600 Subject: [PATCH 162/172] Migrating a small tweak added to the v10.1.0 release into the develop branch. --- met/README | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/met/README b/met/README index 9ea770c2bf..82fb383f4d 100644 --- a/met/README +++ b/met/README @@ -188,7 +188,7 @@ sub-directory, or the MET Online Tutorial: - If all tools are enabled and the build is successful, the "/bin" directory (where is the prefix you specified on your configure - command line) will contain 36 executables: + command line) will contain the following executables: - ascii2nc - ensemble_stat - gen_ens_prod @@ -200,6 +200,7 @@ sub-directory, or the MET Online Tutorial: - grid_diag - gsid2mpr - gsidens2orank + - ioda2nc - lidar2nc - madis2nc - mode From bdb90bb0f50fea6c327bb4ee56f3b1ccf0a9227f Mon Sep 17 00:00:00 2001 From: MET Tools Test Account Date: Thu, 17 Mar 2022 10:46:38 -0600 Subject: [PATCH 163/172] Adding SonarQube location to development.seneca file. --- scripts/environment/development.seneca | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/environment/development.seneca b/scripts/environment/development.seneca index 650257b3ab..ccbf506dbf 100644 --- a/scripts/environment/development.seneca +++ b/scripts/environment/development.seneca @@ -49,3 +49,8 @@ export MET_TEST_RSCRIPT=/usr/local/R-4.1.2/bin/Rscript export PATH="/usr/local/nco/bin:/usr/local/netcdf/bin:\ /usr/local/sbin:/usr/local/bin:/usr/sbin:\ /usr/bin:/sbin:/bin:/usr/bin/X11:/opt/bin:$PATH" + +# SonarQube +export SONARQUBE_DIR=/d1/projects/SonarQube/ +export SONARQUBE_WRAPPER_BIN=$SONARQUBE_DIR/build-wrapper-linux-x86 +export SONARQUBE_SCANNER_BIN=$SONARQUBE_DIR/sonar-scanner-4.6.2.2472-linux/bin From 6caff899d4f5c6a28230b3577837de2064391ad4 Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Mon, 28 Mar 2022 14:10:02 -0600 Subject: [PATCH 164/172] Bugfix #2102 develop initialize modified_hdr_typ (#2104) Co-authored-by: Howard Soh Co-authored-by: johnhg --- .github/dummy_for_action | 2 -- met/src/tools/other/ioda2nc/ioda2nc.cc | 10 +++------- 2 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 .github/dummy_for_action diff --git a/.github/dummy_for_action b/.github/dummy_for_action deleted file mode 100644 index 91bdf4d63e..0000000000 --- a/.github/dummy_for_action +++ /dev/null @@ -1,2 +0,0 @@ -#update me to add action comment - diff --git a/met/src/tools/other/ioda2nc/ioda2nc.cc b/met/src/tools/other/ioda2nc/ioda2nc.cc index cc36eed5fe..6fa1201a6e 100644 --- a/met/src/tools/other/ioda2nc/ioda2nc.cc +++ b/met/src/tools/other/ioda2nc/ioda2nc.cc @@ -351,7 +351,6 @@ void process_ioda_file(int i_pb) { ConcatString file_name, blk_prefix, blk_file, log_message; ConcatString prefix; - char time_str[max_str_len]; ConcatString start_time_str, end_time_str; char min_time_str[max_str_len], max_time_str[max_str_len]; @@ -378,10 +377,6 @@ void process_ioda_file(int i_pb) { conf_info.area_mask.ny() > 0); bool apply_poly_mask = (conf_info.poly_mask.n_points() > 0); - hdr_typ[0] = 0; - - file_ut = beg_ut = end_ut = hdr_vld_ut = (unixtime) 0; - // List the IODA file being processed mlog << Debug(1) << "Processing IODA File:\t" << ioda_files[i_pb]<< "\n"; @@ -399,17 +394,18 @@ void process_ioda_file(int i_pb) { } // Initialize + hdr_typ[0] = 0; + file_ut = beg_ut = end_ut = hdr_vld_ut = (unixtime) 0; filtered_times.clear(); min_msg_ut = max_msg_ut = (unixtime) 0; min_time_str[0] = 0; max_time_str[0] = 0; + modified_hdr_typ[0] = 0; // Set the file name for the IODA file file_name << ioda_files[i_pb]; - int nrecs = 0; - //int nstring = 0; StringArray var_names, dim_names; StringArray metadata_vars; StringArray obs_value_vars; From c0e19447eaf58d5dd73fe18923d9275ba526876a Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:48:56 -0600 Subject: [PATCH 165/172] =?UTF-8?q?added=20logic=20to=20manually=20trigger?= =?UTF-8?q?=20a=20workflow=20via=20the=20GitHub=E2=80=A6=20(develop)=20(#2?= =?UTF-8?q?109)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: John Halley Gotway --- .github/jobs/set_job_controls.sh | 8 +++++++- .github/workflows/testing.yml | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh index 9d0cbfe577..3cb1389658 100755 --- a/.github/jobs/set_job_controls.sh +++ b/.github/jobs/set_job_controls.sh @@ -81,7 +81,13 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then fi fi - + +elif [ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]; then + + if [ "${force_tests}" == "true" ]; then + run_diff=true + fi + fi # if updating truth or running diff, run unit tests diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 88332b4da0..550add3594 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -23,6 +23,13 @@ on: paths-ignore: - 'met/docs/**' + workflow_dispatch: + inputs: + force_tests: + description: 'Run the unit tests' + default: true + type: boolean + env: DOCKERHUB_REPO: dtcenter/met-dev @@ -39,6 +46,7 @@ jobs: run: .github/jobs/set_job_controls.sh env: commit_msg: ${{ github.event.head_commit.message }} + force_tests: ${{ github.event.inputs.force_tests }} outputs: run_compile: ${{ steps.job_status.outputs.run_compile }} From f5f7a4131dfc336aad7dc961c45a4600539cc86c Mon Sep 17 00:00:00 2001 From: jprestop Date: Wed, 30 Mar 2022 15:44:19 -0600 Subject: [PATCH 166/172] Feature update installation info (#2114) * Updating configuration and modulefiles * Removed jet files --- .../installation/config/install_MET_env.dell | 4 +-- .../installation/config/install_met_env.acorn | 35 ++++++++++++++++++ .../config/install_met_env.dogwood | 36 +++++++++++++++++++ .../installation/config/install_met_env.jet | 11 ------ .../installation/config/install_met_env.orion | 4 +-- .../config/install_met_env.stampede | 28 +++++++++++++++ .../config/install_met_env_all.casper | 29 ++++++++++----- .../config/install_met_env_all.cheyenne | 24 +++++++++---- .../config/install_met_env_all.hera | 14 +++++--- .../config/install_met_env_met_only.hera | 14 +++++--- .../config/install_met_env_met_only.orion | 26 ++++++++++++++ .../config/install_met_env_met_only.stampede | 6 ++-- .../installation/modulefiles/10.0.0_casper | 20 ----------- scripts/installation/modulefiles/10.0.0_jet | 21 ----------- scripts/installation/modulefiles/10.1.0_acorn | 34 ++++++++++++++++++ .../{10.0.0_cheyenne => 10.1.0_casper} | 14 ++++---- .../installation/modulefiles/10.1.0_cheyenne | 29 +++++++++++++++ .../modulefiles/{10.0.0_dell => 10.1.0_dell} | 6 ++-- .../installation/modulefiles/10.1.0_dogwood | 32 +++++++++++++++++ .../modulefiles/{10.0.0_hera => 10.1.0_hera} | 23 ++++++------ .../{10.0.0_orion => 10.1.0_orion} | 16 ++++----- .../{10.0.0_stampede => 10.1.0_stampede} | 7 ++-- 22 files changed, 316 insertions(+), 117 deletions(-) create mode 100644 scripts/installation/config/install_met_env.acorn create mode 100644 scripts/installation/config/install_met_env.dogwood delete mode 100644 scripts/installation/config/install_met_env.jet create mode 100644 scripts/installation/config/install_met_env.stampede create mode 100644 scripts/installation/config/install_met_env_met_only.orion delete mode 100644 scripts/installation/modulefiles/10.0.0_casper delete mode 100755 scripts/installation/modulefiles/10.0.0_jet create mode 100644 scripts/installation/modulefiles/10.1.0_acorn rename scripts/installation/modulefiles/{10.0.0_cheyenne => 10.1.0_casper} (70%) create mode 100644 scripts/installation/modulefiles/10.1.0_cheyenne rename scripts/installation/modulefiles/{10.0.0_dell => 10.1.0_dell} (93%) create mode 100644 scripts/installation/modulefiles/10.1.0_dogwood rename scripts/installation/modulefiles/{10.0.0_hera => 10.1.0_hera} (76%) rename scripts/installation/modulefiles/{10.0.0_orion => 10.1.0_orion} (81%) rename scripts/installation/modulefiles/{10.0.0_stampede => 10.1.0_stampede} (82%) diff --git a/scripts/installation/config/install_MET_env.dell b/scripts/installation/config/install_MET_env.dell index 5c3dbdb673..76eae86a2c 100644 --- a/scripts/installation/config/install_MET_env.dell +++ b/scripts/installation/config/install_MET_env.dell @@ -9,12 +9,12 @@ module load libpng/1.2.59 module load gsl/2.1 module load g2c/1.6.3 -export TEST_BASE=/gpfs/dell2/emc/verification/noscrub/emc.metplus/met/10.0.0 +export TEST_BASE=/gpfs/dell2/emc/verification/noscrub/emc.metplus/met/10.1.0 export LIB_DIR=${TEST_BASE}/external_libs export BIN_DIR_PATH=${TEST_BASE}/exec export COMPILER=ips_18.0.5.274 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE export PYTHON_MODULE=python_3.6.3 export MET_PYTHON=/usrx/local/prod/packages/python/3.6.3/ diff --git a/scripts/installation/config/install_met_env.acorn b/scripts/installation/config/install_met_env.acorn new file mode 100644 index 0000000000..4a77956e6e --- /dev/null +++ b/scripts/installation/config/install_met_env.acorn @@ -0,0 +1,35 @@ +module use /apps/ops/para/libs/modulefiles/compiler/intel/19.1.3.304/ +module load intel +module load python/3.8.6 +module load netcdf/4.7.4 +module load hdf5/1.10.6 +module load bufr/11.5.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 + +export TEST_BASE=/lfs/h1/emc/vpppg/noscrub/Julie.Prestopnik/MET/10.1.0 +export LIB_DIR=${TEST_BASE}/external_libs +export BIN_DIR_PATH=${TEST_BASE}/exec +export COMPILER=intel_19.1.3.304 +export MET_SUBDIR=${TEST_BASE} +export MET_TARBALL=met-10.1.0.20220314.tar.gz +export USE_MODULES=TRUE +export PYTHON_MODULE=python_3.8.6 +export MET_PYTHON=/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk +export MET_PYTHON_CC=-I/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk/include/python3.8 +export MET_PYTHON_LD=-L/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk/lib\ -lpython3.8\ -lpthread\ -ldl\ -lutil\ -lm\ -Xlinker\ -export-dynamic +export MET_NETCDF=/apps/prod/hpc-stack/intel-19.1.3.304/netcdf/4.7.4 +export MET_HDF5=/apps/prod/hpc-stack/intel-19.1.3.304/hdf5/1.10.6 +export MET_BUFRLIB=/apps/ops/prod/libs/intel/19.1.3.304/bufr/11.5.0/lib64 +export MET_GRIB2CLIB=/apps/ops/prod/libs/intel/19.1.3.304/g2c/1.6.4/lib64 +export MET_GRIB2CINC=/apps/ops/prod/libs/intel/19.1.3.304/g2c/1.6.4/include +export MET_GSL=/apps/spack/gsl/2.7/intel/19.1.3.304/xks7dxbowrdxhjck5zxc4rompopocevb +export BUFRLIB_NAME=-lbufr_4 +export GRIB2CLIB_NAME=-lg2c +export LIB_JASPER=/apps/spack/jasper/2.0.25/intel/19.1.3.304/sjib74krrorkyczqpqah4tvewmlnqdx4/lib64 +export LIB_LIBPNG=/apps/spack/libpng/1.6.37/intel/19.1.3.304/4ohkronuhlyherusoszzrmur5ewvlwzh/lib +export LIB_Z=/apps/spack/zlib/1.2.11/intel/19.1.3.304/hjotqkckeoyt6j6tibalwzrlfljcjtdh/lib +export SET_D64BIT=FALSE \ No newline at end of file diff --git a/scripts/installation/config/install_met_env.dogwood b/scripts/installation/config/install_met_env.dogwood new file mode 100644 index 0000000000..e1644ae7e7 --- /dev/null +++ b/scripts/installation/config/install_met_env.dogwood @@ -0,0 +1,36 @@ +module use /apps/ops/para/libs/modulefiles/compiler/intel/19.1.3.304/ +module load intel +module load python/3.8.6 +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.6 +module load g2c/1.6.4 + +export TEST_BASE=/lfs/h2/emc/vpppg/noscrub/Julie.Prestopnik/MET/10.1.0 +export LIB_DIR=${TEST_BASE}/external_libs +export BIN_DIR_PATH=${TEST_BASE}/exec +export COMPILER=intel_19.1.3.304 +export MET_SUBDIR=${TEST_BASE} +export MET_TARBALL=met-10.1.0.20220314.tar.gz +export USE_MODULES=TRUE +export PYTHON_MODULE=python_3.8.6 +export MET_PYTHON=/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk +export MET_PYTHON_CC=-I/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk/include/python3.8 +export MET_PYTHON_LD=-L/apps/spack/python/3.8.6/intel/19.1.3.304/pjn2nzkjvqgmjw4hmyz43v5x4jbxjzpk/lib\ -lpython3.8\ -lpthread\ -ldl\ -lutil\ -lm\ -Xlinker\ -export-dynamic +export MET_NETCDF=/apps/prod/hpc-stack/intel-19.1.3.304/netcdf/4.7.4 +export MET_HDF5=/apps/prod/hpc-stack/intel-19.1.3.304/hdf5/1.10.6 +export MET_BUFRLIB=/apps/ops/prod/libs/intel/19.1.3.304/bufr/11.5.0/lib64 +export MET_GRIB2CLIB=/apps/ops/prod/libs/intel/19.1.3.304/g2c/1.6.4/lib64 +export MET_GRIB2CINC=/apps/ops/prod/libs/intel/19.1.3.304/g2c/1.6.4/include +export MET_GSL=$GSL_ROOT +export BUFRLIB_NAME=-lbufr_4 +export GRIB2CLIB_NAME=-lg2c +export LIB_JASPER=/apps/spack/jasper/2.0.25/intel/19.1.3.304/sjib74krrorkyczqpqah4tvewmlnqdx4/lib64 +export LIB_LIBPNG=/apps/spack/libpng/1.6.37/intel/19.1.3.304/4ohkronuhlyherusoszzrmur5ewvlwzh/lib +export LIB_Z=/apps/spack/zlib/1.2.11/intel/19.1.3.304/hjotqkckeoyt6j6tibalwzrlfljcjtdh/lib +export SET_D64BIT=FALSE + diff --git a/scripts/installation/config/install_met_env.jet b/scripts/installation/config/install_met_env.jet deleted file mode 100644 index 19cd1be739..0000000000 --- a/scripts/installation/config/install_met_env.jet +++ /dev/null @@ -1,11 +0,0 @@ -export TEST_BASE=/contrib/met/10.0.0 -export COMPILER=intel_18.0.5.274 -export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=met-10.0.0.20210510.tar.gz -export USE_MODULES=TRUE -export PYTHON_MODULE=intelpython_3.6.5 -export MET_PYTHON=/apps/intel/intelpython3 -export MET_PYTHON_CC=-I/apps/intel/intelpython3/include/python3.6m -export MET_PYTHON_LD=-L/apps/intel/intelpython3/lib\ -lpython3.6m\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm\ -Xlinker\ -export-dynamic -export MET_NETCDF=/apps/netcdf/4.6.1/intel/18.0.5.274 -export MET_HDF5=/apps/hdf5/1.10.4/intel_seq/18.0.5.274 diff --git a/scripts/installation/config/install_met_env.orion b/scripts/installation/config/install_met_env.orion index 790407dd51..dcad39eb26 100644 --- a/scripts/installation/config/install_met_env.orion +++ b/scripts/installation/config/install_met_env.orion @@ -1,10 +1,10 @@ module load intel/2020.2 module load intelpython3/2020.2 -export TEST_BASE=/apps/contrib/MET/10.0.0 +export TEST_BASE=/apps/contrib/MET/10.1.0 export COMPILER=intel_2020 export MET_SUBDIR=${TEST_BASE}/ -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/apps/intel-2020.2/intel-2020.2/intelpython3 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.7m diff --git a/scripts/installation/config/install_met_env.stampede b/scripts/installation/config/install_met_env.stampede new file mode 100644 index 0000000000..8b961c99e8 --- /dev/null +++ b/scripts/installation/config/install_met_env.stampede @@ -0,0 +1,28 @@ +module load intel/18.0.2 +module load python3/3.7.0 +module load hdf5/1.10.4 +module load netcdf/4.6.2 + +export TEST_BASE=/work2/06612/tg859120/stampede2/met/10.1.0 +export COMPILER=intel_18.0.2 +export MET_SUBDIR=${TEST_BASE}/ +export MET_TARBALL=met-10.1.0.20220314.tar.gz +export USE_MODULES=TRUE +export MET_PYTHON=/opt/apps/intel18/python3/3.7.0 +export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.7m +export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.7m\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm +export MET_HDF5=/opt/apps/intel18/hdf5/1.10.4/x86_64/ +export MET_NETCDF=/opt/apps/intel18/netcdf/4.6.2/x86_64/ +#export EXTERNAL_LIBS=/work2/06612/tg859120/stampede2/met/10.1.0/external_libs +#export MET_GSL=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export BUFRLIB_NAME=-lbufr +#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +#export MET_GRIB2CINC=${EXTERNAL_LIBS}/include +#export GRIB2CLIB_NAME=-lgrib2c +#export LIB_JASPER=${EXTERNAL_LIBS}/lib +#export LIB_LIBPNG=${EXTERNAL_LIBS}/lib +#export LIB_Z=${EXTERNAL_LIBS}/lib +#export SET_D64BIT=FALSE +#export CFLAGS="-Wall -g" +#export CXXFLAGS="-Wall -g" diff --git a/scripts/installation/config/install_met_env_all.casper b/scripts/installation/config/install_met_env_all.casper index 360d65ea44..f54f0bb00f 100644 --- a/scripts/installation/config/install_met_env_all.casper +++ b/scripts/installation/config/install_met_env_all.casper @@ -1,17 +1,30 @@ -module load intel/19.0.5 -module load python/3.7.5 -module load netcdf/4.7.4 +module load ncarenv/1.3 +module load intel/2021.2 +module load python/3.7.9 +module load netcdf/4.8.0 ncar_pylib -export TEST_BASE=/glade/p/ral/jntp/MET/MET_releases/casper/10.0.0 -export COMPILER=intel_19.0.5 +export TEST_BASE=/glade/p/ral/jntp/MET/MET_releases/casper/10.1.0 +export COMPILER=intel_2021.2 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE -export MET_PYTHON=/glade/u/apps/dav/opt/python/3.7.5/gnu/8.3.0/ +export MET_PYTHON=/glade/u/apps/ch/opt/python/3.7.9/gnu/9.1.0 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.7m export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.7m\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lm -export MET_NETCDF=/glade/u/apps/dav/opt/netcdf/4.7.3/intel/19.0.5 +export MET_NETCDF=/glade/u/apps/ch/opt/netcdf/4.8.0/intel/2021.2/ +export MET_HDF5=/glade/u/apps/ch/opt/netcdf/4.8.0/intel/2021.2/ +#export EXTERNAL_LIBS=/glade/p/ral/jntp/MET/MET_releases/casper/10.1.0/external_libs +#export MET_GSL=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export BUFRLIB_NAME=-lbufr +#export MET_HDF5=${EXTERNAL_LIBS} +#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +#export MET_GRIB2CINC=${EXTERNAL_LIBS}/include +#export GRIB2CLIB_NAME=-lgrib2c +#export LIB_JASPER=${EXTERNAL_LIBS}/lib +#export LIB_LIBPNG=${EXTERNAL_LIBS}/lib +#export LIB_Z=${EXTERNAL_LIBS}/lib export SET_D64BIT=FALSE #export CFLAGS="-Wall -g" #export CXXFLAGS="-Wall -g" diff --git a/scripts/installation/config/install_met_env_all.cheyenne b/scripts/installation/config/install_met_env_all.cheyenne index 1c9b9533a6..a7f39a0064 100644 --- a/scripts/installation/config/install_met_env_all.cheyenne +++ b/scripts/installation/config/install_met_env_all.cheyenne @@ -1,18 +1,30 @@ module load ncarenv/1.3 -module load intel/19.0.5 +module load intel/2021.2 module load python/3.7.9 -module load netcdf/4.7.4 +module load netcdf/4.8.0 ncar_pylib -export TEST_BASE=/glade/p/ral/jntp/MET/MET_releases/10.0.0 -export COMPILER=intel_19.0.5 +export TEST_BASE=/glade/p/ral/jntp/MET/MET_releases/10.1.0 +export COMPILER=intel_2021.2 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/glade/u/apps/ch/opt/python/3.7.9/gnu/9.1.0 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.7m export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.7m\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lm -export MET_NETCDF=/glade/u/apps/ch/opt/netcdf/4.7.4/intel/19.0.5/ +export MET_NETCDF=/glade/u/apps/ch/opt/netcdf/4.8.0/intel/2021.2/ +export MET_HDF5=/glade/u/apps/ch/opt/netcdf/4.8.0/intel/2021.2/ +#export EXTERNAL_LIBS=/glade/p/ral/jntp/MET/MET_releases/10.1.0/external_libs +#export MET_GSL=${EXTERNAL_LIBS} +#export MET_BUFRLIB=${EXTERNAL_LIBS} +#export BUFRLIB_NAME=-lbufr +#export MET_HDF5=${EXTERNAL_LIBS} +#export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +#export MET_GRIB2CINC=${EXTERNAL_LIBS}/include +#export GRIB2CLIB_NAME=-lgrib2c +#export LIB_JASPER=${EXTERNAL_LIBS}/lib +#export LIB_LIBPNG=${EXTERNAL_LIBS}/lib +#export LIB_Z=${EXTERNAL_LIBS}/lib export SET_D64BIT=FALSE #export CFLAGS="-Wall -g" #export CXXFLAGS="-Wall -g" diff --git a/scripts/installation/config/install_met_env_all.hera b/scripts/installation/config/install_met_env_all.hera index a9ea2355bd..7ac6267a46 100644 --- a/scripts/installation/config/install_met_env_all.hera +++ b/scripts/installation/config/install_met_env_all.hera @@ -1,10 +1,14 @@ +module load intel/2022.1.2 impi/2022.1.2 +module load intel-tools +module load intelpython/3.6.5 + module use -a /contrib/anaconda/modulefiles -module load intel/18.0.5.274 -module load anaconda/latest -export TEST_BASE=/contrib/met/10.0.0 -export COMPILER=intel_18.0.5.274 +module load intel/2022.1.2 +module load anaconda/latest +export TEST_BASE=/contrib/met/10.1.0 +export COMPILER=intel_2022.1.2 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE export PYTHON_MODULE=anaconda_latest export MET_PYTHON=/contrib/anaconda/anaconda3/latest/ diff --git a/scripts/installation/config/install_met_env_met_only.hera b/scripts/installation/config/install_met_env_met_only.hera index 7966263813..591f42fa49 100644 --- a/scripts/installation/config/install_met_env_met_only.hera +++ b/scripts/installation/config/install_met_env_met_only.hera @@ -1,16 +1,20 @@ +module load intel/2022.1.2 impi/2022.1.2 +module load intel-tools +module load intelpython/3.6.5 + module use -a /contrib/anaconda/modulefiles -module load intel/18.0.5.274 +module load intel/2022.1.2 module load anaconda/latest -export TEST_BASE=/contrib/met/10.0.0 -export COMPILER=intel_18.0.5.274 +export TEST_BASE=/contrib/met/10.1.0 +export COMPILER=intel_2022.1.2 export MET_SUBDIR=${TEST_BASE} -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE export PYTHON_MODULE=anaconda_latest export MET_PYTHON=/contrib/anaconda/anaconda3/latest/ export MET_PYTHON_CC=-I${MET_PYTHON}include/python3.7m export MET_PYTHON_LD=-L${MET_PYTHON}/lib/python3.7/config-3.7m-x86_64-linux-gnu\ -L${MET_PYTHON}/lib\ -lpython3.7m\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm\ -Xlinker\ -export-dynamic -export EXTERNAL_LIBS=/contrib/met/10.0.0/external_libs/ +export EXTERNAL_LIBS=/contrib/met/10.1.0/external_libs/ export MET_NETCDF=${EXTERNAL_LIBS} export MET_GSL=${EXTERNAL_LIBS} export MET_BUFRLIB=${EXTERNAL_LIBS} diff --git a/scripts/installation/config/install_met_env_met_only.orion b/scripts/installation/config/install_met_env_met_only.orion new file mode 100644 index 0000000000..a869ff8d27 --- /dev/null +++ b/scripts/installation/config/install_met_env_met_only.orion @@ -0,0 +1,26 @@ +module load intel/2020.2 +module load intelpython3/2020.2 + +export TEST_BASE=/apps/contrib/MET/10.1.0 +export COMPILER=intel_2020 +export MET_SUBDIR=${TEST_BASE}/ +export MET_TARBALL=met-10.1.0.20220314.tar.gz +export USE_MODULES=TRUE +export MET_PYTHON=/apps/intel-2020.2/intel-2020.2/intelpython3 +export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.7m +export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.7m\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm +export EXTERNAL_LIBS=/apps/contrib/MET/10.1.0/external_libs +export MET_GSL=${EXTERNAL_LIBS} +export MET_BUFRLIB=${EXTERNAL_LIBS} +export BUFRLIB_NAME=-lbufr +export MET_HDF5=${EXTERNAL_LIBS} +export MET_NETCDF=${EXTERNAL_LIBS} +export MET_GRIB2CLIB=${EXTERNAL_LIBS}/lib +export MET_GRIB2CINC=${EXTERNAL_LIBS}/include +export GRIB2CLIB_NAME=-lgrib2c +export LIB_JASPER=${EXTERNAL_LIBS}/lib +export LIB_LIBPNG=${EXTERNAL_LIBS}/lib +export LIB_Z=${EXTERNAL_LIBS}/lib +export SET_D64BIT=FALSE +export CFLAGS="-Wall -g" +export CXXFLAGS="-Wall -g" diff --git a/scripts/installation/config/install_met_env_met_only.stampede b/scripts/installation/config/install_met_env_met_only.stampede index 7113983130..18495660ab 100644 --- a/scripts/installation/config/install_met_env_met_only.stampede +++ b/scripts/installation/config/install_met_env_met_only.stampede @@ -3,17 +3,17 @@ module load python3/3.7.0 module load hdf5/1.10.4 module load netcdf/4.6.2 -export TEST_BASE=/work2/06612/tg859120/stampede2/met/10.0.0 +export TEST_BASE=/work2/06612/tg859120/stampede2/met/10.1.0 export COMPILER=intel_18.0.2 export MET_SUBDIR=${TEST_BASE}/ -export MET_TARBALL=met-10.0.0.20210510.tar.gz +export MET_TARBALL=met-10.1.0.20220314.tar.gz export USE_MODULES=TRUE export MET_PYTHON=/opt/apps/intel18/python3/3.7.0 export MET_PYTHON_CC=-I${MET_PYTHON}/include/python3.7m export MET_PYTHON_LD=-L${MET_PYTHON}/lib\ -lpython3.7m\ -lcrypt\ -lpthread\ -ldl\ -lutil\ -lrt\ -lm export MET_HDF5=/opt/apps/intel18/hdf5/1.10.4/x86_64/ export MET_NETCDF=/opt/apps/intel18/netcdf/4.6.2/x86_64/ -export EXTERNAL_LIBS=/work2/06612/tg859120/stampede2/met/10.0.0/external_libs +export EXTERNAL_LIBS=/work2/06612/tg859120/stampede2/met/10.1.0/external_libs export MET_GSL=${EXTERNAL_LIBS} export MET_BUFRLIB=${EXTERNAL_LIBS} export BUFRLIB_NAME=-lbufr diff --git a/scripts/installation/modulefiles/10.0.0_casper b/scripts/installation/modulefiles/10.0.0_casper deleted file mode 100644 index 27504264a6..0000000000 --- a/scripts/installation/modulefiles/10.0.0_casper +++ /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 v10.0.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 intel/19.0.5 -module load python/3.7.5 -module load netcdf/4.7.4 - -set base /glade/p/ral/jntp/MET/MET_releases/casper/10.0.0 -set ver 10.0.0 -set share $base/share/met - -prepend-path PATH $base/bin:/glade/p/ral/jntp/MET/MET_releases/casper/10.0.0/external_libs/bin - -setenv METversion V$ver diff --git a/scripts/installation/modulefiles/10.0.0_jet b/scripts/installation/modulefiles/10.0.0_jet deleted file mode 100755 index 4d379eb920..0000000000 --- a/scripts/installation/modulefiles/10.0.0_jet +++ /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 v10.0.0 - *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" -} - -prereq intel -prereq intelpython/3.6.5 -prereq netcdf/4.6.1 -prereq hdf5/1.10.4 - -set base /contrib/met/10.0.0 -set ver 10.0.0 -set share $base/share/met - -prepend-path PATH $base/bin:$base/external_libs/bin:/apps/intel/intelpython3/bin:/apps/netcdf/4.6.1/intel/18.0.5.274/bin:/apps/hdf5/1.10.4/intel_seq/18.0.5.274/bin - - diff --git a/scripts/installation/modulefiles/10.1.0_acorn b/scripts/installation/modulefiles/10.1.0_acorn new file mode 100644 index 0000000000..56d2d6d8dc --- /dev/null +++ b/scripts/installation/modulefiles/10.1.0_acorn @@ -0,0 +1,34 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.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 load python/3.8.6 +module load netcdf/4.7.4 +module load hdf5/1.10.6 +module load bufr/11.5.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 + +set base /lfs/h2/emc/vpppg/noscrub/Julie.Prestopnik/MET/10.1.0 +set ver 10.1.0 +set share $base/share/met +set lib_base $base + +prepend-path PATH $base/exec + +setenv METversion V$ver +setenv MET_ROOT $base + + diff --git a/scripts/installation/modulefiles/10.0.0_cheyenne b/scripts/installation/modulefiles/10.1.0_casper similarity index 70% rename from scripts/installation/modulefiles/10.0.0_cheyenne rename to scripts/installation/modulefiles/10.1.0_casper index 98bd539cfc..ac50f68913 100644 --- a/scripts/installation/modulefiles/10.0.0_cheyenne +++ b/scripts/installation/modulefiles/10.1.0_casper @@ -3,23 +3,23 @@ ## Model Evaluation Tools ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.0.0 + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.1.0 *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } -# If they exist, remove ncdump and ncgen from /glade/p/ral/jntp/MET/MET_releases/10.0.0/external_libs/bin +# If they exist, remove ncdump and ncgen from /glade/p/ral/jntp/MET/MET_releases/casper/10.1.0/external_libs/bin # The intel compiler is required to run MET module load ncarenv/1.3 -module load intel/19.0.5 +module load intel/2021.2 module load python/3.7.9 -module load netcdf/4.7.4 +module load netcdf/4.8.0 -set base /glade/p/ral/jntp/MET/MET_releases/10.0.0 -set ver 10.0.0 +set base /glade/p/ral/jntp/MET/MET_releases/casper/10.1.0 +set ver 10.1.0 set share $base/share/met -prepend-path PATH $base/bin:/glade/p/ral/jntp/MET/MET_releases/10.0.0/external_libs/bin +prepend-path PATH $base/bin:/glade/p/ral/jntp/MET/MET_releases/casper/10.1.0/external_libs/bin setenv METversion V$ver diff --git a/scripts/installation/modulefiles/10.1.0_cheyenne b/scripts/installation/modulefiles/10.1.0_cheyenne new file mode 100644 index 0000000000..e3a408ff8f --- /dev/null +++ b/scripts/installation/modulefiles/10.1.0_cheyenne @@ -0,0 +1,29 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.1.0 + *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" +} + +# If they exist, remove ncdump and ncgen from /glade/p/ral/jntp/MET/MET_releases/10.1.0/external_libs/bin + +# The intel compiler is required to run MET +module load ncarenv/1.3 +module load intel/2021.2 +module load python/3.7.9 +module load netcdf/4.8.0 + +set base /glade/p/ral/jntp/MET/MET_releases/10.1.0 +set ver 10.1.0 +set share $base/share/met + +prepend-path PATH $base/bin:/glade/p/ral/jntp/MET/MET_releases/10.1.0/external_libs/bin + + +setenv METversion V$ver + +# setenv MET_BUFRLIB /glade/p/ral/jntp/MET/MET_releases/10.1.0/external_libs/libs +# setenv MET_GRIB2C /glade/p/ral/jntp/MET/MET_releases/10.1.0/external_libs +# setenv MET_GSL /glade/p/ral/jntp/MET/MET_releases/10.1.0/external_libs diff --git a/scripts/installation/modulefiles/10.0.0_dell b/scripts/installation/modulefiles/10.1.0_dell similarity index 93% rename from scripts/installation/modulefiles/10.0.0_dell rename to scripts/installation/modulefiles/10.1.0_dell index 05e23803e1..320248ca3a 100644 --- a/scripts/installation/modulefiles/10.0.0_dell +++ b/scripts/installation/modulefiles/10.1.0_dell @@ -3,7 +3,7 @@ ## Model Evaluation Tools ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.0.0 + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.1.0 *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } @@ -20,8 +20,8 @@ module load zlib/1.2.11 module load gsl/2.1 module load g2c/1.6.3 -set base /gpfs/dell2/emc/verification/noscrub/emc.metplus/met/10.0.0 -set ver 10.0.0 +set base /gpfs/dell2/emc/verification/noscrub/emc.metplus/met/10.1.0 +set ver 10.1.0 set share $base/share/met set lib_base $base diff --git a/scripts/installation/modulefiles/10.1.0_dogwood b/scripts/installation/modulefiles/10.1.0_dogwood new file mode 100644 index 0000000000..82d86411c3 --- /dev/null +++ b/scripts/installation/modulefiles/10.1.0_dogwood @@ -0,0 +1,32 @@ +#%Module###################################################################### +## +## Model Evaluation Tools +## +proc ModulesHelp { } { + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.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 load python/3.8.6 +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.6 +module load g2c/1.6.4 + +set base /lfs/h2/emc/vpppg/noscrub/Julie.Prestopnik/MET/10.1.0 +set ver 10.1.0 +set share $base/share/met +set lib_base $base + +prepend-path PATH $base/exec + +setenv METversion V$ver +setenv MET_ROOT $base diff --git a/scripts/installation/modulefiles/10.0.0_hera b/scripts/installation/modulefiles/10.1.0_hera similarity index 76% rename from scripts/installation/modulefiles/10.0.0_hera rename to scripts/installation/modulefiles/10.1.0_hera index 216c567fb8..7e3294d7f9 100644 --- a/scripts/installation/modulefiles/10.0.0_hera +++ b/scripts/installation/modulefiles/10.1.0_hera @@ -1,9 +1,9 @@ -#%Module###################################################################### +%Module###################################################################### ## ## Model Evaluation Tools ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.0.0 + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.1.0 *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } @@ -12,18 +12,16 @@ prereq intel prereq anaconda/latest set base /contrib/met -set ver 10.0.0 +set ver 10.1.0 set share $base/$ver/share/met -set lib_base $base/10.0.0 - +set lib_base $base/10.1.0 prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin - #prepend-path LD_LIBRARY_PATH $lib_base/external_libs/lib #setenv METversion $ver -#setenv MET_ROOT $base/$ver/met-10.0.0-beta5 +#setenv MET_ROOT $base/$ver/met-10.1.0 #setenv MET_CONFIG $share/config #setenv MET_POLY $share/poly #setenv MET_COLORTABLES $share/colortables @@ -35,13 +33,13 @@ prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin #setenv CXX icc #setenv F77 ifort -#module load intel/18.0.5.274 +#module load intel/2022.1.2 #module load anaconda/latest -#setenv libdir /contrib/met/10.0.0-beta5/external_libs/lib -#setenv incdir /contrib/met/10.0.0-beta5/external_libs/include -#setenv iprefix /contrib/met/10.0.0-beta5/external_libs -#setenv basedir /contrib/met/10.0.0-beta5/met-10.0.0-beta5 +#setenv libdir /contrib/met/10.1.0/external_libs/lib +#setenv incdir /contrib/met/10.1.0/external_libs/include +#setenv iprefix /contrib/met/10.1.0/external_libs +#setenv basedir /contrib/met/10.1.0/met-10.1.0 #setenv MET_HDF5 $iprefix #setenv MET_NETCDF $incdir @@ -65,4 +63,3 @@ prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin #setenv MET_FREETYPELIB $libdir #setenv MET_FREETYPEINC $incdir/freetype2 - diff --git a/scripts/installation/modulefiles/10.0.0_orion b/scripts/installation/modulefiles/10.1.0_orion similarity index 81% rename from scripts/installation/modulefiles/10.0.0_orion rename to scripts/installation/modulefiles/10.1.0_orion index cbc04944f5..05f7971e9a 100644 --- a/scripts/installation/modulefiles/10.0.0_orion +++ b/scripts/installation/modulefiles/10.1.0_orion @@ -3,7 +3,7 @@ ## Model Evaluation Tools ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.0.0. + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.1.0. *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } @@ -11,9 +11,10 @@ prereq intel/2020.2 prereq intelpython3/2020.2 set base /apps/contrib/MET -set ver 10.0.0 +set ver 10.1.0 set share $base/$ver/share/met -set lib_base $base/10.0.0 +set lib_base $base/10.1.0 + prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin @@ -22,10 +23,10 @@ prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin #export F77=ifort #module load intel/2020.2 #module load intelpython3/2020.2 -#export libdir=/apps/contrib/met/10.0.0/external_libs/lib -#export incdir=/apps/contrib/met/10.0.0/external_libs/include -#export iprefix=/apps/contrib/met/10.0.0/external_libs -#export basedir=/apps/contrib/met/10.0.0/met-10.0.0 +#export libdir=/apps/contrib/met/10.1.0/external_libs/lib +#export incdir=/apps/contrib/met/10.1.0/external_libs/include +#export iprefix=/apps/contrib/met/10.1.0/external_libs +#export basedir=/apps/contrib/met/10.1.0/met-10.1.0 #export MET_HDF5=$iprefix #export MET_NETCDF=$incdir #export MET_GRIB2CINC=$incdir @@ -43,4 +44,3 @@ prepend-path PATH $base/$ver/bin:$lib_base/external_libs/bin #export MET_FONT_DIR=$basedir/fonts/ #export LDFLAGS=-Wl,--disable-new-dtags -Wl,-rpath,${libdir}:${MET_PYTHON}/lib #export CPPFLAGS=-I/apps/contrib/met/10.0.0/external_libs/include - diff --git a/scripts/installation/modulefiles/10.0.0_stampede b/scripts/installation/modulefiles/10.1.0_stampede similarity index 82% rename from scripts/installation/modulefiles/10.0.0_stampede rename to scripts/installation/modulefiles/10.1.0_stampede index baf04f43f0..aa62ef1fe6 100644 --- a/scripts/installation/modulefiles/10.0.0_stampede +++ b/scripts/installation/modulefiles/10.1.0_stampede @@ -3,7 +3,7 @@ ## Model Evaluation Tools ## proc ModulesHelp { } { - puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.0.0 + puts stderr "Sets up the paths and environment variables to use the Model Evaluation Tools v10.1.0 *** For help see the official MET webpage at http://www.dtcenter.org/met/users ***" } @@ -12,8 +12,8 @@ module load python3/3.7.0 module load hdf5/1.10.4 module load netcdf/4.6.2 -set base /work2/06612/tg859120/stampede2/met/10.0.0 -set ver 10.0.0 +set base /work2/06612/tg859120/stampede2/met/10.1.0 +set ver 10.1.0 set share $base/share/met set lib_base $base @@ -21,3 +21,4 @@ prepend-path PATH $base/bin setenv METversion V$ver setenv MET_ROOT $base + From f1e7e9f2fa6e3108e386e52f3affb51e8063ab0a Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 30 Mar 2022 17:16:49 -0600 Subject: [PATCH 167/172] create DockerHub tag that ends with -lite to use when triggering the METplus testing workflow --- .github/workflows/build_docker_and_trigger_metplus.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml index ed97e44d80..63c306f7e1 100644 --- a/.github/workflows/build_docker_and_trigger_metplus.yml +++ b/.github/workflows/build_docker_and_trigger_metplus.yml @@ -25,13 +25,13 @@ jobs: - name: Build Docker Image run: .github/jobs/build_docker_image.sh env: - SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }} + SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }}-lite MET_BASE_IMAGE: minimum - name: Push Docker Image run: .github/jobs/push_docker_image.sh env: - SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }} + SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }}-lite DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} From f75e27cd39615fc13cb23f890d6198e673b6f0c3 Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 1 Apr 2022 07:40:37 -0600 Subject: [PATCH 168/172] Bugfix #2115 develop Rotated LatLon (#2117) --- met/src/libcode/vx_data2d_nccf/nccf_file.cc | 6 ++++-- test/xml/unit_plot_data_plane.xml | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.cc b/met/src/libcode/vx_data2d_nccf/nccf_file.cc index 7ccdd710ae..dbe5e4e323 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.cc +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.cc @@ -2430,10 +2430,12 @@ void NcCfFile::get_grid_mapping_rotated_latitude_longitude(const NcVar *grid_map data.name = rotated_latlon_proj_type; - // Derive south pole location from the north pole + // Derive south pole location from the north pole: + // - Reverse the sign of the latitude + // - Add 180 to the longitude and switch from degrees east to west data.true_lat_south_pole = -1.0 * get_att_value_double(grid_np_lat_att); double np_lon = rescale_lon(get_att_value_double(grid_np_lon_att)); - data.true_lon_south_pole = rescale_lon(-1.0 * (180.0 - fabs(np_lon))); + data.true_lon_south_pole = rescale_lon(-1.0 * (np_lon + 180.0)); // Copied from the LatLon data structure data.rot_lat_ll = ll_data.lat_ll; diff --git a/test/xml/unit_plot_data_plane.xml b/test/xml/unit_plot_data_plane.xml index c118078829..3db1b4bfa0 100644 --- a/test/xml/unit_plot_data_plane.xml +++ b/test/xml/unit_plot_data_plane.xml @@ -271,6 +271,20 @@ + + &MET_BIN;/plot_data_plane + \ + &DATA_DIR_MODEL;/nccf/prods_op_ukv_rotated_latlon_20220301_00_000.nc \ + &OUTPUT_DIR;/plot_data_plane/plot_data_plane_NCCF_rotlatlon.ps \ + 'name="surface_altitude"; level="(*,*)";' \ + -title "Rotated Lat/Lon Surface Altitude" \ + -v 1 + + + &OUTPUT_DIR;/plot_data_plane/plot_data_plane_NCCF_rotlatlon.ps + + + &MET_BIN;/plot_data_plane \ From cf7ddecee73f77f12b8ede38dafaa35559133f90 Mon Sep 17 00:00:00 2001 From: Seth Linden Date: Wed, 6 Apr 2022 14:34:20 -0600 Subject: [PATCH 169/172] Feature 1950 sort station list (#2121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update the top-level README file to list ioda2nc, but also to trigger GHA to run for this new main_v10.1-ref branch. * Added bool Sorted variable, set to true or false in relevant functions. Updated sort() function. SL * In parse_sid_mask(), added the line: mask_sid.sort(). SL * Per issue #1950, put in some cout statements for testing. SL * Per issue #1950, working in has() function, checking for Sort and put in initial cout's for testing. SL * Per issue #1950: Cleaned up some cout (print) statements. Left one in there that is commented out for future testing. SL * Per issue #1950: modified has() function. Added lower_bound search for sorted arrays. Left some print (cout) statements in there for further testing. SL * Per issue #1950: In has(), I commented out the print (cout) statements for time testing. SL * added logic to manually trigger a workflow via the GitHub… (#2107) * Per issue #1950, put back in some print (cout) statements for testing. SL * Per issue #1950: in has() function, experimenting using the upper_bound() search instead of lower_bound() for sorted vectors. In progress. SL * Per issue #1950: added a new has function that uses binary_search. Re-working the other has() functions related to this. SL * Per issue #1950: re-worked original has(), basically reverted back to what it was...but it's now only used for unsorted vectors or for a case insensitive search. Cleaned up. SL * Per issue #1950: in section that checks Obs Station Id in SID masking list, changed cout to a mlog (debug) statement. SL * Per issue #1950: created new mask station id list (CONUS METARs) and modified the PointStatConfig_MASK_SID config file to use this list along with the existing lists. SL * Per issue #1950: reverted back to orginal sid mask site-lists. SL * Per issue #1950: checking in this site-list that was used for testing point_stat. SL * Per issue #1950, modified and added better debugging to figure out current issue with ascii2nc. SL * Per #1950, small tweak in ascii2nc to make it slightly more efficient. After adding the new obs varable name to the end of the list, we can compute var_index direclty without needing to call StringArray::has() a second time. * Per #1950: removed mlog and cout print statements from has() functions. Cleaned up. SL * Update met/src/basic/vx_log/string_array.cc Co-authored-by: johnhg * Update met/src/basic/vx_log/string_array.cc Co-authored-by: johnhg * Update met/src/basic/vx_log/string_array.cc Co-authored-by: johnhg * Update met/src/basic/vx_log/string_array.cc Co-authored-by: johnhg * Update met/src/basic/vx_log/string_array.cc Co-authored-by: johnhg * Update met/src/basic/vx_log/string_array.h Co-authored-by: johnhg * Delete SID_CONUS.txt * Delete SID_CONUS_times11.txt Co-authored-by: John Halley Gotway Co-authored-by: Seth Linden Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> --- met/src/basic/vx_config/config_util.cc | 3 + met/src/basic/vx_log/string_array.cc | 193 +++++++++++------- met/src/basic/vx_log/string_array.h | 8 +- .../libcode/vx_statistics/pair_data_point.cc | 2 + met/src/tools/other/ascii2nc/met_handler.cc | 2 +- 5 files changed, 128 insertions(+), 80 deletions(-) diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index e08ef7d19b..fa2f777307 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -690,6 +690,9 @@ void parse_sid_mask(const ConcatString &mask_sid_str, } + // Sort the mask_sid's + mask_sid.sort(); + return; } diff --git a/met/src/basic/vx_log/string_array.cc b/met/src/basic/vx_log/string_array.cc index 59539bdf5b..95f110b7eb 100644 --- a/met/src/basic/vx_log/string_array.cc +++ b/met/src/basic/vx_log/string_array.cc @@ -135,6 +135,8 @@ MaxLength = 0; clear(); +Sorted = false; + return; } @@ -149,6 +151,8 @@ void StringArray::clear() s.clear(); +Sorted = false; + return; } @@ -166,6 +170,7 @@ clear(); s = a.s; IgnoreCase = a.IgnoreCase; +Sorted = a.Sorted; return; @@ -183,6 +188,7 @@ Indent prefix(depth); Indent prefix2(depth + 1); out << prefix << "IgnoreCase = " << IgnoreCase << "\n"; +out << prefix << "Sorted = " << (Sorted ? "true" : "false") << "\n"; int j; @@ -250,6 +256,8 @@ void StringArray::add(const std::string text) s.push_back(text); +Sorted = false; + return; } @@ -265,7 +273,9 @@ void StringArray::add(const StringArray & a) if ( a.n() == 0 ) return; s.insert(s.end(), a.s.begin(), a.s.end()); - + +Sorted = false; + return; } @@ -298,6 +308,8 @@ void StringArray::add_css(const std::string text) } + Sorted = false; + return; } @@ -314,6 +326,9 @@ s.clear(); s.push_back(text); +// Setting to a single value, by nature it is Sorted +Sorted = true; + return; } @@ -336,6 +351,8 @@ void StringArray::set(int i, const std::string text) s[i] = text; +Sorted = false; + return; } @@ -358,6 +375,8 @@ void StringArray::insert(int i, const char * text) s.insert(s.begin()+i, text); + Sorted = false; + return; } @@ -366,90 +385,104 @@ void StringArray::insert(int i, const char * text) //////////////////////////////////////////////////////////////////////// -bool StringArray::has(const std::string text, bool forward) const +bool StringArray::has(const std::string text) const { + bool found = false; + bool forward = true; + + if (Sorted && !IgnoreCase) { + found = binary_search(s.begin(), s.end(), text); +} +else { + return ( has(text, forward) ); +} - int index; + return found; +} - return ( has(text, index, forward) ); -} +//////////////////////////////////////////////////////////////////////// + + +bool StringArray::has(const std::string text, bool forward) const +{ + int index; + return ( has(text, index, forward) ); +} //////////////////////////////////////////////////////////////////////// bool StringArray::has(const std::string text, int & index, bool forward) const - { - bool found = false; - index = -1; - - if (!s.empty()) { - int count; - std::string lower_text = text; - std::vector::const_iterator it; - if ( IgnoreCase ) transform(lower_text.begin(), lower_text.end(), lower_text.begin(), ::tolower); - - if (forward) { - count = 0; - for(it = s.begin(); it != s.end(); it++, count++) { - if ( IgnoreCase ) { - std::string lower_s = *it; - transform(lower_s.begin(), lower_s.end(), lower_s.begin(), ::tolower); - if ( lower_s == lower_text) { - // if ( strcasecmp((*it).c_str(), text.c_str()) ) { - found = true; - break; - } - } - else { - if ( *it == text ) { - found = true; - break; - } - } - } - } - else { - count = s.size() - 1; - it = s.end(); - for(it--; it != s.begin(); it--, count--) { - if ( IgnoreCase ) { - std::string lower_s = *it; - transform(lower_s.begin(), lower_s.end(), lower_s.begin(), ::tolower); - if ( lower_s == lower_text) { - found = true; - break; - } - } - else { - if ( *it == text ) { - found = true; - break; - } - } + // This function is now used for either an un-sorted array (Sorted is false) + // Or for a case-insensitive search (IgnoreCase is true) + // + bool found = false; + index = -1; + + if (!s.empty()) { + int count; + std::string lower_text = text; + std::vector::const_iterator it; + if ( IgnoreCase ) transform(lower_text.begin(), lower_text.end(), lower_text.begin(), ::tolower); + + if (forward) { + count = 0; + for(it = s.begin(); it != s.end(); it++, count++) { + if ( IgnoreCase ) { + std::string lower_s = *it; + transform(lower_s.begin(), lower_s.end(), lower_s.begin(), ::tolower); + if ( lower_s == lower_text) { + found = true; + break; + } + } + else { + if ( *it == text ) { + found = true; + break; + } + } + } } - if (!found && it == s.begin()) { - if ( IgnoreCase ) { - std::string lower_s = *it; - transform(lower_s.begin(), lower_s.end(), lower_s.begin(), ::tolower); - found = ( lower_s == lower_text ); - } - else found = ( *it == text ); + else { + count = s.size() - 1; + it = s.end(); + for(it--; it != s.begin(); it--, count--) { + if ( IgnoreCase ) { + std::string lower_s = *it; + transform(lower_s.begin(), lower_s.end(), lower_s.begin(), ::tolower); + if ( lower_s == lower_text) { + found = true; + break; + } + } + else { + if ( *it == text ) { + found = true; + break; + } + } + } + if (!found && it == s.begin()) { + if ( IgnoreCase ) { + std::string lower_s = *it; + transform(lower_s.begin(), lower_s.end(), lower_s.begin(), ::tolower); + found = ( lower_s == lower_text ); + } + else found = ( *it == text ); + } } - } - if (found) index = count; - } - //mlog << Debug(9) << " StringArray::has() size=" << s.size() - // << " for " << text << ", found: " << (found ? "true" : "false") - // << ", forward: " << (forward ? "yes" : "no") << "\n"; - - return found; - + if (found) index = count; + } + + return found; } + //////////////////////////////////////////////////////////////////////// @@ -500,6 +533,8 @@ void StringArray::parse_delim(const std::string text, const char *delim) if (start < str.length()) s.push_back(str.substr(start).c_str()); + Sorted = false; + return; } @@ -616,13 +651,19 @@ return ( s[k].length() ); void StringArray::sort() { - -if ( n() <= 1 ) return; - - std::sort(s.begin(), s.end()); - -return; - + if ( n() <= 1 ) { + Sorted = true; + return; + } + + if ( !Sorted ) { + std::sort(s.begin(), s.end()); + } + + Sorted = true; + + return; + } diff --git a/met/src/basic/vx_log/string_array.h b/met/src/basic/vx_log/string_array.h index 22f300b305..9d2aa286e7 100644 --- a/met/src/basic/vx_log/string_array.h +++ b/met/src/basic/vx_log/string_array.h @@ -30,7 +30,6 @@ class StringArray { public: - void init_from_scratch(); void assign(const StringArray &); @@ -40,7 +39,8 @@ class StringArray { int MaxLength; bool IgnoreCase; - + + bool Sorted; public: @@ -77,8 +77,10 @@ class StringArray { int length(int) const; - bool has(const std::string, bool forward=true) const; + bool has(const std::string) const; + bool has(const std::string, bool forward) const; + bool has(const std::string, int & index, bool forward=true) const; // diff --git a/met/src/libcode/vx_statistics/pair_data_point.cc b/met/src/libcode/vx_statistics/pair_data_point.cc index e6366da500..cc8a156ed9 100644 --- a/met/src/libcode/vx_statistics/pair_data_point.cc +++ b/met/src/libcode/vx_statistics/pair_data_point.cc @@ -1142,6 +1142,8 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, // masking SID list else if(pd[i][j][0].mask_sid_ptr != (StringArray *) 0) { if(!pd[i][j][0].mask_sid_ptr->has(hdr_sid_str)) { + mlog << Debug(9) << "Checking for the obs station id in the masking SID list: rejected hdr_sid_str = " + << hdr_sid_str << "\n"; inc_count(rej_mask, i, j); continue; } diff --git a/met/src/tools/other/ascii2nc/met_handler.cc b/met/src/tools/other/ascii2nc/met_handler.cc index dbb4c4d2a7..cd7c8f2576 100644 --- a/met/src/tools/other/ascii2nc/met_handler.cc +++ b/met/src/tools/other/ascii2nc/met_handler.cc @@ -159,7 +159,7 @@ bool MetHandler::_readObservations(LineDataFile &ascii_file) use_var_id = true; if (!obs_names.has(data_line[6], var_index)) { obs_names.add(data_line[6]); - obs_names.has(data_line[6], var_index); + var_index = obs_names.n() - 1; } grib_code = var_index; break; From 1e1a4cc87a4e7edd7682694c04e85fe68ccf5f7f Mon Sep 17 00:00:00 2001 From: johnhg Date: Fri, 8 Apr 2022 13:16:06 -0600 Subject: [PATCH 170/172] Bugfix #2118 develop grib1_rotll (#2130) Co-authored-by: George McCabe <23407799+georgemccabe@users.noreply.github.com> --- .github/jobs/set_job_controls.sh | 36 +++--- met/src/libcode/vx_data2d_grib/data2d_grib.cc | 4 + .../libcode/vx_data2d_grib/grib_classes.cc | 21 ++++ met/src/libcode/vx_data2d_grib/grib_classes.h | 30 ++++- met/src/libcode/vx_data2d_grib/grib_utils.cc | 113 +++++++++++++++--- .../libcode/vx_data2d_grib2/data2d_grib2.cc | 2 +- .../libcode/vx_data2d_nc_met/get_met_grid.cc | 2 +- test/xml/unit_plot_data_plane.xml | 46 ++++--- 8 files changed, 203 insertions(+), 51 deletions(-) diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh index 3cb1389658..54aeca8507 100755 --- a/.github/jobs/set_job_controls.sh +++ b/.github/jobs/set_job_controls.sh @@ -17,9 +17,11 @@ if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then run_diff=true - # if base branch starts with main_v, use that input data + # if pull request into main_vX.Y branch, + # set truth data version to branch name and set input data version to X.Y if [ "${GITHUB_BASE_REF:0:6}" == "main_v" ]; then - input_data_version=${GITHUB_BASE_REF:6} + truth_data_version=${GITHUB_BASE_REF} + input_data_version=${GITHUB_BASE_REF:6} fi fi @@ -35,9 +37,9 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then run_diff=true truth_data_version=${branch_name:0: -4} - # if branch starts with main_v, use that input data + # if main_vX.Y-ref branch, use X.Y input data if [ "${branch_name:0:6}" == "main_v" ]; then - input_data_version=${branch_name:6:-4} + input_data_version=${branch_name:6: -4} fi else @@ -46,10 +48,10 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then if [ "$branch_name" == "develop" ] || [ "${branch_name:0:6}" == "main_v" ]; then - run_diff=true - truth_data_version=${branch_name} + run_diff=true + truth_data_version=${branch_name} - # if branch starts with main_v, use that input data + # if main_vX.Y branch, use X.Y input data if [ "${branch_name:0:6}" == "main_v" ]; then input_data_version=${branch_name:6} fi @@ -59,24 +61,24 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then # check commit messages for skip or force keywords if grep -q "ci-skip-all" <<< "$commit_msg"; then - run_compile=false - run_push=false - run_unit_tests=false - run_diff=false - run_update_truth=false + run_compile=false + run_push=false + run_unit_tests=false + run_diff=false + run_update_truth=false fi # check commit messages for ci-skip or ci-run keywords if grep -q "ci-skip-compile" <<< "$commit_msg"; then - run_compile=false + run_compile=false fi if grep -q "ci-run-unit" <<< "$commit_msg"; then - run_diff=true + run_diff=true fi @@ -84,9 +86,9 @@ elif [ "${GITHUB_EVENT_NAME}" == "push" ]; then elif [ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]; then - if [ "${force_tests}" == "true" ]; then - run_diff=true - fi + if [ "${force_tests}" == "true" ]; then + run_diff=true + fi fi diff --git a/met/src/libcode/vx_data2d_grib/data2d_grib.cc b/met/src/libcode/vx_data2d_grib/data2d_grib.cc index ef5e622b9c..c92e64569a 100644 --- a/met/src/libcode/vx_data2d_grib/data2d_grib.cc +++ b/met/src/libcode/vx_data2d_grib/data2d_grib.cc @@ -762,6 +762,10 @@ bool is_grid_relative(const GribRecord &r) { else if(r.gds->type == 5) { res_flag = r.gds->grid_type.stereographic.res_flag; } + // Rotated LatLon + else if(r.gds->type == 10) { + res_flag = r.gds->grid_type.rot_latlon_grid.res_flag; + } else { mlog << Error << "\nis_grid_relative() -> " << "Unsupported grid type value: " << r.gds->type diff --git a/met/src/libcode/vx_data2d_grib/grib_classes.cc b/met/src/libcode/vx_data2d_grib/grib_classes.cc index da1a5f0f76..d02445c6ef 100644 --- a/met/src/libcode/vx_data2d_grib/grib_classes.cc +++ b/met/src/libcode/vx_data2d_grib/grib_classes.cc @@ -1874,6 +1874,27 @@ else if ((h.type == 5)) file << " scan_flag: " << (int) h.grid_type.stereographic.scan_flag << "\n\n"; } +else if ((h.type == 10)) +{ + + file << " lat1: " << char3_to_int(h.grid_type.rot_latlon_grid.lat1) << "\n"; + file << " lon1: " << char3_to_int(h.grid_type.rot_latlon_grid.lon1) << "\n"; + + file << " res_flag: " << (int) h.grid_type.rot_latlon_grid.res_flag << "\n"; + + file << " lat2: " << char3_to_int(h.grid_type.rot_latlon_grid.lat2) << "\n"; + file << " lon2: " << char3_to_int(h.grid_type.rot_latlon_grid.lon2) << "\n"; + + file << " di: " << char2_to_int(h.grid_type.rot_latlon_grid.di) << "\n"; + file << " dj: " << char2_to_int(h.grid_type.rot_latlon_grid.dj) << "\n"; + + file << " scan_flag: " << (int) h.grid_type.rot_latlon_grid.scan_flag << "\n"; + + file << " lat_sp: " << char3_to_int(h.grid_type.rot_latlon_grid.lat_sp) << "\n"; + file << " lon_sp: " << char3_to_int(h.grid_type.rot_latlon_grid.lon_sp) << "\n"; + + file << " rotation: " << char4_to_dbl(h.grid_type.rot_latlon_grid.rotation) << "\n\n"; +} return ( file ); diff --git a/met/src/libcode/vx_data2d_grib/grib_classes.h b/met/src/libcode/vx_data2d_grib/grib_classes.h index 55b7046d65..3b0295cf45 100644 --- a/met/src/libcode/vx_data2d_grib/grib_classes.h +++ b/met/src/libcode/vx_data2d_grib/grib_classes.h @@ -162,7 +162,7 @@ struct Section1_Header { // PDS //////////////////////////////////////////////////////////////////////// -struct LatLon { // Latitude/Longitude Grid +struct LatLon { // Latitude/Longitude Grid unsigned char lat1[3]; // 11 - 13 unsigned char lon1[3]; // 14 - 16 @@ -179,6 +179,32 @@ struct LatLon { // Latitude/Longitude Grid unsigned char unused[14]; // 29 - 42 +}; + + // Reference: https://apps.ecmwf.int/codes/grib/format/grib1/grids/10 + +struct RotLatLon { // Rotated Latitude/Longitude Grid + + unsigned char lat1[3]; // 11 - 13 + unsigned char lon1[3]; // 14 - 16 + + unsigned char res_flag; // 17 + + unsigned char lat2[3]; // 18 - 20 + unsigned char lon2[3]; // 21 - 23 + + unsigned char di[2]; // 24 - 25 + unsigned char dj[2]; // 26 - 27 + + unsigned char scan_flag; // 28 + + unsigned char unused[4]; // 29 - 32 + + unsigned char lat_sp[3]; // 33 - 35 + unsigned char lon_sp[3]; // 36 - 38 + + unsigned char rotation[4]; // 39 - 42 + }; struct Mercator { // Mercator Grid @@ -282,7 +308,7 @@ struct Gaussian { union GridType { struct LatLon latlon_grid; // Latitude/Longitude Grid - // struct RotLatLon rot_latlon_grid; // Rotated Latitude/Longitude Grid + struct RotLatLon rot_latlon_grid; // Rotated Latitude/Longitude Grid struct Mercator mercator; // Mercator Grid struct LambertConf lambert_conf; // Lambert Conformal Secant Grid struct Stereographic stereographic; // Stereographic Grid diff --git a/met/src/libcode/vx_data2d_grib/grib_utils.cc b/met/src/libcode/vx_data2d_grib/grib_utils.cc index 6dc5b7c563..c1ef70f775 100644 --- a/met/src/libcode/vx_data2d_grib/grib_utils.cc +++ b/met/src/libcode/vx_data2d_grib/grib_utils.cc @@ -29,11 +29,13 @@ using namespace std; // grid types from the GDS section // -static const int latlon_type = 0; -static const int mercator_type = 1; -static const int lambert_type = 3; -static const int stereographic_type = 5; -static const int gaussian_type = 4; +static const int latlon_type = 0; +static const int mercator_type = 1; +static const int lambert_type = 3; +static const int gaussian_type = 4; +static const int stereographic_type = 5; +static const int rotated_latlon_type = 10; + //////////////////////////////////////////////////////////////////////// @@ -62,7 +64,7 @@ void gds_to_grid(const Section2_Header & gds, Grid & gr) LambertData lc_data; StereographicData st_data; LatLonData ll_data; -//RotatedLatLonData rll_data; +RotatedLatLonData rll_data; MercatorData mc_data; GaussianData g_data; @@ -84,11 +86,11 @@ if ( gds.type == latlon_type ) { gr.set(ll_data); -// else if ( gds.type == rotated_latlon_type ) { -// -// gds_to_rotated_latlon(gds, rll_data); -// -// gr.set(rll_data); +} else if ( gds.type == rotated_latlon_type ) { + + gds_to_rotated_latlon(gds, rll_data); + + gr.set(rll_data); } else if ( gds.type == mercator_type ) { @@ -143,6 +145,7 @@ void gds_to_order(const Section2_Header & gds, int & xdir, int & ydir, int & ord // Check GDS for the grid type. // The following Projection types are supported: // - Lat/Lon + // - Rotated Lat/Lon // - Mercator // - Lambert Conformal // - Polar Stereographic @@ -154,6 +157,10 @@ if ( gds.type == latlon_type ) { scan_flag_to_order(gds.grid_type.latlon_grid.scan_flag, xdir, ydir, order); +} else if ( gds.type == rotated_latlon_type ) { + + scan_flag_to_order(gds.grid_type.rot_latlon_grid.scan_flag, xdir, ydir, order); + } else if (gds.type == mercator_type ) { scan_flag_to_order(gds.grid_type.mercator.scan_flag, xdir, ydir, order); @@ -278,10 +285,88 @@ void gds_to_rotated_latlon(const Section2_Header & gds, RotatedLatLonData & data { -mlog << Error << "\ngds_to_rotated_latlon() -> " - << "Rotated Lat/Lon grids are not supported in GRIB version 1.\n\n"; +int xdir, ydir, order; +double d; + +scan_flag_to_order(gds.grid_type.rot_latlon_grid.scan_flag, xdir, ydir, order); + + // Store the grid name +data.name = rotated_latlon_proj_type; + + // + // Multiply longitude values by -1 since the NCAR code considers + // degrees west to be positive. + // + + // Latitude of the bottom left corner +data.rot_lat_ll = min(decode_lat_lon(gds.grid_type.rot_latlon_grid.lat1, 3), + decode_lat_lon(gds.grid_type.rot_latlon_grid.lat2, 3)); + + // Longitude of the bottom left corner +if ( xdir == 0 ) data.rot_lon_ll = -1.0*rescale_lon(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon1, 3)); +else data.rot_lon_ll = -1.0*rescale_lon(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon2, 3)); + + // Number of points in the Latitudinal (y) direction +data.Nlat = char2_to_int(gds.ny); + + // Number of points in the Longitudinal (x) direction +data.Nlon = char2_to_int(gds.nx); + + // Check for thinned lat/lon grids +if ( data.Nlon == 65535 ) { -exit ( 1 ); + mlog << Error << "\ngds_to_rotated_latlon() -> " + << "Thinned Lat/Lon grids are not supported for GRIB version 1.\n\n"; + + exit ( 1 ); + +} + + // Compute latitudinal increment from lat1 and lat2 +d = fabs(decode_lat_lon(gds.grid_type.rot_latlon_grid.lat1, 3) + - decode_lat_lon(gds.grid_type.rot_latlon_grid.lat2, 3)); + +data.delta_rot_lat = d/(data.Nlat); + + // If explicitly specified and non-zero, use it +if ( ! all_bits_set(gds.grid_type.rot_latlon_grid.dj, 2) ) { + + d = decode_lat_lon(gds.grid_type.rot_latlon_grid.dj, 2); + + if ( d > 0 ) data.delta_rot_lat = d; + +} + + // Compute longitudinal increment from lon1 and lon2 +d = fabs(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon1, 3) + - decode_lat_lon(gds.grid_type.rot_latlon_grid.lon2, 3)); + +data.delta_rot_lon = d/(data.Nlon); + + // If explicitly specified and non-zero, use it +if ( ! all_bits_set(gds.grid_type.rot_latlon_grid.di, 2) ) { + + d = decode_lat_lon(gds.grid_type.rot_latlon_grid.di, 2); + + if ( d > 0 ) data.delta_rot_lon = d; + +} + + // Location of (rotated) south pole +data.true_lat_south_pole = + decode_lat_lon(gds.grid_type.rot_latlon_grid.lat_sp, 3); + +data.true_lon_south_pole = + -1.0*rescale_lon(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon_sp, 3)); + + // Auxiliary rotation +data.aux_rotation = char4_to_dbl(gds.grid_type.rot_latlon_grid.rotation); + +data.dump(); + + // + // done + // return; diff --git a/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc b/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc index 0061d2fd00..65df4c7ef7 100644 --- a/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc +++ b/met/src/libcode/vx_data2d_grib2/data2d_grib2.cc @@ -1100,7 +1100,7 @@ void MetGrib2DataFile::read_grib2_grid( gribfield *gfld) { data.true_lon_south_pole = s_lon; // - // auxilliary rotation around the rotated polar axis + // auxiliary rotation around the rotated polar axis // data.aux_rotation = (t[21])*angle_factor; diff --git a/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc b/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc index 8e9e68cf4d..3512c6aaed 100644 --- a/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc +++ b/met/src/libcode/vx_data2d_nc_met/get_met_grid.cc @@ -309,7 +309,7 @@ data.rot_lon_ll *= -1.0; get_global_att(ncfile, string("true_lon_south_pole"), data.true_lon_south_pole); if ( !west_longitude_positive ) data.true_lon_south_pole *= -1.0; - // auxilliary rotation + // auxiliary rotation get_global_att(ncfile, string("aux_rotation"), data.aux_rotation); diff --git a/test/xml/unit_plot_data_plane.xml b/test/xml/unit_plot_data_plane.xml index 3db1b4bfa0..d07cc7aa7a 100644 --- a/test/xml/unit_plot_data_plane.xml +++ b/test/xml/unit_plot_data_plane.xml @@ -88,6 +88,20 @@ + + &MET_BIN;/plot_data_plane + \ + &DATA_DIR_MODEL;/grib1/cosmo/lfff03080000.grib \ + &OUTPUT_DIR;/plot_data_plane/cosmo_rotlatlon_GRIB1_TMP_Z2.ps \ + 'name="T"; level="Z2";' \ + -title "Rotated Lat/Lon 2-meter Temperature" \ + -v 1 + + + &OUTPUT_DIR;/plot_data_plane/cosmo_rotlatlon_GRIB1_TMP_Z2.ps + + + &MET_BIN;/plot_data_plane \ @@ -131,6 +145,22 @@ + + &MET_BIN;/plot_data_plane + \ + &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F012.grib2 \ + &OUTPUT_DIR;/plot_data_plane/sref_prob_2012040821_F012_GRIB2_PROB_APCP_12_gt2.54.ps \ + 'name = "PROB"; level = "A12"; prob = { name = "APCP"; thresh_lo = 2.54; };' \ + -title "GRIB2 Probability of 12-hour APCP > 2.54mm)" \ + -color_table &MET_BASE;/colortables/NCL_colortables/WhBlGrYeRe.ctable \ + -plot_range 0 100 \ + -v 1 + + + &OUTPUT_DIR;/plot_data_plane/sref_prob_2012040821_F012_GRIB2_PROB_APCP_12_gt2.54.ps + + + &MET_BIN;/plot_data_plane \ @@ -285,22 +315,6 @@ - - &MET_BIN;/plot_data_plane - \ - &DATA_DIR_MODEL;/grib2/sref_pr/sref_prob_2012040821_F012.grib2 \ - &OUTPUT_DIR;/plot_data_plane/sref_prob_2012040821_F012_GRIB2_PROB_APCP_12_gt2.54.ps \ - 'name = "PROB"; level = "A12"; prob = { name = "APCP"; thresh_lo = 2.54; };' \ - -title "GRIB2 Probability of 12-hour APCP > 2.54mm)" \ - -color_table &MET_BASE;/colortables/NCL_colortables/WhBlGrYeRe.ctable \ - -plot_range 0 100 \ - -v 1 - - - &OUTPUT_DIR;/plot_data_plane/sref_prob_2012040821_F012_GRIB2_PROB_APCP_12_gt2.54.ps - - - &MET_BIN;/plot_data_plane \ From a80097b1a012e822a187bfdcdc8ac8abf0484742 Mon Sep 17 00:00:00 2001 From: hsoh-u Date: Fri, 8 Apr 2022 22:50:04 -0600 Subject: [PATCH 171/172] Bugfix 2123 nccf valid time (#2127) Co-authored-by: Howard Soh Co-authored-by: johnhg --- met/src/libcode/vx_data2d_nccf/nccf_file.cc | 15 ++---- met/src/libcode/vx_nc_util/nc_utils.cc | 57 +++++++++++++++++---- test/xml/unit_plot_data_plane.xml | 14 +++++ 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/met/src/libcode/vx_data2d_nccf/nccf_file.cc b/met/src/libcode/vx_data2d_nccf/nccf_file.cc index dbe5e4e323..7dcb7dc99a 100644 --- a/met/src/libcode/vx_data2d_nccf/nccf_file.cc +++ b/met/src/libcode/vx_data2d_nccf/nccf_file.cc @@ -296,17 +296,15 @@ bool NcCfFile::open(const char * filepath) } // Parse the units for the time variable. + ut = sec_per_unit = 0; NcVarAtt *units_att = get_nc_att(valid_time_var, (string)"units", false); if (IS_VALID_NC_P(units_att)) { - get_att_value_chars(units_att, units); - - if (units.length() == 0) + if (!get_att_value_chars(units_att, units) || units.length() == 0) { mlog << Warning << "\n" << method_name << "the \"time\" variable must contain a \"units\" attribute. " << "Using valid time of 0\n\n"; - ut = sec_per_unit = 0; } else { @@ -315,14 +313,10 @@ bool NcCfFile::open(const char * filepath) parse_cf_time_string(units.c_str(), ut, sec_per_unit); } } - else - { - ut = sec_per_unit = 0; - } + if (units_att) delete units_att; NcVar bounds_time_var; NcVar *nc_time_var = (NcVar *)0; - nc_time_var = valid_time_var; bool use_bounds_var = false; ConcatString bounds_var_name; nc_time_var = valid_time_var; @@ -338,12 +332,12 @@ bool NcCfFile::open(const char * filepath) } if (bounds_att) delete bounds_att; - if (units_att) delete units_att; // Determine the number of times present. int n_times = (int) get_data_size(valid_time_var); int tim_buf_size = n_times; if (use_bounds_var) tim_buf_size *= 2; double *time_values = new double[tim_buf_size]; + if( get_nc_data(nc_time_var, time_values) ) { bool no_leap_year = get_att_no_leap_year(valid_time_var); if( time_dim_count > 1 ) { @@ -375,6 +369,7 @@ bool NcCfFile::open(const char * filepath) } } } + else ValidTime.add(0); //Initialize delete [] time_values; } diff --git a/met/src/libcode/vx_nc_util/nc_utils.cc b/met/src/libcode/vx_nc_util/nc_utils.cc index 8d8e5b1087..0fa9f87df9 100644 --- a/met/src/libcode/vx_nc_util/nc_utils.cc +++ b/met/src/libcode/vx_nc_util/nc_utils.cc @@ -1533,6 +1533,7 @@ bool get_nc_data(NcVar *var, float *data) { // Note: missing data was checked here // int type_id = GET_NC_TYPE_ID_P(var); + return_status = true; if (NcType::nc_FLOAT == type_id) { var->getVar(data); } @@ -1565,9 +1566,26 @@ bool get_nc_data(NcVar *var, float *data) { if (IS_VALID_NC_P(att_scale_factor)) scale_factor = get_att_value_float(att_scale_factor); mlog << Debug(4) << method_name << "add_offset = " << add_offset << ", scale_factor=" << scale_factor << ", cell_count=" << cell_count - << ", is_unsigned_value: " << unsigned_value << "\n"; + << ", is_unsigned_value: " << unsigned_value << " for " << GET_NC_NAME_P(var) << "\n"; switch ( type_id ) { + case NcType::nc_INT64: + { + long long fill_value = bad_data_int; + long long min_value = 2147483647; + long long max_value = -2147483648; + long long *packed_data = new long long[cell_count]; + + if (IS_VALID_NC_P(att_fill_value)) + fill_value = get_att_value_int(att_fill_value); + + var->getVar(packed_data); + _apply_scale_factor(data, packed_data, cell_count, + fill_value, min_value, max_value, "int64", + add_offset, scale_factor); + delete [] packed_data; + } + break; case NcType::nc_INT: { int fill_value = bad_data_int; @@ -1720,15 +1738,15 @@ bool get_nc_data(NcVar *var, float *data) { } break; default: - mlog << Debug(1) << method_name << "type_id: " - << type_id << " type name: " << GET_NC_TYPE_NAME_P(var) - << "\n"; + return_status = false; + mlog << Debug(1) << method_name << "Did not read data because of unsupported data type (" + << type_id << ", type name: " << GET_NC_TYPE_NAME_P(var) + << ") for " << GET_NC_NAME_P(var) << "\n"; } if(att_add_offset) delete att_add_offset; if(att_scale_factor) delete att_scale_factor; if(att_fill_value) delete att_fill_value; } - return_status = true; } mlog << Debug(6) << method_name << "took " @@ -1821,6 +1839,7 @@ bool get_nc_data(NcVar *var, double *data) { // int unpacked_count = 0; int type_id = GET_NC_TYPE_ID_P(var); + return_status = true; if ((NcType::nc_DOUBLE == type_id) || (NcType::nc_FLOAT == type_id)){ var->getVar(data); } @@ -1844,9 +1863,26 @@ bool get_nc_data(NcVar *var, double *data) { } mlog << Debug(4) << method_name << "add_offset = " << add_offset << ", scale_factor=" << scale_factor << ", cell_count=" << cell_count - << ", is_unsigned_value: " << unsigned_value << "\n"; + << ", is_unsigned_value: " << unsigned_value << " for " << GET_NC_NAME_P(var) << "\n"; switch ( type_id ) { + case NcType::nc_INT64: + { + long long fill_value = bad_data_int; + long long min_value = 2147483647; + long long max_value = -2147483648; + long long *packed_data = new long long[cell_count]; + + if (IS_VALID_NC_P(att_fill_value)) + fill_value = get_att_value_int(att_fill_value); + + var->getVar(packed_data); + _apply_scale_factor(data, packed_data, cell_count, + fill_value, min_value, max_value, "int64", + add_offset, scale_factor); + delete [] packed_data; + } + break; case NcType::nc_INT: { int fill_value = bad_data_int; @@ -2001,15 +2037,16 @@ bool get_nc_data(NcVar *var, double *data) { } break; default: - mlog << Debug(1) << method_name << "type_id: " - << type_id << " type name: " << GET_NC_TYPE_NAME_P(var) - << "\n"; + return_status = false; + mlog << Debug(1) << method_name << "Did not read data because of unsupported data type (" + << type_id << ", type name: " << GET_NC_TYPE_NAME_P(var) + << ") for " << GET_NC_NAME_P(var) << "\n"; + } if(att_add_offset) delete att_add_offset; if(att_scale_factor) delete att_scale_factor; if(att_fill_value) delete att_fill_value; } - return_status = true; } return(return_status); } diff --git a/test/xml/unit_plot_data_plane.xml b/test/xml/unit_plot_data_plane.xml index d07cc7aa7a..02f85765bc 100644 --- a/test/xml/unit_plot_data_plane.xml +++ b/test/xml/unit_plot_data_plane.xml @@ -301,6 +301,20 @@ + + &MET_BIN;/plot_data_plane + \ + &DATA_DIR_MODEL;/nccf/precipitation_int64_time.nc \ + &OUTPUT_DIR;/plot_data_plane/plot_data_plane_NCCF_int64_time.ps \ + 'name="precipitation"; level="(*,*)";' \ + -title "Observation precipitation" \ + -v 1 + + + &OUTPUT_DIR;/plot_data_plane/plot_data_plane_NCCF_int64_time.ps + + + &MET_BIN;/plot_data_plane \ From 2e53ff72f645530fad28111d50fcc7b12099da52 Mon Sep 17 00:00:00 2001 From: johnhg Date: Mon, 11 Apr 2022 10:56:44 -0600 Subject: [PATCH 172/172] Feature #2132 version 11.0.0 (#2133) --- met/data/config/Ascii2NcConfig_default | 2 +- met/data/config/EnsembleStatConfig_default | 2 +- met/data/config/GenEnsProdConfig_default | 2 +- met/data/config/GridDiagConfig_default | 2 +- met/data/config/GridStatConfig_default | 2 +- met/data/config/IODA2NCConfig_default | 2 +- met/data/config/MODEAnalysisConfig_default | 2 +- met/data/config/MODEConfig_default | 2 +- met/data/config/MODEMultivarConfig_default | 2 +- met/data/config/MTDConfig_default | 2 +- met/data/config/Madis2NcConfig_default | 2 +- met/data/config/PB2NCConfig_default | 2 +- met/data/config/Point2GridConfig_default | 2 +- met/data/config/PointStatConfig_default | 2 +- met/data/config/RMWAnalysisConfig_default | 2 +- met/data/config/STATAnalysisConfig_CBS_Index | 2 +- met/data/config/STATAnalysisConfig_GO_Index | 2 +- met/data/config/STATAnalysisConfig_default | 2 +- met/data/config/SeriesAnalysisConfig_default | 2 +- met/data/config/TCGenConfig_default | 2 +- met/data/config/TCPairsConfig_default | 2 +- met/data/config/TCRMWConfig_default | 2 +- met/data/config/TCStatConfig_default | 2 +- met/data/config/WaveletStatConfig_default | 2 +- met/data/table_files/Makefile.am | 1 + .../table_files/met_header_columns_V11.0.txt | 38 +++++++++++++++++++ met/scripts/config/EnsembleStatConfig | 2 +- met/scripts/config/GenEnsProdConfig | 2 +- met/scripts/config/GridStatConfig_APCP_12 | 2 +- met/scripts/config/GridStatConfig_APCP_24 | 2 +- met/scripts/config/GridStatConfig_POP_12 | 2 +- met/scripts/config/GridStatConfig_all | 2 +- met/scripts/config/MODEAnalysisConfig | 2 +- met/scripts/config/MODEConfig_APCP_12 | 2 +- met/scripts/config/MODEConfig_APCP_24 | 2 +- met/scripts/config/MODEConfig_RH | 2 +- met/scripts/config/PB2NCConfig_G212 | 2 +- met/scripts/config/PointStatConfig | 2 +- met/scripts/config/STATAnalysisConfig | 2 +- met/scripts/config/WaveletStatConfig_APCP_12 | 2 +- .../config/WaveletStatConfig_APCP_12_NC | 2 +- met/src/basic/vx_util/string_fxns.cc | 2 +- met/src/basic/vx_util/util_constants.h | 3 +- scripts/docker/build_met_docker.sh | 1 - test/config/Ascii2NcConfig.surfrad | 2 +- test/config/Ascii2NcConfig_aeronet | 2 +- test/config/EnsembleStatConfig | 2 +- test/config/EnsembleStatConfig_MASK_SID | 2 +- test/config/EnsembleStatConfig_climo | 2 +- test/config/EnsembleStatConfig_grid_weight | 2 +- test/config/EnsembleStatConfig_one_cdf_bin | 2 +- test/config/EnsembleStatConfig_python | 2 +- test/config/EnsembleStatConfig_qty_inc_exc | 2 +- .../EnsembleStatConfig_single_file_grib | 2 +- test/config/EnsembleStatConfig_single_file_nc | 2 +- test/config/GenEnsProdConfig | 2 +- .../GenEnsProdConfig_climo_anom_ens_member_id | 2 +- test/config/GenEnsProdConfig_normalize | 2 +- test/config/GenEnsProdConfig_single_file_grib | 2 +- test/config/GenEnsProdConfig_single_file_nc | 2 +- test/config/GridDiagConfig | 2 +- test/config/GridDiagConfig_APCP_06_FCST_OBS | 2 +- test/config/GridDiagConfig_TMP | 2 +- test/config/GridStatConfig_APCP_regrid | 2 +- test/config/GridStatConfig_GRIB_lvl_typ_val | 2 +- test/config/GridStatConfig_GRIB_set_attr | 2 +- test/config/GridStatConfig_GTG_latlon | 2 +- test/config/GridStatConfig_GTG_lc | 2 +- test/config/GridStatConfig_apply_mask | 2 +- test/config/GridStatConfig_climo_WMO | 2 +- test/config/GridStatConfig_climo_prob | 2 +- test/config/GridStatConfig_fbias_perc_thresh | 2 +- test/config/GridStatConfig_fourier | 2 +- test/config/GridStatConfig_grid_weight | 2 +- test/config/GridStatConfig_interp_shape | 2 +- test/config/GridStatConfig_mpr_thresh | 2 +- test/config/GridStatConfig_no_leap | 2 +- test/config/GridStatConfig_prob_as_scalar | 2 +- test/config/GridStatConfig_python | 2 +- test/config/GridStatConfig_python_mixed | 2 +- test/config/GridStatConfig_rtma | 2 +- test/config/GridStatConfig_rtma_perc_thresh | 2 +- test/config/GridStatConfig_st4 | 2 +- test/config/GridStatConfig_st4_censor | 2 +- test/config/IODA2NCConfig_mask | 2 +- test/config/IODA2NCConfig_summary | 2 +- test/config/MODEConfig_cut_line | 2 +- test/config/MODEConfig_hmt | 2 +- test/config/MODEConfig_multivar_fake_data | 2 +- test/config/MODEConfig_perc_thresh | 2 +- test/config/MODEConfig_python | 2 +- test/config/MODEConfig_python_mixed | 2 +- test/config/MODEConfig_quilt | 2 +- test/config/MTDConfig_python | 2 +- test/config/Madis2NcConfig_time_summary | 2 +- test/config/NetcdfConfig | 2 +- test/config/PB2NCConfig | 2 +- test/config/PB2NCConfig_airnow | 2 +- test/config/PB2NCConfig_all | 2 +- test/config/PB2NCConfig_pbl | 2 +- test/config/PB2NCConfig_summary | 2 +- test/config/PB2NCConfig_vlevel | 2 +- test/config/Point2GridConfig_valid_time | 2 +- test/config/PointStatConfig_APCP | 2 +- test/config/PointStatConfig_APCP_HIRA | 2 +- test/config/PointStatConfig_GTG_latlon | 2 +- test/config/PointStatConfig_GTG_lc | 2 +- test/config/PointStatConfig_INTERP_OPTS | 2 +- test/config/PointStatConfig_LAND_TOPO_MASK | 2 +- test/config/PointStatConfig_MASK_SID | 2 +- test/config/PointStatConfig_PHYS | 2 +- test/config/PointStatConfig_PHYS_pint | 2 +- test/config/PointStatConfig_WINDS | 2 +- test/config/PointStatConfig_aeronet | 2 +- test/config/PointStatConfig_airnow | 2 +- test/config/PointStatConfig_climo | 2 +- test/config/PointStatConfig_climo_WMO | 2 +- test/config/PointStatConfig_climo_prob | 2 +- test/config/PointStatConfig_dup | 2 +- test/config/PointStatConfig_mpr_thresh | 2 +- test/config/PointStatConfig_obs_summary | 2 +- test/config/PointStatConfig_obs_summary_all | 2 +- test/config/PointStatConfig_prob | 2 +- test/config/PointStatConfig_python | 2 +- test/config/PointStatConfig_qty_inc_exc | 2 +- test/config/PointStatConfig_sid_inc_exc | 2 +- test/config/RMWAnalysisConfig | 2 +- test/config/STATAnalysisConfig_APCP_HIRA | 2 +- test/config/STATAnalysisConfig_SFC_SS_Index | 2 +- test/config/STATAnalysisConfig_climo | 2 +- test/config/STATAnalysisConfig_filter_times | 2 +- test/config/STATAnalysisConfig_grid_stat | 2 +- test/config/STATAnalysisConfig_point_stat | 2 +- test/config/STATAnalysisConfig_ramps | 2 +- test/config/SeriesAnalysisConfig | 2 +- test/config/SeriesAnalysisConfig_climo | 2 +- test/config/SeriesAnalysisConfig_climo_prob | 2 +- test/config/SeriesAnalysisConfig_conditional | 2 +- test/config/SeriesAnalysisConfig_python | 2 +- test/config/TCGenConfig_2016 | 2 +- test/config/TCGenConfig_prob | 2 +- test/config/TCGenConfig_shape | 2 +- test/config/TCPairsConfig_ALAL2010 | 2 +- test/config/TCPairsConfig_BASIN_MAP | 2 +- test/config/TCPairsConfig_INTERP12 | 2 +- test/config/TCPairsConfig_PROBRIRW | 2 +- test/config/TCRMWConfig_gonzalo | 2 +- test/config/TCRMWConfig_pressure_lev_out | 2 +- test/config/TCStatConfig_ALAL2010 | 2 +- test/config/TCStatConfig_PROBRIRW | 2 +- test/config/WaveletStatConfig | 2 +- test/config/WaveletStatConfig_no_thresholds | 2 +- test/config/WaveletStatConfig_python | 2 +- test/config/WaveletStatConfig_python_mixed | 2 +- test/config/ref_config/GridStatConfig_03h | 2 +- test/config/ref_config/GridStatConfig_24h | 2 +- test/config/ref_config/PB2NCConfig | 2 +- test/config/ref_config/PointStatConfig_ADPUPA | 2 +- test/config/ref_config/PointStatConfig_ONLYSF | 2 +- test/config/ref_config/PointStatConfig_WINDS | 2 +- test/hdr/met_11_0.hdr | 37 ++++++++++++++++++ 161 files changed, 234 insertions(+), 158 deletions(-) create mode 100644 met/data/table_files/met_header_columns_V11.0.txt create mode 100644 test/hdr/met_11_0.hdr diff --git a/met/data/config/Ascii2NcConfig_default b/met/data/config/Ascii2NcConfig_default index 458e31df81..ed3a28a819 100644 --- a/met/data/config/Ascii2NcConfig_default +++ b/met/data/config/Ascii2NcConfig_default @@ -49,4 +49,4 @@ message_type_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/met/data/config/EnsembleStatConfig_default b/met/data/config/EnsembleStatConfig_default index 1cb84c3714..93380170ef 100644 --- a/met/data/config/EnsembleStatConfig_default +++ b/met/data/config/EnsembleStatConfig_default @@ -314,6 +314,6 @@ rng = { grid_weight_flag = NONE; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/GenEnsProdConfig_default b/met/data/config/GenEnsProdConfig_default index 7a3db915cd..ac44a0cc7a 100644 --- a/met/data/config/GenEnsProdConfig_default +++ b/met/data/config/GenEnsProdConfig_default @@ -144,6 +144,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/GridDiagConfig_default b/met/data/config/GridDiagConfig_default index 9ff8d0b81e..29dde19885 100644 --- a/met/data/config/GridDiagConfig_default +++ b/met/data/config/GridDiagConfig_default @@ -61,6 +61,6 @@ mask = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/GridStatConfig_default b/met/data/config/GridStatConfig_default index 2ee10600a2..2a2050f689 100644 --- a/met/data/config/GridStatConfig_default +++ b/met/data/config/GridStatConfig_default @@ -259,6 +259,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/IODA2NCConfig_default b/met/data/config/IODA2NCConfig_default index 090938210a..b1ac078d9c 100644 --- a/met/data/config/IODA2NCConfig_default +++ b/met/data/config/IODA2NCConfig_default @@ -125,6 +125,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/MODEAnalysisConfig_default b/met/data/config/MODEAnalysisConfig_default index 2a1e3849c6..b07292ca6b 100644 --- a/met/data/config/MODEAnalysisConfig_default +++ b/met/data/config/MODEAnalysisConfig_default @@ -188,6 +188,6 @@ unmatched = FALSE; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/MODEConfig_default b/met/data/config/MODEConfig_default index 35090f770a..58bd78615f 100644 --- a/met/data/config/MODEConfig_default +++ b/met/data/config/MODEConfig_default @@ -243,6 +243,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/MODEMultivarConfig_default b/met/data/config/MODEMultivarConfig_default index dde6e5ca3b..a7e6ee9f7e 100644 --- a/met/data/config/MODEMultivarConfig_default +++ b/met/data/config/MODEMultivarConfig_default @@ -254,6 +254,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/MTDConfig_default b/met/data/config/MTDConfig_default index 6e539d30d6..900f5ddb01 100644 --- a/met/data/config/MTDConfig_default +++ b/met/data/config/MTDConfig_default @@ -232,6 +232,6 @@ txt_output = { output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/Madis2NcConfig_default b/met/data/config/Madis2NcConfig_default index 41cfb3a477..36a44cb8bc 100644 --- a/met/data/config/Madis2NcConfig_default +++ b/met/data/config/Madis2NcConfig_default @@ -34,4 +34,4 @@ time_summary = { // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/met/data/config/PB2NCConfig_default b/met/data/config/PB2NCConfig_default index edbd17b6fc..f765d98ec3 100644 --- a/met/data/config/PB2NCConfig_default +++ b/met/data/config/PB2NCConfig_default @@ -156,6 +156,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/Point2GridConfig_default b/met/data/config/Point2GridConfig_default index 4429c77d59..a3a7ea39e1 100644 --- a/met/data/config/Point2GridConfig_default +++ b/met/data/config/Point2GridConfig_default @@ -77,6 +77,6 @@ quality_mark_thresh = 2; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/PointStatConfig_default b/met/data/config/PointStatConfig_default index 3967152fe6..a5669867da 100644 --- a/met/data/config/PointStatConfig_default +++ b/met/data/config/PointStatConfig_default @@ -292,6 +292,6 @@ output_flag = { tmp_dir = "/tmp"; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/RMWAnalysisConfig_default b/met/data/config/RMWAnalysisConfig_default index da5d813a30..1911204ab4 100644 --- a/met/data/config/RMWAnalysisConfig_default +++ b/met/data/config/RMWAnalysisConfig_default @@ -64,7 +64,7 @@ valid_mask = ""; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/STATAnalysisConfig_CBS_Index b/met/data/config/STATAnalysisConfig_CBS_Index index e65ff69483..f16faf87bb 100644 --- a/met/data/config/STATAnalysisConfig_CBS_Index +++ b/met/data/config/STATAnalysisConfig_CBS_Index @@ -140,6 +140,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/STATAnalysisConfig_GO_Index b/met/data/config/STATAnalysisConfig_GO_Index index e157e1f6de..24a21cf5d4 100644 --- a/met/data/config/STATAnalysisConfig_GO_Index +++ b/met/data/config/STATAnalysisConfig_GO_Index @@ -148,6 +148,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/STATAnalysisConfig_default b/met/data/config/STATAnalysisConfig_default index 9ac2467ccb..17956c17b3 100644 --- a/met/data/config/STATAnalysisConfig_default +++ b/met/data/config/STATAnalysisConfig_default @@ -118,6 +118,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/SeriesAnalysisConfig_default b/met/data/config/SeriesAnalysisConfig_default index 0249671fb6..d3cbf58be8 100644 --- a/met/data/config/SeriesAnalysisConfig_default +++ b/met/data/config/SeriesAnalysisConfig_default @@ -153,6 +153,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/TCGenConfig_default b/met/data/config/TCGenConfig_default index 839d8bd21d..1a6a5c5aae 100644 --- a/met/data/config/TCGenConfig_default +++ b/met/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 = "V10.1.0"; +version = "V11.0.0"; diff --git a/met/data/config/TCPairsConfig_default b/met/data/config/TCPairsConfig_default index aa4afb51b6..ed3c659d5f 100644 --- a/met/data/config/TCPairsConfig_default +++ b/met/data/config/TCPairsConfig_default @@ -152,4 +152,4 @@ basin_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/met/data/config/TCRMWConfig_default b/met/data/config/TCRMWConfig_default index 8d9acfc338..a9b1aec3bb 100644 --- a/met/data/config/TCRMWConfig_default +++ b/met/data/config/TCRMWConfig_default @@ -104,6 +104,6 @@ rmw_scale = 0.2; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/config/TCStatConfig_default b/met/data/config/TCStatConfig_default index a9ea169154..5063ad8feb 100644 --- a/met/data/config/TCStatConfig_default +++ b/met/data/config/TCStatConfig_default @@ -202,4 +202,4 @@ jobs = []; // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/met/data/config/WaveletStatConfig_default b/met/data/config/WaveletStatConfig_default index 6a7356c7ee..ff472a61f6 100644 --- a/met/data/config/WaveletStatConfig_default +++ b/met/data/config/WaveletStatConfig_default @@ -138,6 +138,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/data/table_files/Makefile.am b/met/data/table_files/Makefile.am index ab8a87b130..df5b863bd0 100644 --- a/met/data/table_files/Makefile.am +++ b/met/data/table_files/Makefile.am @@ -19,6 +19,7 @@ tablefilesdir = $(pkgdatadir)/table_files tablefiles_DATA = \ + met_header_columns_V11.0.txt \ met_header_columns_V10.1.txt \ met_header_columns_V10.0.txt \ met_header_columns_V9.1.txt \ diff --git a/met/data/table_files/met_header_columns_V11.0.txt b/met/data/table_files/met_header_columns_V11.0.txt new file mode 100644 index 0000000000..0c30295879 --- /dev/null +++ b/met/data/table_files/met_header_columns_V11.0.txt @@ -0,0 +1,38 @@ +V11.0 : STAT : CNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR FBAR_NCL FBAR_NCU FBAR_BCL FBAR_BCU FSTDEV FSTDEV_NCL FSTDEV_NCU FSTDEV_BCL FSTDEV_BCU OBAR OBAR_NCL OBAR_NCU OBAR_BCL OBAR_BCU OSTDEV OSTDEV_NCL OSTDEV_NCU OSTDEV_BCL OSTDEV_BCU PR_CORR PR_CORR_NCL PR_CORR_NCU PR_CORR_BCL PR_CORR_BCU SP_CORR KT_CORR RANKS FRANK_TIES ORANK_TIES ME ME_NCL ME_NCU ME_BCL ME_BCU ESTDEV ESTDEV_NCL ESTDEV_NCU ESTDEV_BCL ESTDEV_BCU MBIAS MBIAS_BCL MBIAS_BCU MAE MAE_BCL MAE_BCU MSE MSE_BCL MSE_BCU BCMSE BCMSE_BCL BCMSE_BCU RMSE RMSE_BCL RMSE_BCU E10 E10_BCL E10_BCU E25 E25_BCL E25_BCU E50 E50_BCL E50_BCU E75 E75_BCL E75_BCU E90 E90_BCL E90_BCU EIQR EIQR_BCL EIQR_BCU MAD MAD_BCL MAD_BCU ANOM_CORR ANOM_CORR_NCL ANOM_CORR_NCU ANOM_CORR_BCL ANOM_CORR_BCU ME2 ME2_BCL ME2_BCU MSESS MSESS_BCL MSESS_BCU RMSFA RMSFA_BCL RMSFA_BCU RMSOA RMSOA_BCL RMSOA_BCU ANOM_CORR_UNCNTR ANOM_CORR_UNCNTR_BCL ANOM_CORR_UNCNTR_BCU SI SI_BCL SI_BCU +V11.0 : STAT : CTC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FY_OY FY_ON FN_OY FN_ON +V11.0 : STAT : CTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASER BASER_NCL BASER_NCU BASER_BCL BASER_BCU FMEAN FMEAN_NCL FMEAN_NCU FMEAN_BCL FMEAN_BCU ACC ACC_NCL ACC_NCU ACC_BCL ACC_BCU FBIAS FBIAS_BCL FBIAS_BCU PODY PODY_NCL PODY_NCU PODY_BCL PODY_BCU PODN PODN_NCL PODN_NCU PODN_BCL PODN_BCU POFD POFD_NCL POFD_NCU POFD_BCL POFD_BCU FAR FAR_NCL FAR_NCU FAR_BCL FAR_BCU CSI CSI_NCL CSI_NCU CSI_BCL CSI_BCU GSS GSS_BCL GSS_BCU HK HK_NCL HK_NCU HK_BCL HK_BCU HSS HSS_BCL HSS_BCU ODDS ODDS_NCL ODDS_NCU ODDS_BCL ODDS_BCU LODDS LODDS_NCL LODDS_NCU LODDS_BCL LODDS_BCU ORSS ORSS_NCL ORSS_NCU ORSS_BCL ORSS_BCU EDS EDS_NCL EDS_NCU EDS_BCL EDS_BCU SEDS SEDS_NCL SEDS_NCU SEDS_BCL SEDS_BCU EDI EDI_NCL EDI_NCU EDI_BCL EDI_BCU SEDI SEDI_NCL SEDI_NCU SEDI_BCL SEDI_BCU BAGSS BAGSS_BCL BAGSS_BCU +V11.0 : STAT : FHO : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL F_RATE H_RATE O_RATE +V11.0 : STAT : ISC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL TILE_DIM TILE_XLL TILE_YLL NSCALE ISCALE MSE ISC FENERGY2 OENERGY2 BASER FBIAS +V11.0 : STAT : MCTC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_CAT) F[0-9]*_O[0-9]* EC_VALUE +V11.0 : STAT : MCTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_CAT ACC ACC_NCL ACC_NCU ACC_BCL ACC_BCU HK HK_BCL HK_BCU HSS HSS_BCL HSS_BCU GER GER_BCL GER_BCU HSS_EC HSS_EC_BCL HSS_EC_BCU EC_VALUE +V11.0 : STAT : MPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX OBS_SID OBS_LAT OBS_LON OBS_LVL OBS_ELV FCST OBS OBS_QC CLIMO_MEAN CLIMO_STDEV CLIMO_CDF +V11.0 : STAT : NBRCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBS FBS_BCL FBS_BCU FSS FSS_BCL FSS_BCU AFSS AFSS_BCL AFSS_BCU UFSS UFSS_BCL UFSS_BCU F_RATE F_RATE_BCL F_RATE_BCU O_RATE O_RATE_BCL O_RATE_BCU +V11.0 : STAT : NBRCTC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FY_OY FY_ON FN_OY FN_ON +V11.0 : STAT : NBRCTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASER BASER_NCL BASER_NCU BASER_BCL BASER_BCU FMEAN FMEAN_NCL FMEAN_NCU FMEAN_BCL FMEAN_BCU ACC ACC_NCL ACC_NCU ACC_BCL ACC_BCU FBIAS FBIAS_BCL FBIAS_BCU PODY PODY_NCL PODY_NCU PODY_BCL PODY_BCU PODN PODN_NCL PODN_NCU PODN_BCL PODN_BCU POFD POFD_NCL POFD_NCU POFD_BCL POFD_BCU FAR FAR_NCL FAR_NCU FAR_BCL FAR_BCU CSI CSI_NCL CSI_NCU CSI_BCL CSI_BCU GSS GSS_BCL GSS_BCU HK HK_NCL HK_NCU HK_BCL HK_BCU HSS HSS_BCL HSS_BCU ODDS ODDS_NCL ODDS_NCU ODDS_BCL ODDS_BCU LODDS LODDS_NCL LODDS_NCU LODDS_BCL LODDS_BCU ORSS ORSS_NCL ORSS_NCU ORSS_BCL ORSS_BCU EDS EDS_NCL EDS_NCU EDS_BCL EDS_BCU SEDS SEDS_NCL SEDS_NCU SEDS_BCL SEDS_BCU EDI EDI_NCL EDI_NCU EDI_BCL EDI_BCU SEDI SEDI_NCL SEDI_NCU SEDI_BCL SEDI_BCU BAGSS BAGSS_BCL BAGSS_BCU +V11.0 : STAT : GRAD : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FGBAR OGBAR MGBAR EGBAR S1 S1_OG FGOG_RATIO DX DY +V11.0 : STAT : DMAP : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FY OY FBIAS BADDELEY HAUSDORFF MED_FO MED_OF MED_MIN MED_MAX MED_MEAN FOM_FO FOM_OF FOM_MIN FOM_MAX FOM_MEAN ZHU_FO ZHU_OF ZHU_MIN ZHU_MAX ZHU_MEAN G GBETA BETA_VALUE +V11.0 : STAT : ORANK : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX OBS_SID OBS_LAT OBS_LON OBS_LVL OBS_ELV OBS PIT RANK N_ENS_VLD (N_ENS) ENS_[0-9]* OBS_QC ENS_MEAN CLIMO_MEAN SPREAD ENS_MEAN_OERR SPREAD_OERR SPREAD_PLUS_OERR CLIMO_STDEV +V11.0 : STAT : PCT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_THRESH) THRESH_[0-9]* OY_[0-9]* ON_[0-9]* +V11.0 : STAT : PJC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_THRESH) THRESH_[0-9]* OY_TP_[0-9]* ON_TP_[0-9]* CALIBRATION_[0-9]* REFINEMENT_[0-9]* LIKELIHOOD_[0-9]* BASER_[0-9]* +V11.0 : STAT : PRC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_THRESH) THRESH_[0-9]* PODY_[0-9]* POFD_[0-9]* +V11.0 : STAT : PSTD : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_THRESH) BASER BASER_NCL BASER_NCU RELIABILITY RESOLUTION UNCERTAINTY ROC_AUC BRIER BRIER_NCL BRIER_NCU BRIERCL BRIERCL_NCL BRIERCL_NCU BSS BSS_SMPL THRESH_[0-9]* +V11.0 : STAT : ECLV : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASER VALUE_BASER (N_PTS) CL_[0-9]* VALUE_[0-9]* +V11.0 : STAT : ECNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS CRPS CRPSS IGN ME RMSE SPREAD ME_OERR RMSE_OERR SPREAD_OERR SPREAD_PLUS_OERR CRPSCL CRPS_EMP CRPSCL_EMP CRPSS_EMP +V11.0 : STAT : RPS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_PROB RPS_REL RPS_RES RPS_UNC RPS RPSS RPSS_SMPL RPS_COMP +V11.0 : STAT : RHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_RANK) RANK_[0-9]* +V11.0 : STAT : PHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BIN_SIZE (N_BIN) BIN_[0-9]* +V11.0 : STAT : RELP : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL (N_ENS) RELP_[0-9]* +V11.0 : STAT : SAL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FABAR OABAR FOABAR FFABAR OOABAR MAE +V11.0 : STAT : SL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR OBAR FOBAR FFBAR OOBAR MAE +V11.0 : STAT : SSVAR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_BIN BIN_i BIN_N VAR_MIN VAR_MAX VAR_MEAN FBAR OBAR FOBAR FFBAR OOBAR FBAR_NCL FBAR_NCU FSTDEV FSTDEV_NCL FSTDEV_NCU OBAR_NCL OBAR_NCU OSTDEV OSTDEV_NCL OSTDEV_NCU PR_CORR PR_CORR_NCL PR_CORR_NCU ME ME_NCL ME_NCU ESTDEV ESTDEV_NCL ESTDEV_NCU MBIAS MSE BCMSE RMSE +V11.0 : STAT : VAL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFABAR VFABAR UOABAR VOABAR UVFOABAR UVFFABAR UVOOABAR +V11.0 : STAT : VL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFBAR VFBAR UOBAR VOBAR UVFOBAR UVFFBAR UVOOBAR F_SPEED_BAR O_SPEED_BAR +V11.0 : STAT : VCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR FBAR_BCL FBAR_BCU OBAR OBAR_BCL OBAR_BCU FS_RMS FS_RMS_BCL FS_RMS_BCU OS_RMS OS_RMS_BCL OS_RMS_BCU MSVE MSVE_BCL MSVE_BCU RMSVE RMSVE_BCL RMSVE_BCU FSTDEV FSTDEV_BCL FSTDEV_BCU OSTDEV OSTDEV_BCL OSTDEV_BCU FDIR FDIR_BCL FDIR_BCU ODIR ODIR_BCL ODIR_BCU FBAR_SPEED FBAR_SPEED_BCL FBAR_SPEED_BCU OBAR_SPEED OBAR_SPEED_BCL OBAR_SPEED_BCU VDIFF_SPEED VDIFF_SPEED_BCL VDIFF_SPEED_BCU VDIFF_DIR VDIFF_DIR_BCL VDIFF_DIR_BCU SPEED_ERR SPEED_ERR_BCL SPEED_ERR_BCU SPEED_ABSERR SPEED_ABSERR_BCL SPEED_ABSERR_BCU DIR_ERR DIR_ERR_BCL DIR_ERR_BCU DIR_ABSERR DIR_ABSERR_BCL DIR_ABSERR_BCU +V11.0 : STAT : GENMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX STORM_ID PROB_LEAD PROB_VAL AGEN_INIT AGEN_FHR AGEN_LAT AGEN_LON AGEN_DLAND BGEN_LAT BGEN_LON BGEN_DLAND GEN_DIST GEN_TDIFF INIT_TDIFF DEV_CAT OPS_CAT +V11.0 : STAT : SSIDX : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE FCST_MODEL REF_MODEL N_INIT N_TERM N_VLD SS_INDEX + +V11.0 : MODE : OBJ : VERSION MODEL N_VALID GRID_RES DESC FCST_LEAD FCST_VALID FCST_ACCUM OBS_LEAD OBS_VALID OBS_ACCUM FCST_RAD FCST_THR OBS_RAD OBS_THR FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE OBJECT_ID OBJECT_CAT CENTROID_X CENTROID_Y CENTROID_LAT CENTROID_LON AXIS_ANG LENGTH WIDTH AREA AREA_THRESH CURVATURE CURVATURE_X CURVATURE_Y COMPLEXITY INTENSITY_10 INTENSITY_25 INTENSITY_50 INTENSITY_75 INTENSITY_90 INTENSITY_USER INTENSITY_SUM CENTROID_DIST BOUNDARY_DIST CONVEX_HULL_DIST ANGLE_DIFF ASPECT_DIFF AREA_RATIO INTERSECTION_AREA UNION_AREA SYMMETRIC_DIFF INTERSECTION_OVER_AREA CURVATURE_RATIO COMPLEXITY_RATIO PERCENTILE_INTENSITY_RATIO INTEREST +V11.0 : MODE : CTS : VERSION MODEL N_VALID GRID_RES DESC FCST_LEAD FCST_VALID FCST_ACCUM OBS_LEAD OBS_VALID OBS_ACCUM FCST_RAD FCST_THR OBS_RAD OBS_THR FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE FIELD TOTAL FY_OY FY_ON FN_OY FN_ON BASER FMEAN ACC FBIAS PODY PODN POFD FAR CSI GSS HK HSS ODDS + +V11.0 : TCST : TCMPR : VERSION AMODEL BMODEL DESC STORM_ID BASIN CYCLONE STORM_NAME INIT LEAD VALID INIT_MASK VALID_MASK LINE_TYPE TOTAL INDEX LEVEL WATCH_WARN INITIALS ALAT ALON BLAT BLON TK_ERR X_ERR Y_ERR ALTK_ERR CRTK_ERR ADLAND BDLAND AMSLP BMSLP AMAX_WIND BMAX_WIND AAL_WIND_34 BAL_WIND_34 ANE_WIND_34 BNE_WIND_34 ASE_WIND_34 BSE_WIND_34 ASW_WIND_34 BSW_WIND_34 ANW_WIND_34 BNW_WIND_34 AAL_WIND_50 BAL_WIND_50 ANE_WIND_50 BNE_WIND_50 ASE_WIND_50 BSE_WIND_50 ASW_WIND_50 BSW_WIND_50 ANW_WIND_50 BNW_WIND_50 AAL_WIND_64 BAL_WIND_64 ANE_WIND_64 BNE_WIND_64 ASE_WIND_64 BSE_WIND_64 ASW_WIND_64 BSW_WIND_64 ANW_WIND_64 BNW_WIND_64 ARADP BRADP ARRP BRRP AMRD BMRD AGUSTS BGUSTS AEYE BEYE ADIR BDIR ASPEED BSPEED ADEPTH BDEPTH +V11.0 : TCST : PROBRIRW : VERSION AMODEL BMODEL DESC STORM_ID BASIN CYCLONE STORM_NAME INIT LEAD VALID INIT_MASK VALID_MASK LINE_TYPE ALAT ALON BLAT BLON INITIALS TK_ERR X_ERR Y_ERR ADLAND BDLAND RIRW_BEG RIRW_END RIRW_WINDOW AWIND_END BWIND_BEG BWIND_END BDELTA BDELTA_MAX BLEVEL_BEG BLEVEL_END (N_THRESH) THRESH_[0-9]* PROB_[0-9]* diff --git a/met/scripts/config/EnsembleStatConfig b/met/scripts/config/EnsembleStatConfig index 9a1845555e..2dde84f7bb 100644 --- a/met/scripts/config/EnsembleStatConfig +++ b/met/scripts/config/EnsembleStatConfig @@ -348,6 +348,6 @@ rng = { grid_weight_flag = NONE; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GenEnsProdConfig b/met/scripts/config/GenEnsProdConfig index a0a52794c9..b3ff002f7a 100644 --- a/met/scripts/config/GenEnsProdConfig +++ b/met/scripts/config/GenEnsProdConfig @@ -158,6 +158,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_APCP_12 b/met/scripts/config/GridStatConfig_APCP_12 index 76747e7908..12213ba271 100644 --- a/met/scripts/config/GridStatConfig_APCP_12 +++ b/met/scripts/config/GridStatConfig_APCP_12 @@ -213,6 +213,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "APCP_12"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_APCP_24 b/met/scripts/config/GridStatConfig_APCP_24 index bca332cdde..7b9b82c7a4 100644 --- a/met/scripts/config/GridStatConfig_APCP_24 +++ b/met/scripts/config/GridStatConfig_APCP_24 @@ -223,6 +223,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "APCP_24"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_POP_12 b/met/scripts/config/GridStatConfig_POP_12 index 2df3bc3914..03cdd78e64 100644 --- a/met/scripts/config/GridStatConfig_POP_12 +++ b/met/scripts/config/GridStatConfig_POP_12 @@ -223,6 +223,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "POP_12"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_all b/met/scripts/config/GridStatConfig_all index 13b7f601f3..a782bcfb67 100644 --- a/met/scripts/config/GridStatConfig_all +++ b/met/scripts/config/GridStatConfig_all @@ -254,6 +254,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/MODEAnalysisConfig b/met/scripts/config/MODEAnalysisConfig index c305e257e4..da06f9bfde 100644 --- a/met/scripts/config/MODEAnalysisConfig +++ b/met/scripts/config/MODEAnalysisConfig @@ -186,6 +186,6 @@ simple = TRUE; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/MODEConfig_APCP_12 b/met/scripts/config/MODEConfig_APCP_12 index 2eed350075..e76132d42a 100644 --- a/met/scripts/config/MODEConfig_APCP_12 +++ b/met/scripts/config/MODEConfig_APCP_12 @@ -240,6 +240,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/MODEConfig_APCP_24 b/met/scripts/config/MODEConfig_APCP_24 index b9e9ee910d..a410061fcd 100644 --- a/met/scripts/config/MODEConfig_APCP_24 +++ b/met/scripts/config/MODEConfig_APCP_24 @@ -246,6 +246,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/MODEConfig_RH b/met/scripts/config/MODEConfig_RH index 18ff0de05f..f9809a326a 100644 --- a/met/scripts/config/MODEConfig_RH +++ b/met/scripts/config/MODEConfig_RH @@ -242,6 +242,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/PB2NCConfig_G212 b/met/scripts/config/PB2NCConfig_G212 index 25108a011a..348b2ba42b 100644 --- a/met/scripts/config/PB2NCConfig_G212 +++ b/met/scripts/config/PB2NCConfig_G212 @@ -94,6 +94,6 @@ event_stack_flag = TOP; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/PointStatConfig b/met/scripts/config/PointStatConfig index a39a25626e..8a4c18a5f0 100644 --- a/met/scripts/config/PointStatConfig +++ b/met/scripts/config/PointStatConfig @@ -211,6 +211,6 @@ output_flag = { rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/STATAnalysisConfig b/met/scripts/config/STATAnalysisConfig index 712813c57e..1ec8c0ea22 100644 --- a/met/scripts/config/STATAnalysisConfig +++ b/met/scripts/config/STATAnalysisConfig @@ -109,6 +109,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/WaveletStatConfig_APCP_12 b/met/scripts/config/WaveletStatConfig_APCP_12 index 67079ef1c7..ad7a8c8956 100644 --- a/met/scripts/config/WaveletStatConfig_APCP_12 +++ b/met/scripts/config/WaveletStatConfig_APCP_12 @@ -144,6 +144,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/WaveletStatConfig_APCP_12_NC b/met/scripts/config/WaveletStatConfig_APCP_12_NC index 2598e74883..c2d3317ad0 100644 --- a/met/scripts/config/WaveletStatConfig_APCP_12_NC +++ b/met/scripts/config/WaveletStatConfig_APCP_12_NC @@ -136,6 +136,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/string_fxns.cc b/met/src/basic/vx_util/string_fxns.cc index d03976f034..ce450b214a 100644 --- a/met/src/basic/vx_util/string_fxns.cc +++ b/met/src/basic/vx_util/string_fxns.cc @@ -35,13 +35,13 @@ using namespace std; bool match_met_version(const char * check_version) { - bool match = false; // // Check if the major version numbers match. // ConcatString check_major(parse_version_major(check_version)); ConcatString met_major(parse_version_major(met_version)); + return(check_major == met_major); } diff --git a/met/src/basic/vx_util/util_constants.h b/met/src/basic/vx_util/util_constants.h index 34da0d9e91..c648b49e86 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_11_0_0[] = "V11.0.0"; static const char met_version_10_1_0[] = "V10.1.0"; static const char met_version_10_0_0[] = "V10.0.0"; 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_10_1_0; +static const char * const met_version = met_version_11_0_0; 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/scripts/docker/build_met_docker.sh b/scripts/docker/build_met_docker.sh index fae3682113..dbb4ec4aa7 100755 --- a/scripts/docker/build_met_docker.sh +++ b/scripts/docker/build_met_docker.sh @@ -31,7 +31,6 @@ if [ $? != 0 ]; then exit 1 fi - if [[ $MET_GIT_NAME == "v"* ]]; then cd /met; rm -rf MET-*; fi diff --git a/test/config/Ascii2NcConfig.surfrad b/test/config/Ascii2NcConfig.surfrad index caca1df8b7..c202506b15 100644 --- a/test/config/Ascii2NcConfig.surfrad +++ b/test/config/Ascii2NcConfig.surfrad @@ -50,4 +50,4 @@ time_summary = { // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/Ascii2NcConfig_aeronet b/test/config/Ascii2NcConfig_aeronet index 76dd6954cc..e96f2a0666 100644 --- a/test/config/Ascii2NcConfig_aeronet +++ b/test/config/Ascii2NcConfig_aeronet @@ -46,4 +46,4 @@ message_type_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/EnsembleStatConfig b/test/config/EnsembleStatConfig index 1b12b3e973..1e9c7cf244 100644 --- a/test/config/EnsembleStatConfig +++ b/test/config/EnsembleStatConfig @@ -286,6 +286,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_MASK_SID b/test/config/EnsembleStatConfig_MASK_SID index 76e4adb43f..fab2c42267 100644 --- a/test/config/EnsembleStatConfig_MASK_SID +++ b/test/config/EnsembleStatConfig_MASK_SID @@ -275,6 +275,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_climo b/test/config/EnsembleStatConfig_climo index fea0dc9180..f2018f80c6 100644 --- a/test/config/EnsembleStatConfig_climo +++ b/test/config/EnsembleStatConfig_climo @@ -298,6 +298,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_grid_weight b/test/config/EnsembleStatConfig_grid_weight index 19325f310a..011c18daed 100644 --- a/test/config/EnsembleStatConfig_grid_weight +++ b/test/config/EnsembleStatConfig_grid_weight @@ -283,6 +283,6 @@ rng = { grid_weight_flag = ${GRID_WEIGHT}; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_one_cdf_bin b/test/config/EnsembleStatConfig_one_cdf_bin index 1197e77517..a2fee38da0 100644 --- a/test/config/EnsembleStatConfig_one_cdf_bin +++ b/test/config/EnsembleStatConfig_one_cdf_bin @@ -276,6 +276,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_python b/test/config/EnsembleStatConfig_python index b8261dcde3..e51aeb9e8a 100644 --- a/test/config/EnsembleStatConfig_python +++ b/test/config/EnsembleStatConfig_python @@ -267,6 +267,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_qty_inc_exc b/test/config/EnsembleStatConfig_qty_inc_exc index 62b42d75c2..cc0838f25e 100644 --- a/test/config/EnsembleStatConfig_qty_inc_exc +++ b/test/config/EnsembleStatConfig_qty_inc_exc @@ -290,6 +290,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_single_file_grib b/test/config/EnsembleStatConfig_single_file_grib index 27c802e30a..e731c8074f 100644 --- a/test/config/EnsembleStatConfig_single_file_grib +++ b/test/config/EnsembleStatConfig_single_file_grib @@ -326,6 +326,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/EnsembleStatConfig_single_file_nc b/test/config/EnsembleStatConfig_single_file_nc index 5f29e6c671..285ea922fc 100644 --- a/test/config/EnsembleStatConfig_single_file_nc +++ b/test/config/EnsembleStatConfig_single_file_nc @@ -330,6 +330,6 @@ rng = { grid_weight_flag = NONE; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig b/test/config/GenEnsProdConfig index 9e0e07dedd..ba6c0db94c 100644 --- a/test/config/GenEnsProdConfig +++ b/test/config/GenEnsProdConfig @@ -161,6 +161,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_climo_anom_ens_member_id b/test/config/GenEnsProdConfig_climo_anom_ens_member_id index de251a3445..686427c3a3 100644 --- a/test/config/GenEnsProdConfig_climo_anom_ens_member_id +++ b/test/config/GenEnsProdConfig_climo_anom_ens_member_id @@ -156,6 +156,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_normalize b/test/config/GenEnsProdConfig_normalize index d07328e973..755f29cdda 100644 --- a/test/config/GenEnsProdConfig_normalize +++ b/test/config/GenEnsProdConfig_normalize @@ -147,6 +147,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_single_file_grib b/test/config/GenEnsProdConfig_single_file_grib index c46677ab41..2ed7e5fe09 100644 --- a/test/config/GenEnsProdConfig_single_file_grib +++ b/test/config/GenEnsProdConfig_single_file_grib @@ -145,6 +145,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GenEnsProdConfig_single_file_nc b/test/config/GenEnsProdConfig_single_file_nc index f18517e2a7..c7adc3c89b 100644 --- a/test/config/GenEnsProdConfig_single_file_nc +++ b/test/config/GenEnsProdConfig_single_file_nc @@ -145,6 +145,6 @@ ensemble_flag = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridDiagConfig b/test/config/GridDiagConfig index 08b212c508..e2d4c5d8c5 100644 --- a/test/config/GridDiagConfig +++ b/test/config/GridDiagConfig @@ -63,6 +63,6 @@ mask = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridDiagConfig_APCP_06_FCST_OBS b/test/config/GridDiagConfig_APCP_06_FCST_OBS index 9ddae92cf6..9372a6bb0f 100644 --- a/test/config/GridDiagConfig_APCP_06_FCST_OBS +++ b/test/config/GridDiagConfig_APCP_06_FCST_OBS @@ -56,6 +56,6 @@ mask = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridDiagConfig_TMP b/test/config/GridDiagConfig_TMP index 14a6c46b4a..3d424fd848 100644 --- a/test/config/GridDiagConfig_TMP +++ b/test/config/GridDiagConfig_TMP @@ -67,6 +67,6 @@ mask = { //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_APCP_regrid b/test/config/GridStatConfig_APCP_regrid index af00db9f28..c9e10b1d6f 100644 --- a/test/config/GridStatConfig_APCP_regrid +++ b/test/config/GridStatConfig_APCP_regrid @@ -204,6 +204,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GRIB_lvl_typ_val b/test/config/GridStatConfig_GRIB_lvl_typ_val index 8ace03905d..767ef54558 100644 --- a/test/config/GridStatConfig_GRIB_lvl_typ_val +++ b/test/config/GridStatConfig_GRIB_lvl_typ_val @@ -301,6 +301,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "GRIB_lvl_typ_val"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GRIB_set_attr b/test/config/GridStatConfig_GRIB_set_attr index 917a0caf66..d4d2b2c387 100644 --- a/test/config/GridStatConfig_GRIB_set_attr +++ b/test/config/GridStatConfig_GRIB_set_attr @@ -233,6 +233,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "GRIB_set_attr"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GTG_latlon b/test/config/GridStatConfig_GTG_latlon index 36356d9b48..afb9706715 100644 --- a/test/config/GridStatConfig_GTG_latlon +++ b/test/config/GridStatConfig_GTG_latlon @@ -212,6 +212,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GTG_lc b/test/config/GridStatConfig_GTG_lc index c32de7a1b7..c8a126fe6d 100644 --- a/test/config/GridStatConfig_GTG_lc +++ b/test/config/GridStatConfig_GTG_lc @@ -212,6 +212,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_apply_mask b/test/config/GridStatConfig_apply_mask index 9142054e30..c3af968573 100644 --- a/test/config/GridStatConfig_apply_mask +++ b/test/config/GridStatConfig_apply_mask @@ -213,6 +213,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_WMO b/test/config/GridStatConfig_climo_WMO index f16d03b47e..c4cedceac9 100644 --- a/test/config/GridStatConfig_climo_WMO +++ b/test/config/GridStatConfig_climo_WMO @@ -274,6 +274,6 @@ nc_pairs_flag = { grid_weight_flag = COS_LAT; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_prob b/test/config/GridStatConfig_climo_prob index 085a8135d9..15ff20258f 100644 --- a/test/config/GridStatConfig_climo_prob +++ b/test/config/GridStatConfig_climo_prob @@ -284,6 +284,6 @@ nc_pairs_flag = { grid_weight_flag = COS_LAT; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_fbias_perc_thresh b/test/config/GridStatConfig_fbias_perc_thresh index 1072db748a..eebddc15fe 100644 --- a/test/config/GridStatConfig_fbias_perc_thresh +++ b/test/config/GridStatConfig_fbias_perc_thresh @@ -199,6 +199,6 @@ nc_pairs_flag = FALSE; grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_fourier b/test/config/GridStatConfig_fourier index ae4e33c118..f328963f4d 100644 --- a/test/config/GridStatConfig_fourier +++ b/test/config/GridStatConfig_fourier @@ -239,6 +239,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_grid_weight b/test/config/GridStatConfig_grid_weight index 4cd850faf1..f718d258c3 100644 --- a/test/config/GridStatConfig_grid_weight +++ b/test/config/GridStatConfig_grid_weight @@ -224,6 +224,6 @@ nc_pairs_flag = { grid_weight_flag = ${GRID_WEIGHT}; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_interp_shape b/test/config/GridStatConfig_interp_shape index 66d1658886..51e0a5ae06 100644 --- a/test/config/GridStatConfig_interp_shape +++ b/test/config/GridStatConfig_interp_shape @@ -207,6 +207,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_mpr_thresh b/test/config/GridStatConfig_mpr_thresh index b2930f027b..c266aac664 100644 --- a/test/config/GridStatConfig_mpr_thresh +++ b/test/config/GridStatConfig_mpr_thresh @@ -272,6 +272,6 @@ nc_pairs_flag = { grid_weight_flag = COS_LAT; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_no_leap b/test/config/GridStatConfig_no_leap index b33a52c222..9e4e39de3b 100644 --- a/test/config/GridStatConfig_no_leap +++ b/test/config/GridStatConfig_no_leap @@ -213,6 +213,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_prob_as_scalar b/test/config/GridStatConfig_prob_as_scalar index 8a462ce48a..29152d64d1 100644 --- a/test/config/GridStatConfig_prob_as_scalar +++ b/test/config/GridStatConfig_prob_as_scalar @@ -234,6 +234,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_python b/test/config/GridStatConfig_python index 3d9059219b..933d9ded81 100644 --- a/test/config/GridStatConfig_python +++ b/test/config/GridStatConfig_python @@ -210,6 +210,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "python"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_python_mixed b/test/config/GridStatConfig_python_mixed index 9b868a2745..0968c0f978 100644 --- a/test/config/GridStatConfig_python_mixed +++ b/test/config/GridStatConfig_python_mixed @@ -218,6 +218,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "python_mixed"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_rtma b/test/config/GridStatConfig_rtma index 2c3d3ba058..d3ed0cf0ec 100644 --- a/test/config/GridStatConfig_rtma +++ b/test/config/GridStatConfig_rtma @@ -214,6 +214,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_rtma_perc_thresh b/test/config/GridStatConfig_rtma_perc_thresh index 3a739645ad..a487d3be1f 100644 --- a/test/config/GridStatConfig_rtma_perc_thresh +++ b/test/config/GridStatConfig_rtma_perc_thresh @@ -217,6 +217,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_st4 b/test/config/GridStatConfig_st4 index 5f210db851..3b90e8d9da 100644 --- a/test/config/GridStatConfig_st4 +++ b/test/config/GridStatConfig_st4 @@ -218,6 +218,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_st4_censor b/test/config/GridStatConfig_st4_censor index 1942cfe107..fc023edc06 100644 --- a/test/config/GridStatConfig_st4_censor +++ b/test/config/GridStatConfig_st4_censor @@ -227,6 +227,6 @@ nc_pairs_flag = { grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/IODA2NCConfig_mask b/test/config/IODA2NCConfig_mask index 8a603c0e21..8a4007c370 100644 --- a/test/config/IODA2NCConfig_mask +++ b/test/config/IODA2NCConfig_mask @@ -117,6 +117,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/IODA2NCConfig_summary b/test/config/IODA2NCConfig_summary index b23b9b4df9..cbb33c11ba 100644 --- a/test/config/IODA2NCConfig_summary +++ b/test/config/IODA2NCConfig_summary @@ -117,6 +117,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_cut_line b/test/config/MODEConfig_cut_line index 105881ad2f..8a1c129527 100644 --- a/test/config/MODEConfig_cut_line +++ b/test/config/MODEConfig_cut_line @@ -234,6 +234,6 @@ shift_right = 50; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_hmt b/test/config/MODEConfig_hmt index cad4f3a3c2..739a3b1e6c 100644 --- a/test/config/MODEConfig_hmt +++ b/test/config/MODEConfig_hmt @@ -234,6 +234,6 @@ ct_stats_flag = TRUE; //////////////////////////////////////////////////////////////////////////////// output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_multivar_fake_data b/test/config/MODEConfig_multivar_fake_data index 282d7e7ec7..9402569bd9 100644 --- a/test/config/MODEConfig_multivar_fake_data +++ b/test/config/MODEConfig_multivar_fake_data @@ -254,6 +254,6 @@ shift_right = 0; // grid squares //////////////////////////////////////////////////////////////////////////////// output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_perc_thresh b/test/config/MODEConfig_perc_thresh index 659137e487..023c4bf2ba 100644 --- a/test/config/MODEConfig_perc_thresh +++ b/test/config/MODEConfig_perc_thresh @@ -235,6 +235,6 @@ ct_stats_flag = TRUE; //////////////////////////////////////////////////////////////////////////////// output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_python b/test/config/MODEConfig_python index a638b6603b..2bee9d62d5 100644 --- a/test/config/MODEConfig_python +++ b/test/config/MODEConfig_python @@ -239,6 +239,6 @@ ct_stats_flag = TRUE; //////////////////////////////////////////////////////////////////////////////// output_prefix = "python"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_python_mixed b/test/config/MODEConfig_python_mixed index 56253f07d0..17facabefc 100644 --- a/test/config/MODEConfig_python_mixed +++ b/test/config/MODEConfig_python_mixed @@ -242,6 +242,6 @@ ct_stats_flag = TRUE; //////////////////////////////////////////////////////////////////////////////// output_prefix = "python_mixed"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MODEConfig_quilt b/test/config/MODEConfig_quilt index d4b2fcc341..f79129c96c 100644 --- a/test/config/MODEConfig_quilt +++ b/test/config/MODEConfig_quilt @@ -232,6 +232,6 @@ ct_stats_flag = TRUE; //////////////////////////////////////////////////////////////////////////////// output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/MTDConfig_python b/test/config/MTDConfig_python index ed68eb6afc..b2926a7ec2 100644 --- a/test/config/MTDConfig_python +++ b/test/config/MTDConfig_python @@ -230,6 +230,6 @@ txt_output = { output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/Madis2NcConfig_time_summary b/test/config/Madis2NcConfig_time_summary index 7c8c1e586b..7fd2424c2f 100644 --- a/test/config/Madis2NcConfig_time_summary +++ b/test/config/Madis2NcConfig_time_summary @@ -33,4 +33,4 @@ time_summary = { // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/NetcdfConfig b/test/config/NetcdfConfig index e1b0eceaf9..943365b6d0 100644 --- a/test/config/NetcdfConfig +++ b/test/config/NetcdfConfig @@ -12,4 +12,4 @@ nc_compression = 2; -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/PB2NCConfig b/test/config/PB2NCConfig index a75189ec01..5225ffb9ef 100644 --- a/test/config/PB2NCConfig +++ b/test/config/PB2NCConfig @@ -101,6 +101,6 @@ event_stack_flag = TOP; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_airnow b/test/config/PB2NCConfig_airnow index 2a0a74ca08..5b9bc4bed3 100644 --- a/test/config/PB2NCConfig_airnow +++ b/test/config/PB2NCConfig_airnow @@ -115,6 +115,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_all b/test/config/PB2NCConfig_all index 7679b23413..27aa5bab1d 100644 --- a/test/config/PB2NCConfig_all +++ b/test/config/PB2NCConfig_all @@ -100,6 +100,6 @@ event_stack_flag = TOP; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_pbl b/test/config/PB2NCConfig_pbl index aeb272cfe3..4ddfb11cb1 100644 --- a/test/config/PB2NCConfig_pbl +++ b/test/config/PB2NCConfig_pbl @@ -137,6 +137,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_summary b/test/config/PB2NCConfig_summary index af236e212f..7ae20bc07e 100644 --- a/test/config/PB2NCConfig_summary +++ b/test/config/PB2NCConfig_summary @@ -128,6 +128,6 @@ time_summary = { //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PB2NCConfig_vlevel b/test/config/PB2NCConfig_vlevel index 011f37e9f9..b1ffd9b4bb 100644 --- a/test/config/PB2NCConfig_vlevel +++ b/test/config/PB2NCConfig_vlevel @@ -100,6 +100,6 @@ event_stack_flag = TOP; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/Point2GridConfig_valid_time b/test/config/Point2GridConfig_valid_time index cc93c91b86..4493880641 100644 --- a/test/config/Point2GridConfig_valid_time +++ b/test/config/Point2GridConfig_valid_time @@ -77,6 +77,6 @@ valid_time = "20201022_173000"; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_APCP b/test/config/PointStatConfig_APCP index 002e33aa49..b795c13f2a 100644 --- a/test/config/PointStatConfig_APCP +++ b/test/config/PointStatConfig_APCP @@ -134,6 +134,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_APCP_HIRA b/test/config/PointStatConfig_APCP_HIRA index 1972bec64b..44dbd4220b 100644 --- a/test/config/PointStatConfig_APCP_HIRA +++ b/test/config/PointStatConfig_APCP_HIRA @@ -137,6 +137,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_GTG_latlon b/test/config/PointStatConfig_GTG_latlon index a7fc58e970..f98475964f 100644 --- a/test/config/PointStatConfig_GTG_latlon +++ b/test/config/PointStatConfig_GTG_latlon @@ -156,6 +156,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_GTG_lc b/test/config/PointStatConfig_GTG_lc index a9dab3da7a..b2133e7ee4 100644 --- a/test/config/PointStatConfig_GTG_lc +++ b/test/config/PointStatConfig_GTG_lc @@ -164,6 +164,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_INTERP_OPTS b/test/config/PointStatConfig_INTERP_OPTS index 7898e9e17e..eaf7027140 100644 --- a/test/config/PointStatConfig_INTERP_OPTS +++ b/test/config/PointStatConfig_INTERP_OPTS @@ -147,6 +147,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_LAND_TOPO_MASK b/test/config/PointStatConfig_LAND_TOPO_MASK index c03318bcf6..cae0c06dee 100644 --- a/test/config/PointStatConfig_LAND_TOPO_MASK +++ b/test/config/PointStatConfig_LAND_TOPO_MASK @@ -187,6 +187,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_MASK_SID b/test/config/PointStatConfig_MASK_SID index 30f427d627..4b11f2805e 100644 --- a/test/config/PointStatConfig_MASK_SID +++ b/test/config/PointStatConfig_MASK_SID @@ -142,6 +142,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_PHYS b/test/config/PointStatConfig_PHYS index 2e227a74b3..cce7b88b95 100644 --- a/test/config/PointStatConfig_PHYS +++ b/test/config/PointStatConfig_PHYS @@ -143,6 +143,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_PHYS_pint b/test/config/PointStatConfig_PHYS_pint index 9ca75701a8..e9927a2339 100644 --- a/test/config/PointStatConfig_PHYS_pint +++ b/test/config/PointStatConfig_PHYS_pint @@ -138,6 +138,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_WINDS b/test/config/PointStatConfig_WINDS index 8156066edb..4a7644510e 100644 --- a/test/config/PointStatConfig_WINDS +++ b/test/config/PointStatConfig_WINDS @@ -158,6 +158,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_aeronet b/test/config/PointStatConfig_aeronet index 69799ede63..d99143041f 100644 --- a/test/config/PointStatConfig_aeronet +++ b/test/config/PointStatConfig_aeronet @@ -207,6 +207,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_airnow b/test/config/PointStatConfig_airnow index 5c424a3cb6..244aeda748 100644 --- a/test/config/PointStatConfig_airnow +++ b/test/config/PointStatConfig_airnow @@ -235,6 +235,6 @@ output_flag = { tmp_dir = "/tmp"; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_climo b/test/config/PointStatConfig_climo index 207d251ff5..b215e9b896 100644 --- a/test/config/PointStatConfig_climo +++ b/test/config/PointStatConfig_climo @@ -277,6 +277,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_climo_WMO b/test/config/PointStatConfig_climo_WMO index c801f581ac..29febac1df 100644 --- a/test/config/PointStatConfig_climo_WMO +++ b/test/config/PointStatConfig_climo_WMO @@ -225,6 +225,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_climo_prob b/test/config/PointStatConfig_climo_prob index ca4cadcbc9..b85293f226 100644 --- a/test/config/PointStatConfig_climo_prob +++ b/test/config/PointStatConfig_climo_prob @@ -227,6 +227,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_dup b/test/config/PointStatConfig_dup index 9e8b6a68c7..2d72cf364d 100644 --- a/test/config/PointStatConfig_dup +++ b/test/config/PointStatConfig_dup @@ -160,6 +160,6 @@ duplicate_flag = ${DUPLICATE_FLAG}; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_mpr_thresh b/test/config/PointStatConfig_mpr_thresh index f1559f1d3f..5a482ab234 100644 --- a/test/config/PointStatConfig_mpr_thresh +++ b/test/config/PointStatConfig_mpr_thresh @@ -219,6 +219,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_obs_summary b/test/config/PointStatConfig_obs_summary index 8530672ab9..3875c81010 100644 --- a/test/config/PointStatConfig_obs_summary +++ b/test/config/PointStatConfig_obs_summary @@ -148,6 +148,6 @@ output_flag = { rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_obs_summary_all b/test/config/PointStatConfig_obs_summary_all index 0d868dd519..0ab61af959 100644 --- a/test/config/PointStatConfig_obs_summary_all +++ b/test/config/PointStatConfig_obs_summary_all @@ -217,6 +217,6 @@ output_flag = { rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_prob b/test/config/PointStatConfig_prob index c576eb31f5..91ec54e3de 100644 --- a/test/config/PointStatConfig_prob +++ b/test/config/PointStatConfig_prob @@ -145,6 +145,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_python b/test/config/PointStatConfig_python index 8d70867143..ba5ddefd93 100644 --- a/test/config/PointStatConfig_python +++ b/test/config/PointStatConfig_python @@ -214,7 +214,7 @@ output_flag = { rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = ""; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_qty_inc_exc b/test/config/PointStatConfig_qty_inc_exc index 6e4f88509a..2cdf627cae 100644 --- a/test/config/PointStatConfig_qty_inc_exc +++ b/test/config/PointStatConfig_qty_inc_exc @@ -204,6 +204,6 @@ duplicate_flag = NONE; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_sid_inc_exc b/test/config/PointStatConfig_sid_inc_exc index 7ae01d3238..31318d2d18 100644 --- a/test/config/PointStatConfig_sid_inc_exc +++ b/test/config/PointStatConfig_sid_inc_exc @@ -151,6 +151,6 @@ obs_summary = NEAREST; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/RMWAnalysisConfig b/test/config/RMWAnalysisConfig index da5d813a30..1911204ab4 100644 --- a/test/config/RMWAnalysisConfig +++ b/test/config/RMWAnalysisConfig @@ -64,7 +64,7 @@ valid_mask = ""; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_APCP_HIRA b/test/config/STATAnalysisConfig_APCP_HIRA index e76c4a8ffc..6580be50eb 100644 --- a/test/config/STATAnalysisConfig_APCP_HIRA +++ b/test/config/STATAnalysisConfig_APCP_HIRA @@ -110,6 +110,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_SFC_SS_Index b/test/config/STATAnalysisConfig_SFC_SS_Index index d6f104843d..06b2ecd293 100644 --- a/test/config/STATAnalysisConfig_SFC_SS_Index +++ b/test/config/STATAnalysisConfig_SFC_SS_Index @@ -114,6 +114,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_climo b/test/config/STATAnalysisConfig_climo index 608bd3b255..eb7f9c8aac 100644 --- a/test/config/STATAnalysisConfig_climo +++ b/test/config/STATAnalysisConfig_climo @@ -116,6 +116,6 @@ hss_ec_value = NA; rank_corr_flag = FALSE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_filter_times b/test/config/STATAnalysisConfig_filter_times index 6af000732f..b52f6264c4 100644 --- a/test/config/STATAnalysisConfig_filter_times +++ b/test/config/STATAnalysisConfig_filter_times @@ -113,6 +113,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_grid_stat b/test/config/STATAnalysisConfig_grid_stat index 3365bf5f24..b6c222b123 100644 --- a/test/config/STATAnalysisConfig_grid_stat +++ b/test/config/STATAnalysisConfig_grid_stat @@ -106,6 +106,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_point_stat b/test/config/STATAnalysisConfig_point_stat index 82a68fbaf6..af33842c2e 100644 --- a/test/config/STATAnalysisConfig_point_stat +++ b/test/config/STATAnalysisConfig_point_stat @@ -135,6 +135,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/STATAnalysisConfig_ramps b/test/config/STATAnalysisConfig_ramps index aca6de0045..a06ac2dfcd 100644 --- a/test/config/STATAnalysisConfig_ramps +++ b/test/config/STATAnalysisConfig_ramps @@ -105,6 +105,6 @@ hss_ec_value = NA; rank_corr_flag = TRUE; vif_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig b/test/config/SeriesAnalysisConfig index 9d28ce3925..b172a154b4 100644 --- a/test/config/SeriesAnalysisConfig +++ b/test/config/SeriesAnalysisConfig @@ -146,6 +146,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig_climo b/test/config/SeriesAnalysisConfig_climo index 78d9e7449f..08807d55e5 100644 --- a/test/config/SeriesAnalysisConfig_climo +++ b/test/config/SeriesAnalysisConfig_climo @@ -150,6 +150,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig_climo_prob b/test/config/SeriesAnalysisConfig_climo_prob index ee023bf6c4..916c7e9ec2 100644 --- a/test/config/SeriesAnalysisConfig_climo_prob +++ b/test/config/SeriesAnalysisConfig_climo_prob @@ -159,6 +159,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig_conditional b/test/config/SeriesAnalysisConfig_conditional index b4becd6656..e939a4a616 100644 --- a/test/config/SeriesAnalysisConfig_conditional +++ b/test/config/SeriesAnalysisConfig_conditional @@ -113,6 +113,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/SeriesAnalysisConfig_python b/test/config/SeriesAnalysisConfig_python index a33b237ab3..41e2a800ab 100644 --- a/test/config/SeriesAnalysisConfig_python +++ b/test/config/SeriesAnalysisConfig_python @@ -150,6 +150,6 @@ output_stats = { hss_ec_value = NA; rank_corr_flag = FALSE; tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/TCGenConfig_2016 b/test/config/TCGenConfig_2016 index b1d78ba8e7..022d4fd0c0 100644 --- a/test/config/TCGenConfig_2016 +++ b/test/config/TCGenConfig_2016 @@ -326,4 +326,4 @@ nc_pairs_grid = "G003"; // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCGenConfig_prob b/test/config/TCGenConfig_prob index db075b4479..1ac71fff6c 100644 --- a/test/config/TCGenConfig_prob +++ b/test/config/TCGenConfig_prob @@ -285,4 +285,4 @@ nc_pairs_grid = "G003"; // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCGenConfig_shape b/test/config/TCGenConfig_shape index 767349741e..39d50d1d4e 100644 --- a/test/config/TCGenConfig_shape +++ b/test/config/TCGenConfig_shape @@ -289,4 +289,4 @@ nc_pairs_grid = "G003"; // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCPairsConfig_ALAL2010 b/test/config/TCPairsConfig_ALAL2010 index 790c667f28..0dfc50ee28 100644 --- a/test/config/TCPairsConfig_ALAL2010 +++ b/test/config/TCPairsConfig_ALAL2010 @@ -143,4 +143,4 @@ basin_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCPairsConfig_BASIN_MAP b/test/config/TCPairsConfig_BASIN_MAP index 83bb491385..fb0075ee17 100644 --- a/test/config/TCPairsConfig_BASIN_MAP +++ b/test/config/TCPairsConfig_BASIN_MAP @@ -144,4 +144,4 @@ basin_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCPairsConfig_INTERP12 b/test/config/TCPairsConfig_INTERP12 index 7c2301d50c..92e00a10b5 100644 --- a/test/config/TCPairsConfig_INTERP12 +++ b/test/config/TCPairsConfig_INTERP12 @@ -144,4 +144,4 @@ basin_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCPairsConfig_PROBRIRW b/test/config/TCPairsConfig_PROBRIRW index e75b3a3bd1..1632603972 100644 --- a/test/config/TCPairsConfig_PROBRIRW +++ b/test/config/TCPairsConfig_PROBRIRW @@ -143,4 +143,4 @@ basin_map = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCRMWConfig_gonzalo b/test/config/TCRMWConfig_gonzalo index 933bb6c153..8693104167 100644 --- a/test/config/TCRMWConfig_gonzalo +++ b/test/config/TCRMWConfig_gonzalo @@ -105,6 +105,6 @@ rmw_scale = 0.2; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/TCRMWConfig_pressure_lev_out b/test/config/TCRMWConfig_pressure_lev_out index df980f1295..a627d572e1 100644 --- a/test/config/TCRMWConfig_pressure_lev_out +++ b/test/config/TCRMWConfig_pressure_lev_out @@ -105,6 +105,6 @@ rmw_scale = 0.2; //////////////////////////////////////////////////////////////////////////////// -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/TCStatConfig_ALAL2010 b/test/config/TCStatConfig_ALAL2010 index 33a746fe84..85c3141ffe 100644 --- a/test/config/TCStatConfig_ALAL2010 +++ b/test/config/TCStatConfig_ALAL2010 @@ -204,4 +204,4 @@ jobs = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/TCStatConfig_PROBRIRW b/test/config/TCStatConfig_PROBRIRW index 41ffbf1c8a..a48bcc6dba 100644 --- a/test/config/TCStatConfig_PROBRIRW +++ b/test/config/TCStatConfig_PROBRIRW @@ -202,4 +202,4 @@ jobs = [ // Indicate a version number for the contents of this configuration file. // The value should generally not be modified. // -version = "V10.1.0"; +version = "V11.0.0"; diff --git a/test/config/WaveletStatConfig b/test/config/WaveletStatConfig index 06963c8f51..21b1882f07 100644 --- a/test/config/WaveletStatConfig +++ b/test/config/WaveletStatConfig @@ -134,6 +134,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/WaveletStatConfig_no_thresholds b/test/config/WaveletStatConfig_no_thresholds index 42e02ca680..ab039429b4 100644 --- a/test/config/WaveletStatConfig_no_thresholds +++ b/test/config/WaveletStatConfig_no_thresholds @@ -134,6 +134,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = "${OUTPUT_PREFIX}"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/WaveletStatConfig_python b/test/config/WaveletStatConfig_python index b9e2d62f04..3ae9a60c08 100644 --- a/test/config/WaveletStatConfig_python +++ b/test/config/WaveletStatConfig_python @@ -125,6 +125,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = "python"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/WaveletStatConfig_python_mixed b/test/config/WaveletStatConfig_python_mixed index 899766b007..f7724b37fd 100644 --- a/test/config/WaveletStatConfig_python_mixed +++ b/test/config/WaveletStatConfig_python_mixed @@ -134,6 +134,6 @@ wvlt_plot = { //////////////////////////////////////////////////////////////////////////////// output_prefix = "python_mixed"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/GridStatConfig_03h b/test/config/ref_config/GridStatConfig_03h index dc40220c7b..c25186b94d 100644 --- a/test/config/ref_config/GridStatConfig_03h +++ b/test/config/ref_config/GridStatConfig_03h @@ -200,6 +200,6 @@ nc_pairs_flag = FALSE; grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${MODEL}_F${FCST_TIME}_03h"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/GridStatConfig_24h b/test/config/ref_config/GridStatConfig_24h index 450b7117aa..22125d478c 100644 --- a/test/config/ref_config/GridStatConfig_24h +++ b/test/config/ref_config/GridStatConfig_24h @@ -200,6 +200,6 @@ nc_pairs_flag = FALSE; grid_weight_flag = NONE; tmp_dir = "/tmp"; output_prefix = "${MODEL}_F${FCST_TIME}_24h"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/PB2NCConfig b/test/config/ref_config/PB2NCConfig index 21bfdf4fb4..96a3d022cf 100644 --- a/test/config/ref_config/PB2NCConfig +++ b/test/config/ref_config/PB2NCConfig @@ -101,6 +101,6 @@ event_stack_flag = TOP; //////////////////////////////////////////////////////////////////////////////// tmp_dir = "/tmp"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/PointStatConfig_ADPUPA b/test/config/ref_config/PointStatConfig_ADPUPA index 8c3be8c75e..63673104be 100644 --- a/test/config/ref_config/PointStatConfig_ADPUPA +++ b/test/config/ref_config/PointStatConfig_ADPUPA @@ -182,6 +182,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${MODEL}_F${FCST_TIME}_ADPUPA"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/PointStatConfig_ONLYSF b/test/config/ref_config/PointStatConfig_ONLYSF index 06bfbc3813..fa9363986b 100644 --- a/test/config/ref_config/PointStatConfig_ONLYSF +++ b/test/config/ref_config/PointStatConfig_ONLYSF @@ -192,6 +192,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${MODEL}_F${FCST_TIME}_ONLYSF"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/PointStatConfig_WINDS b/test/config/ref_config/PointStatConfig_WINDS index 3309419131..23cb75b2d6 100644 --- a/test/config/ref_config/PointStatConfig_WINDS +++ b/test/config/ref_config/PointStatConfig_WINDS @@ -175,6 +175,6 @@ duplicate_flag = NONE; rank_corr_flag = FALSE; tmp_dir = "/tmp"; output_prefix = "${MODEL}_F${FCST_TIME}_WINDS"; -version = "V10.1.0"; +version = "V11.0.0"; //////////////////////////////////////////////////////////////////////////////// diff --git a/test/hdr/met_11_0.hdr b/test/hdr/met_11_0.hdr new file mode 100644 index 0000000000..84f5b5a950 --- /dev/null +++ b/test/hdr/met_11_0.hdr @@ -0,0 +1,37 @@ +CNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR FBAR_NCL FBAR_NCU FBAR_BCL FBAR_BCU FSTDEV FSTDEV_NCL FSTDEV_NCU FSTDEV_BCL FSTDEV_BCU OBAR OBAR_NCL OBAR_NCU OBAR_BCL OBAR_BCU OSTDEV OSTDEV_NCL OSTDEV_NCU OSTDEV_BCL OSTDEV_BCU PR_CORR PR_CORR_NCL PR_CORR_NCU PR_CORR_BCL PR_CORR_BCU SP_CORR KT_CORR RANKS FRANK_TIES ORANK_TIES ME ME_NCL ME_NCU ME_BCL ME_BCU ESTDEV ESTDEV_NCL ESTDEV_NCU ESTDEV_BCL ESTDEV_BCU MBIAS MBIAS_BCL MBIAS_BCU MAE MAE_BCL MAE_BCU MSE MSE_BCL MSE_BCU BCMSE BCMSE_BCL BCMSE_BCU RMSE RMSE_BCL RMSE_BCU E10 E10_BCL E10_BCU E25 E25_BCL E25_BCU E50 E50_BCL E50_BCU E75 E75_BCL E75_BCU E90 E90_BCL E90_BCU EIQR EIQR_BCL EIQR_BCU MAD MAD_BCL MAD_BCU ANOM_CORR ANOM_CORR_NCL ANOM_CORR_NCU ANOM_CORR_BCL ANOM_CORR_BCU ME2 ME2_BCL ME2_BCU MSESS MSESS_BCL MSESS_BCU RMSFA RMSFA_BCL RMSFA_BCU RMSOA RMSOA_BCL RMSOA_BCU ANOM_CORR_UNCNTR ANOM_CORR_UNCNTR_BCL ANOM_CORR_UNCNTR_BCU SI SI_BCL SI_BCU +CTC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FY_OY FY_ON FN_OY FN_ON +CTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASER BASER_NCL BASER_NCU BASER_BCL BASER_BCU FMEAN FMEAN_NCL FMEAN_NCU FMEAN_BCL FMEAN_BCU ACC ACC_NCL ACC_NCU ACC_BCL ACC_BCU FBIAS FBIAS_BCL FBIAS_BCU PODY PODY_NCL PODY_NCU PODY_BCL PODY_BCU PODN PODN_NCL PODN_NCU PODN_BCL PODN_BCU POFD POFD_NCL POFD_NCU POFD_BCL POFD_BCU FAR FAR_NCL FAR_NCU FAR_BCL FAR_BCU CSI CSI_NCL CSI_NCU CSI_BCL CSI_BCU GSS GSS_BCL GSS_BCU HK HK_NCL HK_NCU HK_BCL HK_BCU HSS HSS_BCL HSS_BCU ODDS ODDS_NCL ODDS_NCU ODDS_BCL ODDS_BCU LODDS LODDS_NCL LODDS_NCU LODDS_BCL LODDS_BCU ORSS ORSS_NCL ORSS_NCU ORSS_BCL ORSS_BCU EDS EDS_NCL EDS_NCU EDS_BCL EDS_BCU SEDS SEDS_NCL SEDS_NCU SEDS_BCL SEDS_BCU EDI EDI_NCL EDI_NCU EDI_BCL EDI_BCU SEDI SEDI_NCL SEDI_NCU SEDI_BCL SEDI_BCU BAGSS BAGSS_BCL BAGSS_BCU +FHO : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL F_RATE H_RATE O_RATE +ISC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL TILE_DIM TILE_XLL TILE_YLL NSCALE ISCALE MSE ISC FENERGY2 OENERGY2 BASER FBIAS +MCTC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_CAT _VAR_ +MCTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_CAT ACC ACC_NCL ACC_NCU ACC_BCL ACC_BCU HK HK_BCL HK_BCU HSS HSS_BCL HSS_BCU GER GER_BCL GER_BCU HSS_EC HSS_EC_BCL HSS_EC_BCU EC_VALUE +MPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX OBS_SID OBS_LAT OBS_LON OBS_LVL OBS_ELV FCST OBS OBS_QC CLIMO_MEAN CLIMO_STDEV CLIMO_CDF_VAR_ +NBRCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBS FBS_BCL FBS_BCU FSS FSS_BCL FSS_BCU AFSS AFSS_BCL AFSS_BCU UFSS UFSS_BCL UFSS_BCU F_RATE F_RATE_BCL F_RATE_BCU O_RATE O_RATE_BCL O_RATE_BCU +NBRCTC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FY_OY FY_ON FN_OY FN_ON +NBRCTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASER BASER_NCL BASER_NCU BASER_BCL BASER_BCU FMEAN FMEAN_NCL FMEAN_NCU FMEAN_BCL FMEAN_BCU ACC ACC_NCL ACC_NCU ACC_BCL ACC_BCU FBIAS FBIAS_BCL FBIAS_BCU PODY PODY_NCL PODY_NCU PODY_BCL PODY_BCU PODN PODN_NCL PODN_NCU PODN_BCL PODN_BCU POFD POFD_NCL POFD_NCU POFD_BCL POFD_BCU FAR FAR_NCL FAR_NCU FAR_BCL FAR_BCU CSI CSI_NCL CSI_NCU CSI_BCL CSI_BCU GSS GSS_BCL GSS_BCU HK HK_NCL HK_NCU HK_BCL HK_BCU HSS HSS_BCL HSS_BCU ODDS ODDS_NCL ODDS_NCU ODDS_BCL ODDS_BCU LODDS LODDS_NCL LODDS_NCU LODDS_BCL LODDS_BCU ORSS ORSS_NCL ORSS_NCU ORSS_BCL ORSS_BCU EDS EDS_NCL EDS_NCU EDS_BCL EDS_BCU SEDS SEDS_NCL SEDS_NCU SEDS_BCL SEDS_BCU EDI EDI_NCL EDI_NCU EDI_BCL EDI_BCU SEDI SEDI_NCL SEDI_NCU SEDI_BCL SEDI_BCU BAGSS BAGSS_BCL BAGSS_BCU +GRAD : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FGBAR OGBAR MGBAR EGBAR S1 S1_OG FGOG_RATIO DX DY +DMAP : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FY OY FBIAS BADDELEY HAUSDORFF MED_FO MED_OF MED_MIN MED_MAX MED_MEAN FOM_FO FOM_OF FOM_MIN FOM_MAX FOM_MEAN ZHU_FO ZHU_OF ZHU_MIN ZHU_MAX ZHU_MEAN G GBETA BETA_VALUE +ORANK : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX OBS_SID OBS_LAT OBS_LON OBS_LVL OBS_ELV OBS PIT RANK N_ENS_VLD N_ENS _VAR_ +PCT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_THRESH _VAR_ +PJC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_THRESH _VAR_ +PRC : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_THRESH _VAR_ +PSTD : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_THRESH BASER BASER_NCL BASER_NCU RELIABILITY RESOLUTION UNCERTAINTY ROC_AUC BRIER BRIER_NCL BRIER_NCU BRIERCL BRIERCL_NCL BRIERCL_NCU BSS BSS_SMPL _VAR_ +ECLV : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BASE N_PTS _VAR_ +ECNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS CRPS CRPSS IGN ME RMSE SPREAD ME_OERR RMSE_OERR SPREAD_OERR SPREAD_PLUS_OERR CRPSCL CRPS_EMP CRPSCL_EMP CRPSS_EMP +RPS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_PROB RPS_REL RPS_RES RPS_UNC RPS RPSS RPSS_SMPL RPS_COMP +RHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL CRPS IGN N_RANK CRPSS SPREAD _VAR_ +PHIST : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL BIN_SIZE N_BIN _VAR_ +RELP : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_ENS _VAR_ +SAL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FABAR OABAR FOABAR FFABAR OOABAR MAE +SL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR OBAR FOBAR FFBAR OOBAR MAE +SSVAR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL N_BIN BIN_i BIN_N VAR_MIN VAR_MAX VAR_MEAN FBAR OBAR FOBAR FFBAR OOBAR FBAR_NCL FBAR_NCU FSTDEV FSTDEV_NCL FSTDEV_NCU OBAR_NCL OBAR_NCU OSTDEV OSTDEV_NCL OSTDEV_NCU PR_CORR PR_CORR_NCL PR_CORR_NCU ME ME_NCL ME_NCU ESTDEV ESTDEV_NCL ESTDEV_NCU MBIAS MSE BCMSE RMSE +VL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFBAR VFBAR UOBAR VOBAR UVFOBAR UVFFBAR UVOOBAR F_SPEED_BAR O_SPEED_BAR +VAL1L2 : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL UFABAR VFABAR UOABAR VOABAR UVFOABAR UVFFABAR UVOOABAR +VCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL FBAR FBAR_BCL FBAR_BCU OBAR OBAR_BCL OBAR_BCU FS_RMS FS_RMS_BCL FS_RMS_BCU OS_RMS OS_RMS_BCL OS_RMS_BCU MSVE MSVE_BCL MSVE_BCU RMSVE RMSVE_BCL RMSVE_BCU FSTDEV FSTDEV_BCL FSTDEV_BCU OSTDEV OSTDEV_BCL OSTDEV_BCU FDIR FDIR_BCL FDIR_BCU ODIR ODIR_BCL ODIR_BCU FBAR_SPEED FBAR_SPEED_BCL FBAR_SPEED_BCU OBAR_SPEED OBAR_SPEED_BCL OBAR_SPEED_BCU VDIFF_SPEED VDIFF_SPEED_BCL VDIFF_SPEED_BCU VDIFF_DIR VDIFF_DIR_BCL VDIFF_DIR_BCU SPEED_ERR SPEED_ERR_BCL SPEED_ERR_BCU SPEED_ABSERR SPEED_ABSERR_BCL SPEED_ABSERR_BCU DIR_ERR DIR_ERR_BCL DIR_ERR_BCU DIR_ABSERR DIR_ABSERR_BCL DIR_ABSERR_BCU +GENMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE TOTAL INDEX STORM_ID PROB_LEAD PROB_VAL AGEN_INIT AGEN_FHR AGEN_LAT AGEN_LON AGEN_DLAND BGEN_LAT BGEN_LON BGEN_DLAND GEN_DIST GEN_TDIFF INIT_TDIFF DEV_CAT OPS_CAT +SSIDX : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE FCST_MODEL REF_MODEL N_INIT N_TERM N_VLD SS_INDEX +MODE_SOA : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE N_VALID GRID_RES OBJECT_ID OBJECT_CAT CENTROID_X CENTROID_Y CENTROID_LAT CENTROID_LON AXIS_ANG LENGTH WIDTH AREA AREA_THRESH CURVATURE CURVATURE_X CURVATURE_Y COMPLEXITY INTENSITY_10 INTENSITY_25 INTENSITY_50 INTENSITY_75 INTENSITY_90 INTENSITY_50 INTENSITY_SUM +MODE_POA : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE N_VALID GRID_RES OBJECT_ID OBJECT_CAT CENTROID_DIST BOUNDARY_DIST CONVEX_HULL_DIST ANGLE_DIFF ASPECT_DIFF AREA_RATIO INTERSECTION_AREA UNION_AREA SYMMETRIC_DIFF INTERSECTION_OVER_AREA CURVATURE_RATIO COMPLEXITY_RATIO PERCENTILE_INTENSITY_RATIO INTEREST +MODE_CTS : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE N_VALID GRID_RES FIELD TOTAL FY_OY FY_ON FN_OY FN_ON BASER FMEAN ACC FBIAS PODY PODN POFD FAR CSI GSS HK HSS ODDS +TCST_TCMPR : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE AMODEL BMODEL STORM_ID BASIN CYCLONE STORM_NAME INIT_MASK VALID_MASK TOTAL INDEX LEVEL WATCH_WARN INITIALS ALAT ALON BLAT BLON TK_ERR X_ERR Y_ERR ALTK_ERR CRTK_ERR ADLAND BDLAND AMSLP BMSLP AMAX_WIND BMAX_WIND AAL_WIND_34 BAL_WIND_34 ANE_WIND_34 BNE_WIND_34 ASE_WIND_34 BSE_WIND_34 ASW_WIND_34 BSW_WIND_34 ANW_WIND_34 BNW_WIND_34 AAL_WIND_50 BAL_WIND_50 ANE_WIND_50 BNE_WIND_50 ASE_WIND_50 BSE_WIND_50 ASW_WIND_50 BSW_WIND_50 ANW_WIND_50 BNW_WIND_50 AAL_WIND_64 BAL_WIND_64 ANE_WIND_64 BNE_WIND_64 ASE_WIND_64 BSE_WIND_64 ASW_WIND_64 BSW_WIND_64 ANW_WIND_64 BNW_WIND_64 ARADP BRADP ARRP BRRP AMRD BMRD AGUSTS BGUSTS AEYE BEYE ADIR BDIR ASPEED BSPEED ADEPTH BDEPTH +TCST_PROBRIRW : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_LEAD OBS_VALID_BEG OBS_VALID_END FCST_VAR FCST_UNITS FCST_LEV OBS_VAR OBS_UNITS OBS_LEV OBTYPE VX_MASK INTERP_MTHD INTERP_PNTS FCST_THRESH OBS_THRESH COV_THRESH ALPHA LINE_TYPE ALAT ALON BLAT BLON INITIALS TK_ERR X_ERR Y_ERR ADLAND BDLAND RI_BEG RI_END RI_WINDOW AWIND_END BWIND_BEG BWIND_END BDELTA BDELTA_MAX BLEVEL_BEG BLEVEL_END N_THRESH _VAR_