diff --git a/docs/Users_Guide/config_options.rst b/docs/Users_Guide/config_options.rst index fb6e4f47eb..5a92571886 100644 --- a/docs/Users_Guide/config_options.rst +++ b/docs/Users_Guide/config_options.rst @@ -1626,6 +1626,26 @@ The default setting is >=0.1&&<=0.85. seeps_p1_thresh = >=0.1&&<=0.85; +seeps_grid_climo_name +--------------------- + +The "seeps_grid_climo_name" option sets the location and the filename of the SEEPS climo file for the gridded data. +The default setting is the empty string. It should be configured by the user. It can be overridden by the environment variable, MET_SEEPS_GRID_CLIMO_NAME. + +.. code-block:: none + + seeps_grid_climo_name = ""; + +seeps_point_climo_name +---------------------- + +The "seeps_point_climo_name" option controls the location and the filename of the SEEPS climo file for the point data. +The default setting is the empty string which does not override the default location and name. It can be overridden by the environment variable, MET_SEEPS_POINT_CLIMO_NAME. + +.. code-block:: none + + seeps_point_climo_name = ""; + mask_missing_flag ----------------- diff --git a/docs/Users_Guide/grid-stat.rst b/docs/Users_Guide/grid-stat.rst index c09df58d54..051178cfb1 100644 --- a/docs/Users_Guide/grid-stat.rst +++ b/docs/Users_Guide/grid-stat.rst @@ -428,7 +428,7 @@ The **output_flag** array controls the type of output that the Grid-Stat tool ge Note that the first two line types are easily derived from one another. The user is free to choose which measure is most desired. The output line types are described in more detail in :numref:`grid_stat-output`. -The SEEPS climo file is not distributed with MET tools because of the file size. It should be configured by using the environment variable, MET_SEEPS_GRID_CLIMO_NAME. +The SEEPS climo file is not distributed with MET tools because of the file size. It should be configured by using the configuration file (seeps_grid_climo_name). It can be overridden by the environment variable, MET_SEEPS_GRID_CLIMO_NAME. _____________________ diff --git a/docs/Users_Guide/point-stat.rst b/docs/Users_Guide/point-stat.rst index 025b462f23..0f42d54129 100644 --- a/docs/Users_Guide/point-stat.rst +++ b/docs/Users_Guide/point-stat.rst @@ -501,7 +501,7 @@ Note that writing out matched pair data (MPR lines) for a large number of cases If all line types corresponding to a particular verification method are set to NONE, the computation of those statistics will be skipped in the code and thus make the Point-Stat tool run more efficiently. For example, if FHO, CTC, and CTS are all set to NONE, the Point-Stat tool will skip the categorical verification step. -The default SEEPS climo file exists at MET_BASE/climo/seeps/PPT24_seepsweights.nc. It can be overridden by using the environment variable, MET_SEEPS_POINT_CLIMO_NAME. +The default SEEPS climo file exists at MET_BASE/climo/seeps/PPT24_seepsweights.nc. It is configurable by using the configuration file (seeps_point_climo_name). It can be overridden by the environment variable, MET_SEEPS_POINT_CLIMO_NAME. .. _point_stat-output: diff --git a/internal/test_unit/config/GridStatConfig_SEEPS b/internal/test_unit/config/GridStatConfig_SEEPS index 8a23c76c45..51bc14e2d6 100644 --- a/internal/test_unit/config/GridStatConfig_SEEPS +++ b/internal/test_unit/config/GridStatConfig_SEEPS @@ -210,6 +210,7 @@ nc_pairs_flag = { // Threshold for SEEPS p1 (Probability of being dry) seeps_p1_thresh = ${SEEPS_P1_THRESH}; +seeps_grid_climo_name = "${SEEPS_GRID_CLIMO_NAME}"; //////////////////////////////////////////////////////////////////////////////// diff --git a/internal/test_unit/config/PointStatConfig_APCP b/internal/test_unit/config/PointStatConfig_APCP index a6a6f06d64..b1df56e94b 100644 --- a/internal/test_unit/config/PointStatConfig_APCP +++ b/internal/test_unit/config/PointStatConfig_APCP @@ -127,15 +127,10 @@ output_flag = { rps = NONE; eclv = BOTH; mpr = NONE; - seeps = ${SEEPS_FLAG}; - seeps_mpr = ${SEEPS_FLAG}; + seeps = NONE; + seeps_mpr = NONE; } -//////////////////////////////////////////////////////////////////////////////// -// Threshold for SEEPS p1 (Probability of being dry) - -seeps_p1_thresh = ${SEEPS_P1_THRESH}; - //////////////////////////////////////////////////////////////////////////////// duplicate_flag = NONE; diff --git a/internal/test_unit/config/PointStatConfig_SEEPS b/internal/test_unit/config/PointStatConfig_SEEPS new file mode 100644 index 0000000000..20ffa18cfb --- /dev/null +++ b/internal/test_unit/config/PointStatConfig_SEEPS @@ -0,0 +1,149 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Point-Stat configuration file. +// +// For additional information, please see the MET User's Guide. +// Copied from PointStatConfig_APCP +// +//////////////////////////////////////////////////////////////////////////////// + +model = "FCST"; + +// +// Output description to be written +// May be set separately in each "obs.field" entry +// +desc = "NA"; + +//////////////////////////////////////////////////////////////////////////////// + +regrid = { + to_grid = NONE; + method = NEAREST; + width = 1; +} + +//////////////////////////////////////////////////////////////////////////////// + +obs_window = { + beg = ${BEG_DS}; + end = ${END_DS}; +} + +//////////////////////////////////////////////////////////////////////////////// + +mpr_column = []; +mpr_thresh = []; +cnt_thresh = [ NA ]; +cnt_logic = UNION; +wind_thresh = [ NA ]; +wind_logic = UNION; +eclv_points = 0.05; + +cat_thresh = [ >0.254, >0.635, >1.270, >2.540 ]; +message_type = "ADPSFC"; + +fcst = { + sid_inc = []; + sid_exc = []; + obs_quality_inc = []; + obs_quality_exc = []; + + field = [ + { + name = "${FCST_FIELD_NAME}"; + level = "${FCST_FIELD_LEVEL}"; + } + ]; + +} +obs = ${OBS_DICT}; + +//////////////////////////////////////////////////////////////////////////////// + +mask = { + grid = [ "FULL" ]; + poly = []; + sid = []; + llpnt = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +ci_alpha = [ 0.05 ]; + +boot = { + interval = PCTILE; + rep_prop = 1.0; + n_rep = 0; + rng = "mt19937"; + seed = "1"; +} + +//////////////////////////////////////////////////////////////////////////////// + +interp = { + vld_thresh = 1.0; + + type = [ + { method = MEDIAN; width = 3; }, + { method = NEAREST; width = 1; }, + { method = DW_MEAN; width = [ 3, 5 ]; }, + { method = LS_FIT; width = [ 3, 5 ]; }, + { method = BILIN; width = 2; } + ]; +} + +//////////////////////////////////////////////////////////////////////////////// + +hira = { + flag = FALSE; + width = [ 2, 3, 4, 5 ]; + vld_thresh = 1.0; + cov_thresh = [ ==0.25 ]; + shape = SQUARE; + prob_cat_thresh = []; +} + +//////////////////////////////////////////////////////////////////////////////// + +output_flag = { + fho = BOTH; + ctc = BOTH; + cts = BOTH; + mctc = NONE; + mcts = NONE; + cnt = BOTH; + sl1l2 = BOTH; + sal1l2 = NONE; + vl1l2 = NONE; + val1l2 = NONE; + vcnt = NONE; + pct = NONE; + pstd = NONE; + pjc = NONE; + prc = NONE; + ecnt = NONE; + orank = NONE; + rps = NONE; + eclv = BOTH; + mpr = NONE; + seeps = BOTH; + seeps_mpr = BOTH; +} + +//////////////////////////////////////////////////////////////////////////////// +// Threshold for SEEPS p1 (Probability of being dry) + +seeps_p1_thresh = ${SEEPS_P1_THRESH}; +seeps_point_climo_name = "${SEEPS_POINT_CLIMO_NAME}"; + +//////////////////////////////////////////////////////////////////////////////// + +duplicate_flag = NONE; +rank_corr_flag = FALSE; +tmp_dir = "/tmp"; +output_prefix = "${OUTPUT_PREFIX}"; +version = "V12.0.0"; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/internal/test_unit/xml/unit_grid_stat.xml b/internal/test_unit/xml/unit_grid_stat.xml index cc24ad21d3..ad070dff60 100644 --- a/internal/test_unit/xml/unit_grid_stat.xml +++ b/internal/test_unit/xml/unit_grid_stat.xml @@ -296,7 +296,7 @@ SEEPS_FLAG BOTH SEEPS_P1_THRESH NA OUTPUT_PREFIX SEEPS - MET_SEEPS_GRID_CLIMO_NAME&DATA_DIR_CLIMO;/seeps/PPT24_seepsweights_grid.nc + SEEPS_GRID_CLIMO_NAME&DATA_DIR_CLIMO;/seeps/PPT24_seepsweights_grid.nc \ &DATA_DIR_MODEL;/seeps/gpm_2021120100_2021120200_trmmgrid.nc \ diff --git a/internal/test_unit/xml/unit_point_stat.xml b/internal/test_unit/xml/unit_point_stat.xml index aea2b8e042..2c90567c80 100644 --- a/internal/test_unit/xml/unit_point_stat.xml +++ b/internal/test_unit/xml/unit_point_stat.xml @@ -168,8 +168,6 @@ FCST_FIELD_NAME APCP FCST_FIELD_LEVEL A3 OBS_DICT fcst - SEEPS_FLAG NONE - SEEPS_P1_THRESH NA OUTPUT_PREFIX GRIB1_NAM_TRMM \ @@ -196,8 +194,6 @@ FCST_FIELD_NAME APCP FCST_FIELD_LEVEL A3 OBS_DICT fcst - SEEPS_FLAG NONE - SEEPS_P1_THRESH NA OUTPUT_PREFIX GRIB2_SREF_TRMM \ @@ -224,8 +220,6 @@ FCST_FIELD_NAME APCP_24 FCST_FIELD_LEVEL (*,*) OBS_DICT { field = [ { name = "APCP"; level = "A24"; } ]; } - SEEPS_FLAG NONE - SEEPS_P1_THRESH NA OUTPUT_PREFIX NCMET_NAM_HMTGAGE \ @@ -252,14 +246,14 @@ FCST_FIELD_NAME APCP_24 FCST_FIELD_LEVEL (*,*) OBS_DICT { field = [ { name = "TP24"; level = "L0"; is_precipitation = TRUE; } ]; } - SEEPS_FLAG BOTH SEEPS_P1_THRESH ge0.1&&le0.85 + SEEPS_POINT_CLIMO_NAME OUTPUT_PREFIX NCMET_NAM_NDAS_SEEPS \ &DATA_DIR_MODEL;/met_nc/nam/nam_2012040900_F036_APCP24.nc \ &OUTPUT_DIR;/pb2nc/ndas.20120410.t12z.prepbufr.tm00.nc \ - &CONFIG_DIR;/PointStatConfig_APCP \ + &CONFIG_DIR;/PointStatConfig_SEEPS \ -outdir &OUTPUT_DIR;/point_stat -v 1 diff --git a/src/basic/vx_config/config_constants.h b/src/basic/vx_config/config_constants.h index deb9a425fe..7640873bc3 100644 --- a/src/basic/vx_config/config_constants.h +++ b/src/basic/vx_config/config_constants.h @@ -690,7 +690,9 @@ static const char conf_key_obs_to_qc_map[] = "obs_to_qc_map"; static const char conf_key_missing_thresh[] = "missing_thresh"; static const char conf_key_control_id[] = "control_id"; static const char conf_key_ens_member_ids[] = "ens_member_ids"; -static const char conf_key_seeps_p1_thresh[] = "seeps_p1_thresh"; +static const char conf_key_seeps_grid_climo_name[] = "seeps_grid_climo_name"; +static const char conf_key_seeps_point_climo_name[] = "seeps_point_climo_name"; +static const char conf_key_seeps_p1_thresh[] = "seeps_p1_thresh"; static const char conf_key_ugrid_coordinates_file[] = "ugrid_coordinates_file"; static const char conf_key_ugrid_dataset[] = "ugrid_dataset"; static const char conf_key_ugrid_map_config[] = "ugrid_map_config"; diff --git a/src/libcode/vx_seeps/seeps.cc b/src/libcode/vx_seeps/seeps.cc index 406a09ee94..c3114acffc 100644 --- a/src/libcode/vx_seeps/seeps.cc +++ b/src/libcode/vx_seeps/seeps.cc @@ -35,14 +35,9 @@ using namespace netCDF; bool standalone_debug_seeps = false; -static SeepsClimo *seeps_climo = 0; +static SeepsClimo *seeps_climo = nullptr; static std::map seeps_climo_grid_map_00; -static const char *def_seeps_filename = - "MET_BASE/climo/seeps/PPT24_seepsweights.nc"; -static const char *def_seeps_grid_filename = - "MET_BASE/climo/seeps/PPT24_seepsweights_grid.nc"; - static const char *var_name_sid = "sid"; static const char *var_name_lat = "lat"; static const char *var_name_lon = "lon"; @@ -55,20 +50,20 @@ double weighted_average(double, double, double, double); //////////////////////////////////////////////////////////////////////// -SeepsClimo *get_seeps_climo() { - if (! seeps_climo) seeps_climo = new SeepsClimo(); +SeepsClimo *get_seeps_climo(ConcatString seeps_point_climo_name) { + if (! seeps_climo) seeps_climo = new SeepsClimo(seeps_point_climo_name); return seeps_climo; } //////////////////////////////////////////////////////////////////////// void release_seeps_climo() { - if (seeps_climo) { delete seeps_climo; seeps_climo = 0; } + if (seeps_climo) { delete seeps_climo; seeps_climo = nullptr; } } //////////////////////////////////////////////////////////////////////// -SeepsClimoGrid *get_seeps_climo_grid(int month, int hour) { +SeepsClimoGrid *get_seeps_climo_grid(int month, ConcatString seeps_grid_climo_name, int hour) { bool not_found = true; SeepsClimoGrid *seeps_climo_grid = nullptr; for (map::iterator it=seeps_climo_grid_map_00.begin(); @@ -81,7 +76,7 @@ SeepsClimoGrid *get_seeps_climo_grid(int month, int hour) { } if (not_found) { - seeps_climo_grid = new SeepsClimoGrid(month, hour); + seeps_climo_grid = new SeepsClimoGrid(month, hour, seeps_grid_climo_name); seeps_climo_grid_map_00[month] = seeps_climo_grid; } return seeps_climo_grid; @@ -174,9 +169,11 @@ SeepsAggScore & SeepsAggScore::operator+=(const SeepsAggScore &c) { //////////////////////////////////////////////////////////////////////// +SeepsClimoBase::SeepsClimoBase(ConcatString seeps_climo_name) : climo_file_name{seeps_climo_name} { -SeepsClimoBase::SeepsClimoBase() { clear(); + seeps_ready = false; + } //////////////////////////////////////////////////////////////////////// @@ -188,13 +185,56 @@ SeepsClimoBase::~SeepsClimoBase() { //////////////////////////////////////////////////////////////////////// void SeepsClimoBase::clear() { - seeps_ready = false; filtered_count = 0; seeps_p1_thresh.clear(); } //////////////////////////////////////////////////////////////////////// +ConcatString SeepsClimoBase::get_climo_filename() { + ConcatString log_seeps_filename; + ConcatString seeps_filename; + const char *method_name = "SeepsClimoBase::get_climo_filename() -> "; + + // Use the environment variable, if set. + ConcatString env_climo_name = get_env_climo_name(); + bool use_env = get_env(env_climo_name.c_str(), seeps_filename); + if(!use_env) { + seeps_filename = climo_file_name.nonempty() ? climo_file_name : get_def_climo_name(); + } + seeps_filename = replace_path(seeps_filename); + + seeps_ready = file_exists(seeps_filename.c_str()); + if (seeps_ready) { + mlog << Debug(7) << method_name << "SEEPS climo name=\"" + << seeps_filename.c_str() << "\"\n"; + } + else { + ConcatString message = ""; + ConcatString message2 = ""; + if (use_env) { + message.add("from the environment variable "); + message.add(env_climo_name); + message2.add("Correct the environment variable"); + } + else { + message.add(climo_file_name.nonempty() + ? "from the configuration" : "from the default"); + message2.add("Correct the configuration"); + } + mlog << Warning << "\n" << method_name + << "The SEEPS climo name \"" << seeps_filename.c_str() + << "\" " << message << " does not exist!\n" + << message2 << " to set its location " + << "or disable output for SEEPS and SEEPS_MPR.\n\n"; + exit(1); + } + + return seeps_filename; +} + +//////////////////////////////////////////////////////////////////////// + void SeepsClimoBase::set_p1_thresh(const SingleThresh &p1_thresh) { seeps_p1_thresh = p1_thresh; } @@ -203,19 +243,12 @@ void SeepsClimoBase::set_p1_thresh(const SingleThresh &p1_thresh) { //////////////////////////////////////////////////////////////////////// -SeepsClimo::SeepsClimo() { +SeepsClimo::SeepsClimo(ConcatString seeps_climo_name) : SeepsClimoBase{seeps_climo_name} { + + clear(); + ConcatString seeps_name = get_climo_filename(); + if (file_exists(seeps_name.c_str())) read_seeps_scores(seeps_name); - ConcatString seeps_name = get_seeps_climo_filename(); - seeps_ready = file_exists(seeps_name.c_str()); - if (seeps_ready) read_seeps_scores(seeps_name); - else { - mlog << Error << "\nSeepsClimo::SeepsClimo() -> " - << "The SEEPS point climo data \"" << seeps_name << "\" is missing!\n" - << "Set the " << MET_ENV_SEEPS_POINT_CLIMO_NAME - << " environment variable to define its location " - << "or disable output for SEEPS and SEEPS_MPR.\n\n"; - exit(1); - } } //////////////////////////////////////////////////////////////////////// @@ -287,7 +320,7 @@ SeepsRecord *SeepsClimo::get_record(int sid, int month, int hour) { SeepsRecord *record = nullptr; const char *method_name = "SeepsClimo::get_record() -> "; - if (seeps_ready) { + if (is_seeps_ready()) { SeepsClimoRecord *climo_record = nullptr; map::iterator it; if (hour < 6 || hour >= 18) { @@ -300,7 +333,7 @@ SeepsRecord *SeepsClimo::get_record(int sid, int month, int hour) { } if (nullptr != climo_record) { double p1 = climo_record->p1[month-1]; - if (seeps_p1_thresh.check(p1)) { + if (check_seeps_p1_thresh(p1)) { record = new SeepsRecord; record->sid = climo_record->sid; record->lat = climo_record->lat; @@ -316,7 +349,7 @@ SeepsRecord *SeepsClimo::get_record(int sid, int month, int hour) { } } else if (!is_eq(p1, bad_data_double)) { - filtered_count++; + increase_filtered_count(); mlog << Debug(7) << method_name << " filtered by threshold p1=" << climo_record->p1[month-1] <<"\n"; } @@ -336,35 +369,6 @@ SeepsRecord *SeepsClimo::get_record(int sid, int month, int hour) { //////////////////////////////////////////////////////////////////////// -ConcatString SeepsClimo::get_seeps_climo_filename() { - ConcatString seeps_filename; - const char *method_name = "SeepsClimo::get_seeps_climo_filename() -> "; - - // Use the environment variable, if set. - bool use_env = get_env(MET_ENV_SEEPS_POINT_CLIMO_NAME, seeps_filename); - if(use_env) seeps_filename = replace_path(seeps_filename); - else seeps_filename = replace_path(def_seeps_filename); - - if (seeps_ready = file_exists(seeps_filename.c_str())) { - mlog << Debug(7) << method_name << "SEEPS point climo name=\"" - << seeps_filename.c_str() << "\"\n"; - } - else { - ConcatString message = ""; - if (use_env) { - message.add("from the env. name "); - message.add(MET_ENV_SEEPS_POINT_CLIMO_NAME); - } - mlog << Warning << "\n" << method_name - << "The SEEPS point climo name \"" << seeps_filename.c_str() - << "\"" << message << " does not exist!\n\n"; - } - - return seeps_filename; -} - -//////////////////////////////////////////////////////////////////////// - double SeepsClimo::get_score(int sid, double p_fcst, double p_obs, int month, int hour) { double score = bad_data_double; @@ -484,6 +488,8 @@ void SeepsClimo::read_seeps_scores(ConcatString filename) { double matrix_12_buf[SEEPS_MONTH*SEEPS_MATRIX_SIZE]; NcFile *nc_file = open_ncfile(filename.c_str()); + clear(); + // dimensions: month = 12 ; nstn = 5293 ; nmatrix = 9 ; get_dim(nc_file, dim_name_nstn, nstn, true); mlog << Debug(6) << method_name << "dimensions nstn = " << nstn << "\n"; @@ -642,7 +648,7 @@ void SeepsClimo::read_seeps_scores(ConcatString filename) { } catch(int i_err) { - seeps_ready = false; + set_seeps_ready(false); mlog << Error << "\n" << method_name << "encountered an error on reading " << filename << ". ecception_code=" << i_err << "\n\n"; @@ -656,23 +662,16 @@ void SeepsClimo::read_seeps_scores(ConcatString filename) { //////////////////////////////////////////////////////////////////////// -SeepsClimoGrid::SeepsClimoGrid(int month, int hour) : month{month}, hour{hour} +SeepsClimoGrid::SeepsClimoGrid(int month, int hour, ConcatString seeps_climo_name) + : month{month}, hour{hour}, SeepsClimoBase{seeps_climo_name} { + clear(); p1_buf = p2_buf = t1_buf = t2_buf = nullptr; s12_buf = s13_buf = s21_buf = s23_buf = s31_buf = s32_buf = nullptr; - ConcatString seeps_name = get_seeps_climo_filename(); - seeps_ready = file_exists(seeps_name.c_str()); - if (seeps_ready) read_seeps_scores(seeps_name); - else { - mlog << Error << "\nSeepsClimoGrid::SeepsClimoGrid -> " - << "The SEEPS grid climo data \"" << seeps_name << "\" is missing!\n" - << "Set the " << MET_ENV_SEEPS_GRID_CLIMO_NAME - << " environment variable to define its location " - << "or disable output for SEEPS.\n\n"; - exit(1); - } + ConcatString seeps_name = get_climo_filename(); + if (file_exists(seeps_name.c_str())) read_seeps_scores(seeps_name); } @@ -708,7 +707,7 @@ SeepsScore *SeepsClimoGrid::get_record(int ix, int iy, int offset = iy * nx + ix; double p1 = p1_buf[offset]; - if (seeps_p1_thresh.check(p1)) { + if (check_seeps_p1_thresh(p1)) { // Determine location in contingency table int ic = (p_obs>t1_buf[offset])+(p_obs>t2_buf[offset]); int jc = (p_fcst>t1_buf[offset])+(p_fcst>t2_buf[offset]); @@ -725,7 +724,7 @@ SeepsScore *SeepsClimoGrid::get_record(int ix, int iy, seeps_record->score = score; } else if (~is_eq(p1, bad_data_double)) { - filtered_count++; + increase_filtered_count(); mlog << Debug(7) << method_name << " filtered by threshold p1=" << p1_buf[offset] <<"\n"; } } @@ -781,37 +780,6 @@ double SeepsClimoGrid::get_score(int ix, int iy, double p_fcst, double p_obs) { //////////////////////////////////////////////////////////////////////// -ConcatString SeepsClimoGrid::get_seeps_climo_filename() { - ConcatString seeps_filename; - const char *method_name = "SeepsClimoGrid::get_seeps_climo_filename() -> "; - - // Use the environment variable, if set. - bool use_env = get_env(MET_ENV_SEEPS_GRID_CLIMO_NAME, seeps_filename); - if(use_env) { - seeps_filename = replace_path(seeps_filename); - } - else seeps_filename = replace_path(def_seeps_grid_filename); - - if (seeps_ready = file_exists(seeps_filename.c_str())) { - mlog << Debug(7) << method_name << "SEEPS grid climo name=\"" - << seeps_filename.c_str() << "\"\n"; - } - else { - ConcatString message = ""; - if (use_env) { - message.add("from the env. name "); - message.add(MET_ENV_SEEPS_GRID_CLIMO_NAME); - } - mlog << Warning << "\n" << method_name - << "The SEEPS grid climo name \"" << seeps_filename.c_str() - << "\"" << message << " does not exist!\n\n"; - } - - return seeps_filename; -} - -//////////////////////////////////////////////////////////////////////// - void SeepsClimoGrid::read_seeps_scores(ConcatString filename) { clock_t clock_time = clock(); const char *method_name = "SeepsClimoGrid::read_seeps_scores() -> "; @@ -922,7 +890,7 @@ void SeepsClimoGrid::read_seeps_scores(ConcatString filename) { } catch(...) { - seeps_ready = false; + set_seeps_ready(false); mlog << Error << "\n" << method_name << "encountered an error on reading " << filename << ".\n\n"; diff --git a/src/libcode/vx_seeps/seeps.h b/src/libcode/vx_seeps/seeps.h index 60bca4468b..208275e7cd 100644 --- a/src/libcode/vx_seeps/seeps.h +++ b/src/libcode/vx_seeps/seeps.h @@ -17,44 +17,49 @@ //////////////////////////////////////////////////////////////////////// -#define SEEPS_MONTH 12 -#define SEEPS_MATRIX_SIZE 9 +constexpr int SEEPS_MONTH = 12; +constexpr int SEEPS_MATRIX_SIZE = 9; -#define SAMPLE_STATION_ID 11035 +constexpr int SAMPLE_STATION_ID = 11035; //////////////////////////////////////////////////////////////////////// -static const char *MET_ENV_SEEPS_POINT_CLIMO_NAME = "MET_SEEPS_POINT_CLIMO_NAME"; -static const char *MET_ENV_SEEPS_GRID_CLIMO_NAME = "MET_SEEPS_GRID_CLIMO_NAME"; - -static const char *dim_name_nstn = "nstn"; - -static const char *var_name_p1_00 = "p1_00"; -static const char *var_name_p2_00 = "p2_00"; -static const char *var_name_t1_00 = "t1_00"; -static const char *var_name_t2_00 = "t2_00"; -static const char *var_name_p1_12 = "p1_12"; -static const char *var_name_p2_12 = "p2_12"; -static const char *var_name_t1_12 = "t1_12"; -static const char *var_name_t2_12 = "t2_12"; -static const char *var_name_matrix_00 = "matrix_00"; -static const char *var_name_matrix_12 = "matrix_12"; -static const char *var_name_s12_00 = "s12_00"; -static const char *var_name_s13_00 = "s13_00"; -static const char *var_name_s21_00 = "s21_00"; -static const char *var_name_s23_00 = "s23_00"; -static const char *var_name_s31_00 = "s31_00"; -static const char *var_name_s32_00 = "s32_00"; -static const char *var_name_s12_12 = "s12_12"; -static const char *var_name_s13_12 = "s13_12"; -static const char *var_name_s21_12 = "s21_12"; -static const char *var_name_s23_12 = "s23_12"; -static const char *var_name_s31_12 = "s31_12"; -static const char *var_name_s32_12 = "s32_12"; +constexpr char MET_ENV_SEEPS_POINT_CLIMO_NAME[] = "MET_SEEPS_POINT_CLIMO_NAME"; +constexpr char MET_ENV_SEEPS_GRID_CLIMO_NAME[] = "MET_SEEPS_GRID_CLIMO_NAME"; + +constexpr char dim_name_nstn[] = "nstn"; + +constexpr char var_name_p1_00[] = "p1_00"; +constexpr char var_name_p2_00[] = "p2_00"; +constexpr char var_name_t1_00[] = "t1_00"; +constexpr char var_name_t2_00[] = "t2_00"; +constexpr char var_name_p1_12[] = "p1_12"; +constexpr char var_name_p2_12[] = "p2_12"; +constexpr char var_name_t1_12[] = "t1_12"; +constexpr char var_name_t2_12[] = "t2_12"; +constexpr char var_name_matrix_00[] = "matrix_00"; +constexpr char var_name_matrix_12[] = "matrix_12"; +constexpr char var_name_s12_00[] = "s12_00"; +constexpr char var_name_s13_00[] = "s13_00"; +constexpr char var_name_s21_00[] = "s21_00"; +constexpr char var_name_s23_00[] = "s23_00"; +constexpr char var_name_s31_00[] = "s31_00"; +constexpr char var_name_s32_00[] = "s32_00"; +constexpr char var_name_s12_12[] = "s12_12"; +constexpr char var_name_s13_12[] = "s13_12"; +constexpr char var_name_s21_12[] = "s21_12"; +constexpr char var_name_s23_12[] = "s23_12"; +constexpr char var_name_s31_12[] = "s31_12"; +constexpr char var_name_s32_12[] = "s32_12"; + +constexpr char def_seeps_point_filename[] = + "MET_BASE/climo/seeps/PPT24_seepsweights.nc"; +constexpr char def_seeps_grid_filename[] = + "MET_BASE/climo/seeps/PPT24_seepsweights_grid.nc"; //density_radius = 0.75 degrees (83km; this is described as “the smallest possible // value that ensures approximately equal representation of all subregions of Europe”.) -static double density_radius = 0.75; +constexpr double density_radius = 0.75; const double density_radius_rad = density_radius * rad_per_deg; //////////////////////////////////////////////////////////////////////// @@ -135,21 +140,31 @@ struct SeepsClimoRecord { class SeepsClimoBase { - protected: - + private: bool seeps_ready; int filtered_count; - SingleThresh seeps_p1_thresh; // Range of SEEPS p1 (probability of being dry)std::map seeps_score_00_map; + SingleThresh seeps_p1_thresh; // Range of SEEPS p1 (probability of being dry) + ConcatString climo_file_name; + + protected: + + bool is_seeps_ready() { return seeps_ready; }; + void increase_filtered_count() { filtered_count++; }; + bool check_seeps_p1_thresh(double p1) { return seeps_p1_thresh.check(p1); }; + ConcatString get_climo_filename(); virtual void clear(); + virtual ConcatString get_env_climo_name() { return "not defined"; }; + virtual char *get_def_climo_name() { return nullptr; }; + virtual void read_seeps_scores(ConcatString filename) {}; + void set_seeps_ready(bool _seeps_ready) { seeps_ready = _seeps_ready; }; public: - SeepsClimoBase(); - ~SeepsClimoBase(); - + SeepsClimoBase(ConcatString seeps_climo_name); + virtual ~SeepsClimoBase(); void set_p1_thresh(const SingleThresh &p1_thresh); - int get_filtered_count(); + int get_filtered_count() const; }; @@ -169,15 +184,17 @@ class SeepsClimo : public SeepsClimoBase { void print_record(SeepsClimoRecord *record, bool with_header=false); void read_records(ConcatString filename); - ConcatString get_seeps_climo_filename(); - void read_seeps_scores(ConcatString filename); + protected: + void clear() override; + ConcatString get_env_climo_name() override { return MET_ENV_SEEPS_POINT_CLIMO_NAME; }; + char *get_def_climo_name() override { return (char *)def_seeps_point_filename; }; + void read_seeps_scores(ConcatString filename) override; public: - SeepsClimo(); + SeepsClimo(ConcatString seeps_climo_name); ~SeepsClimo(); - void clear(); SeepsRecord *get_record(int sid, int month, int hour); double get_score(int sid, double p_fcst, double p_obs, int month, int hour); SeepsScore *get_seeps_score(int sid, double p_fcst, double p_obs, int month, int hour); @@ -199,7 +216,7 @@ class SeepsClimoGrid : public SeepsClimoBase { private: int month; - int hour; + int hour; // not implemented int nx; int ny; double *p1_buf; @@ -213,15 +230,17 @@ class SeepsClimoGrid : public SeepsClimoBase { double *s31_buf; double *s32_buf; - ConcatString get_seeps_climo_filename(); - void read_seeps_scores(ConcatString filename); + protected: + void clear() override; + ConcatString get_env_climo_name() override { return MET_ENV_SEEPS_GRID_CLIMO_NAME; }; + char *get_def_climo_name() override { return (char *)def_seeps_grid_filename; }; + void read_seeps_scores(ConcatString filename) override; public: - SeepsClimoGrid(int month, int hour); + SeepsClimoGrid(int month, int hour, ConcatString seeps_climo_name); ~SeepsClimoGrid(); - void clear(); SeepsScore *get_record(int ix, int iy, double p_fcst, double p_obs); double get_score(int offset, int obs_cat, int fcst_cat); double get_score(int ix, int iy, double p_fcst, double p_obs); @@ -236,12 +255,12 @@ class SeepsClimoGrid : public SeepsClimoBase { //////////////////////////////////////////////////////////////////////// -inline int SeepsClimoBase::get_filtered_count() { return filtered_count; } +inline int SeepsClimoBase::get_filtered_count() const { return filtered_count; } //////////////////////////////////////////////////////////////////////// -extern SeepsClimo *get_seeps_climo(); -extern SeepsClimoGrid *get_seeps_climo_grid(int month, int hour=0); +extern SeepsClimo *get_seeps_climo(ConcatString seeps_point_climo_name); +extern SeepsClimoGrid *get_seeps_climo_grid(int month, ConcatString seeps_grid_climo_name, int hour=0); extern void release_seeps_climo(); extern void release_seeps_climo_grid(); diff --git a/src/libcode/vx_statistics/compute_stats.cc b/src/libcode/vx_statistics/compute_stats.cc index e4fe518558..d775637dd3 100644 --- a/src/libcode/vx_statistics/compute_stats.cc +++ b/src/libcode/vx_statistics/compute_stats.cc @@ -1547,7 +1547,8 @@ void compute_aggregated_seeps(const PairDataPoint *pd, SeepsAggScore *seeps) { void compute_aggregated_seeps_grid(const DataPlane &fcst_dp, const DataPlane &obs_dp, DataPlane &seeps_dp, DataPlane &seeps_dp_fcat, DataPlane &seeps_dp_ocat,SeepsAggScore *seeps, - int month, int hour, const SingleThresh &seeps_p1_thresh) { + int month, int hour, const SingleThresh &seeps_p1_thresh, + const ConcatString &seeps_climo_name) { int fcst_cat, obs_cat; int seeps_count, count_diagonal, nan_count, bad_count; int nx = fcst_dp.nx(); @@ -1569,7 +1570,7 @@ void compute_aggregated_seeps_grid(const DataPlane &fcst_dp, const DataPlane &ob c12 = c13 = c21 = c23 = c31 = c32 = 0; seeps->clear(); - SeepsClimoGrid *seeps_climo = get_seeps_climo_grid(month); + SeepsClimoGrid *seeps_climo = get_seeps_climo_grid(month, seeps_climo_name); seeps_climo->set_p1_thresh(seeps_p1_thresh); for (int i=0; i &density_vector); diff --git a/src/libcode/vx_statistics/pair_data_point.cc b/src/libcode/vx_statistics/pair_data_point.cc index d33d8f2311..1041f80324 100644 --- a/src/libcode/vx_statistics/pair_data_point.cc +++ b/src/libcode/vx_statistics/pair_data_point.cc @@ -183,8 +183,8 @@ bool PairDataPoint::add_point_pair(const char *sid, double lat, double lon, //////////////////////////////////////////////////////////////////////// -void PairDataPoint::load_seeps_climo() { - if (nullptr == seeps_climo) seeps_climo = get_seeps_climo(); +void PairDataPoint::load_seeps_climo(const ConcatString &seeps_climo_name) { + if (nullptr == seeps_climo) seeps_climo = get_seeps_climo(seeps_climo_name); } //////////////////////////////////////////////////////////////////////// @@ -1674,11 +1674,11 @@ void VxPairDataPoint::set_obs_perc_value(int percentile) { //////////////////////////////////////////////////////////////////////// -void VxPairDataPoint::load_seeps_climo() { +void VxPairDataPoint::load_seeps_climo(const ConcatString &seeps_climo_name) { for(int i=0; i < n_msg_typ; i++){ for(int j=0; j < n_mask; j++){ for(int k=0; k < n_interp; k++){ - pd[i][j][k].load_seeps_climo(); + pd[i][j][k].load_seeps_climo(seeps_climo_name); } } } diff --git a/src/libcode/vx_statistics/pair_data_point.h b/src/libcode/vx_statistics/pair_data_point.h index c68ddf1f33..166e177b84 100644 --- a/src/libcode/vx_statistics/pair_data_point.h +++ b/src/libcode/vx_statistics/pair_data_point.h @@ -59,7 +59,7 @@ class PairDataPoint : public PairBase { bool add_point_pair(const char *, double, double, double, double, unixtime, double, double, double, double, const char *, double, double, double); - void load_seeps_climo(); + void load_seeps_climo(const ConcatString &seeps_climo_name); void set_seeps_thresh(const SingleThresh &p1_thresh); void set_seeps_score(SeepsScore *, int index=-1); @@ -229,7 +229,7 @@ class VxPairDataPoint { void set_mpr_thresh(const StringArray &, const ThreshArray &); - void load_seeps_climo(); + void load_seeps_climo(const ConcatString &seeps_climo_name); void set_seeps_thresh(const SingleThresh &p1_thresh); void set_climo_cdf_info_ptr(const ClimoCDFInfo *); diff --git a/src/tools/core/grid_stat/grid_stat.cc b/src/tools/core/grid_stat/grid_stat.cc index 6d8e13864d..ccb03a7df1 100644 --- a/src/tools/core/grid_stat/grid_stat.cc +++ b/src/tools/core/grid_stat/grid_stat.cc @@ -1206,7 +1206,7 @@ void process_scores() { compute_aggregated_seeps_grid(fcst_dp_smooth, obs_dp_smooth, seeps_dp, seeps_dp_fcat, seeps_dp_ocat, &seeps, month, hour, - conf_info.vx_opt[i].seeps_p1_thresh); + conf_info.seeps_p1_thresh, conf_info.seeps_climo_name); write_nc("SEEPS_MPR_SCORE", seeps_dp, i, mthd, pnts, conf_info.vx_opt[i].interp_info.field); diff --git a/src/tools/core/grid_stat/grid_stat_conf_info.cc b/src/tools/core/grid_stat/grid_stat_conf_info.cc index db34b15925..b9e8b8587a 100644 --- a/src/tools/core/grid_stat/grid_stat_conf_info.cc +++ b/src/tools/core/grid_stat/grid_stat_conf_info.cc @@ -84,6 +84,9 @@ void GridStatConfInfo::clear() { output_ascii_flag = false; output_nc_flag = false; + seeps_climo_name.clear(); + seeps_p1_thresh.clear(); + // Deallocate memory if(vx_opt) { delete [] vx_opt; vx_opt = (GridStatVxOpt *) nullptr; } @@ -162,6 +165,12 @@ void GridStatConfInfo::process_config(GrdFileType ftype, // Conf: tmp_dir tmp_dir = parse_conf_tmp_dir(&conf); + // Conf: threshold for SEEPS p1 + seeps_p1_thresh = conf.lookup_thresh(conf_key_seeps_p1_thresh); + + // Conf: SEEPS climo filename + seeps_climo_name = conf.lookup_string(conf_key_seeps_grid_climo_name, false); + #ifdef WITH_UGRID // Conf: ugrid_dataset if (!ignore_ugrid_dataset) ugrid_dataset = parse_conf_ugrid_dataset(&conf); @@ -618,8 +627,6 @@ void GridStatVxOpt::clear() { hss_ec_value = bad_data_double; rank_corr_flag = false; - seeps_p1_thresh.clear(); - for(i=0; iseeps_climo_name); + vx_pd.set_seeps_thresh(conf_info->seeps_p1_thresh); } return; } diff --git a/src/tools/core/point_stat/point_stat_conf_info.h b/src/tools/core/point_stat/point_stat_conf_info.h index befde20349..fb838bae0a 100644 --- a/src/tools/core/point_stat/point_stat_conf_info.h +++ b/src/tools/core/point_stat/point_stat_conf_info.h @@ -131,7 +131,6 @@ class PointStatVxOpt { StringArray mpr_sa; // MPR column names ThreshArray mpr_ta; // MPR column thresholds - SingleThresh seeps_p1_thresh; // SEESP p1 threshold // Vector of MaskLatLon objects defining Lat/Lon Point masks std::vector mask_llpnt; @@ -246,6 +245,10 @@ class PointStatConfInfo { ConcatString tmp_dir; // Directory for temporary files ConcatString output_prefix; // String to customize output file name ConcatString version; // Config file version + + ConcatString seeps_climo_name; // SEESP climo filename + SingleThresh seeps_p1_thresh; // SEESP p1 threshold + #ifdef WITH_UGRID bool ignore_ugrid_dataset; ConcatString ugrid_nc; // NetCDF for coordinate variables of unstructured grid