Process Package (swimrs.process)¶
Daily soil water balance engine with typed dataclasses, Numba kernels, and HDF5 SwimInput built from .swim containers.
Loop and IO¶
run_daily_loop(swim_input: SwimInput, parameters: CalibrationParameters | None = None, properties: FieldProperties | None = None) -> tuple[DailyOutput, WaterBalanceState]
¶
Run the daily water balance simulation loop.
Parameters¶
swim_input : SwimInput Input data container (HDF5-backed) parameters : CalibrationParameters, optional Calibration parameters. If not provided, uses swim_input.parameters. properties : FieldProperties, optional Field properties. If not provided, uses swim_input.properties. Pass custom properties to use PEST++ calibrated values (awc, mad).
Returns¶
output : DailyOutput Daily output arrays final_state : WaterBalanceState Final state after simulation
step_day(state: WaterBalanceState, props: FieldProperties, params: CalibrationParameters, ndvi: NDArray[np.float64], etr: NDArray[np.float64], prcp: NDArray[np.float64], tmin: NDArray[np.float64], tmax: NDArray[np.float64], srad: NDArray[np.float64], irr_flag: NDArray[np.bool_], runoff_process: str = 'cn', prcp_hr: NDArray[np.float64] | None = None, f_sub: NDArray[np.float64] | None = None) -> dict[str, NDArray[np.float64]]
¶
Execute a single daily time step.
This function orchestrates all the physics kernels in the correct sequence for one day of simulation.
Parameters¶
state : WaterBalanceState Current state (modified in-place) props : FieldProperties Static field properties params : CalibrationParameters Calibration parameters ndvi : (n_fields,) NDVI values etr : (n_fields,) Reference ET (mm/day) prcp : (n_fields,) Precipitation (mm) tmin : (n_fields,) Minimum temperature (°C) tmax : (n_fields,) Maximum temperature (°C) srad : (n_fields,) Solar radiation (W/m²), daily mean downward shortwave radiation irr_flag : (n_fields,) Irrigation flag for this day runoff_process : str Runoff mode: 'cn' for Curve Number or 'ier' for infiltration-excess prcp_hr : (24, n_fields,), optional Hourly precipitation (mm/hr), required for IER mode f_sub : (n_fields,), optional Year-specific groundwater subsidy fraction. If provided, overrides props.f_sub for this time step.
Returns¶
dict Daily output values
DailyOutput
dataclass
¶
Container for daily output arrays.
All arrays have shape (n_days, n_fields).
Attributes¶
n_days : int Number of simulation days n_fields : int Number of fields eta : NDArray[np.float64] Actual ET (mm/day) etf : NDArray[np.float64] ET fraction (ETa/ETr) kcb : NDArray[np.float64] Basal crop coefficient ke : NDArray[np.float64] Evaporation coefficient ks : NDArray[np.float64] Water stress coefficient kr : NDArray[np.float64] Evaporation reduction coefficient runoff : NDArray[np.float64] Surface runoff (mm) rain : NDArray[np.float64] Liquid precipitation (mm) melt : NDArray[np.float64] Snowmelt (mm) swe : NDArray[np.float64] Snow water equivalent (mm) depl_root : NDArray[np.float64] Root zone depletion (mm) dperc : NDArray[np.float64] Deep percolation (mm) irr_sim : NDArray[np.float64] Simulated irrigation (mm) gw_sim : NDArray[np.float64] Groundwater subsidy (mm) et_irr : NDArray[np.float64] ET from irrigation water (mm) - consumptive use dperc_irr : NDArray[np.float64] Deep percolation of irrigation water (mm) - return flow irr_frac_root : NDArray[np.float64] Irrigation fraction in root zone [0, 1] irr_frac_l3 : NDArray[np.float64] Irrigation fraction in layer 3 [0, 1]
n_days: int
instance-attribute
¶
n_fields: int
instance-attribute
¶
eta: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
etf: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
kcb: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ke: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ks: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
kr: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
runoff: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
rain: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
melt: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
swe: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
depl_root: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
dperc: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_sim: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
gw_sim: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
et_irr: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
dperc_irr: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_frac_root: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_frac_l3: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
__post_init__()
¶
Initialize output arrays.
__init__(n_days: int, n_fields: int, eta: NDArray[np.float64] = None, etf: NDArray[np.float64] = None, kcb: NDArray[np.float64] = None, ke: NDArray[np.float64] = None, ks: NDArray[np.float64] = None, kr: NDArray[np.float64] = None, runoff: NDArray[np.float64] = None, rain: NDArray[np.float64] = None, melt: NDArray[np.float64] = None, swe: NDArray[np.float64] = None, depl_root: NDArray[np.float64] = None, dperc: NDArray[np.float64] = None, irr_sim: NDArray[np.float64] = None, gw_sim: NDArray[np.float64] = None, et_irr: NDArray[np.float64] = None, dperc_irr: NDArray[np.float64] = None, irr_frac_root: NDArray[np.float64] = None, irr_frac_l3: NDArray[np.float64] = None) -> None
¶
SwimInput(h5_path: Path, start_date: datetime = None, end_date: datetime = None, n_days: int = 0, n_fields: int = 0, fids: list = list(), runoff_process: str = 'cn', refet_type: str = 'eto', properties: FieldProperties = None, parameters: CalibrationParameters = None, spinup_state: WaterBalanceState = None, _h5_file: h5py.File = None, _gwsub_years: dict = dict())
dataclass
¶
HDF5-backed input data container for soil water balance modeling.
This container provides all data needed for a SWIM-RS simulation run. It can be built from JSON input files and saved to HDF5 for distribution to PEST++ workers, or loaded directly from HDF5.
Attributes¶
h5_path : Path Path to the HDF5 file start_date : datetime Simulation start date end_date : datetime Simulation end date n_days : int Number of simulation days n_fields : int Number of fields/pixels fids : list[str] Field identifiers runoff_process : str Runoff mode ('cn' Curve Number or 'ier' infiltration-excess) refet_type : str Reference ET type ('eto' or 'etr') properties : FieldProperties Static field properties parameters : CalibrationParameters Calibration parameters (base values) spinup_state : WaterBalanceState Initial state from spinup
Example¶
Build from container and access data:
>>> from swimrs.container import SwimContainer
>>> from swimrs.process.input import build_swim_input, SwimInput
>>>
>>> # Build HDF5 from container
>>> container = SwimContainer.open("project.swim")
>>> swim_input = build_swim_input(container, output_h5="input.h5")
>>>
>>> # Access data
>>> print(f"Fields: {swim_input.n_fields}, Days: {swim_input.n_days}")
>>> ndvi = swim_input.get_time_series("ndvi", day_idx=0)
>>> swim_input.close()
h5_path: Path
instance-attribute
¶
start_date: datetime = field(default=None)
class-attribute
instance-attribute
¶
end_date: datetime = field(default=None)
class-attribute
instance-attribute
¶
n_days: int = field(default=0)
class-attribute
instance-attribute
¶
n_fields: int = field(default=0)
class-attribute
instance-attribute
¶
fids: list = field(default_factory=list)
class-attribute
instance-attribute
¶
runoff_process: str = field(default='cn')
class-attribute
instance-attribute
¶
refet_type: str = field(default='eto')
class-attribute
instance-attribute
¶
properties: FieldProperties = field(default=None)
class-attribute
instance-attribute
¶
parameters: CalibrationParameters = field(default=None)
class-attribute
instance-attribute
¶
spinup_state: WaterBalanceState = field(default=None)
class-attribute
instance-attribute
¶
_h5_file: h5py.File = field(default=None, repr=False)
class-attribute
instance-attribute
¶
_gwsub_years: dict = field(default_factory=dict, repr=False)
class-attribute
instance-attribute
¶
__post_init__()
¶
Open HDF5 file and load metadata if path exists.
_load_from_h5()
¶
Load metadata and static arrays from HDF5.
_load_gwsub_years(h5: h5py.File) -> dict[int, NDArray[np.float64]]
¶
Load year-specific f_sub data from HDF5.
Returns¶
dict[int, NDArray[np.float64]] Mapping of year -> f_sub array (n_fields,)
_load_properties(h5: h5py.File) -> FieldProperties
¶
Load field properties from HDF5.
_load_parameters(h5: h5py.File) -> CalibrationParameters
¶
Load calibration parameters from HDF5.
_load_spinup(h5: h5py.File) -> WaterBalanceState
¶
Load spinup state from HDF5.
close()
¶
Close the HDF5 file.
__enter__()
¶
__exit__(exc_type, exc_val, exc_tb)
¶
get_time_series(variable: str, day_idx: int | None = None) -> NDArray[np.float64]
¶
Get time series data for a variable.
Parameters¶
variable : str Variable name (e.g., 'ndvi', 'prcp', 'tmin', 'tmax', 'srad', 'ref_et', 'etr', 'eto'). Note: 'etr'/'eto' are aliases for 'ref_et' in newer HDF5 files, and 'ref_et' is an alias for 'etr'/'eto' in older files. day_idx : int, optional If provided, return only data for this day index. Otherwise return full time series (n_days, n_fields).
Returns¶
NDArray[np.float64] Time series data. Shape (n_fields,) if day_idx provided, otherwise (n_days, n_fields).
get_irr_flag(day_idx: int | None = None) -> NDArray[np.bool_]
¶
has_hourly_precip() -> bool
¶
Check if hourly precipitation data is available.
Returns¶
bool True if prcp_hr dataset exists in time_series group
get_hourly_precip(day_idx: int) -> NDArray[np.float64] | None
¶
get_date(day_idx: int) -> datetime
¶
Get date for a given day index.
get_day_idx(date: datetime) -> int
¶
Get day index for a given date.
get_f_sub_for_year(year: int) -> NDArray[np.float64]
¶
has_year_specific_gwsub() -> bool
¶
Check if year-specific groundwater subsidy data is available.
apply_multipliers(mult_dir: Path | str) -> CalibrationParameters
¶
build_swim_input(container: SwimContainer, output_h5: Path | str, spinup_state: dict[str, NDArray[np.float64]] | None = None, spinup_json_path: Path | str | None = None, calibrated_params_path: Path | str | None = None, start_date: str | datetime | None = None, end_date: str | datetime | None = None, runoff_process: str = 'cn', refet_type: str = 'eto', etf_model: str = 'ssebop', met_source: str = 'gridmet', fields: list[str] | None = None, empirical_kc_max: bool = False) -> SwimInput
¶
Build HDF5 input file from SwimContainer.
Parameters¶
container : SwimContainer SwimContainer instance with ingested data output_h5 : Path | str Path for output HDF5 file spinup_state : dict, optional Dictionary with spinup arrays: depl_root, swe, kr, ks, zr. If not provided, uses default initialization. spinup_json_path : Path | str, optional Path to spinup JSON file (like old model's spinup.json). Takes precedence over spinup_state if both provided. calibrated_params_path : Path | str, optional Path to JSON file with calibrated parameters per field. Format: {fid: {param_name: value, ...}, ...} start_date : str | datetime, optional Override start date (default: from container) end_date : str | datetime, optional Override end date (default: from container) runoff_process : str Runoff mode: 'cn' (curve number) or 'ier' (infiltration excess) refet_type : str Reference ET type to use from the container: 'eto' (grass) or 'etr' (alfalfa). This is typically configured in the project TOML and passed through the CLI. etf_model : str ET fraction model (e.g., 'ssebop', 'ptjpl') met_source : str Meteorology source (e.g., 'gridmet', 'era5') fields : list[str], optional List of field UIDs to include (default: all fields in container) empirical_kc_max : bool If True, use empirical kc_max from container (90th percentile ETf). If False (default), use fixed FAO-56 value of 1.2.
Returns¶
SwimInput Loaded SwimInput container
Example¶
>>> from swimrs.container import SwimContainer
>>> from swimrs.process.input import build_swim_input
>>>
>>> container = SwimContainer.open("project.swim")
>>> swim_input = build_swim_input(
... container=container,
... output_h5="swim_input.h5",
... )
>>> print(f"Fields: {swim_input.n_fields}, Days: {swim_input.n_days}")
State containers¶
WaterBalanceState(n_fields: int, depl_root: NDArray[np.float64] = None, depl_ze: NDArray[np.float64] = None, daw3: NDArray[np.float64] = None, taw3: NDArray[np.float64] = None, swe: NDArray[np.float64] = None, albedo: NDArray[np.float64] = None, zr: NDArray[np.float64] = None, kr: NDArray[np.float64] = None, ks: NDArray[np.float64] = None, irr_continue: NDArray[np.float64] = None, next_day_irr: NDArray[np.float64] = None, s: NDArray[np.float64] = None, s1: NDArray[np.float64] = None, s2: NDArray[np.float64] = None, s3: NDArray[np.float64] = None, s4: NDArray[np.float64] = None, irr_frac_root: NDArray[np.float64] = None, irr_frac_l3: NDArray[np.float64] = None)
dataclass
¶
Mutable state arrays for daily water balance computation.
All arrays have shape (n_fields,). State is updated in-place during the daily step loop.
Attributes¶
n_fields : int Number of fields/pixels being modeled depl_root : NDArray[np.float64] Root zone depletion (mm), 0 = field capacity depl_ze : NDArray[np.float64] Surface layer depletion (mm) for evaporation daw3 : NDArray[np.float64] Available water in layer 3 below root zone (mm) taw3 : NDArray[np.float64] Total available water capacity in layer 3 (mm) swe : NDArray[np.float64] Snow water equivalent (mm) albedo : NDArray[np.float64] Snow albedo (dimensionless, 0-1) zr : NDArray[np.float64] Current root depth (m) kr : NDArray[np.float64] Evaporation reduction coefficient (damped) ks : NDArray[np.float64] Water stress coefficient (damped) irr_continue : NDArray[np.float64] Irrigation continuation flag (1.0 if continuing from previous day) next_day_irr : NDArray[np.float64] Carryover irrigation amount for next day (mm) s : NDArray[np.float64] Current day S retention parameter (mm) for CN runoff s1, s2, s3, s4 : NDArray[np.float64] S history from 1-4 days ago (mm), used for smoothed runoff on irrigated fields irr_frac_root : NDArray[np.float64] Fraction of root zone water that originated from irrigation [0, 1]. Used for consumptive use accounting. irr_frac_l3 : NDArray[np.float64] Fraction of layer 3 water that originated from irrigation [0, 1]. Used for deep percolation accounting.
n_fields: int
instance-attribute
¶
depl_root: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
depl_ze: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
daw3: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
taw3: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
swe: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
albedo: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
zr: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
kr: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ks: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_continue: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
next_day_irr: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
s: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
s1: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
s2: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
s3: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
s4: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_frac_root: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_frac_l3: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
__post_init__()
¶
Initialize arrays with zeros if not provided.
from_spinup(n_fields: int, depl_root: NDArray[np.float64], swe: NDArray[np.float64], kr: NDArray[np.float64], ks: NDArray[np.float64], zr: NDArray[np.float64], daw3: NDArray[np.float64] | None = None, taw3: NDArray[np.float64] | None = None, depl_ze: NDArray[np.float64] | None = None, albedo: NDArray[np.float64] | None = None, s: NDArray[np.float64] | None = None, s1: NDArray[np.float64] | None = None, s2: NDArray[np.float64] | None = None, s3: NDArray[np.float64] | None = None, s4: NDArray[np.float64] | None = None, irr_frac_root: NDArray[np.float64] | None = None, irr_frac_l3: NDArray[np.float64] | None = None, irr_status: NDArray[np.bool_] | None = None) -> WaterBalanceState
classmethod
¶
Create state from spinup values.
Parameters¶
n_fields : int Number of fields depl_root : NDArray[np.float64] Initial root zone depletion (mm) swe : NDArray[np.float64] Initial snow water equivalent (mm) kr : NDArray[np.float64] Initial evaporation reduction coefficient ks : NDArray[np.float64] Initial water stress coefficient zr : NDArray[np.float64] Initial root depth (m) daw3 : NDArray[np.float64], optional Initial layer 3 available water (mm) taw3 : NDArray[np.float64], optional Initial layer 3 total capacity (mm) depl_ze : NDArray[np.float64], optional Initial surface layer depletion (mm) albedo : NDArray[np.float64], optional Initial snow albedo s : NDArray[np.float64], optional Current S retention (mm) s1, s2, s3, s4 : NDArray[np.float64], optional S history from 1-4 days ago (mm) irr_frac_root : NDArray[np.float64], optional Irrigation fraction in root zone [0, 1]. If not provided, initialized based on irr_status (0.5 if irrigated, 0.0 if not). irr_frac_l3 : NDArray[np.float64], optional Irrigation fraction in layer 3 [0, 1]. If not provided, initialized based on irr_status (0.5 if irrigated, 0.0 if not). irr_status : NDArray[np.bool_], optional Whether each field is irrigated. Used to initialize irrigation fractions when they are not provided in spinup data.
Returns¶
WaterBalanceState Initialized state container
copy() -> WaterBalanceState
¶
Create a deep copy of the state.
FieldProperties(n_fields: int, fids: NDArray = None, awc: NDArray[np.float64] = None, ksat: NDArray[np.float64] = None, rew: NDArray[np.float64] = None, tew: NDArray[np.float64] = None, cn2: NDArray[np.float64] = None, zr_max: NDArray[np.float64] = None, zr_min: NDArray[np.float64] = None, mad: NDArray[np.float64] = None, irr_status: NDArray[np.bool_] = None, perennial: NDArray[np.bool_] = None, gw_status: NDArray[np.bool_] = None, ke_max: NDArray[np.float64] = None, kc_max: NDArray[np.float64] = None, f_sub: NDArray[np.float64] = None, ndvi_bare: NDArray[np.float64] = None, ndvi_full: NDArray[np.float64] = None)
dataclass
¶
Static soil and crop properties for each field.
All arrays have shape (n_fields,). These properties are read from the HDF5 input file and do not change during simulation.
Attributes¶
n_fields : int Number of fields/pixels fids : NDArray Field identifiers (string or int) awc : NDArray[np.float64] Available water capacity (mm/m) ksat : NDArray[np.float64] Saturated hydraulic conductivity (mm/day).
This is converted to an hourly infiltration capacity (mm/hr) when
running infiltration-excess runoff (IER) using hourly precipitation.
rew : NDArray[np.float64] Readily evaporable water (mm) tew : NDArray[np.float64] Total evaporable water (mm) cn2 : NDArray[np.float64] Curve number for average antecedent moisture (AMC II) zr_max : NDArray[np.float64] Maximum root depth (m) zr_min : NDArray[np.float64] Minimum root depth (m) mad : NDArray[np.float64] Depletion fraction for stress onset irr_status : NDArray[np.bool_] Whether field is irrigated perennial : NDArray[np.bool_] Whether crop is perennial (affects root dynamics) gw_status : NDArray[np.bool_] Whether groundwater subsidy is available ke_max : NDArray[np.float64] Maximum soil evaporation coefficient, derived from ETf observations where NDVI < 0.3 (90th percentile of bare soil ETf) kc_max : NDArray[np.float64] Maximum crop coefficient, derived from ETf observations (90th percentile of all ETf values) f_sub : NDArray[np.float64] Groundwater subsidy fraction (0-1), derived from ETa/PPT ratio where f_sub = (ratio - 1) / ratio when ratio > 1 ndvi_bare : NDArray[np.float64] NDVI value representing bare/dormant soil conditions, used for computing fractional cover directly from NDVI. Typically the 5th percentile of the site's NDVI record. Default: 0.15. ndvi_full : NDArray[np.float64] NDVI value representing full vegetation cover, used for computing fractional cover directly from NDVI. Typically the 95th percentile of the site's NDVI record. Default: 0.85.
n_fields: int
instance-attribute
¶
fids: NDArray = field(default=None)
class-attribute
instance-attribute
¶
awc: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ksat: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
rew: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
tew: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
cn2: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
zr_max: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
zr_min: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
mad: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
irr_status: NDArray[np.bool_] = field(default=None)
class-attribute
instance-attribute
¶
perennial: NDArray[np.bool_] = field(default=None)
class-attribute
instance-attribute
¶
gw_status: NDArray[np.bool_] = field(default=None)
class-attribute
instance-attribute
¶
ke_max: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
kc_max: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
f_sub: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ndvi_bare: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ndvi_full: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
__post_init__()
¶
Initialize arrays with reasonable defaults if not provided.
compute_taw(zr: NDArray[np.float64]) -> NDArray[np.float64]
¶
CalibrationParameters(n_fields: int, kc_min: NDArray[np.float64] = None, ndvi_k: NDArray[np.float64] = None, ndvi_0: NDArray[np.float64] = None, swe_alpha: NDArray[np.float64] = None, swe_beta: NDArray[np.float64] = None, kr_damp: NDArray[np.float64] = None, ks_damp: NDArray[np.float64] = None, max_irr_rate: NDArray[np.float64] = None)
dataclass
¶
Parameters that can be modified by PEST++ multipliers.
All arrays have shape (n_fields,). These are the calibration parameters that PEST++ adjusts via multiplier files.
Attributes¶
n_fields : int Number of fields/pixels kc_min : NDArray[np.float64] Minimum crop coefficient (bare soil) ndvi_k : NDArray[np.float64] Sigmoid steepness parameter for Kcb ndvi_0 : NDArray[np.float64] Sigmoid midpoint (inflection) NDVI swe_alpha : NDArray[np.float64] Snow melt radiation coefficient swe_beta : NDArray[np.float64] Snow melt degree-day coefficient kr_damp : NDArray[np.float64] Kr damping factor (0-1) ks_damp : NDArray[np.float64] Ks damping factor (0-1) max_irr_rate : NDArray[np.float64] Maximum daily irrigation rate (mm/day)
n_fields: int
instance-attribute
¶
kc_min: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ndvi_k: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ndvi_0: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
swe_alpha: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
swe_beta: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
kr_damp: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
ks_damp: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
max_irr_rate: NDArray[np.float64] = field(default=None)
class-attribute
instance-attribute
¶
__post_init__()
¶
Initialize arrays with default values if not provided.
from_base_with_multipliers(base: CalibrationParameters, multipliers: dict[str, NDArray[np.float64]]) -> CalibrationParameters
classmethod
¶
copy() -> CalibrationParameters
¶
Create a deep copy of the parameters.
from_pest_mult(mult_dir: str, fids: list[str], base: CalibrationParameters | None = None) -> CalibrationParameters
classmethod
¶
Load parameters from PEST++ multiplier CSV files.
PEST++ writes parameter multiplier files in the format: mult/p_{param}_{fid}_0_constant.csv
The CSV has a header row and the value is in the last column ('1').
Parameters¶
mult_dir : str Path to the mult/ directory containing CSV files fids : list[str] Field IDs in simulation order base : CalibrationParameters, optional Base parameters to start from. If None, uses defaults.
Returns¶
CalibrationParameters Parameters loaded from mult files