Output Format
These pages are the complete schema reference for every file novomodelo run
writes: column names, Arrow types, nullability, units, JSON fields and the
binary checkpoint. This page holds the output directory tree, the success
markers and the Hive partition layout; each file’s schema is on its group
page.
If you are new to Novomodelo output, start with Convergence & Diagnostics. That page explains how to read results programmatically and assess convergence. The group pages are for readers who need the precise schema definition — for writing parsers, building dashboards, or implementing compatibility checks.
Files by page
Section titled “Files by page”The table lists each file novomodelo run can write, in the order of the directory
tree below, with the page that documents it.
Output Directory Tree
Section titled “Output Directory Tree”A complete novomodelo run produces the following directory structure. Not every
entity directory appears in every run: novomodelo run only writes directories for
entity types present in the case. For example, a case with no pumping stations
will not produce simulation/pumping_stations/.
<output_dir>/ training/ metadata.json convergence.parquet dictionaries/ codes.json entities.csv variables.csv bounds.parquet timing/ iterations.parquet solver/ iterations.parquet retry_histogram.parquet scaling_report.json hydro_models.json (always) model_provenance.json (always) cut_selection/ iterations.parquet (when cut_selection is enabled) _SUCCESS # after training/metadata.json policy/ # at policy.path (default ./policy), resolved against the output directory manifest.bin # study-global; FlatBuffers, written last cuts/ # pool-keyed 000.bin 001.bin ... NNN.bin basis/ # node-keyed 000.bin 001.bin ... NNN.bin states/ # stage-keyed; when exports.states = true 000.bin 001.bin ... NNN.bin simulation/ metadata.json paths.parquet scenario_summary.parquet costs/ scenario_id=0000/ data.parquet scenario_id=0001/ data.parquet ... hydros/ scenario_id=0000/data.parquet ... hydro_bus_generation/ scenario_id=0000/data.parquet ... thermals/ scenario_id=0000/data.parquet ... exchanges/ scenario_id=0000/data.parquet ... buses/ scenario_id=0000/data.parquet ... pumping_stations/ scenario_id=0000/data.parquet ... contracts/ scenario_id=0000/data.parquet ... non_controllables/ scenario_id=0000/data.parquet ... inflow_lags/ scenario_id=0000/data.parquet ... in_transit/ # when a travel-time arc is declared scenario_id=0000/data.parquet ... transit_seed/ # when a travel-time arc is declared scenario_id=0000/data.parquet ... anticipated_lanes/ # when the study declares post_study_stages scenario_id=0000/data.parquet ... violations/ generic/ scenario_id=0000/data.parquet ... solver/ iterations.parquet retry_histogram.parquet _SUCCESS # after simulation/metadata.json anticipated/ # when a pre-study-decided post-horizon commitment exists fixed_deliveries.parquet generic_constraints/ # when the study has generic constraints resolved_echo.parquet hydro_models/ fpha_hyperplanes.parquet (when a computed fit produces planes) evaporation_models.parquet (when any hydro has evaporation) fpha_deviation_points.parquet (when exports.fpha_deviation_points = true and a deviation point exists) stochastic/ # only when exports.stochastic = true (off by default) inflow_seasonal_stats.parquet (always, when exported) inflow_ar_coefficients.parquet (always, when exported) inflow_annual_component.parquet (always, when exported) correlation.json (always, when exported) fitting_report.json (when estimation ran) noise_openings.parquet (always, when exported) load_seasonal_stats.parquet (when a load model has std_mw > 0)Every Parquet output file is written with ZSTD compression (level 3), dictionary encoding and row groups of at most 100 000 rows.
Success markers
Section titled “Success markers”novomodelo run writes its files in a fixed order. training/_SUCCESS is an empty
file written last when training ran, and simulation/_SUCCESS one written last
when a simulation ran:
- Before training starts: when training will run, the stale
training/_SUCCESSand the conditional training files (training/cut_selection/,training/solver/files,anticipated/fixed_deliveries.parquet,hydro_models/*.parquet,generic_constraints/resolved_echo.parquet) are removed; when a simulation will run,simulation/_SUCCESSand every earlier simulation output (eachsimulation/<family>/tree,simulation/solver/files,paths.parquet,scenario_summary.parquetandmetadata.json) are removed; thentraining/hydro_models.json,training/model_provenance.json, thestochastic/exports (whenexports.stochastic = true) andtraining/scaling_report.jsonare written. - During training: periodic checkpoints under
policy.pathwhenpolicy.checkpointing.enabledistrue. - After training: the policy checkpoint under
policy.path(policy/by default;manifest.binlast inside it), thentraining/dictionaries/,training/convergence.parquet,training/timing/iterations.parquetandtraining/metadata.json, thenhydro_models/fpha_hyperplanes.parquet,hydro_models/evaporation_models.parquet,hydro_models/fpha_deviation_points.parquet,generic_constraints/resolved_echo.parquet,anticipated/fixed_deliveries.parquet,training/solver/iterations.parquet,training/solver/retry_histogram.parquetandtraining/cut_selection/iterations.parquet, each only when the run has content for it, thentraining/_SUCCESS. - During simulation: the entity partitions under
simulation/, as the scenarios run. - After simulation:
simulation/metadata.json,simulation/solver/iterations.parquet,simulation/solver/retry_histogram.parquet,simulation/paths.parquetandsimulation/scenario_summary.parquet, thensimulation/_SUCCESS.
A stochastic/ export is never removed, and a training-only run leaves an
earlier simulation/ tree, its _SUCCESS included.
A _SUCCESS marker therefore signals that its phase finished writing;
stochastic/ files are covered by neither marker. It is not a verdict on the
run: when training stops on a failure, novomodelo run writes the policy
checkpoint, every training output (convergence.termination_reason is
"error") and training/_SUCCESS, then exits with the code of the error (see
Exit Codes). A run that fails before a
phase’s last write leaves that phase without a marker.
The exit status of novomodelo run is the run-outcome signal. A scenario whose
output partitions could not be written does not change it: the scenario is
counted in scenarios.failed of simulation/metadata.json, and the run still
writes simulation/_SUCCESS and exits 0. A script that needs every scenario’s
output checks scenarios.failed.
Hive Partitioning
Section titled “Hive Partitioning”All simulation Parquet output uses Hive partitioning: results for each scenario
are stored in a directory named scenario_id=NNNN/ containing a single
data.parquet file. scenario_id is both the Hive partition directory
and an explicit non-null Int32 column inside every entity Parquet file
(the leading column of the shared (scenario_id, stage_id, node_id) axis —
see Node Axis and Policy-Graph Outputs).
A three-way join across entity files, or a join against
simulation/paths.parquet / simulation/scenario_summary.parquet, is
therefore a join on ordinary columns rather than a directory-name parse.
All major columnar data tools understand this layout and can read an entire
simulation/<entity>/ directory as a single table, either inferring
scenario_id from the partition directory names or reading it directly from
the in-file column — both agree by construction.
Reading recipes for Polars and pandas are in
Convergence & Diagnostics — Reading a whole table;
the R and DuckDB scenario filters are in
Filtering to a single scenario.
Scenario IDs are zero-based integers. The number of scenario_id=NNNN/
partitions written is scenarios.completed in simulation/metadata.json.