diff --git a/src/tools/core/mode/mode.cc b/src/tools/core/mode/mode.cc index 68463a6c84..d71a7698b5 100644 --- a/src/tools/core/mode/mode.cc +++ b/src/tools/core/mode/mode.cc @@ -57,6 +57,7 @@ // 020 07/06/22 Howard Soh METplus-Internal #19 Rename main to met_main // 021 06/09/23 Albo Major changes for multivariate mode // 022 11/02/23 Halley Gotway MET #2724 add OpenMP to convolution +// 023 12/27/23 Albo MET #2745 more unit tests, read data one time, percentile thresholding // //////////////////////////////////////////////////////////////////////// @@ -78,6 +79,7 @@ using namespace std; #include "string_array.h" #include "mode_usage.h" #include "mode_frontend.h" +#include "multivar_frontend.h" #include "mode_conf_info.h" #ifdef WITH_PYTHON @@ -97,7 +99,6 @@ using namespace std; /////////////////////////////////////////////////////////////////////// -extern int mode_frontend(const StringArray &); extern int multivar_frontend(const StringArray &); extern const char * const program_name; @@ -186,13 +187,15 @@ int met_main(int argc, char * argv []) config.check_multivar_not_implemented(); // run the multivar version of mode - - status = multivar_frontend(Argv); + + MultivarFrontEnd *frontend = new MultivarFrontEnd(); + status = frontend->run(Argv); + if ( frontend ) { delete frontend; frontend = 0; } } else { - // run the traditional version of mode, with command line arguments as is + // run the traditional version of mode ModeFrontEnd *frontend = new ModeFrontEnd; status = frontend->run_traditional(Argv); diff --git a/src/tools/core/mode/mode_exec.cc b/src/tools/core/mode/mode_exec.cc index 28818ba8b8..2f44e944c0 100644 --- a/src/tools/core/mode/mode_exec.cc +++ b/src/tools/core/mode/mode_exec.cc @@ -60,12 +60,11 @@ static void replaceAll(std::string& str, const std::string& from, const std::str /////////////////////////////////////////////////////////////////////// -ModeExecutive::ModeExecutive(Processing_t p) +ModeExecutive::ModeExecutive()//Processing_t p) { init_from_scratch(); - ptype = p; } @@ -132,8 +131,6 @@ void ModeExecutive::clear() R_index = T_index = 0; - ptype = TRADITIONAL; - // // done // @@ -206,24 +203,6 @@ void ModeExecutive::init_traditional(int n_files) /////////////////////////////////////////////////////////////////////// - -void ModeExecutive::init_multivar_verif_grid(const DataPlane &fcst, - const DataPlane &obs, - const ModeConfInfo &conf) -{ - - R_index = T_index = 0; - engine.conf_info = conf; - engine.conf_info.check_multivar_not_implemented(); - - // engine.conf_info.nc_info.compress_level = engine.conf_info.get_compression_level(); - - return; - -} - -/////////////////////////////////////////////////////////////////////// - void ModeExecutive::init_multivar_simple(int j, int n_files, ModeDataType dtype, const ModeConfInfo &conf) @@ -268,7 +247,7 @@ void ModeExecutive::init_multivar_intensities(GrdFileType ftype, GrdFileType oty /////////////////////////////////////////////////////////////////////// -void ModeExecutive::setup_fcst_obs_data_traditional() +void ModeExecutive::setup_traditional_fcst_obs_data() { @@ -282,7 +261,7 @@ void ModeExecutive::setup_fcst_obs_data_traditional() if ( !(fcst_mtddf->data_plane(*(engine.conf_info.Fcst->var_info), Fcst_sd.data)) ) { - mlog << Error << "\nModeExecutive::setup_fcst_obs_data_traditional() -> " + mlog << Error << "\nModeExecutive::setup_traditionalfcst_obs_data() -> " << "can't get forecast data \"" << engine.conf_info.Fcst->var_info->magic_str() << "\" from file \"" << fcst_file << "\"\n\n"; @@ -293,7 +272,7 @@ void ModeExecutive::setup_fcst_obs_data_traditional() if ( !(obs_mtddf->data_plane(*(engine.conf_info.Obs->var_info), Obs_sd.data)) ) { - mlog << Error << "\nModeExecutive::setup_fcst_obs_data_traditional() -> " + mlog << Error << "\nModeExecutive::setup_traditional_fcst_obs_data() -> " << "can't get observation data \"" << engine.conf_info.Obs->var_info->magic_str() << "\" from file \"" << obs_file << "\"\n\n"; @@ -341,7 +320,7 @@ void ModeExecutive::setup_fcst_obs_data_traditional() if(Fcst_sd.data.valid() != Obs_sd.data.valid()) { - mlog << Warning << "\nModeExecutive::setup_fcst_obs_data_traditional() -> " + mlog << Warning << "\nModeExecutive::setup_traditional_fcst_obs_data() -> " << "Forecast and observation valid times do not match " << unix_to_yyyymmdd_hhmmss(Fcst_sd.data.valid()) << " != " << unix_to_yyyymmdd_hhmmss(Obs_sd.data.valid()) << " for " @@ -355,7 +334,7 @@ void ModeExecutive::setup_fcst_obs_data_traditional() engine.conf_info.Obs->var_info->level().type() == LevelType_Accum && Fcst_sd.data.accum() != Obs_sd.data.accum()) { - mlog << Warning << "\nModeExecutive::setup_fcst_obs_data_traditional() -> " + mlog << Warning << "\nModeExecutive::setup_traditional_fcst_obs_data() -> " << "Forecast and observation accumulation times do not match " << sec_to_hhmmss(Fcst_sd.data.valid()) << " != " << sec_to_hhmmss(Obs_sd.data.valid()) << " for " @@ -423,22 +402,19 @@ void ModeExecutive::setup_fcst_obs_data_traditional() /////////////////////////////////////////////////////////////////////// - void ModeExecutive::setup_verification_grid(const ModeInputData &fcst, - const ModeInputData &obs) + const ModeInputData &obs, + const ModeConfInfo &conf) { - - // ShapeData fcst_sd, obs_sd; - double fmin, omin, fmax, omax; + R_index = T_index = 0; + engine.conf_info = conf; + engine.conf_info.check_multivar_not_implemented(); Fcst_sd.clear(); Obs_sd.clear(); - Fcst_sd.data = fcst._dataPlane; Obs_sd.data = obs._dataPlane; - // Determine the verification grid - engine.conf_info.set_field_index(0); grid = parse_vx_grid(engine.conf_info.Fcst->var_info->regrid(), &fcst._grid, &obs._grid); @@ -447,9 +423,8 @@ void ModeExecutive::setup_verification_grid(const ModeInputData &fcst, /////////////////////////////////////////////////////////////////////// - -void ModeExecutive::setup_fcst_data(const Grid &verification_grid, - const ModeInputData &input) +void ModeExecutive::setup_multivar_fcst_data(const Grid &verification_grid, + const ModeInputData &input) { double fmin, fmax; @@ -511,9 +486,8 @@ void ModeExecutive::setup_fcst_data(const Grid &verification_grid, /////////////////////////////////////////////////////////////////////// - -void ModeExecutive::setup_obs_data(const Grid &verification_grid, - const ModeInputData &input) +void ModeExecutive::setup_multivar_obs_data(const Grid &verification_grid, + const ModeInputData &input) { // ShapeData fcst_sd, obs_sd; @@ -579,7 +553,7 @@ void ModeExecutive::setup_obs_data(const Grid &verification_grid, /////////////////////////////////////////////////////////////////////// -void ModeExecutive::setup_fcst_obs_data_multivar_intensities(const MultiVarData &mvdf, +void ModeExecutive::setup_multivar_fcst_obs_data_intensities(const MultiVarData &mvdf, const MultiVarData &mvdo) { double fmin, fmax, omin, omax; @@ -600,7 +574,7 @@ void ModeExecutive::setup_fcst_obs_data_multivar_intensities(const MultiVarData // Print a warning if the valid times do not match if(Fcst_sd.data.valid() != Obs_sd.data.valid()) { - mlog << Warning << "\nModeExecutive::setup_fcst_obs_data_multivar_intensities() -> " + mlog << Warning << "\nModeExecutive::setup_multivar_fcst_obs_data_intensities() -> " << "Forecast and observation valid times do not match " << unix_to_yyyymmdd_hhmmss(Fcst_sd.data.valid()) << " != " << unix_to_yyyymmdd_hhmmss(Obs_sd.data.valid()) << " for " @@ -613,7 +587,7 @@ void ModeExecutive::setup_fcst_obs_data_multivar_intensities(const MultiVarData engine.conf_info.Obs->var_info->level().type() == LevelType_Accum && Fcst_sd.data.accum() != Obs_sd.data.accum()) { - mlog << Warning << "\nModeExecutive::setup_fcst_obs_data_multivar_intensities() -> " + mlog << Warning << "\nModeExecutive::setup_multivar_fcst_obs_data_intensities() -> " << "Forecast and observation accumulation times do not match " << sec_to_hhmmss(Fcst_sd.data.valid()) << " != " << sec_to_hhmmss(Obs_sd.data.valid()) << " for " @@ -669,7 +643,7 @@ void ModeExecutive::setup_fcst_obs_data_multivar_intensities(const MultiVarData /////////////////////////////////////////////////////////////////////// -void ModeExecutive::setup_fcst_obs_data_multivar_super(const ShapeData &f_super, +void ModeExecutive::setup_multivar_fcst_obs_data_super(const ShapeData &f_super, const ShapeData &o_super, const Grid &igrid) { @@ -697,7 +671,7 @@ void ModeExecutive::setup_fcst_obs_data_multivar_super(const ShapeData &f_super, // Print a warning if the valid times do not match if(Fcst_sd.data.valid() != Obs_sd.data.valid()) { - mlog << Warning << "\nModeExecutive::setup_fcst_obs_data_multivar_super() -> " + mlog << Warning << "\nModeExecutive::setup_multivar_fcst_obs_data_super() -> " << "Forecast and observation valid times do not match " << unix_to_yyyymmdd_hhmmss(Fcst_sd.data.valid()) << " != " << unix_to_yyyymmdd_hhmmss(Obs_sd.data.valid()) << " for " @@ -710,7 +684,7 @@ void ModeExecutive::setup_fcst_obs_data_multivar_super(const ShapeData &f_super, engine.conf_info.Obs->var_info->level().type() == LevelType_Accum && Fcst_sd.data.accum() != Obs_sd.data.accum()) { - mlog << Warning << "\nModeExecutive::setup_fcst_obs_data_multivar_super() -> " + mlog << Warning << "\nModeExecutive::setup_multivar_fcst_obs_data_super() -> " << "Forecast and observation accumulation times do not match " << sec_to_hhmmss(Fcst_sd.data.valid()) << " != " << sec_to_hhmmss(Obs_sd.data.valid()) << " for " @@ -756,7 +730,7 @@ void ModeExecutive::setup_fcst_obs_data_multivar_super(const ShapeData &f_super, /////////////////////////////////////////////////////////////////////// -void ModeExecutive::do_conv_thresh(const int r_index, const int t_index) +void ModeExecutive::do_conv_thresh_traditional(const int r_index, const int t_index) { ModeConfInfo & conf = engine.conf_info; @@ -768,65 +742,162 @@ void ModeExecutive::do_conv_thresh(const int r_index, const int t_index) R_index = r_index; T_index = t_index; - if (ptype == MULTIVAR_SIMPLE_MERGE) { - conf.set_conv_thresh_by_merge_index(T_index); - } else if (ptype == MULTIVAR_SUPER) { - SingleThresh s("ne-9999"); - conf.set_conv_thresh(s); - conf.set_conv_radius(0.0); + conf.set_conv_radius_by_index(R_index); + conf.set_conv_thresh_by_index(T_index); + conf.set_merge_thresh_by_index(T_index); + + // + // Set up the engine with these raw fields + // + + string what = "forecast and observation fields"; + mlog << Debug(2) << "Identifying objects in the " << what << "...\n"; + + if ( r_index != local_r_index ) { + // need to do convolution + engine.set(Fcst_sd, Obs_sd); } else { - // this could break down if obs and fcst have different arrays - // currently not allowed in multivar mode, should work correctly - // for traditional mode - conf.set_conv_radius_by_index(R_index); - conf.set_conv_thresh_by_index(T_index); + // don't need to do convolution + engine.set_no_conv(Fcst_sd, Obs_sd); } + // + // Compute the contingency table statistics for the fields, if needed + // + if ( conf.ct_stats_flag ) compute_ct_stats(); + + // + // done + // + + local_r_index = r_index; + + return; + +} + +/////////////////////////////////////////////////////////////////////// + +void ModeExecutive::do_conv_thresh_multivar_super() +{ + + ModeConfInfo & conf = engine.conf_info; + + R_index = 0; + T_index = 0; + + SingleThresh s("ne-9999"); + conf.set_conv_thresh(s); + conf.set_conv_radius(0.0); conf.set_merge_thresh_by_index(T_index); // // Set up the engine with these raw fields // - string what = "forecast and observation fields"; - if (ptype == MULTIVAR_SIMPLE || ptype == MULTIVAR_SIMPLE_MERGE) { - if (conf.data_type == ModeDataType_MvMode_Obs) { - what = "observation field"; - } else { - what = "forecast field"; - } - } mlog << Debug(2) << "Identifying objects in the " << what << "...\n"; - if ( r_index != local_r_index ) { // need to do convolution + engine.set_only_split(Fcst_sd, Obs_sd); - if (ptype == MULTIVAR_INTENSITY || ptype == MULTIVAR_SUPER) { - engine.set_only_split(Fcst_sd, Obs_sd); - } else {// MULTIVAR_SIMPLE, MULTIVAR_SIMPLE_MERGE, TRADITIONAL - engine.set(Fcst_sd, Obs_sd); - } - } else { // don't need to do convolution + // + // Compute the contingency table statistics for the fields, if needed + // (not needed for simple or merge, only one field) + // + if ( conf.ct_stats_flag ) compute_ct_stats(); - if (ptype == MULTIVAR_INTENSITY || ptype == MULTIVAR_SUPER) { - engine.set_only_split(Fcst_sd, Obs_sd); - } else {// MULTIVAR_SIMPLE, MULTIVAR_SIMPLE_MERGE, TRADITIONAL - engine.set_no_conv(Fcst_sd, Obs_sd); - } - } + // + // done + // + + local_r_index = 0; + + return; + +} + + +/////////////////////////////////////////////////////////////////////// + + +void ModeExecutive::do_conv_thresh_multivar_intensity_compare() +{ + + ModeConfInfo & conf = engine.conf_info; + + R_index = 0; + T_index = 0; + + conf.set_conv_radius_by_index(R_index); + conf.set_conv_thresh_by_index(T_index); + conf.set_merge_thresh_by_index(T_index); + + // + // Set up the engine with these raw fields + // + + string what = "forecast and observation fields"; + mlog << Debug(2) << "Identifying objects in the " << what << "...\n"; + + engine.set_only_split(Fcst_sd, Obs_sd); // // Compute the contingency table statistics for the fields, if needed - // (not needed for simple or merge, only one field) // - if (ptype != MULTIVAR_SIMPLE && ptype != MULTIVAR_SIMPLE_MERGE) { - if ( conf.ct_stats_flag ) compute_ct_stats(); - } + if ( conf.ct_stats_flag ) compute_ct_stats(); // // done // - local_r_index = r_index; + local_r_index = 0; + + return; + +} + +/////////////////////////////////////////////////////////////////////// + +void ModeExecutive::do_conv_thresh_multivar_simple(Processing_t p) +{ + + ModeConfInfo & conf = engine.conf_info; + + R_index = 0; + T_index = 0; + + if (p == MULTIVAR_SIMPLE_MERGE) { + conf.set_conv_thresh_by_merge_index(T_index); + } else if (p == MULTIVAR_SIMPLE) { + conf.set_conv_radius_by_index(0); + conf.set_conv_thresh_by_index(0); + } else { + mlog << Error << "\nModeExecutive::do_conv_thresh_multivar_simple() -> " + << "Wrong processing type input " << stype(p) << "\"\n\n"; + exit(1); + } + + conf.set_merge_thresh_by_index(0); + + // + // Set up the engine with these raw fields + // + + string what; + if (conf.data_type == ModeDataType_MvMode_Obs) { + what = "observation field"; + } else { + what = "forecast field"; + } + mlog << Debug(2) << "Identifying objects in the " << what << "...\n"; + + engine.set(Fcst_sd, Obs_sd); + + // (ct_stats not needed for simple or merge, only one field) + // + // done + // + + local_r_index = 0; return; @@ -841,7 +912,7 @@ void ModeExecutive::clear_internal_r_index() /////////////////////////////////////////////////////////////////////// -void ModeExecutive::do_merging() +void ModeExecutive::do_merging_traditional() { mlog << Debug(2) << "Identified: " << engine.n_fcst << " forecast objects " @@ -873,10 +944,11 @@ void ModeExecutive::do_merging() /////////////////////////////////////////////////////////////////////// -void ModeExecutive::do_merging(const ShapeData &f_merge, const ShapeData &o_merge) - +void ModeExecutive::do_merging_multivar(const ShapeData &f_merge, + const ShapeData &o_merge, + Processing_t p) { - if (ptype == MULTIVAR_SUPER) { + if (p == MULTIVAR_SUPER) { // set the merge flag and merge_thresh appropriately ModeConfInfo & conf = engine.conf_info; SingleThresh s("ne-9999"); @@ -884,14 +956,11 @@ void ModeExecutive::do_merging(const ShapeData &f_merge, const ShapeData &o_merg conf.set_fcst_merge_thresh(s); conf.set_obs_merge_flag(MergeType_Thresh); conf.set_obs_merge_thresh(s); - } else { - if (ptype != MULTIVAR_INTENSITY) { - mlog << Error << "\nModeExecutive::do_merging(shapedata, shapedata) -> " - << "wrong method for processing type " << stype(ptype) << "\n\n"; - exit(1); - } + } else if (p != MULTIVAR_INTENSITY) { + mlog << Error << "\nModeExecutive::do_merging(shapedata, shapedata, p) -> " + << "wrong method for processing type " << stype(p) << "\n\n"; + exit(1); } - mlog << Debug(2) << "Identified: " << engine.n_fcst << " forecast objects " @@ -926,11 +995,12 @@ void ModeExecutive::do_merging(const ShapeData &f_merge, const ShapeData &o_merg /////////////////////////////////////////////////////////////////////// -void ModeExecutive::do_match_merge(const ShapeData &f_merge, - const ShapeData &o_merge) +void ModeExecutive::do_match_merge_multivar(const ShapeData &f_merge, + const ShapeData &o_merge, + Processing_t p) { - do_merging(f_merge, o_merge); + do_merging_multivar(f_merge, o_merge, p); // Do the matching of objects between fields @@ -943,10 +1013,10 @@ void ModeExecutive::do_match_merge(const ShapeData &f_merge, /////////////////////////////////////////////////////////////////////// -void ModeExecutive::do_match_merge() +void ModeExecutive::do_match_merge_traditional() { - do_merging(); + do_merging_traditional(); // Do the matching of objects between fields @@ -1117,82 +1187,104 @@ void ModeExecutive::set_raw_to_full(float *fcst_raw_data, /////////////////////////////////////////////////////////////////////// -void ModeExecutive::process_output(const MultiVarData *mvdf, - const MultiVarData *mvdo) - +void ModeExecutive::process_output_multivar_super() { + isMultivarOutput = false; + isMultivarSuperOutput = true; - // store to class member so don't have to pass it around - isMultivarOutput = (ptype == MULTIVAR_INTENSITY); - isMultivarSuperOutput = (ptype == MULTIVAR_SUPER); + // use the configured multivar name and level + fcst_magic_string = engine.conf_info.fcst_multivar_name.string() + "_" + engine.conf_info.fcst_multivar_level.string(); + obs_magic_string = engine.conf_info.obs_multivar_name.string() + "_" + engine.conf_info.obs_multivar_level.string(); - if (isMultivarOutput) { + // Create output stats files and plots - // get the magic strings, which will be used in file naming - fcst_magic_string = engine.conf_info.Fcst->var_info->magic_str().c_str(); - obs_magic_string = engine.conf_info.Obs->var_info->magic_str().c_str(); + write_obj_stats(); - // replace forward slashes with underscores to prevent new directories - replace(fcst_magic_string.begin(), fcst_magic_string.end(), '/', '_'); - replace(obs_magic_string.begin(), obs_magic_string.end(), '/', '_'); + if ( engine.conf_info.ct_stats_flag ) write_ct_stats(); + + write_obj_netcdf(engine.conf_info.nc_info); - // replace (*,*) with '_all_all_' - replaceAll(fcst_magic_string, "*", "all"); - replaceAll(obs_magic_string, "*", "all"); - replaceAll(fcst_magic_string, ",", "_"); - replaceAll(obs_magic_string, ",", "_"); - replaceAll(fcst_magic_string, "(", "_"); - replaceAll(obs_magic_string, "(", "_"); - replaceAll(fcst_magic_string, ")", ""); - replaceAll(obs_magic_string, ")", ""); - - } else if (isMultivarSuperOutput) { + if ( engine.conf_info.ps_plot_flag ) plot_engine(); - // use the configured multivar name and level - fcst_magic_string = engine.conf_info.fcst_multivar_name.string() + "_" + engine.conf_info.fcst_multivar_level.string(); - obs_magic_string = engine.conf_info.obs_multivar_name.string() + "_" + engine.conf_info.obs_multivar_level.string(); + return; - } else { +} - // just in case make these empty - fcst_magic_string = ""; - obs_magic_string = ""; +/////////////////////////////////////////////////////////////////////// - } - +void ModeExecutive::process_output_multivar_intensity_compare(const MultiVarData *mvdf, + const MultiVarData *mvdo) + +{ + isMultivarOutput = true; + isMultivarSuperOutput = false; + + // get the magic strings, which will be used in file naming + fcst_magic_string = engine.conf_info.Fcst->var_info->magic_str().c_str(); + obs_magic_string = engine.conf_info.Obs->var_info->magic_str().c_str(); + + // replace forward slashes with underscores to prevent new directories + replace(fcst_magic_string.begin(), fcst_magic_string.end(), '/', '_'); + replace(obs_magic_string.begin(), obs_magic_string.end(), '/', '_'); + + // replace (*,*) with '_all_all_' + replaceAll(fcst_magic_string, "*", "all"); + replaceAll(obs_magic_string, "*", "all"); + replaceAll(fcst_magic_string, ",", "_"); + replaceAll(obs_magic_string, ",", "_"); + replaceAll(fcst_magic_string, "(", "_"); + replaceAll(obs_magic_string, "(", "_"); + replaceAll(fcst_magic_string, ")", ""); + replaceAll(obs_magic_string, ")", ""); + // Create output stats files and plots write_obj_stats(); if ( engine.conf_info.ct_stats_flag ) write_ct_stats(); - - if (isMultivarOutput) { - if (mvdf && mvdo) { - double fmin = mvdf->_data_min; - double fmax = mvdf->_data_max; - double omin = mvdo->_data_min; - double omax = mvdo->_data_max; - double data_min, data_max; - if (!is_bad_data(fmin) && !is_bad_data(omin)) data_min = min(fmin, omin); - else if(!is_bad_data(fmin) && is_bad_data(omin)) data_min = fmin; - else if( is_bad_data(fmin) && !is_bad_data(omin)) data_min = omin; - - if (!is_bad_data(fmax) && !is_bad_data(omax)) data_max = max(fmax, omax); - else if(!is_bad_data(fmax) && is_bad_data(omax)) data_max = fmax; - else if( is_bad_data(fmax) && !is_bad_data(omax)) data_max = omax; + double fmin = mvdf->_data_min; + double fmax = mvdf->_data_max; + double omin = mvdo->_data_min; + double omax = mvdo->_data_max; + double data_min, data_max; + if (!is_bad_data(fmin) && !is_bad_data(omin)) data_min = min(fmin, omin); + else if(!is_bad_data(fmin) && is_bad_data(omin)) data_min = fmin; + else if( is_bad_data(fmin) && !is_bad_data(omin)) data_min = omin; + + if (!is_bad_data(fmax) && !is_bad_data(omax)) data_max = max(fmax, omax); + else if(!is_bad_data(fmax) && is_bad_data(omax)) data_max = fmax; + else if( is_bad_data(fmax) && !is_bad_data(omax)) data_max = omax; - set_raw_to_full(mvdf->_simple->_raw_data, - mvdo->_simple->_raw_data, - mvdf->_nx, mvdf->_ny, - data_min, data_max); - } else { - mlog << Error << "\nModeExecutive::process_output() -> " - << "no multivar data when multivar data is expected\n\n"; - exit(1); - } - } + set_raw_to_full(mvdf->_simple->_raw_data,mvdo->_simple->_raw_data, + mvdf->_nx, mvdf->_ny, data_min, data_max); + + write_obj_netcdf(engine.conf_info.nc_info); + + if ( engine.conf_info.ps_plot_flag ) plot_engine(); + + return; + +} + +/////////////////////////////////////////////////////////////////////// + +void ModeExecutive::process_output_traditional() +{ + isMultivarOutput = false; + isMultivarSuperOutput = false; + + // just in case make these empty + fcst_magic_string = ""; + obs_magic_string = ""; + + // Create output stats files and plots + + write_obj_stats(); + + if ( engine.conf_info.ct_stats_flag ) write_ct_stats(); + write_obj_netcdf(engine.conf_info.nc_info); if ( engine.conf_info.ps_plot_flag ) plot_engine(); diff --git a/src/tools/core/mode/mode_exec.h b/src/tools/core/mode/mode_exec.h index c326c6ab30..574bf937c6 100644 --- a/src/tools/core/mode/mode_exec.h +++ b/src/tools/core/mode/mode_exec.h @@ -75,14 +75,12 @@ class ModeExecutive { // the various mode algorithm settings typedef enum {TRADITIONAL, MULTIVAR_SIMPLE, MULTIVAR_SIMPLE_MERGE, MULTIVAR_INTENSITY, MULTIVAR_SUPER} Processing_t; - ModeExecutive(Processing_t p=TRADITIONAL); + ModeExecutive(); ~ModeExecutive(); void clear(); void init_traditional(int n_files); - void init_multivar_verif_grid(const DataPlane &fcst, - const DataPlane &obs, const ModeConfInfo &config); void init_multivar_simple(int j, int n_files, ModeDataType dtype, const ModeConfInfo &conf); void init_multivar_intensities(GrdFileType ftype, GrdFileType otype, const ModeConfInfo &conf); @@ -132,29 +130,44 @@ class ModeExecutive { bool isMultivarOutput; bool isMultivarSuperOutput; - Processing_t ptype; + //Processing_t ptype; - void clear_internal_r_index(); void setup_verification_grid(const ModeInputData &fcst, - const ModeInputData &obs); - void setup_fcst_obs_data_traditional(); - void setup_fcst_data(const Grid &verification_grid, const ModeInputData &input); - void setup_obs_data(const Grid &verification_grid, const ModeInputData &input); - void setup_fcst_obs_data_multivar_intensities(const MultiVarData &mvdf, + const ModeInputData &obs, + const ModeConfInfo &conf); + + void clear_internal_r_index(); + + void setup_traditional_fcst_obs_data(); + void setup_multivar_fcst_data(const Grid &verification_grid, const ModeInputData &input); + void setup_multivar_obs_data(const Grid &verification_grid, const ModeInputData &input); + void setup_multivar_fcst_obs_data_intensities(const MultiVarData &mvdf, const MultiVarData &mvdo); - void setup_fcst_obs_data_multivar_super(const ShapeData &f_super, - const ShapeData &o_super, const Grid &igrid); - void do_conv_thresh(const int r_index, const int t_index); - void do_merging(); - void do_merging(const ShapeData &f_merge, const ShapeData &o_merge); - void do_match_merge(); - void do_match_merge(const ShapeData &f_merge, const ShapeData &o_merge); + void setup_multivar_fcst_obs_data_super(const ShapeData &f_super, + const ShapeData &o_super, + const Grid &igrid); + + void do_conv_thresh_traditional(const int r_index, const int t_index); + void do_conv_thresh_multivar_super(); + void do_conv_thresh_multivar_intensity_compare(); + void do_conv_thresh_multivar_simple(Processing_t p); + + void do_merging_traditional(); + void do_merging_multivar(const ShapeData &f_merge, const ShapeData &o_merge, + Processing_t p); + + void do_match_merge_traditional(); + void do_match_merge_multivar(const ShapeData &f_merge, const ShapeData &o_merge, + Processing_t p); void process_masks(ShapeData &, ShapeData &); void process_fcst_masks(ShapeData &); void process_obs_masks(ShapeData &); - void process_output(const MultiVarData *mvdf=NULL, - const MultiVarData *mvdo=NULL); + + void process_output_traditional(); + void process_output_multivar_intensity_compare(const MultiVarData *mvdf, + const MultiVarData *mvdo); + void process_output_multivar_super(); void set_raw_to_full(float *fcst_raw_data, float *obs_raw_data, diff --git a/src/tools/core/mode/mode_frontend.cc b/src/tools/core/mode/mode_frontend.cc index efbe774485..4831cb59d2 100644 --- a/src/tools/core/mode/mode_frontend.cc +++ b/src/tools/core/mode/mode_frontend.cc @@ -35,13 +35,11 @@ using namespace std; extern const char * const program_name; static ModeExecutive *mode_exec = 0; -static ModeExecutive::Processing_t ptype = ModeExecutive::TRADITIONAL; // used only for traditional mode, multivar sets it into config previous // to the frontend creation static int compress_level = -1; - /////////////////////////////////////////////////////////////////////// @@ -64,154 +62,13 @@ ModeFrontEnd::~ModeFrontEnd() } -/////////////////////////////////////////////////////////////////////// - -Grid ModeFrontEnd::create_verification_grid(const ModeInputData &fcst, - const ModeInputData &obs, - const string &config_file, - const ModeConfInfo &config) -{ - if ( mode_exec ) { delete mode_exec; mode_exec = 0; } - mode_exec = new ModeExecutive; - mode_exec->out_dir = default_out_dir; - mode_exec->fcst_file = "None"; - mode_exec->obs_file = "None"; - mode_exec->match_config_file = config_file; - mode_exec->init_multivar_verif_grid(fcst._dataPlane, obs._dataPlane, config); - - ModeConfInfo & conf = mode_exec->engine.conf_info; - conf.set_field_index(0); - mode_exec->setup_verification_grid(fcst, obs); - Grid g = mode_exec->grid; - delete mode_exec; mode_exec = 0; - return g; -} - - -/////////////////////////////////////////////////////////////////////// - -int -ModeFrontEnd::create_multivar_simple_objects( - const ModeConfInfo &config, - ModeDataType dtype, - const Grid &verification_grid, - const ModeInputData &input, - const string &filename, - const string &config_file, - const string &outdir, - int field_index, int n_files) - -{ - init(ModeExecutive::MULTIVAR_SIMPLE); - - mode_exec->out_dir = replace_path(default_out_dir); - if (dtype == ModeDataType_MvMode_Fcst) { - mode_exec->fcst_file = filename; - mode_exec->obs_file = "None"; - } else { - mode_exec->obs_file = filename; - mode_exec->fcst_file = "None"; - } - mode_exec->match_config_file = config_file; - mode_exec->out_dir = outdir; - mode_exec->init_multivar_simple(field_index, n_files, dtype, config); - - ModeConfInfo & conf = mode_exec->engine.conf_info; - - if (dtype == ModeDataType_MvMode_Fcst) { - mode_exec->setup_fcst_data(verification_grid, input); - } else { - mode_exec->setup_obs_data(verification_grid, input); - } - - // - // mode algorithm - // - if ( conf.quilt ) { - - do_quilt(); - - } else { - - do_straight(); - - } - - // - // done - // - -#ifdef WITH_PYTHON - GP.finalize(); -#endif - return (0); -} - -/////////////////////////////////////////////////////////////////////// - -int -ModeFrontEnd::create_multivar_merge_objects(const ModeConfInfo &config, - ModeDataType dtype, - const Grid &verification_grid, - const ModeInputData &input, - const string &filename, - const string &config_file, - const string &outdir, int field_index, - int n_files) -{ - init(ModeExecutive::MULTIVAR_SIMPLE_MERGE); - - mode_exec->out_dir = replace_path(default_out_dir); - if (dtype == ModeDataType_MvMode_Fcst) { - mode_exec->fcst_file = filename; - mode_exec->obs_file = "None"; - } else { - mode_exec->obs_file = filename; - mode_exec->fcst_file = "None"; - } - mode_exec->match_config_file = config_file; - mode_exec->out_dir = outdir; - - mode_exec->init_multivar_simple(field_index, n_files, dtype, config); - - ModeConfInfo & conf = mode_exec->engine.conf_info; - - if (dtype == ModeDataType_MvMode_Fcst) { - mode_exec->setup_fcst_data(verification_grid, input); - } else { - mode_exec->setup_obs_data(verification_grid, input); - } - - - // - // mode algorithm - // - if ( conf.quilt ) { - - do_quilt(); - - } else { - - do_straight(); - - } - - // - // done - // - -#ifdef WITH_PYTHON - GP.finalize(); -#endif - return (0); -} /////////////////////////////////////////////////////////////////////// int ModeFrontEnd::run_traditional(const StringArray & Argv) { - init(ModeExecutive::TRADITIONAL); + init(); int field_index = -1; int n_files = 1; @@ -220,7 +77,7 @@ int ModeFrontEnd::run_traditional(const StringArray & Argv) // Process the command line arguments // - process_command_line(Argv, false); + process_command_line(Argv); mode_exec->init_traditional(n_files); @@ -233,7 +90,7 @@ int ModeFrontEnd::run_traditional(const StringArray & Argv) // read in data // - mode_exec->setup_fcst_obs_data_traditional(); + mode_exec->setup_traditional_fcst_obs_data(); // // mode algorithm @@ -260,133 +117,6 @@ int ModeFrontEnd::run_traditional(const StringArray & Argv) /////////////////////////////////////////////////////////////////////// -int -ModeFrontEnd::multivar_intensity_comparisons(const ModeConfInfo &config, - const MultiVarData &mvdf, - const MultiVarData &mvdo, bool has_union_f, - bool has_union_o, const ShapeData &merge_f, - const ShapeData &merge_o, - int field_index_f, int field_index_o, - const string &fcst_filename, - const string &obs_filename, - const string &config_file, const string &dir) -{ - init(ModeExecutive::MULTIVAR_INTENSITY); - - mode_exec->out_dir = replace_path(default_out_dir); - mode_exec->fcst_file = fcst_filename; - mode_exec->obs_file = obs_filename; - mode_exec->match_config_file = config_file; - mode_exec->out_dir = dir; - - mode_exec->init_multivar_intensities(mvdf._type, mvdo._type, config); - - ModeConfInfo & conf = mode_exec->engine.conf_info; - conf.set_field_index(field_index_f, field_index_o); - - // for multivar intensities, explicity set the level and units using stored values - // from pass1 - conf.Fcst->var_info->set_level_name(mvdf._level.c_str()); - conf.Fcst->var_info->set_units(mvdf._units.c_str()); - if (has_union_f && conf.Fcst->merge_flag == MergeType_Thresh) { - mlog << Warning << "\nModeFrontEnd::multivar_intensity_comparisons() -> " - << "Logic includes union '||' along with 'merge_flag=THRESH' " - << ". This can lead to bad results\n\n"; - } - conf.Obs->var_info->set_level_name(mvdo._level.c_str()); - conf.Obs->var_info->set_units(mvdo._units.c_str()); - if (has_union_o && conf.Obs->merge_flag == MergeType_Thresh) { - mlog << Warning << "\nModeFrontEnd::multivar_intensity_comparisons() -> " - << "Logic includes union '||' along with 'merge_flag=THRESH' " - << ". This can lead to bad results\n\n"; - } - - // - // set up data access using inputs - // - mode_exec->setup_fcst_obs_data_multivar_intensities(mvdf, mvdo); - - // - // run the mode algorithm - // - - if ( conf.quilt ) { - - do_quilt(); - - } else { - - do_straight_multivar_intensity(mvdf, mvdo, merge_f, merge_o); - - } - - // - // done - // - -#ifdef WITH_PYTHON - GP.finalize(); -#endif - return (0); -} - -/////////////////////////////////////////////////////////////////////// - -int ModeFrontEnd::run_super(const ModeConfInfo &config, - const ModeSuperObject &fsuper, - const ModeSuperObject &osuper, - GrdFileType ftype, GrdFileType otype, const Grid &grid, - bool has_union, const string &config_file, const string &dir) -{ - init(ModeExecutive::MULTIVAR_SUPER); - - mode_exec->out_dir = replace_path(default_out_dir); - mode_exec->fcst_file = "not set"; - mode_exec->obs_file = "not set"; - mode_exec->match_config_file = config_file; - mode_exec->out_dir = dir; - - mode_exec->init_multivar_intensities(ftype, otype, config); - - ModeConfInfo & conf = mode_exec->engine.conf_info; - if (has_union && (conf.Fcst->merge_flag == MergeType_Thresh || - conf.Obs->merge_flag == MergeType_Thresh)) { - mlog << Warning << "\nModeFrontEnd::run_super() -> " - << "Logic includes union '||' along with 'merge_flag=THRESH' " - << ". This can lead to bad results\n\n"; - } - - // - // set up data access using inputs - // - mode_exec->setup_fcst_obs_data_multivar_super(fsuper._simple_sd, osuper._simple_sd, grid); - - // - // run the mode algorithm - // - - if ( conf.quilt ) { - - do_quilt(); - - } else { - - do_straight_multivar_super(fsuper._merge_sd_split, osuper._merge_sd_split); - - } - - // - // done - // - -#ifdef WITH_PYTHON - GP.finalize(); -#endif - return (0); -} - -/////////////////////////////////////////////////////////////////////// - void ModeFrontEnd::do_straight() @@ -399,12 +129,9 @@ void ModeFrontEnd::do_straight() for (int index=0; indexdo_conv_thresh(index, index); - if (ptype == ModeExecutive::TRADITIONAL) { - - mode_exec->do_match_merge(); - mode_exec->process_output(); - } + mode_exec->do_conv_thresh_traditional(index, index); + mode_exec->do_match_merge_traditional(); + mode_exec->process_output_traditional(); } mode_exec->clear_internal_r_index(); @@ -420,83 +147,9 @@ void ModeFrontEnd::do_straight() /////////////////////////////////////////////////////////////////////// -void ModeFrontEnd::do_straight_multivar_intensity(const MultiVarData &mvdf, - const MultiVarData &mvdo, - const ShapeData &f_merge, - const ShapeData &o_merge) - -{ - int NCT, NCR; - - do_straight_init(NCT, NCR); - - mode_exec->clear_internal_r_index(); - - for (int index=0; indexdo_conv_thresh(index, index); - mode_exec->do_match_merge(f_merge, o_merge); - - // here replace raw data and min/max for plotting - - mode_exec->process_output(&mvdf, &mvdo); - } - - mode_exec->clear_internal_r_index(); - - // - // done - // - - return; - -} - - - -/////////////////////////////////////////////////////////////////////// - - -void ModeFrontEnd::do_straight_multivar_super(const ShapeData &f_merge, - const ShapeData &o_merge) - -{ - int NCT, NCR; - - do_straight_init(NCT, NCR); - - mode_exec->clear_internal_r_index(); - - for (int index=0; indexdo_conv_thresh(index, index); - mode_exec->do_match_merge(f_merge, o_merge); - mode_exec->process_output(); - } - - mode_exec->clear_internal_r_index(); - - // - // done - // - - return; - -} - - -/////////////////////////////////////////////////////////////////////// - - void ModeFrontEnd::do_quilt() { - if (ptype != ModeExecutive::TRADITIONAL) { - mlog << Error << "\nModeFrontend::do_quilt() -> quilting not yet implemented for multivar mode \n\n"; - exit ( 1 ); - } - - int t_index, r_index; // indices into the convolution threshold and radius arrays @@ -505,14 +158,9 @@ void ModeFrontEnd::do_quilt() for (r_index=0; r_index<(mode_exec->n_conv_radii()); ++r_index) { for (t_index=0; t_index<(mode_exec->n_conv_threshs()); ++t_index) { - - mode_exec->do_conv_thresh(r_index, t_index); - - mode_exec->do_match_merge(); - - if (ptype == ModeExecutive::TRADITIONAL) { - mode_exec->process_output(); - } + mode_exec->do_conv_thresh_traditional(r_index, t_index); + mode_exec->do_match_merge_traditional(); + mode_exec->process_output_traditional(); } } @@ -528,29 +176,13 @@ void ModeFrontEnd::do_quilt() /////////////////////////////////////////////////////////////////////// -MultiVarData *ModeFrontEnd::get_multivar_data(ModeDataType dtype) +void ModeFrontEnd::init() { - return mode_exec->get_multivar_data(dtype); -} - - -/////////////////////////////////////////////////////////////////////// - -void ModeFrontEnd::add_multivar_merge_data(MultiVarData *mvdi, ModeDataType dtype) -{ - return mode_exec->add_multivar_merge_data(mvdi, dtype); -} - -/////////////////////////////////////////////////////////////////////// - -void ModeFrontEnd::init(ModeExecutive::Processing_t p) -{ - ptype = p; - mlog << Debug(1) << "Running multivar front end for " << ModeExecutive::stype(ptype) << "\n"; + mlog << Debug(1) << "Running traditional mode front end\n"; if ( mode_exec ) { delete mode_exec; mode_exec = 0; } - mode_exec = new ModeExecutive(ptype); + mode_exec = new ModeExecutive();//ModeExecutive::TRADITIONAL); compress_level = -1; } @@ -571,20 +203,12 @@ void ModeFrontEnd::do_straight_init(int &NCT, int &NCR) const exit ( 1 ); } - - if (NCT > 1 && ptype != ModeExecutive::TRADITIONAL) { - - mlog << Error << "\nModeFrontEnd::do_straight_init() ->" - << ": multiple convolution radii and thresholds not implemented in multivar mode\n\n"; - - exit ( 1 ); - } } /////////////////////////////////////////////////////////////////////// -void ModeFrontEnd::process_command_line(const StringArray & argv, bool ismultivar) +void ModeFrontEnd::process_command_line(const StringArray & argv) { CommandLine cline; ConcatString s; @@ -597,7 +221,7 @@ void ModeFrontEnd::process_command_line(const StringArray & argv, bool ismultiva mode_exec->out_dir = replace_path(default_out_dir); // - // Check for zero arguments (note not correct for multivar mode, want to show multivar_usage + // Check for zero arguments // if(argc == 1) singlevar_usage(); @@ -609,7 +233,7 @@ void ModeFrontEnd::process_command_line(const StringArray & argv, bool ismultiva cline.set(argv); // - // Set the usage function NOTE wrong for multivar, want multivar_usage + // Set the usage function // cline.set_usage(singlevar_usage); @@ -630,103 +254,19 @@ void ModeFrontEnd::process_command_line(const StringArray & argv, bool ismultiva cline.parse(); - if (ismultivar) { - // - // Check for error. There should be 1 argument left: - // config filename - // - if(cline.n() != 1) singlevar_usage(); // wrong need multivar usage - - // - // Store the input forecast and observation file names, placeholders - // - mode_exec->fcst_file = "not set"; - mode_exec->obs_file = "not set"; - mode_exec->match_config_file = cline[0]; - - } else { - // - // Check for error. There should be three arguments left: - // forecast, observation, and config filenames - // - if(cline.n() != 3) singlevar_usage(); - - // - // Store the input forecast and observation file names - // - mode_exec->fcst_file = cline[0]; - mode_exec->obs_file = cline[1]; - mode_exec->match_config_file = cline[2]; - - } -} - - -/////////////////////////////////////////////////////////////////////// - -void ModeFrontEnd::process_command_line_for_simple_objects(const StringArray &argv, ModeDataType dtype) -{ - CommandLine cline; - ConcatString s; - const int argc = argv.n(); - - // - // Set the default output directory - // - - mode_exec->out_dir = replace_path(default_out_dir); - - // - // Check for zero arguments (note not correct for multivar mode, want to show multivar_usage - // - - if(argc == 1) singlevar_usage(); - - // - // Parse the command line into tokens // - - cline.set(argv); - - // - // Set the usage function NOTE wrong for multivar, want multivar_usage + // Check for error. There should be three arguments left: + // forecast, observation, and config filenames // - - cline.set_usage(singlevar_usage); + if(cline.n() != 3) singlevar_usage(); // - // Add the options function calls + // Store the input forecast and observation file names // + mode_exec->fcst_file = cline[0]; + mode_exec->obs_file = cline[1]; + mode_exec->match_config_file = cline[2]; - cline.add(set_config_merge_file, "-config_merge", 1); - cline.add(set_outdir, "-outdir", 1); - cline.add(set_logfile, "-log", 1); - cline.add(set_verbosity, "-v", 1); - cline.add(set_compress, "-compress", 1); - - // - // Parse the command line - // - - cline.parse(); - - // - // Check for error. There should be two arguments left: - // data and config filenames - // - if(cline.n() != 2) singlevar_usage(); - - // - // Store the file name - // - if (dtype == ModeDataType_MvMode_Fcst) { - mode_exec->fcst_file = cline[0]; - mode_exec->obs_file = "None"; - } else { - mode_exec->obs_file = cline[0]; - mode_exec->fcst_file = "None"; - } - mode_exec->match_config_file = cline[1]; } /////////////////////////////////////////////////////////////////////// diff --git a/src/tools/core/mode/mode_frontend.h b/src/tools/core/mode/mode_frontend.h index f12b40eaa0..658f90ff4c 100644 --- a/src/tools/core/mode/mode_frontend.h +++ b/src/tools/core/mode/mode_frontend.h @@ -19,10 +19,6 @@ #include #include "mode_exec.h" #include "string_array.h" -#include "multivar_data.h" -#include "mode_input_data.h" -#include "mode_data_type.h" -#include "mode_superobject.h" class ModeFrontEnd { @@ -36,75 +32,21 @@ class ModeFrontEnd { string default_out_dir; - Grid create_verification_grid(const ModeInputData &fcst, - const ModeInputData &obs, - const string &config_file, - const ModeConfInfo &config); - - - // run the multivar simple object, where there is only one input data, either forecast or obs - int create_multivar_simple_objects(const ModeConfInfo &conf, - ModeDataType dtype, const Grid &verification_grid, - const ModeInputData &input, - const string &filename, const string &config_file, - const string &outdir, - int field_index=-1, int n_files=1); - - // run the multivar simple object merge algorithm, with one input data, either forecast or obs - int create_multivar_merge_objects(const ModeConfInfo &conf, - ModeDataType dtype, const Grid &verification_grid, - const ModeInputData &input, - const string &filename, const string &config_file, - const string &outdir, - int field_index=-1, int n_files=1); // run the default single var mode interface (traditional mode) int run_traditional(const StringArray & Argv); - // run the multivar intensity algorithm, where one forecast and one obs are restricted to be within superobjects - // and the traditional mode algorithm compares them - int multivar_intensity_comparisons(const ModeConfInfo &conf, - const MultiVarData &mvdf, const MultiVarData &mvdo, - bool has_union_f, bool has_union_o, const ShapeData &merge_f, - const ShapeData &merge_o, int field_index_f, int field_index_o, - const string &fcst_filename, const string &obs_filename, - const string &config_file, const string &dir); - - - // multivar superobject interface, with no intensities - int run_super(const ModeConfInfo &conf, - const ModeSuperObject &fsuper, - const ModeSuperObject &osuper, - GrdFileType ftype, GrdFileType otype, const Grid &grid, bool has_union, - const string &config_file, const string &dir); - + void init(); // so far only implemented for traditional mode void do_quilt (); - // MODE algorithm for traditional, multivar simple, or multivar merge cases + // MODE algorithm for traditional mode void do_straight (); - // MODE algorithm when doing multivar intensities - void do_straight_multivar_intensity (const MultiVarData &mvdf, - const MultiVarData &mvdo, - const ShapeData &mergef, - const ShapeData &mergeo); - - // MODE algorithm when doing multivar super with no intensities - void do_straight_multivar_super (const ShapeData &f_merge, - const ShapeData &o_merge); - - - MultiVarData *get_multivar_data(ModeDataType dtype); - - void add_multivar_merge_data(MultiVarData *mvdi, ModeDataType dtype); - - void init(ModeExecutive::Processing_t p); void do_straight_init(int &NCT, int &NCR) const; - void process_command_line_for_simple_objects(const StringArray &, ModeDataType dtype); - void process_command_line(const StringArray &, bool is_multivar); + void process_command_line(const StringArray &); static void set_config_merge_file (const StringArray &); static void set_outdir (const StringArray &); diff --git a/src/tools/core/mode/mode_superobject.cc b/src/tools/core/mode/mode_superobject.cc index c6e24dcff3..27d1c3092f 100644 --- a/src/tools/core/mode/mode_superobject.cc +++ b/src/tools/core/mode/mode_superobject.cc @@ -1,5 +1,70 @@ using namespace std; #include "mode_superobject.h" +#include "multivar_data.h" + +//////////////////////////////////////////////////////////////////////// +static void _mask_super(const string &name, int nx, int ny, DataPlane &data) +{ + + if (nx != data.nx() || ny != data.ny()) { + mlog << Error << "\nModeSuperObject::mask_data_super() -> " << name + << " :dimensions don't match " << nx << " " << ny + << " " << data.nx() << " " << data.ny() << "\n\n"; + + exit( 1 ); + } + + int nmasked=0, nkeep=0; + + for (int x=0; x " << name + << " :dimensions don't match " << nx << " " << ny + << " " << data.nx() << " " << data.ny() << "\n\n"; + + exit( 1 ); + } + + int nmasked=0, nkeep=0; + + for (int x=0; x &mvd, BoolCalc &calc) { + _hasUnion = calc.has_union(); + // // set the BoolPlane values using the mvd content // @@ -100,3 +167,18 @@ ModeSuperObject::ModeSuperObject(bool isFcst, int n_files, bool do_clusters, delete [] simple_plane; delete [] merge_plane; } + +void ModeSuperObject::mask_data_simple(const string &name, MultiVarData &mvd) const +{ + int nx = mvd._nx; + int ny = mvd._ny; + _mask(name, nx, ny, _simple_result, mvd._simple->_sd->data); +} + + +void ModeSuperObject::mask_data_super(const string &name, const MultiVarData &mvd) +{ + int nx = mvd._nx; + int ny = mvd._ny; + _mask_super(name, nx, ny, _simple_sd.data); +} diff --git a/src/tools/core/mode/mode_superobject.h b/src/tools/core/mode/mode_superobject.h index 10151e88ed..83278b20a6 100644 --- a/src/tools/core/mode/mode_superobject.h +++ b/src/tools/core/mode/mode_superobject.h @@ -22,6 +22,8 @@ #include #include +class MultiVarData; + class ModeSuperObject { private: @@ -33,7 +35,11 @@ class ModeSuperObject { BoolCalc &calc); inline ~ModeSuperObject() {} + void mask_data_simple(const string &name, MultiVarData &mvd) const; + void mask_data_super(const string &name, const MultiVarData &mvd); + bool _isFcst; + bool _hasUnion; BoolPlane _simple_result; ShapeData _simple_sd; ShapeData _merge_sd_split; diff --git a/src/tools/core/mode/multivar_frontend.cc b/src/tools/core/mode/multivar_frontend.cc index 1512bc8a83..4d88f37df5 100644 --- a/src/tools/core/mode/multivar_frontend.cc +++ b/src/tools/core/mode/multivar_frontend.cc @@ -6,199 +6,88 @@ // ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - -//////////////////////////////////////////////////////////////////////// - - -// for multivar mode, this is the default file -static const char mode_default_config [] = "MET_BASE/config/MODEMultivarConfig_default"; - -static const int dir_creation_mode = 0755; - //////////////////////////////////////////////////////////////////////// using namespace std; -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "vx_util.h" -#include "file_exists.h" -#include "two_d_array.h" -#include "get_filenames.h" -#include "mode_conf_info.h" -#include "shapedata.h" -#include "interest.h" -#include "met_file.h" -#include "mode_usage.h" -#include "mode_exec.h" - -#include "combine_boolplanes.h" -#include "objects_from_netcdf.h" -#include "parse_file_list.h" -#include "mode_frontend.h" -#include "multivar_data.h" -#include "mode_input_data.h" -#include "mode_data_type.h" +#include "multivar_frontend.h" -using namespace netCDF; +#include "mode_usage.h" +#ifdef WITH_PYTHON +#include "global_python.h" +#endif //////////////////////////////////////////////////////////////////////// extern const char * const program_name; - static const char sep [] = "===================================================="; -static const char tab [] = " "; - -// this is hardwired for the multivar case, at least for now -static const bool do_clusters = false; - -static string default_out_dir = "."; - -static ModeConfInfo config; - -static string mode_path; -static string fcst_fof; -static string obs_fof; -static string config_file; -static string outdir; +static string outdir; static int compress_level = -1; -static Grid verification_grid; - -//////////////////////////////////////////////////////////////////////// - - -static void set_outdir (const StringArray &); -static void set_logfile (const StringArray &); -static void set_verbosity (const StringArray &); -static void set_compress (const StringArray &); - -static void read_input(const string &name, int index, ModeDataType type, - GrdFileType f_t, GrdFileType other_t, int shift, - vector &inputs); - -static void multivar_consistency_checks(StringArray &fcst_filenames, StringArray &obs_filenames, - BoolCalc &f_calc, BoolCalc &o_calc, int &n_fcst_files, - int &n_obs_files); - -static ConcatString set_multivar_dir(); - -static void create_verification_grid(const ModeInputData &fcst, const ModeInputData &obs); - - -static MultiVarData *create_simple_objects(ModeDataType dtype, int j, int n_files, - const string &filename, - const ConcatString &dir, - const ModeInputData &input); - -static void create_intensity_comparisons(int findex, int oindex, - const ModeSuperObject &fsuper, - const ModeSuperObject &osuper, - const ConcatString &dir, - MultiVarData &mvdf, MultiVarData &mvdo, - bool has_union_f, bool has_union_o, - const string &fcst_filename, - const string &obs_filename); - -static void process_superobjects(ModeSuperObject &fsuper, - ModeSuperObject &osuper, - int nx, int ny, const ConcatString &dir, - GrdFileType ftype, GrdFileType otype, const Grid &grid, - bool has_union); - -static void mask_data(const string &name, int nx, int ny, const BoolPlane &mask, - DataPlane &data); -static void mask_data_super(const string &name, int nx, int ny, DataPlane &data); +// for multivar mode, this is the default file +static const char mode_default_config [] = "MET_BASE/config/MODEMultivarConfig_default"; -static void read_config(const string & filename); +static const int dir_creation_mode = 0755; -static void process_command_line(const StringArray &); +static ModeExecutive *mode_exec = 0; -static int _mkdir(const char *dir); //////////////////////////////////////////////////////////////////////// - -int multivar_frontend(const StringArray & Argv) - +MultivarFrontEnd::MultivarFrontEnd() { + // this is hardwired for the multivar case, at least for now + do_clusters = false; + default_out_dir = "."; + compress_level = -1; + mode_exec = 0; +} - const int Argc = Argv.n(); - - if ( Argc < 4 ) multivar_usage(); - - int j, n_fcst_files, n_obs_files; - StringArray fcst_filenames; - StringArray obs_filenames; - BoolCalc f_calc, o_calc ; - - // set some logging related things here, used in all further processing +//////////////////////////////////////////////////////////////////////// - process_command_line(Argv); +int MultivarFrontEnd::run(const StringArray & Argv) - // read the config as fully as possible without any data reads - // (Initialize all the input fields) - - read_config(config_file); +{ - // check for length discrepencies. + // initialize - multivar_consistency_checks(fcst_filenames, obs_filenames, f_calc, o_calc, - n_fcst_files, n_obs_files); + init(Argv); mlog << Debug(2) << "\n" << sep << "\n"; - ConcatString dir = set_multivar_dir(); - // read in all the data - vector fcstInput, obsInput; - GrdFileType ft, ot; - // in the conf object, shift *can* be set independently for obs and fcst int shift = config.shift_right; for (int i=0; i mvdObs, mvdFcst; - - for (j=0; j 0) { mvdFcst[0]->checkFileTypeConsistency(*mvdi, j); } @@ -220,11 +110,14 @@ int multivar_frontend(const StringArray & Argv) mvdi->print(); } // for j - for (j=0; j 0) { mvdObs[0]->checkFileTypeConsistency(*mvdi, j); } @@ -240,11 +133,9 @@ int multivar_frontend(const StringArray & Argv) ModeSuperObject osuper(true, n_obs_files, do_clusters, mvdObs, o_calc); // - // Filter the data to within the superobjects only and do statistics by invoking mode algorithm again - // on the masked data pairs + // Filter the data to within the superobjects only and do statistics by invoking mode + // algorithm again on the masked data pairs // - bool f_has_union = f_calc.has_union(); - bool o_has_union = o_calc.has_union(); for (int k=0; k_nx; - int ny = mvdFcst[0]->_ny; - GrdFileType ftype = mvdFcst[0]->_type; - GrdFileType otype = mvdObs[0]->_type; - Grid grid = *(mvdFcst[0]->_grid); + if (config.fcst_multivar_compare_index.n() <= 0) { - // here run one more time using superobjects as input + process_superobjects(fsuper, osuper, *mvdFcst[0], *mvdObs[0]); + } + + // + // done + // + return (0); +} - bool has_union = f_calc.has_union() || o_calc.has_union(); +//////////////////////////////////////////////////////////////////////// - process_superobjects(fsuper, osuper, nx, ny, dir, ftype, otype, grid, has_union); +MultivarFrontEnd::~MultivarFrontEnd() +{ + if ( mode_exec ) { + delete mode_exec; mode_exec = 0; } - - // free up memory - for (j=0; jgrid(); + GrdFileType ft = f->file_type(); + + //? + f->set_shift_right(shift); + + // update config now that we know file type (this sets Fcst to index i) + DataPlane dp; + + if (type == ModeDataType_MvMode_Fcst) { + config.process_config_field(ft, other_t, type, index); + f->data_plane(*(config.Fcst->var_info), dp); + fcstInput.push_back(ModeInputData(name, dp, g, ft)); + } else { + config.process_config_field(other_t, ft, type, index); + f->data_plane(*(config.Obs->var_info), dp); + obsInput.push_back(ModeInputData(name, dp, g, ft)); + } + + delete f; +} + //////////////////////////////////////////////////////////////////////// +void MultivarFrontEnd::create_verif_grid() +{ + mlog << Debug(2) << "\n creating the verification grid \n" << sep << "\n"; + + _init_exec(ModeExecutive::TRADITIONAL, "None", "None"); + // mode_exec->init_multivar_verif_grid(fcstInput[0]._dataPlane, + // obsInput[0]._dataPlane, config); + // ModeConfInfo & conf = mode_exec->engine.conf_info; + // conf.set_field_index(0); + mode_exec->setup_verification_grid(fcstInput[0], obsInput[0], config); + verification_grid = mode_exec->grid; + delete mode_exec; mode_exec = 0; +} -void read_config(const string & filename) +//////////////////////////////////////////////////////////////////////// +MultiVarData *MultivarFrontEnd::create_simple_objects(ModeDataType dtype, int j, + int n_files, + const string &filename, + const ModeInputData &input) { + // + // create simple non merged objects + // + _simple_objects(ModeExecutive::MULTIVAR_SIMPLE, dtype, j, n_files, + filename, input); + MultiVarData *mvdi = mode_exec->get_multivar_data(dtype); + delete mode_exec; mode_exec = 0; - ConcatString path; + // + // create simple merged objects + // + _simple_objects(ModeExecutive::MULTIVAR_SIMPLE_MERGE, dtype, j, n_files, + filename, input); + mode_exec->add_multivar_merge_data(mvdi, dtype); + delete mode_exec; mode_exec = 0; + return mvdi; +} - path = replace_path(mode_default_config); +//////////////////////////////////////////////////////////////////////// - config.read_config(path.c_str(), filename.c_str()); +void +MultivarFrontEnd::create_intensity_comparisons(int findex, int oindex, + const ModeSuperObject &fsuper, + const ModeSuperObject &osuper, + MultiVarData &mvdf, MultiVarData &mvdo, + const string &fcst_filename, + const string &obs_filename) +{ - // process the config except for the fields - config.process_config_except_fields(); + // mask the input data to be valid only inside the simple super objects + fsuper.mask_data_simple("Fcst", mvdf); + osuper.mask_data_simple("Obs", mvdo); - // done once here, used for all data - // what is this, command line overrides config? look deeper.. remove from exec - // except traditional mode - if (compress_level >= 0) config.nc_info.set_compress_level(compress_level); - // from within mode_exec: - // engine.conf_info.nc_info.compress_level = engine.conf_info.get_compression_level(); + mlog << Debug(1) << "Running mvmode intensity comparisions \n\n"; + _init_exec(ModeExecutive::MULTIVAR_INTENSITY, fcst_filename, obs_filename); + mode_exec->init_multivar_intensities(mvdf._type, mvdo._type, config); - return; + ModeConfInfo & conf = mode_exec->engine.conf_info; + conf.set_field_index(findex, oindex); -} + // for multivar intensities, explicity set the level and units using stored values + // from pass1 + conf.Fcst->var_info->set_level_name(mvdf._level.c_str()); + conf.Fcst->var_info->set_units(mvdf._units.c_str()); + if (fsuper._hasUnion && conf.Fcst->merge_flag == MergeType_Thresh) { + mlog << Warning << "\nModeFrontEnd::multivar_intensity_comparisons() -> " + << "Logic includes union '||' along with 'merge_flag=THRESH' " + << ". This can lead to bad results\n\n"; + } + conf.Obs->var_info->set_level_name(mvdo._level.c_str()); + conf.Obs->var_info->set_units(mvdo._units.c_str()); + if (osuper._hasUnion && conf.Obs->merge_flag == MergeType_Thresh) { + mlog << Warning << "\nModeFrontEnd::multivar_intensity_comparisons() -> " + << "Logic includes union '||' along with 'merge_flag=THRESH' " + << ". This can lead to bad results\n\n"; + } + + // + // set up data access using inputs + // + mode_exec->setup_multivar_fcst_obs_data_intensities(mvdf, mvdo); + + // + // run the mode algorithm for multivar intensities + // + _intensity_compare_mode_algorithm(mvdf, mvdo, fsuper, osuper); + delete mode_exec; mode_exec = 0; +} //////////////////////////////////////////////////////////////////////// +void MultivarFrontEnd::process_superobjects(ModeSuperObject &fsuper, + ModeSuperObject &osuper, + const MultiVarData &mvdf, + const MultiVarData &mvdo) +{ + mlog << Debug(1) << "Running superobject mode \n\n"; + + // set the data to 0 inside superobjects and missing everywhere else + + fsuper.mask_data_super("FcstSimple", mvdf); + osuper.mask_data_super("ObsSimple", mvdo); -void process_command_line(const StringArray & argv) + _init_exec(ModeExecutive::MULTIVAR_SUPER, "None", "None"); + mode_exec->init_multivar_intensities(mvdf._type, mvdo._type, config); + + ModeConfInfo & conf = mode_exec->engine.conf_info; + if ((fsuper._hasUnion || osuper._hasUnion) && + (conf.Fcst->merge_flag == MergeType_Thresh || + conf.Obs->merge_flag == MergeType_Thresh)) { + mlog << Warning << "\nModeFrontEnd::run_super() -> " + << "Logic includes union '||' along with 'merge_flag=THRESH' " + << ". This can lead to bad results\n\n"; + } + + // + // set up data access using inputs + // + mode_exec->setup_multivar_fcst_obs_data_super(fsuper._simple_sd, osuper._simple_sd, + *mvdf._grid); + + // run the mode algorithm + _superobject_mode_algorithm(fsuper, osuper); + + delete mode_exec; mode_exec = 0; +} + +//////////////////////////////////////////////////////////////////////// + +void MultivarFrontEnd::_process_command_line(const StringArray & argv) { @@ -411,57 +454,45 @@ void process_command_line(const StringArray & argv) // should be 3 arguments left // - fcst_fof = cline[0]; obs_fof = cline[1]; config_file = cline[2]; - return; } //////////////////////////////////////////////////////////////////////// -void read_input(const string &name, int index, ModeDataType type, - GrdFileType f_t, GrdFileType other_t, int shift, - vector &inputs) - { - Met2dDataFileFactory mtddf_factory; - Met2dDataFile *f = mtddf_factory.new_met_2d_data_file(name.c_str(), f_t); - if (!f) { - mlog << Error << "\nTrouble reading fcst file \"" - << name << "\"\n\n"; - exit(1); - } - Grid g = f->grid(); - GrdFileType ft = f->file_type(); - - //? - f->set_shift_right(shift); - - // update config now that we know file type (this sets Fcst to index i) - DataPlane dp; - - if (type == ModeDataType_MvMode_Fcst) { - config.process_config_field(ft, other_t, type, index); - // need to have set the var_info! - f->data_plane(*(config.Fcst->var_info), dp); - } else { - config.process_config_field(other_t, ft, type, index); - // need to have set the var_info! - f->data_plane(*(config.Obs->var_info), dp); - } - - inputs.push_back(ModeInputData(name, dp, g, ft)); - delete f; - } - + +void MultivarFrontEnd::_read_config(const string & filename) + +{ + + ConcatString path; + + path = replace_path(mode_default_config); + + config.read_config(path.c_str(), filename.c_str()); + + // process the config except for the fields + config.process_config_except_fields(); + + // done once here, used for all data + // what is this, command line overrides config? look deeper.. remove from exec + // except traditional mode + if (compress_level >= 0) config.nc_info.set_compress_level(compress_level); + // from within mode_exec: + // engine.conf_info.nc_info.compress_level = engine.conf_info.get_compression_level(); + + + return; + +} + //////////////////////////////////////////////////////////////////////// -void multivar_consistency_checks(StringArray &fcst_filenames, StringArray &obs_filenames, - BoolCalc &f_calc, BoolCalc &o_calc, int &n_fcst_files, - int &n_obs_files) +void MultivarFrontEnd::_setup_inputs() { // // make sure the multivar logic programs are in the config file @@ -547,234 +578,190 @@ void multivar_consistency_checks(StringArray &fcst_filenames, StringArray &obs_f //////////////////////////////////////////////////////////////////////// -ConcatString set_multivar_dir() +void MultivarFrontEnd::_set_output_path() { - ConcatString dir; int status; - dir.clear(); + output_path.clear(); // no longer want numbered subdirectories - if ( outdir.length() > 0 ) dir << outdir; + if ( outdir.length() > 0 ) output_path << outdir; // // test to see of the output directory for this // mode runs exists, and if not, create it // - if ( ! directory_exists(dir.c_str()) ) { + if ( ! directory_exists(output_path.c_str()) ) { mlog << Debug(2) << program_name << ": creating output directory \"" - << dir << "\"\n\n"; + << output_path << "\"\n\n"; - status = _mkdir(dir.c_str()); + status = _mkdir(output_path.c_str()); if ( status < 0 ) { mlog << Error << "\nset_multivar_dir() ->" << " unable to create output directory \"" - << dir << "\"\n\n"; + << output_path << "\"\n\n"; exit ( 1 ); } } - return dir; } //////////////////////////////////////////////////////////////////////// -void create_verification_grid(const ModeInputData &fcst, - const ModeInputData &obs) +int MultivarFrontEnd::_mkdir(const char *dir) { - ModeFrontEnd *frontend = new ModeFrontEnd; - verification_grid = frontend->create_verification_grid(fcst, obs, - config_file, - config); - delete frontend; + char tmp[256]; + char *p = NULL; + size_t len; + + snprintf(tmp, sizeof(tmp),"%s",dir); + len = strlen(tmp); + if (tmp[len - 1] == '/') + tmp[len - 1] = 0; + for (p = tmp + 1; *p; p++) + if (*p == '/') { + *p = 0; + string s = tmp; + if (s != ".") { + if (mkdir(tmp, dir_creation_mode) < 0) { + mlog << Error << "\n_mkdir() -> Error making " << tmp << "\n"; + return -1; + } + } + *p = '/'; + } + + return (mkdir(tmp, dir_creation_mode)); } //////////////////////////////////////////////////////////////////////// -MultiVarData *create_simple_objects(ModeDataType dtype, int j, int n_files, - const string &filename, - const ConcatString &dir, - const ModeInputData &input) +void MultivarFrontEnd::_simple_objects(ModeExecutive::Processing_t p, + ModeDataType dtype, + int j, int n_files, const string &filename, + const ModeInputData &input) { - ModeFrontEnd *frontend = new ModeFrontEnd; - int status = - frontend->create_multivar_simple_objects(config, dtype, verification_grid, input, - filename, config_file, dir, - j, n_files); - MultiVarData *mvdi = frontend->get_multivar_data(dtype); - delete frontend; + if (dtype == ModeDataType_MvMode_Fcst) { + _init_exec(p, filename, "None"); + mode_exec->init_multivar_simple(j, n_files, dtype, config); + mode_exec->setup_multivar_fcst_data(verification_grid, input); + } else { + _init_exec(p, "None", filename); + mode_exec->init_multivar_simple(j, n_files, dtype, config); + mode_exec->setup_multivar_obs_data(verification_grid, input); + } + + _simple_mode_algorithm(p); +} - // - // create simple merge objects - // +//////////////////////////////////////////////////////////////////////// - frontend = new ModeFrontEnd; - status = frontend->create_multivar_merge_objects(config, dtype, verification_grid, input, - filename, config_file, dir, - j, n_files); +void MultivarFrontEnd::_init_exec(ModeExecutive::Processing_t p, + const string &ffile, + const string &ofile) +{ + mlog << Debug(1) << "Running multivar front end for " << ModeExecutive::stype(p) << "\n"; - // add the merge results to the mvdi object - frontend->add_multivar_merge_data(mvdi, dtype); - delete frontend; + if ( mode_exec ) { delete mode_exec; mode_exec = 0; } - return mvdi; + mode_exec = new ModeExecutive(); + // compress_level = -1; + mode_exec->fcst_file = ffile; + mode_exec->obs_file = ofile; + mode_exec->match_config_file = config_file; + mode_exec->out_dir = output_path; } //////////////////////////////////////////////////////////////////////// void -create_intensity_comparisons(int findex, int oindex, - const ModeSuperObject &fsuper, - const ModeSuperObject &osuper, - const ConcatString &dir, - MultiVarData &mvdf, MultiVarData &mvdo, - bool has_union_f, bool has_union_o, - const string &fcst_filename, - const string &obs_filename) +MultivarFrontEnd::_superobject_mode_algorithm(const ModeSuperObject &fsuper, + const ModeSuperObject &osuper) { - - // mask the input data to be valid only inside the simple super objects - int nx = mvdf._nx; - int ny = mvdf._ny; - - mask_data("Fcst", nx, ny, fsuper._simple_result, mvdf._simple->_sd->data); - mask_data("Obs", nx, ny, osuper._simple_result, mvdo._simple->_sd->data); - - mlog << Debug(1) << "Running mvmode intensity comparisions \n\n"; - - ModeFrontEnd *frontend = new ModeFrontEnd; - int status = frontend->multivar_intensity_comparisons(config, mvdf, mvdo, has_union_f, - has_union_o, - fsuper._merge_sd_split, - osuper._merge_sd_split, - findex, - oindex, - fcst_filename, - obs_filename, - config_file, dir); - delete frontend; + _mode_algorithm_init(); + mode_exec->clear_internal_r_index(); + mode_exec->do_conv_thresh_multivar_super(); + mode_exec->do_match_merge_multivar(fsuper._merge_sd_split, osuper._merge_sd_split, + ModeExecutive::MULTIVAR_SUPER); + mode_exec->process_output_multivar_super(); + mode_exec->clear_internal_r_index(); +#ifdef WITH_PYTHON + GP.finalize(); + #endif } //////////////////////////////////////////////////////////////////////// -void process_superobjects(ModeSuperObject &fsuper, - ModeSuperObject &osuper, - int nx, int ny, const ConcatString &dir, - GrdFileType ftype, GrdFileType otype, - const Grid &grid, bool has_union) +void +MultivarFrontEnd::_intensity_compare_mode_algorithm(const MultiVarData &mvdf, + const MultiVarData &mvdo, + const ModeSuperObject &fsuper, + const ModeSuperObject &osuper) { - mlog << Debug(1) << "Running superobject mode \n\n"; + _mode_algorithm_init(); + mode_exec->do_conv_thresh_multivar_intensity_compare(); + mode_exec->do_match_merge_multivar(fsuper._merge_sd_split, osuper._merge_sd_split, + ModeExecutive::MULTIVAR_INTENSITY); + // here replace raw data and min/max for plotting + mode_exec->process_output_multivar_intensity_compare(&mvdf, &mvdo); + mode_exec->clear_internal_r_index(); +#ifdef WITH_PYTHON + GP.finalize(); + #endif +} - // set the data to 0 inside superobjects and missing everywhere else - mask_data_super("FcstSimple", nx, ny, fsuper._simple_sd.data); - mask_data_super("ObsSimple", nx, ny, osuper._simple_sd.data); - - - ModeFrontEnd *frontend = new ModeFrontEnd; - - int status = frontend->run_super(config, fsuper, osuper, - ftype, otype, grid, has_union, - config_file, dir); - delete frontend; -} - //////////////////////////////////////////////////////////////////////// -void mask_data(const string &name, int nx, int ny, const BoolPlane &bp, DataPlane &data) +void MultivarFrontEnd::_simple_mode_algorithm(ModeExecutive::Processing_t p) { - - if (nx != data.nx() || ny != data.ny()) { - mlog << Error << "\nmask_data() -> " << name - << " :dimensions don't match " << nx << " " << ny - << " " << data.nx() << " " << data.ny() << "\n\n"; - - exit( 1 ); - } - - int nmasked=0, nkeep=0; + _mode_algorithm_init(); + mode_exec->clear_internal_r_index(); + mode_exec->do_conv_thresh_multivar_simple(p); + mode_exec->clear_internal_r_index(); - for (int x=0; xengine.conf_info; + if ( conf.quilt ) { + mlog << Error << "\nMultiVarFontend::mode_algorithm() -> " + << "quilting not yet implemented for multivar mode \n\n"; + exit ( 1 ); } - - mlog << Debug(1) << name << " superobject masking.." - << nkeep << " points of " - << nmasked + nkeep << " in superobjects\n"; -} + int NCT = conf.n_conv_threshs(); + int NCR = conf.n_conv_radii(); + if ( NCT != NCR ) { -//////////////////////////////////////////////////////////////////////// -void mask_data_super(const string &name, int nx, int ny, DataPlane &data) -{ + mlog << Error << "\nMultivarFrontEnd::_mode_algorithm_init() ->" + << "all convolution radius and threshold arrays must have the same number of elements\n\n"; - if (nx != data.nx() || ny != data.ny()) { - mlog << Error << "\nmask_data_super() -> " << name - << " :dimensions don't match " << nx << " " << ny - << " " << data.nx() << " " << data.ny() << "\n\n"; + exit ( 1 ); - exit( 1 ); } - int nmasked=0, nkeep=0; - - for (int x=0; x 1) { - for (int y=0; y" + << ": multiple convolution radii and thresholds not implemented in multivar mode\n\n"; - if(is_bad_data(data.get(x,y))) { - nmasked ++; - } else { - data.set(0.0, x, y); - nkeep ++; - } - } + exit ( 1 ); } - - mlog << Debug(1) << name << " superobject masking.." - << nkeep << " points of " - << nmasked + nkeep << " in superobjects\n"; } -//////////////////////////////////////////////////////////////////////// - -int _mkdir(const char *dir) -{ - char tmp[256]; - char *p = NULL; - size_t len; - snprintf(tmp, sizeof(tmp),"%s",dir); - len = strlen(tmp); - if (tmp[len - 1] == '/') - tmp[len - 1] = 0; - for (p = tmp + 1; *p; p++) - if (*p == '/') { - *p = 0; - string s = tmp; - if (s != ".") { - if (mkdir(tmp, dir_creation_mode) < 0) { - mlog << Error << "\n_mkdir() -> Error making " << tmp << "\n"; - return -1; - } - } - *p = '/'; - } - return (mkdir(tmp, dir_creation_mode)); -} + diff --git a/src/tools/core/mode/multivar_frontend.h b/src/tools/core/mode/multivar_frontend.h new file mode 100644 index 0000000000..a518bc5d31 --- /dev/null +++ b/src/tools/core/mode/multivar_frontend.h @@ -0,0 +1,106 @@ +// ** Copyright UCAR (c) 1992 - 2023 +// ** University Corporation for Atmospheric Research (UCAR) +// ** National Center for Atmospheric Research (NCAR) +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + + +//////////////////////////////////////////////////////////////////////// + + +#ifndef __MULTIVAR_FRONTEND_H__ +#define __MULTIVAR_FRONTEND_H__ + + +//////////////////////////////////////////////////////////////////////// + +#include +#include "mode_conf_info.h" +#include "two_d_array.h" +#include "bool_calc.h" +#include "multivar_data.h" +#include "mode_superobject.h" +#include "mode_input_data.h" +#include "mode_exec.h" + +class MultivarFrontEnd { + +private: + + int n_fcst_files, n_obs_files; + StringArray fcst_filenames; + StringArray obs_filenames; + BoolCalc f_calc, o_calc ; + vector fcstInput, obsInput; + vector mvdFcst, mvdObs; + string fcst_fof; + string obs_fof; + + void _process_command_line(const StringArray &); + void _read_config(const string & filename); + void _setup_inputs(); + void _set_output_path(); + int _mkdir(const char *dir); + void _simple_objects(ModeExecutive::Processing_t p, ModeDataType dtype, + int j, int n_files, const string &filename, + const ModeInputData &input); + void _init_exec(ModeExecutive::Processing_t p, const string &ffile, const string &ofile); + void _superobject_mode_algorithm(const ModeSuperObject &fsuper, const ModeSuperObject &osuper); + void _intensity_compare_mode_algorithm(const MultiVarData &mvdf, const MultiVarData &mvdo, + const ModeSuperObject &fsuper, const ModeSuperObject &osuper); + void _simple_mode_algorithm(ModeExecutive::Processing_t p); + void _mode_algorithm_init() const; + +public: + + bool do_clusters; + string default_out_dir; + ModeConfInfo config; + ConcatString output_path; + string mode_path; + string config_file; + Grid verification_grid; + + MultivarFrontEnd(); + + ~MultivarFrontEnd(); + + + int run(const StringArray & Argv); + void init(const StringArray & Argv); + + static void set_outdir (const StringArray &); + static void set_logfile (const StringArray &); + static void set_verbosity (const StringArray &); + static void set_compress (const StringArray &); + + void read_input(const string &name, int index, ModeDataType type, + GrdFileType f_t, GrdFileType other_t, int shift); + + + void create_verif_grid(void); + + MultiVarData *create_simple_objects(ModeDataType dtype, int j, int n_files, + const string &filename, + const ModeInputData &input); + + void create_intensity_comparisons(int findex, int oindex, + const ModeSuperObject &fsuper, + const ModeSuperObject &osuper, + MultiVarData &mvdf, MultiVarData &mvdo, + const string &fcst_filename, + const string &obs_filename); + + void process_superobjects(ModeSuperObject &fsuper, + ModeSuperObject &osuper, + const MultiVarData &mvdf, + const MultiVarData &mvdo); + +}; + + +#endif /* __MULTIVAR_FRONT_END_H__ */ + + +/////////////////////////////////////////////////////////////////////////