pycsamt.interp.hydromodel#

Quantitative hydro-geophysical model from EM resistivity sections.

Converts a 2-D ResistivityModel (from TDEM, AMT, MT, or EMAP inversion) into quantitative hydrogeological deliverables:

  • Porosity and water-saturation maps (n_z × n_x)

  • Hydraulic conductivity map via Archie → Kozeny-Carman, or cubic-law for fractured basement (AMT targets)

  • Water-table depth per station column

  • Transmissivity and storativity profiles

  • Dar-Zarrouk parameters (transverse resistance TR, longitudinal conductance S)

  • TDS indicator from pore-water resistivity

The main entry point is EMHydroModel which wraps the transforms already implemented in pycsamt.interp.petrophysics. The workflow is intentionally deterministic (single best-estimate); uncertainty propagation will be added in a later phase.

Typical use#

>>> from pycsamt.interp import ResistivityModel
>>> from pycsamt.interp.petrophysics import ArchieModel
>>> from pycsamt.interp.hydromodel import EMHydroModel, PetrophysicalConfig
>>>
>>> cfg = PetrophysicalConfig(
...     petro=ArchieModel(m=1.8, n=2.0),
...     rho_w=0.025,
...     porosity_prior=0.25,
... )
>>> result = EMHydroModel(resistivity_model=rm, config=cfg).fit()
>>> print(result.water_table)        # (n_x,) depth in metres
>>> print(result.transmissivity)     # (n_x,) m²/s

References

Classes

EMHydroModel(resistivity_model[, config, ...])

Quantitative hydrogeological model from an EM resistivity section.

EMHydroResult(resistivity_model, config, ...)

Quantitative hydrogeological output of one EM resistivity section.

PetrophysicalConfig([petro, rho_w, ...])

All petrophysical and hydraulic parameters needed by EMHydroModel.

class pycsamt.interp.hydromodel.PetrophysicalConfig(petro=<factory>, rho_w=20.0, porosity_prior=0.25, Sw_water_table_threshold=0.85, d50_m=0.00025, kozeny_C=180.0, kozeny_tortuosity=0.5, fracture_depth_m=None, fracture_rho_matrix=5000.0, specific_storage=0.0001, min_wt_search_depth=0.5)[source]#

Bases: PyCSAMTObject

All petrophysical and hydraulic parameters needed by EMHydroModel.

Parameters:
  • petro (ArchieModel or WaxmanSmitsModel) – Petrophysical model for ρ ↔ (φ, Sw) transforms. Default is ArchieModel(m=1.8, n=2.0) — appropriate for clean sands targeted by shallow TDEM and AMT surveys.

  • rho_w (float) – Pore-water resistivity (Ω·m). Default 20 Ω·m (EC ≈ 0.5 mS/cm, potable fresh water at 25 °C; range: 0.2 Ω·m seawater – 100+ Ω·m pristine groundwater). Constrained by water-quality measurements or EC logs via pycsamt.interp.constraints.

  • porosity_prior (float) – Reference porosity used in the vadose zone and as an upper-clip for unrealistic Archie-inferred porosities (default 0.25).

  • Sw_water_table_threshold (float) – Saturation value that marks the water table in the Archie inverse (default 0.85; lower it for coarser-grained aquifers).

  • d50_m (float) – Median grain size (m) for Kozeny-Carman K (default 2.5 × 10⁻⁴ m, fine sand). Increase to ~1 × 10⁻³ m for coarse sand/gravel.

  • kozeny_C (float) – Kozeny constant × shape factor (default 180 for spheres).

  • kozeny_tortuosity (float) – Tortuosity correction in Kozeny-Carman (default 0.5).

  • fracture_depth_m (float or None) – Depth (m) below which fractured_zone_K() replaces Kozeny-Carman. Use for AMT/MT basement targets. None disables fracture K everywhere (default: None).

  • fracture_rho_matrix (float) – Background resistivity of intact rock for the cubic-law fracture K (Ω·m; default 5 000).

  • specific_storage (float) – Specific storage Ss (m⁻¹) for confined storativity (default 10⁻⁴).

  • min_wt_search_depth (float) – Minimum depth (m) for water-table detection; skips near-surface noise (default 0.5 m).

petro: ArchieModel | WaxmanSmitsModel#
rho_w: float = 20.0#
porosity_prior: float = 0.25#
Sw_water_table_threshold: float = 0.85#
d50_m: float = 0.00025#
kozeny_C: float = 180.0#
kozeny_tortuosity: float = 0.5#
fracture_depth_m: float | None = None#
fracture_rho_matrix: float = 5000.0#
specific_storage: float = 0.0001#
min_wt_search_depth: float = 0.5#
class pycsamt.interp.hydromodel.EMHydroResult(resistivity_model, config, porosity, saturation, hydraulic_K, water_table, transmissivity, storativity_confined, storativity_unconfined, dar_zarrouk_TR, dar_zarrouk_S, tds, method_tag='', metadata=<factory>)[source]#

Bases: PyCSAMTObject

Quantitative hydrogeological output of one EM resistivity section.

All 2-D arrays have shape (n_z, n_x) matching the source ResistivityModel; 1-D station arrays have shape (n_x,).

Variables:
  • resistivity_model (ResistivityModel)

  • config (PetrophysicalConfig)

  • porosity (ndarray (n_z, n_x)) – Effective porosity per cell (dimensionless, 0–1). Below the water table: Archie inverse at Sw = 1. Above the water table: config.porosity_prior.

  • saturation (ndarray (n_z, n_x)) – Water saturation Sw per cell (0–1). Below the water table: 1.0. Above the water table: Archie inverse at φ = porosity_prior.

  • hydraulic_K (ndarray (n_z, n_x)) – Hydraulic conductivity K (m/s). Porous media (z < fracture_depth_m): Kozeny-Carman from φ. Fractured basement (z ≥ fracture_depth_m): cubic-law from ρ contrast.

  • water_table (ndarray (n_x,)) – Estimated water-table depth (m, positive downward). nan where detection failed (resistivity column shows no saturation transition above the Sw threshold).

  • transmissivity (ndarray (n_x,)) – Aquifer transmissivity T = ∫K dz over the saturated zone (m²/s).

  • storativity_confined (ndarray (n_x,)) – Confined storativity S = Ss × b_sat (dimensionless).

  • storativity_unconfined (ndarray (n_x,)) – Unconfined storativity ≈ mean porosity in saturated zone (≈ specific yield).

  • dar_zarrouk_TR (ndarray (n_x,)) – Transverse resistance TR = Σ ρᵢ hᵢ (Ω·m²) over all cells.

  • dar_zarrouk_S (ndarray (n_x,)) – Longitudinal conductance S = Σ hᵢ/ρᵢ (siemens) over all cells.

  • tds (float) – Estimated total dissolved solids (mg/L) from config.rho_w.

  • method_tag (str) – Source EM method label (e.g. 'TDEM', 'AMT').

  • metadata (dict) – Provenance and parameter snapshot.

Parameters:
resistivity_model: ResistivityModel#
config: PetrophysicalConfig#
porosity: ndarray#
saturation: ndarray#
hydraulic_K: ndarray#
water_table: ndarray#
transmissivity: ndarray#
storativity_confined: ndarray#
storativity_unconfined: ndarray#
dar_zarrouk_TR: ndarray#
dar_zarrouk_S: ndarray#
tds: float#
method_tag: str = ''#
metadata: dict#
station_report()[source]#

Return one dict per model column with key hydro indicators.

Return type:

list[dict]

to_csv(path)[source]#

Write cell-level hydro parameters to a flat CSV file.

Parameters:

path (str | Path)

Return type:

Path

station_report_csv(path)[source]#

Write per-station hydro summary to CSV.

Parameters:

path (str | Path)

Return type:

Path

to_dataframe()[source]#

Return station summary as a pandas.DataFrame (requires pandas).

Return type:

Any

class pycsamt.interp.hydromodel.EMHydroModel(resistivity_model, config=None, *, petro=None, rho_w=None, porosity_prior=None, method_tag='')[source]#

Bases: PyCSAMTObject

Quantitative hydrogeological model from an EM resistivity section.

Wires the petrophysical transforms in pycsamt.interp.petrophysics onto a full 2-D ResistivityModel to produce spatially continuous porosity, saturation, hydraulic-conductivity, and water-table maps.

The computation follows a two-pass strategy to break the Archie chicken-and-egg (φ needs Sw, Sw needs φ):

  1. Water-table pass — scan each column with the Archie-inverse Sw estimator to find the saturation front (Sw ≥ threshold).

  2. Cell-property pass — for cells below the water table assume full saturation (Sw = 1) and solve for φ; for cells above use porosity_prior and solve for Sw.

Parameters:
  • resistivity_model (ResistivityModel) – Source inversion model.

  • config (PetrophysicalConfig, optional) – Full parameter bundle. If None, default parameters are used. Individual keyword arguments below override specific fields.

  • petro (ArchieModel or WaxmanSmitsModel, optional) – Petrophysical model.

  • rho_w (float, optional) – Pore-water resistivity (Ω·m).

  • porosity_prior (float, optional) – Prior porosity.

  • method_tag (str, optional) – EM method label ('TDEM', 'AMT', 'MT', 'EMAP').

Examples

>>> cfg = PetrophysicalConfig(rho_w=0.03, porosity_prior=0.20,
...                           fracture_depth_m=300.0)
>>> result = EMHydroModel(rm, cfg, method_tag="AMT").fit()
>>> result.water_table          # array of depths, one per x-column
>>> result.transmissivity       # T profile (m²/s)
fit()[source]#

Run all petrophysical transforms and return EMHydroResult.

Return type:

EMHydroResult