From e423644eb132b5e433bc107cbf49ec68367c60eb Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 8 Jul 2021 14:00:37 -0600 Subject: [PATCH 01/36] Per #1673, add a distance_map.beta_value entry to all the Grid-Stat config files. --- met/data/config/GridStatConfig_default | 1 + 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 ++ test/config/GridStatConfig_APCP_regrid | 1 + test/config/GridStatConfig_GRIB_lvl_typ_val | 1 + test/config/GridStatConfig_GRIB_set_attr | 1 + test/config/GridStatConfig_GTG_latlon | 1 + test/config/GridStatConfig_GTG_lc | 1 + test/config/GridStatConfig_apply_mask | 1 + test/config/GridStatConfig_climo_WMO | 1 + test/config/GridStatConfig_climo_prob | 1 + test/config/GridStatConfig_fourier | 1 + test/config/GridStatConfig_grid_weight | 1 + test/config/GridStatConfig_interp_shape | 1 + test/config/GridStatConfig_mpr_thresh | 1 + test/config/GridStatConfig_no_leap | 1 + test/config/GridStatConfig_prob_as_scalar | 1 + test/config/GridStatConfig_python | 1 + test/config/GridStatConfig_python_mixed | 1 + test/config/GridStatConfig_rtma | 1 + test/config/GridStatConfig_rtma_perc_thresh | 1 + test/config/GridStatConfig_st4 | 1 + test/config/GridStatConfig_st4_censor | 1 + test/config/ref_config/GridStatConfig_03h | 1 + test/config/ref_config/GridStatConfig_24h | 1 + 27 files changed, 31 insertions(+) diff --git a/met/data/config/GridStatConfig_default b/met/data/config/GridStatConfig_default index e79a3e42b1..94be3a175c 100644 --- a/met/data/config/GridStatConfig_default +++ b/met/data/config/GridStatConfig_default @@ -202,6 +202,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_APCP_12 b/met/scripts/config/GridStatConfig_APCP_12 index e63c3a3d23..ab6c7ad91f 100644 --- a/met/scripts/config/GridStatConfig_APCP_12 +++ b/met/scripts/config/GridStatConfig_APCP_12 @@ -158,6 +158,8 @@ distance_map = { baddeley_p = 2; baddeley_max_dist = NA; fom_alpha = 0.1; + zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_APCP_24 b/met/scripts/config/GridStatConfig_APCP_24 index 9ad9e8bb53..0d132582ef 100644 --- a/met/scripts/config/GridStatConfig_APCP_24 +++ b/met/scripts/config/GridStatConfig_APCP_24 @@ -168,6 +168,8 @@ distance_map = { baddeley_p = 2; baddeley_max_dist = NA; fom_alpha = 0.1; + zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_POP_12 b/met/scripts/config/GridStatConfig_POP_12 index 20c48f59a6..4407d5601b 100644 --- a/met/scripts/config/GridStatConfig_POP_12 +++ b/met/scripts/config/GridStatConfig_POP_12 @@ -168,6 +168,8 @@ distance_map = { baddeley_p = 2; baddeley_max_dist = NA; fom_alpha = 0.1; + zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_all b/met/scripts/config/GridStatConfig_all index 901ec29565..6d7c251520 100644 --- a/met/scripts/config/GridStatConfig_all +++ b/met/scripts/config/GridStatConfig_all @@ -199,6 +199,8 @@ distance_map = { baddeley_p = 2; baddeley_max_dist = NA; fom_alpha = 0.1; + zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_APCP_regrid b/test/config/GridStatConfig_APCP_regrid index dfcfbf73a7..df9e784d7c 100644 --- a/test/config/GridStatConfig_APCP_regrid +++ b/test/config/GridStatConfig_APCP_regrid @@ -150,6 +150,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GRIB_lvl_typ_val b/test/config/GridStatConfig_GRIB_lvl_typ_val index 1b3a539f57..e2303e06a4 100644 --- a/test/config/GridStatConfig_GRIB_lvl_typ_val +++ b/test/config/GridStatConfig_GRIB_lvl_typ_val @@ -247,6 +247,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GRIB_set_attr b/test/config/GridStatConfig_GRIB_set_attr index dae59b6282..cb7347ca46 100644 --- a/test/config/GridStatConfig_GRIB_set_attr +++ b/test/config/GridStatConfig_GRIB_set_attr @@ -179,6 +179,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GTG_latlon b/test/config/GridStatConfig_GTG_latlon index 0f18b04d2d..50538cc505 100644 --- a/test/config/GridStatConfig_GTG_latlon +++ b/test/config/GridStatConfig_GTG_latlon @@ -158,6 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GTG_lc b/test/config/GridStatConfig_GTG_lc index 531a3bb9cf..1ced0947af 100644 --- a/test/config/GridStatConfig_GTG_lc +++ b/test/config/GridStatConfig_GTG_lc @@ -158,6 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_apply_mask b/test/config/GridStatConfig_apply_mask index 1c62a9a929..f0baf81178 100644 --- a/test/config/GridStatConfig_apply_mask +++ b/test/config/GridStatConfig_apply_mask @@ -159,6 +159,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_WMO b/test/config/GridStatConfig_climo_WMO index 39e64895ce..c321eeda8c 100644 --- a/test/config/GridStatConfig_climo_WMO +++ b/test/config/GridStatConfig_climo_WMO @@ -219,6 +219,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_prob b/test/config/GridStatConfig_climo_prob index b5f4629bf1..a0a6985312 100644 --- a/test/config/GridStatConfig_climo_prob +++ b/test/config/GridStatConfig_climo_prob @@ -229,6 +229,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_fourier b/test/config/GridStatConfig_fourier index 6b2ba521f3..aa9adc28c3 100644 --- a/test/config/GridStatConfig_fourier +++ b/test/config/GridStatConfig_fourier @@ -185,6 +185,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_grid_weight b/test/config/GridStatConfig_grid_weight index af74b784c7..3a93382223 100644 --- a/test/config/GridStatConfig_grid_weight +++ b/test/config/GridStatConfig_grid_weight @@ -170,6 +170,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_interp_shape b/test/config/GridStatConfig_interp_shape index f6a69c5e35..9da6c42712 100644 --- a/test/config/GridStatConfig_interp_shape +++ b/test/config/GridStatConfig_interp_shape @@ -152,6 +152,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_mpr_thresh b/test/config/GridStatConfig_mpr_thresh index 4e95022a48..ecc9a1ae6d 100644 --- a/test/config/GridStatConfig_mpr_thresh +++ b/test/config/GridStatConfig_mpr_thresh @@ -217,6 +217,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_no_leap b/test/config/GridStatConfig_no_leap index 3b80dc0330..e2c22b2050 100644 --- a/test/config/GridStatConfig_no_leap +++ b/test/config/GridStatConfig_no_leap @@ -159,6 +159,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_prob_as_scalar b/test/config/GridStatConfig_prob_as_scalar index f497641518..0eaf736e63 100644 --- a/test/config/GridStatConfig_prob_as_scalar +++ b/test/config/GridStatConfig_prob_as_scalar @@ -180,6 +180,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_python b/test/config/GridStatConfig_python index 9bb128ac92..2a6d00cf2e 100644 --- a/test/config/GridStatConfig_python +++ b/test/config/GridStatConfig_python @@ -156,6 +156,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_python_mixed b/test/config/GridStatConfig_python_mixed index 38a5f9fa90..0973c96cee 100644 --- a/test/config/GridStatConfig_python_mixed +++ b/test/config/GridStatConfig_python_mixed @@ -164,6 +164,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_rtma b/test/config/GridStatConfig_rtma index b49db75a73..7944ec7a7d 100644 --- a/test/config/GridStatConfig_rtma +++ b/test/config/GridStatConfig_rtma @@ -160,6 +160,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_rtma_perc_thresh b/test/config/GridStatConfig_rtma_perc_thresh index 55b42b4456..7658f8695c 100644 --- a/test/config/GridStatConfig_rtma_perc_thresh +++ b/test/config/GridStatConfig_rtma_perc_thresh @@ -163,6 +163,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_st4 b/test/config/GridStatConfig_st4 index 00dbf1d8a0..c4b997fb55 100644 --- a/test/config/GridStatConfig_st4 +++ b/test/config/GridStatConfig_st4 @@ -164,6 +164,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_st4_censor b/test/config/GridStatConfig_st4_censor index d0ae97d7d9..d45a2afeac 100644 --- a/test/config/GridStatConfig_st4_censor +++ b/test/config/GridStatConfig_st4_censor @@ -173,6 +173,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/GridStatConfig_03h b/test/config/ref_config/GridStatConfig_03h index 70f885dd08..3bbd17a535 100644 --- a/test/config/ref_config/GridStatConfig_03h +++ b/test/config/ref_config/GridStatConfig_03h @@ -158,6 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/GridStatConfig_24h b/test/config/ref_config/GridStatConfig_24h index a66ffcf276..7f8b7d33fe 100644 --- a/test/config/ref_config/GridStatConfig_24h +++ b/test/config/ref_config/GridStatConfig_24h @@ -158,6 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } //////////////////////////////////////////////////////////////////////////////// From caff652a9563785dd845693f33fb2250ef0c6d56 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 8 Jul 2021 14:02:43 -0600 Subject: [PATCH 02/36] Per #1673, enhance Grid-Stat to parse the new beta_value option and set its value in the library code. --- met/src/basic/vx_config/config_constants.h | 1 + met/src/libcode/vx_statistics/met_stats.cc | 14 +++++++++----- met/src/libcode/vx_statistics/met_stats.h | 4 +++- .../tools/core/grid_stat/grid_stat_conf_info.cc | 14 ++++++++++++++ met/src/tools/core/grid_stat/grid_stat_conf_info.h | 3 ++- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/met/src/basic/vx_config/config_constants.h b/met/src/basic/vx_config/config_constants.h index d3b8773e58..34fe74c978 100644 --- a/met/src/basic/vx_config/config_constants.h +++ b/met/src/basic/vx_config/config_constants.h @@ -692,6 +692,7 @@ static const char conf_key_baddeley_p[] = "baddeley_p"; static const char conf_key_baddeley_max_dist[] = "baddeley_max_dist"; static const char conf_key_fom_alpha[] = "fom_alpha"; static const char conf_key_zhu_weight[] = "zhu_weight"; +static const char conf_key_beta_value[] = "beta_value"; // // Wavelet-Stat specific parameter key names diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index b7bd5ed012..0f7233af90 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2750,10 +2750,11 @@ void DMAPInfo::clear() { //////////////////////////////////////////////////////////////////////// void DMAPInfo::reset_options() { - baddeley_p = 2; // Exponent for lp-norm - baddeley_max_dist = 5.0; // Maximum distance constant - fom_alpha = 0.1; // FOM Alpha - zhu_weight = 0.5; // Zhu Weight + baddeley_p = 2; // Exponent for lp-norm + baddeley_max_dist = bad_data_double; // Maximum distance constant + fom_alpha = 0.1; // FOM Alpha + zhu_weight = 0.5; // Zhu Weight + beta_value = bad_data_double; // G-Beta Value return; } @@ -2796,6 +2797,7 @@ void DMAPInfo::assign(const DMAPInfo &c) { baddeley_max_dist = c.baddeley_max_dist; fom_alpha = c.fom_alpha; zhu_weight = c.zhu_weight; + beta_value = c.beta_value; return; } @@ -2948,11 +2950,13 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, //////////////////////////////////////////////////////////////////////// void DMAPInfo::set_options(const int _baddeley_p, const double _baddeley_max_dist, - const double _fom_alpha, const double _zhu_weight) { + const double _fom_alpha, const double _zhu_weight, + const double _beta_value) { baddeley_p = _baddeley_p; baddeley_max_dist = _baddeley_max_dist; fom_alpha = _fom_alpha; zhu_weight = _zhu_weight; + beta_value = _beta_value; } //////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_statistics/met_stats.h b/met/src/libcode/vx_statistics/met_stats.h index 38d5b3bafd..a03ed958b8 100644 --- a/met/src/libcode/vx_statistics/met_stats.h +++ b/met/src/libcode/vx_statistics/met_stats.h @@ -606,6 +606,7 @@ class DMAPInfo { double baddeley_max_dist; // Maximum distance constant double fom_alpha; // FOM Alpha double zhu_weight; // Zhu Weight + double beta_value; // G-Beta Value public: @@ -642,7 +643,8 @@ class DMAPInfo { const NumArray &fthr_na, const NumArray &othr_na); void set_options(const int _baddeley_p, const double _baddeley_max_dist, - const double _fom_alpha, const double _zhu_weight); + const double _fom_alpha, const double _zhu_weight, + const double _beta_value); void clear(); void reset_options(); 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 0bae27039c..d6b25d581f 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 @@ -529,6 +529,12 @@ void GridStatVxOpt::clear() { grad_dx.clear(); grad_dy.clear(); + baddeley_p = bad_data_int; + baddeley_max_dist = bad_data_double; + fom_alpha = bad_data_double; + zhu_weight = bad_data_double; + beta_value = bad_data_double; + hss_ec_value = bad_data_double; rank_corr_flag = false; @@ -811,6 +817,14 @@ void GridStatVxOpt::process_config( exit(1); } + beta_value = d->lookup_double(conf_key_beta_value); + if(beta_value <=0) { + mlog << Error << "\nGridStatVxOpt::process_config() -> " + << "The \"" << conf_key_beta_value << "\" option (" + << beta_value << ") must be set > 0.\n\n"; + exit(1); + } + // Conf: hss_ec_value hss_ec_value = odict.lookup_double(conf_key_hss_ec_value); 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 ff731985ac..d72e33dbfd 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 @@ -186,7 +186,8 @@ class GridStatVxOpt { int baddeley_p; // Exponent for lp-norm double baddeley_max_dist; // Maximum distance constant double fom_alpha; // FOM Alpha - double zhu_weight; // Zhu Weight + double zhu_weight; // Zhu Weight + double beta_value; // G-Beta Value double hss_ec_value; // MCTS HSS expected correct value bool rank_corr_flag; // Flag for computing rank correlations From f1d85c9ac4bcc3b0c422c7c62f929d29c8111602 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 8 Jul 2021 14:03:42 -0600 Subject: [PATCH 03/36] Per #1673, set the user-defined beta_value when processing the distance map scores. --- met/src/tools/core/grid_stat/grid_stat.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 1d75923bf3..1c5bf441d8 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -1298,7 +1298,8 @@ void process_scores() { conf_info.vx_opt[i].baddeley_p, conf_info.vx_opt[i].baddeley_max_dist, conf_info.vx_opt[i].fom_alpha, - conf_info.vx_opt[i].zhu_weight); + conf_info.vx_opt[i].zhu_weight, + conf_info.vx_opt[i].beta_value); // Compute DMAP statistics dmap_info.set(conf_info.vx_opt[i].fcat_ta[k], From b3bbc0f0519119dc3e983dec15fbd7aff3eec96e Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 8 Jul 2021 15:12:16 -0600 Subject: [PATCH 04/36] Per #1673, add 4 new DMAP columns write them. Just writing bad data values right now, still need to actually compute them! Also need to update Stat-Analysis to update the parsing/aggregation of these new values. --- .../table_files/met_header_columns_V10.1.txt | 2 +- met/src/basic/vx_util/stat_column_defs.h | 3 ++- met/src/libcode/vx_stat_out/stat_columns.cc | 15 ++++++++++- met/src/libcode/vx_statistics/met_stats.cc | 26 ++++++++++++++----- met/src/libcode/vx_statistics/met_stats.h | 10 +++++++ test/hdr/met_10_1.hdr | 2 +- 6 files changed, 48 insertions(+), 10 deletions(-) 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 6c64d89a5f..d5fbdd69af 100644 --- a/met/data/table_files/met_header_columns_V10.1.txt +++ b/met/data/table_files/met_header_columns_V10.1.txt @@ -10,7 +10,7 @@ V10.1 : STAT : NBRCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID V10.1 : 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 V10.1 : 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 V10.1 : 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 -V10.1 : 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 +V10.1 : 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 AGBETA BETA_VALUE V10.1 : 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 V10.1 : 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]* V10.1 : 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]* diff --git a/met/src/basic/vx_util/stat_column_defs.h b/met/src/basic/vx_util/stat_column_defs.h index d34fa22fdd..1726b6f74c 100644 --- a/met/src/basic/vx_util/stat_column_defs.h +++ b/met/src/basic/vx_util/stat_column_defs.h @@ -246,7 +246,8 @@ static const char * dmap_columns [] = { "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" + "ZHU_FO", "ZHU_OF", "ZHU_MIN", "ZHU_MAX", "ZHU_MEAN", + "G", "GBETA", "AGBETA", "BETA_VALUE" }; static const char * isc_columns [] = { diff --git a/met/src/libcode/vx_stat_out/stat_columns.cc b/met/src/libcode/vx_stat_out/stat_columns.cc index e385cfcfc7..6c99b8f826 100644 --- a/met/src/libcode/vx_stat_out/stat_columns.cc +++ b/met/src/libcode/vx_stat_out/stat_columns.cc @@ -3471,7 +3471,8 @@ void write_dmap_cols(const DMAPInfo &dmap_info, // 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 + // ZHU_FO, ZHU_OF, ZHU_MIN, ZHU_MAX, ZHU_MEAN, + // G, GBETA, AGBETA, BETA_VALUE // at.set_entry(r, c+0, // TOTAL dmap_info.total); @@ -3536,6 +3537,18 @@ void write_dmap_cols(const DMAPInfo &dmap_info, at.set_entry(r, c+20, // ZHU_MEAN dmap_info.zhu_mean); + at.set_entry(r, c+21, // G + dmap_info.g); + + at.set_entry(r, c+22, // GBETA + dmap_info.gbeta); + + at.set_entry(r, c+23, // AGBETA + dmap_info.agbeta); + + at.set_entry(r, c+24, // BETA_VALUE + dmap_info.get_beta_value()); + return; } diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 0f7233af90..a356494608 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2743,6 +2743,7 @@ void DMAPInfo::clear() { med_fo = med_of = med_min = med_max = med_mean = bad_data_double; fom_fo = fom_of = fom_min = fom_max = fom_mean = bad_data_double; zhu_fo = zhu_of = zhu_min = zhu_max = zhu_mean = bad_data_double; + g = gbeta = agbeta = beta_value = bad_data_double; return; } @@ -2793,6 +2794,10 @@ void DMAPInfo::assign(const DMAPInfo &c) { zhu_max = c.zhu_max; zhu_mean = c.zhu_mean; + g = c.g; + gbeta = c.gbeta; + agbeta = c.agbeta; + baddeley_p = c.baddeley_p; baddeley_max_dist = c.baddeley_max_dist; fom_alpha = c.fom_alpha; @@ -2935,15 +2940,24 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, zhu_mean = (zhu_fo + zhu_of) / 2; } + // G, G-Beta, and asymmetric G-Beta + // JHG work here! + g = bad_data_double; + gbeta = bad_data_double; + agbeta = bad_data_double; + mlog << Debug(4) << " DMAP: nf=" << fy << ", no=" << oy << ", total=" << total << "\tbaddeley=" << baddeley << ", hausdorff=" << hausdorff - << "\n\tmed_fo=" << med_fo << ", med_of=" << med_of - << ", med_min=" << med_min << ", med_max=" << med_max << ", med_mean=" << med_mean - << "\n\tfom_fo=" << fom_fo << ", fom_of=" << fom_of - << ", fom_min=" << fom_min << ", fom_max=" << fom_max << ", fom_mean=" << fom_mean - << "\n\tzhu_fo=" << zhu_fo << ", zhu_of=" << zhu_of - << ", zhu_min=" << zhu_min << ", zhu_max=" << zhu_max << ", zhu_mean=" << zhu_mean + << "\n\tmed_fo=" << med_fo << ", med_of=" << med_of + << ", med_min=" << med_min << ", med_max=" << med_max << ", med_mean=" << med_mean + << "\n\tfom_fo=" << fom_fo << ", fom_of=" << fom_of + << ", fom_min=" << fom_min << ", fom_max=" << fom_max << ", fom_mean=" << fom_mean + << "\n\tzhu_fo=" << zhu_fo << ", zhu_of=" << zhu_of + << ", zhu_min=" << zhu_min << ", zhu_max=" << zhu_max << ", zhu_mean=" << zhu_mean + << "\n\tg=" << g << ", gbeta=" << gbeta << ", agbeta=" << agbeta + << ", beta_value=" << beta_value << "\n"; + return; } diff --git a/met/src/libcode/vx_statistics/met_stats.h b/met/src/libcode/vx_statistics/met_stats.h index a03ed958b8..23d1ba2eef 100644 --- a/met/src/libcode/vx_statistics/met_stats.h +++ b/met/src/libcode/vx_statistics/met_stats.h @@ -634,6 +634,9 @@ class DMAPInfo { // Zhu Metric double zhu_fo, zhu_of, zhu_min, zhu_max, zhu_mean; + // G, G-Beta, and assymetric G-Beta + double g, gbeta, agbeta; + // Compute statistics double fbias() const; // fbias = fy / oy @@ -646,10 +649,17 @@ class DMAPInfo { const double _fom_alpha, const double _zhu_weight, const double _beta_value); + // Get functions + double get_beta_value() const; + void clear(); void reset_options(); }; +//////////////////////////////////////////////////////////////////////// + +inline double DMAPInfo::get_beta_value() const { return(beta_value); } + //////////////////////////////////////////////////////////////////////// // // Utility functions for parsing data from configuration files diff --git a/test/hdr/met_10_1.hdr b/test/hdr/met_10_1.hdr index 77d4fa0053..ec3b6482b2 100644 --- a/test/hdr/met_10_1.hdr +++ b/test/hdr/met_10_1.hdr @@ -10,7 +10,7 @@ NBRCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_L 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 +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 AGBETA 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_ From 69f82df2cb8fe61c15de40a6a5fe85134d7f2600 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 8 Jul 2021 15:24:01 -0600 Subject: [PATCH 05/36] Per #1673, enable beta_value to be set to a default bad data value. --- met/src/tools/core/grid_stat/grid_stat_conf_info.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d6b25d581f..0dc8fcd301 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 @@ -818,7 +818,7 @@ void GridStatVxOpt::process_config( } beta_value = d->lookup_double(conf_key_beta_value); - if(beta_value <=0) { + if(!is_bad_data(beta_value) && beta_value <=0) { mlog << Error << "\nGridStatVxOpt::process_config() -> " << "The \"" << conf_key_beta_value << "\" option (" << beta_value << ") must be set > 0.\n\n"; From c89ad5c7c349a51634e5a20cd9dd6aa3387cf9c9 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 9 Jul 2021 09:36:20 -0600 Subject: [PATCH 06/36] Per #1673 and @ericgilleland instruction (https://github.com/dtcenter/MET/issues/1673#issuecomment-876907466), strip asymmetric G-Beta (AGBETA) from the output. --- .../table_files/met_header_columns_V10.1.txt | 2 +- met/src/basic/vx_util/stat_column_defs.h | 2 +- met/src/libcode/vx_stat_out/stat_columns.cc | 7 +-- met/src/libcode/vx_statistics/met_stats.cc | 52 +++++++++++++------ met/src/libcode/vx_statistics/met_stats.h | 6 +-- test/hdr/met_10_1.hdr | 2 +- 6 files changed, 44 insertions(+), 27 deletions(-) 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 d5fbdd69af..f6c2665f4f 100644 --- a/met/data/table_files/met_header_columns_V10.1.txt +++ b/met/data/table_files/met_header_columns_V10.1.txt @@ -10,7 +10,7 @@ V10.1 : STAT : NBRCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID V10.1 : 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 V10.1 : 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 V10.1 : 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 -V10.1 : 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 AGBETA BETA_VALUE +V10.1 : 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 V10.1 : 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 V10.1 : 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]* V10.1 : 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]* diff --git a/met/src/basic/vx_util/stat_column_defs.h b/met/src/basic/vx_util/stat_column_defs.h index 1726b6f74c..3c82a88af1 100644 --- a/met/src/basic/vx_util/stat_column_defs.h +++ b/met/src/basic/vx_util/stat_column_defs.h @@ -247,7 +247,7 @@ static const char * dmap_columns [] = { "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", "AGBETA", "BETA_VALUE" + "G", "GBETA", "BETA_VALUE" }; static const char * isc_columns [] = { diff --git a/met/src/libcode/vx_stat_out/stat_columns.cc b/met/src/libcode/vx_stat_out/stat_columns.cc index 6c99b8f826..21d56cf7ae 100644 --- a/met/src/libcode/vx_stat_out/stat_columns.cc +++ b/met/src/libcode/vx_stat_out/stat_columns.cc @@ -3472,7 +3472,7 @@ void write_dmap_cols(const DMAPInfo &dmap_info, // 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, AGBETA, BETA_VALUE + // G, GBETA, BETA_VALUE // at.set_entry(r, c+0, // TOTAL dmap_info.total); @@ -3543,10 +3543,7 @@ void write_dmap_cols(const DMAPInfo &dmap_info, at.set_entry(r, c+22, // GBETA dmap_info.gbeta); - at.set_entry(r, c+23, // AGBETA - dmap_info.agbeta); - - at.set_entry(r, c+24, // BETA_VALUE + at.set_entry(r, c+23, // BETA_VALUE dmap_info.get_beta_value()); return; diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index a356494608..153fdb12f3 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2738,12 +2738,12 @@ void DMAPInfo::clear() { fthresh.clear(); othresh.clear(); - total = fy = oy = 0; + total = fy = oy = foy = 0; baddeley = hausdorff = bad_data_double; med_fo = med_of = med_min = med_max = med_mean = bad_data_double; fom_fo = fom_of = fom_min = fom_max = fom_mean = bad_data_double; zhu_fo = zhu_of = zhu_min = zhu_max = zhu_mean = bad_data_double; - g = gbeta = agbeta = beta_value = bad_data_double; + g = gbeta = beta_value = bad_data_double; return; } @@ -2772,6 +2772,7 @@ void DMAPInfo::assign(const DMAPInfo &c) { total = c.total; fy = c.fy; oy = c.oy; + foy = c.foy; baddeley = c.baddeley; hausdorff = c.hausdorff; @@ -2794,9 +2795,8 @@ void DMAPInfo::assign(const DMAPInfo &c) { zhu_max = c.zhu_max; zhu_mean = c.zhu_mean; - g = c.g; - gbeta = c.gbeta; - agbeta = c.agbeta; + g = c.g; + gbeta = c.gbeta; baddeley_p = c.baddeley_p; baddeley_max_dist = c.baddeley_max_dist; @@ -2819,7 +2819,7 @@ double DMAPInfo::fbias() const { } //////////////////////////////////////////////////////////////////////// - + void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, const NumArray &fdmap_na, const NumArray &odmap_na, const NumArray &fthr_na, const NumArray &othr_na) { @@ -2866,17 +2866,23 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, if (is_bad_data(fdmap_na[i]) || is_bad_data(odmap_na[i]) || is_bad_data(fthr_na[i]) || is_bad_data(othr_na[i])) continue; + // Forecast event if (fthr_na[i] > 0) { fy++; med_of_sum += odmap_na[i]; fom_of_sum += 1 / (1 + odmap_na[i] * odmap_na[i] * fom_alpha); } + + // Observation if (othr_na[i] > 0) { oy++; med_fo_sum += fdmap_na[i]; fom_fo_sum += 1 / (1 + fdmap_na[i] * fdmap_na[i] * fom_alpha); } + // Forecast and observation event + if (fthr_na[i] > 0 && othr_na[i] > 0) foy++; + sum_event_diff += (fthr_na[i] - othr_na[i]) * (fthr_na[i] - othr_na[i]); f_distance = (!is_bad_data(baddeley_max_dist) && @@ -2940,22 +2946,36 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, zhu_mean = (zhu_fo + zhu_of) / 2; } - // G, G-Beta, and asymmetric G-Beta - // JHG work here! - g = bad_data_double; - gbeta = bad_data_double; - agbeta = bad_data_double; + // G and G-Beta + // Reference: + // Gilleland, E.: Novel measures for summarizing high-resolution forecast performance, + // Adv. Stat. Clim. Meteorol. Oceanogr., 7, 13–34, + // https://doi.org/10.5194/ascmo-7-13-2021, 2021. + + // If not set by the user, default maximum distance to the number of pairs + double max_dist = (is_bad_data(baddeley_max_dist) ? + (double) total : baddeley_max_dist); + + double g_med_fo = (oy == 0 ? max_dist : med_fo); + double g_med_of = (fy == 0 ? max_dist : met_of); + int g_y1 = fy + oy - 2 * foy; + double g_y2 = g_med_fo * oy + g_med_of * fy; + double g_y = g_y1 * g_y2; + g = pow(g_y, 1.0 / 3.0); + + // If not set by the user, default beta to the number of pairs divided by 2 + double g_b = (is_bad_data(beta_value) ? (double) total / 2.0 : beta_value); + gbeta = max(1.0 - g_y / g_b, 0.0); mlog << Debug(4) << " DMAP: nf=" << fy << ", no=" << oy << ", total=" << total << "\tbaddeley=" << baddeley << ", hausdorff=" << hausdorff << "\n\tmed_fo=" << med_fo << ", med_of=" << med_of - << ", med_min=" << med_min << ", med_max=" << med_max << ", med_mean=" << med_mean + << ", med_min=" << med_min << ", med_max=" << med_max << ", med_mean=" << med_mean << "\n\tfom_fo=" << fom_fo << ", fom_of=" << fom_of - << ", fom_min=" << fom_min << ", fom_max=" << fom_max << ", fom_mean=" << fom_mean + << ", fom_min=" << fom_min << ", fom_max=" << fom_max << ", fom_mean=" << fom_mean << "\n\tzhu_fo=" << zhu_fo << ", zhu_of=" << zhu_of - << ", zhu_min=" << zhu_min << ", zhu_max=" << zhu_max << ", zhu_mean=" << zhu_mean - << "\n\tg=" << g << ", gbeta=" << gbeta << ", agbeta=" << agbeta - << ", beta_value=" << beta_value + << ", zhu_min=" << zhu_min << ", zhu_max=" << zhu_max << ", zhu_mean=" << zhu_mean + << "\n\tg=" << g << ", gbeta=" << gbeta << ", beta_value=" << beta_value << "\n"; return; diff --git a/met/src/libcode/vx_statistics/met_stats.h b/met/src/libcode/vx_statistics/met_stats.h index 23d1ba2eef..ccfd85782e 100644 --- a/met/src/libcode/vx_statistics/met_stats.h +++ b/met/src/libcode/vx_statistics/met_stats.h @@ -620,7 +620,7 @@ class DMAPInfo { SingleThresh othresh; // Counts - int total, fy, oy; + int total, fy, oy, foy; // Distance metrics double baddeley, hausdorff; @@ -634,8 +634,8 @@ class DMAPInfo { // Zhu Metric double zhu_fo, zhu_of, zhu_min, zhu_max, zhu_mean; - // G, G-Beta, and assymetric G-Beta - double g, gbeta, agbeta; + // G and G-Beta + double g, gbeta; // Compute statistics double fbias() const; // fbias = fy / oy diff --git a/test/hdr/met_10_1.hdr b/test/hdr/met_10_1.hdr index ec3b6482b2..4c667d2b6b 100644 --- a/test/hdr/met_10_1.hdr +++ b/test/hdr/met_10_1.hdr @@ -10,7 +10,7 @@ NBRCNT : VERSION MODEL DESC FCST_LEAD FCST_VALID_BEG FCST_VALID_END OBS_L 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 AGBETA BETA_VALUE +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_ From c38a3481d918ee1b89a6cfd1bd736a1e952cdfa6 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 9 Jul 2021 09:44:05 -0600 Subject: [PATCH 07/36] Per #1673, fix typo that was causing the code not to compile. --- met/src/libcode/vx_statistics/met_stats.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 153fdb12f3..dc7ec80315 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2957,7 +2957,7 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, (double) total : baddeley_max_dist); double g_med_fo = (oy == 0 ? max_dist : med_fo); - double g_med_of = (fy == 0 ? max_dist : met_of); + double g_med_of = (fy == 0 ? max_dist : med_of); int g_y1 = fy + oy - 2 * foy; double g_y2 = g_med_fo * oy + g_med_of * fy; double g_y = g_y1 * g_y2; From 19159820390fe22c003cacdc63954726e0f2e043 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 16 Jul 2021 12:25:40 -0600 Subject: [PATCH 08/36] Per #1673, update MET User's Guide about G/GBETA. --- met/docs/Users_Guide/grid-stat.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index 123954bc47..872d593909 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -289,9 +289,10 @@ ____________________ baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; + beta_value = NA; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **GBETA** statistic. If left to its default NA value, the beta value will be set to N / 2 where N is the number of matched pairs for each verification task. _____________________ @@ -804,6 +805,15 @@ The format of the STAT and ASCII output of the Grid-Stat tool are the same as th * - 45 - ZHU_MEAN - Mean of ZHU_FO and ZHU_OF + * - 46 + - G + - G distance measure + * - 47 + - GBETA + - G-Beta distance measure + * - 48 + - BETA_VALUE + - Beta value used to compute GBETA, where NA means that TOTAL/2 was used If requested using the **nc_pairs_flag** dictionary in the configuration file, a NetCDF file containing the matched pair and forecast minus observation difference fields for each combination of variable type/level and masking region applied will be generated. The contents of this file are determined by the contents of the nc_pairs_flag dictionary. The output NetCDF file is named similarly to the other output files: **grid_stat_PREFIX_ HHMMSSL_YYYYMMDD_HHMMSSV_pairs.nc**. Commonly available NetCDF utilities such as ncdump or ncview may be used to view the contents of the output file. From 7cb41d54cdb43f5033d5e75d280e79e4083d142c Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 16 Jul 2021 14:56:46 -0600 Subject: [PATCH 09/36] Per #1673, report BETA_VALUE = TOTAL / 2 in the output instead of NA, as directed by Eric. --- 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 dc7ec80315..dfe8c88965 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2963,9 +2963,10 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, double g_y = g_y1 * g_y2; g = pow(g_y, 1.0 / 3.0); - // If not set by the user, default beta to the number of pairs divided by 2 - double g_b = (is_bad_data(beta_value) ? (double) total / 2.0 : beta_value); - gbeta = max(1.0 - g_y / g_b, 0.0); + // If not set by the user, set beta_value as the number of pairs divided by 2 + if(is_bad_data(beta_value)) beta_value = (double) total / 2.0; + + gbeta = max(1.0 - g_y / beta_value, 0.0); mlog << Debug(4) << " DMAP: nf=" << fy << ", no=" << oy << ", total=" << total << "\tbaddeley=" << baddeley << ", hausdorff=" << hausdorff From 35167fa385d7ed86abe9ca9eb0e42d76f63cfe71 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 23 Jul 2021 10:08:24 -0600 Subject: [PATCH 10/36] Per #1673, remove descriptions of Grid-Stat-specific config options for nbrhd, fourier, gradient, and distance_map from the overview section since they belong in the Grid-Stat chapter. Also add direct links for them in the Grid-Stat chapter. --- met/docs/Users_Guide/config_options.rst | 132 +----------------------- met/docs/Users_Guide/grid-stat.rst | 31 ++++-- 2 files changed, 26 insertions(+), 137 deletions(-) diff --git a/met/docs/Users_Guide/config_options.rst b/met/docs/Users_Guide/config_options.rst index a490ea1e27..5c3149b03f 100644 --- a/met/docs/Users_Guide/config_options.rst +++ b/met/docs/Users_Guide/config_options.rst @@ -413,7 +413,7 @@ e.g. model = "GFS"; model = "WRF"; -.._desc: +.. _desc: :ref:`desc ` @@ -1615,136 +1615,6 @@ This dictionary may include the following entries: ]; } -.. _nbrhd: - -:ref:`nbrhd ` - -The "nbrhd" entry is a dictionary that is very similar to the "interp" -entry. It specifies information for computing neighborhood statistics in -Grid-Stat. This dictionary may include the following entries: - -* The "field" entry specifies to which field(s) the computation of - fractional coverage should be applied. Grid-Stat processes each - combination of categorical threshold and neighborhood width to - derive the fractional coverage fields from which neighborhood - statistics are calculated. Users who have computed fractional - coverage fields outside of MET can use this option to disable - these computations. Instead, the raw input values will be - used directly to compute neighborhood statistics: - - * "BOTH" to compute fractional coverage for both the forecast - and the observation fields (default). - - * "FCST" to only process the forecast field. - - * "OBS" to only process the observation field. - - * "NONE" to process neither field. - -* The "vld_thresh" entry is described above. - -* The "shape" entry defines the shape of the neighborhood. - Valid values are "SQUARE" or "CIRCLE" - -* The "width" entry is as described above, and must be odd. - -* The "cov_thresh" entry is an array of thresholds to be used when - computing categorical statistics for the neighborhood fractional - coverage field. - -.. code-block:: none - - nbrhd = { - field = BOTH; - vld_thresh = 1.0; - shape = SQUARE; - width = [ 1 ]; - cov_thresh = [ >=0.5 ]; - } - -.. _fourier: - -:ref:`fourier ` - -The "fourier" entry is a dictionary which specifies the application of the -Fourier decomposition method. It consists of two arrays of the same length -which define the beginning and ending wave numbers to be included. If the -arrays have length zero, no Fourier decomposition is applied. For each array -entry, the requested Fourier decomposition is applied to the forecast and -observation fields. The beginning and ending wave numbers are indicated in -the MET ASCII output files by the INTERP_MTHD column (e.g. WV1_0-3 for waves -0 to 3 or WV1_10 for only wave 10). This 1-dimensional Fourier decomposition -is computed along the Y-dimension only (i.e. the columns of data). It is only -defined when each grid point contains valid data. If either input field -contains missing data, no Fourier decomposition is computed. - -The available wave numbers start at 0 (the mean across each row of data) -and end at (Nx+1)/2 (the finest level of detail), where Nx is the X-dimension -of the verification grid: - -* The "wave_1d_beg" entry is an array of integers specifying the first - wave number to be included. - -* The "wave_1d_end" entry is an array of integers specifying the last - wave number to be included. - -.. code-block:: none - - fourier = { - wave_1d_beg = [ 0, 4, 10 ]; - wave_1d_end = [ 3, 9, 20 ]; - } - -.. _gradient: - -:ref:`gradient ` - -The "gradient" entry is a dictionary which specifies the number and size of -gradients to be computed. The "dx" and "dy" entries specify the size of the -gradients in grid units in the X and Y dimensions, respectively. dx and dy -are arrays of integers (positive or negative) which must have the same -length, and the GRAD output line type will be computed separately for each -entry. When computing gradients, the value at the (x, y) grid point is -replaced by the value at the (x+dx, y+dy) grid point minus the value at -(x, y). - -This configuration option may be set separately in each "obs.field" entry. - -.. code-block:: none - - gradient = { - dx = [ 1 ]; - dy = [ 1 ]; - } - -.. _distance_map: - -:ref:`distance_map ` - -The "distance_map" entry is a dictionary containing options related to the -distance map statistics in the DMAP output line type. The "baddeley_p" entry -is an integer specifying the exponent used in the Lp-norm when computing the -Baddeley Delta metric. The "baddeley_max_dist" entry is a floating point -number specifying the maximum allowable distance for each distance map. Any -distances larger than this number will be reset to this constant. A value of -NA indicates that no maximum distance value should be used. The "fom_alpha" -entry is a floating point number specifying the scaling constant to be used -when computing Pratt's Figure of Merit. The "zhu_weight" specifies a value -between 0 and 1 to define the importance of the RMSE of the binary fields -(i.e. amount of overlap) versus the mean-error distance (MED). The default -value of 0.5 gives equal weighting. - -This configuration option may be set separately in each "obs.field" entry. - -.. code-block:: none - - distance_map = { - baddeley_p = 2; - baddeley_max_dist = NA; - fom_alpha = 0.1; - zhu_weight = 0.5; - } - .. _land_mask: :ref:`land_mask ` diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index 08c1208e4d..e532d37dfe 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -234,6 +234,10 @@ The configuration options listed above are common to multiple MET tools and are ___________________________ +.. _nbrhd: + +:ref:`nbrhd ` + .. code-block:: none nbrhd = { @@ -244,7 +248,7 @@ ___________________________ cov_thresh = [ >=0.5 ]; } - + The **nbrhd** dictionary contains a list of values to be used in defining the neighborhood to be used when computing neighborhood verification statistics. The neighborhood **shape** is a **SQUARE** or **CIRCLE** centered on the current point, and the **width** value specifies the width of the square or diameter of the circle as an odd integer. The **field** entry is set to **BOTH, FCST, OBS**, or **NONE** to indicate the fields to which the fractional coverage derivation logic should be applied. This should always be set to **BOTH** unless you have already computed the fractional coverage field(s) with numbers between 0 and 1 outside of MET. @@ -255,6 +259,10 @@ The **cov_thresh** entry contains a comma separated list of thresholds to be app ___________________ +.. _fourier: + +:ref:`fourier ` + .. code-block:: none fourier = { @@ -263,25 +271,36 @@ ___________________ } -The **fourier** entry is a dictionary which specifies the application of the Fourier decomposition method. It consists of two arrays of the same length which define the beginning and ending wave numbers to be included. If the arrays have length zero, no Fourier decomposition is applied. For each array entry, the requested Fourier decomposition is applied to the forecast and observation fields. The beginning and ending wave numbers are indicated in the MET ASCII output files by the INTERP_MTHD column (e.g. WV1_0-3 for waves 0 to 3 or WV1_10 for only wave 10). This 1-dimensional Fourier decomposition is computed along the Y-dimension only (i.e. the columns of data). It is applied to the forecast and observation fields as well as the climatological mean field, if specified. It is only defined when each grid point contains valid data. If any input field contains missing data, no Fourier decomposition is computed. The available wave numbers start at 0 (the mean across each row of data) and end at (Nx+1)/2 (the finest level of detail), where Nx is the X-dimension of the verification grid. +The **fourier** entry is a dictionary which specifies the application of the Fourier decomposition method. It consists of two arrays of the same length which define the beginning and ending wave numbers to be included. If the arrays have length zero, no Fourier decomposition is applied. For each array entry, the requested Fourier decomposition is applied to the forecast and observation fields. The beginning and ending wave numbers are indicated in the MET ASCII output files by the INTERP_MTHD column (e.g. WV1_0-3 for waves 0 to 3 or WV1_10 for only wave 10). This 1-dimensional Fourier decomposition is computed along the Y-dimension only (i.e. the columns of data). It is applied to the forecast and observation fields as well as the climatological mean field, if specified. It is only defined when each grid point contains valid data. If any input field contains missing data, no Fourier decomposition is computed. + +The available wave numbers start at 0 (the mean across each row of data) and end at (Nx+1)/2 (the finest level of detail), where Nx is the X-dimension of the verification grid: -The **wave_1d_beg** entry is an array of integers specifying the first wave number to be included. The **wave_1d_end** entry is an array of integers specifying the last wave number to be included. +* The **wave_1d_beg** entry is an array of integers specifying the first wave number to be included. + +* The **wave_1d_end** entry is an array of integers specifying the last wave number to be included. _____________________ +.. _gradient: + +:ref:`gradient ` + .. code-block:: none - grad = { + gradient = { dx = [ 1 ]; dy = [ 1 ]; } - The **gradient** entry is a dictionary which specifies the number and size of gradients to be computed. The **dx** and **dy** entries specify the size of the gradients in grid units in the X and Y dimensions, respectively. **dx** and **dy** are arrays of integers (positive or negative) which must have the same length, and the GRAD output line type will be computed separately for each entry. When computing gradients, the value at the (x, y) grid point is replaced by the value at the (x+dx, y+dy) grid point minus the value at (x, y). This configuration option may be set separately in each **obs.field** entry. ____________________ +.. _distance_map: + +:ref:`distance_map ` + .. code-block:: none distance_map = { @@ -756,7 +775,7 @@ The format of the STAT and ASCII output of the Grid-Stat tool are the same as th - Frequency Bias * - 29 - BADDELEY - - Baddeley's Delta Metric + - Baddeley's :math:`\Delta` Metric * - 30 - HAUSDORFF - Hausdorff Distance From fbe6eb17a87e2148ab3297eedf438aab7c6dbb98 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 23 Jul 2021 12:23:44 -0600 Subject: [PATCH 11/36] Per #1673, do not reset the beta_value in DMAP::clear(). --- met/src/libcode/vx_statistics/met_stats.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index dfe8c88965..4cc6676c66 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2743,7 +2743,7 @@ void DMAPInfo::clear() { med_fo = med_of = med_min = med_max = med_mean = bad_data_double; fom_fo = fom_of = fom_min = fom_max = fom_mean = bad_data_double; zhu_fo = zhu_of = zhu_min = zhu_max = zhu_mean = bad_data_double; - g = gbeta = beta_value = bad_data_double; + g = gbeta = bad_data_double; return; } @@ -2858,7 +2858,8 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, mlog << Debug(4) << " DMAP.Options: baddeley_p=" << baddeley_p << ", baddeley_max_dist=" << baddeley_max_dist << ", fom_alpha=" << fom_alpha - << ", zhu_weight=" << zhu_weight << "\n"; + << ", zhu_weight=" << zhu_weight + << ", beta_value=" << beta_value << "\n"; for (int i=0; i Date: Fri, 23 Jul 2021 15:29:32 -0600 Subject: [PATCH 12/36] Per #1673, log the DMAP options only after the beta_value has been determined. --- met/src/libcode/vx_statistics/met_stats.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 4cc6676c66..e39590833e 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2855,12 +2855,6 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, non_zero_count = 0; - mlog << Debug(4) << " DMAP.Options: baddeley_p=" << baddeley_p - << ", baddeley_max_dist=" << baddeley_max_dist - << ", fom_alpha=" << fom_alpha - << ", zhu_weight=" << zhu_weight - << ", beta_value=" << beta_value << "\n"; - for (int i=0; i Date: Fri, 23 Jul 2021 15:50:10 -0600 Subject: [PATCH 13/36] Per #1673, correct the default beta_value setting as N*N / 2.0. --- met/docs/Users_Guide/grid-stat.rst | 2 +- met/src/libcode/vx_statistics/met_stats.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index e532d37dfe..258ccbf76f 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -311,7 +311,7 @@ ____________________ beta_value = NA; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **GBETA** statistic. If left to its default NA value, the beta value will be set to N / 2 where N is the number of matched pairs for each verification task. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **GBETA** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. _____________________ diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index e39590833e..786d0a5827 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2958,8 +2958,8 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, double g_y = g_y1 * g_y2; g = pow(g_y, 1.0 / 3.0); - // If not set by the user, set beta_value as the number of pairs divided by 2 - if(is_bad_data(beta_value)) beta_value = (double) total / 2.0; + // If not set by the user, set beta_value as the total squared divided by 2 + if(is_bad_data(beta_value)) beta_value = pow((double) total, 2.0) / 2.0; gbeta = max(1.0 - g_y / beta_value, 0.0); From 50a51272e6f4c289985b0d5c6b87a02f1c7f0def Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 23 Jul 2021 15:55:17 -0600 Subject: [PATCH 14/36] Per #1673, trying to format G-beta well. --- met/docs/Users_Guide/grid-stat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index 258ccbf76f..bd58ac8c36 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -311,7 +311,7 @@ ____________________ beta_value = NA; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **GBETA** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **::math`G_\Beta`** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. _____________________ From 6afa6d746319570bcf9637be58073a798786c2cb Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 23 Jul 2021 15:58:18 -0600 Subject: [PATCH 15/36] Per #1673, trying to format G-beta well. --- met/docs/Users_Guide/grid-stat.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index bd58ac8c36..ef0e3052a3 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -311,7 +311,7 @@ ____________________ beta_value = NA; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **::math`G_\Beta`** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **:math:`G_\Beta`** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. _____________________ @@ -826,13 +826,13 @@ The format of the STAT and ASCII output of the Grid-Stat tool are the same as th - Mean of ZHU_FO and ZHU_OF * - 46 - G - - G distance measure + - :math:`G` distance measure * - 47 - GBETA - - G-Beta distance measure + - :math:`G_\Beta` distance measure * - 48 - BETA_VALUE - - Beta value used to compute GBETA, where NA means that TOTAL/2 was used + - Beta value used to compute :math:`G_\Beta` If requested using the **nc_pairs_flag** dictionary in the configuration file, a NetCDF file containing the matched pair and forecast minus observation difference fields for each combination of variable type/level and masking region applied will be generated. The contents of this file are determined by the contents of the nc_pairs_flag dictionary. The output NetCDF file is named similarly to the other output files: **grid_stat_PREFIX_ HHMMSSL_YYYYMMDD_HHMMSSV_pairs.nc**. Commonly available NetCDF utilities such as ncdump or ncview may be used to view the contents of the output file. From 2b104e78e94729790deb2fa4e4e5f67d69b6fa5d Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 23 Jul 2021 16:05:14 -0600 Subject: [PATCH 16/36] Per #1673, beta is formatted as \beta and not \Beta in latex. --- met/docs/Users_Guide/grid-stat.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index ef0e3052a3..33552cd166 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -311,7 +311,7 @@ ____________________ beta_value = NA; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **:math:`G_\Beta`** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **:math:`G_\beta`** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. _____________________ @@ -829,10 +829,10 @@ The format of the STAT and ASCII output of the Grid-Stat tool are the same as th - :math:`G` distance measure * - 47 - GBETA - - :math:`G_\Beta` distance measure + - :math:`G_\beta` distance measure * - 48 - BETA_VALUE - - Beta value used to compute :math:`G_\Beta` + - Beta value used to compute :math:`G_\beta` If requested using the **nc_pairs_flag** dictionary in the configuration file, a NetCDF file containing the matched pair and forecast minus observation difference fields for each combination of variable type/level and masking region applied will be generated. The contents of this file are determined by the contents of the nc_pairs_flag dictionary. The output NetCDF file is named similarly to the other output files: **grid_stat_PREFIX_ HHMMSSL_YYYYMMDD_HHMMSSV_pairs.nc**. Commonly available NetCDF utilities such as ncdump or ncview may be used to view the contents of the output file. From 667d74df4d1d4fcb97145e9ae2d1bb270621fc46 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 23 Jul 2021 16:07:58 -0600 Subject: [PATCH 17/36] Per #1673, beta is formatted as \beta and not \Beta in latex. --- met/docs/Users_Guide/grid-stat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index 33552cd166..7c583b1498 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -311,7 +311,7 @@ ____________________ beta_value = NA; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the **:math:`G_\beta`** statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the :math:`G_\beta` statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. _____________________ From 26477def28631bd85c56d9252790c472e0678cac Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 26 Jul 2021 11:47:51 -0600 Subject: [PATCH 18/36] Per #1673, switch to defining beta_value as a function of the input grid size. --- met/data/config/GridStatConfig_default | 2 +- met/docs/Users_Guide/grid-stat.rst | 4 ++-- 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/src/libcode/vx_statistics/met_stats.cc | 12 ++++++++---- met/src/tools/core/grid_stat/grid_stat.cc | 2 +- met/src/tools/core/grid_stat/grid_stat_conf_info.cc | 10 +++++----- met/src/tools/core/grid_stat/grid_stat_conf_info.h | 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_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/ref_config/GridStatConfig_03h | 2 +- test/config/ref_config/GridStatConfig_24h | 2 +- 32 files changed, 44 insertions(+), 40 deletions(-) diff --git a/met/data/config/GridStatConfig_default b/met/data/config/GridStatConfig_default index 94be3a175c..89dc90e156 100644 --- a/met/data/config/GridStatConfig_default +++ b/met/data/config/GridStatConfig_default @@ -202,7 +202,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index 7c583b1498..d65df13412 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -308,10 +308,10 @@ ____________________ baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is a floating point number used to compute the :math:`G_\beta` statistic. If left to its default NA value, the beta value will be set to :math:`N^2 / 2` where N is the number of matched pairs for each verification task. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is defined as a function of n, where n is the total number of grid points in the domain (i.e. Nx * Ny). The resulting beta_value is used to compute the :math:`G_\beta` statistic. The default function, :math:`N^2 / 2`, is recommended in published literature but can be modified as needed. _____________________ diff --git a/met/scripts/config/GridStatConfig_APCP_12 b/met/scripts/config/GridStatConfig_APCP_12 index ab6c7ad91f..76747e7908 100644 --- a/met/scripts/config/GridStatConfig_APCP_12 +++ b/met/scripts/config/GridStatConfig_APCP_12 @@ -159,7 +159,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_APCP_24 b/met/scripts/config/GridStatConfig_APCP_24 index 0d132582ef..bca332cdde 100644 --- a/met/scripts/config/GridStatConfig_APCP_24 +++ b/met/scripts/config/GridStatConfig_APCP_24 @@ -169,7 +169,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_POP_12 b/met/scripts/config/GridStatConfig_POP_12 index 4407d5601b..2df3bc3914 100644 --- a/met/scripts/config/GridStatConfig_POP_12 +++ b/met/scripts/config/GridStatConfig_POP_12 @@ -169,7 +169,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/scripts/config/GridStatConfig_all b/met/scripts/config/GridStatConfig_all index 6d7c251520..6e9ae9e38b 100644 --- a/met/scripts/config/GridStatConfig_all +++ b/met/scripts/config/GridStatConfig_all @@ -200,7 +200,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index 786d0a5827..a1fa103d54 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2835,6 +2835,14 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, exit(1); } + // Check that beta_value has been set + if(is_bad_data(beta_value) || beta_value <= 0.0) { + mlog << Error << "\nDMAPInfo::set() -> " + << "the beta_value (" << beta_value + << ") must be greater than 0!\n\n"; + exit(1); + } + // Initialize clear(); @@ -2957,10 +2965,6 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, double g_y2 = g_med_fo * oy + g_med_of * fy; double g_y = g_y1 * g_y2; g = pow(g_y, 1.0 / 3.0); - - // If not set by the user, set beta_value as the total squared divided by 2 - if(is_bad_data(beta_value)) beta_value = pow((double) total, 2.0) / 2.0; - gbeta = max(1.0 - g_y / beta_value, 0.0); // Dump debug distance map info diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 1c5bf441d8..4c3983d5a0 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -1299,7 +1299,7 @@ void process_scores() { conf_info.vx_opt[i].baddeley_max_dist, conf_info.vx_opt[i].fom_alpha, conf_info.vx_opt[i].zhu_weight, - conf_info.vx_opt[i].beta_value); + conf_info.vx_opt[i].beta_value_fx((double) (grid.nx()*grid.ny()))); // Compute DMAP statistics dmap_info.set(conf_info.vx_opt[i].fcat_ta[k], 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 0dc8fcd301..4db0bf356b 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 @@ -533,7 +533,7 @@ void GridStatVxOpt::clear() { baddeley_max_dist = bad_data_double; fom_alpha = bad_data_double; zhu_weight = bad_data_double; - beta_value = bad_data_double; + beta_value_fx.clear(); hss_ec_value = bad_data_double; rank_corr_flag = false; @@ -817,11 +817,11 @@ void GridStatVxOpt::process_config( exit(1); } - beta_value = d->lookup_double(conf_key_beta_value); - if(!is_bad_data(beta_value) && beta_value <=0) { + beta_value_fx.set(d->lookup(conf_key_beta_value)); + if(!beta_value_fx.is_set()) { mlog << Error << "\nGridStatVxOpt::process_config() -> " - << "The \"" << conf_key_beta_value << "\" option (" - << beta_value << ") must be set > 0.\n\n"; + << "The \"" << conf_key_beta_value + << "\" function is not set!\n\n"; exit(1); } 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 d72e33dbfd..73bc476124 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 @@ -187,7 +187,7 @@ class GridStatVxOpt { double baddeley_max_dist; // Maximum distance constant double fom_alpha; // FOM Alpha double zhu_weight; // Zhu Weight - double beta_value; // G-Beta Value + UserFunc_1Arg beta_value_fx; // G-Beta Value Function double hss_ec_value; // MCTS HSS expected correct value bool rank_corr_flag; // Flag for computing rank correlations diff --git a/test/config/GridStatConfig_APCP_regrid b/test/config/GridStatConfig_APCP_regrid index df9e784d7c..af00db9f28 100644 --- a/test/config/GridStatConfig_APCP_regrid +++ b/test/config/GridStatConfig_APCP_regrid @@ -150,7 +150,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GRIB_lvl_typ_val b/test/config/GridStatConfig_GRIB_lvl_typ_val index e2303e06a4..8ace03905d 100644 --- a/test/config/GridStatConfig_GRIB_lvl_typ_val +++ b/test/config/GridStatConfig_GRIB_lvl_typ_val @@ -247,7 +247,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GRIB_set_attr b/test/config/GridStatConfig_GRIB_set_attr index cb7347ca46..917a0caf66 100644 --- a/test/config/GridStatConfig_GRIB_set_attr +++ b/test/config/GridStatConfig_GRIB_set_attr @@ -179,7 +179,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GTG_latlon b/test/config/GridStatConfig_GTG_latlon index 50538cc505..36356d9b48 100644 --- a/test/config/GridStatConfig_GTG_latlon +++ b/test/config/GridStatConfig_GTG_latlon @@ -158,7 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_GTG_lc b/test/config/GridStatConfig_GTG_lc index 1ced0947af..c32de7a1b7 100644 --- a/test/config/GridStatConfig_GTG_lc +++ b/test/config/GridStatConfig_GTG_lc @@ -158,7 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_apply_mask b/test/config/GridStatConfig_apply_mask index f0baf81178..9142054e30 100644 --- a/test/config/GridStatConfig_apply_mask +++ b/test/config/GridStatConfig_apply_mask @@ -159,7 +159,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_WMO b/test/config/GridStatConfig_climo_WMO index c321eeda8c..e23f74a2be 100644 --- a/test/config/GridStatConfig_climo_WMO +++ b/test/config/GridStatConfig_climo_WMO @@ -219,7 +219,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_climo_prob b/test/config/GridStatConfig_climo_prob index a0a6985312..a97291af88 100644 --- a/test/config/GridStatConfig_climo_prob +++ b/test/config/GridStatConfig_climo_prob @@ -229,7 +229,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_fourier b/test/config/GridStatConfig_fourier index aa9adc28c3..ad8c121b23 100644 --- a/test/config/GridStatConfig_fourier +++ b/test/config/GridStatConfig_fourier @@ -185,7 +185,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_grid_weight b/test/config/GridStatConfig_grid_weight index 3a93382223..4cd850faf1 100644 --- a/test/config/GridStatConfig_grid_weight +++ b/test/config/GridStatConfig_grid_weight @@ -170,7 +170,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_interp_shape b/test/config/GridStatConfig_interp_shape index 9da6c42712..66d1658886 100644 --- a/test/config/GridStatConfig_interp_shape +++ b/test/config/GridStatConfig_interp_shape @@ -152,7 +152,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_mpr_thresh b/test/config/GridStatConfig_mpr_thresh index ecc9a1ae6d..268e24cbc6 100644 --- a/test/config/GridStatConfig_mpr_thresh +++ b/test/config/GridStatConfig_mpr_thresh @@ -217,7 +217,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_no_leap b/test/config/GridStatConfig_no_leap index e2c22b2050..b33a52c222 100644 --- a/test/config/GridStatConfig_no_leap +++ b/test/config/GridStatConfig_no_leap @@ -159,7 +159,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_prob_as_scalar b/test/config/GridStatConfig_prob_as_scalar index 0eaf736e63..8a462ce48a 100644 --- a/test/config/GridStatConfig_prob_as_scalar +++ b/test/config/GridStatConfig_prob_as_scalar @@ -180,7 +180,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_python b/test/config/GridStatConfig_python index 2a6d00cf2e..3d9059219b 100644 --- a/test/config/GridStatConfig_python +++ b/test/config/GridStatConfig_python @@ -156,7 +156,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_python_mixed b/test/config/GridStatConfig_python_mixed index 0973c96cee..9b868a2745 100644 --- a/test/config/GridStatConfig_python_mixed +++ b/test/config/GridStatConfig_python_mixed @@ -164,7 +164,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_rtma b/test/config/GridStatConfig_rtma index 7944ec7a7d..178a1269b1 100644 --- a/test/config/GridStatConfig_rtma +++ b/test/config/GridStatConfig_rtma @@ -160,7 +160,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_rtma_perc_thresh b/test/config/GridStatConfig_rtma_perc_thresh index 7658f8695c..3a739645ad 100644 --- a/test/config/GridStatConfig_rtma_perc_thresh +++ b/test/config/GridStatConfig_rtma_perc_thresh @@ -163,7 +163,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_st4 b/test/config/GridStatConfig_st4 index c4b997fb55..5f210db851 100644 --- a/test/config/GridStatConfig_st4 +++ b/test/config/GridStatConfig_st4 @@ -164,7 +164,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/GridStatConfig_st4_censor b/test/config/GridStatConfig_st4_censor index d45a2afeac..1942cfe107 100644 --- a/test/config/GridStatConfig_st4_censor +++ b/test/config/GridStatConfig_st4_censor @@ -173,7 +173,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/GridStatConfig_03h b/test/config/ref_config/GridStatConfig_03h index 3bbd17a535..dc40220c7b 100644 --- a/test/config/ref_config/GridStatConfig_03h +++ b/test/config/ref_config/GridStatConfig_03h @@ -158,7 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/config/ref_config/GridStatConfig_24h b/test/config/ref_config/GridStatConfig_24h index 7f8b7d33fe..450b7117aa 100644 --- a/test/config/ref_config/GridStatConfig_24h +++ b/test/config/ref_config/GridStatConfig_24h @@ -158,7 +158,7 @@ distance_map = { baddeley_max_dist = NA; fom_alpha = 0.1; zhu_weight = 0.5; - beta_value = NA; + beta_value(n) = n * n / 2.0; } //////////////////////////////////////////////////////////////////////////////// From d4f04e5a48e85984ee673e52e258eafbe0c255a0 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 28 Jul 2021 14:06:37 -0600 Subject: [PATCH 19/36] Per #1673, push initial appendix C updates for GBETA. --- met/docs/Users_Guide/appendixC.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 082dcc208c..87fb970cec 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1178,6 +1178,26 @@ where MED *(A,B)* is as in the Mean-error distance, *N* is the total number of g The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forecast. +:math:`G` and :math:`G_\beta` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` + +The :math:`G` measure is given by: + +.. math:: \G(A,B) = y^{1/3}, +where +.. math:: y={y_1}{y_2} +and +.. math:: y_1=n_A+n_B-2n_AB +and +.. math:: y_2=MED(A,B)*n_B+MET(B,A)*n_A + +The :math:`G_\beta` measure is given by: + +.. math:: G_\beta(A,B)=max{1-\frac{y}/\beta,0}, +where :math:`\beta > 0` is a user-chosen parameter and is configurable in the Grid-Stat configuration file. + Calculating Percentiles _______________________ From 1ca54ea5dd80608576ff3494d471241e89b76ec7 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 28 Jul 2021 14:29:05 -0600 Subject: [PATCH 20/36] Per #1673, working on G and GBETA equations. --- met/docs/Users_Guide/appendixC.rst | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 87fb970cec..19bace2e25 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1183,20 +1183,17 @@ The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forec Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` -The :math:`G` measure is given by: +Let :math:`y={y_1}{y_2}` where :math:`y_1=n_A+n_B-2n_{AB}`, and :math:`y_2=MED(A,B) \cdot n_B+MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above. -.. math:: \G(A,B) = y^{1/3}, -where -.. math:: y={y_1}{y_2} -and -.. math:: y_1=n_A+n_B-2n_AB -and -.. math:: y_2=MED(A,B)*n_B+MET(B,A)*n_A +The :math:`G` performance measure is given by: + +.. math:: G(A,B) = y^{1/3}, + +and the :math:`G_\beta` performance measure is given by: -The :math:`G_\beta` measure is given by: +.. math:: G_\beta(A,B)=max\{1-\frac{y}{\beta},0\}, -.. math:: G_\beta(A,B)=max{1-\frac{y}/\beta,0}, -where :math:`\beta > 0` is a user-chosen parameter and is configurable in the Grid-Stat configuration file. +where :math:`\beta > 0` is a user-chosen parameter with a default value of :math:`n^2 / 2.0` with :math:`n` equal to the number of points in the domain. Calculating Percentiles _______________________ From b994b67fc16f64d00b1dad55d1728259e23214ff Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 28 Jul 2021 15:01:35 -0600 Subject: [PATCH 21/36] Per #1673, working on G and GBETA equations. --- met/docs/Users_Guide/appendixC.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 19bace2e25..105e4d58d3 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1183,15 +1183,15 @@ The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forec Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` -Let :math:`y={y_1}{y_2}` where :math:`y_1=n_A+n_B-2n_{AB}`, and :math:`y_2=MED(A,B) \cdot n_B+MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above. +Let :math:`y = {y_1}{y_2}` where :math:`y_1 = n_A + n_B - 2n_{AB}`, and :math:`y_2 = MED(A,B) \cdot n_B + MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above. -The :math:`G` performance measure is given by: +The :math:`G` performance measure is given by -.. math:: G(A,B) = y^{1/3}, +.. math:: G(A,B) = y^{1/3} -and the :math:`G_\beta` performance measure is given by: +and the :math:`G_\beta` performance measure is given by -.. math:: G_\beta(A,B)=max\{1-\frac{y}{\beta},0\}, +.. math:: G_\beta(A,B) = max\{1-\frac{y}{\beta}, 0\} where :math:`\beta > 0` is a user-chosen parameter with a default value of :math:`n^2 / 2.0` with :math:`n` equal to the number of points in the domain. From 9cb4c5fcab859cbf5efaa9fa1f98ef7be83e041a Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Thu, 29 Jul 2021 15:06:39 -0600 Subject: [PATCH 22/36] Per 1673, update GBETA details in appendix C. --- met/docs/Users_Guide/appendixC.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 105e4d58d3..96ade7b949 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1183,7 +1183,7 @@ The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forec Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` -Let :math:`y = {y_1}{y_2}` where :math:`y_1 = n_A + n_B - 2n_{AB}`, and :math:`y_2 = MED(A,B) \cdot n_B + MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above. +Let :math:`y = {y_1}{y_2}` where :math:`y_1 = n_A + n_B - 2n_{AB}`, and :math:`y_2 = MED(A,B) \cdot n_B + MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above, and where :math:`n_{A}`, :math:`n_{B}`, and :math:`n_{AB}` are the number of events within event areas *A*, *B*, and the intersection of *A* and *B*, respectively. The :math:`G` performance measure is given by From 0493fc0d65830adb6c1faaecd27d24ad4c60e3f4 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Fri, 30 Jul 2021 13:55:11 -0600 Subject: [PATCH 23/36] Per #1673, add Eric's info about selecting beta. --- met/docs/Users_Guide/figure/grid-stat_fig6.png | Bin 0 -> 153718 bytes met/docs/Users_Guide/grid-stat.rst | 15 +++++++++++++++ met/docs/Users_Guide/refs.rst | 14 ++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 met/docs/Users_Guide/figure/grid-stat_fig6.png diff --git a/met/docs/Users_Guide/figure/grid-stat_fig6.png b/met/docs/Users_Guide/figure/grid-stat_fig6.png new file mode 100644 index 0000000000000000000000000000000000000000..e0916152f709d4a28005cff941aa855c0429a191 GIT binary patch literal 153718 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 y)1HZ(p%5C;( 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%0D*^h)WI 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. For each combination of input field and categorical threshold requested in the configuration file, Grid-Stat applies that threshold to define events in the forecast and observation fields and computes distance maps for those binary fields. Statistics for all requested masking regions are derived from those distance maps. Note that the distance maps are computed only once over the full verification domain, not separately for each masking region. Events occurring outside of a masking region can affect the distance map values inside that masking region and, therefore, can also affect the distance maps statistics for that region. +Selecting :math:`\beta` for :math:`G_\beta` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :math:`G_\beta` statistic provides a summary measure of forecast quality for each user-defined threshold chosen. Its value ranges from 0 to 1, with 1 being a perfect score. It is sensitive to the choice of :math:`\beta`, which depends on the (i) specific domain, (ii) variable, and (iii) user’s needs. Smaller values make :math:`G_\beta` more stringent and larger values make it more lenient. :numref:`grid-stat_fig6` shows an example of applying :math:`G_\beta` over a range of thresholds to a precipitation verification set where the binary fields are created by applying a threshold of :math:`2.1 mmh^{-1}`. Color choice and human bias can make it difficult to determine the quality of the forecast for a human observer looking at the raw images in the top row of the figure (:ref:`Ahijevych et al., 2009 `). The bottom left panel of the figure displays the differences in their binary fields, which highlights that the forecast captured the overall shapes of the observed rain areas but suffers from a spatial displacement error (perhaps really a timing error). + +Whether or not the forecast from :numref:`grid-stat_fig6` is “good” or not depends on the specific user. Is it sufficient that the forecast came as close as it did to the observation field? If the answer is yes for the user, then a higher choice of :math:`\beta`, such as :math:`N/2`, with :math:`N` equal the number of points in the domain, will correctly inform this user that it is a “good” forecast as it will lead to a :math:`G_\beta` value near one. If the user requires the forecast to be much better aligned spatially with the observation field, then a lower choice, perhaps :math:`\beta = N`, will correctly inform that the forecast suffers from spatial displacement errors that are too large for this user to be pleased. If the goal is to rank a series of ensemble forecasts, for example, then a choice of :math:`\beta` that falls in the steep part of the curve shown in the lower right panel of the figure should be preferred, say somewhere between :math:`\beta = N` and :math:`\beta = N^2/2`. Such a choice will ensure that each member is differentiated by the measure. + +.. _grid-stat_fig6: + +.. figure:: figure/grid-stat_fig6.png + + Top left is an example of an accumulated precipitation (mm/h) forecast with the corresponding observed field on the top right. Bottom left shows the difference in binary fields, where the binary fields are created by setting all values in the original fields that fall above :math:`2.1 mmh^{-1}` to one and the rest to zero. Bottom right shows the results for :math:`G_\beta` over a range of choices for :math:`\beta`. + +In some cases, a user may be interested in a much higher threshold than :math:`2.1 mmh^{-1}` of the above example. :ref:`Gilleland, 2021 (Fig. 4) `, for example, shows this same forecast using a threshold of :math:`40 mmh^{-1}`. Only a small area in Mississippi has such extreme rain predicted at this valid time; yet none was observed. Small spatial areas of extreme rain in the observed field, however, did occur in a location far away from Mississippi that was not predicted. Generally, for this type of verification, the Hausdorff metric is a good choice of measure. However, a small choice of :math:`\beta` will provide similar results as the Hausdorff distance (:ref:`Gilleland, 2021 `). The user should think about the average size of storm areas and multiply this value by the displacement distance they are comfortable with in order to get a good initial choice for :math:`\beta`, and may have to increase or decrease its value by trial-and-error using one or two example cases from their verification set. + Practical information _____________________ diff --git a/met/docs/Users_Guide/refs.rst b/met/docs/Users_Guide/refs.rst index a58ddf8dda..493a6c9a38 100644 --- a/met/docs/Users_Guide/refs.rst +++ b/met/docs/Users_Guide/refs.rst @@ -9,6 +9,13 @@ References | Atlantic Basin. *Weather & Forecasting*, 13, 1005-1015. | +.. _Ahijevych-2009: + +| Ahijevych, D., E. Gilleland, B.G. Brown, and E.E. Ebert, 2009. Application of +| spatial verification methods to idealized and NWP-gridded precipitation forecasts. +| Weather Forecast., 24 (6), 1485 - 1497, doi: 10.1175/2009WAF2222298.1. +| + .. _Barker-1991: @@ -117,6 +124,13 @@ References | Oceanic Technology on 2 December 2019. Re-submitted on 12 May 2020 | +.. _Gilleland-2021: + +| Gilleland, E., 2021. Novel measures for summarizing high-resolution forecast +| performance. Advances in Statistical Climatology, Meteorology and Oceanography, +| 7 (1), 13 - 34, doi: 10.5194/ascmo-7-13-2021. +| + .. _Gneiting-2004: | Gneiting, T., A. Westveld, A. Raferty, and T. Goldman, 2004: *Calibrated* From af8dc4bc45bfa9509e488dae33303d9d723e7cb8 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 2 Aug 2021 11:30:08 -0600 Subject: [PATCH 24/36] Per #1673, update reference for Gilleland-2019 to Gilleland_PartI-2020 and Gilleland_PartII-2020. --- met/docs/Users_Guide/appendixC.rst | 2 +- met/docs/Users_Guide/refs.rst | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 96ade7b949..1adefc5cec 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1107,7 +1107,7 @@ A mathematical metric, :math:`m(A,B)\geq 0`, must have the following three prope The first establishes that a perfect score is zero and that the only way to obtain a perfect score is if the two sets are identical according to the metric. The second requirement ensures that the order by which the two sets are evaluated will not change the result. The third property ensures that if *C* is closer to *A* than *B* is to *A*, then :math:`m(A,C) < m(A,B)`. -It has been argued in :ref:`Gilleland (2019) ` that the second property of symmetry is not necessarily an important quality to have for a summary measure for verification purposes because lack of symmetry allows for information about false alarms and misses. +It has been argued in :ref:`Gilleland, Part II (2020) ` that the second property of symmetry is not necessarily an important quality to have for a summary measure for verification purposes because lack of symmetry allows for information about false alarms and misses. 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. diff --git a/met/docs/Users_Guide/refs.rst b/met/docs/Users_Guide/refs.rst index 493a6c9a38..f50ece82ff 100644 --- a/met/docs/Users_Guide/refs.rst +++ b/met/docs/Users_Guide/refs.rst @@ -117,11 +117,19 @@ References | Gilleland, E., 2010: Confidence intervals for forecast verification. | *NCAR Technical Note* NCAR/TN-479+STR, 71pp. -.. _Gilleland-2019: +.. _Gilleland_PartI-2020: -| Gilleland, E., 2019: Bootstrap methods for statistical inference. Part II: -| Extreme-value analysis. Submitted to the Journal of Atmospheric and -| Oceanic Technology on 2 December 2019. Re-submitted on 12 May 2020 +| Gilleland, E., 2020. Bootstrap methods for statistical inference. +| Part I: Comparative forecast verification for continuous variables. +| Journal of Atmospheric and Oceanic Technology, 37 (11), 2117 - 2134, +| doi: 10.1175/JTECH-D-20-0069.1. +| + +.. _Gilleland_PartII-2020: + +| Gilleland, E., 2020. Bootstrap methods for statistical inference. +| Part II: Extreme-value analysis. Journal of Atmospheric and Oceanic +| Technology, 37 (11), 2135 - 2144, doi: 10.1175/JTECH-D-20-0070.1. | .. _Gilleland-2021: From 92168b89db9a4a2dbd09739100de46cc27ae5ebb Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 2 Aug 2021 11:40:32 -0600 Subject: [PATCH 25/36] Per 1673, fix typo. --- met/docs/Users_Guide/grid-stat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index 1dc4e8cd1b..a392a4c602 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -127,7 +127,7 @@ Selecting :math:`\beta` for :math:`G_\beta` The :math:`G_\beta` statistic provides a summary measure of forecast quality for each user-defined threshold chosen. Its value ranges from 0 to 1, with 1 being a perfect score. It is sensitive to the choice of :math:`\beta`, which depends on the (i) specific domain, (ii) variable, and (iii) user’s needs. Smaller values make :math:`G_\beta` more stringent and larger values make it more lenient. :numref:`grid-stat_fig6` shows an example of applying :math:`G_\beta` over a range of thresholds to a precipitation verification set where the binary fields are created by applying a threshold of :math:`2.1 mmh^{-1}`. Color choice and human bias can make it difficult to determine the quality of the forecast for a human observer looking at the raw images in the top row of the figure (:ref:`Ahijevych et al., 2009 `). The bottom left panel of the figure displays the differences in their binary fields, which highlights that the forecast captured the overall shapes of the observed rain areas but suffers from a spatial displacement error (perhaps really a timing error). -Whether or not the forecast from :numref:`grid-stat_fig6` is “good” or not depends on the specific user. Is it sufficient that the forecast came as close as it did to the observation field? If the answer is yes for the user, then a higher choice of :math:`\beta`, such as :math:`N/2`, with :math:`N` equal the number of points in the domain, will correctly inform this user that it is a “good” forecast as it will lead to a :math:`G_\beta` value near one. If the user requires the forecast to be much better aligned spatially with the observation field, then a lower choice, perhaps :math:`\beta = N`, will correctly inform that the forecast suffers from spatial displacement errors that are too large for this user to be pleased. If the goal is to rank a series of ensemble forecasts, for example, then a choice of :math:`\beta` that falls in the steep part of the curve shown in the lower right panel of the figure should be preferred, say somewhere between :math:`\beta = N` and :math:`\beta = N^2/2`. Such a choice will ensure that each member is differentiated by the measure. +Whether or not the forecast from :numref:`grid-stat_fig6` is “good” or not depends on the specific user. Is it sufficient that the forecast came as close as it did to the observation field? If the answer is yes for the user, then a higher choice of :math:`\beta`, such as :math:`N/2`, with :math:`N` equal to the number of points in the domain, will correctly inform this user that it is a “good” forecast as it will lead to a :math:`G_\beta` value near one. If the user requires the forecast to be much better aligned spatially with the observation field, then a lower choice, perhaps :math:`\beta = N`, will correctly inform that the forecast suffers from spatial displacement errors that are too large for this user to be pleased. If the goal is to rank a series of ensemble forecasts, for example, then a choice of :math:`\beta` that falls in the steep part of the curve shown in the lower right panel of the figure should be preferred, say somewhere between :math:`\beta = N` and :math:`\beta = N^2/2`. Such a choice will ensure that each member is differentiated by the measure. .. _grid-stat_fig6: From e64b74e3ba3715cdc4385cbda5eca5a8df67bca0 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 2 Aug 2021 13:14:04 -0600 Subject: [PATCH 26/36] Per #1673, making changes requested by Eric. --- met/docs/Users_Guide/appendixC.rst | 7 ++++++- met/docs/Users_Guide/grid-stat.rst | 14 ++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 1adefc5cec..b9da4f2b9d 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1178,10 +1178,13 @@ where MED *(A,B)* is as in the Mean-error distance, *N* is the total number of g The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forecast. +.. _App_C-gbeta: + :math:`G` and :math:`G_\beta` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` +See :numref:`grid-stat_gbeta` for a description of these statistics. Let :math:`y = {y_1}{y_2}` where :math:`y_1 = n_A + n_B - 2n_{AB}`, and :math:`y_2 = MED(A,B) \cdot n_B + MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above, and where :math:`n_{A}`, :math:`n_{B}`, and :math:`n_{AB}` are the number of events within event areas *A*, *B*, and the intersection of *A* and *B*, respectively. @@ -1193,7 +1196,9 @@ and the :math:`G_\beta` performance measure is given by .. math:: G_\beta(A,B) = max\{1-\frac{y}{\beta}, 0\} -where :math:`\beta > 0` is a user-chosen parameter with a default value of :math:`n^2 / 2.0` with :math:`n` equal to the number of points in the domain. +where :math:`\beta > 0` is a user-chosen parameter with a default value of :math:`n^2 / 2.0` with :math:`n` equal to the number of points in the domain. The square-root of :math:`G` will give units of grid points, where :math:`y^{1/3}` gives units of grid points squared. + +The range for :math:`G_\beta` is 0 to 1, with a score of 1 indicating a perfect forecast. Calculating Percentiles _______________________ diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index a392a4c602..f85cc964c8 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -122,10 +122,16 @@ While :numref:`grid-stat_fig1` and :numref:`grid-stat_fig2` are helpful in illus The statistics derived from these distance maps are described in :numref:`Appendix C, Section %s `. For each combination of input field and categorical threshold requested in the configuration file, Grid-Stat applies that threshold to define events in the forecast and observation fields and computes distance maps for those binary fields. Statistics for all requested masking regions are derived from those distance maps. Note that the distance maps are computed only once over the full verification domain, not separately for each masking region. Events occurring outside of a masking region can affect the distance map values inside that masking region and, therefore, can also affect the distance maps statistics for that region. -Selecting :math:`\beta` for :math:`G_\beta` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _grid-stat_gbeta: -The :math:`G_\beta` statistic provides a summary measure of forecast quality for each user-defined threshold chosen. Its value ranges from 0 to 1, with 1 being a perfect score. It is sensitive to the choice of :math:`\beta`, which depends on the (i) specific domain, (ii) variable, and (iii) user’s needs. Smaller values make :math:`G_\beta` more stringent and larger values make it more lenient. :numref:`grid-stat_fig6` shows an example of applying :math:`G_\beta` over a range of thresholds to a precipitation verification set where the binary fields are created by applying a threshold of :math:`2.1 mmh^{-1}`. Color choice and human bias can make it difficult to determine the quality of the forecast for a human observer looking at the raw images in the top row of the figure (:ref:`Ahijevych et al., 2009 `). The bottom left panel of the figure displays the differences in their binary fields, which highlights that the forecast captured the overall shapes of the observed rain areas but suffers from a spatial displacement error (perhaps really a timing error). +:math:`\beta` and :math:`G_\beta` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See :numref:`App_C-gbeta` for the equations for :math:`G` and :math:`G_\beta`. + +:math:`G_\beta` provides a summary measure of forecast quality for each user-defined threshold chosen. It falls into a range from zero to one where one is a perfect forecast and zero is considered to be a very poor forecast as determined by the user through the value of :math:`\beta`. Values of :math:`G_\beta` closer to one represent better forecasts and worse forecasts as it decreases toward zero. Although a particular value cannot be universally compared against any forecast, when applied with the same choice of :math:`\beta` for the same variable and on the same domain, it is highly effective at ranking such forecasts. + +:math:`G_\beta` is sensitive to the choice of :math:`\beta`, which depends on the (i) specific domain, (ii) variable, and (iii) user’s needs. Smaller values make :math:`G_\beta` more stringent and larger values make it more lenient. :numref:`grid-stat_fig6` shows an example of applying :math:`G_\beta` over a range of :math:`\beta` values to a precipitation verification set where the binary fields are created by applying a threshold of :math:`2.1 mmh^{-1}`. Color choice and human bias can make it difficult to determine the quality of the forecast for a human observer looking at the raw images in the top row of the figure (:ref:`Ahijevych et al., 2009 `). The bottom left panel of the figure displays the differences in their binary fields, which highlights that the forecast captured the overall shapes of the observed rain areas but suffers from a spatial displacement error (perhaps really a timing error). Whether or not the forecast from :numref:`grid-stat_fig6` is “good” or not depends on the specific user. Is it sufficient that the forecast came as close as it did to the observation field? If the answer is yes for the user, then a higher choice of :math:`\beta`, such as :math:`N/2`, with :math:`N` equal to the number of points in the domain, will correctly inform this user that it is a “good” forecast as it will lead to a :math:`G_\beta` value near one. If the user requires the forecast to be much better aligned spatially with the observation field, then a lower choice, perhaps :math:`\beta = N`, will correctly inform that the forecast suffers from spatial displacement errors that are too large for this user to be pleased. If the goal is to rank a series of ensemble forecasts, for example, then a choice of :math:`\beta` that falls in the steep part of the curve shown in the lower right panel of the figure should be preferred, say somewhere between :math:`\beta = N` and :math:`\beta = N^2/2`. Such a choice will ensure that each member is differentiated by the measure. @@ -133,7 +139,7 @@ Whether or not the forecast from :numref:`grid-stat_fig6` is “good” or not d .. figure:: figure/grid-stat_fig6.png - Top left is an example of an accumulated precipitation (mm/h) forecast with the corresponding observed field on the top right. Bottom left shows the difference in binary fields, where the binary fields are created by setting all values in the original fields that fall above :math:`2.1 mmh^{-1}` to one and the rest to zero. Bottom right shows the results for :math:`G_\beta` over a range of choices for :math:`\beta`. + Top left is an example of an accumulated precipitation (mm/h) forecast with the corresponding observed field on the top right. Bottom left shows the difference in binary fields, where the binary fields are created by setting all values in the original fields that fall above :math:`2.1 mmh^{-1}` to one and the rest to zero. Bottom right shows the results for :math:`G_\beta` calculated on the binary fields using the threshold of :math:`2.1 mmh^{-1}` over a range of choices for :math:`\beta`. In some cases, a user may be interested in a much higher threshold than :math:`2.1 mmh^{-1}` of the above example. :ref:`Gilleland, 2021 (Fig. 4) `, for example, shows this same forecast using a threshold of :math:`40 mmh^{-1}`. Only a small area in Mississippi has such extreme rain predicted at this valid time; yet none was observed. Small spatial areas of extreme rain in the observed field, however, did occur in a location far away from Mississippi that was not predicted. Generally, for this type of verification, the Hausdorff metric is a good choice of measure. However, a small choice of :math:`\beta` will provide similar results as the Hausdorff distance (:ref:`Gilleland, 2021 `). The user should think about the average size of storm areas and multiply this value by the displacement distance they are comfortable with in order to get a good initial choice for :math:`\beta`, and may have to increase or decrease its value by trial-and-error using one or two example cases from their verification set. From a34c89f8e25fb40f6ce7aacc93d4a7fa7626d548 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 2 Aug 2021 13:17:14 -0600 Subject: [PATCH 27/36] Per #1673, making changes requested by Eric. --- met/docs/Users_Guide/appendixC.rst | 3 ++- met/docs/Users_Guide/grid-stat.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index b9da4f2b9d..0feeff67e1 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1184,7 +1184,8 @@ The range for ZHU is 0 to infinity, with a score of 0 indicating a perfect forec ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Called "G" and "GBETA" in the DMAP output :numref:`table_GS_format_info_DMAP` -See :numref:`grid-stat_gbeta` for a description of these statistics. + +See :numref:`grid-stat_gbeta` for a description. Let :math:`y = {y_1}{y_2}` where :math:`y_1 = n_A + n_B - 2n_{AB}`, and :math:`y_2 = MED(A,B) \cdot n_B + MED(B,A) \cdot n_A`, with the mean-error distance (:math:`MED`) as described above, and where :math:`n_{A}`, :math:`n_{B}`, and :math:`n_{AB}` are the number of events within event areas *A*, *B*, and the intersection of *A* and *B*, respectively. diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index f85cc964c8..b5eeb5afed 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -127,7 +127,7 @@ The statistics derived from these distance maps are described in :numref:`Append :math:`\beta` and :math:`G_\beta` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See :numref:`App_C-gbeta` for the equations for :math:`G` and :math:`G_\beta`. +See :numref:`App_C-gbeta` for the :math:`G` and :math:`G_\beta` equations. :math:`G_\beta` provides a summary measure of forecast quality for each user-defined threshold chosen. It falls into a range from zero to one where one is a perfect forecast and zero is considered to be a very poor forecast as determined by the user through the value of :math:`\beta`. Values of :math:`G_\beta` closer to one represent better forecasts and worse forecasts as it decreases toward zero. Although a particular value cannot be universally compared against any forecast, when applied with the same choice of :math:`\beta` for the same variable and on the same domain, it is highly effective at ranking such forecasts. From fab997b3a5b08bb07eb8fa86b204649071b74901 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 2 Aug 2021 15:50:50 -0600 Subject: [PATCH 28/36] Per #1673, update references based on Eric's feedback. --- met/docs/Users_Guide/appendixC.rst | 2 +- met/docs/Users_Guide/refs.rst | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/appendixC.rst b/met/docs/Users_Guide/appendixC.rst index 0feeff67e1..88c865171c 100644 --- a/met/docs/Users_Guide/appendixC.rst +++ b/met/docs/Users_Guide/appendixC.rst @@ -1107,7 +1107,7 @@ A mathematical metric, :math:`m(A,B)\geq 0`, must have the following three prope The first establishes that a perfect score is zero and that the only way to obtain a perfect score is if the two sets are identical according to the metric. The second requirement ensures that the order by which the two sets are evaluated will not change the result. The third property ensures that if *C* is closer to *A* than *B* is to *A*, then :math:`m(A,C) < m(A,B)`. -It has been argued in :ref:`Gilleland, Part II (2020) ` that the second property of symmetry is not necessarily an important quality to have for a summary measure for verification purposes because lack of symmetry allows for information about false alarms and misses. +It has been argued in :ref:`Gilleland (2017) ` that the second property of symmetry is not necessarily an important quality to have for a summary measure for verification purposes because lack of symmetry allows for information about false alarms and misses. 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. diff --git a/met/docs/Users_Guide/refs.rst b/met/docs/Users_Guide/refs.rst index f50ece82ff..543274ef0e 100644 --- a/met/docs/Users_Guide/refs.rst +++ b/met/docs/Users_Guide/refs.rst @@ -116,6 +116,15 @@ References | Gilleland, E., 2010: Confidence intervals for forecast verification. | *NCAR Technical Note* NCAR/TN-479+STR, 71pp. +| + +.. _Gilleland-2017: + +| Gilleland, E., 2017. A new characterization in the spatial verification +| framework for false alarms, misses, and overall patterns. +| Weather Forecast., 32 (1), 187 - 198, doi: 10.1175/WAF-D-16-0134.1. +| + .. _Gilleland_PartI-2020: From 63fac37ca5a7f22cacd9c33efc1a915452dc7020 Mon Sep 17 00:00:00 2001 From: ericgilleland <34106925+ericgilleland@users.noreply.github.com> Date: Tue, 3 Aug 2021 13:08:31 -0600 Subject: [PATCH 29/36] Update appendixD.rst (#1869) Updated this appendix. --- met/docs/Users_Guide/appendixD.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/appendixD.rst b/met/docs/Users_Guide/appendixD.rst index a90c71b620..83c8ac2126 100644 --- a/met/docs/Users_Guide/appendixD.rst +++ b/met/docs/Users_Guide/appendixD.rst @@ -77,8 +77,9 @@ All other verification scores with CIs in MET must be obtained through bootstrap 5. Calculate CIs for the parameters directly from the sample (see text below for more details) -Typically, a simple random sample is taken for step 2, and that is how it is done in MET. As an example of what happens in this step, suppose our sample is :math:`X_1,X_2,X_3,X_4`. Then, one possible replicate might be :math:`X_2,X_2,X_2,X_4`. Usually one samples :math:`m = n` points in this step, but there are cases where one should use :math:`m < n`. For example, when the underlying distribution is heavy-tailed, one should use a smaller size m than n (e.g., the closest integer value to the square root of the original sample size). +Typically, a simple random sample is taken for step 2, and that is how it is done in MET. As an example of what happens in this step, suppose our sample is :math:`X_1,X_2,X_3,X_4`. Then, one possible replicate might be :math:`X_2,X_2,X_2,X_4`. Usually one samples :math:`m = n` points in this step, but there are cases where one should use :math:`m < n`. For example, when the underlying distribution is heavy-tailed, one should use a smaller size m than n (e.g., the closest integer value to the square root of the original sample size). See :ref: `Gilleland (2020 part II) ` for considerably more information about the issues with estimators that follow a heavy tailed distribution and the closely related issue of bootstrapping extreme-valued estimators, such as the maximum, in the atmospheric science domain. There are numerous ways to construct CIs from the sample obtained in step 4. MET allows for two of these procedures: the percentile and the BCa. The percentile is the most commonly known method, and the simplest to understand. It is merely the :math:`\alpha / 2` and :math:`1 - \alpha / 2` percentiles from the sample of statistics. Unfortunately, however, it has been shown that this interval is too optimistic in practice (i.e., it doesn't have accurate coverage). One solution is to use the BCa method, which is very accurate, but it is also computationally intensive. This method adjusts for bias and non-constant variance, and yields the percentile interval in the event that the sample is unbiased with constant variance. -If there is dependency in the sample, then it is prudent to account for this dependency in some way. One method that does not make a lot of assumptions is circular block bootstrapping. This is not currently implemented in MET, but will be available in a future release. At that time, the method will be explained more fully here, but until then consult :ref:`Gilleland (2010) ` for more details. +If there is dependency in the sample, then it is prudent to account for this dependency in some way. :ref:`Gilleland (2010) ` describes the bootstrap procedure, along with the above-mentioned parametric methods, in more detail specifically for the verification application. If there is dependency in the sample, then it is prudent to account for this dependency in some way (see :ref:`Gilleland (2020) ` part I for an in-depth discussion of bootstrapping in the competing forecast verification domain). One method that is particularly appropriate for serially dependent data is the circular block resampling procedure for step 2. + From 0c902857f883dc339c4f92c9df5417e0286aefce Mon Sep 17 00:00:00 2001 From: johnhg Date: Tue, 3 Aug 2021 13:16:29 -0600 Subject: [PATCH 30/36] Update appendixD.rst --- met/docs/Users_Guide/appendixD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/docs/Users_Guide/appendixD.rst b/met/docs/Users_Guide/appendixD.rst index 83c8ac2126..2c370817a2 100644 --- a/met/docs/Users_Guide/appendixD.rst +++ b/met/docs/Users_Guide/appendixD.rst @@ -77,7 +77,7 @@ All other verification scores with CIs in MET must be obtained through bootstrap 5. Calculate CIs for the parameters directly from the sample (see text below for more details) -Typically, a simple random sample is taken for step 2, and that is how it is done in MET. As an example of what happens in this step, suppose our sample is :math:`X_1,X_2,X_3,X_4`. Then, one possible replicate might be :math:`X_2,X_2,X_2,X_4`. Usually one samples :math:`m = n` points in this step, but there are cases where one should use :math:`m < n`. For example, when the underlying distribution is heavy-tailed, one should use a smaller size m than n (e.g., the closest integer value to the square root of the original sample size). See :ref: `Gilleland (2020 part II) ` for considerably more information about the issues with estimators that follow a heavy tailed distribution and the closely related issue of bootstrapping extreme-valued estimators, such as the maximum, in the atmospheric science domain. +Typically, a simple random sample is taken for step 2, and that is how it is done in MET. As an example of what happens in this step, suppose our sample is :math:`X_1,X_2,X_3,X_4`. Then, one possible replicate might be :math:`X_2,X_2,X_2,X_4`. Usually one samples :math:`m = n` points in this step, but there are cases where one should use :math:`m < n`. For example, when the underlying distribution is heavy-tailed, one should use a smaller size m than n (e.g., the closest integer value to the square root of the original sample size). See :ref:`Gilleland (2020 part II) ` for considerably more information about the issues with estimators that follow a heavy tailed distribution and the closely related issue of bootstrapping extreme-valued estimators, such as the maximum, in the atmospheric science domain. There are numerous ways to construct CIs from the sample obtained in step 4. MET allows for two of these procedures: the percentile and the BCa. The percentile is the most commonly known method, and the simplest to understand. It is merely the :math:`\alpha / 2` and :math:`1 - \alpha / 2` percentiles from the sample of statistics. Unfortunately, however, it has been shown that this interval is too optimistic in practice (i.e., it doesn't have accurate coverage). One solution is to use the BCa method, which is very accurate, but it is also computationally intensive. This method adjusts for bias and non-constant variance, and yields the percentile interval in the event that the sample is unbiased with constant variance. From ee11fc1d24620cb5729926c8510ee88741c6bc52 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 4 Aug 2021 10:20:38 -0600 Subject: [PATCH 31/36] Per #1673, making the formatting of Gilleland-2020 part I and II references consistent. --- met/docs/Users_Guide/appendixD.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/appendixD.rst b/met/docs/Users_Guide/appendixD.rst index 2c370817a2..66c578e91a 100644 --- a/met/docs/Users_Guide/appendixD.rst +++ b/met/docs/Users_Guide/appendixD.rst @@ -77,9 +77,9 @@ All other verification scores with CIs in MET must be obtained through bootstrap 5. Calculate CIs for the parameters directly from the sample (see text below for more details) -Typically, a simple random sample is taken for step 2, and that is how it is done in MET. As an example of what happens in this step, suppose our sample is :math:`X_1,X_2,X_3,X_4`. Then, one possible replicate might be :math:`X_2,X_2,X_2,X_4`. Usually one samples :math:`m = n` points in this step, but there are cases where one should use :math:`m < n`. For example, when the underlying distribution is heavy-tailed, one should use a smaller size m than n (e.g., the closest integer value to the square root of the original sample size). See :ref:`Gilleland (2020 part II) ` for considerably more information about the issues with estimators that follow a heavy tailed distribution and the closely related issue of bootstrapping extreme-valued estimators, such as the maximum, in the atmospheric science domain. +Typically, a simple random sample is taken for step 2, and that is how it is done in MET. As an example of what happens in this step, suppose our sample is :math:`X_1,X_2,X_3,X_4`. Then, one possible replicate might be :math:`X_2,X_2,X_2,X_4`. Usually one samples :math:`m = n` points in this step, but there are cases where one should use :math:`m < n`. For example, when the underlying distribution is heavy-tailed, one should use a smaller size m than n (e.g., the closest integer value to the square root of the original sample size). See :ref:`Gilleland (2020, part II) ` for considerably more information about the issues with estimators that follow a heavy tailed distribution and the closely related issue of bootstrapping extreme-valued estimators, such as the maximum, in the atmospheric science domain. There are numerous ways to construct CIs from the sample obtained in step 4. MET allows for two of these procedures: the percentile and the BCa. The percentile is the most commonly known method, and the simplest to understand. It is merely the :math:`\alpha / 2` and :math:`1 - \alpha / 2` percentiles from the sample of statistics. Unfortunately, however, it has been shown that this interval is too optimistic in practice (i.e., it doesn't have accurate coverage). One solution is to use the BCa method, which is very accurate, but it is also computationally intensive. This method adjusts for bias and non-constant variance, and yields the percentile interval in the event that the sample is unbiased with constant variance. -If there is dependency in the sample, then it is prudent to account for this dependency in some way. :ref:`Gilleland (2010) ` describes the bootstrap procedure, along with the above-mentioned parametric methods, in more detail specifically for the verification application. If there is dependency in the sample, then it is prudent to account for this dependency in some way (see :ref:`Gilleland (2020) ` part I for an in-depth discussion of bootstrapping in the competing forecast verification domain). One method that is particularly appropriate for serially dependent data is the circular block resampling procedure for step 2. +If there is dependency in the sample, then it is prudent to account for this dependency in some way. :ref:`Gilleland (2010) ` describes the bootstrap procedure, along with the above-mentioned parametric methods, in more detail specifically for the verification application. If there is dependency in the sample, then it is prudent to account for this dependency in some way (see :ref:`Gilleland (2020, part I) ` part I for an in-depth discussion of bootstrapping in the competing forecast verification domain). One method that is particularly appropriate for serially dependent data is the circular block resampling procedure for step 2. From 22e2da84b78d3c49a8ef0a1a528ed5c08a2206f9 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 4 Aug 2021 13:22:25 -0600 Subject: [PATCH 32/36] Per #1673, update Grid-Stat docs to clarify that GBETA is only computed on the FULL verification domain and not any masking regions. --- met/docs/Users_Guide/grid-stat.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/met/docs/Users_Guide/grid-stat.rst b/met/docs/Users_Guide/grid-stat.rst index b5eeb5afed..264903825f 100644 --- a/met/docs/Users_Guide/grid-stat.rst +++ b/met/docs/Users_Guide/grid-stat.rst @@ -120,7 +120,7 @@ While :numref:`grid-stat_fig1` and :numref:`grid-stat_fig2` are helpful in illus The absolute difference between the distance maps in the bottom row of :numref:`grid-stat_fig3` (top left), the shortest distances from every grid point in B to the nearest grid point in A (top right), and the shortest distances from every grid point in A to the nearest grid points in B (bottom left). The latter two do not have axes in order to emphasize that the distances are now only considered from within the respective event sets. The top right graphic is the distance map of A conditioned on the presence of an event from B, and that in the bottom left is the distance map of B conditioned on the presence of an event from A. -The statistics derived from these distance maps are described in :numref:`Appendix C, Section %s `. For each combination of input field and categorical threshold requested in the configuration file, Grid-Stat applies that threshold to define events in the forecast and observation fields and computes distance maps for those binary fields. Statistics for all requested masking regions are derived from those distance maps. Note that the distance maps are computed only once over the full verification domain, not separately for each masking region. Events occurring outside of a masking region can affect the distance map values inside that masking region and, therefore, can also affect the distance maps statistics for that region. +The statistics derived from these distance maps are described in :numref:`Appendix C, Section %s `. To make fair comparisons, any grid point containing bad data in either the forecast or observation field is set to bad data in both fields. For each combination of input field and categorical threshold requested in the configuration file, Grid-Stat applies that threshold to define events in the forecast and observation fields and computes distance maps for those binary fields. Statistics for all requested masking regions are derived from those distance maps. Note that the distance maps are computed only once over the full verification domain, not separately for each masking region. Events occurring outside of a masking region can affect the distance map values inside that masking region and, therefore, can also affect the distance maps statistics for that region. .. _grid-stat_gbeta: @@ -143,6 +143,8 @@ Whether or not the forecast from :numref:`grid-stat_fig6` is “good” or not d In some cases, a user may be interested in a much higher threshold than :math:`2.1 mmh^{-1}` of the above example. :ref:`Gilleland, 2021 (Fig. 4) `, for example, shows this same forecast using a threshold of :math:`40 mmh^{-1}`. Only a small area in Mississippi has such extreme rain predicted at this valid time; yet none was observed. Small spatial areas of extreme rain in the observed field, however, did occur in a location far away from Mississippi that was not predicted. Generally, for this type of verification, the Hausdorff metric is a good choice of measure. However, a small choice of :math:`\beta` will provide similar results as the Hausdorff distance (:ref:`Gilleland, 2021 `). The user should think about the average size of storm areas and multiply this value by the displacement distance they are comfortable with in order to get a good initial choice for :math:`\beta`, and may have to increase or decrease its value by trial-and-error using one or two example cases from their verification set. +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 _____________________ @@ -332,7 +334,7 @@ ____________________ beta_value(n) = n * n / 2.0; } -The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is defined as a function of n, where n is the total number of grid points in the domain (i.e. Nx * Ny). The resulting beta_value is used to compute the :math:`G_\beta` statistic. The default function, :math:`N^2 / 2`, is recommended in published literature but can be modified as needed. +The **distance_map** entry is a dictionary containing options related to the distance map statistics in the **DMAP** output line type. The **baddeley_p** entry is an integer specifying the exponent used in the Lp-norm when computing the Baddeley :math:`\Delta` metric. The **baddeley_max_dist** entry is a floating point number specifying the maximum allowable distance for each distance map. Any distances larger than this number will be reset to this constant. A value of **NA** indicates that no maximum distance value should be used. The **fom_alpha** entry is a floating point number specifying the scaling constant to be used when computing Pratt's Figure of Merit. The **zhu_weight** specifies a value between 0 and 1 to define the importance of the RMSE of the binary fields (i.e. amount of overlap) versus the mean-error distance (MED). The default value of 0.5 gives equal weighting. This configuration option may be set separately in each **obs.field** entry. The **beta_value** entry is defined as a function of n, where n is the total number of grid points in the full verification domain containing valid data in both the forecast and observation fields. The resulting beta_value is used to compute the :math:`G_\beta` statistic. The default function, :math:`N^2 / 2`, is recommended in :ref:`Gilleland, 2021 ` but can be modified as needed. _____________________ From f1b1317ece04ff66f9ace416b37c57b4c2d9ec7b Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 4 Aug 2021 13:22:58 -0600 Subject: [PATCH 33/36] Per #1673, add DataPlane::n_good_data() function to return a count valid data values. --- met/src/basic/vx_util/data_plane.cc | 16 ++++++++++++++++ met/src/basic/vx_util/data_plane.h | 1 + 2 files changed, 17 insertions(+) diff --git a/met/src/basic/vx_util/data_plane.cc b/met/src/basic/vx_util/data_plane.cc index c855b2a1d5..c49c360918 100644 --- a/met/src/basic/vx_util/data_plane.cc +++ b/met/src/basic/vx_util/data_plane.cc @@ -297,6 +297,22 @@ bool DataPlane::is_all_bad_data() const { /////////////////////////////////////////////////////////////////////////////// +int DataPlane::n_good_data() const { + int j, n; + + // + // Count number of good data values + // + + for(j=0,n=0; j Date: Wed, 4 Aug 2021 13:23:55 -0600 Subject: [PATCH 34/36] Per #1673, update vx_statistics library code to only set gbeta/beta_value to bad data for sub-domains. --- met/src/libcode/vx_statistics/met_stats.cc | 15 +++++++++++++-- met/src/libcode/vx_statistics/met_stats.h | 3 ++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/met/src/libcode/vx_statistics/met_stats.cc b/met/src/libcode/vx_statistics/met_stats.cc index a1fa103d54..5bc58ee585 100644 --- a/met/src/libcode/vx_statistics/met_stats.cc +++ b/met/src/libcode/vx_statistics/met_stats.cc @@ -2756,6 +2756,7 @@ void DMAPInfo::reset_options() { fom_alpha = 0.1; // FOM Alpha zhu_weight = 0.5; // Zhu Weight beta_value = bad_data_double; // G-Beta Value + n_full_points = bad_data_int; // Number of FULL domain points return; } @@ -2965,7 +2966,15 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, double g_y2 = g_med_fo * oy + g_med_of * fy; double g_y = g_y1 * g_y2; g = pow(g_y, 1.0 / 3.0); - gbeta = max(1.0 - g_y / beta_value, 0.0); + + // Only compute GBETA over the full verification domain. + // Report bad data for masking regions. + if(total == n_full_points) { + gbeta = max(1.0 - g_y / beta_value, 0.0); + } + else { + gbeta = beta_value = bad_data_double; + } // Dump debug distance map info mlog << Debug(4) << " DMAP.Options: baddeley_p=" << baddeley_p @@ -2973,6 +2982,7 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, << ", fom_alpha=" << fom_alpha << ", zhu_weight=" << zhu_weight << ", beta_value=" << beta_value + << ", n_full_points=" << n_full_points << "\n"; mlog << Debug(4) << " DMAP: nf=" << fy << ", no=" << oy << ", nfo=" << foy << ", total=" << total @@ -2994,12 +3004,13 @@ void DMAPInfo::set(const SingleThresh &fthr, const SingleThresh &othr, void DMAPInfo::set_options(const int _baddeley_p, const double _baddeley_max_dist, const double _fom_alpha, const double _zhu_weight, - const double _beta_value) { + const double _beta_value, const int _n_full_points) { baddeley_p = _baddeley_p; baddeley_max_dist = _baddeley_max_dist; fom_alpha = _fom_alpha; zhu_weight = _zhu_weight; beta_value = _beta_value; + n_full_points = _n_full_points; } //////////////////////////////////////////////////////////////////////// diff --git a/met/src/libcode/vx_statistics/met_stats.h b/met/src/libcode/vx_statistics/met_stats.h index ccfd85782e..151fba93d1 100644 --- a/met/src/libcode/vx_statistics/met_stats.h +++ b/met/src/libcode/vx_statistics/met_stats.h @@ -607,6 +607,7 @@ class DMAPInfo { double fom_alpha; // FOM Alpha double zhu_weight; // Zhu Weight double beta_value; // G-Beta Value + int n_full_points; // Number of FULL domain points public: @@ -647,7 +648,7 @@ class DMAPInfo { void set_options(const int _baddeley_p, const double _baddeley_max_dist, const double _fom_alpha, const double _zhu_weight, - const double _beta_value); + const double _beta_value, const int _n_full_points); // Get functions double get_beta_value() const; From e299004d6cdff746d5f6091cc173084b4b24c293 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Wed, 4 Aug 2021 13:25:02 -0600 Subject: [PATCH 35/36] Per #1673, update grid_stat to mask out bad data between the fcst/obs fields before computing distance maps. This will change existing unit test results! Also store the count of valid data values in the full verification domain. --- met/src/tools/core/grid_stat/grid_stat.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/met/src/tools/core/grid_stat/grid_stat.cc b/met/src/tools/core/grid_stat/grid_stat.cc index 4c3983d5a0..f8f5740974 100644 --- a/met/src/tools/core/grid_stat/grid_stat.cc +++ b/met/src/tools/core/grid_stat/grid_stat.cc @@ -1210,6 +1210,13 @@ void process_scores() { DataPlane fcst_dp_dmap, obs_dp_dmap; pd.extend(grid.nx()*grid.ny()); + // Mask out missing data between the fields for a fair comparison + DataPlane fcst_dp_mm = fcst_dp; + DataPlane obs_dp_mm = obs_dp; + mask_bad_data(fcst_dp_mm, obs_dp_mm); + mask_bad_data(obs_dp_mm, fcst_dp_mm); + int n_good_data = obs_dp_mm.n_good_data(); + // Loop over the categorical thresholds for(k=0; k Date: Thu, 5 Aug 2021 12:43:26 -0600 Subject: [PATCH 36/36] Per #1673, since GBETA is only reported when VX_MASK = FULL, updating GridStatConfig_all to include the FULL masking region to make this example more meaningful. --- met/scripts/config/GridStatConfig_all | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/met/scripts/config/GridStatConfig_all b/met/scripts/config/GridStatConfig_all index 6e9ae9e38b..13b7f601f3 100644 --- a/met/scripts/config/GridStatConfig_all +++ b/met/scripts/config/GridStatConfig_all @@ -118,7 +118,7 @@ climo_mean = { // Verification masking regions // mask = { - grid = [ "DTC165", "DTC166" ]; + grid = [ "FULL", "DTC165", "DTC166" ]; poly = [ "${TEST_OUT_DIR}/gen_vx_mask/CONUS_poly.nc", "MET_BASE/poly/LMV.poly" ]; }