pycsamt.emtools.source_effects#

CSAMT source overprint and shadow effect analysis.

Implements the analytical β-ratio method and spectral slope criterion:

yan2004Yan & Fu (2004), “An analytical method to estimate shadow and

source overprint effects in CSAMT sounding”, Geophysics 69(1), 161–163.

da2016Da et al. (2016), “Modeling and analysis of CSAMT field source

effect and its characteristics”, J. Geophys. Eng. 13, 49–58.

The β ratio is the ground-wave / surface-wave amplitude ratio at the receiver location. When β > 3 % the shadow / overprint effect may be significant (yan2004 threshold). Companion spectral slope analysis (da2016) flags low-frequency ρ_a anomalies that are characteristic of a resistivity contrast beneath the source dipole.

Functions

correct_near_field(sites, source_offset, *)

Correct impedance tensor for CSAMT near-field contamination.

detect_source_overprint(sites[, ...])

Per-frequency source overprint β index for a set of CSAMT sites.

normalize_response(sites[, rho_ref, ...])

Normalized apparent resistivity and subtracted phase (Wang & Lin 2023).

overprint_beta(rho, freq, offset, *[, dh_frac])

Ground-wave / surface-wave amplitude ratio β_Ey (%).

plot_normalized_response(sites[, rho_ref, ...])

Pseudosection of normalized ρ_a and subtracted phase (Wang & Lin 2023).

plot_overprint_section(sites[, ...])

Plot source overprint β pseudo-section (station × frequency).

source_overprint_table(sites[, ...])

Per-station summary of source overprint metrics.

pycsamt.emtools.source_effects.overprint_beta(rho, freq, offset, *, dh_frac=0.001)[source]#

Ground-wave / surface-wave amplitude ratio β_Ey (%).

Evaluates equation (6) of Yan & Fu (2004) analytically at the surface receiver position broadside to the source dipole.

Parameters:
  • rho (float or ndarray) – Half-space apparent resistivity [Ω·m].

  • freq (float or ndarray) – Frequency [Hz].

  • offset (float or ndarray) – Source–receiver horizontal offset r [m].

  • dh_frac (float) – Step size as a fraction of offset used for numerical differentiation (default 1e-3).

Returns:

beta_pct – β × 100 [%]. Values above BETA_THRESH_PCT (3 %) indicate potential shadow / source overprint (yan2004).

Return type:

ndarray

Notes

The function uses central finite differences to evaluate the partial derivatives of the Sommerfeld term P = e^{−k₁r}/r and the Foster term N = I₀(p) K₀(q), where k₁ = √(iωμ₀/ρ) is the complex wavenumber and p, q are related to the 3-D distance and depth.

pycsamt.emtools.source_effects.detect_source_overprint(sites, source_offset=None, *, beta_threshold=3.0, recursive=True, on_dup='replace', strict=False, verbose=0)[source]#

Per-frequency source overprint β index for a set of CSAMT sites.

Computes the ground-wave / surface-wave ratio β_Ey (yan2004) for every measurement frequency at each site and returns a long-form DataFrame.

Parameters:
  • sites (Sites | list) – EDI-like objects or a Sites container.

  • source_offset (float | dict | None) – Source–receiver offset [m]. A scalar applies to all sites; a dict maps {station: offset}. If None the function tries to read the offset from site attributes (source_offset, offset, dist).

  • beta_threshold (float) – β [%] above which the overprint flag is raised (default 3.0).

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

Columns: station, freq_hz, period_s, offset_m, rho_a_ohmm, kr, beta_pct, overprint_flag. Rows with unknown offset have NaN in kr/beta_pct.

Return type:

pd.DataFrame

pycsamt.emtools.source_effects.source_overprint_table(sites, source_offset=None, *, beta_threshold=3.0, f_split=1.0, recursive=True, on_dup='replace', strict=False, verbose=0)[source]#

Per-station summary of source overprint metrics.

In addition to the maximum and mean β values (yan2004), the table includes the log-log ρ_a–frequency slope in the low-frequency (LF) and high-frequency (HF) bands and their difference (da2016). A strongly negative slope_delta (LF slope << HF slope) indicates a resistivity contrast beneath the source (da2016 §2.2–2.3).

Parameters:
  • sites (Sites | list)

  • source_offset (float | dict | None)

  • beta_threshold (float) – β [%] threshold (default BETA_THRESH_PCT = 3.0).

  • f_split (float) – Frequency [Hz] dividing LF from HF bands for slope analysis.

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

Columns: station, n_freq, offset_m, beta_max_pct, beta_mean_pct, n_overprint, overprint_frac, lf_slope, hf_slope, slope_delta, overprint_flag.

Return type:

pd.DataFrame

pycsamt.emtools.source_effects.plot_overprint_section(sites, source_offset=None, *, beta_threshold=3.0, log_color=True, cmap='hot_r', figsize=(10, 5), period_axis=True, log_y=True, contour_beta=True, beta_levels=(1.0, 3.0, 10.0, 30.0), recursive=True, on_dup='replace', strict=False, verbose=0, ax=None)[source]#

Plot source overprint β pseudo-section (station × frequency).

A colour-coded pseudo-section of the ground-wave / surface-wave ratio β_Ey is drawn for each site. Contour lines at selected β levels highlight the overprint-prone zones.

Parameters:
  • sites (Sites | list)

  • source_offset (float | dict | None)

  • beta_threshold (float) – Dashed contour drawn at this level [%] (default 3.0).

  • log_color (bool) – Use log₁₀(β) colour scale.

  • cmap (str) – Matplotlib colormap name.

  • period_axis (bool) – Show periods on the right y-axis when True.

  • log_y (bool) – Logarithmic frequency axis.

  • contour_beta (bool) – Overlay β contour lines.

  • beta_levels (tuple) – β [%] values for contour lines.

  • ax (matplotlib.axes.Axes or None) – Axes to draw on; created if None.

  • figsize (tuple)

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.emtools.source_effects.normalize_response(sites, rho_ref=100.0, source_offset=None, *, comp='det', phi_ref_deg=45.0, recursive=True, on_dup='replace', strict=False, verbose=0)[source]#

Normalized apparent resistivity and subtracted phase (Wang & Lin 2023).

For each (station, frequency) pair computes:

ρ_n    = ρ_obs / ρ_ref
φ_diff = φ_obs − φ_ref

and classifies the measurement zone using the skin-depth formula proposed by Wang & Lin (2023, eq. 1):

δ = 503 √(ρ_a / f) [m]

with thresholds: near (r/δ < 0.5), transition (0.5–4), far (>4).

Parameters:
  • sites (Sites | list) – EDI-like objects or a Sites container.

  • rho_ref (float) – Reference half-space resistivity [Ω·m] (default 100).

  • source_offset (float | dict | None) – Source–receiver offset r [m]. A dict maps {station: r}. If None, zone and kr are NaN.

  • comp ({"det", "xy", "yx"}) – Impedance component used for ρ_a and φ ("det" = geometric-mean determinant).

  • phi_ref_deg (float) – Reference half-space phase [°]. 45° (default) is the far-field plane-wave value for a homogeneous 1-D half-space.

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

Columns: station, freq_hz, period_s, offset_m, rho_a_ohmm, rho_n, phi_obs_deg, phi_ref_deg, phi_diff_deg, zone, kr. zone / kr are None / NaN when no offset is available.

Return type:

pandas.DataFrame

References

Wang & Lin (2023), Geophysics **88**(6), E215–E230.

pycsamt.emtools.source_effects.correct_near_field(sites, source_offset, *, inplace=False, recursive=True, on_dup='replace', strict=False, verbose=0)[source]#

Correct impedance tensor for CSAMT near-field contamination.

Divides each element of Z by the complex near-field factor F(p):

Z_corrected = Z_obs / F(p)

where F(p) = 1 − 3/p² + 3/p³ is the equatorial HED transfer-function ratio and p = k · r, k = √(i·ω·μ₀ / ρ_a). In the far field F(p) → 1 so no correction is applied; in the near/transition zone the correction restores the plane-wave equivalent impedance.

Uses _apply_each() to apply the per-site correction and return a new Sites (or modify in-place).

Parameters:
  • sites (Sites | list) – EDI-like objects or a Sites container.

  • source_offset (float | dict) – Source–receiver separation r [m]. Dict maps {station: r}.

  • inplace (bool, default False) – Modify Z.z in-place and return the original Sites.

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

Sites with corrected impedance tensors.

Return type:

pycsamt.site.base.Sites

References

Wang & Lin (2023), Geophysics **88**(6), E215–E230. Chen & Yan (2005), eqs. (8)–(10).

pycsamt.emtools.source_effects.plot_normalized_response(sites, rho_ref=100.0, source_offset=None, *, comp='det', phi_ref_deg=45.0, period_axis=True, figsize=(12.0, 5.0), cmap_rho='RdBu_r', cmap_phi='RdBu', rho_n_lim=None, phi_diff_lim=None, recursive=True, on_dup='replace', strict=False, verbose=0, axes=None)[source]#

Pseudosection of normalized ρ_a and subtracted phase (Wang & Lin 2023).

Produces a two-panel figure analogous to Fig. 8(e–f) of Wang & Lin (2023):

  • Left panel: ρ_n = ρ_obs / ρ_ref (centred at 1.0; red = high).

  • Right panel: φ_diff = φ_obs − φ_ref [°] (centred at 0°).

Parameters:
  • sites (Sites | list)

  • rho_ref (float) – Reference half-space resistivity [Ω·m].

  • source_offset (float | dict | None)

  • comp ({"det", "xy", "yx"})

  • phi_ref_deg (float) – Reference half-space phase [°] (default 45°).

  • period_axis (bool) – Use period (s) on the y-axis when True (default).

  • figsize ((float, float), default (12, 5))

  • cmap_rho (str) – Matplotlib colormap names for the two panels.

  • cmap_phi (str) – Matplotlib colormap names for the two panels.

  • rho_n_lim ((vmin, vmax) or None) – Colour limits for ρ_n. Default: symmetric about 1.

  • phi_diff_lim ((vmin, vmax) or None) – Colour limits for φ_diff. Default: symmetric about 0.

  • axes ((ax1, ax2) or None) – Draw on existing axes; created if None.

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

(ax1, ax2)

Return type:

tuple of matplotlib.axes.Axes

References

Wang & Lin (2023), Geophysics **88**(6), E215–E230 (Figs. 8e–f).