Skip to content

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.


The table lists each file novomodelo run can write, in the order of the directory tree below, with the page that documents it.

FilePage
training/metadata.jsonMetadata Files
training/convergence.parquetTraining Output
training/dictionaries/Training Output
training/dictionaries/codes.jsonTraining Output
training/dictionaries/entities.csvTraining Output
training/dictionaries/variables.csvTraining Output
training/dictionaries/bounds.parquetTraining Output
training/timing/iterations.parquetTraining Output
training/solver/iterations.parquetTraining Output
training/solver/retry_histogram.parquetTraining Output
training/scaling_report.jsonTraining Output
training/hydro_models.jsonHydro Model Artifacts
training/model_provenance.jsonMetadata Files
training/cut_selection/iterations.parquetTraining Output
training/_SUCCESSOutput Format
policy/manifest.binPolicy Checkpoint
policy/cuts/NNN.binPolicy Checkpoint
policy/basis/NNN.binPolicy Checkpoint
policy/states/NNN.binPolicy Checkpoint
simulation/metadata.jsonMetadata Files
simulation/paths.parquetSimulation Output
simulation/scenario_summary.parquetSimulation Output
simulation/costs/Simulation Output
simulation/hydros/Simulation Output
simulation/hydro_bus_generation/Simulation Output
simulation/thermals/Simulation Output
simulation/exchanges/Simulation Output
simulation/buses/Simulation Output
simulation/pumping_stations/Simulation Output
simulation/contracts/Simulation Output
simulation/non_controllables/Simulation Output
simulation/inflow_lags/Simulation Output
simulation/in_transit/Simulation Output
simulation/transit_seed/Simulation Output
simulation/anticipated_lanes/Simulation Output
simulation/violations/generic/Simulation Output
simulation/solver/iterations.parquetSimulation Output
simulation/solver/retry_histogram.parquetSimulation Output
simulation/_SUCCESSOutput Format
anticipated/fixed_deliveries.parquetSimulation Output
generic_constraints/resolved_echo.parquetSimulation Output
hydro_models/fpha_hyperplanes.parquetHydro Model Artifacts
hydro_models/evaporation_models.parquetHydro Model Artifacts
hydro_models/fpha_deviation_points.parquetHydro Model Artifacts
stochastic/inflow_seasonal_stats.parquetStochastic Artifacts
stochastic/inflow_ar_coefficients.parquetStochastic Artifacts
stochastic/inflow_annual_component.parquetStochastic Artifacts
stochastic/correlation.jsonStochastic Artifacts
stochastic/fitting_report.jsonStochastic Artifacts
stochastic/noise_openings.parquetStochastic Artifacts
stochastic/load_seasonal_stats.parquetStochastic Artifacts

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.


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:

  1. Before training starts: when training will run, the stale training/_SUCCESS and 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/_SUCCESS and every earlier simulation output (each simulation/<family>/ tree, simulation/solver/ files, paths.parquet, scenario_summary.parquet and metadata.json) are removed; then training/hydro_models.json, training/model_provenance.json, the stochastic/ exports (when exports.stochastic = true) and training/scaling_report.json are written.
  2. During training: periodic checkpoints under policy.path when policy.checkpointing.enabled is true.
  3. After training: the policy checkpoint under policy.path (policy/ by default; manifest.bin last inside it), then training/dictionaries/, training/convergence.parquet, training/timing/iterations.parquet and training/metadata.json, then hydro_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.parquet and training/cut_selection/iterations.parquet, each only when the run has content for it, then training/_SUCCESS.
  4. During simulation: the entity partitions under simulation/, as the scenarios run.
  5. After simulation: simulation/metadata.json, simulation/solver/iterations.parquet, simulation/solver/retry_histogram.parquet, simulation/paths.parquet and simulation/scenario_summary.parquet, then simulation/_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.


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.