diff --git a/data/config/GridStatConfig_default b/data/config/GridStatConfig_default
index 9ac3423238..3ac1b1050c 100644
--- a/data/config/GridStatConfig_default
+++ b/data/config/GridStatConfig_default
@@ -90,7 +90,6 @@ climo_mean = {
}
time_interp_method = DW_MEAN;
- match_month = TRUE;
day_interval = 31;
hour_interval = 6;
}
diff --git a/docs/Users_Guide/config_options.rst b/docs/Users_Guide/config_options.rst
index 5cc2432fd6..af1c78f6f2 100644
--- a/docs/Users_Guide/config_options.rst
+++ b/docs/Users_Guide/config_options.rst
@@ -693,14 +693,16 @@ using the following entries:
smoothing. The default is 120. Ignored if not Gaussian method.
* The "gaussian_dx" and "gaussian_radius" settings must be in the same
- units, such as kilometers or degress. Their ratio
+ units, such as kilometers or degress. Their ratio
(sigma = gaussian_radius / gaussian_dx) determines the Guassian weighting
function.
* The "convert", "censor_thresh", and "censor_val" entries are described
- below. When specified, these operations are applied to the output of the
- regridding step. The conversion operation is applied first, followed by
- the censoring operation.
+ below. When specified, these operations are applied to the output of the
+ regridding step. The conversion operation is applied first, followed by
+ the censoring operation. Note that these operations are limited in scope.
+ They are only applied if defined within the regrid dictionary itself.
+ Settings defined at higher levels of config file context are not applied.
.. code-block:: none
diff --git a/internal/test_unit/config/GridStatConfig_climo_wrap_year b/internal/test_unit/config/GridStatConfig_climo_wrap_year
new file mode 100644
index 0000000000..38e8ffcd0c
--- /dev/null
+++ b/internal/test_unit/config/GridStatConfig_climo_wrap_year
@@ -0,0 +1,266 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Grid-Stat configuration file.
+//
+// For additional information, please see the MET User's Guide.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Output model name to be written
+//
+model = "GFSANL";
+
+//
+// Output description to be written
+// May be set separately in each "obs.field" entry
+//
+desc = "NA";
+
+//
+// Output observation type to be written
+//
+obtype = "GFSANL";
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Verification grid
+//
+regrid = {
+ to_grid = NONE;
+ method = NEAREST;
+ width = 1;
+ vld_thresh = 0.5;
+ shape = SQUARE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// May be set separately in each "field" entry
+//
+censor_thresh = [];
+censor_val = [];
+mpr_column = [];
+mpr_thresh = [];
+cat_thresh = [];
+cnt_thresh = [ NA ];
+cnt_logic = UNION;
+wind_thresh = [ NA ];
+wind_logic = UNION;
+eclv_points = 0.05;
+nc_pairs_var_name = "";
+nc_pairs_var_suffix = "";
+hss_ec_value = NA;
+rank_corr_flag = FALSE;
+
+//
+// Forecast and observation fields to be verified
+//
+fcst = {
+
+ name = "TMP";
+ level = "P500";
+
+ field = [
+ { set_attr_init = "20201225_12"; set_attr_valid = "20201225_12"; nc_pairs_var_suffix = "20201225_12"; },
+ { set_attr_init = "20210105_12"; set_attr_valid = "20210105_12"; nc_pairs_var_suffix = "20210105_12"; },
+ { set_attr_init = "20201225_03"; set_attr_valid = "20201225_03"; nc_pairs_var_suffix = "20201225_03"; },
+ { set_attr_init = "20201225_21"; set_attr_valid = "20201225_21"; nc_pairs_var_suffix = "20201225_21"; }
+ ];
+}
+obs = fcst;
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Climatology data
+//
+climo_mean = {
+
+ field = [
+ { name = "TMP"; level = "P500"; },
+ { name = "TMP"; level = "P500"; },
+ { name = "TMP"; level = "P500"; },
+ { name = "TMP"; level = "P500"; }
+ ];
+
+ file_name = [ ${CLIMO_MEAN_FILE_LIST} ];
+
+ regrid = {
+ method = BILIN;
+ width = 2;
+ vld_thresh = 0.5;
+ }
+
+ time_interp_method = DW_MEAN;
+ day_interval = ${DAY_INTERVAL};
+ hour_interval = ${HOUR_INTERVAL};
+}
+
+climo_stdev = climo_mean;
+climo_stdev = {
+ file_name = [ ${CLIMO_STDEV_FILE_LIST} ];
+}
+
+//
+// May be set separately in each "obs.field" entry
+//
+climo_cdf = {
+ cdf_bins = 1;
+ center_bins = TRUE;
+ write_bins = FALSE;
+ direct_prob = FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Verification masking regions
+//
+mask = {
+ grid = [ "FULL" ];
+ poly = [];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Confidence interval settings
+//
+ci_alpha = [ 0.05 ];
+
+boot = {
+ interval = PCTILE;
+ rep_prop = 1.0;
+ n_rep = 0;
+ rng = "mt19937";
+ seed = "";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Data smoothing methods
+//
+interp = {
+ field = BOTH;
+ vld_thresh = 1.0;
+ shape = SQUARE;
+
+ type = [
+ {
+ method = NEAREST;
+ width = 1;
+ }
+ ];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Neighborhood methods
+//
+nbrhd = {
+ width = [ 1 ];
+ cov_thresh = [ >=0.5 ];
+ vld_thresh = 1.0;
+ shape = SQUARE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Fourier decomposition
+//
+fourier = {
+ wave_1d_beg = [];
+ wave_1d_end = [];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Gradient statistics
+// May be set separately in each "obs.field" entry
+//
+gradient = {
+ dx = [ 1, 2, 5 ];
+ dy = [ 1, 3, 5 ];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Distance Map statistics
+// May be set separately in each "obs.field" entry
+//
+distance_map = {
+ baddeley_p = 2;
+ baddeley_max_dist = NA;
+ fom_alpha = 0.1;
+ zhu_weight = 0.5;
+ beta_value(n) = n * n / 2.0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Statistical output types
+//
+output_flag = {
+ fho = NONE;
+ ctc = NONE;
+ cts = NONE;
+ mctc = NONE;
+ mcts = NONE;
+ cnt = NONE;
+ sl1l2 = NONE;
+ sal1l2 = STAT;
+ vl1l2 = NONE;
+ val1l2 = NONE;
+ vcnt = NONE;
+ pct = NONE;
+ pstd = NONE;
+ pjc = NONE;
+ prc = NONE;
+ eclv = NONE;
+ nbrctc = NONE;
+ nbrcts = NONE;
+ nbrcnt = NONE;
+ grad = NONE;
+ dmap = NONE;
+ seeps = NONE;
+}
+
+//
+// NetCDF matched pairs output file
+//
+nc_pairs_flag = {
+ latlon = TRUE;
+ raw = FALSE;
+ diff = FALSE;
+ climo = TRUE;
+ climo_cdp = FALSE;
+ weight = FALSE;
+ nbrhd = FALSE;
+ fourier = FALSE;
+ gradient = FALSE;
+ distance_map = FALSE;
+ apply_mask = FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Threshold for SEEPS p1 (Probability of being dry)
+
+seeps_p1_thresh = NA;
+
+////////////////////////////////////////////////////////////////////////////////
+
+grid_weight_flag = NONE;
+tmp_dir = "/tmp";
+output_prefix = "${OUTPUT_PREFIX}";
+version = "V11.0.0";
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/internal/test_unit/config/PointStatConfig_climo b/internal/test_unit/config/PointStatConfig_climo
index 565463ada5..7bcf6c318f 100644
--- a/internal/test_unit/config/PointStatConfig_climo
+++ b/internal/test_unit/config/PointStatConfig_climo
@@ -53,21 +53,24 @@ fcst = {
field = [
{
- name = "TMP";
- level = [ "Z2" ];
- desc = "KELVIN";
+ name = "TMP";
+ level = [ "Z2" ];
+ desc = "KELVIN";
+ set_attr_units = "K";
},
{
- name = "TMP";
- level = [ "Z2" ];
- desc = "CELCIUS";
- convert(x) = K_to_C(x);
+ name = "TMP";
+ level = [ "Z2" ];
+ desc = "CELCIUS";
+ convert(x) = K_to_C(x);
+ set_attr_units = "C";
},
{
- name = "TMP";
- level = [ "Z2" ];
- desc = "FAHRENHEIT";
- convert(x) = K_to_F(x);
+ name = "TMP";
+ level = [ "Z2" ];
+ desc = "FAHRENHEIT";
+ convert(x) = K_to_F(x);
+ set_attr_units = "F";
},
{
name = "TMP";
diff --git a/internal/test_unit/xml/unit_climatology_2.5deg.xml b/internal/test_unit/xml/unit_climatology_2.5deg.xml
index 7c8c0b300a..b513d5577d 100644
--- a/internal/test_unit/xml/unit_climatology_2.5deg.xml
+++ b/internal/test_unit/xml/unit_climatology_2.5deg.xml
@@ -50,4 +50,64 @@
+
+
+
+ &MET_BIN;/grid_stat
+
+ OUTPUT_PREFIX WRAP_YEAR_CLIMO_2.5DEG
+ DAY_INTERVAL 31
+ HOUR_INTERVAL 6
+ CLIMO_MEAN_FILE_LIST
+ "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19591215",
+ "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19590115"
+
+
+ CLIMO_STDEV_FILE_LIST
+ "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19591215",
+ "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19590115"
+
+
+
+ \
+ &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \
+ &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \
+ &CONFIG_DIR;/GridStatConfig_climo_wrap_year \
+ -outdir &OUTPUT_DIR;/climatology_2.5deg -v 3
+
+
+
+
+
+
+
+ &MET_BIN;/grid_stat
+
+ OUTPUT_PREFIX SINGLE_MONTH_CLIMO_2.5DEG
+ DAY_INTERVAL 31
+ HOUR_INTERVAL 6
+ CLIMO_MEAN_FILE_LIST
+ "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_mean.19591215"
+
+
+ CLIMO_STDEV_FILE_LIST
+ "&DATA_DIR_CLIMO;/NCEP_2.5deg/pgba_stdv.19591215"
+
+
+
+ \
+ &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \
+ &DATA_DIR_MODEL;/grib2/gfsanl/gfsanl_4_20120409_1200_000.grb2 \
+ &CONFIG_DIR;/GridStatConfig_climo_wrap_year \
+ -outdir &OUTPUT_DIR;/climatology_2.5deg -v 3
+
+
+
+
diff --git a/scripts/config/GridStatConfig_all b/scripts/config/GridStatConfig_all
index ae38f06cd5..3d0e53f12e 100644
--- a/scripts/config/GridStatConfig_all
+++ b/scripts/config/GridStatConfig_all
@@ -107,7 +107,6 @@ climo_mean = {
}
time_interp_method = DW_MEAN;
- match_month = TRUE;
match_day = FALSE;
time_step = 21600;
}
diff --git a/src/basic/vx_config/config_util.cc b/src/basic/vx_config/config_util.cc
index 52817f1b6d..318f974654 100644
--- a/src/basic/vx_config/config_util.cc
+++ b/src/basic/vx_config/config_util.cc
@@ -1299,14 +1299,18 @@ RegridInfo parse_conf_regrid(Dictionary *dict, bool error_out) {
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();
+ // 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));
+ info.convert_fx.set(regrid_dict->lookup(conf_key_convert, false));
// Conf: censor_thresh
- info.censor_thresh = regrid_dict->lookup_thresh_array(conf_key_censor_thresh, false);
+ info.censor_thresh = regrid_dict->lookup_thresh_array(conf_key_censor_thresh, false, true, false);
// Conf: censor_val
- info.censor_val = regrid_dict->lookup_num_array(conf_key_censor_val, false);
+ info.censor_val = regrid_dict->lookup_num_array(conf_key_censor_val, false, true, false);
// Validate the settings
info.validate();
diff --git a/src/basic/vx_config/dictionary.cc b/src/basic/vx_config/dictionary.cc
index 08dc1f7fe9..90fae2a93a 100644
--- a/src/basic/vx_config/dictionary.cc
+++ b/src/basic/vx_config/dictionary.cc
@@ -1261,7 +1261,7 @@ return ( e[n] );
////////////////////////////////////////////////////////////////////////
-const DictionaryEntry * Dictionary::lookup(const std::string name)
+const DictionaryEntry * Dictionary::lookup(const std::string name, bool search_parent)
{
@@ -1288,13 +1288,13 @@ scope = Name.split(".");
if ( scope.n_elements() == 1 ) {
- return ( lookup_simple(name) );
+ return ( lookup_simple(name, search_parent) );
}
for (j=0; j<(scope.n_elements() - 1); ++j) {
- E = D->lookup(scope[j].c_str());
+ E = D->lookup(scope[j].c_str(), search_parent);
if ( !E ) {
@@ -1320,7 +1320,7 @@ for (j=0; j<(scope.n_elements() - 1); ++j) {
const string stub = scope[scope.n_elements() - 1].c_str();
-E = D->lookup_simple(stub);
+E = D->lookup_simple(stub, search_parent);
if ( E ) {
@@ -1335,7 +1335,11 @@ if ( E ) {
E = (const DictionaryEntry *) 0;
-if ( Parent ) E = Parent->lookup(name);
+if ( search_parent ) {
+
+ if ( Parent ) E = Parent->lookup(name, search_parent);
+
+}
//
// done
@@ -1351,7 +1355,7 @@ return ( E );
////////////////////////////////////////////////////////////////////////
-const DictionaryEntry * Dictionary::lookup_simple(const std::string name)
+const DictionaryEntry * Dictionary::lookup_simple(const std::string name, bool search_parent)
{
@@ -1381,8 +1385,11 @@ for (j=0; jlookup(name);
+if ( search_parent ) {
+ if ( Parent ) E = Parent->lookup(name);
+
+}
//
// done
//
@@ -1473,11 +1480,12 @@ return;
bool Dictionary::lookup_bool(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
if ( Entry ) {
@@ -1521,11 +1529,12 @@ return ( Entry->b_value() );
int Dictionary::lookup_int(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
if ( Entry ) {
@@ -1569,11 +1578,12 @@ return ( Entry->i_value() );
double Dictionary::lookup_double(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
double v = bad_data_double;
@@ -1641,11 +1651,12 @@ return ( v );
NumArray Dictionary::lookup_num_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
const Dictionary * Dict = (const Dictionary *) 0;
ConfigObjectType Type = no_config_object_type;
bool is_correct_type = false;
@@ -1765,12 +1776,13 @@ return ( array );
IntArray Dictionary::lookup_int_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
IntArray array;
-NumArray num_array = lookup_num_array(name, error_out, print_warning);
+NumArray num_array = lookup_num_array(name, error_out, print_warning, search_parent);
for (int i=0; istring_value() );
StringArray Dictionary::lookup_string_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
const Dictionary * Dict = (const Dictionary *) 0;
bool is_correct_type = false;
StringArray array;
@@ -1934,11 +1948,12 @@ return ( array );
SingleThresh Dictionary::lookup_thresh(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
if ( Entry ) {
@@ -1987,11 +2002,12 @@ return ( *(Entry->thresh_value()) );
ThreshArray Dictionary::lookup_thresh_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
const Dictionary * Dict = (const Dictionary *) 0;
bool is_correct_type = false;
ThreshArray array;
@@ -2089,11 +2105,12 @@ return ( array );
Dictionary *Dictionary::lookup_dictionary(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
if ( Entry ) {
@@ -2139,11 +2156,12 @@ return ( Entry->dict_value() );
Dictionary *Dictionary::lookup_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
if ( Entry ) {
@@ -2191,18 +2209,19 @@ return ( Entry->array_value() );
int Dictionary::lookup_seconds(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-ConcatString cs = lookup_string(name, false);
+ConcatString cs = lookup_string(name, false, true, search_parent);
if ( LastLookupStatus ) {
if ( cs.empty() ) return ( bad_data_int );
else return ( timestring_to_sec( cs.c_str() ) );
}
-return ( lookup_int(name, error_out, print_warning) );
+return ( lookup_int(name, error_out, print_warning, search_parent) );
}
@@ -2212,11 +2231,12 @@ return ( lookup_int(name, error_out, print_warning) );
IntArray Dictionary::lookup_seconds_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-StringArray sa = lookup_string_array(name, error_out, print_warning);
+StringArray sa = lookup_string_array(name, error_out, print_warning, search_parent);
IntArray ia;
int j;
@@ -2232,11 +2252,12 @@ return ( ia );
unixtime Dictionary::lookup_unixtime(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-ConcatString cs = lookup_string(name, error_out, print_warning);
+ConcatString cs = lookup_string(name, error_out, print_warning, search_parent);
if ( cs.empty() ) return ( (unixtime) 0 );
else return ( timestring_to_unix( cs.c_str() ) );
@@ -2248,11 +2269,12 @@ else return ( timestring_to_unix( cs.c_str() ) );
TimeArray Dictionary::lookup_unixtime_array(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-StringArray sa = lookup_string_array(name, error_out, print_warning);
+StringArray sa = lookup_string_array(name, error_out, print_warning, search_parent);
TimeArray ta;
int j;
@@ -2269,11 +2291,12 @@ return ( ta );
PiecewiseLinear *Dictionary::lookup_pwl(const char * name,
bool error_out,
- bool print_warning)
+ bool print_warning,
+ bool search_parent)
{
-const DictionaryEntry * Entry = lookup(name);
+const DictionaryEntry * Entry = lookup(name, search_parent);
bool is_correct_type = false;
if ( Entry ) {
diff --git a/src/basic/vx_config/dictionary.h b/src/basic/vx_config/dictionary.h
index 4265b7c3d1..45ed66e946 100644
--- a/src/basic/vx_config/dictionary.h
+++ b/src/basic/vx_config/dictionary.h
@@ -179,6 +179,8 @@ static const bool default_dictionary_error_out = true;
static const bool default_dictionary_print_warning = true;
+static const bool default_dictionary_search_parent = true;
+
////////////////////////////////////////////////////////////////////////
@@ -195,7 +197,8 @@ class Dictionary {
void patch_parents();
- virtual const DictionaryEntry * lookup_simple(const std::string name); // no scope
+ virtual const DictionaryEntry * lookup_simple(const std::string name,
+ bool search_parent = true); // no scope
int Nentries;
@@ -253,7 +256,7 @@ class Dictionary {
virtual void store(const Dictionary &);
- virtual const DictionaryEntry * lookup(const std::string name);
+ virtual const DictionaryEntry * lookup(const std::string name, bool search_parent = true);
//
// convenience functions
@@ -261,43 +264,56 @@ class Dictionary {
bool lookup_bool (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
int lookup_int (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
double lookup_double (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
NumArray lookup_num_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
IntArray lookup_int_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
ConcatString lookup_string (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
StringArray lookup_string_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
SingleThresh lookup_thresh (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
ThreshArray lookup_thresh_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
int lookup_seconds (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
IntArray lookup_seconds_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
unixtime lookup_unixtime (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
TimeArray lookup_unixtime_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
//
// return value not allocated
@@ -305,13 +321,16 @@ class Dictionary {
Dictionary * lookup_dictionary (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
Dictionary * lookup_array (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
PiecewiseLinear * lookup_pwl (const char * name,
bool error_out = default_dictionary_error_out,
- bool print_warning = default_dictionary_print_warning);
+ bool print_warning = default_dictionary_print_warning,
+ bool search_parent = default_dictionary_search_parent);
};
diff --git a/src/libcode/vx_statistics/read_climo.cc b/src/libcode/vx_statistics/read_climo.cc
index 142833337f..47666cafe3 100644
--- a/src/libcode/vx_statistics/read_climo.cc
+++ b/src/libcode/vx_statistics/read_climo.cc
@@ -299,6 +299,26 @@ DataPlaneArray climo_time_interp(const DataPlaneArray &dpa, int day_ts,
}
// For exactly 2 fields, do a simple time interpolation.
else if(it->second.n() == 2) {
+
+ // If the valid time falls outside the climo times, shift them.
+ if(vld_ut < min(dpa[it->second[0]].valid(), dpa[it->second[1]].valid()) ||
+ vld_ut > max(dpa[it->second[0]].valid(), dpa[it->second[1]].valid())) {
+
+ unixtime ut1 = dpa[it->second[0]].valid();
+ unixtime ut2 = dpa[it->second[1]].valid();
+
+ int shift_sec = day_of_year_diff(min(ut1, ut2), vld_ut) * sec_per_day;
+
+ mlog << Debug(3)
+ << "Shifting climatology times " << shift_sec / sec_per_day
+ << " day(s) from " << unix_to_yyyymmdd_hhmmss(ut1)
+ << " to " << unix_to_yyyymmdd_hhmmss(ut1 + shift_sec)
+ << " and " << unix_to_yyyymmdd_hhmmss(ut2)
+ << " to " << unix_to_yyyymmdd_hhmmss(ut2 + shift_sec) << ".\n";
+ dpa[it->second[0]].set_valid(ut1 + shift_sec);
+ dpa[it->second[1]].set_valid(ut2 + shift_sec);
+ }
+
mlog << Debug(3)
<< "Interpolating climatology fields at "
<< unix_to_yyyymmdd_hhmmss(dpa[it->second[0]].valid())