pycsamt.interp.timelapse#
Time-lapse EM monitoring for hydrogeological change detection.
Compares a sequence of EM resistivity models (acquired at different times) to detect and quantify:
Resistivity change Δlog₁₀(ρ) — raw geophysical signal
Water-saturation change ΔSw — via Archie inverse
Volumetric water-content change Δθ = φ · ΔSw
Water-table displacement (rise/fall in metres)
Primary applications in an EM-hydro context:
TDEM time-lapse — monitoring recharge, dewatering, or saline intrusion at 10–500 m depth. High sensitivity to near-surface saturation changes.
AMT time-lapse — seasonal or induced changes in regional aquifers and fractured basement (100–2 000 m).
All outputs are referenced to a baseline survey (default: index 0). The
grids of all surveys must match (same x_centers and z_centers). Use
assert_compatible_grids() to check before computing.
Typical use#
>>> from pycsamt.interp import ResistivityModel
>>> from pycsamt.interp.petrophysics import ArchieModel
>>> from pycsamt.interp.timelapse import TimeLapseEM
>>>
>>> tl = TimeLapseEM(
... surveys=[model_dry, model_wet, model_recharge],
... labels=["dry", "wet", "recharge"],
... )
>>> delta_rho = tl.resistivity_change() # list of (n_z, n_x) arrays
>>> delta_Sw = tl.saturation_change(ArchieModel(), rho_w=0.025)
>>> delta_wt = tl.water_table_displacement(ArchieModel()) # (n_surveys-1, n_x)
Functions
|
Raise |
Classes
|
Time-lapse EM analysis for hydrogeological change detection. |
- class pycsamt.interp.timelapse.TimeLapseEM(surveys, *, times=None, labels=None)[source]#
Bases:
PyCSAMTObjectTime-lapse EM analysis for hydrogeological change detection.
- Parameters:
surveys (sequence of ResistivityModel) – Time-ordered EM inversion results. All must share the same grid (checked on construction via
assert_compatible_grids()).times (sequence of float, optional) – Time stamps for each survey (any consistent unit: days, months, etc.). Used for labelling only — no numerical time-derivative is computed.
labels (sequence of str, optional) – Human-readable survey labels (e.g.
['dry2022', 'wet2023']).
- Variables:
- resistivity_change(baseline_idx=0)[source]#
Resistivity change relative to the baseline survey.
\[\Delta\log_{10}\rho_i = \log_{10}\rho_i - \log_{10}\rho_\text{baseline}\]- Parameters:
baseline_idx (int) – Index of the baseline survey (default 0).
- Returns:
One array per non-baseline survey, in time order. Positive values indicate resistivity increase (drying/desaturation). Negative values indicate resistivity decrease (wetting/salinisation).
- Return type:
- saturation_change(petro, *, phi=0.25, rho_w=0.025, baseline_idx=0)[source]#
Water-saturation change Δ*Sw* via Archie/WS inverse.
\[\Delta S_{w,i} = S_w(\rho_i) - S_w(\rho_\text{baseline})\]- Parameters:
petro (ArchieModel or WaxmanSmitsModel) – Petrophysical model for ρ → Sw inversion.
phi (float or ndarray) – Porosity used in the inversion. Scalar for a uniform profile; 2-D array (n_z, n_x) for a spatially varying prior.
rho_w (float) – Pore-water resistivity (Ω·m).
baseline_idx (int) – Index of the baseline survey (default 0).
- Returns:
ΔSw arrays, one per non-baseline survey. Positive = wetting (saturation increase). Negative = drying (saturation decrease).
- Return type:
- water_content_change(petro, *, phi=0.25, rho_w=0.025, baseline_idx=0)[source]#
Volumetric water-content change Δθ = φ · ΔSw.
- Parameters:
petro (ArchieModel | WaxmanSmitsModel) – Same as
saturation_change().phi (float | ndarray) – Same as
saturation_change().rho_w (float) – Same as
saturation_change().baseline_idx (int) – Same as
saturation_change().
- Returns:
Δθ arrays (dimensionless, range ≈ −φ to +φ).
- Return type:
- water_table_displacement(petro, *, rho_w=0.025, Sw_threshold=0.85, min_depth=0.5, baseline_idx=0)[source]#
Water-table depth change relative to the baseline survey.
\[\Delta z_{wt} = z_{wt}(t_i) - z_{wt}(t_\text{baseline})\]Positive values → water table dropped (deeper, e.g. dry season). Negative values → water table rose (shallower, e.g. recharge).
nanis returned where the water table cannot be detected in either the baseline or the comparison survey.- Parameters:
petro (ArchieModel or WaxmanSmitsModel)
rho_w (float)
Sw_threshold (float) – Saturation level that defines the water table (default 0.85).
min_depth (float) – Minimum search depth in metres (default 0.5).
baseline_idx (int)
- Returns:
Water-table displacement in metres, one row per non-baseline survey.
- Return type:
ndarray (n_surveys−1, n_x)
- water_table_map(petro, *, rho_w=0.025, Sw_threshold=0.85, min_depth=0.5)[source]#
Water-table depth (m) for every survey and every column.
- Returns:
nanwhere the water table could not be detected.- Return type:
- Parameters:
petro (ArchieModel | WaxmanSmitsModel)
rho_w (float)
Sw_threshold (float)
min_depth (float)
- pycsamt.interp.timelapse.assert_compatible_grids(surveys, *, rtol=0.0001)[source]#
Raise
ValueErrorif surveys have incompatible grids.- Parameters:
surveys (sequence of ResistivityModel)
rtol (float) – Relative tolerance for coordinate comparison (default 1e-4).
- Return type:
None