diff --git a/.github/jobs/build_docker_image.sh b/.github/jobs/build_docker_image.sh
index 4fabd88d2e..55bd37c644 100755
--- a/.github/jobs/build_docker_image.sh
+++ b/.github/jobs/build_docker_image.sh
@@ -15,8 +15,5 @@ time_command docker build -t ${DOCKERHUB_TAG} \
-f $DOCKERFILE_PATH ${GITHUB_WORKSPACE}
if [ $? != 0 ]; then
cat ${GITHUB_WORKSPACE}/docker_build.log
- # Append the full make_install.log file
- echo "Appending make_install.log to docker_build.log. See the logs artifact for details."
- cat ${GITHUB_WORKSPACE}/make_install.log >> ${GITHUB_WORKSPACE}/docker_build.log
exit 1
fi
diff --git a/.github/jobs/set_job_controls.sh b/.github/jobs/set_job_controls.sh
index e897aaa912..76a123d18b 100755
--- a/.github/jobs/set_job_controls.sh
+++ b/.github/jobs/set_job_controls.sh
@@ -6,7 +6,7 @@ run_unit_tests=false
run_diff=false
run_update_truth=false
met_base_repo=met-base
-met_base_tag=v1.1
+met_base_tag=v2.0_debian10
input_data_version=develop
truth_data_version=develop
diff --git a/.github/jobs/test_env_vars.sh b/.github/jobs/test_env_vars.sh
index 4607e58f07..a77a9ca0f8 100755
--- a/.github/jobs/test_env_vars.sh
+++ b/.github/jobs/test_env_vars.sh
@@ -10,4 +10,4 @@ export MET_TEST_TRUTH=/data/output/met_test_truth
export MET_TEST_DIFF=/data/output/met_test_diff
export MET_TEST_RSCRIPT=/usr/bin/Rscript
-export MET_TEST_MET_PYTHON_EXE=/usr/bin/python3
+export MET_TEST_MET_PYTHON_EXE=/usr/local/bin/python3
diff --git a/.github/workflows/build_docker_and_trigger_metplus.yml b/.github/workflows/build_docker_and_trigger_metplus.yml
index 15cd652caf..89e5e14f67 100644
--- a/.github/workflows/build_docker_and_trigger_metplus.yml
+++ b/.github/workflows/build_docker_and_trigger_metplus.yml
@@ -29,7 +29,7 @@ jobs:
env:
SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }}-lite
MET_BASE_REPO: met-base
- MET_BASE_TAG: v1.1
+ MET_BASE_TAG: v2.0_debian10
- name: Push Docker Image
run: .github/jobs/push_docker_image.sh
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..025c633d29 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".
@@ -1729,12 +1730,12 @@ This dictionary may include the following entries:
* The "shape" entry may be set to SQUARE or CIRCLE to specify the shape
of the smoothing area.
-* The "type" entry is an array of dictionaries, each specifying an
- interpolation method. Interpolation is performed over a N by N box
- centered on each point, where N is the width specified. Each of these
+* The "type" entry is an array of dictionaries, each specifying one or more
+ interpolation methods and widths. Interpolation is performed over an N by N
+ box centered on each point, where N is the width specified. Each of these
dictionaries must include:
- * The "width" entry is an integer which specifies the size of the
+ * The "width" entry is an array of integers to specify the size of the
interpolation area. The area is either a square or circle containing
the observation point. The width value specifies the width of the
square or diameter of the circle. A width value of 1 is interpreted
@@ -1747,7 +1748,7 @@ This dictionary may include the following entries:
grid point closest to the observation point. For grid-to-grid
comparisons (i.e. Grid-Stat), the width must be odd.
- * The "method" entry specifies the interpolation procedure to be
+ * The "method" entry is an array of interpolation procedures to be
applied to the points in the box:
* MIN for the minimum value
@@ -1792,6 +1793,9 @@ This dictionary may include the following entries:
only valid smoothing methods are MIN, MAX, MEDIAN, UW_MEAN, and
GAUSSIAN, and MAXGAUSS.
+ * If multiple "method" and "width" options are specified, all possible
+ permutations of their values are applied.
+
.. code-block:: none
interp = {
@@ -1801,8 +1805,8 @@ This dictionary may include the following entries:
type = [
{
- method = UW_MEAN;
- width = 1;
+ method = [ NEAREST ];
+ width = [ 1 ];
}
];
}
diff --git a/internal/scripts/docker/build_met_docker.sh b/internal/scripts/docker/build_met_docker.sh
index a7e2aa7a07..df02108390 100755
--- a/internal/scripts/docker/build_met_docker.sh
+++ b/internal/scripts/docker/build_met_docker.sh
@@ -2,33 +2,37 @@
echo "Running script to build MET in Docker"
-LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_configure.log
-
source internal/scripts/environment/development.docker
+mkdir -p /met/logs
+
+LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_configure.log
echo "Configuring MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}"
./bootstrap
-./configure --enable-grib2 --enable-mode_graphics --enable-modis --enable-lidar2nc --enable-python > ${LOG_FILE}
+./configure --enable-grib2 --enable-mode_graphics --enable-modis --enable-lidar2nc --enable-python CPPFLAGS="-I/usr/local/include -I/usr/local/include/freetype2 -I/usr/local/include/cairo" > ${LOG_FILE} 2>&1
if [ $? != 0 ]; then
- exit 1
+ cat ${LOG_FILE}
+ exit 1
fi
if [ ! -z "${MAKE_ARGS}" ]; then
echo Adding make arguments: ${MAKE_ARGS}
fi
-LOG_FILE=/met/MET-${MET_GIT_NAME}/make_install.log
+LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_make_install.log
echo "Compiling MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}"
make ${MAKE_ARGS} install > ${LOG_FILE}
if [ $? != 0 ]; then
- exit 1
+ cat ${LOG_FILE}
+ exit 1
fi
LOG_FILE=/met/logs/MET-${MET_GIT_NAME}_make_test.log
echo "Testing MET ${MET_GIT_NAME} and writing log file ${LOG_FILE}"
make ${MAKE_ARGS} test > ${LOG_FILE} 2>&1
if [ $? != 0 ]; then
- exit 1
+ cat ${LOG_FILE}
+ exit 1
fi
if [[ $MET_GIT_NAME == "v"* ]]; then
diff --git a/internal/scripts/environment/development.docker b/internal/scripts/environment/development.docker
index c7be4a77fe..e7968889f6 100644
--- a/internal/scripts/environment/development.docker
+++ b/internal/scripts/environment/development.docker
@@ -1,5 +1,4 @@
-# Define the development environment for NCAR project machine seneca
-# Based on settings in /usr/local/src/met/README.snat
+# Define the development environment for Docker
# Top-level MET project directory
MET_PROJ_DIR=`ls -1d /met/MET*`
@@ -7,33 +6,17 @@ MET_PROJ_DIR=`ls -1d /met/MET*`
# Variables required to build MET
export MET_DEVELOPMENT=true
-export MET_NETCDF=/usr/local
-export MET_HDF5INC=/usr/include
-export MET_HDF5LIB=/usr/lib64
-export MET_HDF=/usr/local/hdf
-export MET_HDFEOS=/usr/local/hdfeos
-export MET_BUFR=/usr/local
-export MET_GRIB2CINC=/usr/include
-export MET_GRIB2CLIB=/usr/lib64
-export MET_GSLINC=/usr/include/gsl
-export MET_GSLLIB=/usr/lib64
-export MET_CAIROINC=/usr/include/cairo
-export MET_CAIROLIB=/usr/lib64
-export MET_FREETYPEINC=/usr/include/freetype2
-export MET_FREETYPELIB=/usr/lib64
-export MET_JASPERLIB=/usr/lib64
-
-export MET_PYTHON_BIN_EXE=/usr/bin/python3
-export MET_PYTHON_CC="-I/usr/include/python3.6m"
-export MET_PYTHON_LD="-L/usr/lib64 -lpython3.6m -lpthread -ldl -lutil -lm"
-
-# -D__64BIT__ is required because we've compiled libgrib2c.a with that flag
-export CFLAGS="-DUNDERSCORE -fPIC -D__64BIT__ -g"
+export MET_PYTHON=/usr/local
+export MET_PYTHON_BIN_EXE=${MET_PYTHON}/bin/python3
+export MET_PYTHON_CC="-I${MET_PYTHON}/include/python3.10"
+export MET_PYTHON_LD="-L${MET_PYTHON}/lib -lpython3.10 -lcrypt -lpthread -ldl -lutil -lm"
+
+export CFLAGS="-DUNDERSCORE -fPIC -g"
export CXXFLAGS=${CFLAGS}
# Set LDFLAGS to include -rpath settings when compiling MET
export LDFLAGS="-Wl,--disable-new-dtags"
-export LDFLAGS="${LDFLAGS} -Wl,-rpath,/usr/local/lib:/usr/lib64:${MET_HDF}/lib:${MET_HDFEOS}/lib"
+export LDFLAGS="${LDFLAGS} -Wl,-rpath,/usr/local/lib:/usr/lib64"
# Variables required to run MET
export MET_TEST_INPUT=${MET_PROJ_DIR}/MET_test_data/unit_test
@@ -44,3 +27,16 @@ export MET_TEST_RSCRIPT=/usr/bin/Rscript
# set make arguments to build using multiple jobs
export MAKE_ARGS=-j
+
+export TEST_BASE=/met
+export COMPILER=gnu
+export MET_SUBDIR=${TEST_BASE}
+export MET_TARBALL=none
+export USE_MODULES=FALSE
+
+export MET_INSTALL_DIR=/usr/local
+
+export COMPILE_HDF=1
+export COMPILE_HDFEOS=1
+export COMPILE_FREETYPE=1
+export COMPILE_CAIRO=1
diff --git a/internal/scripts/installation/compile_MET_all.sh b/internal/scripts/installation/compile_MET_all.sh
index e0ff3290cc..9810a124f2 100755
--- a/internal/scripts/installation/compile_MET_all.sh
+++ b/internal/scripts/installation/compile_MET_all.sh
@@ -89,8 +89,23 @@ echo "MET_TARBALL = ${MET_TARBALL? "ERROR: MET_TARBALL must be set"}"
echo "USE_MODULES = ${USE_MODULES? "ERROR: USE_MODULES must be set to TRUE if using modules or FALSE otherwise"}"
echo ${MAKE_ARGS:+MAKE_ARGS = $MAKE_ARGS}
-export LIB_DIR=${TEST_BASE}/external_libs
+LIB_DIR=${TEST_BASE}/external_libs
MET_DIR=${MET_SUBDIR}
+
+if [ -z "${BIN_DIR_PATH}" ]; then
+ if [ -z "${MET_INSTALL_DIR}" ]; then
+ BIN_DIR_PATH=${TEST_BASE}/bin
+ else
+ BIN_DIR_PATH=${MET_INSTALL_DIR}/bin
+ fi
+fi
+
+if [ -z "${MET_INSTALL_DIR}" ]; then
+ MET_INSTALL_DIR=${MET_DIR}
+else
+ LIB_DIR=${MET_INSTALL_DIR}
+fi
+
TAR_DIR=${TEST_BASE}/tar_files
MET_TARBALL=${TAR_DIR}/${MET_TARBALL}
@@ -415,12 +430,16 @@ if [ $COMPILE_G2CLIB -eq 1 ]; then
rm -rf ${LIB_DIR}/g2clib/g2clib*
tar -xf ${TAR_DIR}/g2clib*.tar -C ${LIB_DIR}/g2clib
cd ${LIB_DIR}/g2clib/g2clib*
- cat makefile | \
- sed -r 's/INC=.*/INC=-I${LIB_DIR}\/include -I${LIB_DIR}\/include\/jasper/g' | \
- sed 's/CC=gcc/CC=${CC_COMPILER}/g' | \
- sed 's/-D__64BIT__//g' \
- > makefile_new
- mv makefile_new makefile
+ sed -i 's|INC=.*|INC=-I${LIB_DIR}/include -I${LIB_DIR}/include/jasper|g' makefile
+
+ # allow other compilers besides gcc
+ sed -i 's/CC=gcc/CC=${CC_COMPILER}/g' makefile
+
+ # remove -D__64BIT__ flag because compiling with it has
+ # shown issues with GRIB/GRIB2 files that are over 2GB in size
+ # This flag was removed in g2clib 1.6.4
+ # so this can be removed if the version is updated
+ sed -i 's/-D__64BIT__//g' makefile
export CC_COMPILER=${CC}
echo "cd `pwd`"
# g2clib appears to compile but causes failure compiling MET if -j argument is used
@@ -628,7 +647,7 @@ if [[ $COMPILER_FAMILY == "pgi" ]]; then
export OPT_ARGS="${OPT_ARGS} FFLAGS=-lpgf90"
fi
-configure_cmd="./configure --prefix=${MET_DIR} --bindir=${BIN_DIR_PATH}"
+configure_cmd="./configure --prefix=${MET_INSTALL_DIR} --bindir=${BIN_DIR_PATH}"
configure_cmd="${configure_cmd} BUFRLIB_NAME=${BUFRLIB_NAME}"
configure_cmd="${configure_cmd} GRIB2CLIB_NAME=${GRIB2CLIB_NAME} --enable-grib2"
if [[ ! -z ${MET_FREETYPEINC} && ! -z ${MET_FREETYPELIB} && \
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..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/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