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/data/table_files/ndbc_stations.xml b/data/table_files/ndbc_stations.xml
index 7e73ef73a3..c536e399f4 100644
--- a/data/table_files/ndbc_stations.xml
+++ b/data/table_files/ndbc_stations.xml
@@ -260,6 +260,7 @@
+
@@ -475,6 +476,7 @@
+
@@ -777,6 +779,7 @@
+
@@ -789,6 +792,7 @@
+
@@ -919,9 +923,11 @@
+
+
@@ -946,6 +952,7 @@
+
@@ -1113,11 +1120,13 @@
+
+
@@ -1231,6 +1240,7 @@
+
@@ -1333,6 +1343,7 @@
+
@@ -1341,6 +1352,7 @@
+
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..9a738810f3 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, search_parent);
+
+}
//
// 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_grib/grib_utils.cc b/src/libcode/vx_data2d_grib/grib_utils.cc
index c1ef70f775..71b3ee8dc2 100644
--- a/src/libcode/vx_data2d_grib/grib_utils.cc
+++ b/src/libcode/vx_data2d_grib/grib_utils.cc
@@ -572,6 +572,12 @@ data.nx = char2_to_int(gds.nx);
// Number of points in the y-direction
data.ny = char2_to_int(gds.ny);
+data.eccentricity = 0.;
+data.false_east = 0.;
+data.false_north = 0.;
+data.scale_factor = 1.0;
+data.dy_km = data.d_km;
+
data.dump();
//
diff --git a/src/libcode/vx_data2d_grib2/data2d_grib2.cc b/src/libcode/vx_data2d_grib2/data2d_grib2.cc
index 42582b781e..45d931b9c2 100644
--- a/src/libcode/vx_data2d_grib2/data2d_grib2.cc
+++ b/src/libcode/vx_data2d_grib2/data2d_grib2.cc
@@ -1172,6 +1172,11 @@ void MetGrib2DataFile::read_grib2_grid( gribfield *gfld) {
data.r_km = r_km;
data.nx = gfld->igdtmpl[7];
data.ny = gfld->igdtmpl[8];
+ data.eccentricity = 0.;
+ data.false_east = 0.;
+ data.false_north = 0.;
+ data.scale_factor = 1.0;
+ data.dy_km = data.d_km;
// check for dx != dy
if( !is_eq((double)gfld->igdtmpl[14] / 1000000.0,
diff --git a/src/libcode/vx_data2d_nc_met/get_met_grid.cc b/src/libcode/vx_data2d_nc_met/get_met_grid.cc
index 6016ab4dd2..67ddad0fa8 100644
--- a/src/libcode/vx_data2d_nc_met/get_met_grid.cc
+++ b/src/libcode/vx_data2d_nc_met/get_met_grid.cc
@@ -447,6 +447,12 @@ get_global_att(ncfile, string("nx"), data.nx);
// Number of points in the y-direction
get_global_att(ncfile, string("ny"), data.ny);
+data.eccentricity = 0.;
+data.false_east = 0.;
+data.false_north = 0.;
+data.scale_factor = 1.0;
+data.dy_km = data.d_km;
+
data.dump();
//
@@ -643,6 +649,12 @@ get_global_att(ncfile, string("nx"), data.nx);
// Number of points in the y-direction
get_global_att(ncfile, string("ny"), data.ny);
+data.eccentricity = 0.;
+data.false_east = 0.;
+data.false_north = 0.;
+data.scale_factor = 1.0;
+data.dy_km = data.d_km;
+
data.dump();
//
diff --git a/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc b/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc
index b5a78b109a..d93f0d3701 100644
--- a/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc
+++ b/src/libcode/vx_data2d_nc_pinterp/get_pinterp_grid.cc
@@ -185,6 +185,12 @@ data.d_km *= 0.001;
data.r_km = default_grib_radius_km;
+data.eccentricity = 0.;
+data.false_east = 0.;
+data.false_north = 0.;
+data.scale_factor = 1.0;
+data.dy_km = data.d_km;
+
//
// done
//
diff --git a/src/libcode/vx_data2d_python/grid_from_python_dict.cc b/src/libcode/vx_data2d_python/grid_from_python_dict.cc
index 8c9aa7dae1..93de48387d 100644
--- a/src/libcode/vx_data2d_python/grid_from_python_dict.cc
+++ b/src/libcode/vx_data2d_python/grid_from_python_dict.cc
@@ -208,6 +208,11 @@ data.r_km = dict.lookup_double("r_km");
data.nx = dict.lookup_int("nx");
data.ny = dict.lookup_int("ny");
+data.eccentricity = 0.;
+data.false_east = 0.;
+data.false_north = 0.;
+data.scale_factor = 1.0;
+data.dy_km = data.d_km;
////////////////
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())
diff --git a/src/tools/other/ascii2nc/ndbc_handler.cc b/src/tools/other/ascii2nc/ndbc_handler.cc
index f76df3c4d8..cd9f960f90 100644
--- a/src/tools/other/ascii2nc/ndbc_handler.cc
+++ b/src/tools/other/ascii2nc/ndbc_handler.cc
@@ -87,11 +87,11 @@ NdbcHandler::NdbcHandler(const string &program_name) :
// read in and parse the locations file
if (!locations.initialize(locationsFileName)) {
- mlog << Error << "\ncould not initialize station loations file\n\n";
+ mlog << Error << "\nCannot initialize NDBC station loations file: "
+ << locationsFileName << "\n\n";
exit(1);
}
- //locations.print();
-
+
//
// store column info for all the data columns (column names)
// NOTE these will be used as index values in the observations
@@ -215,13 +215,14 @@ bool NdbcHandler::_readObservations(LineDataFile &ascii_file)
////////////////////////////////////////////////////////////////////////
bool NdbcHandler::_parseObservationLineStandard(DataLine &data_line,
- const string &filename)
+ const string &filename)
{
string method_name = "NdbcHandler::_parseObservationLineStandard() ";
if (format_version != NDBC_FORMAT_VERSION_STANDARD) {
- mlog << Error << "\n" << method_name << "->"
- << "Standard NDBC format is the only supported format\n\n";
+ mlog << Warning << "\n" << method_name << "->"
+ << "Standard NDBC format is the only supported format: "
+ << filename << "\n\n";
return false;
}
@@ -229,11 +230,11 @@ bool NdbcHandler::_parseObservationLineStandard(DataLine &data_line,
// Make sure that the line contains the correct number of tokens
//
if (data_line.n_items() != NUM_COLS_STANDARD) {
- mlog << Error << "\n" << method_name << "-> "
- << "line number " << data_line.line_number()
- << " does not have the correct number of columns " << data_line.n_items()
- << " (" << NUM_COLS_STANDARD << "). Skipping this line in \""
- << filename << "\".\n\n";
+ mlog << Warning << "\n" << method_name << "-> "
+ << "Skipping line number " << data_line.line_number()
+ << " with an unexpected number of columns ("
+ << data_line.n_items() << " != " << NUM_COLS_STANDARD << "): "
+ << filename << "\n\n";
return false;
}
@@ -242,10 +243,10 @@ bool NdbcHandler::_parseObservationLineStandard(DataLine &data_line,
//
time_t valid_time = _getValidTime(data_line);
if (valid_time == 0) {
- mlog << Error << "\n" << method_name << "-> "
- << "line number " << data_line.line_number()
- << " time could not be parsed, skipping this line in \""
- << filename << "\".\n\n";
+ mlog << Warning << "\n" << method_name << "-> "
+ << "Skipping line number " << data_line.line_number()
+ << " whose vaild time cannot not be parsed: "
+ << filename << "\n\n";
return false;
}
@@ -263,9 +264,9 @@ bool NdbcHandler::_parseObservationLineStandard(DataLine &data_line,
name = column[i].name;
grib_code = i; // it's not actually grib code, its obs_vid, according to howard
_addObservations(Observation(header_type, stationId, valid_time,
- stationLat, stationLon, stationAlt,
- quality_flag, grib_code, pressure_level_hpa,
- height_m, value, name));
+ stationLat, stationLon, stationAlt,
+ quality_flag, grib_code, pressure_level_hpa,
+ height_m, value, name));
}
return true;
}
@@ -287,15 +288,15 @@ bool NdbcHandler::_setStationInfo(const string &filename)
// expect .txt as the name
i0 = fname.find(".txt");
if (i0 == string::npos) {
- mlog << Error << "\n" << "expect file name of format '.txt'\n"
- << "Got " << fname << "\n\n";
+ mlog << Warning << "\n" << "NDBC file name does not follow the "
+ << "expected '.txt' format: " << fname << "\n\n";
return false;
}
stationId = fname.substr(0, i0);
if (!locations.lookupLatLonElev(stationId, stationLat, stationLon,
- stationAlt)) {
- mlog << Error << "\n" << "No location information found for station "
- << stationId << " do not process file " << filename << "\n\n";
+ stationAlt)) {
+ mlog << Warning << "\n" << "NDBC station " << stationId
+ << " location information not found: " << filename << "\n\n";
return false;
}
return true;
@@ -323,8 +324,8 @@ bool NdbcHandler::_determineFileType(LineDataFile &ascii_file)
}
}
format_version = NDBC_FORMAT_VERSION_UNKNOWN;
- mlog << Error << "\nNdbcHandler::_determineFileType -> "
- << "Unknown file type\n\n";
+ mlog << Warning << "\nNdbcHandler::_determineFileType -> "
+ << "Unknown file type: " << ascii_file.filename() << "\n\n";
return false;
}
@@ -335,10 +336,10 @@ time_t NdbcHandler::_getValidTime(const DataLine &data_line) const
//
// Pull out the date information
//
- if (column_pointer_year < 0 || column_pointer_month < 0 || column_pointer_day < 0 ||
+ if (column_pointer_year < 0 || column_pointer_month < 0 || column_pointer_day < 0 ||
column_pointer_hour < 0 || column_pointer_minute < 0) {
- mlog << Error << "\nNdbcHandler::_getValidTime -> "
- << "Not all time related column pointers are set\n\n";
+ mlog << Warning << "\nNdbcHandler::_getValidTime -> "
+ << "Not all time related column pointers are set.\n\n";
return 0;
}
string year = _extractColumn(data_line, column_pointer_year);
@@ -391,9 +392,9 @@ bool NdbcHandler::_readHeaderInfo(LineDataFile &ascii_file)
// The first line of the file contains the headers
//
if (!(ascii_file >> data_line)) {
- mlog << Error << "\nNdbcHandler::_readHeaderInfo() -> "
- << "error reading header line from input ASCII file \""
- << ascii_file.filename() << "\"\n\n";
+ mlog << Warning << "\nNdbcHandler::_readHeaderInfo() -> "
+ << "Problem reading header line from input ASCII file: "
+ << ascii_file.filename() << "\n\n";
return false;
}
@@ -401,9 +402,10 @@ bool NdbcHandler::_readHeaderInfo(LineDataFile &ascii_file)
// Check for the correct number of columns in the header line
//
if (data_line.n_items() != NUM_COLS_STANDARD) {
- mlog << Error << "\nNdbcHandler::_readHeaderInfo() -> "
- << "NDBC file has incorrect number of columns ("
- << data_line.n_items() << ") in header line\n\n";
+ mlog << Warning << "\nNdbcHandler::_readHeaderInfo() -> "
+ << "Unexpected number of header columns (" << data_line.n_items()
+ << " != " << NUM_COLS_STANDARD << "): "
+ << ascii_file.filename() << "\n\n";
return false;
}
@@ -426,30 +428,33 @@ bool NdbcHandler::_readHeaderInfo(LineDataFile &ascii_file)
} else {
bool found = false;
for (size_t j=0; j "
- << "NDBC file has unknown header item " << s << "\n\n";
- status = false;
+ mlog << Warning << "\nNdbcHandler::_readHeaderInfo() -> "
+ << "Unexpected header column (" << s << "): "
+ << ascii_file.filename() << "\n\n";
+ status = false;
}
}
}
- if (column_pointer_year == -1 || column_pointer_month == -1 ||
- column_pointer_day == -1 || column_pointer_hour == -1 ||
+ if (column_pointer_year == -1 || column_pointer_month == -1 ||
+ column_pointer_day == -1 || column_pointer_hour == -1 ||
column_pointer_minute == -1) {
- mlog << Error << "\nNdbcHandler::_readHeaderInfo() -> "
- << "NDBC file did not have all time fields in header \n\n";
- status = false;
+ mlog << Warning << "\nNdbcHandler::_readHeaderInfo() -> "
+ << "NDBC file did not have all time fields in header: "
+ << ascii_file.filename() << "\n\n";
+ status = false;
}
for (size_t j=0; j "
- << "NDBC file did not have all expected fields in header \n\n";
+ mlog << Warning << "\nNdbcHandler::_readHeaderInfo() -> "
+ << "NDBC file did not have all expected fields in header: "
+ << ascii_file.filename() << "\n\n";
status = false;
break;
}
diff --git a/src/tools/other/mode_time_domain/nc_grid.cc b/src/tools/other/mode_time_domain/nc_grid.cc
index e31246ab4d..022a2e8ebe 100644
--- a/src/tools/other/mode_time_domain/nc_grid.cc
+++ b/src/tools/other/mode_time_domain/nc_grid.cc
@@ -191,6 +191,11 @@ data.r_km = string_att_as_double(f, "r_km");
data.nx = string_att_as_int(f, "nx");
data.ny = string_att_as_int(f, "ny");
+data.eccentricity = 0.;
+data.false_east = 0.;
+data.false_north = 0.;
+data.scale_factor = 1.0;
+data.dy_km = data.d_km;
//
// done