Skip to content

Commit

Permalink
Per #2924, update the logic of parse_conf_regrid() to (hopefully) mak…
Browse files Browse the repository at this point in the history
…e it work the way @georgemccabe expects it to. It now uses pointers to both the primary and default dictionaries and parses each entry individually.
  • Loading branch information
JohnHalleyGotway committed Sep 12, 2024
1 parent 6edd245 commit 1563d97
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 75 deletions.
175 changes: 134 additions & 41 deletions src/basic/vx_config/config_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "config_util.h"
#include "enum_as_int.hpp"
#include "configobjecttype_to_string.h"

#include "vx_math.h"
#include "vx_util.h"
Expand Down Expand Up @@ -1334,10 +1335,10 @@ BootInfo parse_conf_boot(Dictionary *dict) {

///////////////////////////////////////////////////////////////////////////////

RegridInfo parse_conf_regrid(Dictionary *dict, bool error_out) {
Dictionary *regrid_dict = (Dictionary *) nullptr;
RegridInfo parse_conf_regrid(Dictionary *dict, Dictionary *default_dict, bool error_out) {
Dictionary *regrid_dict = nullptr;
Dictionary *regrid_default = nullptr;
RegridInfo info;
int v;

if(!dict) {
mlog << Error << "\nparse_conf_regrid() -> "
Expand All @@ -1348,8 +1349,13 @@ RegridInfo parse_conf_regrid(Dictionary *dict, bool error_out) {
// Conf: regrid
regrid_dict = dict->lookup_dictionary(conf_key_regrid, false);

// Dictionary with default settings
if(default_dict) {
regrid_default = default_dict->lookup_dictionary(conf_key_regrid, false);
}

// Check that the regrid dictionary is present
if(!regrid_dict) {
if(!regrid_dict && !regrid_default) {
if(error_out) {
mlog << Error << "\nparse_conf_regrid() -> "
<< "can't find the \"regrid\" dictionary!\n\n";
Expand All @@ -1360,61 +1366,148 @@ RegridInfo parse_conf_regrid(Dictionary *dict, bool error_out) {
}
}

// Parse to_grid as an integer
v = regrid_dict->lookup_int(conf_key_to_grid, false, false);
// Conf: to_grid (optional) as an integer or string
const DictionaryEntry * entry = regrid_dict->lookup(conf_key_to_grid, false);
if(!entry) entry = regrid_default->lookup(conf_key_to_grid, false);

// If integer lookup successful, convert to FieldType.
if(regrid_dict->last_lookup_status()) {
info.field = int_to_fieldtype(v);
info.enable = (info.field == FieldType::Fcst ||
info.field == FieldType::Obs);
// to_grid found
if(entry) {

// Convert integer to FieldType
if(entry->type() == IntegerType) {
info.field = int_to_fieldtype(entry->i_value());
info.enable = (info.field == FieldType::Fcst ||
info.field == FieldType::Obs);
}
// Store grid name string
else if(entry->type() == StringType) {
info.name = entry->string_value();
info.enable = true;
}
else {
mlog << Error << "\nparse_conf_regrid() -> "
<< "Unexpected type ("
<< configobjecttype_to_string(entry->type())
<< ") for \"" << conf_key_to_grid
<< "\" configuration entry.\n\n";
exit(1);
}
}
// If integer lookup unsuccessful, parse vx_grid as a string.
// Do not error out since to_grid isn't specified for climo.regrid.
// to_grid not found
else {
info.name = regrid_dict->lookup_string(conf_key_to_grid, false);
info.name = "";
info.enable = true;
}

// Conf: vld_thresh
double thr = regrid_dict->lookup_double(conf_key_vld_thresh, false);
info.vld_thresh = (is_bad_data(thr) ? default_vld_thresh : thr);
// Conf: vld_thresh (required)
double v_dbl = bad_data_double;
if(regrid_dict && regrid_dict->lookup(conf_key_vld_thresh, false)) {
v_dbl = regrid_dict->lookup_double(conf_key_vld_thresh);
}
else if(regrid_default && regrid_default->lookup(conf_key_vld_thresh, false)) {
v_dbl = regrid_default->lookup_double(conf_key_vld_thresh);
}
info.vld_thresh = (is_bad_data(v_dbl) ? default_vld_thresh : v_dbl);

// Parse the method and width
info.method = int_to_interpmthd(regrid_dict->lookup_int(conf_key_method));
info.width = regrid_dict->lookup_int(conf_key_width);
// Conf: method (required)
int v_int = bad_data_int;
if(regrid_dict && regrid_dict->lookup(conf_key_method, false)) {
v_int = regrid_dict->lookup_int(conf_key_method);
}
else if(regrid_default && regrid_default->lookup(conf_key_method, false)) {
v_int = regrid_default->lookup_int(conf_key_method);
}
info.method = int_to_interpmthd(v_int);

// Conf: shape
v = regrid_dict->lookup_int(conf_key_shape, false);
if (regrid_dict->last_lookup_status()) {
info.shape = int_to_gridtemplate(v);
// Conf: width (required)
v_int = bad_data_int;
if(regrid_dict && regrid_dict->lookup(conf_key_width, false)) {
v_int = regrid_dict->lookup_int(conf_key_width);
}
else {
// If not specified, use the default square shape
info.shape = GridTemplateFactory::GridTemplates::Square;
else if(regrid_default && regrid_default->lookup(conf_key_width, false)) {
v_int = regrid_default->lookup_int(conf_key_width);
}
info.width = v_int;

// Conf: gaussian dx and radius
double conf_value = regrid_dict->lookup_double(conf_key_gaussian_dx, false);
info.gaussian.dx = (is_bad_data(conf_value) ? default_gaussian_dx : conf_value);
conf_value = regrid_dict->lookup_double(conf_key_gaussian_radius, false);
info.gaussian.radius = (is_bad_data(conf_value) ? default_gaussian_radius : conf_value);
conf_value = regrid_dict->lookup_double(conf_key_trunc_factor, false);
info.gaussian.trunc_factor = (is_bad_data(conf_value) ? default_trunc_factor : conf_value);
if (info.method == InterpMthd::Gaussian || info.method == InterpMthd::MaxGauss) info.gaussian.compute();
// Conf: shape (optional)
v_int = bad_data_int;
if(regrid_dict && regrid_dict->lookup(conf_key_shape, false)) {
v_int = regrid_dict->lookup_int(conf_key_shape);
}
else if(regrid_default && regrid_default->lookup(conf_key_shape, false)) {
v_int = regrid_default->lookup_int(conf_key_shape);
}
// Default is square
info.shape = (is_bad_data(v_int) ?
GridTemplateFactory::GridTemplates::Square :
int_to_gridtemplate(v_int));

// Conf: gaussian_dx (optional)
v_dbl = bad_data_double;
if(regrid_dict && regrid_dict->lookup(conf_key_gaussian_dx, false)) {
v_dbl = regrid_dict->lookup_double(conf_key_gaussian_dx);
}
else if(regrid_default && regrid_default->lookup(conf_key_gaussian_dx, false)) {
v_dbl = regrid_default->lookup_double(conf_key_gaussian_dx);
}
info.gaussian.dx = (is_bad_data(v_dbl) ? default_gaussian_dx : v_dbl);

// Conf: gaussian_radius (optional)
v_dbl = bad_data_double;
if(regrid_dict && regrid_dict->lookup(conf_key_gaussian_radius, false)) {
v_dbl = regrid_dict->lookup_double(conf_key_gaussian_radius);
}
else if(regrid_default && regrid_default->lookup(conf_key_gaussian_radius, false)) {
v_dbl = regrid_default->lookup_double(conf_key_gaussian_radius);
}
info.gaussian.radius = (is_bad_data(v_dbl) ?
default_gaussian_radius :
v_dbl);

// Conf: gaussian_trunc_factor (optional)
v_dbl = bad_data_double;
if(regrid_dict && regrid_dict->lookup(conf_key_trunc_factor, false)) {
v_dbl = regrid_dict->lookup_double(conf_key_trunc_factor);
}
else if(regrid_default && regrid_default->lookup(conf_key_trunc_factor, false)) {
v_dbl = regrid_default->lookup_double(conf_key_trunc_factor);
}
info.gaussian.trunc_factor = (is_bad_data(v_dbl) ?
default_trunc_factor :
v_dbl);

if(info.method == InterpMthd::Gaussian ||
info.method == InterpMthd::MaxGauss) {
info.gaussian.compute();
}

// MET#2437 Do not search the higher levels of config file context for convert,
// censor_thresh, and censor_val. They must be specified within the
// regrid dictionary itself.

// Conf: convert
info.convert_fx.set(regrid_dict->lookup(conf_key_convert, false));
// Conf: convert (optional)
if(regrid_dict && regrid_dict->lookup(conf_key_convert, false)) {
info.convert_fx.set(regrid_dict->lookup(conf_key_convert));
}
else if(regrid_default && regrid_default->lookup(conf_key_convert, false)) {
info.convert_fx.set(regrid_default->lookup(conf_key_convert));
}

// Conf: censor_thresh
info.censor_thresh = regrid_dict->lookup_thresh_array(conf_key_censor_thresh, false, true, false);
// Conf: censor_thresh (optional)
if(regrid_dict && regrid_dict->lookup(conf_key_censor_thresh, false)) {
info.censor_thresh = regrid_dict->lookup_thresh_array(conf_key_censor_thresh);
}
else if(regrid_default && regrid_default->lookup(conf_key_censor_thresh, false)) {
info.censor_thresh = regrid_default->lookup_thresh_array(conf_key_censor_thresh);
}

// Conf: censor_val
info.censor_val = regrid_dict->lookup_num_array(conf_key_censor_val, false, true, false);
// Conf: censor_val (optional)
if(regrid_dict && regrid_dict->lookup(conf_key_censor_val, false)) {
info.censor_val = regrid_dict->lookup_num_array(conf_key_censor_val);
}
else if(regrid_default && regrid_default->lookup(conf_key_censor_val, false)) {
info.censor_val = regrid_default->lookup_num_array(conf_key_censor_val);
}

// Validate the settings
info.validate();
Expand Down
63 changes: 47 additions & 16 deletions src/basic/vx_config/config_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,34 @@ static const char conf_key_old_prepbufr_map[] = "obs_prefbufr_map"; // for ba
////////////////////////////////////////////////////////////////////////

extern ConcatString parse_conf_version(Dictionary *dict);
extern ConcatString parse_conf_string(Dictionary *dict, const char *, bool check_empty = true);
extern ConcatString parse_conf_string(
Dictionary *dict,
const char *,
bool check_empty=true);
extern GrdFileType parse_conf_file_type(Dictionary *dict);
extern std::map<STATLineType,STATOutputType>
parse_conf_output_flag(Dictionary *dict, const STATLineType *, int);
parse_conf_output_flag(
Dictionary *dict,
const STATLineType *, int);
extern std::map<STATLineType,StringArray>
parse_conf_output_stats(Dictionary *dict);
extern int parse_conf_n_vx(Dictionary *dict);
extern Dictionary parse_conf_i_vx_dict(Dictionary *dict, int index);
extern StringArray parse_conf_tc_model(Dictionary *dict, bool error_out = default_dictionary_error_out);
extern StringArray parse_conf_message_type(Dictionary *dict, bool error_out = default_dictionary_error_out);
extern StringArray parse_conf_sid_list(Dictionary *dict, const char *);
extern void parse_sid_mask(const ConcatString &, StringArray &, ConcatString &);
extern Dictionary parse_conf_i_vx_dict(
Dictionary *dict,
int index);
extern StringArray parse_conf_tc_model(
Dictionary *dict,
bool error_out=default_dictionary_error_out);
extern StringArray parse_conf_message_type(
Dictionary *dict,
bool error_out=default_dictionary_error_out);
extern StringArray parse_conf_sid_list(
Dictionary *dict,
const char *);
extern void parse_sid_mask(
const ConcatString &,
StringArray &,
ConcatString &);
extern std::vector<MaskLatLon>
parse_conf_llpnt_mask(Dictionary *dict);
extern StringArray parse_conf_obs_qty_inc(Dictionary *dict);
Expand All @@ -51,27 +67,40 @@ extern NumArray parse_conf_ci_alpha(Dictionary *dict);
extern NumArray parse_conf_eclv_points(Dictionary *dict);
extern ClimoCDFInfo parse_conf_climo_cdf(Dictionary *dict);
extern TimeSummaryInfo parse_conf_time_summary(Dictionary *dict);
extern std::map<ConcatString,ConcatString> parse_conf_key_value_map(
Dictionary *dict, const char *conf_key_map_name, const char *caller=nullptr);
extern std::map<ConcatString,ConcatString>
parse_conf_key_value_map(
Dictionary *dict,
const char *conf_key_map_name,
const char *caller=nullptr);
extern void parse_add_conf_key_value_map(
Dictionary *dict, const char *conf_key_map_name, std::map<ConcatString,ConcatString> *m);
Dictionary *dict,
const char *conf_key_map_name,
std::map<ConcatString,ConcatString> *m);
extern void parse_add_conf_key_values_map(
Dictionary *dict, const char *conf_key_map_name,
std::map<ConcatString,StringArray> *m, const char *caller=nullptr);
Dictionary *dict,
const char *conf_key_map_name,
std::map<ConcatString,StringArray> *m,
const char *caller=nullptr);
extern std::map<ConcatString,ConcatString>
parse_conf_message_type_map(Dictionary *dict);
extern std::map<ConcatString,StringArray>
parse_conf_message_type_group_map(Dictionary *dict);
extern std::map<ConcatString,StringArray> parse_conf_metadata_map(Dictionary *dict);
extern std::map<ConcatString,StringArray>
parse_conf_metadata_map(Dictionary *dict);
extern std::map<ConcatString,ConcatString>
parse_conf_obs_name_map(Dictionary *dict);
extern std::map<ConcatString,StringArray>
parse_conf_obs_to_qc_map(Dictionary *dict);
extern std::map<ConcatString,UserFunc_1Arg>
parse_conf_key_convert_map(
Dictionary *dict, const char *conf_key_map_name, const char *caller=nullptr);
Dictionary *dict,
const char *conf_key_map_name,
const char *caller=nullptr);
extern BootInfo parse_conf_boot(Dictionary *dict);
extern RegridInfo parse_conf_regrid(Dictionary *dict, bool error_out = default_dictionary_error_out);
extern RegridInfo parse_conf_regrid(
Dictionary *dict,
Dictionary *default_dict=nullptr,
bool error_out=default_dictionary_error_out);
extern InterpInfo parse_conf_interp(Dictionary *dict, const char *);
extern NbrhdInfo parse_conf_nbrhd(Dictionary *dict, const char *);
extern HiRAInfo parse_conf_hira(Dictionary *dict);
Expand All @@ -92,7 +121,9 @@ extern ConcatString parse_conf_ugrid_coordinates_file(Dictionary *dict);
extern ConcatString parse_conf_ugrid_dataset(Dictionary *dict);
extern ConcatString parse_conf_ugrid_map_config(Dictionary *dict);
extern double parse_conf_ugrid_max_distance_km(Dictionary *dict);
extern void parse_add_conf_ugrid_metadata_map(Dictionary *dict, std::map<ConcatString,StringArray> *m);
extern void parse_add_conf_ugrid_metadata_map(
Dictionary *dict,
std::map<ConcatString,StringArray> *m);

extern void check_mask_names(const StringArray &);

Expand Down
2 changes: 1 addition & 1 deletion src/libcode/vx_data2d/var_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ void VarInfo::set_dict(Dictionary &dict) {
if(dict.last_lookup_status()) set_range(na);

// Parse regrid, if present
Regrid = parse_conf_regrid(&dict, false);
Regrid = parse_conf_regrid(&dict, nullptr, false);

// Parse set_attr strings
SetAttrName =
Expand Down
23 changes: 6 additions & 17 deletions src/libcode/vx_statistics/read_climo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,23 +106,12 @@ DataPlaneArray read_climo_data_plane_array(Dictionary *dict,
// Get the i-th array entry
Dictionary i_dict = parse_conf_i_vx_dict(field_dict, i_vx);

// Find the "climo_name.regrid" setting
Dictionary *climo_dict = nullptr;
cs << cs_erase << climo_name << "." << conf_key_regrid;

// Try the current climo_name.regrid setting
// e.g. "config.fcst.climo_mean.regrid"
if(dict->lookup(cs.c_str(), false)) {
climo_dict = dict->lookup_dictionary(climo_name);
}
// Try the default climo_name.regrid setting
// e.g. "config.climo_mean.regrid"
else {
climo_dict = dict->parent()->lookup_dictionary(climo_name);
}

// Parse the "regrid" dictionary
RegridInfo regrid_info = parse_conf_regrid(climo_dict);
// Parse the "regrid" dictionary from the current location
// (e.g. "config.fcst.climo_mean.regrid") or default
// location (e.g. "config.climo_mean.regrid")
RegridInfo regrid_info = parse_conf_regrid(
dict->lookup_dictionary(climo_name, false, false, false),
dict->parent()->lookup_dictionary(climo_name, false, false, false));

// Parse the "time_interp_method"
cs << cs_erase << climo_name << "." << conf_key_time_interp_method;
Expand Down

0 comments on commit 1563d97

Please sign in to comment.