Releases: HydroModPy/HydroModPy
Release list
v2.0.0a4
Changed
- Time-varying fields are stored in float32 with the mantissa rounded to 16 kept bits
([simulation.results.persistence] field_precision = "compact", the default;"exact"keeps
float64). The error is at most 2**-17 of the value, under 1 mm on a 130 m head, and a rounded
array carries the CFquantizationattributes.release_fluxandfluxes_from_budgetare
rebuilt on read from the budget terms instead of stored. A daily 6-year run of example 04 goes
from 1375 to 397 MB, a monthly one from 16 to 5.5 MB; its NSE moves by 7e-8. Stores written
before read as they did. A spin-up writes its cycles exact, since their heads start the next
cycle and the production run. - A field is read over a range of timesteps with the store opened once
(results.run.geographic.field_range,field_steps), and the flow-state figures use it: the
15 figures of a daily example 04 run render in 17 s instead of about 2 min, the same pixels. - A calibration promotes a trial from the solve the trial already ran: the trial's MODFLOW
folder is kept while it may be promoted (every trial undersave_runs = "all", the
save_best_nor the best otherwise), and the promotion resumes at extraction instead of
writing inputs and solving again. The promoted run is the same, all Zarr arrays bit for bit,
and is taggedpromoted_from_trial:<N>; a trial that was not kept is replayed as before, with
the reason logged. On the daily API grid of example 04 a promotion no longer spends its ~7 min
of solve. The kept folders are released on every exit path. - The CLI banner draws every letter whole in its color. The slanted font joined the Hydro "o" to
the "M" and the Mod "d" to the "P" with a shared stroke, so the color changed inside a letter
and the "P" had no yellow stem. The art keeps a blank column at both joins, four columns wider. - Every file of example 04 draws more figures and writes exports to
share/<run>/. Step 1
declares three[[export]]blocks, steps 2 to 4 append theirs with[[export__append]], and
step 5 drops them withexport__delete = trueto write its own eleven.project.tomlexports
the catchment and its network, the water table and the seepage cells of October 2002, the
discharge and the budget, which every calibration writes for each run it promotes; the daily
API grid writes its own, dated 2019. Step 2 keeps the per-cell recharge, which the distance map
and the persistence maps of step 4 read. The composite calibration draws its cost profile and
its distance crossing against K instead of four figures that did not apply to two parameters.
Fixed
- The scan of
data/<variable>/before a run removes an orphan sidecar, one whose data file is
gone, when it holds nothing the file does not give back (hash, CRS, bbox, undetermined licence).
Git ignores the sidecars HydroModPy writes, so a data file a commit removed left its sidecar in
every clone, and everyhmp runof that workspace warnedauto_scan skippedabout it, lake
sidecars included for a run without a lake. A sidecar with a stated licence or notes is kept
and reported as kept;hmp data checksays which of the two the next scan does. - A calibration whose gauge comes from an API cache promotes its runs again. A station read back
from its cached_LOC.csvcarried numpy values, and a one-station file reads an integer
column asint64, which the catalog refused to write as JSON: every promotion of the daily API
grid of example 04 failed on its second launch. A station location now holds plain Python
values, whatever reader built it. - The catchment buffer no longer warns
The resolution argument to buffer is deprecatedunder
geopandas 1.2, which renamed itquad_segs; 1.1 still requires the old name, and the declared
range covers both, so the buffer calls shapely directly.
v2.0.0a3
Changed
- On a terminal, a console log line starts with a glyph for its level, like the phase checkmarks:
✗error,!warning,›milestone,·debug. A long line wraps under its message, not
under the glyph. Thenext:line of the run recap prints dim, without a glyph
(core.progress.HINT). A pipe keeps the[WARNING]labels, and the log files are unchanged.
Fixed
hmp example add 04merges the rows of the stations it reads (NANCON, NANCON_REA) into the
workspace registriesdata/<variable>/<variable>_custom_LOC.csv.hmp workspace initwrites
those registries empty, so every hydrometry, recharge and runoff load failed and the full
transient runs diverged. A row already there with other values is kept unless--force.hydromodpy.__version__reads thepyproject.tomlof the checkout it is imported from before
the installed metadata. An editable install keeps the number it was installed at, so a
checkout bumped to 2.0.0a2 still reported 2.0.0a1 inhmp doctor, run provenance and PNG
metadata.- Several runs of one project run at once. Each run, or each calibration session with its
trials, phases and promotions, works in its own.hmp/scratch/<config>.p<pid>/
(core.state.paths.run_scratch): its preprocessing, its solver folders and the recharge its
trials share..hmp/scratch/was shared by the whole project, so on example 04 four runs
started together lost three inbuild_geographic(a Whitebox panic, a missing
dem_fill.tif, a missingoutlet.shp), concurrent calibrations read the network another run
wrote and shared one_shared_rechargeacross different recharges, and a run that ended
swept the solver folders of all the others ("Solver output directory is missing", "CBC file
not found"). A child process inherits its parent's folder throughHMP_RUN_SCRATCH; the next
run of the project removes the folders of killed runs.PREPROCESSING_DIRis replaced by
core.state.paths.preprocessing_dir(root). batch_sizeandparallelof a calibration and of a phase are user options, andparallel
alone now runs trials side by side: a batch holds at leastparalleltrials, where a batch of
one serialized them. Measured on the composite of example 04, 8 trials atparallel = 4take
278 s for 695 s of solves.run_calibration_api_daily.tomlsolves its five K at once.scipy_nelder_meadruns on a port of SciPy 1.18.1's Nelder-Mead that evaluates the candidates of
one step side by side (reflection, contractions, expansion, shrink points) and keeps only the
values SciPy's rules read: the path, the answer, the evaluation count and the status are SciPy's,
call for call, at everyparallel. The candidates solved and not read stay in the history,
markedspeculative_unusedin the journal, and spend no budget.- The root search uses
parallel: its sweep is solved at once, and each round cuts the bracket
intoparallel + 1parts in log instead of two, both roots of a two-bound search at the same
time. On the Nancon bounds, one root takes 6 rounds (20 solves) at 4 against 15 rounds today,
two roots 8 rounds (26) against 24. The root lies in the same stopping-width bracket;parallel = 1repeats today's search trial for trial, and the counted budget follows the width. - Every phase takes the
parallelandbatch_sizeof[calibration]unless it sets its own
(CalibrationConfig.parallel_for,batch_size_for): the phases a protocol writes declare none,
so the section's value reached none of them. Run completed: <name> [<id>] <n>sprints the run's duration, theduration_sthe catalog
stores, instead of the solver step alone (6 s printed for a 19 s run).- The help of
[simulation] if_existssays whatreplacedoes: it trashes the predecessor,
which keeps its name, and registers the new run under the next freename.vN. It said the
new run took the name. flux_timeseries,water_budgetand the testbed budget metrics read the catchment budget
zone, or the domain one when there is no catchment, and the figures name the frame. They
summed both zones: the catchment lies inside the MODFLOW 6 domain, so its water was counted
twice (1.68 m3/s of recharge drawn for 1.09 on the domain and 0.59 on the catchment).seepage_network_confusion_mapandnetwork_extent_bounds_mapcount every legend class on
the frame they declare. "no stream" counted the whole grid (20 548 cells) under "frame: the
delineated catchment", and the both-bounds extents counted the domain (1234 cells) next to
scored counts taken in the catchment (714).- A GeoPackage or Shapefile export of
simulated_active_networkholds the active cells only,
with their attribute. It wrote every cell of the grid (21 406 polygons, 610 active, 5 MB). - The calibrated discharge adds a gridded runoff (SIM2,
extent = "watershed"), reduced to its
watershed mean as the run stores it. The objective read runoff stations only, so
run_calibration_api_daily.tomlscored the drain alone against the total gauged flow while
its runs reported drain plus runoff, which pushed K onto the lower bound. - A network output whose
timeis a date is redrawn at that date by the figures of the run,
on the period[s, e)that holds it, the state the trials scored. The derive path accepted
lastandfirstonly, so the promotion ofrun_calibration_composite.toml
(time = "2002-10-15") failed in its display step. The period rule moved to
core.time.selection.resolve_state, shared by the calibration and the results layer. - Every run a calibration promotes keeps its watershed. The export step of the first promotion
dropped the session's shared preprocessing tree, so withsave_runs = "all"the next ones
had no watershed: their catchment discharge summed the whole domain (PBIAS -95 % on the
daily API grid of example 04) and 6 of 15 figures did not apply. - A calibration whose promotion fails says so and exits 21 (
CalibrationError) fromhmp run
andhmp calibrate, after printing the results of the search, which are kept. It printed
"done" and exited 0 while the promoted run wasfailedin the catalog. - The progress line of a bisection shows its bracket, then its root, instead of the lowest
cost met, which is not the answer of a root search (BD Topage:best 71.8at K = 1e-7 for a
root at K = 5.9e-6). - A calibrated value no other trial comes close to prints "no other trial within the
tolerance" instead of a zero-width interval[x, x]. - A session journal names its project (the project folder, as its runs do) and the metrics of
its objective blocks, and drops thevariable/objectivepair a block-scored phase leaves at
its defaults. It wroteproject = "calibration",objective_name = "nse"and
variable = "head"for a network phase scored ondistance_gap. - The calibration figures read what they need from the session journal:
parameter_cost_profilemarks the trial the calibration returned, not the lowest cost:
the BD Topage profile named K = 1e-7 for a returned K of 5.9e-6.matching_hydrographic_network_cardof a two-bound search shows Delta, the combined value,
the validity and the cells without being passed the roots.bisection_bracket_tracedraws a two-bound search, both residual series and both roots.parameter_cost_profileandcalibration_progressshare the interval of the calibration
summary (one mesh cell for a distance cost, 5 % otherwise). The profile drew a +10 % rise
instead,[8.094e-05, 8.115e-05]for a summary of[7.499e-05, 1e-4], and itsrise
option is removed.- The axes carry their units:
K (m/s),|D_so - D_os| (m),1 - NSElog (-).
- A figure that finds while reading the run that it does not apply raises
display.figure.FigureNotApplicable, and the batch skips it with its reason whatever
on_errorsays. The one-parameter calibration figures do so on a session that sampled
several parameters together: the composite of example 04 (K and Sy) failed its promotion on
downslope_distance_crossingunderon_error = "raise". - The figures of a run redraw the stream network with the mean recharge its trials scored
with. The trials averaged the rate the forcing gives each period; the redraw averaged the
budget, where a steady spin-up period holds the record mean in place of its month (8.656e-9
against 9.075e-9 m/s on the monthly Nancon), so the drawn network was cut at another
threshold than the scored one and "The mean recharge moved" was logged for an unchanged
forcing. Both now apply one rule (core.stream_recharge) to the forcing, the redraw reading
the station forcing the run stores; a real change of data or window still warns.
v2.0.0a2
Added
[[export]]: one block per export request (variables,time,period,format,folder,
file,crs,resolution,layer,nodata). The format follows the data: GeoTIFF for a field at
one date, NetCDF for several dates, CSV for series and the budget, GeoPackage for vector layers.
The catchment, the mapped networks,watershed_dem, the water budget and the virtual field
simulated_active_networkbecome exportable.formatalso takespackage,stac,rocrate,prov.hmp export SIM_REF [variables...]speaks the same words (--time,--period,--format,--file,
--crs...), andhmp export SIM_REF --listprints what a run can export, by kind.hydromodpy.core.time.selectionandRun.step_at,Run.steps_for,Run.period_edges: one
date-to-stress-period resolver for figures and exports.[display] timeand a per-figuretimename the instant a map draws as a date,firstorlast;
a steady calibration phase resolves any date of its record, so no phase override is needed.
hmp.figure(..., time=...)andhmp viz show --timetake it too.- A network calibration output takes an ISO date in
time;normalize_cost = trueon
distance_gapanddistance_meandivides by the validity length, so phase shares are real shares. - A calibration ends with a short recap in normal mode (one line per phase, best values with their
interval, where the best runs are) and writes its methods paragraph tomethods.md. [geographic.snap_streams]inapplymode reaches every consumer of the mapped network:
stream burning snaps the map on the raster's own D8 graph before burning it, a mesh built along
a mapped network (rivers.source = "file") follows the snapped lines, and the network cells,
metrics, CSV exports and reference-network figures read the snapped map the run stored.
diagnosekeeps the raw map everywhere while the snap is computed and reported.- A calibration session stores its root-search result (
bracket, orrootswith both roots,
Delta and the combined value) insession.json; the protocol card and the calibration report
read it back. hmp calibrate --checksays when stage two of the protocol scores the whole run, spin-up year
included.- A network calibration output takes a minimal (permanent) map beside its maximal one, as a file
(minimal_stream_geometry_path) or as the permanent reaches of the hydrography data family
(minimal_observed_network = "data.hydrography", refused by name when the source says nothing
about permanence). The maximal map is scored as the union of the two, and
frac_minimal_outside_maximalis published. - The transient two-bound mode,
[calibration.outputs.<name>.extent]. For each complete calendar
year inside the phase'sscoring_window, the maximal simulated mask holds the cells flowing at
leastmaximal_flowing_stepstimesteps and the minimal one the cells dry at most
minimal_dry_stepstimesteps (both 1 by default, counted in timesteps); the years are aggregated
byyear_quorum(0.5) and each bound is scored once with the distance criterion. A cell flows
when it is in the downstream closure of the seepage and its routed discharge reaches
visible_flow("1 L/s" by default, or a share of the outlet discharge such as "1%").
hydromodpy.core.stream_extentholds this one definition of flowing for the criterion and the
figures. - Two bounds, one value: the bisection closes one root per bound on the same trials and returns
their weighted geometric mean, log K = w_min log K*_min + w_max log K*_max (weights, 0.5 each),
evaluated once so every published number comes from a solve. The report andhmp calibrate
give both roots, both brackets and Delta = log10(K*_max / K*_min); a minimiser's cost is
w_min |J_min| + w_max |J_max|.max_iter = "auto"budgets both roots. [geographic.snap_streams](offby default,diagnose,apply) moves the mapped network
onto the talwegs of the criterion graph, flow-accumulation guided from downstream to upstream,
within a radius in metres (2 h_obs by default), rejecting what it cannot attach. Trials publish
the displacement (p50, p90), the rejected share, the length ratio and the floor F, the Doptim of
the snapped map against the raw one; inapplyEq. 4 also bounds the displacement. A run
stores its snapped map, and two figures,observed_network_snap_mapand
observed_network_snap_histogram, show what moved.validity_lengthon a network output,"auto"or a length such as"150 m": Eq. 4 reads
Doptim <= validity_length."auto"is 2 h, with h = max(h_obs, observed_position_accuracy), and
h + max(h, F) when a snap floor exists. Each trial publishes the length and what set it.network_extent_bounds_mapdraws the maximal and minimal simulated extents of a transient run
against its two maps, outside any calibration.hydrographic_network_permanencedraws the mapped network split by permanence: the permanent
reaches (the minimal map) over the reaches the complete map adds, with the length and reach
count of each class. It needs a hydrography source that says which reaches flow all year.- Preflight refuses an extent table on a steady search, a minimal map file that does not exist,
and adata.hydrographyminimal map without a declared hydrography source. hmp runon an overview ends on the catchment, its area, the web report and the figures folder;
--verbosekeeps the full recap. The overview shows its phases and the data families load
under one progress bar.
Changed
optimizer_kwargsis nowmethod_options, and the protocol's*_engine_optionsare
*_method_options; the old names load with a warning. Options are checked when the file loads
and byhmp calibrate --check. The rename changes every calibrationparams_hashonce.- The per-figure
timestepis nowtime; old files load,hmp doctor --fix-configrewrites them.
An unknown key in[display.overrides.<figure>]is refused at load. - An old
[export]table of format toggles or[[export.artifacts]]loads as[[export]]blocks. hmp calibrate --checkprints only real departures from the paper; the full record is at-v.
--expandprints the whole pasteable section.--list-phasesprints shares below 1 % and names the
station a point output observes.- A scoring window is accepted beside a network output read in one state; it is refused only when
it does not hold that state.warmupandwarmup_periodsmove to the expert profile. - Promoted calibration runs are named
<simulation name>_<phase>instead of<method>_iter_NNNN. - Figures:
seepage_mapdraws two classes; maps open on the catchment in projected metres; titles
name the period drawn and saycatchment outlet; the identity card drops its status and id rows
and wraps long names; the network maps state the seepage threshold in words. - Normal console: the licence warning prints once per workspace;
Run completedprints last; the
figure summary warns only when a config option would have kept a skipped figure; the runoff and
outlet messages are one sentence each. [geographic].dem_correc_typedefaults to"fill", the paper's FillDepressions, instead of
"breach". A file that writes"breach"keeps it, and the Methods paragraph and
hmp calibrate --checkname it as a departure from the paper.matching_hydrographic_networkis version 1.2: the DEM is filled by default, stage two leaves
the first year of the run out as spin-up unless the file declares a window, and the Eq. 4
bound is a length. A pin on 1.1 is refused.- The protocol card reads the keys a trial published: both bounds side by side in the two-bound
mode, the validation map beside the scored one in a one-state run. - Example 04: every TOML follows the current code (budget
"auto", no retired key, comments on
the criterion, the maps, the buffer and the protocol version brought up to date), the new
options shown commented out; the burning of the routing DEM is dropped. - With both maps, a one-state network output is scored on the minimal map, as the WRR 2025 paper
calibrates, and the maximal map is published as a validation outside the cost. L_ref, the length that normalises roptim and sets the interval width of a network search, is
h_obs, the median distance between neighbouring cell centres over the mapped cells of the
catchment. Unchanged on a regular grid; the fine cell on a mesh refined along the streams.- roptim is always Doptim / h_obs, the paper's Eq. 3; a declared
observed_position_accuracy
enters the validity length only. - The persistence figures and
simulated_active_networkin persistence mode count a cell as
flowing by the criterion's definition, and the stream-network maps redraw with the settings the
run sealed, so they show the partition the trial scored. - Toggling
[geographic.snap_streams]does not invalidate the geographic cache. hmp config templatewithout--moduleswrites every module,[calibration]and
[mesh_catchment]included. They were left out so the template would validate as written,
which it never did.
Removed
hmp data export,hmp data export-packageandhmp catalog export:hmp exportreplaces them.- The
[export]format toggles,output_dir,[[export.artifacts]]andvar,fmt,dest. roptim_max. The load-time migration andhmp doctor --fix-configdroproptim_max = 2, which
validity_length = "auto"reproduces, and refuse any other value with the length to write.geometry_from_run, replaced bynetwork_maps_from_run, which returns every declared map.
Fixed
hmp calibrate --checknames an option a phase-two method refuses, instead of failing after phase
one spent its budget.- The network criterion no longer warns that the mean recharge moved on float noise.
- The protocol card of the second promoted run draws...
v2.0.0a1
Removed
-
reference_valuesfrom calibration protocols and fromprotocol_record. -
The
hydromodpy.optimizerentry-point group. A method it listed was refused
anyway by the closed union ofoptim/method_config.py. Search methods ship
with HydroModPy; a search of one's own runs from Python, as an object that
satisfiesOptimizerhanded toCalibrationEngine(optimizer=...). -
geographic.bottom_path, which nothing read.hmp doctor --fix-configand
the loader move its path to[[data.substratum.sources]]and leave
[domain.depth_model]as it was; a loader that skips the migration accepts
the key, ignores it and warns. Dropping it from the geographic fingerprint
rebuilds each geographic cache once. -
examples/projects/02_nancon_watershed/run_sweep_sy.toml, a design draft for
asweepworkflow that does not exist, andrun_transient_prototype.py.draft
leave the example. -
examples/projects/19_cheze_reservoir, the lake test project of the Chèze
reservoir, the three projects ofexamples/projects/new_to_sort, the Chèze
diagnostic scripts oftools/diagnostics/andtools/view_mesh_grid_3d.py
leave the repository with the lake data only they read. None was cited by a
test, the documentation or the example manifest. -
The
data-fetchprocess,hydromodpy/data/fetch/and
hydromodpy/schema/processes/data-fetch@1.json.data-requestreplaces it
and serves every[data]variable instead of six sources. Only the request
format changes. Adata-fetchrequest named one source by a taggedid
with its options beside it, and the extent at the top ofinputs:{"process": {"id": "data-fetch", "version": "1.0.0"}, "inputs": {"source": {"id": "hubeau-piezometry", "product": "level"}, "mask": {"href": "/jobs/4711/outputs/watershed.gpkg"}, "period": {"start": "2020-01-01", "end": "2020-12-31"}}}A
data-requestrequest carries[data]sections, written as in a project
TOML, and the extent underextent(bboxwithcrs,mask, or
station_ids); a plugin source goes underinstalledbyname:{"process": {"id": "data-request", "version": "1.0.0"}, "inputs": {"data": {"piezometry": {"sources": [{"source": "hubeau", "product": "level"}]}}, "extent": {"mask": {"href": "/jobs/4711/outputs/watershed.gpkg"}}, "period": {"start": "2020-01-01", "end": "2020-12-31"}}}The report moves from
outputs/fetch.jsontooutputs/request.json, and
the payload from one ofoutputs/points.parquet,fields.nc,
features.gpkg,raster.tifto oneoutputs/<variable>_<source>file per
variable and source. A chain links the mask asextent.maskinstead of
mask. -
HubeauPiezometrySource,IgnDemSourceandSim2PrecipitationSource, and
the source idshubeau-piezometry,ign-bdaltiandsim2-precipitation
ofhydromodpy.data.source.registry. Their only caller wasdata-fetch.
Piezometry, the DEM and SIM2 are asked through their[data]section, in a
project TOML or a data request; a plugin source goes underinstalled. The
port keepsBdTopageSource,EuHydroSourceandOsmSource. -
hydromodpy.data.DataManagers,hydromodpy.data.loading.entry.DataEntryand
hydromodpy.results.catalog.cross_db.entry_used_by, which nothing called.
With them go the two layer tolerancesdata -> resultsand
results -> datathat the cross-database bridge needed;run.input_entries()
remains the way from a run to the cache entries it read. -
The 7-name facade of
hydromodpy.calibration.runners, which nothing
imported, andhydromodpy.calibration.protocols.registry.assert_version_is_available:
the protocol version is checked inmatching_hydrographic_network.py
instead. -
hydromodpy.display.renderer.save_figure,hydromodpy.display.theme.plot_params,
hydromodpy.display.colormaps.check_no_banned_in_call, the module
hydromodpy.display.geo.basemaps, andGeoFigureMixin.add_basemapwith the
crsattribute only it read. Nothing called them; a figure is saved by
BaseFigure.plot. -
The module
hydromodpy.display.catchment_report.cli: the options of
hmp report catchmentlive inhydromodpy/cli/commands/report.py,
unchanged.python -m hydromodpy.display.catchment_report.pipelineand
python -m hydromodpy.display.catchment_report.contextgo with it: use
hmp report catchment <toml>, orbuild_context_from_report_configfrom
Python for the context alone.
Added
- BD Topage reaches carry a canonical
permanencecolumn (permanent,intermittent,
ephemeral,dry,unknown, vocabulary inhydromodpy/data/source/permanence.py) beside
PersistanceTH. The download writes its permanent reaches to
hydrography_bdtopage_permanent_<hash>.gpkgbesidehydrography_bdtopage_<hash>.gpkg, the run
clips them tostreams_permanent.shpbesidestreams.shpand keeps them as the
reference_permanenthydrographic network. A network that says nothing about permanence has no
permanent part. CatchmentDomainProductsand the geographic cache manifest recordbuffer_rule,
buffer_declaredandbuffer_area_increase, so a domain says how its margin was drawn.- A MODFLOW 6 twin validation case for the stream-network criterion. A planar hillslope run at
a known K draws the mapped network, and a network-only bisection recovers that K within 1 per
cent, with J at zero and consistent K/R, dsat, T/R and Toptim in the report
(tests/validation/calibration/test_twin_matching_stream_network_modflow6.py, tolerances rows
76 to 79). observed_rasterizationon a network calibration output."crossing", the default, keeps a
cell where a mapped line crosses the segment joining two edge-sharing cell centres: on a grid
this is WhiteboxTools VectorLinesToRaster, the paper's tool, so a model that reproduces the map
scores J = 0."touch"replays sessions made before.line_crossing_cell_maskserves DIS,
DISV and Voronoi meshes. The redrawn comparison figures read the same rule, and each trial
publishesn_observed_cellsandn_observed_features_fallback.- Secondary network diagnostics, outside the cost:
D_so_over_D_osand the overlap indices of
the authors' published code (overlap_Ea,overlap_Sa,overlap_Na,overlap_E,
n_neither,L_sim_m,L_obs_m). - The calibration report records the Eq. 4 verdict of the returned trial (
roptim_verdict), the
final bracket of a bisection (bracket) and whether the search met its stopping rule
(search);hmp calibrateprints each on one line. The bisection warns at start when
max_iteris below what its bracket needs. hmp calibrate --checkwarns when an objective scored only on network outputs moves more
than one parameter, a T/R ridge. A network search that moves K is refused, at preflight and
before the first solve, next to an active SFR or LAK, whose conductance does not follow K.- The staged report and the Methods paragraph publish the steady window stage one averaged the
recharge over; a window shorter than 365 days warns. matching_hydrographic_networkdeclares six more departures: the outlet sealed into the
target of D_so, theL_capsaturation and its 5 % guard, the log10 K bisection and its sweep,
the support of D_os against the authors' published code,breachby default and the
rasterisation rule.- The aquifer geometry can be calibrated.
[calibration.parameters.thickness]searches the
thickness of aconstant_thicknessdepth model (log space) and
[calibration.parameters.substratum_elevation]the elevation of aflat_substratumone
(linear space);hmp config targetslists whichever the declared depth model carries. The
file states the bounds. A parameter that reaches a raster depth model, or a field the
declared kind does not expose, is refused and the error names the kind. - A stream-network trial publishes the paper's
dsatas<output>.d_sat_m:
the saturated thickness averaged by area over the catchment, at the state the
network is read from. Beside it,d_aquifer_m,d_sat_over_dand
d_sat_unset_fraction. A backend that serves no saturated thickness
publishes none of them and still scores the network. - A calibration whose one moved parameter is
flow.param.K.field.value,
written as a value and scored on a network output, reports the derived
values of Table 1 of Abherve et al. (2023):k_over_r,k_optim_m_s,
d_sat_m,t_over_r_mandt_optim_m2_s, printed on one line by
hmp calibrate. A search on any other parameter gets none of them. - A raster substratum: two depth models read the bottom of the aquifer from
the new[data.substratum]variable, one user raster in metres.
kind = "raster_substratum"takes its values as the substratum elevation,
the raster twin offlat_substratum;kind = "raster_thickness"subtracts
them from the top, the raster twin ofconstant_thickness, and takes a
scale. Both takeoffsetandmin_thickness. The raster is reprojected
onto the grid of the top and must cover every cell of the chosen extent (the
catchment fordomain_extent = "watershed", the buffered box for"box"),
or the run stops and counts the missing cells. Thedomain-buildprocess
takes it as asubstratuminput, the mask being the extent there. - The
data-requestprocess (hmp process run data-request --job DIR), the
job form ofhmp data get: the managers' cache lives under$TMPDIRwith an
in-memory index, acustomsource is refused before anything is written, a
variable that fails fails the job with its typed exit code, and the declared
hosts are those ofhydromodpy/schema/sources.py. A chain link fills a
nested member through a dotted path such asextent.mask. - The twelve v1 examples run in the current format, examples 06 to 11 included
(particle tracking, analytical recession, expo...
HydroModPy v1.0.0
First stable release of HydroModPy, and the version described in the technical
note submitted to Hydrology and Earth System Sciences
(EGUsphere preprint). This is the
reference cited by the paper. The v1.0 branch stays open for 1.0.X bug fixes
so the paper link always points to a working release, while feature development
continues on main as HydroModPy v2.
Install the maintained paper version with pip install "hydromodpy==1.0.*",
which resolves to the latest 1.0.X patch and never upgrades to the v2 series.
Added
- First PyPI release published from GitHub, with MODFLOW, MODPATH and MT3D-USGS binaries bundled in the wheel.
- Release pipeline on GitHub Actions: tag/version guard, build,
twine check --strict, PyPI Trusted Publishing (OIDC) and a GitHub release carrying the changelog notes. - Weekly cross-platform install and example smoke tests on Linux, Windows, macOS x86 and macOS arm, for Python 3.11 to 3.13.
- Multi-version documentation served at https://docs.hydromodpy.fr/v1.0/, rebuilt on every push to the
v1.0branch.
Changed
- Repository, issues and CI moved from GitLab to GitHub.
- Documentation moved from ReadTheDocs to GitHub Pages under the
docs.hydromodpy.frdomain. - README leads with the pip installation path; authors, affiliations and title aligned with the preprint.
- Upper pin on
numpy(<2.5) forpyshedscompatibility, anddaskadded for multi-file xarray merges. - Development status classifier raised to
5 - Production/Stable.
Fixed
- MODPATH particle flux is sampled with
rasterioinstead ofwhitebox. - Interactive matplotlib backend detected through
backend_registry. - Watershed object is rebuilt when the stored pickle cannot be read.
- Transport and PyHELP examples run headless, without user interaction.
Removed
- GitLab CI pipeline and ReadTheDocs configuration.
HydroModPy v0.3.4
Added
- Added
requirements-docker-light.txtfor pip-only Docker/server installs without IDE or visualization dependencies. - Added optional Dask handling in SIM2 (chunked xarray only when Dask is available).
Changed
- HydroModPy now loads display modules only when display features are invoked.
- Dockerfile updated for a light production flow using pip requirements.
Fixed
- Improved PROJ database detection and fallback (including rasterio data dirs) to reduce
proj.dblayout errors in containers.
Originally released on GitLab on: 2026-01-05
HydroModPy v0.3.2
Changed
- Reworked SIM2 workflow: coarse clip without reprojection to trim inputs, resample on that reduced dataset, then final clip/mask with reprojection for clean outputs without wasted time or RAM.
disk_clipnow accepts.shp,.gpkg, and.geojson, and SIM2 filename parsing keeps the full variable name before_SIM2_.
Fixed
toolbox.load_to_xarrayreprojects whendst_crsis provided even without a mask, matching the new SIM2 flow and avoiding extra memory use.- SIM2 resampling preserves encodings and applies masking with the reprojected DEM consistently.
Originally released on GitLab on: 2025-11-28
HydroModPy v0.3.1
Changed
- Installation guide reorganized with ready-made command recipes, dual YAML options (runtime vs editable), and clearer guidance for conda-versus-pip setups.
- README now flags v0.3.1 as the stable release and the conda YAMLs pin Python 3.11–3.13 explicitly.
- Add spyder package to the conda environment for users of that IDE.
Fixed
pyproject.tomlnow lets setuptools auto-discover allhydromodpy*packages sopip install hydromodpy(and ReadTheDocs builds) no longer fail if optional submodules such ashydromodpy.modeling.gr4jare absent from the current branch.- Pinned NumPy to >= 2.0 and restricted supported Python to >= 3.11, < 3.14 to avoid incompatibilities with other packages.
Originally released on GitLab on: 2025-11-14
HydroModPy v0.3.0
Added
- Logging system with a LogManager class. All print statements are replaced by structured logging.
- CI/CD pipeline on GitLab for automated build, test, and publication on PyPI.
- Single conda environment file that works on Linux, macOS, and Windows.
- Automatic download of HELP3O binaries during the first call. No Fortran compiler is needed.
- Packaging now includes executables, documentation, and example folders.
- PROJ data paths are now set explicitly to avoid loading an outdated
proj.dbfile. - The
pyhelpcommand line tool sets thePYHELP_WORKDIRvariable and supports aworkdirargument. This fixes the crash of Example 10 on Windows.
Changed
- Package renamed from
srctohydromodpy. All imports are updated. - GDAL is replaced by rasterio to allow installation with pip only.
- First release available with
pip install hydromodpy. - Conda installation is now based on a single environment file that uses only conda-forge packages.
- Examples 00 to 11 use the new
hydromodpyimports. - PyHELP now relies on prebuilt binaries instead of local Fortran compilation.
- Logging offers three modes: dev, verbose, and quiet.
- Deepdish serialization is replaced by pickle.
Removed
- Old and platform-specific environment files.
- All Fortran compilation steps for PyHELP.
- Unused FTP-AQUIFER scripts.
- Hard-coded references to GDAL.
- Legacy dependencies such as hydroeval and deepdish.
Fixed
- Consistent naming of example folders.
- Path handling now works on all supported systems.
- Suppression of noisy logs from external libraries such as matplotlib and flopy.
- PROJ data handling is stable in the PyHELP NetCDF writer.
- Extraction of HELP3O binaries works correctly on macOS.
Originally released on GitLab on: 2025-11-14
HydroModPy v0.2.0
Added
- Added MT3D-USGS support with the new transport modules, Example 09, and executables for Linux, macOS, and Windows.
- Added the GR4J rainfall–runoff calibration toolkit, the PyHELP land-surface coupling package with Example 10, Example 11 (headless workflow), the regression-test suite, yearly intermittency output, MT3D seepage concentration/mass, and OS-specific conda env files.
Changed
- Updated modflow/hydraulic handling to support elevation-based decay and the evapotranspiration extinction depth, refreshed modpath particle placement, expanded watershed_root with transport + calibration logic, improved timeseries input handling, and adjusted geographic/hydrography helpers.
Fixed
- Updated SIM2 climate variables/units (soil drought index now included) and restored the watershed visualization legend and color bar.
Originally released on GitLab on: 2025-11-05