[calibration] CalibrationConfig#
TOML section: [calibration]
Pydantic model: CalibrationConfig defined in hydromodpy.calibration.config.
Top-level [calibration] section.
The config selects the optimizer, iteration budget, candidate persistence
policy, parameter declarations, observable outputs, and objective blocks.
It is the stable user-facing schema used by CLI calibration and
Project.calibrate.
When no explicit objective block is declared, HydroModPy can synthesize one
from objective and variable if the matching output exists.
Fields#
protocol
in TOML:
[calibration.protocol]
MatchingHydrographicNetworkOptions | None default = None user source
Published calibration method this file runs, named instead of retyped. A protocol writes the stages, their criteria and the model regimes they need, so the file states only what belongs to the site. Write the name alone, or a table carrying it plus the names this file uses for the parameters and outputs the method moves. Registered: ‘matching_hydrographic_network’ (Abherve et al., 2023, doi:10.5194/hess-27-3221-2023). A file that declares its own phases or objective blocks cannot also name a protocol.
method
str default = “grid” user source
Optimization method. Built-ins: ‘grid’ (regular sweep, sized by optimizer_kwargs.points_per_dim), ‘random_search’, ‘bisection’ (root of a signed criterion on one parameter, the stream-network stage), ‘optuna’ (TPE), ‘cma_es’, ‘scipy_de’, ‘scipy_nelder_mead’, ‘gp_mapping’, ‘da_mh_gp’. An unknown name is refused when the optimizer is built, with the list installed here.Optuna is installed by default; install the calibration extra for cma_es and Optuna’s cmaes sampler.
tolerance
Optional[float] default = None user source
How precisely the search has to pin a parameter before it stops, as a relative precision on the parameter itself: 0.01 asks for one per cent, 0.1 for ten. On a log-transformed parameter that is a ratio, which is how a conductivity is known in the first place, and it holds wherever the value sits; on any other transform there is no scale on the value to be relative to before the search has one, so it reads as a fraction of the declared interval. Each engine’s own stopping option is written from it, so the same number survives a change of engine, and the engine’s own option stays available for reproducing a published call verbatim. Unset, the engine’s default applies. An engine that stops on its budget rather than on a precision refuses this rather than ignore it.
batch_size
int default = 1 dev source
Number of suggestions drawn per ask (for parallel optimizers).
parallel
int default = 1 dev source
Number of trials evaluated concurrently inside one batch via a thread pool. parallel=1 keeps the legacy sequential loop.
reject_water_budget_above
float | None default = None user source
Percent water-balance discrepancy past which a trial is rejected instead of scored. The solver reports the figure on every run; unset, it is recorded and nothing acts on it, so a run at twelve per cent is ranked beside one that closed even though part of the water it routed came from nowhere. There is no default because there is no universal value: a steady solve on a coarse mesh closes to a fraction of a per cent, a transient one with a lake and a routed network legitimately sits higher.
warmup_periods
int default = 0 user source
Spin-up (burn-in) periods excluded from every objective block. The first warmup_periods of each observed/simulated series are dropped before the metric, so the window where the state still depends on the initial condition does not bias the calibration. Default 0 (no exclusion). Size it by increasing it until the objective stops changing (initial-condition insensitivity), not a fixed guess.
scoring_window
in TOML:
[calibration.scoring_window]
CalibScoringWindow | None default = None user source
Dates bounding the samples every metric is computed on. Mutually exclusive with warmup_periods, which counts samples instead of dates.
phases
in TOML:
[[calibration.phases]]
list[CalibPhaseDecl] | None default = None user source
Stages run one after the other, each calibrating its own parameters and freezing them for the next. Declaring this table is what switches the runner to staged mode; without it nothing changes for an existing configuration. The default is None and not an empty list on purpose: the resume lock hashes the configuration with exclude_none, so an absent table leaves that hash untouched and checkpoints stay resumable.
save_runs
str default = “none” user source
How much to persist per iteration: - ‘none’: 1 DuckDB row per iteration, no Zarr. - ‘best_n’: same + promote top N to full simulations after the loop. - ‘all’: every iteration becomes a full simulation (Zarr included).
One of: "none" "best_n" "all"
save_best_n
int default = 10 user source
Number of top iterations to promote when save_runs=’best_n’.
lightweight_extraction
bool default = True dev source
Skip Parquet/Zarr writes for lumped models (GR4J, …) and read simulated series from the per-trial RAM cache instead. Only the promoted runs go through the catalog write path.
objective
str default = “nse” user source
Metric scoring the single simulated series, when no objective block is declared. Same vocabulary as a block’s ‘metric’; typed here so a bad value is reported against the key that was written.
One of: "rmse" "nse" "kge" "mae" "nse_log" "nse_delta" "nse_seasonal" "reservoir" "distance_gap" "distance_mean"
observed_station_id
str | None default = None user source
Observed station whose cost the optimizer minimises. Every loaded gauge is already scored at its own mesh cell, on the discharge routed to that cell, and every cost is reported; naming one says which of them drives the search. Required when several stations are loaded, optional with one.
optimizer_kwargs
in TOML:
[calibration.optimizer_kwargs.<id>]
dict[str, Any] factory dev source
Extra keyword arguments forwarded to the optimizer adapter.
parameters
in TOML:
[calibration.parameters.<id>]
dict[str, CalibParameterDecl] factory user source
Per-parameter declarations (bounds, transform, prior, path).
outputs
in TOML:
[calibration.outputs.<id>]
support = “point” | “boundary” | “cell” | “lake” | “network” factory user source
Named observables extracted from each candidate run.
Pick a tab below: setting
supportselects the matching schema.
TOML: [calibration.outputs.<id>] with support = "point" – model CalibOutputPoint.
observes
str | None default = None user source
Station whose loaded record this output is scored against. The record is aligned on the simulated timestamps, so a weighted block scores dated observations rather than a vector typed into the file. The data family follows ‘variable’: discharge from hydrometry, head from piezometry, stage from lake_levels. Mutually exclusive with ‘observed_values’. The station is located by its own record and not by coordinates written beside it, so this output and the single-metric route read the same cell and their costs are comparable; a station the project cannot locate is refused by name rather than scored on another quantity.
geometry
in TOML:
[calibration.outputs.<id>.geometry.<id>]
dict[str, Any] | None default = None user source
GeoJSON point geometry. Coordinates are in metres.
x
Optional[Any] default = None user source
X coordinate. Accepts a bare number (metres) or a pint string like ‘100 m’.
y
Optional[Any] default = None user source
Y coordinate. Accepts a bare number (metres) or a pint string like ‘100 m’.
time
Union[str, list[str]] default = “all” user source
‘all’ keeps every time step; ‘last’ / ‘first’ selects one; a list of ISO timestamps selects specific steps.
One of: "all" "last" "first"
reducer
str default = “none” user source
Aggregation over the retained time slice.
One of: "mean" "sum" "last" "none"
observed_values
list[float] | None default = None user source
Hard-coded observed values, positional and dateless. Name a station in ‘observes’ to score a record the project loaded instead.
TOML: [calibration.outputs.<id>] with support = "boundary" – model CalibOutputBoundary.
observes
str | None default = None user source
Station whose loaded record this output is scored against. The record is aligned on the simulated timestamps, so a weighted block scores dated observations rather than a vector typed into the file. The data family follows ‘variable’: discharge from hydrometry, head from piezometry, stage from lake_levels. Mutually exclusive with ‘observed_values’. The station is located by its own record and not by coordinates written beside it, so this output and the single-metric route read the same cell and their costs are comparable; a station the project cannot locate is refused by name rather than scored on another quantity.
time
Union[str, list[str]] default = “all” user source
‘all’ keeps every time step; ‘last’ / ‘first’ selects one; a list of ISO timestamps selects specific steps.
One of: "all" "last" "first"
reducer
str default = “none” user source
Aggregation over the retained time slice.
One of: "mean" "sum" "last" "none"
observed_values
list[float] | None default = None user source
Hard-coded observed values, positional and dateless. Name a station in ‘observes’ to score a record the project loaded instead.
TOML: [calibration.outputs.<id>] with support = "cell" – model CalibOutputCell.
observes
str | None default = None user source
Station whose loaded record this output is scored against. The record is aligned on the simulated timestamps, so a weighted block scores dated observations rather than a vector typed into the file. The data family follows ‘variable’: discharge from hydrometry, head from piezometry, stage from lake_levels. Mutually exclusive with ‘observed_values’. The station is located by its own record and not by coordinates written beside it, so this output and the single-metric route read the same cell and their costs are comparable; a station the project cannot locate is refused by name rather than scored on another quantity.
time
Union[str, list[str]] default = “all” user source
‘all’ keeps every time step; ‘last’ / ‘first’ selects one; a list of ISO timestamps selects specific steps.
One of: "all" "last" "first"
reducer
str default = “none” user source
Aggregation over the retained time slice.
One of: "mean" "sum" "last" "none"
observed_values
list[float] | None default = None user source
Hard-coded observed values, positional and dateless. Name a station in ‘observes’ to score a record the project loaded instead.
TOML: [calibration.outputs.<id>] with support = "lake" – model CalibOutputLake.
observes
str | None default = None user source
Station whose loaded record this output is scored against. The record is aligned on the simulated timestamps, so a weighted block scores dated observations rather than a vector typed into the file. The data family follows ‘variable’: discharge from hydrometry, head from piezometry, stage from lake_levels. Mutually exclusive with ‘observed_values’. The station is located by its own record and not by coordinates written beside it, so this output and the single-metric route read the same cell and their costs are comparable; a station the project cannot locate is refused by name rather than scored on another quantity.
variable
str default = “stage” user source
Simulated lake quantity: ‘stage’ (water level, m), ‘volume’ (m3) or ‘surface_area’ (m2). All three are LAK observation states, read in native units and never time-scaled.
One of: "stage" "volume" "surface_area"
time
Union[str, list[str]] default = “all” user source
‘all’ keeps every time step; ‘last’ / ‘first’ selects one; a list of ISO timestamps selects specific steps.
One of: "all" "last" "first"
reducer
str default = “none” user source
Aggregation over the retained time slice.
One of: "mean" "sum" "last" "none"
observed_values
list[float] | None default = None user source
Hard-coded observed values, positional and dateless. Name a station in ‘observes’ to score a record the project loaded instead.
TOML: [calibration.outputs.<id>] with support = "network" – model CalibOutputNetwork.
variable
str default = “release_flux” user source
Per-cell observable read from the solver, in m3/s, positive when the aquifer feeds the surface.
stream_geometry_path
str required user source
Vector file holding the mapped stream network. Required, and read only from here: the criterion resolves no geometry of its own and does not reuse the one the hydrography data family loaded.
tau_specific_ratio
float default = 0.0001 user source
A cell releasing less than this fraction of its own recharge is not a seepage face. Zero reproduces the purely geometric criterion of the paper. Frozen over the whole search: a threshold moving with the trial would cost the criterion its monotonicity.
weighting
str default = “cell” user source
Average one cell one vote (the paper) or weighted by cell area. Both values are always reported; use ‘area’ on a mesh refined along the streams, where cell density is highest exactly where distances are smallest.
One of: "cell" "area"
diagonal_neighbors
bool default = False user source
Route over shared nodes rather than shared edges, which recovers the diagonal descents of a D8 grid. Only meaningful on a structured quad mesh. The default is the literal reading of the paper and it is not a second-decimal choice: on a synthetic valley whose talweg runs along the grid diagonal, the most accumulated cell collects 6.6 per cent of the domain over shared edges and 100 per cent over shared nodes, and the delineation that produced the catchment itself uses a D8 pointer. Set it to true wherever the talwegs are not axis-aligned, which on real topography is most of them.
observed_position_accuracy
Optional[Any] default = None user source
Positional accuracy of the mapped network. The validity ratio is normalised by max(cell size, this), because the error floor is set by the network’s own precision and not by the model resolution. Unset is the literal reading of the paper.
roptim_max
float default = 2.0 user source
Validity bound of Eq. 4. It qualifies the result and never penalises the cost: a bad ratio says the agreement is coarse, not that the calibrated value should be discarded.
on_roptim_violation
str default = “warn” user source
What a violation of the validity bound does. Default warns and returns the value, because a calibration is asked for a number.
One of: "warn" "error"
max_unreachable_fraction
float default = 0.05 user source
Bound on ‘frac_unreachable_so’ alone: the share of the simulated network whose descent never meets the mapped one, whose target does not move between trials. Beyond a few per cent the routing surface is not conditioned and D_so would be a fiction. The reciprocal share, ‘frac_unreachable_os’, is reported and deliberately left unbounded: its target is the simulated network, which the search itself retracts.
alpha_warning_threshold
float default = 0.9 expert source
Below this value of ‘alpha_obs_closure_catchment’ the run warns that its distances carry a top-versus-map disagreement on top of the hydrogeology. alpha is the share of the downstream closure of the mapped network the network itself covers, measured on the MODEL TOP and on the catchment. It changes nothing that is computed: the criterion is scored the same way above and below it.
clipping_warning_gap
float default = 0.05 expert source
Minimum absolute gap between the whole-mesh and the catchment alpha for the clipping report to fire. A linework spilling out of the catchment over ground that routes the same way leaves the two ratios equal, and reporting it there would be noise on every ordinary project.
time
Union[str, list[str]] default = “last” user source
Which timesteps the release flux is read at. Phase one runs a single steady period, so ‘last’ is the whole run.
One of: "all" "last" "first"
objective_blocks
in TOML:
[[calibration.objective_blocks]]
list[CalibObjectiveBlockDecl] factory user source
Weighted blocks making up a composite objective. When empty, a single implicit block is built from ‘objective’ and ‘variable’.
persist_iteration_detail
str default = “summary” dev source
‘none’ skips component metrics; ‘summary’ keeps block totals; ‘full’ also stores per-block raw and normalized costs.
One of: "none" "summary" "full"
persist_model_distribution
bool default = False dev source
Persist the candidate distribution alongside the session.
rerun_best_with_outputs
bool default = False user source
Replay the best candidate with full outputs after the loop.
materialize_candidates
bool default = False dev source
Write a standalone override TOML for each candidate under ‘candidates_root’ so runs can be replayed later.
candidates_root
PurePosixPath | None default = None dev source
Directory for per-candidate overlay TOMLs. Required when materialize_candidates is True.
aggregate
in TOML:
[calibration.aggregate]
CalibAggregateDecl factory user source
How several scored targets become one cost: what made them comparable, how nested gauges are read, and what one unscorable member does.
uncertainty
in TOML:
[calibration.uncertainty]
CalibUncertaintyDecl factory user source
How wide the search reports its own answer to be. The calibrated value is unaffected; this only decides the interval printed beside it.
persistence
in TOML:
[calibration.persistence]
PersistenceConfig factory user source
Single switch governing every persistence sink (catalog, Zarr, Parquet, lockfile) for calibration outputs.