diff --git a/src/tools/core/ensemble_stat/ensemble_stat.cc b/src/tools/core/ensemble_stat/ensemble_stat.cc index e12b659220..b15f0fd728 100644 --- a/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -70,9 +70,10 @@ // 038 09/06/22 Halley Gotway MET #1908 Remove ensemble processing logic. // 039 09/29/22 Halley Gotway MET #2286 Refine GRIB1 table lookup logic. // 040 10/03/22 Prestopnik MET #2227 Remove using namespace netCDF from -// header files +// header files. // 041 04/16/24 Halley Gotway MET #2786 Compute RPS from climo bin probs. // 042 04/29/24 Halley Gotway MET #2870 Ignore MISSING keyword. +// 043 04/29/24 Halley Gotway MET #2795 Move level mismatch warning. // //////////////////////////////////////////////////////////////////////// @@ -807,6 +808,10 @@ void process_point_vx() { // Loop through each of the fields to be verified for(i=0; iget_var_info(); + VarInfo *obs_info = conf_info.vx_opt[i].vx_pd.obs_info; + bool print_level_mismatch_warning = true; + // Initialize emn_dpa.clear(); @@ -825,6 +830,23 @@ void process_point_vx() { continue; } + // MET #2795, for multiple individual forecast levels, print a + // warning if the observations levels are not fully covered. + if(print_level_mismatch_warning && + fcst_dpa.n_planes() > 1 && + !is_eq(fcst_info->level().lower(), fcst_info->level().upper()) && + (obs_info->level().lower() < fcst_info->level().lower() || + obs_info->level().upper() > fcst_info->level().upper())) { + mlog << Warning << "\nprocess_point_vx() -> " + << "The forecast level range (" << fcst_info->magic_str() + << ") does not fully contain the observation level range (" + << obs_info->magic_str() << "). No vertical interpolation " + << "will be performed for observations falling outside " + << "the range of forecast levels. Instead, they will be " + << "matched to the single nearest forecast level.\n\n"; + print_level_mismatch_warning = false; + } + // Store ensemble member data conf_info.vx_opt[i].vx_pd.set_fcst_dpa(fcst_dpa); @@ -843,20 +865,18 @@ void process_point_vx() { mlog << Debug(2) << "Processing ensemble mean file: " << ens_mean_file << "\n"; - VarInfo *info = conf_info.vx_opt[i].vx_pd.fcst_info->get_var_info(); - // Read the gridded data from the ensemble mean file - if(!get_data_plane_array(ens_mean_file.c_str(), info->file_type(), info, - emn_dpa, true)) { + if(!get_data_plane_array(ens_mean_file.c_str(), fcst_info->file_type(), + fcst_info, emn_dpa, true)) { mlog << Error << "\nprocess_point_vx() -> " << "trouble reading the ensemble mean field \"" - << info->magic_str() << "\" from file \"" + << fcst_info->magic_str() << "\" from file \"" << ens_mean_file << "\"\n\n"; exit(1); } // Dump out the number of levels found - mlog << Debug(2) << "For " << info->magic_str() + mlog << Debug(2) << "For " << fcst_info->magic_str() << " found " << emn_dpa.n_planes() << " forecast levels.\n"; } diff --git a/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc b/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc index 8306e3f41e..7987c742de 100644 --- a/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc +++ b/src/tools/core/ensemble_stat/ensemble_stat_conf_info.cc @@ -710,25 +710,6 @@ void EnsembleStatVxOpt::process_config(GrdFileType ftype, Dictionary &fdict, vx_pd.obs_info->dump(cout); } - // Check the levels for the forecast and observation fields. If the - // forecast field is a range of pressure levels, check to see if the - // range of observation field pressure levels is wholly contained in the - // fcst levels. If not, print a warning message. - if(vx_pd.fcst_info->get_var_info()->level().type() == LevelType_Pres && - !is_eq(vx_pd.fcst_info->get_var_info()->level().lower(), vx_pd.fcst_info->get_var_info()->level().upper()) && - (vx_pd.obs_info->level().lower() < vx_pd.fcst_info->get_var_info()->level().lower() || - vx_pd.obs_info->level().upper() > vx_pd.fcst_info->get_var_info()->level().upper())) { - - mlog << Warning - << "\nEnsembleStatVxOpt::process_config() -> " - << "The range of requested observation pressure levels " - << "is not contained within the range of requested " - << "forecast pressure levels. No vertical interpolation " - << "will be performed for observations falling outside " - << "the range of forecast levels. Instead, they will be " - << "matched to the single nearest forecast level.\n\n"; - } - // No support for wind direction if(vx_pd.fcst_info->get_var_info()->is_wind_direction() || vx_pd.obs_info->is_wind_direction()) { diff --git a/src/tools/core/point_stat/point_stat.cc b/src/tools/core/point_stat/point_stat.cc index 313db804b8..bbfb8774d5 100644 --- a/src/tools/core/point_stat/point_stat.cc +++ b/src/tools/core/point_stat/point_stat.cc @@ -102,7 +102,8 @@ // 050 02/11/22 Halley Gotway MET #2045 Fix HiRA output. // 051 07/06/22 Howard Soh METplus-Internal #19 Rename main to met_main // 052 09/29/22 Halley Gotway MET #2286 Refine GRIB1 table lookup logic. -// 053 10/03/22 Prestopnik MET #2227 Remove using namespace netCDF from header files +// 053 10/03/22 Prestopnik MET #2227 Remove using namespace netCDF from header files. +// 054 04/29/24 Halley Gotway MET #2795 Move level mismatch warning. // //////////////////////////////////////////////////////////////////////// @@ -606,25 +607,37 @@ void process_fcst_climo_files() { // the forecast and climatological fields for verification for(int i=0; idata_plane_array( - *conf_info.vx_opt[i].vx_pd.fcst_info, fcst_dpa); - mlog << Debug(2) - << "\n" << sep_str << "\n\n" - << "Reading data for " - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() - << ".\n"; + n_fcst = fcst_mtddf->data_plane_array(*fcst_info, fcst_dpa); + mlog << Debug(2) << "\n" << sep_str << "\n\n" + << "Reading data for " << fcst_info->magic_str() << ".\n"; // Check for zero fields if(n_fcst == 0) { mlog << Warning << "\nprocess_fcst_climo_files() -> " - << "no fields matching " - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() - << " found in file: " - << fcst_file << "\n\n"; + << "no fields matching " << fcst_info->magic_str() + << " found in file: " << fcst_file << "\n\n"; continue; } + // MET #2795, for multiple individual forecast levels, print a + // warning if the observations levels are not fully covered. + if(n_fcst > 1 && + !is_eq(fcst_info->level().lower(), fcst_info->level().upper()) && + (obs_info->level().lower() < fcst_info->level().lower() || + obs_info->level().upper() > fcst_info->level().upper())) { + mlog << Warning << "\nprocess_fcst_climo_files() -> " + << "The forecast level range (" << fcst_info->magic_str() + << ") does not fully contain the observation level range (" + << obs_info->magic_str() << "). No vertical interpolation " + << "will be performed for observations falling outside " + << "the range of forecast levels. Instead, they will be " + << "matched to the single nearest forecast level.\n\n"; + } + // Setup the first pass through the data if(is_first_pass) setup_first_pass(fcst_dpa[0], fcst_mtddf->grid()); @@ -632,19 +645,18 @@ void process_fcst_climo_files() { if(!(fcst_mtddf->grid() == grid)) { mlog << Debug(1) << "Regridding " << fcst_dpa.n_planes() - << " forecast field(s) for " - << conf_info.vx_opt[i].vx_pd.fcst_info->magic_str() + << " forecast field(s) for " << fcst_info->magic_str() << " to the verification grid.\n"; // Loop through the forecast fields for(j=0; jgrid(), grid, - conf_info.vx_opt[i].vx_pd.fcst_info->regrid()); + fcst_info->regrid()); } } // Rescale probabilities from [0, 100] to [0, 1] - if(conf_info.vx_opt[i].vx_pd.fcst_info->p_flag()) { + if(fcst_info->p_flag()) { for(j=0; jmagic_str() - << " found " << n_fcst << " forecast levels, " + << "For " << fcst_info->magic_str() << " found " + << n_fcst << " forecast levels, " << cmn_dpa.n_planes() << " climatology mean levels, and " << csd_dpa.n_planes() << " climatology standard deviation levels.\n"; @@ -1825,8 +1837,8 @@ void do_hira_ens(int i_vx, const PairDataPoint *pd_ptr) { conf_info.vx_opt[i_vx].hira_info.width[i], grid.wrap_lon()); if (nullptr == gt) { - mlog << Warning - << "\nPdo_hira_ens() Fail to get GridTemplate for " << i << "-th width.\n\n"; + mlog << Warning << "\ndo_hira_ens() -> " + << "failed to get GridTemplate for " << i << "-th width.\n\n"; continue; } diff --git a/src/tools/core/point_stat/point_stat_conf_info.cc b/src/tools/core/point_stat/point_stat_conf_info.cc index e05157d5bc..1a416fbd5a 100644 --- a/src/tools/core/point_stat/point_stat_conf_info.cc +++ b/src/tools/core/point_stat/point_stat_conf_info.cc @@ -851,25 +851,6 @@ void PointStatVxOpt::process_config(GrdFileType ftype, vx_pd.obs_info->dump(cout); } - // Check the levels for the forecast and observation fields. If the - // forecast field is a range of pressure levels, check to see if the - // range of observation field pressure levels is wholly contained in the - // fcst levels. If not, print a warning message. - if(vx_pd.fcst_info->level().type() == LevelType_Pres && - !is_eq(vx_pd.fcst_info->level().lower(), vx_pd.fcst_info->level().upper()) && - (vx_pd.obs_info->level().lower() < vx_pd.fcst_info->level().lower() || - vx_pd.obs_info->level().upper() > vx_pd.fcst_info->level().upper())) { - - mlog << Warning - << "\nPointStatVxOpt::process_config() -> " - << "The range of requested observation pressure levels " - << "is not contained within the range of requested " - << "forecast pressure levels. No vertical interpolation " - << "will be performed for observations falling outside " - << "the range of forecast levels. Instead, they will be " - << "matched to the single nearest forecast level.\n\n"; - } - // No support for wind direction if(vx_pd.fcst_info->is_wind_direction() || vx_pd.obs_info->is_wind_direction()) {