GridStat: Temporal and spatial verification of soil moisture

model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python.conf

Scientific Objective

Comparison between prototype forecast models and existing observational data is critical to ensuring that model upgrades are completed with minimal downsides or degradation in verification statistics. This use case compares a GFS HR run to SMOPS, a combination dataset of satellite measurements concerning soil characteristics. By completing temporal and spatial verification measurements, this use case serves as an excellent baseline for evaluating near surface model soil moisture

Version Added

METplus version 13.0

Datasets

Forecast: Global Forecast System (GFS) v17 prototype version (tag HR1) 12km resolution, 0-0.1 meter soil temperature

Observation: NOAA Soil Moisture Products System (SMOPS) 0.25 degree resolution, blended soil temperature NOTE: Retrieving observation data from CLASS requires user account

Climatology: None

Location: All of the input data required for this use case can be found in a sample data tarball. Each use case category will have one or more sample data tarballs. It is only necessary to download the tarball with the use case’s dataset and not the entire collection of sample data. Click here to access the METplus releases page and download sample data for the appropriate release: https://github.com/dtcenter/METplus/releases This tarball should be unpacked into the directory that you will set the value of INPUT_BASE. See Running METplus section for more information.

METplus Components

The two MET tools used in this use case are GridStat and SeriesAnalysis. Both tools require Python Embedding to ingest observation data.

METplus Workflow

Beginning time (INIT_BEG): 2020-06-07

End time (INIT_END): 2020-06-07

Increment between beginning and end times (INIT_INCREMENT): 12 hours

Sequence of forecast leads to process (LEAD_SEQ): 24 hours

With an increment of 12 hours and no difference between the INIT_BEG and INIT_END, only one time is run in this use case: a 24 hour lead from 2020-06-07. Both GridStat and SeriesAnalysis are used over this time frame, requesting CNT line type output. Because both tools are run using the same input data, much of SeriesAnalysis’ settings reference GridStat’s settings, which is the first tool used. The forecast and observation grid resolutions differ, so regridding is used to interpolate the higher resolution forecast data to the lower resolution observation data for verification, using a bilinear method. Note that for rigorous comparisons of water budgets users may want to use conservative regridding rather than bilinear as bilinear regridding does not conserve total water mass. A poly masking for CONUS is used, with the mask being available from the MET installation.

METplus Configuration

METplus first loads all of the configuration files found in parm/metplus_config, then it loads any configuration files passed to METplus via the command line, e.g. parm/use_cases/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python.conf

[config]

# Documentation for this use case can be found at
# https://metplus.readthedocs.io/en/latest/generated/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python.html

# For additional information, please see the METplus Users Guide.
# https://metplus.readthedocs.io/en/latest/Users_Guide

###
# Processes to run
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#process-list
###

PROCESS_LIST = GridStat, SeriesAnalysis

###
# Time Info
# LOOP_BY options are INIT, VALID, RETRO, and REALTIME
# If set to INIT or RETRO:
#   INIT_TIME_FMT, INIT_BEG, INIT_END, and INIT_INCREMENT must also be set
# If set to VALID or REALTIME:
#   VALID_TIME_FMT, VALID_BEG, VALID_END, and VALID_INCREMENT must also be set
# LEAD_SEQ is the list of forecast leads to process
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#timing-control
###

LOOP_BY = INIT
INIT_TIME_FMT = %Y%m%d%H
INIT_BEG=2020060700
INIT_END=2020060700
INIT_INCREMENT = 12H

LEAD_SEQ = 24


###
# File I/O
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#directory-and-filename-template-info
###

FCST_GRID_STAT_INPUT_DIR = {INPUT_BASE}/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python
FCST_GRID_STAT_INPUT_TEMPLATE = {init?fmt=%Y%m%d%H}.f{lead?fmt=%3H}.grib2

OBS_GRID_STAT_INPUT_DIR = 
OBS_GRID_STAT_INPUT_TEMPLATE = PYTHON_NUMPY

GRID_STAT_CLIMO_MEAN_INPUT_DIR =
GRID_STAT_CLIMO_MEAN_INPUT_TEMPLATE =

GRID_STAT_CLIMO_STDEV_INPUT_DIR =
GRID_STAT_CLIMO_STDEV_INPUT_TEMPLATE =

GRID_STAT_OUTPUT_DIR = {OUTPUT_BASE}/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python/GridStat
#GRID_STAT_OUTPUT_TEMPLATE = {MODEL}_verify_{OBTYPE}_{valid?fmt=%Y%m%d%H}


###
# Field Info
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info
###

MODEL = WRF
OBTYPE = SMOPS

GRID_STAT_ONCE_PER_FIELD = False

FCST_IS_PROB = false

FCST_VAR1_NAME = SOILW
FCST_VAR1_LEVELS = Z0-0.1

OBS_VAR1_NAME = {PARM_BASE}/use_cases/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python/read_SMOPS_data.py {INPUT_BASE}/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python/NPR_SMOPS_CMAP_D20200608.nc Blended_SM
OBS_VAR1_LEVELS = "(*,*)"


#LOG_GRID_STAT_VERBOSITY = 2

GRID_STAT_CONFIG_FILE = {PARM_BASE}/met_config/GridStatConfig_wrapped

GRID_STAT_REGRID_TO_GRID = OBS
GRID_STAT_REGRID_METHOD = BILIN
GRID_STAT_REGRID_WIDTH = 2
GRID_STAT_DESC = NA


GRID_STAT_OUTPUT_FLAG_CNT = STAT

GRID_STAT_NC_PAIRS_FLAG_LATLON = TRUE
GRID_STAT_NC_PAIRS_FLAG_RAW = TRUE
GRID_STAT_NC_PAIRS_FLAG_DIFF = TRUE
GRID_STAT_NC_PAIRS_FLAG_CLIMO = FALSE
GRID_STAT_NC_PAIRS_FLAG_APPLY_MASK = TRUE


GRID_STAT_MASK_POLY = MET_BASE/poly/CONUS.poly


SERIES_ANALYSIS_RUNTIME_FREQ = RUN_ONCE_PER_INIT_OR_VALID
SERIES_ANALYSIS_RUN_ONCE_PER_STORM_ID = False
FCST_SERIES_ANALYSIS_INPUT_DIR = {FCST_GRID_STAT_INPUT_DIR}
FCST_SERIES_ANALYSIS_INPUT_TEMPLATE = {FCST_GRID_STAT_INPUT_TEMPLATE}

OBS_SERIES_ANALYSIS_INPUT_DIR = {FCST_GRID_STAT_INPUT_DIR}
OBS_SERIES_ANALYSIS_INPUT_TEMPLATE = NPR_SMOPS_CMAP_D{valid?fmt=%Y%m%d}.nc 
OBS_SERIES_ANALYSIS_INPUT_DATATYPE = PYTHON_NUMPY

SERIES_ANALYSIS_OUTPUT_DIR = {OUTPUT_BASE}/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python/SeriesAnalysis
SERIES_ANALYSIS_OUTPUT_TEMPLATE = valid_{valid?fmt=%Y%m%d%H}_cnt_output.nc

SERIES_ANALYSIS_REGRID_TO_GRID = OBS
SERIES_ANALYSIS_REGRID_METHOD = BILIN

SERIES_ANALYSIS_OUTPUT_STATS_CNT = ME, MAE, RMSE, MBIAS, FBAR, OBAR

SERIES_ANALYSIS_MASK_POLY = MET_BASE/poly/CONUS.poly
SERIES_ANALYSIS_BLOCK_SIZE = 0

MET Configuration

METplus sets environment variables based on user settings in the METplus configuration file. See How METplus controls MET config file settings for more details.

YOU SHOULD NOT SET ANY OF THESE ENVIRONMENT VARIABLES YOURSELF! THEY WILL BE OVERWRITTEN BY METPLUS WHEN IT CALLS THE MET TOOLS!

If there is a setting in the MET configuration file that is currently not supported by METplus you’d like to control, please refer to: Overriding Unsupported MET config file settings

GridStatConfig_wrapped
////////////////////////////////////////////////////////////////////////////////
//
// Grid-Stat configuration file.
//
// For additional information, see the MET_BASE/config/README file.
//
////////////////////////////////////////////////////////////////////////////////

//
// Output model name to be written
//
// model =
${METPLUS_MODEL}

//
// Output description to be written
// May be set separately in each "obs.field" entry
//
// desc =
${METPLUS_DESC}

//
// Output observation type to be written
//
// obtype =
${METPLUS_OBTYPE}

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

//
// Verification grid
//
// regrid = {
${METPLUS_REGRID_DICT}

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

//censor_thresh =
${METPLUS_CENSOR_THRESH}
//censor_val =
${METPLUS_CENSOR_VAL}
//cat_thresh =
${METPLUS_CAT_THRESH}
cnt_thresh  	 = [ NA ];
cnt_logic   	 = UNION;
wind_thresh 	 = [ NA ];
wind_logic  	 = UNION;
eclv_points      = 0.05;
//nc_pairs_var_name =
${METPLUS_NC_PAIRS_VAR_NAME}
nc_pairs_var_suffix = "";
//hss_ec_value =
${METPLUS_HSS_EC_VALUE}

rank_corr_flag   = FALSE;

//
// Forecast and observation fields to be verified
//
fcst = {
  ${METPLUS_FCST_FILE_TYPE}
  ${METPLUS_FCST_FIELD}
  ${METPLUS_FCST_CLIMO_MEAN_DICT}
  ${METPLUS_FCST_CLIMO_STDEV_DICT}
}
obs = {
  ${METPLUS_OBS_FILE_TYPE}
  ${METPLUS_OBS_FIELD}
  ${METPLUS_OBS_CLIMO_MEAN_DICT}
  ${METPLUS_OBS_CLIMO_STDEV_DICT}
}

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

//
// Climatology mean data
//
//climo_mean = {
${METPLUS_CLIMO_MEAN_DICT}


//climo_stdev = {
${METPLUS_CLIMO_STDEV_DICT}

//
// May be set separately in each "obs.field" entry
//
//climo_cdf = {
${METPLUS_CLIMO_CDF_DICT}

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

//
// Verification masking regions
//
// mask = {
${METPLUS_MASK_DICT}

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

//
// Confidence interval settings
//
ci_alpha  = [ 0.05 ];

boot = {
   interval = PCTILE;
   rep_prop = 1.0;
   n_rep    = 0;
   rng      = "mt19937";
   seed     = "";
}

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

//
// Data smoothing methods
//
//interp = {
${METPLUS_INTERP_DICT}

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

//
// Neighborhood methods
//
nbrhd = {
   field      = BOTH;
   // shape =
   ${METPLUS_NBRHD_SHAPE}
   // width =
   ${METPLUS_NBRHD_WIDTH}
   // cov_thresh =
   ${METPLUS_NBRHD_COV_THRESH}
   vld_thresh = 1.0;
}

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

//
// Fourier decomposition
// May be set separately in each "obs.field" entry
//
//fourier = {
${METPLUS_FOURIER_DICT}

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

//
// Gradient statistics
// May be set separately in each "obs.field" entry
//
//gradient = {
${METPLUS_GRADIENT_DICT}

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

//
// Distance Map statistics
// May be set separately in each "obs.field" entry
//
//distance_map = {
${METPLUS_DISTANCE_MAP_DICT}


////////////////////////////////////////////////////////////////////////////////
// Threshold for SEEPS p1 (Probability of being dry)

//seeps_p1_thresh =
${METPLUS_SEEPS_P1_THRESH}

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

//
// Statistical output types
//
//output_flag = {
${METPLUS_OUTPUT_FLAG_DICT}

//
// NetCDF matched pairs output file
// May be set separately in each "obs.field" entry
//
// nc_pairs_flag = {
${METPLUS_NC_PAIRS_FLAG_DICT}

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

//ugrid_dataset =
${METPLUS_UGRID_DATASET}

//ugrid_max_distance_km =
${METPLUS_UGRID_MAX_DISTANCE_KM}

//ugrid_coordinates_file =
${METPLUS_UGRID_COORDINATES_FILE}

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

//grid_weight_flag =
${METPLUS_GRID_WEIGHT_FLAG}

tmp_dir = "${MET_TMP_DIR}";

// output_prefix =
${METPLUS_OUTPUT_PREFIX}

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

${METPLUS_TIME_OFFSET_WARNING}
${METPLUS_MET_CONFIG_OVERRIDES}
SeriesAnalysisConfig_wrapped
////////////////////////////////////////////////////////////////////////////////
//
// Series-Analysis configuration file.
//
// For additional information, see the MET_BASE/config/README file.
//
////////////////////////////////////////////////////////////////////////////////

//
// Output model name to be written
//
//model =
${METPLUS_MODEL}

//
// Output description to be written
//
//desc =
${METPLUS_DESC}

//
// Output observation type to be written
//
//obtype =
${METPLUS_OBTYPE}

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

//
// Verification grid
// May be set separately in each "field" entry
//
//regrid = {
${METPLUS_REGRID_DICT}

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

censor_thresh = [];
censor_val    = [];
//cat_thresh =
${METPLUS_CAT_THRESH}
cnt_thresh    = [ NA ];
cnt_logic     = UNION;

//
// Forecast and observation fields to be verified
//
fcst = {
   ${METPLUS_FCST_FILE_TYPE}
   ${METPLUS_FCST_CAT_THRESH}
   //field = [
   ${METPLUS_FCST_FIELD}
   ${METPLUS_FCST_CLIMO_MEAN_DICT}
   ${METPLUS_FCST_CLIMO_STDEV_DICT}
}
obs = {
   ${METPLUS_OBS_FILE_TYPE}
   ${METPLUS_OBS_CAT_THRESH}
   //field = [
   ${METPLUS_OBS_FIELD}
   ${METPLUS_OBS_CLIMO_MEAN_DICT}
   ${METPLUS_OBS_CLIMO_STDEV_DICT}
}

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

//
// Climatology data
//
//climo_mean = {
${METPLUS_CLIMO_MEAN_DICT}


//climo_stdev = {
${METPLUS_CLIMO_STDEV_DICT}

//climo_cdf = {
${METPLUS_CLIMO_CDF_DICT}

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

//
// Confidence interval settings
//
ci_alpha  = [ 0.05 ];

boot = {
   interval = PCTILE;
   rep_prop = 1.0;
   n_rep    = 0;
   rng      = "mt19937";
   seed     = "";
}

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

//
// Verification masking regions
//
//mask = {
${METPLUS_MASK_DICT}

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

//
// Gradient statistics
// May be set separately in each "obs.field" entry
//
//gradient = {
${METPLUS_GRADIENT_DICT}

//
// Number of grid points to be processed concurrently.  Set smaller to use
// less memory but increase the number of passes through the data.
//
//block_size =
${METPLUS_BLOCK_SIZE}

//
// Ratio of valid matched pairs to compute statistics for a grid point
//
//vld_thresh =
${METPLUS_VLD_THRESH}

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

//
// Statistical output types
//
//output_stats = {
${METPLUS_OUTPUT_STATS_DICT}

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

//hss_ec_value =
${METPLUS_HSS_EC_VALUE}
rank_corr_flag = FALSE;

tmp_dir = "${MET_TMP_DIR}";

//version        = "V10.0";

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

${METPLUS_TIME_OFFSET_WARNING}
${METPLUS_MET_CONFIG_OVERRIDES}

Python Embedding

This use case calls the read_SMOPS_data.py script to read and pass to GridStat and SeriesAnalysis a MET-usable dataset for the observation data. In its current form, the SMOPS data is read in by MET upside down, and is not CF-compliant. Using a simplified Python script, the input file and variable field are passed at runtime and the associated data is extracted. This is passed in memory to MET and verification proceeds normally.

parm/use_cases/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python/read_SMOPS_data.py
import sys
from netCDF4 import Dataset
import numpy as np

filename, vari_name = sys.argv[1:]

f_in = Dataset(filename, 'r')

met_data = f_in[vari_name][:]
date_info = f_in.Date_Start


attrs = {

        'valid': str(date_info)+'_000000',
        'init': str(date_info)+'_000000',
        'name': vari_name,
        'long_name': f_in[vari_name].long_name,
        'lead': '00',
        'accum': '00',
        'level': 'UNKNOWN',
        'units': f_in[vari_name].units,

        'grid': {
            'name': 'Global 0.25 degree',
            'type': 'LatLon',
            'lat_ll': -90.0,
            'lon_ll': -180.0,
            'delta_lat': 0.25,
            'delta_lon': 0.25,

            'Nlon': f_in.dimensions['Longitude'].size,
            'Nlat': f_in.dimensions['Latitude'].size,
            }
        }

#print some output to show script ran successfully
print("Input file: " + repr(filename))
print("Variable name: " + repr(vari_name))
print("Attributes:\t" + repr(attrs))
f_in.close()

For more information on the basic requirements to utilize Python Embedding in METplus, please refer to the MET User’s Guide section on Python embedding.

User Scripting

This use case does not use additional scripts.

Running METplus

Pass the use case configuration file to the run_metplus.py script along with any user-specific system configuration files if desired:

run_metplus.py /path/to/METplus/parm/use_cases/model_applications/land/GridStat_fcstGFS_obsSMOPS_soilMoisture_Python.conf /path/to/user_system.conf

See Running METplus for more information.

Expected Output

A successful run will output the following both to the screen and to the logfile:

INFO: METplus has successfully finished running.

Refer to the value set for OUTPUT_BASE to find where the output data was generated. Output will be in two subfolders relative to OUTPUT_BASE:

  • GridStat

  • SeriesAnalysis

Each of these directories will hold the output from their respectively named tools. The GridStat folder will contain two files, one STAT file with the CNT line type output and one netCDF file, which contains 3 fields (not including the lat/lon fields). Those fields are:

  • FCST_SOILW_Z0.1-0_CONUS(lat, lon)

  • OBS_Blended_SM_UNKNOWN_CONUS(lat, lon)

  • DIFF_SOILW_Z0.1-0_Blended_SM_UNKNOWN_CONUS(lat, lon)

For the SeriesAnalysis folder, only one netCDF output is created. Six variable fields are present (not including the lat/lon and series fields). Those variables are:

  • series_cnt_ME(lat, lon)

  • series_cnt_MAE(lat, lon)

  • series_cnt_RMSE(lat, lon)

  • series_cnt_MBIAS(lat, lon)

  • series_cnt_FBAR(lat, lon)

  • series_cnt_OBAR(lat, lon)

Keywords

Note

  • GridStatToolUseCase

  • PythonEmbeddingFileUseCase

  • LandAppUseCase

Navigate to the METplus Quick Search for Use Cases page to discover other similar use cases.

sphinx_gallery_thumbnail_path = ‘_static/land-GridStat_fcstGFS_obsSMOPS_soilMoisture_Python.png’

Gallery generated by Sphinx-Gallery