pycsamt.iot.edge_csamt#

CSAMT / controlled-source specific edge quality-control metrics.

edge_amt covers natural-source AMT/MT concerns (powerline harmonics, passive electrode contact, continuous spectra). Controlled-source audio-magnetotellurics adds a transmitter and therefore a different set of field diagnostics:

  • field-zone classification — the single most important CSAMT QC: whether a frequency is recorded in the far field (where the plane-wave MT assumption holds) or has slipped into the transition/near field, where apparent resistivities roll off and a near-field correction is required. Driven by the skin depth versus the transmitter-receiver offset;

  • transmitter-frequency comb detection — CSAMT transmits a discrete set of frequencies rather than a natural continuum, so QC checks that energy is actually present, and resolvable, at each expected line;

  • source-signal stability — transmitter current/voltage steadiness and on/off keying, which bound the quality of every sounding.

Like edge_amt, everything here is numpy-only (the spectral helpers are shared with that module) so the subpackage imports without SciPy.

Functions

assess_source_stability(tx_current[, ...])

Assess transmitter current (and optional voltage) steadiness.

classify_field_zones(freq, resistivity, ...)

Classify each frequency as near, transition, or far field.

csamt_edge_report(data, sample_rate, *, ...)

Run the core CSAMT edge diagnostics on one channel and collate them.

csamt_edge_table(reports, *[, api])

Flatten one or more csamt_edge_report() results into a table.

detect_transmitter_frequencies(data, ...[, ...])

Check that recorded energy is present at each transmitted frequency.

skin_depth_m(resistivity, freq)

Electromagnetic skin depth in metres.

Classes

FieldZone(*values)

Wave-propagation regime of a CSAMT measurement at one frequency.

FieldZoneCoverage(offset_m[, freq_hz, ...])

Result of classify_field_zones().

SourceLine(frequency_hz, snr_db, ...)

Detection result for one expected transmitter frequency.

SourceStability(current_mean_a, current_cv, ...)

Result of assess_source_stability().

TransmitterComb([lines])

Result of detect_transmitter_frequencies().

class pycsamt.iot.edge_csamt.FieldZone(*values)[source]#

Bases: str, Enum

Wave-propagation regime of a CSAMT measurement at one frequency.

NEAR = 'near'#
TRANSITION = 'transition'#
FAR = 'far'#
class pycsamt.iot.edge_csamt.FieldZoneCoverage(offset_m, freq_hz=<factory>, skin_depth_m=<factory>, offset_ratio=<factory>, zones=<factory>, n_near=0, n_transition=0, n_far=0)[source]#

Bases: PyCSAMTObject

Result of classify_field_zones().

Parameters:
offset_m: float#
freq_hz: list[float]#
skin_depth_m: list[float]#
offset_ratio: list[float]#
zones: list[str]#
n_near: int = 0#
n_transition: int = 0#
n_far: int = 0#
property far_fraction: float[source]#

Fraction of frequencies recorded in the far field.

property all_far_field: bool[source]#

True when every frequency satisfies the far-field assumption.

True when any frequency needs a near-field correction.

first_far_field_hz()[source]#

Lowest frequency that reaches the far field, if any.

Return type:

float | None

as_dict()[source]#
Return type:

dict[str, Any]

class pycsamt.iot.edge_csamt.SourceLine(frequency_hz, snr_db, power_ratio, detected)[source]#

Bases: PyCSAMTObject

Detection result for one expected transmitter frequency.

Parameters:
frequency_hz: float#
snr_db: float#
power_ratio: float#
detected: bool#
as_dict()[source]#
Return type:

dict[str, Any]

class pycsamt.iot.edge_csamt.TransmitterComb(lines=<factory>)[source]#

Bases: PyCSAMTObject

Result of detect_transmitter_frequencies().

Parameters:

lines (list[SourceLine])

lines: list[SourceLine]#
property n_expected: int[source]#
property n_detected: int[source]#
property detection_fraction: float[source]#
missing()[source]#

Expected frequencies whose energy was not resolvable.

Return type:

list[float]

as_dict()[source]#
Return type:

dict[str, Any]

class pycsamt.iot.edge_csamt.SourceStability(current_mean_a, current_cv, current_drift_a, on_fraction, voltage_mean_v=None, stable=False, flags=<factory>)[source]#

Bases: PyCSAMTObject

Result of assess_source_stability().

Parameters:
current_mean_a: float#
current_cv: float#
current_drift_a: float#
on_fraction: float#
voltage_mean_v: float | None = None#
stable: bool = False#
flags: list[str]#
as_dict()[source]#
Return type:

dict[str, Any]

pycsamt.iot.edge_csamt.skin_depth_m(resistivity, freq)[source]#

Electromagnetic skin depth in metres.

\(\delta = 503.29\,\sqrt{\rho / f}\) with \(\rho\) in \(\Omega\cdot m\) and \(f\) in Hz. Scalars and arrays broadcast together; non-positive or non-finite inputs yield nan.

Parameters:
  • resistivity (Any)

  • freq (Any)

Return type:

ndarray

pycsamt.iot.edge_csamt.classify_field_zones(freq, resistivity, offset_m, *, near_ratio=1.0, far_ratio=3.0)[source]#

Classify each frequency as near, transition, or far field.

The controlling quantity is the transmitter-receiver offset expressed in skin depths, \(r / \delta\). A larger ratio means the receiver is electrically farther from the source and the plane-wave assumption is safer.

Parameters:
  • freq (array-like of float) – Frequencies in Hz.

  • resistivity (float or array-like) – (Apparent) resistivity in \(\Omega\cdot m\). A scalar is used as a half-space value for every frequency; an array must match freq.

  • offset_m (float) – Transmitter-receiver separation \(r\) in metres.

  • near_ratio (float) – r / delta at or below which a frequency is near field.

  • far_ratio (float) – r / delta at or above which a frequency is far field. Values in between are the transition zone.

Return type:

FieldZoneCoverage

pycsamt.iot.edge_csamt.detect_transmitter_frequencies(data, sample_rate, tx_frequencies, *, bandwidth_hz=1.0, snr_threshold_db=6.0)[source]#

Check that recorded energy is present at each transmitted frequency.

For every expected transmitter frequency the in-band power is compared with a local out-of-band noise estimate to form a per-line SNR. A line counts as detected when its SNR meets snr_threshold_db; lines above Nyquist are reported as undetected.

Parameters:
  • data (array-like) – Single-channel time series.

  • sample_rate (float) – Sampling frequency in Hz.

  • tx_frequencies (iterable of float) – Expected transmitter frequencies in Hz.

  • bandwidth_hz (float) – Half-width of the signal band around each line.

  • snr_threshold_db (float) – Minimum in-band/out-of-band SNR for a line to count as detected.

Return type:

TransmitterComb

pycsamt.iot.edge_csamt.assess_source_stability(tx_current, tx_voltage=None, *, max_cv=0.05, on_threshold_frac=0.5)[source]#

Assess transmitter current (and optional voltage) steadiness.

The transmitter current sets the signal level of every sounding, so its steadiness bounds data quality. This reports the coefficient of variation and linear drift of the on-state current, together with the on-fraction of an on/off-keyed source.

Parameters:
  • tx_current (array-like) – Transmitter current samples (A).

  • tx_voltage (array-like, optional) – Transmitter voltage samples (V).

  • max_cv (float) – Maximum on-state current coefficient of variation for a stable source.

  • on_threshold_frac (float) – Fraction of the peak current above which the source counts as “on”; on-state statistics use only those samples.

Return type:

SourceStability

pycsamt.iot.edge_csamt.csamt_edge_report(data, sample_rate, *, tx_frequencies, offset_m, resistivity, tx_current=None, tx_voltage=None, near_ratio=1.0, far_ratio=3.0)[source]#

Run the core CSAMT edge diagnostics on one channel and collate them.

Parameters:
Return type:

dict[str, Any]

pycsamt.iot.edge_csamt.csamt_edge_table(reports, *, api=None)[source]#

Flatten one or more csamt_edge_report() results into a table.

Parameters:
Return type:

Any