Skip to content

Getting started

METplus is the Python orchestration layer that drives the MET verification tools (Grid-Stat, Point-Stat, MODE, and more) so you can verify forecasts against observations without hand-writing each tool’s configuration. This page walks the practical path: what you need installed, how to obtain METplus, how its configuration hierarchy resolves settings, and how to launch a run with run_metplus.py.

The Model Evaluation Tools (MET) are a suite of command-line verification programs — each one compares a forecast field against an observation and writes statistics. Running them by hand means authoring a separate, detailed configuration for every tool, every date, and every field. METplus wraps those tools in Python so that a small set of human-readable .conf files can drive an entire workflow: it builds each tool’s configuration, loops over your times and forecast leads, and runs the tools in the order you specify.

The single entry point is a script named run_metplus.py. You hand it one or more configuration files; it reads them, resolves every setting, runs the requested wrappers, and reports “METplus has successfully finished running.” when it completes.

Before METplus can do anything useful, two pieces must already be in place: a working MET install and a Python environment with the right packages. The documentation lists these minimum versions.

Core requirements

These three are non-negotiable for nearly every workflow.

  • MET version 12.2.0 or above (install separately per the MET User’s Guide).
  • Python 3.12.0 or above.
  • python-dateutil 2.8 — required by most wrappers.

Wrapper-specific extras

Only needed if you run the wrapper that depends on them.

  • DataIngest: requests (2.32.5)
  • SeriesAnalysis: netCDF4 (1.5.4) plus ImageMagick’s convert
  • CyclonePlotter: cartopy (0.20.3) and matplotlib (3.5.2)

The base dependency can be installed with either package manager:

Terminal window
pip3 install python-dateutil==2.8
# or
conda install -c conda-forge python-dateutil=2.8

METplus is distributed as source from the dtcenter/metplus GitHub repository. Clone it over HTTPS or SSH, or download a release archive from the browser.

Terminal window
# HTTPS
git clone https://github.com/dtcenter/metplus
# SSH
git clone git@github.com:dtcenter/metplus

A bare clone leaves you on the moving development tip. For reproducible work, check out a tagged release after cloning — or clone the tag directly:

Terminal window
# move an existing clone onto a tagged release
cd metplus
git checkout v6.0.0
# or clone a single tagged release directly
git clone --branch v6.0.0 --depth 1 https://github.com/dtcenter/metplus

You can also download the source archive (.zip or .tar.gz) for the latest stable METplus release from its page on GitHub. Replace v6.0.0 with whichever tag you intend to use.

Sample input data is published separately in the METplus data repository. Download a dataset and point the INPUT_BASE configuration variable at it (covered below) so the example use cases have something to read.

Once cloned or unpacked, the METplus tree has a predictable shape. Two directories matter most when you are starting out: parm/ holds the configuration files, and ush/ holds the script you actually run.

DirectoryWhat lives there
ush/The run_metplus.py script that is executed to run use cases.
parm/All configuration files for MET and the METplus wrappers, including parm/use_cases/ and parm/metplus_config/.
metplus/The METplus Python package (the wrapper code itself).
docs/Documentation sources.
internal/Internal tooling and tests.
produtil/Supporting utility library.

For convenience you can put ush/ on your shell PATH so the command is callable from anywhere:

Terminal window
export PATH=/path/to/METplus/ush:$PATH

This is the concept that makes METplus flexible — and the one that confuses newcomers most. METplus does not read a single config file; it reads a stack of them and merges the results. When the same variable is defined more than once, the later definition wins. As the documentation puts it: “If a configuration variable is defined multiple times, each subsequent instance of that variable will override the previous value.”

The stack is processed in this order, from lowest to highest priority:

  1. Default configurationparm/metplus_config/defaults.conf loads first, automatically.
  2. Use case configuration files — the .conf files you name on the command line, in the order you list them.
  3. Your user configuration file — passed last among the files so its settings (paths for your machine) take precedence.
  4. Command-line single overrides — applied last of all, beating everything above.

A command-line override uses the form <SECTION>.<VARIABLE>=<VALUE>, for example:

config.OUTPUT_BASE=/data/output/my_data_dir

List values that contain spaces must be quoted:

config.LEAD_SEQ="6H, 12H"

Forecast leads accept several interchangeable forms: a plain list of hours (0, 6, 12), explicit units (6H, 12H, where the unit is assumed to be hours if omitted), or the begin_end_incr(start,end,step) shorthand — begin_end_incr(0,12,6) expands to 0, 6, 12. See the common config pattern for more.

After a run, METplus writes the fully-resolved settings to a file named metplus_final.conf (by default under OUTPUT_BASE, stamped with the run timestamp). When you are unsure what value a variable actually ended up with, read this file — it shows the result of the entire override stack.

METplus configuration override hierarchy feeding run_metplus.py Four stacked configuration layers — defaults, use case files, user config, and command-line overrides — flow in order of increasing priority into run_metplus.py, which writes a merged metplus_final.conf and produces output. A minimal directory layout is shown alongside. LOWEST PRIORITY 1 · defaults.conf loads automatically 2 · use case .conf files in listed order 3 · user / system config passed last among files 4 · command-line overrides config.VAR=value · win all HIGHEST PRIORITY run_metplus.py merges + runs wrappers metplus_ final.conf MET output + logs MINIMAL DIRECTORY LAYOUT METplus/ ush/ run_metplus.py lives here parm/ metplus_config/ · use_cases/ OUTPUT_BASE/ logs/ · metplus_final.conf where results and the merged config land
Figure 1. Four configuration layers merge in priority order — later wins — into run_metplus.py, which records the result in metplus_final.conf and writes MET output and logs under OUTPUT_BASE.

A handful of variables in the [config] section tell METplus where your MET install, inputs, and outputs live. The three marked required have placeholder defaults of /path/to that you must replace before anything runs. The rest derive sensible defaults from those, so you usually only set a few.

VariablePurposeDefault
MET_INSTALL_DIRLocation of the MET tools (required)/path/to
INPUT_BASERoot of the sample / input data (required)/path/to
OUTPUT_BASEWhere logs and output files are written (required)/path/to
MET_BIN_DIRMET executables directory{MET_INSTALL_DIR}/bin
TMP_DIRTemporary files{OUTPUT_BASE}/tmp
STAGING_DIRUncompressed / converted files{OUTPUT_BASE}/stage
LOG_DIRLog files{OUTPUT_BASE}/logs
CONFIG_DIRLocation of user configuration files

Two other configuration ideas are worth knowing early. The PROCESS_LIST variable defines which wrappers run, and in what order — and the same wrapper can appear more than once using an instance name in parentheses:

PROCESS_LIST = GridStat, GridStat(my_instance_name)

That instance then reads overrides from a matching [my_instance_name] section. Time looping is controlled with variables such as LOOP_BY (set to VALID, INIT, RETRO, or REALTIME), the range bounds VALID_BEG and VALID_END, the step VALID_INCREMENT, and the forecast-lead list LEAD_SEQ. You can also place environment variables for the MET tools in a [user_env_vars] section.

To launch a run, call run_metplus.py and list your configuration files as arguments. The documented example pairs a bundled use case file with a user/system config — and remember, the file you place last wins on any conflicting variable:

Terminal window
run_metplus.py \
/path/to/METplus/parm/use_cases/met_tool_wrapper/Example/Example.conf \
/path/to/user_system.conf

You can append command-line overrides after the files to tweak a single value without editing any config:

Terminal window
run_metplus.py \
/path/to/METplus/parm/use_cases/met_tool_wrapper/Example/Example.conf \
/path/to/user_system.conf \
config.OUTPUT_BASE=/data/output/my_data_dir

When the run completes successfully you will see the message “METplus has successfully finished running.” and find logs, MET output, and the resolved metplus_final.conf under your OUTPUT_BASE.

  1. Install the prerequisites. Confirm MET 12.2.0+ is installed, then a Python 3.12.0+ environment with python-dateutil==2.8. Add any wrapper-specific packages only when a use case needs them.
  2. Obtain METplus. git clone https://github.com/dtcenter/metplus, then git checkout a tagged release (or download that release’s archive) so the version is pinned to match your MET and sample-data versions. Optionally add ush/ to your PATH.
  3. Get sample data. Download a dataset from the METplus data repository and note its path — it becomes your INPUT_BASE.
  4. Write a user config. Create a small .conf with a [config] section setting MET_INSTALL_DIR, INPUT_BASE, and OUTPUT_BASE for your machine.
  5. Run a use case. Call run_metplus.py with a bundled use case file followed by your user config (and any config.VAR=value overrides last).
  6. Read the output. Check the “successfully finished running” message, inspect {OUTPUT_BASE}/logs, and open metplus_final.conf to confirm the resolved settings are what you expected.

A derived, human-readable re-presentation — not official documentation. Sources: getting_started · installation · systemconfiguration