pycsamt.interp.constraints#

Field-measurement constraints for petrophysical calibration.

Hydrogeological field measurements — piezometer levels, pumping-test transmissivity, slug-test K, and EC logs — can be used to anchor the petrophysical parameters (ρ_w, Archie m/n, porosity prior) that drive the quantitative EMHydroModel.

ConstrainedCalibrator accepts a list of constraint objects and optimises one or more parameters of a PetrophysicalConfig to minimise the weighted least-squares misfit between model-predicted hydrogeological quantities and the observations.

EM method relevance#

  • TDEM — water-level constraints from piezometers are the most direct. rho_w is the primary free parameter (calibrated from well EC or TDS).

  • AMT — pumping-test T constraints calibrate porosity_prior + rho_w jointly; fracture aperture is not fitted here but can be set manually.

  • MT — EC constraints from deep formation waters calibrate rho_w for basin-scale aquifer studies.

  • EMAP — EC logs along the profile calibrate rho_w laterally.

Typical use#

>>> from pycsamt.interp.constraints import (
...     ConstrainedCalibrator,
...     WaterLevelConstraint,
...     PumpingTestConstraint,
... )
>>> from pycsamt.interp.hydromodel import EMHydroModel, PetrophysicalConfig
>>>
>>> cal = ConstrainedCalibrator(
...     constraints=[
...         WaterLevelConstraint(x=500.0,  depth_m=18.5),
...         WaterLevelConstraint(x=1200.0, depth_m=22.0),
...         PumpingTestConstraint(x=800.0, T_m2s=1.2e-3),
...     ],
...     calibrate_rho_w=True,
...     calibrate_phi_prior=True,
... )
>>> model   = EMHydroModel(rm, PetrophysicalConfig())
>>> result  = cal.fit(model)      # returns calibrated EMHydroResult
>>> print(cal.calibrated_config_) # fitted PetrophysicalConfig
>>> print(cal.misfit_history_)    # optimiser convergence

References

Classes

ConstrainedCalibrator(constraints, *[, ...])

Calibrate petrophysical parameters to match hydrogeological field data.

ECConstraint(x, ec_mscm[, uncertainty_mscm, ...])

Electrical conductivity of formation water (e.g., from an EC log or sample).

PumpingTestConstraint(x, T_m2s[, S, ...])

Transmissivity (and optionally storativity) from a pumping test.

SlugTestConstraint(x, K_ms, depth_m[, ...])

Hydraulic conductivity K from a slug test or bail test.

WaterLevelConstraint(x, depth_m[, ...])

Piezometer or well water-level measurement.

class pycsamt.interp.constraints.WaterLevelConstraint(x, depth_m, uncertainty_m=1.0, station='')[source]#

Bases: PyCSAMTObject

Piezometer or well water-level measurement.

The calibrator matches the EM-derived water-table depth at the nearest model column to the observed depth.

Parameters:
  • x (float) – Profile position of the measurement (m, same reference as the model).

  • depth_m (float) – Observed water-table depth below surface (m, positive downward).

  • uncertainty_m (float) – Measurement + representativeness uncertainty (m; default 1.0 m).

  • station (str) – Optional label for reporting.

x: float#
depth_m: float#
uncertainty_m: float = 1.0#
station: str = ''#
class pycsamt.interp.constraints.PumpingTestConstraint(x, T_m2s, S=None, uncertainty_factor=3.0, station='')[source]#

Bases: PyCSAMTObject

Transmissivity (and optionally storativity) from a pumping test.

Misfit is computed in log₁₀ space because T spans orders of magnitude.

Parameters:
  • x (float) – Profile position of the pumping well (m).

  • T_m2s (float) – Observed transmissivity (m²/s).

  • S (float, optional) – Observed storativity (dimensionless). Currently used for reporting only; storativity calibration will be added in a future release.

  • uncertainty_factor (float) – Multiplicative uncertainty on T (default 3 → ±0.5 in log₁₀).

  • station (str) – Optional label.

x: float#
T_m2s: float#
S: float | None = None#
uncertainty_factor: float = 3.0#
station: str = ''#
class pycsamt.interp.constraints.SlugTestConstraint(x, K_ms, depth_m, uncertainty_factor=5.0, station='')[source]#

Bases: PyCSAMTObject

Hydraulic conductivity K from a slug test or bail test.

Matches the model K at the nearest cell to (x, depth_m).

Parameters:
  • x (float) – Profile position (m).

  • K_ms (float) – Observed K (m/s).

  • depth_m (float) – Depth of the tested interval mid-point (m).

  • uncertainty_factor (float) – Multiplicative uncertainty (default 5 → ~0.7 in log₁₀).

  • station (str) – Optional label.

x: float#
K_ms: float#
depth_m: float#
uncertainty_factor: float = 5.0#
station: str = ''#
class pycsamt.interp.constraints.ECConstraint(x, ec_mscm, uncertainty_mscm=2.0, station='')[source]#

Bases: PyCSAMTObject

Electrical conductivity of formation water (e.g., from an EC log or sample).

Directly constrains rho_w via the EC ↔ ρ_w conversion.

Parameters:
  • x (float) – Profile position (m).

  • ec_mscm (float) – Observed pore-water EC (mS/cm; ≈ 1 mS/cm for fresh water at 25 °C).

  • uncertainty_mscm (float) – Measurement uncertainty (mS/cm; default 2.0).

  • station (str) – Optional label.

x: float#
ec_mscm: float#
uncertainty_mscm: float = 2.0#
station: str = ''#
class pycsamt.interp.constraints.ConstrainedCalibrator(constraints, *, calibrate_rho_w=True, calibrate_m=False, calibrate_phi_prior=False, rho_w_bounds=(0.003, 2.0), m_bounds=(1.2, 2.8), phi_bounds=(0.03, 0.6), n_restarts=1, verbose=False)[source]#

Bases: PyCSAMTObject

Calibrate petrophysical parameters to match hydrogeological field data.

Uses scipy.optimize.minimize (L-BFGS-B) to find the parameter set that minimises the weighted sum of squared residuals between the EM-derived hydrogeological quantities and the supplied observations.

The optimisation is deterministic (single run from the current parameter values). If convergence is poor, set n_restarts > 1 to try multiple random starting points within the parameter bounds.

Parameters:
  • constraints (sequence of constraint objects) – Any mix of WaterLevelConstraint, PumpingTestConstraint, SlugTestConstraint, ECConstraint.

  • calibrate_rho_w (bool) – Fit pore-water resistivity ρ_w (default True). Almost always needed.

  • calibrate_m (bool) – Fit Archie cementation exponent m (default False).

  • calibrate_phi_prior (bool) – Fit prior porosity (default False).

  • rho_w_bounds ((float, float)) – Search bounds for ρ_w in Ω·m (default 0.003 – 2.0).

  • m_bounds ((float, float)) – Search bounds for Archie m (default 1.2 – 2.8).

  • phi_bounds ((float, float)) – Search bounds for porosity prior (default 0.03 – 0.60).

  • n_restarts (int) – Number of optimisation restarts with random initialisations (default 1).

  • verbose (bool) – Print iteration count and final misfit (default False).

:param Attributes (set after fit()): :param ———————————–: :param calibrated_config_: The fitted configuration. :type calibrated_config_: PetrophysicalConfig :param misfit_history_: Final misfit value per restart. :type misfit_history_: list of float :param opt_result_: Raw scipy result from the best restart. :type opt_result_: OptimizeResult or None

calibrated_config_: PetrophysicalConfig | None#
misfit_history_: list[float]#
opt_result_: Any#
fit(em_hydro_model)[source]#

Calibrate and return the best EMHydroResult.

Parameters:

em_hydro_model (EMHydroModel) – The model to calibrate. Its config provides the starting point for the optimisation.

Returns:

Model result evaluated at the calibrated parameters.

Return type:

EMHydroResult

constraint_residuals(result)[source]#

Return per-constraint residuals for the given result (for diagnostics).

Parameters:

result (EMHydroResult)

Return type:

list[dict]