diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..d959c9e411 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,50 @@ +name: MET CI/CD Workflow +on: + push: + branches: + - develop + - develop-ref + - feature_* + - main_* + - bugfix_* + pull_request: + types: [opened, reopened, synchronize] + +jobs: + documentation: + name: Build Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Install dependencies + run: | + python -m pip install --upgrade python-dateutil requests sphinx \ + sphinx-gallery Pillow sphinx_rtd_theme + - name: Build docs + continue-on-error: true + run: | + DOCS_DIR=${GITHUB_WORKSPACE}/met/docs + cd ${DOCS_DIR} + make clean html + cd ${GITHUB_WORKSPACE} + warning_file=${DOCS_DIR}/_build/warnings.log + mkdir -p artifact/documentation + cp -r ${DOCS_DIR}/_build/html/* artifact/documentation + if [ -s $warning_file ]; then + cp -r ${DOCS_DIR}/_build/warnings.log artifact/doc_warnings.log + cp artifact/doc_warnings.log artifact/documentation + else + rm ${warning_file} + fi + - uses: actions/upload-artifact@v2 + with: + name: documentation + path: artifact/documentation + - uses: actions/upload-artifact@v2 + with: + name: documentation_warnings.log + path: artifact/doc_warnings.log + if-no-files-found: ignore diff --git a/met/data/config/GridStatConfig_default b/met/data/config/GridStatConfig_default index acd3a71051..c32872783a 100644 --- a/met/data/config/GridStatConfig_default +++ b/met/data/config/GridStatConfig_default @@ -43,6 +43,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/met/data/config/PointStatConfig_default b/met/data/config/PointStatConfig_default index ae05370fbc..b0a4981c62 100644 --- a/met/data/config/PointStatConfig_default +++ b/met/data/config/PointStatConfig_default @@ -38,6 +38,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = [ NA ]; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/met/docs/Makefile b/met/docs/Makefile index 6d88c8d309..81e7849441 100644 --- a/met/docs/Makefile +++ b/met/docs/Makefile @@ -21,4 +21,5 @@ clean: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + [ -d $(BUILDDIR) ] || mkdir -p $(BUILDDIR) + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -w "$(BUILDDIR)/warnings.log" diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index e1f65cc7b4..1277564934 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -640,12 +640,12 @@ to be verified. This dictionary may include the following entries: metadata of any output files, but the user can set the "desc" entry accordingly. - Examples of user-defined conversion functions include: + Examples of user-defined data censoring operations include: .. code-block:: none censor_thresh = [ >12000 ]; - censor_val = [ 12000 ]; + censor_val = [ 12000 ]; * Several configuration options are provided to override and correct the metadata read from the input file. The supported options are listed @@ -678,6 +678,25 @@ to be verified. This dictionary may include the following entries: is_wind_direction = boolean; is_prob = boolean; + * The "mpr_column" and "mpr_thresh" entries are arrays of strings and + thresholds to specify which matched pairs should be included in the + statistics. These options apply to the Point-Stat and Grid-Stat tools. + They are parsed seperately for each "obs.field" array entry. + The "mpr_column" strings specify MPR column names ("FCST", "OBS", + "CLIMO_MEAN", "CLIMO_STDEV", or "CLIMO_CDF"), differences of columns + ("FCST-OBS"), or the absolute value of those differences ("ABS(FCST-OBS)"). + The number of "mpr_thresh" thresholds must match the number of "mpr_column" + entries, and the n-th threshold is applied to the n-th column. Any matched + pairs which do not meet any of the specified thresholds are excluded from + the analysis. For example, the following settings exclude matched pairs + where the observation value differs from the forecast or climatological + mean values by more than 10: + + .. code-block:: none + + mpr_column = [ "ABS(OBS-FCST)", "ABS(OBS-CLIMO_MEAN)" ]; + mpr_thresh = [ <=10, <=10 ]; + * The "cat_thresh" entry is an array of thresholds to be used when computing categorical statistics. @@ -981,6 +1000,8 @@ or obs = { censor_thresh = []; censor_val = []; + mpr_column = []; + mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index a3aac48240..ff5808df9c 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -221,13 +221,15 @@ __________________________ type = [ { method = NEAREST; width = 1; } ]; } censor_thresh = []; censor_val = []; + mpr_column = []; + mpr_thresh = []; eclv_points = 0.05; rank_corr_flag = TRUE; tmp_dir = "/tmp"; output_prefix = ""; version = "VN.N"; -The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. +The configuration options listed above are common to multiple MET tools and are described in :numref:`config_options`. ___________________________ diff --git a/met/docs/Users_Guide/point-stat.rst b/met/docs/Users_Guide/point-stat.rst index 1ec6fdacb9..bfbbc53fba 100644 --- a/met/docs/Users_Guide/point-stat.rst +++ b/met/docs/Users_Guide/point-stat.rst @@ -334,6 +334,8 @@ ________________________ type = [ { method = NEAREST; width = 1; } ]; } censor_thresh = []; censor_val = []; + mpr_column = []; + mpr_thresh = []; eclv_points = 0.05; rank_corr_flag = TRUE; sid_inc = []; @@ -347,7 +349,7 @@ ________________________ output_prefix = ""; version = "VN.N"; -The configuration options listed above are common to many MET tools and are described in :numref:`config_options`. +The configuration options listed above are common to multiple MET tools and are described in :numref:`config_options`. _________________________ diff --git a/met/docs/conf.py b/met/docs/conf.py index 13f65b1b9d..2a51afe4d7 100644 --- a/met/docs/conf.py +++ b/met/docs/conf.py @@ -53,8 +53,6 @@ html_theme = 'sphinx_rtd_theme' html_theme_path = ["_themes", ] html_js_files = ['pop_ver.js'] -html_theme_options = {'canonical_url': 'https://dtcenter.github.io/MET/latest/'} -html_theme_options['versions'] = {'latest': '../latest', 'develop': '../develop'} html_css_files = ['theme_override.css'] # Add any paths that contain custom static files (such as style sheets) here, diff --git a/met/scripts/config/GridStatConfig_APCP_12 b/met/scripts/config/GridStatConfig_APCP_12 index 9ea99e03bc..f4308d3bca 100644 --- a/met/scripts/config/GridStatConfig_APCP_12 +++ b/met/scripts/config/GridStatConfig_APCP_12 @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; @@ -52,7 +54,6 @@ nc_pairs_var_name = ""; nc_pairs_var_suffix = ""; rank_corr_flag = FALSE; - // // Forecast and observation fields to be verified // diff --git a/met/scripts/config/GridStatConfig_APCP_24 b/met/scripts/config/GridStatConfig_APCP_24 index 9d73b6b21c..af2cf4f003 100644 --- a/met/scripts/config/GridStatConfig_APCP_24 +++ b/met/scripts/config/GridStatConfig_APCP_24 @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; @@ -51,6 +53,7 @@ eclv_points = 0.05; nc_pairs_var_name = ""; nc_pairs_var_suffix = ""; rank_corr_flag = FALSE; + // // Forecast and observation fields to be verified // diff --git a/met/scripts/config/GridStatConfig_POP_12 b/met/scripts/config/GridStatConfig_POP_12 index faff0be7e3..c46f639b94 100644 --- a/met/scripts/config/GridStatConfig_POP_12 +++ b/met/scripts/config/GridStatConfig_POP_12 @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/met/scripts/config/GridStatConfig_all b/met/scripts/config/GridStatConfig_all index 1050ab5920..9360adca0a 100644 --- a/met/scripts/config/GridStatConfig_all +++ b/met/scripts/config/GridStatConfig_all @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/met/scripts/config/PointStatConfig b/met/scripts/config/PointStatConfig index fe007f5f9e..159e9ae1b8 100644 --- a/met/scripts/config/PointStatConfig +++ b/met/scripts/config/PointStatConfig @@ -33,6 +33,8 @@ regrid = { censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index e63a6935f0..bc82d55625 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -380,7 +380,7 @@ struct MaskLatLon { // enum DuplicateType { - DuplicateType_None, // Apply no logic for duplicate point obs + DuplicateType_None, // Apply no logic for duplicate point obs DuplicateType_Unique // Filter out duplicate observation values }; @@ -394,7 +394,7 @@ enum ObsSummary { ObsSummary_None, // Keep all observations, no statistics ObsSummary_Nearest, // Keep only the observation closest in time ObsSummary_Min, // Keep only smallest value - ObsSummary_Max, // Keep only largest valueXS + ObsSummary_Max, // Keep only largest value ObsSummary_UW_Mean, // Calculate un-weighted mean ObsSummary_DW_Mean, // Calculate time weighted mean ObsSummary_Median, // Calculate median @@ -536,6 +536,8 @@ static const char conf_key_obs_qty[] = "obs_quality"; static const char conf_key_convert[] = "convert"; static const char conf_key_censor_thresh[] = "censor_thresh"; static const char conf_key_censor_val[] = "censor_val"; +static const char conf_key_mpr_column[] = "mpr_column"; +static const char conf_key_mpr_thresh[] = "mpr_thresh"; static const char conf_key_cnt_thresh[] = "cnt_thresh"; static const char conf_key_cnt_logic[] = "cnt_logic"; static const char conf_key_cat_thresh[] = "cat_thresh"; diff --git a/met/src/basic/vx_config/config_util.cc b/met/src/basic/vx_config/config_util.cc index 349eb06081..6eb13ef7a5 100644 --- a/met/src/basic/vx_config/config_util.cc +++ b/met/src/basic/vx_config/config_util.cc @@ -2285,46 +2285,6 @@ void check_mctc_thresh(const ThreshArray &ta) { /////////////////////////////////////////////////////////////////////////////// -bool check_fo_thresh(const double f, const double o, - const double cmn, const double csd, - const SingleThresh &ft, const SingleThresh &ot, - const SetLogic type) { - bool status = true; - bool fcheck = ft.check(f, cmn, csd); - bool ocheck = ot.check(o, cmn, csd); - SetLogic t = type; - - // If either of the thresholds is NA, reset the logic to intersection - // because an NA threshold is always true. - if(ft.get_type() == thresh_na || ot.get_type() == thresh_na) { - t = SetLogic_Intersection; - } - - switch(t) { - case(SetLogic_Union): - if(!fcheck && !ocheck) status = false; - break; - - case(SetLogic_Intersection): - if(!fcheck || !ocheck) status = false; - break; - - case(SetLogic_SymDiff): - if(fcheck == ocheck) status = false; - break; - - default: - mlog << Error << "\ncheck_fo_thresh() -> " - << "Unexpected SetLogic value of " << type << ".\n\n"; - exit(1); - break; - } - - return(status); -} - -/////////////////////////////////////////////////////////////////////////////// - const char * statlinetype_to_string(const STATLineType t) { const char *s = (const char *) 0; diff --git a/met/src/basic/vx_config/config_util.h b/met/src/basic/vx_config/config_util.h index d09a154c4c..ced39afb2d 100644 --- a/met/src/basic/vx_config/config_util.h +++ b/met/src/basic/vx_config/config_util.h @@ -80,10 +80,6 @@ extern void check_climo_n_vx(Dictionary *dict, const int); extern InterpMthd int_to_interpmthd(int); extern void check_mctc_thresh(const ThreshArray &); -extern bool check_fo_thresh(const double, const double, const double, const double, - const SingleThresh &, const SingleThresh &, - const SetLogic); - extern const char * statlinetype_to_string(const STATLineType); extern void statlinetype_to_string(const STATLineType, char *); extern STATLineType string_to_statlinetype(const char *); diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index e4074a79a6..27904462d1 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -1207,7 +1207,7 @@ void SL1L2Info::set(const PairDataPoint &pd_all) { zero_out(); // Apply continuous filtering thresholds to subset pairs - pd = subset_pairs(pd_all, fthresh, othresh, logic); + pd = pd_all.subset_pairs_cnt_thresh(fthresh, othresh, logic); // Check for no matched pairs to process if(pd.n_obs == 0) return; diff --git a/met/src/libcode/vx_statistics/pair_base.h b/met/src/libcode/vx_statistics/pair_base.h index 0c1bec3bd0..db7b63297f 100644 --- a/met/src/libcode/vx_statistics/pair_base.h +++ b/met/src/libcode/vx_statistics/pair_base.h @@ -71,6 +71,8 @@ class PairBase { MaskLatLon *mask_llpnt_ptr; // Pointer to Lat/Lon thresholds // which is not allocated + ////////////////////////////////////////////////////////////////// + ConcatString msg_typ; // Name of the verifying message type StringArray msg_typ_vals; // Message type values to be included diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index bc27df220c..5f21f17fe9 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -758,7 +758,7 @@ void PairDataEnsemble::compute_ssvar() { // //////////////////////////////////////////////////////////////////////// -PairDataEnsemble PairDataEnsemble::subset_pairs(const SingleThresh &ot) const { +PairDataEnsemble PairDataEnsemble::subset_pairs_obs_thresh(const SingleThresh &ot) const { // Check for no work to be done if(ot.get_type() == thresh_na) return(*this); diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index 5bfd4d4300..3d71af984b 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -142,7 +142,7 @@ class PairDataEnsemble : public PairBase { void compute_phist(); void compute_ssvar(); - PairDataEnsemble subset_pairs(const SingleThresh &ot) const; + PairDataEnsemble subset_pairs_obs_thresh(const SingleThresh &ot) const; }; //////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_statistics/pair_data_point.cc b/met/src/libcode/vx_statistics/pair_data_point.cc index d728b242cb..0ca19804dd 100644 --- a/met/src/libcode/vx_statistics/pair_data_point.cc +++ b/met/src/libcode/vx_statistics/pair_data_point.cc @@ -174,8 +174,7 @@ void PairDataPoint::set_point_pair(int i_obs, const char *sid, if(i_obs < 0 || i_obs >= n_obs) { mlog << Error << "\nPairDataPoint::set_point_pair() -> " << "range check error: " << i_obs << " not in (0, " - << n_obs << ").\n\n" - ; + << n_obs << ").\n\n"; exit(1); } @@ -232,6 +231,67 @@ bool PairDataPoint::add_grid_pair(const NumArray &f_in, const NumArray &o_in, return(true); } +//////////////////////////////////////////////////////////////////////// + +PairDataPoint PairDataPoint::subset_pairs_cnt_thresh( + const SingleThresh &ft, const SingleThresh &ot, + const SetLogic type) const { + + // Check for no work to be done + if(ft.get_type() == thresh_na && ot.get_type() == thresh_na) { + return(*this); + } + + int i; + PairDataPoint out_pd; + + // Allocate memory for output pairs + out_pd.extend(n_obs); + out_pd.set_climo_cdf_info(cdf_info); + + bool cmn_flag = set_climo_flag(f_na, cmn_na); + bool csd_flag = set_climo_flag(f_na, csd_na); + bool wgt_flag = set_climo_flag(f_na, wgt_na); + + // Loop over the pairs + for(i=0; i " + << "the \"" << conf_key_mpr_column << "\" (" + << write_css(sa) << ") and \"" << conf_key_mpr_thresh + << "\" (" << write_css(ta) + << ") config file entries must have the same length!\n\n"; + exit(1); + } + + mpr_column = sa; + mpr_thresh = ta; + + return; +} + +//////////////////////////////////////////////////////////////////////// + void VxPairDataPoint::set_climo_cdf_info(const ClimoCDFInfo &info) { for(int i=0; imagic_str() << " versus " + << obs_info->magic_str() + << ", skipping observation due to matched pair filter since " + << reason_cs << ":\n" + << point_obs_to_string(hdr_arr, hdr_typ_str, hdr_sid_str, + hdr_ut, obs_qty, obs_arr, var_name) + << "\n"; + inc_count(rej_mpr, i, j, k); + continue; + } + // Compute weight for current point wgt_v = (wgt_dp == (DataPlane *) 0 ? default_grid_weight : wgt_dp->get(x, y)); @@ -1336,64 +1445,199 @@ void VxPairDataPoint::inc_count(int ***&rej, int i, int j, int k) { // //////////////////////////////////////////////////////////////////////// -PairDataPoint subset_pairs(const PairDataPoint &pd, - const SingleThresh &ft, const SingleThresh &ot, - const SetLogic type) { +bool check_fo_thresh(double f, double o, double cmn, double csd, + const SingleThresh &ft, const SingleThresh &ot, + const SetLogic type) { + bool status = true; + bool fcheck = ft.check(f, cmn, csd); + bool ocheck = ot.check(o, cmn, csd); + SetLogic t = type; - // Check for no work to be done - if(ft.get_type() == thresh_na && ot.get_type() == thresh_na) { - return(pd); + // If either of the thresholds is NA, reset the logic to intersection + // because an NA threshold is always true. + if(ft.get_type() == thresh_na || ot.get_type() == thresh_na) { + t = SetLogic_Intersection; } - int i; - PairDataPoint out_pd; + switch(t) { + case(SetLogic_Union): + if(!fcheck && !ocheck) status = false; + break; - // Allocate memory for output pairs - out_pd.extend(pd.n_obs); - out_pd.set_climo_cdf_info(pd.cdf_info); + case(SetLogic_Intersection): + if(!fcheck || !ocheck) status = false; + break; - bool cmn_flag = set_climo_flag(pd.f_na, pd.cmn_na); - bool csd_flag = set_climo_flag(pd.f_na, pd.csd_na); - bool wgt_flag = set_climo_flag(pd.f_na, pd.wgt_na); + case(SetLogic_SymDiff): + if(fcheck == ocheck) status = false; + break; - // Loop over the pairs - for(i=0; i " + << "Unexpected SetLogic value of " << type << ".\n\n"; + exit(1); + break; + } - // Check for bad data - if(is_bad_data(pd.f_na[i]) || - is_bad_data(pd.o_na[i]) || - (cmn_flag && is_bad_data(pd.cmn_na[i])) || - (csd_flag && is_bad_data(pd.csd_na[i])) || - (wgt_flag && is_bad_data(pd.wgt_na[i]))) continue; + return(status); +} - // Keep pairs which meet the threshold criteria - if(check_fo_thresh(pd.f_na[i], pd.o_na[i], - pd.cmn_na[i], pd.csd_na[i], - ft, ot, type)) { +//////////////////////////////////////////////////////////////////////// - // Handle point data - if(pd.is_point_vx()) { - out_pd.add_point_pair(pd.sid_sa[i].c_str(), pd.lat_na[i], - pd.lon_na[i], pd.x_na[i], pd.y_na[i], - pd.vld_ta[i], pd.lvl_na[i], pd.elv_na[i], - pd.f_na[i], pd.o_na[i], pd.o_qc_sa[i].c_str(), - pd.cmn_na[i], pd.csd_na[i], pd.wgt_na[i]); - } - // Handle gridded data - else { - out_pd.add_grid_pair(pd.f_na[i], pd.o_na[i], pd.cmn_na[i], - pd.csd_na[i], pd.wgt_na[i]); +bool check_mpr_thresh(double f, double o, double cmn, double csd, + const StringArray &col_sa, const ThreshArray &col_ta, + ConcatString *reason_ptr) { + // Initialize + if(reason_ptr) reason_ptr->erase(); + + // Check arrays + if(col_sa.n() == 0 || col_ta.n() == 0) return(true); + + bool keep = true; + bool absv = false; + StringArray sa; + ConcatString cs; + double v, v_cur; + int i, j; + + // Loop over all the column filter names + for(i=0; i 1) { + + // Loop through the columns + for(j=1; j " + << "unsupported matched pair column name requested in \"" + << conf_key_mpr_column << "\" (" << s << ")!\n\n"; + exit(1); + } + + return(v); +} + +//////////////////////////////////////////////////////////////////////// + +void apply_mpr_thresh_mask(DataPlane &fcst_dp, DataPlane &obs_dp, + DataPlane &cmn_dp, DataPlane &csd_dp, + const StringArray &col_sa, const ThreshArray &col_ta) { + + // Check for no work to be done + if(col_sa.n() == 0 && col_ta.n() == 0) return; + + // Check for constant length + if(col_sa.n() != col_ta.n()) { + mlog << Error << "\napply_mpr_thresh_mask() -> " + << "the \"" << conf_key_mpr_column << "\" (" + << write_css(col_sa) << ") and \"" << conf_key_mpr_thresh + << "\" (" << write_css(col_ta) + << ") config file entries must have the same length!\n\n"; + exit(1); + } + + int nxy = fcst_dp.nx() * fcst_dp.ny(); + int n_skip = 0; + bool cmn_flag = !(cmn_dp.is_empty()); + bool csd_flag = !(csd_dp.is_empty()); + + // Loop over the pairs + for(int i=0; isubset_pairs(conf_info.vx_opt[i].othr_ta[m]); + pd = pd_ptr->subset_pairs_obs_thresh(conf_info.vx_opt[i].othr_ta[m]); // Continue if there are no points if(pd.n_obs == 0) continue; @@ -1779,7 +1779,7 @@ void process_grid_vx() { shc.set_obs_thresh(conf_info.vx_opt[i].othr_ta[l]); // Subset pairs using the current obs_thresh - pd = pd_all.subset_pairs(conf_info.vx_opt[i].othr_ta[l]); + pd = pd_all.subset_pairs_obs_thresh(conf_info.vx_opt[i].othr_ta[l]); // Continue if there are no points if(pd.n_obs == 0) continue; diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 14b09c6d5a..cf30bd282f 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -106,6 +106,8 @@ // continuous and probabilistic statistics. // 050 03/02/20 Halley Gotway Add nc_pairs_var_name and rename // nc_pairs_var_str to nc_pairs_var_suffix. +// 051 03/28/21 Halley Gotway Add mpr_column and mpr_thresh +// filtering options. // //////////////////////////////////////////////////////////////////////// @@ -711,6 +713,13 @@ void process_scores() { << " climatology standard deviation field(s) for forecast " << conf_info.vx_opt[i].fcst_info->magic_str() << ".\n"; + // Apply MPR threshold filters + if(conf_info.vx_opt[i].mpr_sa.n() > 0) { + apply_mpr_thresh_mask(fcst_dp, obs_dp, cmn_dp, csd_dp, + conf_info.vx_opt[i].mpr_sa, + conf_info.vx_opt[i].mpr_ta); + } + // Setup the first pass through the data if(is_first_pass) setup_first_pass(fcst_dp); @@ -1961,8 +1970,9 @@ void do_cnt_sl1l2(const GridStatVxOpt &vx_opt, const PairDataPoint *pd_ptr) { for(i=0; isubset_pairs_cnt_thresh(vx_opt.fcnt_ta[i], + vx_opt.ocnt_ta[i], + vx_opt.cnt_logic); // Check for no matched pairs to process if(pd_thr.n_obs == 0) continue; 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 a5702ca06f..8b2b572eca 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 @@ -275,7 +275,7 @@ void GridStatConfInfo::process_flags() { // Check for at least one output data type if(!output_ascii_flag && !output_nc_flag) { - mlog << Error << "\nGridStatVxOpt::process_config() -> " + mlog << Error << "\nGridStatConfInfo::process_flags() -> " << "At least one output STAT or NetCDF type must be " << " requested in \"" << conf_key_output_flag << "\" or \"" << conf_key_nc_pairs_flag << "\".\n\n"; @@ -495,6 +495,9 @@ void GridStatVxOpt::clear() { var_name.clear(); var_suffix.clear(); + mpr_sa.clear(); + mpr_ta.clear(); + fcat_ta.clear(); ocat_ta.clear(); @@ -614,6 +617,10 @@ void GridStatVxOpt::process_config( // Populate the output_flag array with map values for(i=0; i= 5) { mlog << Debug(5) << "Parsed thresholds:\n" + << "Matched pair filter columns: " << write_css(mpr_sa) << "\n" + << "Matched pair filter thresholds: " << mpr_ta.get_str() << "\n" << "Forecast categorical thresholds: " << fcat_ta.get_str() << "\n" << "Observed categorical thresholds: " << ocat_ta.get_str() << "\n" << "Forecast continuous thresholds: " << fcnt_ta.get_str() << "\n" @@ -875,6 +884,7 @@ bool GridStatVxOpt::is_uv_match(const GridStatVxOpt &v) const { // // The following do not impact matched pairs: // desc, var_name, var_suffix, + // mpr_sa, mpr_ta, // fcat_ta, ocat_ta, // fcnt_ta, ocnt_ta, cnt_logic, // fwind_ta, owind_ta, wind_logic, 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 3b92c5be06..e03b657488 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 @@ -145,6 +145,9 @@ class GridStatVxOpt { ConcatString var_suffix; // nc_pairs_var_suffix string // nc_pairs_var_str is deprecated + StringArray mpr_sa; // MPR filtering columns + ThreshArray mpr_ta; // MPR filtering thresholds + ThreshArray fcat_ta; // fcst categorical thresholds ThreshArray ocat_ta; // obs categorical thresholds diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index d1edfdb935..ba28097e6a 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -92,6 +92,8 @@ // 043 11/15/19 Halley Gotway Apply climatology bins to // continuous and probabilistic statistics. // 044 01/24/20 Halley Gotway Add HiRA RPS output. +// 045 03/28/21 Halley Gotway Add mpr_column and mpr_thresh +// filtering options. // //////////////////////////////////////////////////////////////////////// @@ -1016,6 +1018,7 @@ void process_scores() { << "Rejected: bad fcst value = " << conf_info.vx_opt[i].vx_pd.rej_fcst[j][k][l] << "\n" << "Rejected: bad climo mean = " << conf_info.vx_opt[i].vx_pd.rej_cmn[j][k][l] << "\n" << "Rejected: bad climo stdev = " << conf_info.vx_opt[i].vx_pd.rej_csd[j][k][l] << "\n" + << "Rejected: mpr filter = " << conf_info.vx_opt[i].vx_pd.rej_mpr[j][k][l] << "\n" << "Rejected: duplicates = " << conf_info.vx_opt[i].vx_pd.rej_dup[j][k][l] << "\n"; // Print report based on the number of matched pairs @@ -1421,8 +1424,9 @@ void do_cnt_sl1l2(const PointStatVxOpt &vx_opt, const PairDataPoint *pd_ptr) { for(i=0; isubset_pairs_cnt_thresh(vx_opt.fcnt_ta[i], + vx_opt.ocnt_ta[i], + vx_opt.cnt_logic); // Check for no matched pairs to process if(pd_thr.n_obs == 0) continue; 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 ecd6b8b3dc..5a039e1bae 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 @@ -606,6 +606,9 @@ void PointStatVxOpt::clear() { mask_sid.clear(); mask_llpnt.clear(); + mpr_sa.clear(); + mpr_ta.clear(); + mask_name.clear(); eclv_points.clear(); @@ -774,10 +777,16 @@ void PointStatVxOpt::process_config(GrdFileType ftype, int_to_setlogic(fdict.lookup_int(conf_key_wind_logic)), int_to_setlogic(odict.lookup_int(conf_key_wind_logic))); + // Conf: mpr_column and mpr_thresh + mpr_sa = odict.lookup_string_array(conf_key_mpr_column); + mpr_ta = odict.lookup_thresh_array(conf_key_mpr_thresh); + // Dump the contents of the current thresholds if(mlog.verbosity_level() >= 5) { mlog << Debug(5) << "Parsed thresholds:\n" + << "Matched pair filter columns: " << write_css(mpr_sa) << "\n" + << "Matched pair filter thresholds: " << mpr_ta.get_str() << "\n" << "Forecast categorical thresholds: " << fcat_ta.get_str() << "\n" << "Observed categorical thresholds: " << ocat_ta.get_str() << "\n" << "Forecast continuous thresholds: " << fcnt_ta.get_str() << "\n" @@ -932,6 +941,9 @@ void PointStatVxOpt::set_vx_pd(PointStatConfInfo *conf_info) { // Define the dimensions vx_pd.set_pd_size(n_msg_typ, n_mask, n_interp); + // Store the MPR filter threshold + vx_pd.set_mpr_thresh(mpr_sa, mpr_ta); + // Store the climo CDF info vx_pd.set_climo_cdf_info(cdf_info); 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 d849dcc113..dd1d787dfa 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 @@ -123,6 +123,9 @@ class PointStatVxOpt { StringArray mask_poly; // Masking polyline strings StringArray mask_sid; // Masking station ID's + StringArray mpr_sa; // MPR column names + ThreshArray mpr_ta; // MPR column thresholds + // Vector of MaskLatLon objects defining Lat/Lon Point masks vector mask_llpnt; diff --git a/met/src/tools/core/series_analysis/series_analysis.cc b/met/src/tools/core/series_analysis/series_analysis.cc index 5a17f62ff7..acc347aff0 100644 --- a/met/src/tools/core/series_analysis/series_analysis.cc +++ b/met/src/tools/core/series_analysis/series_analysis.cc @@ -1008,8 +1008,8 @@ void do_cnt(int n, const PairDataPoint *pd_ptr) { } // Apply continuous filtering thresholds to subset pairs - pd = subset_pairs(*pd_ptr, cnt_info.fthresh, cnt_info.othresh, - cnt_info.logic); + pd = pd_ptr->subset_pairs_cnt_thresh(cnt_info.fthresh, cnt_info.othresh, + cnt_info.logic); // Check for no matched pairs to process if(pd.n_obs == 0) continue; diff --git a/test/config/GridStatConfig_APCP_regrid b/test/config/GridStatConfig_APCP_regrid index 445ff414e9..7696febce9 100644 --- a/test/config/GridStatConfig_APCP_regrid +++ b/test/config/GridStatConfig_APCP_regrid @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_GRIB_lvl_typ_val b/test/config/GridStatConfig_GRIB_lvl_typ_val index ceadb05264..5e0f64d6a7 100644 --- a/test/config/GridStatConfig_GRIB_lvl_typ_val +++ b/test/config/GridStatConfig_GRIB_lvl_typ_val @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_GRIB_set_attr b/test/config/GridStatConfig_GRIB_set_attr index 88703198c1..d1d5dbc30d 100644 --- a/test/config/GridStatConfig_GRIB_set_attr +++ b/test/config/GridStatConfig_GRIB_set_attr @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_GTG_latlon b/test/config/GridStatConfig_GTG_latlon index 86419f863c..648863688e 100644 --- a/test/config/GridStatConfig_GTG_latlon +++ b/test/config/GridStatConfig_GTG_latlon @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_GTG_lc b/test/config/GridStatConfig_GTG_lc index 290756e91e..846f5a2e6e 100644 --- a/test/config/GridStatConfig_GTG_lc +++ b/test/config/GridStatConfig_GTG_lc @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_apply_mask b/test/config/GridStatConfig_apply_mask index fef335f064..1bb34bb9f1 100644 --- a/test/config/GridStatConfig_apply_mask +++ b/test/config/GridStatConfig_apply_mask @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_climo_WMO b/test/config/GridStatConfig_climo_WMO index 6974d71937..a9f4c120cf 100644 --- a/test/config/GridStatConfig_climo_WMO +++ b/test/config/GridStatConfig_climo_WMO @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_climo_prob b/test/config/GridStatConfig_climo_prob index 4d652daa12..7b91e8da0f 100644 --- a/test/config/GridStatConfig_climo_prob +++ b/test/config/GridStatConfig_climo_prob @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_fourier b/test/config/GridStatConfig_fourier index e978c99f8c..a441acd51f 100644 --- a/test/config/GridStatConfig_fourier +++ b/test/config/GridStatConfig_fourier @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_grid_weight b/test/config/GridStatConfig_grid_weight index c5cf23cef6..5ea4b6df87 100644 --- a/test/config/GridStatConfig_grid_weight +++ b/test/config/GridStatConfig_grid_weight @@ -41,6 +41,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_interp_shape b/test/config/GridStatConfig_interp_shape index cc212d77f8..af303ec165 100644 --- a/test/config/GridStatConfig_interp_shape +++ b/test/config/GridStatConfig_interp_shape @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_mpr_thresh b/test/config/GridStatConfig_mpr_thresh new file mode 100644 index 0000000000..bd28d883f2 --- /dev/null +++ b/test/config/GridStatConfig_mpr_thresh @@ -0,0 +1,274 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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 = "GFSANL"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// 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 = ""; +rank_corr_flag = FALSE; + +// +// Forecast and observation fields to be verified +// +fcst = { + + name = "TMP"; + level = "Z2"; + + field = [ + { + desc = "NO_MPR_THRESH"; + nc_pairs_var_suffix = desc; + }, + { + mpr_column = [ "OBS-FCST" ]; + mpr_thresh = [ >=-5&&<=5 ]; + desc = "OBS_FCST_DIFF"; + nc_pairs_var_suffix = desc; + }, + { + mpr_column = [ "ABS(OBS-FCST)" ]; + mpr_thresh = [ <=5 ]; + desc = "ABS_OBS_FCST_DIFF"; + nc_pairs_var_suffix = desc; + }, + { + mpr_column = [ "ABS(OBS-CLIMO_MEAN)" ]; + mpr_thresh = [ <=5 ]; + desc = "ABS_OBS_CLIMO_MEAN_DIFF"; + nc_pairs_var_suffix = desc; + }, + { + mpr_column = [ "CLIMO_CDF" ]; + mpr_thresh = [ >=0.25&&<=0.75 ]; + desc = "CLIMO_CDF_IQR"; + nc_pairs_var_suffix = desc; + } + ]; +} +obs = fcst; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology mean data +// +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 = ${DAY_INTERVAL}; + hour_interval = ${HOUR_INTERVAL}; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = [ ${CLIMO_STDEV_FILE_LIST} ]; +} + +// +// May be set separately in each "obs.field" entry +// +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + write_bins = TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// 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 = ""; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Data smoothing methods +// +interp = { + field = BOTH; + vld_thresh = 1.0; + shape = SQUARE; + + type = [ + { + method = NEAREST; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Neighborhood methods +// +nbrhd = { + width = [ 1 ]; + 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; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Statistical output types +// +output_flag = { + fho = NONE; + ctc = NONE; + cts = NONE; + mctc = NONE; + mcts = NONE; + cnt = NONE; + sl1l2 = STAT; + 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 = { + latlon = FALSE; + raw = FALSE; + diff = TRUE; + climo = FALSE; + climo_cdp = FALSE; + weight = FALSE; + nbrhd = FALSE; + fourier = FALSE; + gradient = FALSE; + distance_map = FALSE; + apply_mask = FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// + +grid_weight_flag = COS_LAT; +tmp_dir = "/tmp"; +output_prefix = "${OUTPUT_PREFIX}"; +version = "V10.0.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_no_leap b/test/config/GridStatConfig_no_leap index e415640c07..47ab1f474b 100644 --- a/test/config/GridStatConfig_no_leap +++ b/test/config/GridStatConfig_no_leap @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_prob_as_scalar b/test/config/GridStatConfig_prob_as_scalar index 2c63950004..13c6143438 100644 --- a/test/config/GridStatConfig_prob_as_scalar +++ b/test/config/GridStatConfig_prob_as_scalar @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_python b/test/config/GridStatConfig_python index 85dd871c5e..0d5e908266 100644 --- a/test/config/GridStatConfig_python +++ b/test/config/GridStatConfig_python @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_python_mixed b/test/config/GridStatConfig_python_mixed index 367c0e1118..b3a6c2ea2b 100644 --- a/test/config/GridStatConfig_python_mixed +++ b/test/config/GridStatConfig_python_mixed @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_rtma b/test/config/GridStatConfig_rtma index 4d88b8e6c7..77d491e5b5 100644 --- a/test/config/GridStatConfig_rtma +++ b/test/config/GridStatConfig_rtma @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_rtma_perc_thresh b/test/config/GridStatConfig_rtma_perc_thresh index 0f96a179f4..cabb9c13df 100644 --- a/test/config/GridStatConfig_rtma_perc_thresh +++ b/test/config/GridStatConfig_rtma_perc_thresh @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_st4 b/test/config/GridStatConfig_st4 index abb1c4079f..7ad113c13f 100644 --- a/test/config/GridStatConfig_st4 +++ b/test/config/GridStatConfig_st4 @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/GridStatConfig_st4_censor b/test/config/GridStatConfig_st4_censor index fd9debdcdf..8f088b7a6d 100644 --- a/test/config/GridStatConfig_st4_censor +++ b/test/config/GridStatConfig_st4_censor @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/PointStatConfig_APCP b/test/config/PointStatConfig_APCP index 3923198689..920034bc27 100644 --- a/test/config/PointStatConfig_APCP +++ b/test/config/PointStatConfig_APCP @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_APCP_HIRA b/test/config/PointStatConfig_APCP_HIRA index 4941473a82..e39d21863c 100644 --- a/test/config/PointStatConfig_APCP_HIRA +++ b/test/config/PointStatConfig_APCP_HIRA @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_GTG_latlon b/test/config/PointStatConfig_GTG_latlon index 4a33c23102..fc5fa1eef9 100644 --- a/test/config/PointStatConfig_GTG_latlon +++ b/test/config/PointStatConfig_GTG_latlon @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_GTG_lc b/test/config/PointStatConfig_GTG_lc index 0a08acdf19..e1c5f89ab2 100644 --- a/test/config/PointStatConfig_GTG_lc +++ b/test/config/PointStatConfig_GTG_lc @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_INTERP_OPTS b/test/config/PointStatConfig_INTERP_OPTS index 902138d916..1538ce4bf9 100644 --- a/test/config/PointStatConfig_INTERP_OPTS +++ b/test/config/PointStatConfig_INTERP_OPTS @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_LAND_TOPO_MASK b/test/config/PointStatConfig_LAND_TOPO_MASK index a98c163ff1..9d9e77564e 100644 --- a/test/config/PointStatConfig_LAND_TOPO_MASK +++ b/test/config/PointStatConfig_LAND_TOPO_MASK @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_MASK_SID b/test/config/PointStatConfig_MASK_SID index 6333358fac..b9afca5389 100644 --- a/test/config/PointStatConfig_MASK_SID +++ b/test/config/PointStatConfig_MASK_SID @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_PHYS b/test/config/PointStatConfig_PHYS index 03a67ca8b4..aea79c4b19 100644 --- a/test/config/PointStatConfig_PHYS +++ b/test/config/PointStatConfig_PHYS @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_PHYS_pint b/test/config/PointStatConfig_PHYS_pint index 951d936320..be5abaaf6f 100644 --- a/test/config/PointStatConfig_PHYS_pint +++ b/test/config/PointStatConfig_PHYS_pint @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_WINDS b/test/config/PointStatConfig_WINDS index 66257da5fa..3dc709d48c 100644 --- a/test/config/PointStatConfig_WINDS +++ b/test/config/PointStatConfig_WINDS @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_aeronet b/test/config/PointStatConfig_aeronet index 7423d57bba..a1405e9424 100644 --- a/test/config/PointStatConfig_aeronet +++ b/test/config/PointStatConfig_aeronet @@ -31,6 +31,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cat_thresh = [ NA ]; cnt_thresh = [ NA ]; //cnt_logic = UNION; diff --git a/test/config/PointStatConfig_airnow b/test/config/PointStatConfig_airnow index 89a1b22252..eb18e2000f 100644 --- a/test/config/PointStatConfig_airnow +++ b/test/config/PointStatConfig_airnow @@ -38,6 +38,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = [ NA ]; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/PointStatConfig_climo b/test/config/PointStatConfig_climo index 843c927614..17005f9979 100644 --- a/test/config/PointStatConfig_climo +++ b/test/config/PointStatConfig_climo @@ -31,6 +31,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cat_thresh = [ NA ]; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/PointStatConfig_climo_WMO b/test/config/PointStatConfig_climo_WMO index fe2eedd6e9..722edd4881 100644 --- a/test/config/PointStatConfig_climo_WMO +++ b/test/config/PointStatConfig_climo_WMO @@ -31,6 +31,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/PointStatConfig_climo_prob b/test/config/PointStatConfig_climo_prob index 2d59e5712b..53a754b87c 100644 --- a/test/config/PointStatConfig_climo_prob +++ b/test/config/PointStatConfig_climo_prob @@ -32,6 +32,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cat_thresh = [ NA ]; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/PointStatConfig_dup b/test/config/PointStatConfig_dup index 9f0c2992ad..e67fb84089 100644 --- a/test/config/PointStatConfig_dup +++ b/test/config/PointStatConfig_dup @@ -30,6 +30,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_mpr_thresh b/test/config/PointStatConfig_mpr_thresh new file mode 100644 index 0000000000..6a33eebf2a --- /dev/null +++ b/test/config/PointStatConfig_mpr_thresh @@ -0,0 +1,221 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Point-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"; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Verification grid +// +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; + vld_thresh = 0.5; +} + +//////////////////////////////////////////////////////////////////////////////// + +mpr_column = []; +mpr_thresh = []; +cat_thresh = [ NA ]; +cnt_thresh = [ NA ]; +cnt_logic = UNION; +wind_thresh = [ NA ]; +wind_logic = UNION; +eclv_points = 0.05; + +// +// Forecast and observation fields to be verified +// +fcst = { + sid_inc = []; + sid_exc = []; + cat_thresh = []; + message_type = [ "ADPSFC" ]; + + name = "TMP"; + level = "Z2"; + + field = [ + { + desc = "NO_MPR_THRESH"; + }, + { + mpr_column = [ "OBS-FCST" ]; + mpr_thresh = [ >=-5&&<=5 ]; + desc = "OBS_FCST_DIFF"; + }, + { + mpr_column = [ "ABS(OBS-FCST)" ]; + mpr_thresh = [ <=5 ]; + desc = "ABS_OBS_FCST_DIFF"; + }, + { + mpr_column = [ "ABS(OBS-CLIMO_MEAN)" ]; + mpr_thresh = [ <=5 ]; + desc = "ABS_OBS_CLIMO_MEAN_DIFF"; + }, + { + mpr_column = [ "CLIMO_CDF" ]; + mpr_thresh = [ >=0.25&&<=0.75 ]; + desc = "CLIMO_CDF_IQR"; + } + ]; +} +obs = fcst; + +//////////////////////////////////////////////////////////////////////////////// + +// +// Climatology mean data +// +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 = ${DAY_INTERVAL}; + hour_interval = ${HOUR_INTERVAL}; +} + +climo_stdev = climo_mean; +climo_stdev = { + file_name = [ ${CLIMO_STDEV_FILE_LIST} ]; +} + +// +// May be set separately in each "obs.field" entry +// +climo_cdf = { + cdf_bins = 1; + center_bins = FALSE; + write_bins = TRUE; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// 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 ]; + +boot = { + interval = PCTILE; + rep_prop = 1.0; + n_rep = 1000; + rng = "mt19937"; + seed = "1"; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Interpolation methods +// +interp = { + vld_thresh = 1.0; + + type = [ + { + method = NEAREST; + width = 1; + } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// HiRA verification method +// +hira = { + flag = FALSE; + width = [ 2, 3, 4, 5 ]; + vld_thresh = 1.0; + cov_thresh = [ ==0.25 ]; + shape = SQUARE; + prob_cat_thresh = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +// +// Statistical output types +// +output_flag = { + fho = NONE; + ctc = NONE; + cts = NONE; + mctc = NONE; + mcts = NONE; + cnt = NONE; + sl1l2 = STAT; + sal1l2 = NONE; + vl1l2 = NONE; + val1l2 = NONE; + vcnt = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + ecnt = NONE; + rps = NONE; + eclv = NONE; + mpr = NONE; +} + +//////////////////////////////////////////////////////////////////////////////// + +obs_quality = []; +duplicate_flag = NONE; +rank_corr_flag = TRUE; +tmp_dir = "/tmp"; +output_prefix = "${OUTPUT_PREFIX}"; +version = "V10.0.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/PointStatConfig_obs_summary b/test/config/PointStatConfig_obs_summary index 1bce341f5e..03b00e3438 100644 --- a/test/config/PointStatConfig_obs_summary +++ b/test/config/PointStatConfig_obs_summary @@ -30,6 +30,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_obs_summary_all b/test/config/PointStatConfig_obs_summary_all index 4bbe7821b3..329a3bd05f 100644 --- a/test/config/PointStatConfig_obs_summary_all +++ b/test/config/PointStatConfig_obs_summary_all @@ -30,6 +30,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_prob b/test/config/PointStatConfig_prob index 3c26b54ec0..c1d7f8d58f 100644 --- a/test/config/PointStatConfig_prob +++ b/test/config/PointStatConfig_prob @@ -31,6 +31,8 @@ obs_window = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/PointStatConfig_python b/test/config/PointStatConfig_python index e975b01b9e..2b073fff61 100644 --- a/test/config/PointStatConfig_python +++ b/test/config/PointStatConfig_python @@ -37,6 +37,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = [ NA ]; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/PointStatConfig_sid_inc_exc b/test/config/PointStatConfig_sid_inc_exc index a7766ff324..70f17d7943 100644 --- a/test/config/PointStatConfig_sid_inc_exc +++ b/test/config/PointStatConfig_sid_inc_exc @@ -33,6 +33,8 @@ obs_window = { censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/ref_config/GridStatConfig_03h b/test/config/ref_config/GridStatConfig_03h index dc93b76496..ce8b0f982c 100644 --- a/test/config/ref_config/GridStatConfig_03h +++ b/test/config/ref_config/GridStatConfig_03h @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; diff --git a/test/config/ref_config/GridStatConfig_24h b/test/config/ref_config/GridStatConfig_24h index 260e1e901d..1f7fb01cda 100644 --- a/test/config/ref_config/GridStatConfig_24h +++ b/test/config/ref_config/GridStatConfig_24h @@ -42,6 +42,8 @@ regrid = { // censor_thresh = []; censor_val = []; +mpr_column = []; +mpr_thresh = []; cat_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; @@ -51,6 +53,7 @@ eclv_points = 0.05; nc_pairs_var_name = ""; nc_pairs_var_suffix = ""; rank_corr_flag = FALSE; + // // Forecast and observation fields to be verified // diff --git a/test/config/ref_config/PointStatConfig_ADPUPA b/test/config/ref_config/PointStatConfig_ADPUPA index 9976d42778..a458683711 100644 --- a/test/config/ref_config/PointStatConfig_ADPUPA +++ b/test/config/ref_config/PointStatConfig_ADPUPA @@ -30,6 +30,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_thresh = [ NA ]; diff --git a/test/config/ref_config/PointStatConfig_ONLYSF b/test/config/ref_config/PointStatConfig_ONLYSF index 8c969f69f0..9276f52a45 100644 --- a/test/config/ref_config/PointStatConfig_ONLYSF +++ b/test/config/ref_config/PointStatConfig_ONLYSF @@ -30,6 +30,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_logic = INTERSECTION; diff --git a/test/config/ref_config/PointStatConfig_WINDS b/test/config/ref_config/PointStatConfig_WINDS index 82ba02f5e4..5e18b2f1dc 100644 --- a/test/config/ref_config/PointStatConfig_WINDS +++ b/test/config/ref_config/PointStatConfig_WINDS @@ -30,6 +30,8 @@ regrid = { //////////////////////////////////////////////////////////////////////////////// +mpr_column = []; +mpr_thresh = []; cnt_thresh = [ NA ]; cnt_logic = UNION; wind_logic = INTERSECTION; diff --git a/test/xml/unit_grid_stat.xml b/test/xml/unit_grid_stat.xml index 729761c71d..1d562778f7 100644 --- a/test/xml/unit_grid_stat.xml +++ b/test/xml/unit_grid_stat.xml @@ -234,4 +234,31 @@ + + &MET_BIN;/grid_stat + + OUTPUT_PREFIX MPR_THRESH + 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;/grib2/gfs/gfs_2012040900_F012.grib2 \ + &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \ + &CONFIG_DIR;/GridStatConfig_mpr_thresh \ + -outdir &OUTPUT_DIR;/grid_stat -v 3 + + + &OUTPUT_DIR;/grid_stat/grid_stat_MPR_THRESH_120000L_20120409_120000V.stat + &OUTPUT_DIR;/grid_stat/grid_stat_MPR_THRESH_120000L_20120409_120000V_pairs.nc + + + diff --git a/test/xml/unit_point_stat.xml b/test/xml/unit_point_stat.xml index c369108a08..8750e1ee68 100644 --- a/test/xml/unit_point_stat.xml +++ b/test/xml/unit_point_stat.xml @@ -8,6 +8,7 @@ + ]> @@ -454,4 +455,30 @@ + + &MET_BIN;/point_stat + + OUTPUT_PREFIX MPR_THRESH + 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;/grib2/gfs/gfs_2012040900_F012.grib2 \ + &OUTPUT_DIR;/pb2nc/ndas.20120409.t12z.prepbufr.tm00.nc \ + &CONFIG_DIR;/PointStatConfig_mpr_thresh \ + -outdir &OUTPUT_DIR;/point_stat -v 3 + + + &OUTPUT_DIR;/point_stat/point_stat_MPR_THRESH_120000L_20120409_120000V.stat + + +