Skip to content

METdbLoad

MET writes its verification results as plain-text ASCII files. That format is easy for MET to produce but awkward to query, filter, and plot at scale. METdbLoad is the loader that reads those files and inserts them into a MySQL-compatible database, so that aggregation and plotting tools — METviewer and METexpress — can pull statistics back out with a query instead of a file scan.

METdbLoad is a component of METdataio. Its job is narrow and important: take the ASCII output that the Model Evaluation Tools (MET) write to disk and insert it into a relational database — a structured store you query with SQL rather than read line by line.

The documentation describes it as a module that “provides support for inserting MET output data (as .stat files) into a relational database (mysql, mariadb, or aurora).” In other words, METdbLoad is the bridge between MET’s verification step and the analysis tools that consume verification results in bulk.

METdbLoad targets MySQL-compatible databases: MySQL, MariaDB, or Amazon Aurora. The target database must use the mv_ name prefix (for example mv_met_data) and must be built from the METviewer schema file mv_mysql.sql. That shared schema is what lets METviewer and METdbLoad agree on table shapes.

METdbLoad reads MET’s ASCII output. Only files with the .stat extension are loaded — “only data files with the .stat extension will be loaded.” Within those files MET packs many different line types, each a distinct row format carrying a particular family of statistics. Which families are ingested is controlled by load flags in the specification.

STAT line types — The general statistics output. A single .stat file interleaves many line types — continuous, categorical, ensemble, and more. Loading them is governed by the <load_stat> flag.

MPR — Matched Pairs — The individual forecast/observation pairs that the summary statistics are derived from. These are voluminous, so they have their own flag, <load_mpr>.

ORANK — Observation Rank — Ensemble rank information used for rank histograms and related ensemble diagnostics. Loaded via <load_orank>.

MODE — object output — Output from MET’s MODE (Method for Object-based Diagnostic Evaluation) tool, which identifies and compares spatial objects in forecast and observed fields. Loaded via <load_mode>.

MTD — MODE Time Domain — Output from MODE-TD, the space-time extension of MODE that tracks objects across time. Loaded via <load_mtd>.

These two levels work together: the <load_*> flags switch whole families on or off, and within the STAT family the individual line types can be restricted with a <line_type> block (more below); if that block is omitted, “all linetypes will be loaded.” A few names — notably MPR and ORANK — are used at both levels: they each have a dedicated load flag and name a STAT line type. Line-type names seen in the documentation’s own examples include CNT, ORANK, SEEPS_MPR, ME, ECNT, VL1L2, and SAL1L2.

A sampling of names that appear in the load documentation. Most are true line types; ME is a statistic within the CNT line type, shown here because it appears as a selectable filter value in the load examples. The full set of MET line types is defined by MET itself, not by METdbLoad.

Line typeFamilyRoughly what it carries
CNTContinuousContinuous-statistics summary (e.g. error and correlation measures)
MEContinuous (CNT statistic)Mean error — a statistic within the CNT line type, not a line type itself; appears in the docs as a selectable filter value
VL1L2Vector partial sumsVector wind partial-sum components
SAL1L2Scalar partial sumsScalar anomaly partial-sum components
ECNTEnsembleEnsemble continuous statistics
ORANKEnsembleObservation rank within the ensemble
SEEPS_MPRMatched pairSEEPS per-pair output

At a high level METdbLoad sits in the middle of a flow: MET writes ASCII files; an XML load specification tells the loader what to read and where to put it; the loader parses the files and inserts rows; downstream tools query the result.

METdbLoad load pipeline MET ASCII .stat output and an XML load specification feed the METdbLoad parser, which inserts rows into a header table and per-line-type data tables in a MySQL-compatible database, which is then queried by METviewer and METexpress. MET ASCII OUTPUT .stat — STAT / MPR / ORANK MODE objects MODE-TD (MTD) XML load spec files · DB · options METdbLoad met_db_load.py parse → insert mv_ DATABASE Header tables stat / mode / mtd _header line_data_cnt line_data_orank line_data_mpr · … data_file index METviewer METexpress
Figure 1. MET ASCII output and an XML load specification feed the METdbLoad parser, which writes header tables and per-line-type data tables into an mv_ database that METviewer and METexpress then query.

METdbLoad is driven entirely by a single XML load specification file. This one document answers three questions: which database to connect to, which files to read, and which options to apply. You pass its path to the loader and nothing else is required.

Conceptually the specification has three regions, and the elements must appear in the order the XML schema defines:

Connection

Where the rows go. The hostname and port, the database name, and the credentials used to connect.

What to load

Either a folder template with variable placeholders, or an explicit list of files — plus an optional line-type filter.

Options

Verbosity, batch size, which families to load, header-duplicate checks, index handling, and metadata to record with the load.

A worked example ships with the source tree at METdataio/METdbLoad/test/Examples/example_load_specification.xml — the recommended starting point for a new load.

In skeleton form, the three regions nest like this (illustrative values; see the example file for a complete, runnable specification):

<load_spec>
<connection>
<host>localhost:3306</host>
<database>mv_met_data</database>
<user>myuser</user>
<password>********</password>
</connection>
<load_stat>true</load_stat>
<load_mode>false</load_mode>
<verbose>false</verbose>
<insert_size>1</insert_size>
<folder_tmpl>/data/met_out/{config}/metprd</folder_tmpl>
<load_val>
<field name="config">
<val>gfs</val>
</field>
</load_val>
</load_spec>

The elements below are those the load documentation names. “Mandatory” / “optional” and the stated limits reflect the schema as described on the source page.

ElementRequiredPurpose
<host>yesDatabase hostname including port (3–67 characters)
<database>yesDatabase name, must use the mv_ prefix (3–124 characters)
<user>yesUsername (3–32 characters)
<password>yesPassword (3–30 characters)
<management_system>optionalEngine: mysql, mariadb, or aurora
<local_infile>optionalTrue/False — enable local-file loading
ElementRequiredControls
<verbose>yesTrue/False — verbose logging
<insert_size>yesPositive integer — rows per insert batch
<load_stat>optionalLoad STAT line types
<load_mode>optionalLoad MODE object output
<load_mtd>optionalLoad MODE-TD (MTD) output
<load_mpr>optionalLoad matched-pair (MPR) lines
<load_orank>optionalLoad observation-rank (ORANK) lines
<stat_header_db_check>optionalCheck for duplicate STAT headers in the DB
<mode_header_db_check>optionalCheck for duplicate MODE headers in the DB
<mtd_header_db_check>optionalCheck for duplicate MTD headers in the DB
<drop_indexes>optionalDrop indexes before loading (faster bulk insert)
<apply_indexes>optionalRe-apply indexes after loading
<force_dup_file>optionalForce loading of a file already recorded as loaded
ElementRequiredPurpose
<folder_tmpl>one ofPath template with {placeholder} variables
<load_files> / <file>one ofExplicit file list (max 200 entries)
<load_val> / <field>with templateDefines template variables (max 20 fields)
<val>within fieldStatic subdirectory value (max 100 per field)
<date_list>optionalDatetime range: start, end, inc, format (max 5)
<line_type> / <val>optionalRestrict to named line types (max 800; all loaded if omitted)
ElementRequiredPurpose
<group>optionalDatabase grouping label (1–300 characters)
<description>optionalDatabase description (1–300 characters)
<load_xml>optionalTrue/False — store the XML commands in the database
<load_note>optionalDescriptive note saved with the load (in instance_info)

Real verification output is rarely a flat directory. It is usually a deep tree organized by configuration, initialization time, ensemble member, valid time, and so on. The <folder_tmpl> mechanism lets you describe that tree once, with {placeholder} variables, and then enumerate the values each placeholder may take.

The documentation gives a template of this shape:

<folder_tmpl>/.../met_out/{config}/{fcst_init}/{mem}/{valid_times}/metprd/{met_out}/</folder_tmpl>

Each {variable} in the template needs a matching <field name="variable"> inside <load_val>. A field is filled in one of two ways:

  • With one or more <val> elements, for fixed subdirectory names (for example a set of configuration names or ensemble members).
  • With a <date_list name="..."/> reference, for date- or time-stamped directories generated from a start/end/inc range.

METdbLoad expands the template against every combination of field values, walks the resulting folders, and loads the .stat files it finds. The alternative — listing each file by hand under <load_files> — is fine for small or irregular sets, but the template is what scales to a large experiment.

The destination database is built from the METviewer schema file mv_mysql.sql. At a high level it follows a header + line-data design that mirrors how MET’s ASCII files are structured.

Header tables — Every MET output line begins with a block of header metadata — the descriptors that identify a result, such as the model, the initialization and valid times, the forecast lead, the level, the variable, and the verification region/mask. METdbLoad factors this shared metadata into header tables (the documentation names stat_header, mode_header, and mtd_header). Many data rows reference one header row, so the metadata is stored once and pointed to.

Per-line-type data tables — The numeric payload of each line type lives in its own table, keyed back to a header row. Because each MET line type has a different set of columns, each gets its own table — for example a continuous-statistics table, an observation-rank table, and a matched-pair table. This is why MPR and ORANK have dedicated load flags: they fan out into large, dedicated tables.

File-tracking and instance tables — The loader records which files have been ingested so that re-running a load does not duplicate data — this is what the <force_dup_file> flag overrides. Load-time metadata such as <load_note> is stored in the instance_info table.

The header-plus-line-data shape is what makes the database efficient to query: tools filter on the small, indexed header tables to find the rows of interest, then join out to the larger data tables only for the matches.

A load is run from the loader’s ush/ directory with the XML specification as the only required argument.

  1. Create the database. The target database must already exist, with insert, delete, update, and index privileges. Create it with, for example, mysql -u[user] -p[pass] -e'create database [db_name];' — using an mv_-prefixed name.

  2. Build the schema. Load the METviewer schema into the new database: mysql -u[user] -p[pass] [db_name] < sql/mv_mysql.sql. This creates the header, line-data, and supporting tables.

  3. Write the load specification. Copy example_load_specification.xml and edit the connection block, the <folder_tmpl> or <load_files> data location, the load flags for the families you want, and any metadata.

  4. Run the loader. From [install]/METdataio/METdbLoad/ush/ run python met_db_load.py /path-to/load_specification.xml. To keep a record, redirect output: python met_db_load.py spec.xml &> log/run.log &.

  5. Verify the result. Confirm rows landed by querying the database, or open it in METviewer/METexpress. For a re-load of already-recorded files, use <force_dup_file>; to (re)build only indexes, use the -index option.

Once loaded, the database is a queryable home for MET’s verification results. The two primary consumers are METviewer — the interactive plotting and aggregation web application — and METexpress, which offers guided, pre-built verification plots over the same schema. Both read directly from the tables METdbLoad populated, which is exactly why the database must conform to the shared mv_mysql.sql schema.


A derived, human-readable re-presentation — not official documentation. Sources: METdataio User’s Guide — Loading Data into a Database