Note
Go to the end to download the full example code.
Grid-Stat, MODE, Stat-Analysis, UserScript, Gen-Vx-Mask: GFS Cloud Statistics by Type
model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer.conf
Scientific Objective
This use case evaluates clouds classified into low, mid, and high levels. The evaluation covers multiple types of statistics including contingency table statistics, neighborhood statistics, distance maps, and an object based evaluation. Additionally, plots are created to demonstrate how to reformat and visualize GSS, CSI, and frequency bias from the command line.
Version Added
METplus version 6.1
Datasets
Forecast: GFS 0.25 degree model
Observation: GFS Analysis
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
This use case calls GenVxMask once, GridStat once, MODE three times, StatAnalysis once, and UserScript twice. MODE has three entries to facilitate calling MODE for three separate variables without invoking Muli-variate MODE, while GridStat is able to run for three separate variables with only one process list entry. Additionally, METcalcpy, METplotpy, and METdataio are required to run this use case. The METcalcpy scripts accessed include the following:
metcalcpy/util/read_env_vars_in_config.py
The METplopty scrips accessed include the following:
metplotpy/plots/line/line.py
The METdataio scripts accessed include the following:
METdbLoad/ush/read_data_files.py
METdbLoad/ush/read_load_xml.py
METreformat/write_stat_ascii.py
METplus Workflow
Beginning time (INIT_BEG): 2024030700
End time (INIT_END): 2024030700
Increment between beginning and end times (INIT_INCREMENT): 6 hours
Sequence of forecast leads to process (LEAD_SEQ): 0, 6, 12, 18
GenVxMask is run once. The Grid-Stat, MODE, and Stat-Analysis tools run for each time. This example loops by model initialization time. It processes one initialization time and three lead times for a total of 3 valid times, listed below.
Both UserScripts are each run once. The first UserScript reformats the GridStat CTS output so that it can be used to create a plot. The second UserScript creates three plots.
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, i.e. parm/use_cases/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer.conf
[config]
# Documentation for this use case can be found at
# https://metplus.readthedocs.io/en/latest/generated/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer.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 = GenVxMask(mask), GridStat, Mode(low_cloud), Mode(mid_cloud), Mode(high_cloud), StatAnalysis(agg_lead), UserScript(reformat_CTS), UserScript(plot_stats)
###
# 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 = 2024030700
INIT_END = 2024030700
INIT_INCREMENT = 21600
LEAD_SEQ = 0, 6, 12, 18
[mask]
# Make one mask for the entire time
INIT_END = {INIT_BEG}
LEAD_SEQ = 6
###
# File I/O
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#directory-and-filename-template-info
###
GEN_VX_MASK_INPUT_DIR = {INPUT_BASE}/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/GFS_0.25
GEN_VX_MASK_INPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/gfs.0p25.{init?fmt=%Y%m%d%H}.f{lead?fmt=%HHH}.grib2
GEN_VX_MASK_INPUT_MASK_DIR = {INPUT_BASE}/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/masks
GEN_VX_MASK_INPUT_MASK_TEMPLATE = West_Pacific.poly
GEN_VX_MASK_OUTPUT_DIR={OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/masks
GEN_VX_MASK_OUTPUT_TEMPLATE = West_Pacific.nc
###
# GenVxMask Settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#genvxmask
###
GEN_VX_MASK_OPTIONS = -type poly
# Return to the config section
[config]
###
# 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/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/GFS_0.25
FCST_GRID_STAT_INPUT_TEMPLATE = {init?fmt=%Y%m%d%H}/gfs.0p25.{init?fmt=%Y%m%d%H}.f{lead?fmt=%HHH}.grib2
OBS_GRID_STAT_INPUT_DIR = {INPUT_BASE}/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/analysis
OBS_GRID_STAT_INPUT_TEMPLATE = {valid?fmt=%Y%m%d}/gfs.t{valid?fmt=%H}z.pgrb2.0p25.f000
GRID_STAT_OUTPUT_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/grid_stat
GRID_STAT_OUTPUT_PREFIX = GFS_cloud
FCST_MODE_INPUT_DIR = {FCST_GRID_STAT_INPUT_DIR}
FCST_MODE_INPUT_TEMPLATE = {FCST_GRID_STAT_INPUT_TEMPLATE}
OBS_MODE_INPUT_DIR = {OBS_GRID_STAT_INPUT_DIR}
OBS_MODE_INPUT_TEMPLATE = {OBS_GRID_STAT_INPUT_TEMPLATE}
MODE_OUTPUT_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/mode
###
# Grid Stat Field Info
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info
###
MODEL = GFS
FCST_GRID_STAT_VAR1_NAME = LCDC
FCST_GRID_STAT_VAR1_LEVELS = L0
FCST_GRID_STAT_VAR1_OPTIONS = GRIB2_ipdtmpl_index=8; GRIB2_ipdtmpl_val = {lead?fmt=%H}
FCST_GRID_STAT_VAR1_THRESH = ge50
FCST_GRID_STAT_VAR2_NAME = MCDC
FCST_GRID_STAT_VAR2_LEVELS = L0
FCST_GRID_STAT_VAR2_OPTIONS = GRIB2_ipdtmpl_index=8; GRIB2_ipdtmpl_val = {lead?fmt=%H}
FCST_GRID_STAT_VAR2_THRESH = ge50
FCST_GRID_STAT_VAR3_NAME = HCDC
FCST_GRID_STAT_VAR3_LEVELS = L0
FCST_GRID_STAT_VAR3_OPTIONS = GRIB2_ipdtmpl_index=8; GRIB2_ipdtmpl_val = {lead?fmt=%H}
FCST_GRID_STAT_VAR3_THRESH = ge50
OBS_GRID_STAT_VAR1_NAME = LCDC
OBS_GRID_STAT_VAR1_LEVELS = L0
OBS_GRID_STAT_VAR1_THRESH = ge50
OBS_GRID_STAT_VAR2_NAME = MCDC
OBS_GRID_STAT_VAR2_LEVELS = L0
OBS_GRID_STAT_VAR2_THRESH = ge50
OBS_GRID_STAT_VAR3_NAME = HCDC
OBS_GRID_STAT_VAR3_LEVELS = L0
OBS_GRID_STAT_VAR3_THRESH = ge50
###
# GridStat Settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#gridstat
###
GRID_STAT_NEIGHBORHOOD_WIDTH = 5
GRID_STAT_NEIGHBORHOOD_SHAPE = SQUARE
#GRID_STAT_MASK_GRID =
GRID_STAT_MASK_POLY = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/masks/West_Pacific.nc
GRID_STAT_OUTPUT_FLAG_CTC = STAT
GRID_STAT_OUTPUT_FLAG_CTS = STAT
GRID_STAT_OUTPUT_FLAG_SL1L2 = STAT
GRID_STAT_OUTPUT_FLAG_CNT = STAT
GRID_STAT_OUTPUT_FLAG_NBRCTC = STAT
GRID_STAT_OUTPUT_FLAG_NBRCTS = STAT
GRID_STAT_OUTPUT_FLAG_NBRNT = STAT
GRID_STAT_OUTPUT_FLAG_DMAP = STAT
GRID_STAT_NC_PAIRS_FLAG_LATLON = TRUE
GRID_STAT_NC_PAIRS_FLAG_RAW = FALSE
GRID_STAT_NC_PAIRS_FLAG_DIFF = FALSE
GRID_STAT_NC_PAIRS_FLAG_CLIMO = FALSE
GRID_STAT_NC_PAIRS_FLAG_NBRHD = FALSE
GRID_STAT_NC_PAIRS_FLAG_DISTANCE_MAP = TRUE
GRID_STAT_NC_PAIRS_FLAG_APPLY_MASK = FALSE
###
# Field Info for common MODE settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#field-info
###
FCST_MODE_VAR1_LEVELS = L0
FCST_MODE_VAR1_OPTIONS = GRIB2_ipdtmpl_index=8; GRIB2_ipdtmpl_val = {lead?fmt=%H};
FCST_MODE_CONV_RADIUS = 5
FCST_MODE_CONV_THRESH = ge50
FCST_MODE_MERGE_FLAG = THRESH
#FCST_MODE_MERGE_FLAG = NONE
FCST_MODE_MERGE_THRESH = ge30
MODE_FCST_FILTER_ATT_NAME = AREA
MODE_FCST_FILTER_ATT_THRESH = ge2
OBS_MODE_VAR1_LEVELS = L0
OBS_MODE_CONV_RADIUS = 5
OBS_MODE_CONV_THRESH = ge50
OBS_MODE_MERGE_FLAG = THRESH
#OBS_MODE_MERGE_FLAG = NONE
OBS_MODE_MERGE_THRESH = ge30
MODE_OBS_FILTER_ATT_NAME = AREA
MODE_OBS_FILTER_ATT_THRESH = ge2
###
# Mode Settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#mode
###
MODE_QUILT = False
#MODE_MATCH_FLAG = MERGE_BOTH
MODE_GRID_RES = 28
MODE_MASK_MISSING_FLAG = BOTH
MODE_MASK_POLY_FLAG = BOTH
MODE_VERIFICATION_MASK_TEMPLATE = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/masks/West_Pacific.nc
MODE_NC_PAIRS_FLAG_POLYLINES = False
[low_cloud]
###
# Mode Settings Specific to Low Clouds
###
FCST_MODE_VAR1_NAME = LCDC
OBS_MODE_VAR1_NAME = LCDC
MODE_OUTPUT_PREFIX = GFS_low_cloud
[mid_cloud]
###
# Mode Settings Specific to Mid Level Clouds
###
FCST_MODE_VAR1_NAME = MCDC
OBS_MODE_VAR1_NAME = MCDC
MODE_OUTPUT_PREFIX = GFS_mid_cloud
[high_cloud]
###
# Mode Settings Specific to High Clouds
###
FCST_MODE_VAR1_NAME = HCDC
OBS_MODE_VAR1_NAME = HCDC
MODE_OUTPUT_PREFIX = GFS_high_cloud
[agg_lead]
###
# Settings for the Stat Analysis Run
###
###
# File I/O
# https://metplus.readthedocs.io/en/latest/Users_Guide/systemconfiguration.html#directory-and-filename-template-info
###
MODEL1 = GFS
STAT_ANALYSIS_CONFIG_FILE = {PARM_BASE}/met_config/STATAnalysisConfig_wrapped
MODEL1_STAT_ANALYSIS_LOOKIN_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/grid_stat
STAT_ANALYSIS_OUTPUT_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/stat_analysis
MODEL1_STAT_ANALYSIS_OUT_STAT_TEMPLATE = stat_analysis_{model?fmt=%s}_ANAL_{vx_mask?fmt=%s}_{lead?fmt=%H%M%S}L_CTS.stat
###
# StatAnalysis Settings
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#statanalysis
###
STAT_ANALYSIS_JOB1 = -job aggregate_stat -line_type CTC -out_line_type CTS -by fcst_var -out_stat [out_stat_file]
MODEL_LIST = {MODEL1}
FCST_LEAD_LIST = 00, 06, 12, 18
VX_MASK_LIST = West_Pacific
GROUP_LIST_ITEMS = MODEL_LIST, VX_MASK_LIST
LOOP_LIST_ITEMS = FCST_LEAD_LIST
[user_env_vars]
# Paths to METdataio, METcalcpy, and METplotpy as needed for the use case
METDATAIO_BASE = {METPLUS_BASE}/../METdataio
METCALCPY_BASE = {METPLUS_BASE}/../METcalcpy
METPLOTPY_BASE = {METPLUS_BASE}/../METplotpy
PYTHONPATH = {METDATAIO_BASE}:{METDATAIO_BASE}/METdbLoad:{METDATAIO_BASE}/METdbLoad/ush:{METDATAIO_BASE}/METreformat:{METCALCPY_BASE}:{METCALCPY_BASE}/metcalcpy:{METPLOTPY_BASE}:{METPLOTPY_BASE}/metplotpy/plots
###
# Settings for the reformatting of the CTS linetype, to later be iused for plotting
###
#
REFORMAT_YAML_CONFIG_NAME = {PARM_BASE}/use_cases/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/reformat_CTS.yaml
# Input directory where the .stat files you need to reformat are located
REFORMAT_INPUT_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/stat_analysis
# Output directory to store the reformatted data
REFORMAT_OUTPUT_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/reformatted
# Name of the output file containing reformatted data
REFORMAT_OUTPUT_FILENAME = reformat_CTS.data
# Line type to reformat
# Currently support FHO, CTC, CTS, CNT, SL1L2, VL1L2, PCT, MCTC, VCNT, ECNT, RHIST, TCDiag, and MPR line types
REFORMAT_LINETYPE = CTS
###
# Settings for creating the plots of GSS, CSI, and frequency bias
###
# Directory where the YAML configurations for plotting are located
PLOTTING_YAML_CONFIG_DIR = {PARM_BASE}/use_cases/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer
# YAML Configuration file list
PLOTTING_YAML_CONFIG_FILE_LIST = custom_line_GSS.yaml, custom_line_CSI.yaml, custom_line_FBIAS.yaml
#Input for plotting (this is the Reformatted data above
PLOTTING_STAT_INPUT = {REFORMAT_OUTPUT_DIR}/{REFORMAT_OUTPUT_FILENAME}
# Output directory for plots
PLOTTING_OUTPUT_DIR = {OUTPUT_BASE}/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/plots
# List of the output filenames for plotting. This should have the same number of files as
# PLOTTING_YAML_CONFIG_FILE_LIST and they should be in the same order
PLOTTING_OUTPUT_FILENAME_LIST = High_low_cloud_GSS.png, High_low_cloud_CSI.png, High_low_cloud_FBIAS.png
# Log file for the plotting
PLOTTING_LOG_FILENAME = {LOG_DIR}/plotting.log
[reformat_CTS]
###
# UserScript Settings to reformat the CTS linetype
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#userscript
###
USER_SCRIPT_RUNTIME_FREQ = RUN_ONCE
USER_SCRIPT_COMMAND = {PARM_BASE}/use_cases/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/reformat_CTS_linetype.py
[plot_stats]
###
# UserScript Settings to create the plots
# https://metplus.readthedocs.io/en/latest/Users_Guide/wrappers.html#userscript
###
USER_SCRIPT_RUNTIME_FREQ = RUN_ONCE
USER_SCRIPT_COMMAND = {PARM_BASE}/use_cases/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer/plot_line_stats.py
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}
MODEConfig_wrapped
////////////////////////////////////////////////////////////////////////////////
//
// MODE 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
//
// regrid = {
${METPLUS_REGRID_DICT}
////////////////////////////////////////////////////////////////////////////////
//
// Approximate grid resolution (km)
//
// grid_res =
${METPLUS_GRID_RES}
////////////////////////////////////////////////////////////////////////////////
//
// Run all permutations of radius and threshold
//
// quilt =
${METPLUS_QUILT}
//
// MODE Multivar boolean combination logic
//
//multivar_logic =
${METPLUS_MULTIVAR_LOGIC}
//multivar_intensity_compare_fcst =
${METPLUS_MULTIVAR_INTENSITY_COMPARE_FCST}
//multivar_intensity_compare_obs =
${METPLUS_MULTIVAR_INTENSITY_COMPARE_OBS}
//
// Forecast and observation fields to be verified
//
fcst = {
//field = {
${METPLUS_FCST_FIELD}
//censor_thresh = [
${METPLUS_FCST_CENSOR_THRESH}
//censor_val = [
${METPLUS_FCST_CENSOR_VAL}
//conv_radius =
${METPLUS_FCST_CONV_RADIUS}
//conv_thresh =
${METPLUS_FCST_CONV_THRESH}
//vld_thresh =
${METPLUS_FCST_VLD_THRESH}
//filter_attr_name = [
${METPLUS_FCST_FILTER_ATTR_NAME}
//filter_attr_thresh = [
${METPLUS_FCST_FILTER_ATTR_THRESH}
//merge_thresh =
${METPLUS_FCST_MERGE_THRESH}
//merge_flag =
${METPLUS_FCST_MERGE_FLAG}
${METPLUS_FCST_FILE_TYPE}
${METPLUS_FCST_MULTIVAR_NAME}
${METPLUS_FCST_MULTIVAR_LEVEL}
}
obs = {
//field = {
${METPLUS_OBS_FIELD}
//censor_thresh = [
${METPLUS_OBS_CENSOR_THRESH}
//censor_val = [
${METPLUS_OBS_CENSOR_VAL}
//conv_radius =
${METPLUS_OBS_CONV_RADIUS}
//conv_thresh =
${METPLUS_OBS_CONV_THRESH}
//vld_thresh =
${METPLUS_OBS_VLD_THRESH}
//filter_attr_name = [
${METPLUS_OBS_FILTER_ATTR_NAME}
//filter_attr_thresh = [
${METPLUS_OBS_FILTER_ATTR_THRESH}
//merge_thresh =
${METPLUS_OBS_MERGE_THRESH}
//merge_flag =
${METPLUS_OBS_MERGE_FLAG}
${METPLUS_OBS_FILE_TYPE}
${METPLUS_OBS_MULTIVAR_NAME}
${METPLUS_OBS_MULTIVAR_LEVEL}
}
////////////////////////////////////////////////////////////////////////////////
//
// Handle missing data
//
// mask_missing_flag =
${METPLUS_MASK_MISSING_FLAG}
//
// Match objects between the forecast and observation fields
//
//match_flag =
${METPLUS_MATCH_FLAG}
//
// Maximum centroid distance for objects to be compared
//
//max_centroid_dist =
${METPLUS_MAX_CENTROID_DIST}
////////////////////////////////////////////////////////////////////////////////
//
// Verification masking regions
//
//mask = {
${METPLUS_MASK_DICT}
////////////////////////////////////////////////////////////////////////////////
//
// Fuzzy engine weights
//
//weight = {
${METPLUS_WEIGHT_DICT}
////////////////////////////////////////////////////////////////////////////////
//
// Fuzzy engine interest functions
//
interest_function = {
//centroid_dist = (
${METPLUS_INTEREST_FUNCTION_CENTROID_DIST}
//boundary_dist = (
${METPLUS_INTEREST_FUNCTION_BOUNDARY_DIST}
//convex_hull_dist = (
${METPLUS_INTEREST_FUNCTION_CONVEX_HULL_DIST}
angle_diff = (
( 0.0, 1.0 )
( 30.0, 1.0 )
( 90.0, 0.0 )
);
aspect_diff = (
( 0.00, 1.0 )
( 0.10, 1.0 )
( 0.75, 0.0 )
);
corner = 0.8;
ratio_if = (
( 0.0, 0.0 )
( corner, 1.0 )
( 1.0, 1.0 )
);
area_ratio = ratio_if;
int_area_ratio = (
( 0.00, 0.00 )
( 0.10, 0.50 )
( 0.25, 1.00 )
( 1.00, 1.00 )
);
curvature_ratio = ratio_if;
complexity_ratio = ratio_if;
inten_perc_ratio = ratio_if;
}
////////////////////////////////////////////////////////////////////////////////
//
// Total interest threshold for determining matches
//
//total_interest_thresh =
${METPLUS_TOTAL_INTEREST_THRESH}
//
// Interest threshold for printing output pair information
//
print_interest_thresh = 0.0;
////////////////////////////////////////////////////////////////////////////////
//
// Plotting information
//
met_data_dir = "MET_BASE";
fcst_raw_plot = {
color_table = "MET_BASE/colortables/met_default.ctable";
plot_min = 0.0;
plot_max = 0.0;
}
obs_raw_plot = {
color_table = "MET_BASE/colortables/met_default.ctable";
plot_min = 0.0;
plot_max = 0.0;
}
object_plot = {
color_table = "MET_BASE/colortables/mode_obj.ctable";
}
//
// Boolean for plotting on the region of valid data within the domain
//
plot_valid_flag = FALSE;
//
// Plot polyline edges using great circle arcs instead of straight lines
//
plot_gcarc_flag = FALSE;
////////////////////////////////////////////////////////////////////////////////
//
// NetCDF matched pairs, PostScript, and contingency table output files
//
//ps_plot_flag =
${METPLUS_PS_PLOT_FLAG}
//nc_pairs_flag = {
${METPLUS_NC_PAIRS_FLAG_DICT}
//ct_stats_flag =
${METPLUS_CT_STATS_FLAG}
////////////////////////////////////////////////////////////////////////////////
shift_right = 0; // grid squares
////////////////////////////////////////////////////////////////////////////////
${METPLUS_OUTPUT_PREFIX}
//version = "V10.0";
tmp_dir = "${MET_TMP_DIR}";
////////////////////////////////////////////////////////////////////////////////
${METPLUS_TIME_OFFSET_WARNING}
${METPLUS_MET_CONFIG_OVERRIDES}
StatAnalysisConfig_wrapped
////////////////////////////////////////////////////////////////////////////////
//
// STAT-Analysis configuration file.
//
// For additional information, see the MET_BASE/config/README file.
//
////////////////////////////////////////////////////////////////////////////////
//
// Filtering input STAT lines by the contents of each column
//
//model = [
${METPLUS_MODEL}
//desc = [
${METPLUS_DESC}
//fcst_lead = [
${METPLUS_FCST_LEAD}
//obs_lead = [
${METPLUS_OBS_LEAD}
//fcst_valid_beg =
${METPLUS_FCST_VALID_BEG}
//fcst_valid_end =
${METPLUS_FCST_VALID_END}
fcst_valid_inc = [];
fcst_valid_exc = [];
//fcst_valid_hour = [
${METPLUS_FCST_VALID_HOUR}
//obs_valid_beg =
${METPLUS_OBS_VALID_BEG}
//obs_valid_end =
${METPLUS_OBS_VALID_END}
obs_valid_inc = [];
obs_valid_exc = [];
//obs_valid_hour = [
${METPLUS_OBS_VALID_HOUR}
//fcst_init_beg =
${METPLUS_FCST_INIT_BEG}
//fcst_init_end =
${METPLUS_FCST_INIT_END}
fcst_init_inc = [];
fcst_init_exc = [];
//fcst_init_hour = [
${METPLUS_FCST_INIT_HOUR}
//obs_init_beg =
${METPLUS_OBS_INIT_BEG}
//obs_init_end =
${METPLUS_OBS_INIT_END}
obs_init_inc = [];
obs_init_exc = [];
//obs_init_hour = [
${METPLUS_OBS_INIT_HOUR}
//fcst_var = [
${METPLUS_FCST_VAR}
//obs_var = [
${METPLUS_OBS_VAR}
//fcst_units = [
${METPLUS_FCST_UNITS}
//obs_units = [
${METPLUS_OBS_UNITS}
//fcst_lev = [
${METPLUS_FCST_LEVEL}
//obs_lev = [
${METPLUS_OBS_LEVEL}
//obtype = [
${METPLUS_OBTYPE}
//vx_mask = [
${METPLUS_VX_MASK}
//interp_mthd = [
${METPLUS_INTERP_MTHD}
//interp_pnts = [
${METPLUS_INTERP_PNTS}
//fcst_thresh = [
${METPLUS_FCST_THRESH}
//obs_thresh = [
${METPLUS_OBS_THRESH}
//cov_thresh = [
${METPLUS_COV_THRESH}
//alpha = [
${METPLUS_ALPHA}
//line_type = [
${METPLUS_LINE_TYPE}
column = [];
weight = [];
////////////////////////////////////////////////////////////////////////////////
//
// Array of STAT-Analysis jobs to be performed on the filtered data
//
//jobs = [
${METPLUS_JOBS}
////////////////////////////////////////////////////////////////////////////////
//
// Confidence interval settings
//
out_alpha = 0.05;
boot = {
interval = PCTILE;
rep_prop = 1.0;
n_rep = 0;
rng = "mt19937";
seed = "";
}
////////////////////////////////////////////////////////////////////////////////
//
// WMO mean computation logic
//
wmo_sqrt_stats = [ "CNT:FSTDEV", "CNT:OSTDEV", "CNT:ESTDEV",
"CNT:RMSE", "CNT:RMSFA", "CNT:RMSOA",
"VCNT:FS_RMS", "VCNT:OS_RMS", "VCNT:RMSVE",
"VCNT:FSTDEV", "VCNT:OSTDEV" ];
wmo_fisher_stats = [ "CNT:PR_CORR", "CNT:SP_CORR",
"CNT:KT_CORR", "CNT:ANOM_CORR" ];
////////////////////////////////////////////////////////////////////////////////
//hss_ec_value =
${METPLUS_HSS_EC_VALUE}
rank_corr_flag = FALSE;
vif_flag = FALSE;
tmp_dir = "${MET_TMP_DIR}";
//version = "V10.0";
${METPLUS_MET_CONFIG_OVERRIDES}
Python Embedding
This use case does not use Python embedding.
User Scripting
There are two Python scripts used in this use case, called using the “UserScript” keyword in the METplus wrappers PROCESS_LIST configuration item. These scripts provide an interface to the functions in the METdataio, METcalcpy, and METplotpy Python modules of METplus. The functions used in these scripts demonstrate reformatting aggregated StatAnalysis output to meet the format required by METcalcpy and METplotpy, and then plotting that reformatted output using functions from METcalcpy and METplotpy.
The first Python script is called reformat_CTS_linetype.py. This script takes the aggregated output CTS linetype from Stat Analysis and reformats it so that the data can be plotted. The script takes an input .yaml file, reformat_CTS.yaml. Environment variables in the yaml file are specified in the [user_env_vars] section of the GridStat_fcstGFS_obsGFS_cloudFracLayer.conf METplus configuration file.
The second Python script is plot_line_stats.py. This script creates line plots for low and high clouds for GSS, CSI, and Frequency bias with lead time, using the YAML files custom_line_CSI.yaml, custom_line_FBIAS.yaml, and custom_line_GSS.yaml Input variables to both scripts are set in the [user_env_vars] section of the GridStat_fcstGFS_obsGFS_cloudFracLayer.conf file.
For more information about YAML configuration options for the line plots shown here, see the METplotpy line plot documentation.
Both Python scripts are located at:
parm/use_cases/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer
reformat_CTS_linetype.py
#!/usr/bin/env python3
import os
import time
import logging
from METdbLoad.ush.read_data_files import ReadDataFiles
from METdbLoad.ush.read_load_xml import XmlLoadFile
from METreformat.write_stat_ascii import WriteStatAscii
from metcalcpy.util import read_env_vars_in_config as readconfig
logger = logging.getLogger(__name__)
def main():
# Read in the YAML configuration file. Environment variables in
# the configuration file are supported.
input_config_file = os.getenv("REFORMAT_YAML_CONFIG_NAME", "reformat_CTS.yaml")
settings = readconfig.parse_config(input_config_file)
logging.info(settings)
# Replacing the need for an XML specification file, pass in the XMLLoadFile and
# ReadDataFile parameters
rdf_obj: ReadDataFiles = ReadDataFiles()
xml_loadfile_obj: XmlLoadFile = XmlLoadFile(None)
# Retrieve all the filenames in the data_dir specified in the YAML config file
load_files = xml_loadfile_obj.filenames_from_template(settings['input_data_dir'],
{})
flags = xml_loadfile_obj.flags
print(flags)
line_types = xml_loadfile_obj.line_types
print(line_types)
beg_read_data = time.perf_counter()
rdf_obj.read_data(flags, load_files, line_types)
end_read_data = time.perf_counter()
time_to_read = end_read_data - beg_read_data
logger.info("Time to read input .stat data files using METdbLoad: %f", time_to_read)
file_df = rdf_obj.stat_data
# Check if the output file already exists, if so, delete it to avoid
# appending output from subsequent runs into the same file.
existing_output_file = os.path.join(settings['output_dir'], settings['output_filename'])
logger.info("Checking if {existing_output_file} already exists")
if os.path.exists(existing_output_file):
logger.info("Removing existing output file {existing_output_file}")
os.remove(existing_output_file)
# Write stat file in ASCII format
stat_lines_obj: WriteStatAscii = WriteStatAscii(settings, logger)
# stat_lines_obj.write_stat_ascii(file_df, parms, logger)
stat_lines_obj.write_stat_ascii(file_df, settings)
if __name__ == "__main__":
main()
plot_line_stats.py
#!/usr/bin/env python3
import os
from time import perf_counter
import logging
import yaml
import metcalcpy.util.read_env_vars_in_config as readconfig
from metplotpy.plots.line import line
def main():
# Read the input files
yaml_files_str = os.environ['PLOTTING_YAML_CONFIG_FILE_LIST'].split(',')
yaml_files = [yf.lstrip() for yf in yaml_files_str]
yaml_file_dir = os.environ['PLOTTING_YAML_CONFIG_DIR']
plot_output_file_list_str = os.environ['PLOTTING_OUTPUT_FILENAME_LIST'].split(',')
plot_output_files = [po.lstrip() for po in plot_output_file_list_str]
plot_output_dir = os.environ['PLOTTING_OUTPUT_DIR']
# Check to see that the two lists have the same number of elements
# If they dont', error out
if len(yaml_files) != len(plot_output_files):
raise RuntimeError('The number of files in PLOTTING_YAML_CONFIG_FILE_LIST must be equal to the number of files in PLOTTING_OUTPUT_FILENAME_LIST')
# Loop through data
for i,j in zip (yaml_files,plot_output_files):
os.environ['PLOTTING_YAML_CONFIG_NAME'] = os.path.join(yaml_file_dir,i)
os.environ['PLOTTING_OUTPUT_FILENAME'] = os.path.join(plot_output_dir,j)
# Read in the YAML configuration file. Environment variables in
# the configuration file are supported.
try:
input_config_file = os.getenv("PLOTTING_YAML_CONFIG_NAME", "custom_line.yaml")
settings = readconfig.parse_config(input_config_file)
logging.info(settings)
except yaml.YAMLError as exc:
logging.error(exc)
try:
start = perf_counter()
plot = line.Line(settings)
plot.save_to_file()
plot.write_html()
plot.write_output_file()
end = perf_counter()
execution_time = end - start
plot.logger.info(f"Finished creating line plot, execution time: {execution_time} seconds")
except ValueError as val_er:
print(val_er)
if __name__ == "__main__":
main()
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/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer.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 for this use case will be found in {OUTPUT_BASE}/model_applications/clouds/GridStat_fcstGFS_obsGFS_cloudFracLayer. There will be 6 directories with output data, masks, grid_stat, mode, stat_analysis, reformatted, and plots. The mask directory will contain an input mask and the following output mask file:
* West_Pacific.nc
The grid_stat directory will contain 4 .stat file sand 4 .nc files:
* grid_stat_GFS_cloud_000000L_20240307_000000V_pairs.nc
* grid_stat_GFS_cloud_000000L_20240307_000000V.stat
* grid_stat_GFS_cloud_060000L_20240307_060000V_pairs.nc
* grid_stat_GFS_cloud_060000L_20240307_060000V.stat
* grid_stat_GFS_cloud_120000L_20240307_120000V_pairs.nc
* grid_stat_GFS_cloud_120000L_20240307_120000V.stat
* grid_stat_GFS_cloud_180000L_20240307_180000V_pairs.nc
* grid_stat_GFS_cloud_180000L_20240307_180000V.stat
The mode directory will contain the following files:
* mode_GFS_high_cloud_000000L_20240307_000000V_000000A_cts.txt
* mode_GFS_high_cloud_000000L_20240307_000000V_000000A_obj.nc
* mode_GFS_high_cloud_000000L_20240307_000000V_000000A_obj.txt
* mode_GFS_high_cloud_000000L_20240307_000000V_000000A.ps
* mode_GFS_high_cloud_060000L_20240307_060000V_000000A_cts.txt
* mode_GFS_high_cloud_060000L_20240307_060000V_000000A_obj.nc
* mode_GFS_high_cloud_060000L_20240307_060000V_000000A_obj.txt
* mode_GFS_high_cloud_060000L_20240307_060000V_000000A.ps
* mode_GFS_high_cloud_120000L_20240307_120000V_000000A_cts.txt
* mode_GFS_high_cloud_120000L_20240307_120000V_000000A_obj.nc
* mode_GFS_high_cloud_120000L_20240307_120000V_000000A_obj.txt
* mode_GFS_high_cloud_120000L_20240307_120000V_000000A.ps
* mode_GFS_high_cloud_180000L_20240307_180000V_000000A_cts.txt
* mode_GFS_high_cloud_180000L_20240307_180000V_000000A_obj.nc
* mode_GFS_high_cloud_180000L_20240307_180000V_000000A_obj.txt
* mode_GFS_high_cloud_180000L_20240307_180000V_000000A.ps
* mode_GFS_low_cloud_000000L_20240307_000000V_000000A_cts.txt
* mode_GFS_low_cloud_000000L_20240307_000000V_000000A_obj.nc
* mode_GFS_low_cloud_000000L_20240307_000000V_000000A_obj.txt
* mode_GFS_low_cloud_000000L_20240307_000000V_000000A.ps
* mode_GFS_low_cloud_060000L_20240307_060000V_000000A_cts.txt
* mode_GFS_low_cloud_060000L_20240307_060000V_000000A_obj.nc
* mode_GFS_low_cloud_060000L_20240307_060000V_000000A_obj.txt
* mode_GFS_low_cloud_060000L_20240307_060000V_000000A.ps
* mode_GFS_low_cloud_120000L_20240307_120000V_000000A_cts.txt
* mode_GFS_low_cloud_120000L_20240307_120000V_000000A_obj.nc
* mode_GFS_low_cloud_120000L_20240307_120000V_000000A_obj.txt
* mode_GFS_low_cloud_120000L_20240307_120000V_000000A.ps
* mode_GFS_low_cloud_180000L_20240307_180000V_000000A_cts.txt
* mode_GFS_low_cloud_180000L_20240307_180000V_000000A_obj.nc
* mode_GFS_low_cloud_180000L_20240307_180000V_000000A_obj.txt
* mode_GFS_low_cloud_180000L_20240307_180000V_000000A.ps
* mode_GFS_mid_cloud_000000L_20240307_000000V_000000A_cts.txt
* mode_GFS_mid_cloud_000000L_20240307_000000V_000000A_obj.nc
* mode_GFS_mid_cloud_000000L_20240307_000000V_000000A_obj.txt
* mode_GFS_mid_cloud_000000L_20240307_000000V_000000A.ps
* mode_GFS_mid_cloud_060000L_20240307_060000V_000000A_cts.txt
* mode_GFS_mid_cloud_060000L_20240307_060000V_000000A_obj.nc
* mode_GFS_mid_cloud_060000L_20240307_060000V_000000A_obj.txt
* mode_GFS_mid_cloud_060000L_20240307_060000V_000000A.ps
* mode_GFS_mid_cloud_120000L_20240307_120000V_000000A_cts.txt
* mode_GFS_mid_cloud_120000L_20240307_120000V_000000A_obj.nc
* mode_GFS_mid_cloud_120000L_20240307_120000V_000000A_obj.txt
* mode_GFS_mid_cloud_120000L_20240307_120000V_000000A.ps
* mode_GFS_mid_cloud_180000L_20240307_180000V_000000A_cts.txt
* mode_GFS_mid_cloud_180000L_20240307_180000V_000000A_obj.nc
* mode_GFS_mid_cloud_180000L_20240307_180000V_000000A_obj.txt
* mode_GFS_mid_cloud_180000L_20240307_180000V_000000A.ps
The stat_analysis directory will contain the following files:
* stat_analysis_GFS_ANAL_West_Pacific_000000L_CTS.stat
* stat_analysis_GFS_ANAL_West_Pacific_060000L_CTS.stat
* stat_analysis_GFS_ANAL_West_Pacific_120000L_CTS.stat
* stat_analysis_GFS_ANAL_West_Pacific_180000L_CTS.stat
The reformatted directory will contain the following files:
* reformat_CTS.data
The plots directory will contain the following files:
* High_low_cloud_CSI.png
* High_low_cloud_FBIAS.png
* High_low_cloud_GSS.png
For the Grid-Stat netCDF files, 6 variable fields are present (not including the lat/lon fields). Those variables are:
* FCST_DMAP_ge50_LCDC_L0_FULL(lat, lon)
* OBS_DMAP_ge50_LCDC_L0_FULL(lat, lon)
* FCST_DMAP_ge50_MCDC_L0_FULL(lat, lon)
* OBS_DMAP_ge50_MCDC_L0_FULL(lat, lon)
* FCST_DMAP_ge50_HCDC_L0_FULL(lat, lon)
* OBS_DMAP_ge50_HCDC_L0_FULL(lat, lon)
For the MODE netCDF files, 18 variable fields are present (not including the lat/lon fields). Those variables are:
* fcst_raw(lat, lon)
* fcst_obj_raw(lat, lon)
* fcst_obj_id(lat, lon)
* fcst_clus_id(lat, lon)
* obs_raw(lat, lon)
* obs_obj_raw(lat, lon)
* obs_obj_id(lat, lon)
* obs_clus_id(lat, lon)
* fcst_conv_radius
* obs_conv_radius
* fcst_conv_threshold(fcst_thresh_length)
* obs_conv_threshold(obs_thresh_length)
* fcst_variable(fcst_variable_length)
* obs_variable(obs_variable_length)
* fcst_level(fcst_level_length)
* obs_level(obs_level_length)
* fcst_units(fcst_units_length)
* obs_units(obs_units_length)
Keywords
Note
GridStatToolUseCase
MODEToolUseCase
StatAnalysisToolUseCase
UserScriptUseCase
ShortRangeAppUseCase
METdataioUseCase
METcalcpyUseCase
METplotpyUseCase
GRIB2FileUseCase
Navigate to the METplus Quick Search for Use Cases page to discover other similar use cases.