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.

Valid: 2024-03-07_00Z
Forecast lead: 00
Valid: 2024-03-07_06Z
Forecast lead: 06
Init: 2024-03-07_12Z
Forecast lead: 12
Init: 2024-03-07_18Z
Forecast lead: 18

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.

Gallery generated by Sphinx-Gallery