Pular para o conteúdo

Output Format

Este conteúdo não está disponível em sua língua ainda.

This page is the complete schema reference for every file produced by cobre run. It documents column names, Arrow data types, nullability, JSON field structures, and binary format layouts for the Parquet schemas, the metadata files, the dictionary files, and the policy checkpoint format.

If you are new to Cobre output, start with Convergence & Diagnostics first. That page explains how to read results programmatically and assess convergence. This page is for readers who need the precise schema definition — for writing parsers, building dashboards, or implementing compatibility checks.


A complete cobre run produces the following directory structure. Not every entity directory appears in every run: cobre 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
mpi_ranks.parquet
solver/
iterations.parquet
retry_histogram.parquet
scaling_report.json
cut_selection/
iterations.parquet (when cut_selection is enabled)
policy/
manifest.bin # study-global; FlatBuffers, written last
cuts/ # pool-keyed
000.bin
001.bin
...
NNN.bin
basis/ # stage-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
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 any hydro uses source: "computed")
evaporation_models.parquet (when any hydro has evaporation)
fpha_deviation_points.parquet (when exports.fpha_deviation_points = true)
stochastic/
inflow_seasonal_stats.parquet (when estimation was performed)
inflow_ar_coefficients.parquet (when estimation was performed)
correlation.json (always)
fitting_report.json (when estimation was performed)
noise_openings.parquet (always)
load_seasonal_stats.parquet (when load buses exist)

The training metadata file is written atomically at the end of the training run. It merges run context, configuration, convergence outcome, row-pool statistics, objective bounds, LP solver statistics, and distribution information into a single file. Consumers should check status before interpreting other fields.

Example (from output/training/metadata.json after a run):

{
"cobre_version": "0.9.0",
"hostname": "<hostname>",
"solver": "highs",
"solver_version": "<solver version>",
"started_at": "<timestamp>",
"completed_at": "<timestamp>",
"duration_seconds": 0.15,
"status": "complete",
"configuration": {
"seed": null,
"max_iterations": 128,
"forward_passes": 1,
"stopping_mode": "any",
"policy_mode": "fresh"
},
"problem_dimensions": {
"num_stages": 4,
"num_hydros": 1,
"num_thermals": 2,
"num_buses": 1,
"num_lines": 0
},
"iterations": {
"completed": 128,
"converged_at": null
},
"convergence": {
"achieved": false,
"final_gap_percent": -2590.77,
"termination_reason": "iteration_limit"
},
"row_pool": {
"total_generated": 384,
"total_active": 384,
"peak_active": 384,
"cuts_active": 384,
"rows_in_lp_total": 0,
"rows_in_lp_solve_count": 0,
"rows_in_lp_max": 0
},
"bounds": {
"final_lower_bound": 15595518.38,
"final_upper_bound": 579592.2,
"final_upper_bound_std": 0.0
},
"solve_stats": {
"total_lp_solves": 5632,
"first_try": 5632,
"retried": 0,
"failed": 0,
"forward_solve_seconds": 0.016,
"backward_solve_seconds": 0.079,
"parallelism": 1
},
"distribution": {
"backend": "local",
"world_size": 1,
"ranks_participated": 1,
"num_nodes": 1,
"threads_per_rank": 1,
"hosts": [{ "hostname": "<hostname>", "ranks": [0] }]
}
}

Top-level fields:

FieldTypeNullableDescription
cobre_versionstringNoVersion of the cobre binary that produced this output (from CARGO_PKG_VERSION).
hostnamestringNoHostname of the machine that ran training.
solverstringNoLP solver backend: "highs" or "clp".
solver_versionstringYesVersion string of the linked LP solver library. Omitted when not available.
started_atstringNoISO 8601 timestamp when training started.
completed_atstringNoISO 8601 timestamp when training completed.
duration_secondsnumberNoTotal training wall-clock duration in seconds.
statusstringNoRun status: "complete" or "partial".

configuration fields:

FieldTypeNullableDescription
seedintegerYesRandom seed used for scenario generation. null when not set.
max_iterationsintegerYesMaximum iterations from the iteration-limit stopping rule. null when no limit was set.
forward_passesintegerYesNumber of forward-pass scenario trajectories per iteration.
stopping_modestringNoHow multiple stopping rules combine: "any" or "all".
policy_modestringNoPolicy warm-start mode: "fresh" or "resume".

problem_dimensions fields:

FieldTypeNullableDescription
num_stagesintegerNoNumber of stages in the planning horizon.
num_hydrosintegerNoTotal number of hydro plants.
num_thermalsintegerNoTotal number of thermal plants.
num_busesintegerNoTotal number of buses.
num_linesintegerNoTotal number of transmission lines.

iterations fields:

FieldTypeNullableDescription
completedintegerNoNumber of training iterations that finished.
converged_atintegerYesIteration at which a convergence stopping rule triggered termination. null for iteration-limit stops.

convergence fields:

FieldTypeNullableDescription
achievedbooleanNotrue if a convergence-oriented stopping rule terminated the run.
final_gap_percentnumberYesOptimality gap between lower and upper bounds at termination as a percentage. null when upper bound evaluation is disabled.
termination_reasonstringNoMachine-readable termination label. Common values: "iteration_limit", "bound_stalling".

row_pool fields:

FieldTypeNullableDescription
total_generatedintegerNoTotal cut rows generated over the entire run.
total_activeintegerNoCut rows still active in the pool at termination.
peak_activeintegerNoHighest number of simultaneously active cut rows observed.
cuts_activeintegerNoCut rows currently active in the LP at termination.
rows_in_lp_totalintegerNoSum of resident rows-in-LP over every lazy-selection solve in the run. Zero when no lazy selection ran.
rows_in_lp_solve_countintegerNoNumber of lazy-selection solves in the run. Zero when no lazy selection ran.
rows_in_lp_maxintegerNoLargest resident rows-in-LP over any single lazy-selection solve. Zero when no lazy selection ran.

bounds fields:

FieldTypeNullableDescription
final_lower_boundnumberNoFinal lower bound on the objective at termination.
final_upper_boundnumberYesFinal upper bound estimate. null when upper-bound evaluation is disabled.
final_upper_bound_stdnumberYesStandard deviation of the final upper-bound estimate. null when unavailable or the bound is exact.
final_upper_bound_kindstringNoUpper-bound regime: "exact" (enumerated forward pass) or "statistical" (sampled forward pass). Defaults to "statistical" when read from pre-exact-regime metadata.

solve_stats fields:

FieldTypeNullableDescription
total_lp_solvesintegerYesTotal number of LP solves performed during training.
first_tryintegerYesNumber of LP solves that succeeded on the first attempt.
retriedintegerYesNumber of LP solves that succeeded after one or more retries.
failedintegerYesNumber of LP solves that failed terminally.
forward_solve_secondsnumberYesCumulative wall-clock seconds in forward-phase LP solves.
backward_solve_secondsnumberYesCumulative wall-clock seconds in backward-phase LP solves.
parallelismintegerYesDegree of parallelism (worker count) used during training.

distribution fields:

FieldTypeNullableDescription
backendstringNoCommunication backend: "mpi" or "local".
world_sizeintegerNoTotal number of processes in the communicator. 1 for single-process runs.
ranks_participatedintegerNoNumber of processes that participated in computation.
num_nodesintegerNoNumber of distinct physical hosts.
threads_per_rankintegerNoRayon worker threads per process.
mpi_librarystringYesMPI implementation version (e.g. "Open MPI v4.1.6"). Omitted for the local backend.
mpi_standardstringYesMPI standard version (e.g. "MPI 4.0"). Omitted for the local backend.
thread_levelstringYesNegotiated MPI thread safety level. Omitted for the local backend.
slurm_job_idstringYesSLURM job ID when running under SLURM. Omitted otherwise.
hostsarrayNoPer-host rank assignment. One entry per physical host. For local single-process runs, contains a single entry with ranks: [0].
hosts[].hostnamestringNoHostname for this entry.
hosts[].ranksinteger arrayNoSorted global ranks assigned to this host.

setup fields (absent from legacy metadata produced before setup timing was collected):

FieldTypeNullableDescription
load_secondsnumberNoWall-clock seconds spent loading the input case.
stochastic_fit_secondsnumberNoWall-clock seconds spent fitting the stochastic process.
production_fit_secondsnumberNoWall-clock seconds spent fitting the production model (FPHA hyperplanes).
evaporation_fit_secondsnumberNoWall-clock seconds spent fitting the evaporation model.
broadcast_secondsnumberNoWall-clock seconds spent broadcasting setup data across MPI ranks.

These values are non-deterministic (informational only): they vary run-to-run with machine load and are excluded from any parity computation. The entire setup key is omitted from metadata produced before setup timing was introduced, and any field absent in such legacy metadata deserialises as 0.0.


Per-iteration convergence log. One row per training iteration. 15 columns.

ColumnTypeNullableDescription
iterationInt32NoTraining iteration number (1-based).
lower_boundFloat64NoBest proven lower bound on the minimum expected cost after this iteration.
upper_boundFloat64NoUpper bound estimate for this iteration: the mean over forward-pass scenarios under a statistical (sampled) forward pass, or the exact enumerated-weighted value under an exact forward pass.
upper_bound_stdFloat64YesStandard deviation of the upper bound estimate across forward-pass scenarios. null on an exact-bound row (upper_bound_kind = "exact"), which carries no sampling variance.
upper_bound_kindUtf8No"exact" when the enumerated weighted bound is in force for this iteration; "statistical" otherwise.
gap_percentFloat64YesRelative gap between lower and upper bounds as a percentage. null when the lower bound is zero or negative.
cuts_addedInt32NoNumber of new cuts added to the pool during this iteration’s backward pass.
cuts_removedInt32NoNumber of cuts deactivated by the cut selection strategy in this iteration.
cuts_activeInt64NoTotal number of active cuts across all stages at the end of this iteration.
time_forward_msInt64NoWall-clock time spent in the forward pass, in milliseconds.
time_backward_msInt64NoWall-clock time spent in the backward pass, in milliseconds.
time_total_msInt64NoTotal wall-clock time for this iteration, in milliseconds.
forward_passesInt32NoNumber of forward-pass scenario trajectories evaluated in this iteration.
lp_solvesInt64NoTotal number of LP solves across all stages and forward passes in this iteration.
mean_rows_in_lpFloat64NoMean number of active LP rows across all stage solves in this iteration.

Per-iteration wall-clock timing breakdown by phase. 19 columns. Emitted as one row per (iteration, rank) for rank-only sequential values (worker_id is NULL) and one row per (iteration, rank, worker_id) for per-worker parallel-region values; SUM(col) GROUP BY iteration recovers the per-iteration total for each timing column. rank and worker_id are nullable Int32; the 16 timing columns are non-nullable.

The top-level non-overlapping phases are: forward_wall_ms, backward_wall_ms, cut_selection_ms, mpi_allreduce_ms, and lower_bound_ms. The backward parallel overhead is decomposed into three components: bwd_setup_ms (aggregate non-solve work summed across workers), bwd_load_imbalance_ms (max-worker minus average-worker), and bwd_scheduling_overhead_ms (parallel wall minus max-worker). The forward pass carries the same three sub-components with fwd_ prefix. The backward phase also has the sub-components cut_sync_ms, state_exchange_ms, and cut_batch_build_ms. The residual not attributed to any phase is overhead_ms.

ColumnTypeNullableDescription
iterationInt32NoTraining iteration number (1-based).
rankInt32YesMPI rank that produced this row. NULL for rank-aggregated rows.
worker_idInt32YesRayon worker index within the rank’s pool. NULL for rank-only sequential rows.
forward_wall_msInt64NoWall-clock time for the forward pass (all stages and scenarios).
backward_wall_msInt64NoWall-clock time for the backward pass (all stages and trial points).
cut_selection_msInt64NoTime spent running the cut selection pipeline (all three stages).
mpi_allreduce_msInt64NoTime spent in MPI allreduce (forward-pass bound synchronization).
cut_sync_msInt64NoTime spent in per-stage cut sync allgatherv (sub-component of backward).
lower_bound_msInt64NoTime spent evaluating the lower bound (stage-0 LP solves for all openings).
state_exchange_msInt64NoTime spent in state exchange allgatherv (sub-component of backward).
cut_batch_build_msInt64NoTime spent assembling cut row batches (sub-component of backward).
bwd_setup_msInt64NoAggregate non-solve work (load_model + add_rows + set_bounds + basis_set) summed across backward workers, in ms. May exceed backward_wall_ms; it is a cost metric, not a wall-time slice.
bwd_load_imbalance_msInt64NoBackward load imbalance: max_worker_total - avg_worker_total, clamped to zero.
bwd_scheduling_overhead_msInt64NoBackward scheduling overhead: parallel_wall - max_worker_total, clamped to zero.
fwd_setup_msInt64NoAggregate non-solve work summed across forward workers, in ms. Same aggregate semantics as bwd_setup_ms.
fwd_load_imbalance_msInt64NoForward load imbalance: max_worker_total - avg_worker_total, clamped to zero.
fwd_scheduling_overhead_msInt64NoForward scheduling overhead: parallel_wall - max_worker_total, clamped to zero.
overhead_msInt64NoResidual wall-clock time not attributed to any of the above phases.
lazy_scoring_msInt64NoPer-worker time spent in lazy candidate scoring inside the lazy-selection solve. A sub-component of the forward/backward phases (not a top-level addend); 0 when the lazy path is unused.

Per-iteration, per-rank timing statistics for distributed runs. One row per (iteration, rank) pair. 8 columns. All columns are non-nullable.

ColumnTypeNullableDescription
iterationInt32NoTraining iteration number (1-based).
rankInt32NoMPI rank index (0-based).
forward_time_msInt64NoWall-clock time this rank spent in the forward pass.
backward_time_msInt64NoWall-clock time this rank spent in the backward pass.
communication_time_msInt64NoWall-clock time this rank spent in MPI communication.
idle_time_msInt64NoWall-clock time this rank was idle (waiting for other ranks).
lp_solvesInt64NoNumber of LP solves performed by this rank in this iteration.
scenarios_processedInt32NoNumber of scenario trajectories processed by this rank.

Per-iteration, per-phase, per-stage, per-opening, per-worker LP solver statistics for diagnosing conditioning issues and retry behavior. One row per (iteration, phase, stage_id, opening_index, rank, worker_id) tuple on the backward phase (per-opening, per-worker); one row per (iteration, phase, stage_id) tuple on the forward, lower_bound, and simulation phases. A training row fills iteration and leaves scenario_id NULL; a simulation row fills scenario_id and leaves iteration NULL. stage_id is NULL on lower_bound rows (no stage); opening_index, rank, and worker_id are NULL wherever the row has no per-opening/per-rank/per-worker dimension. 19 columns. iteration, scenario_id, stage_id, opening_index, rank, and worker_id are nullable Int32; all other columns are non-nullable.

ColumnTypeNullableDescription
iterationInt32YesTraining iteration (1-based). NULL on a simulation row (scenario_id is filled instead).
scenario_idInt32YesSimulation scenario id (0-based). NULL on a training row (iteration is filled instead).
phaseUtf8No"forward", "backward", "lower_bound", or "simulation".
stage_idInt32YesStage index (0-based). NULL on lower_bound rows.
opening_indexInt32YesOpening (noise realization) index within the stage for backward rows. NULL for forward, lower_bound, simulation.
rankInt32YesMPI rank that produced this row. NULL for rank-aggregated rows.
worker_idInt32YesRayon worker index within the rank’s pool. NULL for rows without a per-worker dimension.
lp_solvesUInt32NoNumber of LP solves in this row’s bucket.
lp_successesUInt32NoNumber of solves that returned optimal.
lp_retriesUInt32NoNumber of solves that required at least one retry.
lp_failuresUInt32NoNumber of solves that failed after exhausting all retry levels.
retry_attemptsUInt32NoTotal retry attempts across all LP solves in this bucket.
basis_offeredUInt32NoNumber of solve(Some(&basis)) calls (warm-start attempts).
basis_consistency_failuresUInt32NoNumber of warm-start calls in which the basis was rejected because isBasisConsistent returned false.
simplex_iterationsUInt64NoTotal simplex iterations (or IPM iterations) across all solves.
solve_time_msFloat64NoCumulative LP solve wall-clock time in milliseconds.
load_model_time_msFloat64NoCumulative time spent in load_model calls, in milliseconds.
set_bounds_time_msFloat64NoCumulative time spent in set_row_bounds / set_col_bounds calls, in milliseconds.
basis_set_time_msFloat64NoCumulative time spent installing bases for warm-start, in milliseconds.

Identical schema to training/solver/iterations.parquet. One row per (scenario_id, phase, stage_id) triple where phase == "simulation".

Per-level retry success counts, normalized from the solver iterations table. One row per (iteration, phase, stage_id, retry_level) tuple where the count is positive (sparse encoding). 5 columns. All non-nullable except stage_id.

ColumnTypeNullableDescription
iterationUInt32NoTraining iteration number (1-based).
phaseUtf8NoAlgorithm phase: "forward", "backward", or "lower_bound".
stage_idInt32YesStage index (0-based). NULL for the forward, lower_bound, and simulation rows that carry no per-stage attribution.
retry_levelUInt32NoRetry escalation level (0—11). See the Solver Safeguards section of the Performance Accelerators guide.
countUInt64NoNumber of LP solves recovered at this retry level.

LP prescaling diagnostics written once after stage template construction. Documents the coefficient ranges before and after column/row scaling for each stage, plus the applied scale-factor distributions. Useful for diagnosing numerical conditioning issues.

The JSON is a single top-level object:

{
"cost_scale_factor": 1000000.0,
"stages": [
{
"stage_id": 0,
"dimensions": { "num_cols": 128, "num_rows": 96, "num_nz": 412 },
"pre_scaling": {
"matrix_coeff_range": [0.001, 5000.0],
"matrix_coeff_ratio": 5000000.0,
"objective_range": [1.0, 250000.0],
"objective_ratio": 250000.0
},
"post_scaling": {
"matrix_coeff_range": [0.5, 4.2],
"matrix_coeff_ratio": 8.4,
"objective_range": [0.8, 3.1],
"objective_ratio": 3.875
},
"col_scale": { "min": 0.02, "max": 48.0, "median": 1.0, "count": 128 },
"row_scale": { "min": 0.1, "max": 12.0, "median": 1.0, "count": 96 }
}
],
"summary": {
"worst_pre_scaling_matrix_ratio": 5000000.0,
"worst_post_scaling_matrix_ratio": 8.4,
"improvement_factor": 595238.1,
"num_stages": 1
}
}

Top-level fields:

FieldTypeDescription
cost_scale_factornumberCost scale factor applied to objective coefficients during template build.
stagesarrayOne entry per stage. See “stages[] fields” below.
summaryobjectCross-stage summary. See “summary fields” below.

stages[] fields:

FieldTypeDescription
stage_idintegerStage index (0-based).
dimensionsobjectLP dimensions for this stage’s template. See “dimensions fields” below.
pre_scalingobjectCoefficient ranges before column/row scaling. See “pre_scaling / post_scaling fields” below.
post_scalingobjectCoefficient ranges after column/row (and cost) scaling. Same shape as pre_scaling.
col_scaleobjectSummary of the column scale-factor vector. See “col_scale / row_scale fields” below.
row_scaleobjectSummary of the row scale-factor vector. Same shape as col_scale.

dimensions fields:

FieldTypeDescription
num_colsintegerNumber of columns (decision variables).
num_rowsintegerNumber of structural rows (constraints).
num_nzintegerNumber of nonzero entries in the constraint matrix.

pre_scaling / post_scaling fields:

FieldTypeDescription
matrix_coeff_rangenumber array[min, max] absolute value over nonzero constraint-matrix entries.
matrix_coeff_rationumberRatio of the largest to smallest absolute nonzero matrix coefficient (max / min).
objective_rangenumber array[min, max] absolute value over nonzero objective coefficients.
objective_rationumberRatio of the largest to smallest absolute nonzero objective coefficient (max / min).

col_scale / row_scale fields:

FieldTypeDescription
minnumberMinimum scale factor.
maxnumberMaximum scale factor.
mediannumberMedian scale factor.
countintegerNumber of scale factors (num_cols for col_scale, num_rows for row_scale).

summary fields:

FieldTypeDescription
worst_pre_scaling_matrix_rationumberMaximum pre-scaling matrix coefficient ratio across all stages.
worst_post_scaling_matrix_rationumberMaximum post-scaling matrix coefficient ratio across all stages.
improvement_factornumberworst_pre_scaling_matrix_ratio / worst_post_scaling_matrix_ratio.
num_stagesintegerNumber of stages.

Per-stage cut selection statistics. One row per (iteration, stage_id) pair, written only at iterations where selection ran. 10 columns.

ColumnTypeNullableDescription
iterationInt32NoTraining iteration number (1-based).
stage_idInt32NoStage index (0-based).
cuts_populatedInt32NoTotal cut slots containing cuts (active + inactive).
cuts_active_beforeInt32NoActive cuts before this iteration’s selection pipeline.
cuts_deactivatedInt32NoCuts deactivated by the strategy-based selection (Stage 1).
cuts_reactivatedInt32NoCuts reactivated by the strategy-based selection (Stage 1).
cuts_active_afterInt32NoActive cuts after Stage 1 selection.
selection_time_msFloat64NoWall-clock time for the full selection pipeline.
budget_evictedInt32YesCuts evicted by budget enforcement (Stage 2). null when S2 is disabled.
active_after_budgetInt32YesActive cuts after budget enforcement (Stage 2). null when S2 is disabled.

Four self-documenting files that allow output Parquet files to be interpreted without reference to the original input case. All files are written atomically.

Static mapping from integer codes to human-readable labels for all categorical fields used in Parquet output. The same mapping applies for the lifetime of a release (the version field tracks breaking changes).

{
"version": "1.0",
"generated_at": "<timestamp>",
"operative_state": {
"0": "deactivated",
"1": "maintenance",
"2": "operating",
"3": "saturated"
},
"storage_binding": {
"0": "none",
"1": "below_minimum",
"2": "above_maximum",
"3": "both"
},
"contract_type": {
"0": "import",
"1": "export"
},
"entity_type": {
"0": "hydro",
"1": "thermal",
"2": "bus",
"3": "line",
"4": "pumping_station",
"5": "contract",
"7": "non_controllable",
"8": "hydro_unit_group"
},
"bound_type": {
"0": "storage_min",
"1": "storage_max",
"2": "turbined_min",
"3": "turbined_max",
"4": "outflow_min",
"5": "outflow_max",
"6": "generation_min",
"7": "generation_max",
"8": "flow_min",
"9": "flow_max"
}
}

One row per entity across all entity types, plus one row per hydro unit group (entity type code 8). Columns:

ColumnDescription
entity_type_codeInteger entity type code (see codes.json entity_type mapping).
entity_idInteger entity ID matching the *_id column in the corresponding simulation Parquet file. For a hydro unit group row, this is the group’s id, which is scoped to its plant, not global.
nameHuman-readable entity name from the case input files. A hydro unit group row’s name is "{hydro_id}/{group_name}", plant-qualified since the group id alone is not globally unique.
bus_idInteger bus ID to which this entity is connected. For buses, equals entity_id. -1 for a line (connects two buses) and for a hydro (the plant’s unit groups own the bus association; a split plant has no single owning bus) — a hydro unit group row carries that group’s own bus_id instead.
system_idSystem partition index. Always 0 in the current release (single-system cases).

Rows are ordered by entity_type_code ascending, then by entity_id ascending within each type — except type code 8: a group’s entity_id is plant-scoped, so those rows order plant-major (canonical hydro order), then group-minor (each plant’s own id-sorted unit_groups order).

One row per output column across all Parquet schemas. Documents every column name, its parent schema, and its unit of measure. Useful for building generic result readers that do not hard-code column names.

ColumnDescription
schemaName of the Parquet schema this column belongs to (e.g. "hydros", "costs").
column_nameExact column name as it appears in the Parquet file.
arrow_typeArrow data type string (e.g. "Int32", "Float64", "Boolean").
nullable"true" or "false".
unitPhysical unit or "code" for categorical fields, "boolean" for flag fields, "id" for identifiers, "dimensionless" for pure ratios.
descriptionShort description of the column’s meaning.

Per-entity, per-stage resolved LP variable bounds. Documents the actual numerical bounds used in each LP solve, after applying the three-tier penalty resolution (global / entity / stage overrides).

ColumnTypeNullableDescription
entity_type_codeInt8NoEntity type code (see codes.json).
entity_idInt32NoEntity ID.
stage_idInt32NoStage index (0-based).
bound_type_codeInt8NoBound type code (see codes.json bound_type mapping).
lower_boundFloat64NoResolved lower bound value in the bound’s natural unit.
upper_boundFloat64NoResolved upper bound value in the bound’s natural unit.

FlatBuffers binary file encoding all cuts for a single pool. Pool-keyed: one file per pool (cuts/<pool_id>.bin), zero-padded to three digits (e.g. 000.bin, 012.bin); a pool shared by several leaf nodes appears once. On a plain stage chain, pool id equals stage index, so file names look the same as before — the general node -> pool mapping (for a branching policy graph) is resolved through the graph_manifest in policy/manifest.bin, never trusted from the file name.

Each cuts/<pool>.bin is self-describing: alongside its cuts it carries its own state_dimension, its own cost_scale_factor (the authoritative load-time scale for this pool — see Cost-Scale Canonicalization), and its own graph identity (node and graph-stage ids), so no field of the study-global manifest is needed to interpret a pool’s coefficients.

The binary is not human-readable. The logical record structure for each cut contained in the file is:

FieldTypeDescription
cut_iduint64Unique identifier for this cut across all iterations. Assigned monotonically by the training loop.
slot_indexuint32LP row position. Required for checkpoint reproducibility and basis warm-starting.
iterationuint32Training iteration that generated this cut.
forward_pass_indexuint32Forward pass index within the generating iteration.
interceptfloat64Pre-computed cut intercept: alpha - beta' * x_hat, where x_hat is the state at the generating forward pass node.
coefficientsfloat64[]Gradient coefficient vector. Length equals the state dimension — the number of entries in the embedded entity manifest below, also the pool’s own state_dimension (per-pool, not a policy/manifest.bin field).
is_activeboolWhether this cut is currently active in the LP. Inactive cuts are retained for potential reactivation by the cut selection strategy.

Each NNN.bin also embeds a per-slot entity manifest — one entry per state-vector dimension, in canonical cut-coefficient order — recording which entity each coefficient position belongs to. It is the self-describing replacement for the former state_dictionary.json sidecar, and it is what policy-load validation checks (see policy management): a policy whose dimensions match the current study by count but bind to different entities is rejected.

Manifest fieldTypeDescription
entity_typeuint8State-dimension kind: 0 HydroStorage, 1 HydroInflowLag, 2 AnticipatedThermalState, 3 HydroTransitBucket.
entity_idint32Owning entity id — for a transit bucket, the downstream hydro.
subindexuint32Secondary index within the entity: the inflow-lag order, anticipated-commitment ring slot, or transit maturity lag.
was_activeboolWhether the owning entity was operationally active at this stage (excluded from the load-time identity check).
delivery_dateint32Canonical absolute delivery/arrival calendar date for delivery-timed dimensions, encoded YYYYMMDD (year*10000 + month*100 + day); sentinel i32::MIN when the slot has no delivery semantics.

The encoding uses the FlatBuffers runtime builder API (little-endian, no reflection, no generated code). Field order in the binary matches the declaration order above.

Policy checkpoints written by an earlier release are rejected outright: the format_version marker in policy/manifest.bin is read before any payload is decoded, and a checkpoint with no manifest.bin (every pre-0.15 checkpoint, whose study-global metadata lived in a now-removed policy/metadata.json) fails with a named error rather than being read positionally. There is no converter — retrain from scratch, re-export, or resume from a checkpoint written by this release.

FlatBuffers binary file encoding the LP simplex basis checkpoint for a single stage. Stage-keyed: one file per stage (basis/<stage_id>.bin), zero-padded to three digits. Used to warm-start LP solves when resuming a study.

The logical record structure is:

FieldTypeDescription
stage_iduint32Stage index (0-based).
iterationuint32Training iteration that produced this basis.
column_statusuint8[]One status code per LP column (variable). Encoding is HiGHS-specific.
row_statusuint8[]One status code per LP row (constraint). Encoding is HiGHS-specific.
num_cut_rowsuint32Number of trailing rows in row_status that correspond to cut rows (as opposed to structural constraints).

FlatBuffers binary file encoding the visited forward-pass trial points for a single stage. Stage-keyed: one file per stage (states/<stage_id>.bin), zero-padded to three digits. Present only when exports.states is true (default is false). The states/ directory is omitted entirely when disabled. Like the cut files, each NNN.bin embeds the per-slot entity manifest describing its state dimensions.

Trial points are the state vectors observed at each forward-pass scenario during training. They are always collected in memory regardless of the cut selection method, but persisted to disk only when this export flag is set. Dominated cut selection uses these states at pruning time; for other methods they serve as a diagnostic and analysis artifact.

FieldTypeDescription
stage_iduint32Stage index (0-based).
node_idint32Policy-graph node identity — the declared node id on a branching graph. Sentinel -1 when absent (a caller that never resolved one, or a pre-id:5 checkpoint). Distinct from stage_id the moment a graph carries more than one node per stage.
state_dimensionuint32Length of each state vector; equals the writing pool’s own state_dimension (per-pool, not a policy/manifest.bin field).
countuint32Number of state vectors stored for this stage.
datafloat64[]Flat array of count * state_dimension elements, row-major (one state per row).

The study-global checkpoint manifest: a FlatBuffers root (the CheckpointManifest table, file_identifier "CBVF") describing the checkpoint at a high level, written last as the commit signal and read first behind the format_version gate. It replaces the hand-editable policy/metadata.json of earlier releases; every study-global fact a load needs — the study graph, the stage count, and the producer provenance — lives here. Structured around a neutral core (format/provenance/graph descriptors) plus a namespaced producer block for the training algorithm’s own recorded state, so a reader that does not know the producer can still read the core from the core’s own vocabulary. The Python bindings read and write it as a dict of the shape below (see load_policy); the field names are the dict keys.

Top-level fields:

FieldTypeNullableDescription
format_versionintegerNoOn-disk format version; must equal 1 on read. A checkpoint from an earlier release has no manifest.bin at all and is rejected at the first read, before any payload is parsed.
cobre_versionstringNoVersion of the cobre binary that wrote this checkpoint.
created_atstringNoISO 8601 timestamp when the checkpoint was written.
num_stagesintegerNoNumber of stages the graph manifest spans. Must match the case configuration on resume.
graph_manifestobjectNoGraph manifest: node list, edge list, node -> pool map, and pool-set size. Defaults to empty on a plain stage chain.
producerobjectNoProducer-namespaced metadata — the training algorithm’s own recorded state. See below.

graph_manifest fields:

FieldTypeNullableDescription
n_poolsintegerNoNumber of distinct pools (the pool-set size).
nodes[]arrayNoEvery node, in canonical order, each with its stage and pool. See nodes[] fields below.
edges[]arrayNoEvery directed edge with its transition probability. See edges[] fields below.

nodes[] fields (one entry per policy-graph node):

FieldTypeNullableDescription
idintegerNoDeclared node id.
stage_idintegerNoStage id this node sits at.
pool_idintegerNoPool whose payload holds this node’s affine pieces (the node -> pool map: leaf nodes sharing a pool all name the same pool_id).

edges[] fields (one entry per directed policy-graph edge):

FieldTypeNullableDescription
source_idintegerNoSource node id.
target_idintegerNoTarget node id.
probabilitynumberNoTransition probability P(source -> target).

producer fields:

FieldTypeNullableDescription
completed_iterationsintegerNoNumber of training iterations completed at checkpoint time.
final_lower_boundnumberNoLower bound value after the final completed iteration.
best_upper_boundnumberYesThe final completed iteration’s upper bound, if available — the last value, not a min-tracked/observed best. null when upper bound evaluation was disabled.
max_iterationsintegerNoMaximum iterations configured for the run.
forward_passesintegerNoNumber of forward passes per iteration configured for the run.
warm_start_cutsintegerNoNumber of cuts loaded from a previous policy at run start. 0 for fresh runs.
warm_start_counts[]integer[]NoPer-pool warm-start cut counts, in pool-id order. Empty in old checkpoints; supersedes warm_start_cuts for per-pool accuracy when non-empty.
rng_seedintegerNoRNG seed used by the scenario sampler. Required for reproducibility.
total_visited_statesintegerNoTotal number of visited state vectors across all nodes. 0 when exports.states is off.
training_block_modestringNoBlock mode the artifact was trained under: the shared lowercase mode ("parallel"/"chronological") when every stage agrees, else "mixed".
training_block_mode_per_stage[]string[]NoPer-study-stage training block modes, in study-stage order. Empty when uniform; populated only for mixed-mode studies.
cost_scale_factornumberYesObjective cost-scale factor the writing study resolved (modeling.cost_scale_factor), recorded here as study-global provenance. The authoritative load-time value is carried per pool in each cuts/<pool>.bin (see the cuts payload above), which marks that pool’s cut coefficients/intercepts as canonical currency units; every load path requires it, and a resolved pool missing it is rejected (“predates self-describing cuts … re-export”). See Cost-Scale Canonicalization for the details.

All simulation results use Hive partitioning: one data.parquet file per scenario stored in a scenario_id=NNNN/ subdirectory. See Hive Partitioning below for how to read these files.

The simulation metadata file is written atomically when simulation completes. It captures run context, scenario completion counts, aggregate cost statistics, LP solver statistics, and distribution information.

Example (from output/simulation/metadata.json after a run):

{
"cobre_version": "0.9.0",
"hostname": "<hostname>",
"solver": "highs",
"started_at": "<timestamp>",
"completed_at": "<timestamp>",
"duration_seconds": 0.103,
"status": "complete",
"scenarios": {
"total": 100,
"completed": 100,
"failed": 0
},
"cost": {
"mean_cost": 14532064.35,
"std_cost": 35658862.19
},
"solve_stats": {
"total_lp_solves": 400,
"first_try": 400,
"retried": 0,
"failed": 0,
"solve_seconds": 0.017,
"parallelism": 1
},
"distribution": {
"backend": "local",
"world_size": 1,
"ranks_participated": 1,
"num_nodes": 1,
"threads_per_rank": 1,
"hosts": [{ "hostname": "<hostname>", "ranks": [0] }]
}
}

Top-level fields:

FieldTypeNullableDescription
cobre_versionstringNoVersion of the cobre binary that produced this output.
hostnamestringNoHostname of the machine that ran simulation.
solverstringNoLP solver backend: "highs" or "clp".
solver_versionstringYesLP solver library version string. Omitted when not available.
started_atstringNoISO 8601 timestamp when simulation started.
completed_atstringNoISO 8601 timestamp when simulation completed.
duration_secondsnumberNoTotal simulation wall-clock duration in seconds.
statusstringNoRun status: "complete" or "partial".

scenarios fields:

FieldTypeNullableDescription
totalintegerNoTotal number of scenarios dispatched for simulation.
completedintegerNoNumber of scenarios that completed without error.
failedintegerNoNumber of scenarios that encountered a terminal error.

cost fields (omitted when cost was not persisted):

FieldTypeNullableDescription
mean_costnumberNoMean total cost across simulated scenarios.
std_costnumberNoStandard deviation of the total cost across simulated scenarios.

solve_stats fields:

FieldTypeNullableDescription
total_lp_solvesintegerYesTotal number of LP solves performed during simulation.
first_tryintegerYesNumber of LP solves that succeeded on the first attempt.
retriedintegerYesNumber of LP solves that succeeded after one or more retries.
failedintegerYesNumber of LP solves that failed terminally.
solve_secondsnumberYesCumulative wall-clock seconds spent in simulation LP solves.
parallelismintegerYesDegree of parallelism (worker count) used during simulation.

The distribution object has the same field structure as in training/metadata.json. See the distribution fields table above.


Every simulation/ entity partition below shares a leading (scenario_id, stage_id, node_id) axis: scenario_id and stage_id are the familiar scenario and stage indices, and node_id is the visited policy-graph node’s declared id for that (scenario_id, stage_id) pair. On a plain stage chain (the default, single-node-per-stage graph) node_id always equals stage_id — there is nothing else to distinguish. On a branching policy graph with more than one node per stage, node_id identifies which branch a scenario actually visited at that stage, and joins back to the node’s stage_id/pool_id via the policy checkpoint’s graph_manifest (see policy/manifest.bin). scenario_id duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column, so a join on the axis is a join rather than a directory-name parse (see Hive Partitioning).

Two run-level, unpartitioned files complete this axis:

The per-scenario node-path trace: exactly the (scenario_id, stage_id, node_id) axis prefix, one row per stage visited by each scenario. 3 columns, all non-null. Joins to any entity file on (scenario_id, stage_id).

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based).
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.

Run-level, per-scenario summary: one row per scenario. 3 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based).
probabilityFloat64YesPer-scenario leaf-path weight under a declared census. null under sampled scenario selection.
discounted_immediate_costFloat64NoTotal discounted immediate cost for this scenario, summed across its visited path.

Stage and block-level cost breakdown. One row per (stage, block) pair. 29 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index within the stage. null for stage-level (non-block) records.
total_costFloat64NoTotal discounted cost for this stage/block (monetary units).
immediate_costFloat64NoImmediate (undiscounted) cost for this stage/block.
future_costFloat64NoFuture cost estimate (Benders cut value) at the end of this stage.
discount_factorFloat64NoDiscount factor applied to this stage’s costs.
thermal_costFloat64NoThermal generation cost component.
anticipated_thermal_costFloat64NoAnticipated (forward-committed) thermal generation cost, booked at the decision stage. Zero when no anticipated units exist.
contract_costFloat64NoEnergy contract cost component (positive for imports, negative for exports).
deficit_costFloat64NoCost of unserved load (deficit penalty).
excess_costFloat64NoCost of excess generation (excess penalty).
storage_violation_costFloat64NoCost of reservoir storage bound violations.
filling_target_costFloat64NoCost of missing reservoir filling targets.
hydro_violation_costFloat64NoCost of hydro operational bound violations.
outflow_violation_below_costFloat64NoCost of total outflow below-minimum violations.
outflow_violation_above_costFloat64NoCost of total outflow above-maximum violations.
turbined_violation_costFloat64NoCost of turbined flow bound violations.
generation_violation_costFloat64NoCost of generation bound violations.
evaporation_violation_costFloat64NoCost of evaporation violations.
withdrawal_violation_costFloat64NoCost of water withdrawal violations.
inflow_penalty_costFloat64NoCost of inflow non-negativity slack (numerical penalty).
generic_violation_costFloat64NoCost of generic constraint violations.
spillage_costFloat64NoCost of reservoir spillage.
turbined_costFloat64NoTurbined flow penalty from the future-production hydro approximation.
curtailment_costFloat64NoCost of non-controllable source curtailment.
exchange_costFloat64NoTransmission exchange cost component.
pumping_costFloat64NoPumping station energy cost component.

Hydro plant dispatch results. One row per (stage, block, hydro) triplet. 37 columns.

See the Energy Variables guide for an explanation of the five energy columns (equivalent_productivity_mw_per_m3s through stored_energy_final_mwh).

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
hydro_idInt32NoHydro plant ID.
turbined_m3sFloat64NoTurbined flow in cubic metres per second (m³/s).
spillage_m3sFloat64NoSpilled flow in m³/s.
outflow_m3sFloat64NoTotal outflow (turbined + spilled) in m³/s.
evaporation_m3sFloat64YesNet evaporation flow in m³/s; signed. Positive values are net evaporative loss; negative values are net rainfall input on the lake surface. null if evaporation is not modelled for this plant.
diverted_inflow_m3sFloat64YesDiverted inflow to this reservoir in m³/s. null if no diversion is configured.
diverted_outflow_m3sFloat64YesDiverted outflow from this reservoir in m³/s. null if no diversion is configured.
incremental_inflow_m3sFloat64NoNatural incremental inflow to this reservoir in m³/s (excluding upstream contributions).
inflow_m3sFloat64NoTotal inflow to this reservoir in m³/s (including upstream contributions).
storage_initial_hm3Float64NoReservoir storage at the start of the stage in hectare-metres cubed (hm³).
storage_final_hm3Float64NoReservoir storage at the end of the stage in hm³.
generation_mwFloat64NoAverage power generation over the block in megawatts (MW).
generation_mwhFloat64NoTotal energy generated over the block in megawatt-hours (MWh).
equivalent_productivity_mw_per_m3sFloat64NoEquivalent productivity ρ_eq [MW/(m³/s)] at the reference operating point for this stage.
accumulated_productivity_mw_per_m3sFloat64NoAccumulated cascade productivity ρ_acum [MW/(m³/s)]: sum of ρ_eq for this plant and all downstream plants.
incremental_inflow_energy_mwFloat64NoPower equivalent of incremental inflow: ρ_acum × incremental_inflow_m3s [MW].
stored_energy_initial_mwhFloat64NoEnergy content of usable storage at stage start: (storage_initial_hm3 − V_min) × ρ_acum × 1e6/3600 [MWh].
stored_energy_final_mwhFloat64NoEnergy content of usable storage at stage end: (storage_final_hm3 − V_min) × ρ_acum × 1e6/3600 [MWh].
spillage_costFloat64NoMonetary cost attributed to spillage.
water_value_per_hm3Float64NoShadow price of the reservoir water balance constraint (monetary units per hm³).
storage_binding_codeInt8NoWhether the storage bounds were binding (see codes.json storage_binding mapping).
operative_state_codeInt8NoOperative state code (see codes.json operative_state mapping).
turbined_slack_m3sFloat64NoTurbined flow slack variable (non-negativity enforcement). Zero under normal operation.
outflow_slack_below_m3sFloat64NoOutflow lower-bound slack in m³/s.
outflow_slack_above_m3sFloat64NoOutflow upper-bound slack in m³/s.
generation_slack_mwFloat64NoGeneration bound slack in MW.
storage_violation_below_hm3Float64NoReservoir storage below-minimum violation in hm³. Zero under feasible operation.
filling_target_violation_hm3Float64NoFilling target miss in hm³. Zero when the target is met.
evaporation_violation_pos_m3sFloat64NoSlack absorbing a positive deviation of the signed evaporation flow from the linearised target in m³/s (solver chose a less-negative net flux than the model predicts). Zero under normal operation.
evaporation_violation_neg_m3sFloat64NoSlack absorbing a negative deviation of the signed evaporation flow from the linearised target in m³/s (solver chose a less-positive net flux than the model predicts). Zero under normal operation.
inflow_nonnegativity_slack_m3sFloat64NoInflow non-negativity slack in m³/s. Zero under normal operation.
water_withdrawal_violation_pos_m3sFloat64NoWater withdrawal over-target violation in m³/s. Zero when withdrawal is at or below target.
water_withdrawal_violation_neg_m3sFloat64NoWater withdrawal under-target violation in m³/s. Zero when withdrawal is at or above target.

Hydro dispatch results at (hydro, bus) cell granularity — one cell per distinct bus among a plant’s unit groups (see hydros[].unit_groups[] in the Case Directory Format reference). One row per (stage, block, hydro, bus) quadruplet. 9 columns.

simulation/hydros/ above is unchanged and continues to report each plant’s total: a plant split across several unit groups sharing one bus has no per-group quantity to report, since every split of that shared cell’s flow across its same-bus groups is an equally optimal solution with no dual to distinguish them. This partition reports at the bus-cell granularity the LP itself solves.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
hydro_idInt32NoHydro plant ID.
bus_idInt32NoBus ID for this cell. Always non-null.
turbined_m3sFloat64NoTurbined flow for this cell in m³/s.
generation_mwFloat64NoAverage power generation for this cell over the block in MW.
generation_mwhFloat64NoTotal energy generated by this cell over the block in MWh (generation_mw × block_duration_hours).

A plant’s cell rows sum bit-exactly to its simulation/hydros/ row for turbined_m3s, on every production model. For generation_mw/generation_mwh the cell rows sum bit-exactly only for FPHA and single-cell plants. On a constant-productivity (ConstantProductivity/LinearizedHead) model a multi-cell plant’s total is (Σ_c q_c)·ρ — its cells’ turbined flow summed, then multiplied by the productivity once — while each cell row is q_c·ρ computed independently. The two are equal in exact arithmetic but, because floating-point multiplication does not distribute over addition bit-for-bit, the sum of a plant’s cell rows can differ from its plant total by a rounding-scale amount.


Thermal unit dispatch results. One row per (stage, block, thermal) triplet. 12 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
thermal_idInt32NoThermal unit ID.
generation_mwFloat64NoAverage power generation over the block in MW.
generation_mwhFloat64NoTotal energy generated over the block in MWh.
generation_costFloat64NoMonetary generation cost for this block.
is_anticipatedBooleanNotrue if this unit is configured for anticipated dispatch.
anticipated_committed_mwFloat64YesCommitted capacity under anticipated dispatch in MW. null for non-anticipated units.
anticipated_decision_mwFloat64YesDispatch decision under anticipated dispatch in MW. null for non-anticipated units.
operative_state_codeInt8NoOperative state code (see codes.json operative_state mapping).

Transmission line flow results. One row per (stage, block, line) triplet. 13 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
line_idInt32NoTransmission line ID.
direct_flow_mwFloat64NoFlow in the forward (direct) direction in MW.
reverse_flow_mwFloat64NoFlow in the reverse direction in MW.
net_flow_mwFloat64NoNet flow (direct minus reverse) in MW.
net_flow_mwhFloat64NoNet energy flow over the block in MWh.
losses_mwFloat64NoTransmission losses in MW.
losses_mwhFloat64NoTransmission losses in MWh over the block.
exchange_costFloat64NoMonetary cost attributed to this line’s exchange.
operative_state_codeInt8NoOperative state code (see codes.json operative_state mapping).

Bus load balance results. One row per (stage, block, bus) triplet. 12 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
bus_idInt32NoBus ID.
load_mwFloat64NoTotal load demand at this bus in MW.
load_mwhFloat64NoTotal load energy demand over the block in MWh.
deficit_mwFloat64NoUnserved load (deficit) at this bus in MW. Zero under feasible dispatch.
deficit_mwhFloat64NoUnserved load energy over the block in MWh.
excess_mwFloat64NoExcess generation at this bus in MW. Zero under feasible dispatch.
excess_mwhFloat64NoExcess generation energy over the block in MWh.
spot_priceFloat64NoLocational marginal price (shadow price of the power balance constraint) in monetary units per MWh.

Pumping station results. One row per (stage, block, pumping station) triplet. 11 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
pumping_station_idInt32NoPumping station ID.
pumped_flow_m3sFloat64NoPumped flow rate in m³/s.
pumped_volume_hm3Float64NoTotal pumped volume over the stage in hm³.
power_consumption_mwFloat64NoPower consumed by the pumping station in MW.
energy_consumption_mwhFloat64NoEnergy consumed over the block in MWh.
pumping_costFloat64NoMonetary cost of pumping energy.
operative_state_codeInt8NoOperative state code (see codes.json operative_state mapping).

Energy contract results. One row per (stage, block, contract) triplet. 10 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
contract_idInt32NoContract ID.
power_mwFloat64NoContracted power in MW, non-negative for both import and export contracts. Direction is carried by the contract type and the price sign, not by the sign of this value.
energy_mwhFloat64NoContracted energy over the block in MWh.
price_per_mwhFloat64NoContract price in monetary units per MWh.
total_costFloat64NoTotal contract cost for this block: positive for imports (cost), negative for exports (revenue).
operative_state_codeInt8NoOperative state code (see codes.json operative_state mapping); always 1 for contracts (a dormant stage emits a zero-power_mw row, not a distinct code).

Non-controllable source results (wind, solar, run-of-river hydro without storage, etc.). One row per (stage, block, non-controllable) triplet. 12 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level records.
non_controllable_idInt32NoNon-controllable source ID.
generation_mwFloat64NoActual generation dispatched in MW.
generation_mwhFloat64NoActual energy generated over the block in MWh.
available_mwFloat64NoMaximum available generation in MW (before curtailment).
curtailment_mwFloat64NoGeneration curtailed in MW. Zero when all available generation is dispatched.
curtailment_mwhFloat64NoCurtailed energy over the block in MWh.
curtailment_costFloat64NoMonetary cost attributed to curtailment.
operative_state_codeInt8NoOperative state code (see codes.json operative_state mapping).

Autoregressive inflow lag state variables. One row per (stage, hydro, lag) triplet. No block dimension — inflow lags are stage-level state variables. 6 columns. All columns are non-nullable.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
hydro_idInt32NoHydro plant ID.
lag_indexInt32NoAutoregressive lag order (1-based). Lag 1 is the previous stage’s inflow.
inflow_m3sFloat64NoInflow value for this lag in m³/s.

Water travel-time in-transit volumes. One row per (stage, downstream hydro, maturity lag) triplet. No block dimension — in-transit buckets are stage-level state variables. 7 columns. All columns are non-nullable. The directory is present only when the system declares a travel-time arc (travel_time_hours present, strictly positive, with a downstream_id); byte-neutral otherwise.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
hydro_idInt32NoDownstream (receiving) hydro plant ID the in-transit water is destined for.
lagInt32NoMaturity lag (1-based). Lag 1 matures into the receiving plant’s reservoir at this stage; deeper lags arrive later.
in_transit_volume_hm3Float64NoIn-transit water volume carried at this (stage, plant, lag) bucket in hm³.
delayed_arrival_hm3Float64NoVolume delivered into the receiving plant’s water balance at this stage in hm³; non-zero only at lag = 1.

Rolling release-window seed recording each in-transit bucket’s own upstream release history, for seeding a continuing (resumed) run’s transit buckets across the boundary. Scenario-level — unlike every other simulation partition, a window’s own [start_date, end_date) span anchors the row, not a stage/node index, so this schema carries scenario_id alone (no stage_id/node_id). 5 columns. All columns are non-nullable. Hive-partitioned by scenario_id (transit_seed/scenario_id=NNNN/data.parquet); written only when the system declares a travel-time arc.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
hydro_idInt32NoUpstream entity identifier whose release the window covers.
start_dateDate32NoStart of the release window (inclusive).
end_dateDate32NoEnd of the release window (exclusive).
value_m3sFloat64NoMean release rate over the window, in m³/s.

Post-horizon commitment lane results, keyed (thermal_id, delivery_date) — distinct from the per-plant anticipated_committed_mw/anticipated_decision_mw columns on simulation/thermals/. One row per declared window per terminal scenario. 7 columns. All columns are non-nullable. Hive-partitioned by scenario_id (anticipated_lanes/scenario_id=NNNN/data.parquet); written only when the study declares post_study_stages.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based) at which the lane’s commitment was deposited.
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
thermal_idInt32NoAnticipated thermal unit ID.
delivery_dateInt32NoCalendar date the commitment delivers, encoded YYYYMMDD (year*10000 + month*100 + day).
deposited_decision_mwFloat64NoDispatch decision deposited into this lane at stage_id for delivery at delivery_date, in MW.
carried_committed_mwFloat64NoCommitted capacity carried forward in this lane toward delivery_date, in MW.

Run-level echo of every pre-study-decided commitment that delivers past the study horizon — the DECOMP já-comandada deliveries, declared as past_anticipated_commitments windows extending past the horizon end. Unlike simulation/anticipated_lanes/, this file is not under simulation/, is unpartitioned, and carries no scenario, stage, or node axis: each row is a resolved input, scenario- and stage-independent. One row per fixed post-horizon window. 4 columns. All columns are non-nullable. Written by both the CLI and the Python bindings; written only when at least one such window exists — an empty set writes no file and no anticipated/ directory. There is no cost column: the fuel is a sunk cost, folded into the terminal boundary cut intercepts rather than booked in the study objective.

ColumnTypeNullableDescription
thermal_idInt32NoAnticipated thermal unit ID.
start_dateDate32NoFirst delivery date of the fixed window.
end_dateDate32NoLast delivery date of the fixed window.
value_mwFloat64NoCommitted delivery held constant over the window, in MW.

Generic user-defined constraint violations. One row per (stage, block, constraint) triplet where a violation occurred. 7 columns.

ColumnTypeNullableDescription
scenario_idInt32NoScenario id (0-based). Duplicates the Hive partition directory (scenario_id=NNNN/) as an explicit in-file column.
stage_idInt32NoStage index (0-based).
node_idInt32NoVisited policy-graph node id; equals stage_id on a stage chain.
block_idInt32YesLoad block index. null for stage-level constraints.
constraint_idInt32NoConstraint ID as defined in the case input files.
slack_valueFloat64NoNon-negative for a one-sided constraint. For a two-sided (range) constraint (both bounds finite), the signed net s_plus - s_minus — may be negative. Zero means no violation.
slack_costFloat64NoMonetary cost attributed to this violation.

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:

# Polars — reads all scenarios at once, infers scenario_id from directory names
import polars as pl
df = pl.read_parquet("results/simulation/costs/")
print(df.head())
# Pandas with PyArrow backend
import pandas as pd
df = pd.read_parquet("results/simulation/costs/")
-- DuckDB — filter to a specific scenario at the storage layer
SELECT * FROM read_parquet('results/simulation/costs/**/*.parquet')
WHERE scenario_id = 0;
# R with the arrow package
library(arrow)
ds <- open_dataset("results/simulation/costs/")
dplyr::collect(dplyr::filter(ds, scenario_id == 0))

Scenario IDs are zero-based integers. The total number of scenarios is documented in simulation/metadata.json under scenarios.total.


Both training/metadata.json and simulation/metadata.json use an atomic write protocol:

  1. Serialize JSON to a temporary .json.tmp sibling file.
  2. Atomically rename the .tmp file to the target path.

This ensures consumers never observe a partial file. If a metadata file exists, it contains a complete, valid JSON document. If a run is interrupted before the final write, the .tmp sibling may remain, but the target file reflects the last successfully completed write.

The status field is always the first indicator to check:

StatusMeaning
"complete"The run finished normally. All output files are present.
"partial"Not all scenarios completed without error. (Simulation metadata only.)

cobre report reads both metadata files and prints a combined JSON summary to stdout. Use it in CI pipelines or shell scripts to inspect outcomes without parsing JSON directly:

Terminal window
# Extract the termination reason
cobre report results/ | jq '.training.convergence.termination_reason'
# Fail a CI job if the run did not complete
status=$(cobre report results/ | jq -r '.status')
[ "$status" = "complete" ] || exit 1

The generic_constraints/ directory is written when the study declares any generic user-defined constraints (crates/cobre-cli/src/commands/run/outputs.rs). It sits at the top level of <output_dir>/, a peer of training/ and simulation/, not nested under either. The directory is omitted entirely when the study has no generic constraints.

The fully resolved echo of every generic constraint as the LP actually built it — one row per (constraint, stage, block, term). Written once, not per-scenario (the resolution is deterministic given the case, independent of simulation outcome). 13 columns.

bound_lower/bound_upper are the resolved interval endpoints (lower before upper), each null where unbounded on that side; derived_shape labels the shape those endpoints imply (e.g. a one-sided vs. range constraint). The per-term columns (term_index, variable_kind, variable, coefficient) are null on a term-less constraint’s placeholder row, and slack_penalty is null when slack is disabled for the constraint.

ColumnTypeNullableDescription
stage_idInt32NoStage index (0-based).
block_idInt32YesLoad block index within the stage. null for stage-level (non-block) constraints.
constraint_idInt32NoGeneric constraint ID as defined in the case input files.
constraint_nameUtf8NoHuman-readable constraint name from the case input files.
term_indexInt32YesIndex of this term within the constraint’s linear expression. null on a term-less placeholder row.
variable_kindUtf8YesKind of decision variable this term references. null on a term-less placeholder row.
variableUtf8YesIdentity of the referenced variable within its kind. null on a term-less placeholder row.
coefficientFloat64YesLinear coefficient applied to this term. null on a term-less placeholder row.
bound_lowerFloat64YesResolved lower bound of the constraint’s interval. null when unbounded below.
bound_upperFloat64YesResolved upper bound of the constraint’s interval. null when unbounded above.
derived_shapeUtf8NoShape implied by the resolved bounds (e.g. one-sided or range).
slack_enabledBooleanNoWhether a slack variable is enabled for this constraint.
slack_penaltyFloat64YesPenalty cost per unit of slack. null when slack is disabled.

The hydro_models/ directory is written when at least one of the following conditions holds: any hydro plant uses fpha_config.source: "computed" in system/hydro_production_models.json, any hydro plant has an evaporation model, or exports.fpha_deviation_points is true. The directory is omitted when none of these conditions are met.

Fitted FPHA hyperplane coefficients for all hydros that used source: "computed" in the current run. The schema is identical to the input file system/fpha_hyperplanes.parquet: 11 columns, all with the same names, types, and nullability.

ColumnTypeNullableDescription
hydro_idINT32NoHydro plant ID
stage_idINT32YesStage the plane applies to. null = valid for all stages
plane_idINT32NoPlane index within this hydro (and stage)
gamma_0DOUBLENoIntercept coefficient (MW), unscaled
gamma_vDOUBLENoVolume coefficient (MW/hm³)
gamma_qDOUBLENoTurbined flow coefficient (MW per m³/s)
gamma_sDOUBLENoSpillage coefficient (MW per m³/s)
kappaDOUBLEYesCorrection factor. Defaults to 1.0 when absent or null.
valid_v_min_hm3DOUBLEYesVolume range minimum where this plane is valid (hm³)
valid_v_max_hm3DOUBLEYesVolume range maximum where this plane is valid (hm³)
valid_q_max_m3sDOUBLEYesMaximum turbined flow where this plane is valid (m³/s)

The file is written atomically (via a .tmp rename) and uses the same (hydro_id, stage_id, plane_id)-sorted row order as the input schema. It can be used directly as a future source: "precomputed" input by copying it to system/fpha_hyperplanes.parquet.

See Case Directory Format — system/fpha_hyperplanes.parquet for the full column definitions and validity constraints.

Written when any hydro plant has an evaporation model. Contains the fitted evaporation coefficients for all plants that have evaporation, keyed by (hydro_id, stage_id). Rows with stage_id = null are per-hydro defaults.

Six columns:

ColumnTypeNullableDescription
hydro_idINT32NoHydro plant identifier
stage_idINT32YesStage; null = per-hydro default applicable to all stages
intercept_m3sDOUBLENoEvaporation intercept coefficient (m³/s)
volume_slope_m3s_per_hm3DOUBLENoVolume-dependent slope coefficient (m³/s per hm³)
reference_volume_hm3DOUBLENoReference volume used for linearisation (hm³)
sourceSTRINGNoDerivation label (e.g. "default_midpoint" or "user_supplied")

hydro_models/fpha_deviation_points.parquet

Section titled “hydro_models/fpha_deviation_points.parquet”

Written only when exports.fpha_deviation_points: true is set in config.json. Contains one row per (hydro, stage, V, Q) grid point at spillage = 0, recording how closely the fitted FPHA plane set approximates the exact production function at each sample point. Opt-in because it can be large (one row per grid-point combination for each computed-FPHA plant and stage).

Eight columns:

ColumnTypeNullableDescription
hydro_idINT32NoHydro plant identifier
stage_idINT32YesStage; null when the fit applies to all stages
vDOUBLENoVolume sample point (hm³)
qDOUBLENoTurbined-flow sample point (m³/s)
fph_exactDOUBLENoExact production function value at this (V, Q) point (MW)
fpha_fittedDOUBLENoFitted FPHA approximation at this (V, Q) point (MW)
deviationDOUBLENoSigned residual fpha_fitted − fph_exact (MW); positive = fitted cap above the exact surface
relativeDOUBLENo|deviation| relative to the grid’s peak exact generation (dimensionless, ≥ 0); 0 when the grid peak ≤ 0

The values are a pure function of geometry and config — the file is reproducible when emitted and never enters the parity hash.


When exports.stochastic: true is set in config.json, Cobre writes the stochastic preprocessing artifacts to output/stochastic/ before training begins.

The directory is not written when the config field is not set. Export is off by default.

File pathExport conditionSchema source
stochastic/inflow_seasonal_stats.parquetEstimation was performedSame as input scenarios/inflow_seasonal_stats.parquet
stochastic/inflow_ar_coefficients.parquetEstimation was performedSame as input scenarios/inflow_ar_coefficients.parquet
stochastic/correlation.jsonAlwaysSame as input scenarios/correlation.json
stochastic/fitting_report.jsonEstimation was performedJSON diagnostic report (see below)
stochastic/noise_openings.parquetAlwaysSame schema as scenarios/noise_openings.parquet
stochastic/load_seasonal_stats.parquetLoad buses existSame as input scenarios/load_seasonal_stats.parquet

“Estimation was performed” means the user did not supply the corresponding scenario file directly; Cobre derived it from inflow_history.parquet.

The opening tree used during the training run, written in the same schema as the input file scenarios/noise_openings.parquet. See the Case Directory Format for the 4-column schema (stage_id, opening_index, entity_index, value).

A JSON diagnostic report for the PAR model fitting. This file is written only when Cobre performed estimation from inflow_history.parquet.

Structure:

{
"hydros": {
"<hydro_id>": {
"selected_order": 3,
"aic_scores": [12.4, 11.1, 10.8, 11.3],
"coefficients": [[0.42, -0.11, 0.07]]
}
}
}
FieldTypeDescription
selected_orderintegerAIC-selected AR order for this hydro plant
aic_scoresnumber arrayAIC score for each candidate order; aic_scores[i] is the score for order i+1
coefficientsnested arrayOne row per season; each row contains the AR coefficients for that season

This file is diagnostic only. It is not consumed as input on subsequent runs.

Every exported Parquet and JSON file uses the exact same column names, types, and layout as the corresponding input file. To replay a run with identical stochastic context:

Terminal window
# Run with exports.stochastic: true in config.json
cobre run my_case
# Copy exported artifacts to scenarios/
cp -r my_case/output/stochastic/* my_case/scenarios/
# Re-run: the loader finds the files already present and skips estimation
cobre run my_case

The re-run produces bit-for-bit identical stochastic artifacts because the round-trip eliminates the estimation step. The opening tree is loaded directly from scenarios/noise_openings.parquet instead of being regenerated.

See the Exporting Stochastic Artifacts section of the Running Studies guide for the end-to-end workflow.