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 66c2926af0..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
@@ -1318,9 +1320,8 @@ of several entires defining the climatology file names and fields to be used.
* The "hour_interval" entry is an integer specifying the spacing in hours of
the climatology data for each day. This should be set between 0 and 24,
- with 6 and 12 being common choices. For example, use 6 for climatology data
- with 4 times per day, such as 00Z, 06Z, 12Z, and 18Z. Use "NA" if the timing
- of the climatology data should not be checked.
+ with 6 and 12 being common choices. Use "NA" if the timing of the
+ climatology data should not be checked.
* The "day_interval" and "hour_interval" entries replace the deprecated
entries "match_month", "match_day", and "time_step".
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 ed534d0191..b513d5577d 100644
--- a/internal/test_unit/xml/unit_climatology_2.5deg.xml
+++ b/internal/test_unit/xml/unit_climatology_2.5deg.xml
@@ -81,4 +81,33 @@
+
+
+
+ &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_cal/doyhms_to_unix.cc b/src/basic/vx_cal/doyhms_to_unix.cc
index 2c130131bb..e864089d88 100644
--- a/src/basic/vx_cal/doyhms_to_unix.cc
+++ b/src/basic/vx_cal/doyhms_to_unix.cc
@@ -178,3 +178,4 @@ return ( dt );
////////////////////////////////////////////////////////////////////////
+
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_data2d_python/.python_dataplane.cc.swp b/src/libcode/vx_data2d_python/.python_dataplane.cc.swp
new file mode 100644
index 0000000000..bfc33dd3d5
Binary files /dev/null and b/src/libcode/vx_data2d_python/.python_dataplane.cc.swp differ
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())