pycsamt.tdem#

Time-domain electromagnetic readers, survey objects, transforms, plotting, and workflow helpers.

pycsamt.tdem - Time-domain EM (TEM) processing and MT conversion#

This subpackage converts field TEM data to frequency-domain apparent impedance, producing EDICollection objects that feed directly into the rest of the pyCSAMT pipeline.

Workflow#

  1. Load raw TEM data with a reader from pycsamt.tdem.io.

  2. (Optional) attach a transmitter waveform from pycsamt.tdem.waveform.

  3. Convert to frequency domain with TEMtoEDI.

  4. Inspect the result with pycsamt.tdem.plot.

Quick example#

>>> import numpy as np
>>> from pycsamt.tdem import TEMSounding, TEMtoEDI
>>> t = np.logspace(-5, -2, 30)
>>> dBdt = 5e-5 * t ** (-5.0 / 2.0)           # synthetic decay
>>> snd = TEMSounding(
...     t, dBdt,
...     current=8.0, tx_area=100.0 ** 2,
...     data_type="dBdt",
...     station_name="S01", x=1000.0, y=500.0,
... )
>>> conv = TEMtoEDI(method="late_time", phase_mode="weidelt")
>>> coll = conv.transform(snd)                 # EDICollection (1 site)
class pycsamt.tdem.TEMReader(*, current=None, tx_area=None, loop_side=None, loop_radius=None, rx_area=1.0, rx_turns=1, data_unit='nV/Am2', data_type='dBdt', gate_times_unit='ms', store=False, verbose=0, logger=None)#

Bases: PyCSAMTObject, MetadataMixin

Unified TEM file reader with format auto-detection.

TEMReader is a thin orchestration layer over the individual format functions in pycsamt.tdem.io. It adds:

  • Auto-detectionread(path) infers the file format from the extension and magic bytes.

  • Shared defaults — acquisition parameters set on the instance (current, tx_area, …) are injected into every call so you only specify them once.

  • Per-call override — keyword arguments passed to read() or the named read_* methods always take priority over instance defaults.

  • Verbose / logger — set verbose=1 for INFO messages or verbose=2 for DEBUG. Pass a custom logging.Logger via the logger parameter.

  • Result cache — set store=True to accumulate all results in results keyed by file path.

Parameters:
  • current (float or None) – Transmitter current in Amperes.

  • tx_area (float or None) – Transmitter loop area in m².

  • loop_side (float or None) – Side of a square transmitter loop in m.

  • loop_radius (float or None) – Radius of a circular transmitter loop in m.

  • rx_area (float) – Receiver coil area in m². Default 1.0.

  • rx_turns (int) – Receiver coil turns. Default 1.

  • data_unit (str) – Default data column units. Default "nV/Am2".

  • data_type (str) – Default data type. Default "dBdt".

  • gate_times_unit (str) – Default gate-time unit. Default "ms".

  • store (bool) – Accumulate results in results when True. Default False.

  • verbose (int) – Verbosity level: 0 = silent, 1 = INFO, 2 = DEBUG.

  • logger (logging.Logger or None) – Custom logger. If None a module-level logger is used.

Examples

>>> from pycsamt.tdem import TEMReader
>>> reader = TEMReader(current=8.0, loop_side=200.0, verbose=1)
>>> soundings = reader.read("survey.dat")     # Geosoft DAT
>>> soundings = reader.read("profile.tem")    # AMIRA / WalkTEM
>>> soundings = reader.read_zonge("run.avg")  # explicit format
property formats: list[str]#

Return the list of recognised format names.

property results: dict[str, Any]#

Mapping of path → read result (populated when store=True).

clear()#

Clear the result cache.

Return type:

None

read(path, *, fmt=None, **kwargs)#

Read a TEM file, auto-detecting its format when fmt is omitted.

Parameters:
  • path (str or Path) – Path to the TEM data file.

  • fmt (str or None) – Explicit format key. One of "xyz", "temavg", "tem_z", "tem_log", "geosoft", "amira", "zonge", "walkttem". When None the format is inferred automatically.

  • **kwargs – Passed to the underlying reader function after merging with instance defaults (per-call values win).

Returns:

Whatever the underlying reader returns: a single TEMSounding, a list of TEMSounding, a TEMAVG, etc.

Return type:

Any

Raises:
read_xyz(path, **kwargs)#

Read a generic XYZ / CSV TEM sounding.

See pycsamt.tdem.io.read_xyz() for parameter details.

Parameters:
Return type:

TEMSounding

read_temavg(path, **kwargs)#

Read a Zonge TEMAVG processed .AVG file.

See pycsamt.tdem.io.read_temavg() for parameter details.

Parameters:
read_tem_z(path, **kwargs)#

Read a Zonge TEMAVG contour .Z file.

See pycsamt.tdem.io.read_tem_z() for parameter details.

Parameters:
read_tem_log(path, **kwargs)#

Read a Zonge TEMAVG processing .LOG file.

See pycsamt.tdem.io.read_tem_log() for parameter details.

Parameters:
read_geosoft_dat(path, **kwargs)#

Read a Geosoft Oasis Montaj .dat file.

See pycsamt.tdem.io.read_geosoft_dat() for parameter details.

Parameters:
Return type:

list[TEMSounding]

read_amira(path, **kwargs)#

Read an AMIRA / EMIT .tem file.

See pycsamt.tdem.io.read_amira() for parameter details.

Parameters:
Return type:

list[TEMSounding]

read_zonge(path, **kwargs)#

Read a Zonge GDP .avg / .tem sounding file.

See pycsamt.tdem.io.read_zonge() for parameter details.

Parameters:
Return type:

list[TEMSounding]

read_walkttem(path, **kwargs)#

Read a WalkTEM / Aarhus Workbench .tem file.

See pycsamt.tdem.io.read_walkttem() for parameter details.

Parameters:
Return type:

list[TEMSounding]

read_batch(paths, *, fmt=None, **kwargs)#

Read multiple files and return a mapping of path → result.

Parameters:
  • paths (list of path-like) – File paths to read.

  • fmt (str or None) – Force a single format for all files. None → per-file auto-detection.

  • **kwargs – Forwarded to every read() call.

Returns:

Mapping from str(path) to the read result.

Return type:

dict[str, Any]

configure(**kwargs)#

Update acquisition defaults in-place.

Returns self for chaining:

reader.configure(current=6.6, loop_side=40.0).read("file.tem")
Parameters:

**kwargs (Any) – Any writable TEMReader attribute.

Return type:

TEMReader

summary(**kw)#

Return a short one-line object summary.

Return type:

str

class pycsamt.tdem.TEMSounding(time_gates, data, current, tx_area, data_type='dBdt', tx_turns=1, rx_area=1.0, rx_turns=1, offset=0.0, loop_shape='square', loop_dims=<factory>, station_name='', x=0.0, y=0.0, elevation=0.0, error=None, waveform=None, rx_position=None, rx_offset=None, verbose=0, logger=None)#

Bases: PyCSAMTObject

Container for a single time-domain EM (TEM) sounding.

Stores the measured transient decay data together with all geometric and acquisition parameters needed to compute apparent resistivity and to synthesise a frequency-domain EDI file.

Parameters:
  • time_gates (array-like of float) – Centre times of the off-time measurement windows in seconds. Shape (n_gates,).

  • data (array-like of float) – Measured decay values at each time gate. Units depend on data_type (see below). Shape (n_gates,).

  • current (float) – Transmitter current in Amperes.

  • tx_area (float) – Transmitter loop area in m². For a square loop of side L pass L**2; for a circular loop of radius r pass np.pi * r**2.

  • data_type (str, optional) –

    Describes data units.

    "dBdt"

    \(\partial B_z / \partial t\) normalised by the receiver coil parameters (\(V / (n_{rx} A_{rx})\)), in T s⁻¹.

    "dHdt"

    \(\partial H_z / \partial t\) in A m⁻¹ s⁻¹.

    "voltage"

    Raw induced voltage in V. Must also supply rx_area and rx_turns so the converter can normalise.

    "normalized_voltage"

    Voltage normalised by transmitter moment (V / (A·m²)).

    Default is "dBdt".

  • tx_turns (int, optional) – Number of transmitter loop turns. Default 1.

  • rx_area (float, optional) – Receiver coil effective area in m². Required when data_type="voltage". Default 1.0.

  • rx_turns (int, optional) – Number of receiver coil turns. Required when data_type="voltage". Default 1.

  • offset (float, optional) – Horizontal transmitter–receiver separation in metres. 0.0 means coincident / central-loop configuration (the most common field geometry). Default 0.0.

  • loop_shape (str, optional) – Transmitter loop geometry: "square", "circle", or "rectangular". Affects the geometric correction factor for non-coincident configurations. Default "square".

  • loop_dims (tuple of float, optional) –

    Loop dimensions:

    • "square"(side_length,)

    • "circle"(radius,)

    • "rectangular"(length, width)

  • station_name (str, optional) – Site identifier used in the output EDI >HEAD block.

  • x (float, optional) – Easting / longitude of the station. Default 0.0.

  • y (float, optional) – Northing / latitude of the station. Default 0.0.

  • elevation (float, optional) – Station elevation in metres. Default 0.0.

  • error (array-like of float, optional) – Absolute uncertainty on each data value, same units as data. When provided, it propagates to the EDI impedance variance arrays.

  • waveform (object, optional) – Transmitter waveform descriptor (a SquareWaveform or RampWaveform instance). Required only for the rigorous Fourier-domain transform.

  • rx_position (tuple[float, float] | None)

  • rx_offset (tuple[float, float] | None)

  • verbose (int)

  • logger (object | None)

Variables:

moment (float) – Transmitter magnetic moment \(M = I \cdot n_{tx} \cdot A_{tx}\) in A·m².

Notes

For a coincident-loop system (offset = 0) the late-time apparent resistivity at gate k is:

\[\rho_a(t_k) = \frac{\mu_0}{\pi} \left(\frac{\mu_0^2 M} {20\,|\partial B_z/\partial t(t_k)|\,t_k^{5/2}} \right)^{2/3}\]

(Ward & Hohmann 1988, eq. 4.96; Nabighian & Macnae 1991).

The equivalent pseudo-frequency is mapped as:

\[f_\text{eq}(t) = \frac{1}{2\pi t}\]

Examples

>>> import numpy as np
>>> from pycsamt.tdem import TEMSounding
>>> t = np.logspace(-5, -2, 30)        # 10 µs … 10 ms
>>> M = 8.0 * 100.**2                  # magnetic moment
>>> import math
>>> MU0 = 4 * math.pi * 1e-7
>>> dBdt = M * MU0**2.5 / (10 * math.sqrt(math.pi) * 100.**1.5 * t**2.5)
>>> s = TEMSounding(t, dBdt, current=8.0, tx_area=100.**2)
>>> s.moment
640000.0
time_gates: ndarray#
data: ndarray#
current: float#
tx_area: float#
data_type: str = 'dBdt'#
tx_turns: int = 1#
rx_area: float = 1.0#
rx_turns: int = 1#
offset: float = 0.0#
loop_shape: str = 'square'#
loop_dims: tuple[float, ...]#
station_name: str = ''#
x: float = 0.0#
y: float = 0.0#
elevation: float = 0.0#
error: ndarray | None = None#
waveform: object | None = None#
rx_position: tuple[float, float] | None = None#

2-D receiver offset (rx, ry) in metres from the loop centre. When set, it overrides the scalar offset for the Biot-Savart in-loop correction. None (default) falls back to (offset, 0).

rx_offset: tuple[float, float] | None = None#

Alias for rx_position kept for reader and transform callers.

verbose: int = 0#
logger: object | None = None#
property moment: float#

Transmitter magnetic moment \(M = I n_{tx} A_{tx}\) (A·m²).

property n_gates: int#

Number of time gates.

dBdt()#

Return \(\partial B_z / \partial t\) in T s⁻¹.

Converts from data_type to normalised dB/dt. Raises ValueError for "normalized_voltage" (needs further physical context).

Return type:

ndarray

classmethod from_arrays(time_gates, data, *, current, loop_side=None, loop_radius=None, tx_area=None, **kwargs)#

Convenience constructor — supply either loop_side, loop_radius, or tx_area directly.

Parameters:
Return type:

TEMSounding

summary()#

Return a compact dict of key acquisition parameters.

Return type:

dict

class pycsamt.tdem.TEMAVG(path, metadata=<factory>, records=<factory>, version=None, dated=None, processed=None, verbose=0, logger=None)#

Bases: PyCSAMTObject

Processed content of one Zonge TEMAVG .AVG file.

TEMAVG reads the human-readable output produced by the Zonge TEMAVG processing program. The object stores global metadata such as transmitter ramp, loop dimensions, and receiver area together with one row per station/time gate. It is a processed time-domain EM container, not an EDI or frequency-domain impedance object.

Parameters:
  • path (pathlib.Path) – Source file path.

  • metadata (dict) – Parsed header metadata. Keys include entries such as "TXramp", "TXdx", "TXdy", "TXarea", and "RXarea" when present.

  • records (list of TEMAVGRecord) – Parsed processed data rows.

  • version (str, optional) – TEMAVG program version parsed from the first line.

  • dated (str, optional) – Field data date parsed from the first line.

  • processed (str, optional) – Processing date parsed from the first line.

  • verbose (int)

  • logger (object | None)

Examples

>>> from pycsamt.tdem.avg import TEMAVG
>>> avg = TEMAVG.read("data/TEMAVG/JIANGSU/TEM100.AVG")
>>> avg.n_records > 0
True
>>> avg.stations[:3]
[100.0, 120.0, 140.0]
path: Path#
metadata: dict[str, Any]#
records: list[TEMAVGRecord]#
version: str | None = None#
dated: str | None = None#
processed: str | None = None#
verbose: int = 0#
logger: object | None = None#
classmethod read(path, *, verbose=0, logger=None)#

Read a Zonge TEMAVG .AVG file.

Parameters:
  • path (path-like) – Processed TEMAVG file. The reader expects the standard Zonge header followed by the table whose columns include station, frequency, component, current, window, time, magnitude, apparent resistivity, depth, and percent magnitude.

  • verbose (int)

  • logger (object | None)

Returns:

Parsed TEMAVG file.

Return type:

TEMAVG

property n_records: int#

Number of processed gate rows.

property stations: list[float]#

Sorted station values represented in the file.

property windows: list[int]#

Sorted time-window numbers represented in the file.

property tx_area: float | None#

Transmitter loop area in square metres when present.

property rx_area: float | None#

Receiver loop or coil area in square metres when present.

property tx_dx: float | None#

Transmitter loop x dimension in metres when present.

property tx_dy: float | None#

Transmitter loop y dimension in metres when present.

rows_for_station(station)#

Return all gate rows for one station value.

Parameters:

station (float)

Return type:

list[TEMAVGRecord]

to_soundings(*, stations=None, component='Hz', frequency=None, data_column='magnitude', magnitude_unit='uV/A', data_type='voltage', rx_turns=1, tx_turns=1, coordinate_table=None, profile=None, station_name_template='{stem}_{station:g}', min_gates=1, verbose=0, logger=None)#

Build one TEMSounding per station.

Parameters:
  • stations (list of float, optional) – Station values to export. When omitted, every station in the file is converted.

  • component (str, default "Hz") – Component label to select from the TEMAVG rows.

  • frequency (float, optional) – Repetition frequency to select. When omitted, all rows matching component are used.

  • data_column ({"magnitude"}, default "magnitude") – TEMAVG data column used for the sounding decay. The processed magnitude column is currently the only supported transient column.

  • magnitude_unit (str, default "uV/A") – Unit of the TEMAVG magnitude column. "uV/A" means microvolts per ampere. "V/A", "uV", "V", and "SI" are also accepted.

  • data_type (str, default "voltage") – Output TEMSounding data type. "voltage" keeps the decay as receiver voltage. "dBdt" divides by receiver turns and area. "dHdt" additionally divides by \(\mu_0\).

  • rx_turns (int, default 1) – Receiver and transmitter turn counts passed to the resulting soundings.

  • tx_turns (int, default 1) – Receiver and transmitter turn counts passed to the resulting soundings.

  • coordinate_table (object, optional) – Coordinate table exposing get(profile, point). Matching coordinates are copied to the sounding x, y, and elevation fields.

  • profile (float, optional) – Profile id used with coordinate_table. If omitted and no coordinate table is supplied, coordinates stay at their default values.

  • station_name_template (str, default "{stem}_{station:g}") – Format string used to create each station name. Available fields are stem, station, profile, and component.

  • min_gates (int, default 1) – Minimum number of selected time gates required to create a sounding.

  • verbose (int)

  • logger (object | None)

Returns:

Station-wise soundings ready for late-time or Fourier conversion.

Return type:

list of TEMSounding

to_records()#

Return records as dictionaries with file metadata.

Return type:

list[dict[str, Any]]

to_dataframe()#

Return the parsed table as a pandas.DataFrame.

class pycsamt.tdem.TEMAVGRecord(skip, tx, station, frequency, component, current, window, time, magnitude, ramp_app_res, depth, percent_magnitude)#

Bases: object

One processed TEMAVG gate value.

Parameters:
  • skip (int) – TEMAVG skip or block flag stored in the first column.

  • tx (float) – Transmitter identifier from the Tx column.

  • station (float) – Station coordinate or station number along the survey profile.

  • frequency (float) – Repetition frequency in hertz.

  • component (str) – Measured component label, for example "Hz".

  • current (float) – Transmitter current in amperes from the Amps column.

  • window (int) – Time-window number.

  • time (float) – Gate centre time in milliseconds, as written by TEMAVG.

  • magnitude (float) – Processed transient magnitude. For TEMAVG contour files this is commonly reported in microvolts per ampere.

  • ramp_app_res (float) – Ramp-corrected apparent resistivity in ohm metres.

  • depth (float) – TEMAVG depth estimate in metres.

  • percent_magnitude (float) – Percent magnitude or percent error column.

skip: int#
tx: float#
station: float#
frequency: float#
component: str#
current: float#
window: int#
time: float#
magnitude: float#
ramp_app_res: float#
depth: float#
percent_magnitude: float#
property time_s: float#

Gate centre time in seconds.

class pycsamt.tdem.TEMCoordinate(profile, point, gauss_x, gauss_y, x, y, elevation, remark='')#

Bases: object

Coordinate metadata for one TEM station point.

Parameters:
  • profile (float) – Survey profile or line identifier.

  • point (float) – Station point along the profile.

  • gauss_x (float) – Projected Gauss coordinates in metres.

  • gauss_y (float) – Projected Gauss coordinates in metres.

  • x (float) – Relative local coordinates in metres.

  • y (float) – Relative local coordinates in metres.

  • elevation (float) – Station elevation in metres.

  • remark (str, optional) – Free-text field note from the coordinate table.

profile: float#
point: float#
gauss_x: float#
gauss_y: float#
x: float#
y: float#
elevation: float#
remark: str = ''#
class pycsamt.tdem.TEMCoordinateTable(path, coordinates=<factory>, verbose=0, logger=None)#

Bases: PyCSAMTObject

Collection of TEM station coordinates.

Parameters:
  • path (pathlib.Path) – Source coordinate file.

  • coordinates (dict) – Coordinate records keyed by (profile, point).

  • verbose (int)

  • logger (object | None)

path: Path#
coordinates: dict[tuple[float, float], TEMCoordinate]#
verbose: int = 0#
logger: object | None = None#
classmethod read(path, *, verbose=0, logger=None)#

Read a TEM coordinate table.

Parameters:
  • path (path-like) – Coordinate file. CSV and TSV files are read directly. Legacy .xls files are read with pandas.read_excel() when xlrd is installed, otherwise LibreOffice is used as a conversion fallback when available.

  • verbose (int)

  • logger (object | None)

Returns:

Parsed coordinate table.

Return type:

TEMCoordinateTable

property n_points: int#

Number of coordinate records.

property profiles: list[float]#

Sorted profile identifiers.

property points: list[float]#

Sorted station point identifiers.

get(profile, point)#

Return coordinate metadata for profile and point.

Parameters:
Return type:

TEMCoordinate | None

to_records()#

Return coordinate records as dictionaries.

Return type:

list[dict[str, Any]]

to_dataframe()#

Return coordinates as a pandas.DataFrame.

class pycsamt.tdem.TEMLog(path, metadata=<factory>, records=<factory>, version=None, processed=None, raw_modes=<factory>, verbose=0, logger=None)#

Bases: PyCSAMTObject

Parsed TEMAVG processing log.

TEMLog stores processing provenance emitted by the Zonge TEMAVG program. It captures the stable ASCII metadata and acquisition-summary table while preserving the raw processing-mode text for later inspection.

Parameters:
  • path (pathlib.Path) – Source .LOG file.

  • metadata (dict) – Parsed metadata such as source field file, clock type, clock resolution, output AVG file, data-set count, and close status.

  • records (list of TEMLogRecord) – Parsed acquisition-summary rows.

  • version (str, optional) – TEMAVG program version.

  • processed (str, optional) – Processing date string.

  • raw_modes (list of str) – Lines from the TEMAVG global and processing-mode sections. The original table uses legacy box-drawing characters, so it is preserved as text.

  • verbose (int)

  • logger (object | None)

path: Path#
metadata: dict[str, Any]#
records: list[TEMLogRecord]#
version: str | None = None#
processed: str | None = None#
raw_modes: list[str]#
verbose: int = 0#
logger: object | None = None#
classmethod read(path, *, verbose=0, logger=None)#

Read a TEMAVG .LOG processing file.

Parameters:
  • path (path-like) – TEMAVG log file produced while averaging and writing .AVG and .Z outputs.

  • verbose (int)

  • logger (object | None)

Returns:

Parsed processing log.

Return type:

TEMLog

property n_records: int#

Number of acquisition-summary rows.

property stations: list[float]#

Sorted station values represented in the log.

to_records()#

Return acquisition rows as dictionaries.

Return type:

list[dict[str, Any]]

to_dataframe()#

Return the acquisition-summary table as a DataFrame.

class pycsamt.tdem.TEMLogRecord(station, frequency, loop, component, duty, first_window, rx_moment, time_base)#

Bases: object

One acquisition-summary row from a TEMAVG log.

Parameters:
  • station (float) – Station coordinate or station number.

  • frequency (float) – Repetition frequency in hertz.

  • loop (str) – Loop geometry or acquisition code, for example "INL" for in-loop data.

  • component (str) – Measured component label.

  • duty (str) – Duty-cycle string written by TEMAVG, for example "50%".

  • first_window (float) – First gate centre time in microseconds, parsed from the Window1 column.

  • rx_moment (float) – Receiver moment or area value from the RxMoment column.

  • time_base (str) – Time-base or clock sample label from the Ts column.

station: float#
frequency: float#
loop: str#
component: str#
duty: str#
first_window: float#
rx_moment: float#
time_base: str#
class pycsamt.tdem.TEMSurvey(root, avg_files=<factory>, z_files=<factory>, log_files=<factory>, coordinates=None, companion_files=<factory>, verbose=0, logger=None)#

Bases: PyCSAMTObject

Collection of processed TEM files from one survey folder.

Parameters:
  • root (pathlib.Path) – Directory scanned for time-domain EM files.

  • avg_files (dict of str to TEMAVG) – Parsed .AVG files keyed by file stem.

  • z_files (dict of str to TEMZPlot) – Parsed .Z contour files keyed by file stem.

  • log_files (dict of str to TEMLog) – Parsed .LOG processing files keyed by file stem.

  • coordinates (TEMCoordinateTable, optional) – Profile/point coordinate table used to enrich exported survey records.

  • companion_files (dict) – Available companion files grouped by stem. Each value may contain "log", "z", and other format keys that can be parsed in later processing stages.

  • verbose (int)

  • logger (object | None)

Examples

>>> from pycsamt.tdem.survey import read_temavg_survey
>>> survey = read_temavg_survey("data/TEMAVG/JIANGSU")
>>> survey.n_avg_files > 0
True
root: Path#
avg_files: dict[str, TEMAVG]#
z_files: dict[str, TEMZPlot]#
log_files: dict[str, TEMLog]#
coordinates: TEMCoordinateTable | None = None#
companion_files: dict[str, dict[str, Path]]#
verbose: int = 0#
logger: object | None = None#
property n_avg_files: int#

Number of parsed .AVG files.

property n_z_files: int#

Number of parsed .Z contour files.

property n_log_files: int#

Number of parsed .LOG processing files.

property stems: list[str]#

Sorted file stems represented by parsed .AVG files.

property stations: list[float]#

Sorted union of all station values in parsed data.

to_records()#

Return all parsed .AVG rows as dictionaries.

Return type:

list[dict[str, Any]]

to_dataframe()#

Return all parsed rows as a pandas.DataFrame.

get(stem)#

Return one parsed .AVG file by stem.

Parameters:

stem (str)

Return type:

TEMAVG

get_z(stem)#

Return one parsed .Z file by stem.

Parameters:

stem (str)

Return type:

TEMZPlot

get_log(stem)#

Return one parsed .LOG file by stem.

Parameters:

stem (str)

Return type:

TEMLog

coordinate_for(profile, point)#

Return coordinate metadata for a profile/station pair.

Parameters:
Return type:

TEMCoordinate | None

to_soundings(*, stems=None, component='Hz', frequency=None, data_column='magnitude', magnitude_unit='uV/A', data_type='voltage', rx_turns=1, tx_turns=1, min_gates=1, verbose=None, logger=None)#

Build station-wise TEMSounding objects.

Parameters:
  • stems (list of str, optional) – File stems to export. When omitted, all parsed .AVG files are converted in sorted order.

  • component (str, default "Hz") – TEMAVG component to select.

  • frequency (float, optional) – Repetition frequency to select. When omitted, all rows for component are used.

  • data_column ({"magnitude"}, default "magnitude") – TEMAVG transient column used for the sounding decay.

  • magnitude_unit (str, default "uV/A") – Unit of the TEMAVG magnitude column before conversion to the requested data_type representation.

  • data_type (str, default "voltage") – Data type stored in each sounding. The default is receiver voltage in volts.

  • rx_turns (int, default 1) – Receiver and transmitter turn counts passed to each sounding.

  • tx_turns (int, default 1) – Receiver and transmitter turn counts passed to each sounding.

  • min_gates (int, default 1) – Minimum number of selected time gates required for a station to be exported.

  • verbose (int | None)

  • logger (object | None)

Returns:

Soundings suitable for LateTimeTransform or TEMtoEDI.

Return type:

list of TEMSounding

class pycsamt.tdem.TEMAVGConversion(survey, soundings, results=<factory>, collection=None, written_paths=<factory>, verbose=0, logger=None)#

Bases: PyCSAMTObject

Result bundle returned by TEMAVG workflow helpers.

Parameters:
  • survey (TEMSurvey) – Parsed survey folder, including companion files and optional coordinate table.

  • soundings (list of TEMSounding) – Station-wise soundings built from TEMAVG rows.

  • results (list of dict) – Frequency-domain transform result dictionaries.

  • collection (object, optional) – EDI collection created when return_collection=True.

  • written_paths (list of str) – EDI file paths written when savepath is supplied.

  • verbose (int)

  • logger (object | None)

survey: TEMSurvey#
soundings: list[TEMSounding]#
results: list[dict[str, Any]]#
collection: Any | None = None#
written_paths: list[str]#
verbose: int = 0#
logger: object | None = None#
property n_soundings: int#

Number of generated station soundings.

property n_results: int#

Number of transformed frequency-domain results.

property stations: list[str]#

Station names represented by the generated soundings.

class pycsamt.tdem.TEMZPlot(path, metadata=<factory>, records=<factory>, version=None, processed=None, verbose=0, logger=None)#

Bases: PyCSAMTObject

Parsed content of one TEMAVG contour .Z file.

.Z files are plotting-oriented TEMAVG outputs. They store station, time gate, magnitude, frequency, and window values in a compact fixed-width text layout. They are useful for quick pseudo-section plotting and for checking that the processed .AVG magnitude column was exported correctly.

Parameters:
  • path (pathlib.Path) – Source .Z file.

  • metadata (dict) – Parsed header metadata such as date, plot data type, window name, units, component, receiver area, contour mode, and profile mode when present.

  • records (list of TEMZRecord) – Parsed plot rows.

  • version (str, optional) – TEMAVG program version parsed from the first line.

  • processed (str, optional) – Processing date parsed from the second line.

  • verbose (int)

  • logger (object | None)

Examples

>>> from pycsamt.tdem.zplot import TEMZPlot
>>> z = TEMZPlot.read("data/TEMAVG/JIANGSU/TEM100.Z")
>>> z.n_records > 0
True
>>> z.records[0].window
1
path: Path#
metadata: dict[str, Any]#
records: list[TEMZRecord]#
version: str | None = None#
processed: str | None = None#
verbose: int = 0#
logger: object | None = None#
classmethod read(path, *, verbose=0, logger=None)#

Read a TEMAVG contour .Z file.

Parameters:
  • path (path-like) – TEMAVG contour file produced by the ZPLOT stage.

  • verbose (int)

  • logger (object | None)

Returns:

Parsed contour records and header metadata.

Return type:

TEMZPlot

property n_records: int#

Number of contour data rows.

property stations: list[float]#

Sorted station values represented in the file.

property windows: list[int]#

Sorted time-window numbers represented in the file.

rows_for_station(station)#

Return all contour rows for one station value.

Parameters:

station (float)

Return type:

list[TEMZRecord]

to_records()#

Return contour records as dictionaries.

Return type:

list[dict[str, Any]]

to_dataframe()#

Return the parsed contour table as a DataFrame.

class pycsamt.tdem.TEMZRecord(line, station, time, magnitude, frequency, window)#

Bases: object

One row from a TEMAVG contour .Z file.

Parameters:
  • line (int) – Line or profile identifier stored in the first column.

  • station (float) – Station coordinate or station number.

  • time (float) – Gate centre time in milliseconds.

  • magnitude (float) – Contoured transient magnitude, commonly in microvolts per ampere for TEMAVG output.

  • frequency (float) – Repetition frequency in hertz.

  • window (int) – Time-window number.

line: int#
station: float#
time: float#
magnitude: float#
frequency: float#
window: int#
property time_s: float#

Gate centre time in seconds.

class pycsamt.tdem.TDEMPlotStyle(primary='#2166ac', secondary='#d6604d', accent='#1b7837', warning='#b2182b', grid='#ededed', text='#1a1a1a', decay_cmap='viridis', section_cmap='RdYlBu_r', elevation_cmap='terrain', figsize_single=(7.0, 5.0), figsize_double=(7.0, 8.0), figsize_wide=(9.0, 4.5), multiline=None, verbose=0, logger=None)#

Bases: PyCSAMTObject

Shared style values for TDEM figures.

Parameters:
primary: str = '#2166ac'#
secondary: str = '#d6604d'#
accent: str = '#1b7837'#
warning: str = '#b2182b'#
grid: str = '#ededed'#
text: str = '#1a1a1a'#
decay_cmap: str = 'viridis'#
section_cmap: str = 'RdYlBu_r'#
elevation_cmap: str = 'terrain'#
figsize_single: tuple[float, float] = (7.0, 5.0)#
figsize_double: tuple[float, float] = (7.0, 8.0)#
figsize_wide: tuple[float, float] = (9.0, 4.5)#
multiline: object | None = None#
verbose: int = 0#
logger: object | None = None#
colors(n)#

Return n line colors.

Parameters:

n (int)

Return type:

list[str]

line_kwargs(idx, n, **overrides)#

Return line kwargs from the package multiline style.

Parameters:
Return type:

dict[str, Any]

class pycsamt.tdem.StationTickConfig(every='auto', rotation=45.0, fontsize=8, fmt='{:g}', max_ticks=12, preset='pseudosection', side=None, show_markers=True, use_shared_api=True, verbose=0, logger=None)#

Bases: PyCSAMTObject

Station-axis tick configuration for TDEM plots.

Parameters:
every: int | str = 'auto'#
rotation: float = 45.0#
fontsize: int = 8#
fmt: str = '{:g}'#
max_ticks: int = 12#
preset: str = 'pseudosection'#
side: str | None = None#
show_markers: bool = True#
use_shared_api: bool = True#
verbose: int = 0#
logger: object | None = None#
compute_every(n, figwidth_in=10.0, max_label_len=4)#

Return the station tick step.

Parameters:
Return type:

int

apply(ax, stations, *, labels=None, xlabel='Station', xlim=None)#

Apply station ticks to ax.

Parameters:
Return type:

None

class pycsamt.tdem.PlotDecayCurve(soundings, *, title=None, figsize=None, y_mode='dBdt', show_error=True, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot one or more TEM decay curves on log-log axes.

Parameters:
plot(ax=None)#

Draw the decay curves and return the axes.

class pycsamt.tdem.PlotElevationProfile(data, *, profiles=None, x='point', station_ticks=None, title='TEM elevation profile', figsize=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot TEM station elevation along one or more survey profiles.

Parameters:
plot(ax=None)#

Draw station elevation profiles and return the axes.

class pycsamt.tdem.PlotTransformedRho(data, *, show_phase=True, freq_convention='skin_depth', phase_mode='weidelt', use_control=False, panel_height_ratios=(3.0, 1.15), figsize=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot transformed apparent resistivity and optional phase.

Parameters:
plot(axes=None)#

Draw apparent resistivity and phase panels.

class pycsamt.tdem.PlotTEMAVGSection(data, *, value='ramp_app_res', y='depth', log_value=True, absolute=False, cmap=None, title=None, section='dynamic', figsize=None, station_ticks=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot a TEMAVG pseudo-section from station-gate records.

Parameters:
plot(ax=None, *, colorbar=True)#

Draw the pseudo-section and return the axes.

Parameters:

colorbar (bool)

class pycsamt.tdem.PlotTEMZSection(data, *, value='magnitude', y='time_ms', log_value=True, absolute=True, cmap=None, title=None, section='dynamic', figsize=None, station_ticks=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot a ZPLOT .Z pseudo-section.

Parameters:
plot(ax=None, *, colorbar=True)#

Draw the ZPLOT pseudo-section and return the axes.

Parameters:

colorbar (bool)

class pycsamt.tdem.PlotSurveyMap(data, *, color_by='elevation', annotate=False, contour=False, contour_levels=8, contour_labels=True, marker_preset='survey', marker_size=None, marker_alpha=None, padding=0.04, colorbar_size='3.5%', colorbar_pad=0.04, colorbar_max_ticks=5, cmap=None, title='TEM survey map', figsize=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot TEM station coordinates from a survey or coordinate table.

Parameters:
plot(ax=None, *, colorbar=True)#

Draw the survey station map and return the axes.

Parameters:

colorbar (bool)

class pycsamt.tdem.PlotSurveyOverview(data, *, profile=None, profile_x='point', map_kwargs=None, profile_kwargs=None, title='TEM survey overview', figsize=(10.0, 6.5), height_ratios=(1.25, 1.0), style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot a TEM survey map with a matched elevation profile panel.

Parameters:
plot()#

Draw the survey overview and return the figure.

class pycsamt.tdem.PlotGateProfile(data, *, windows=None, value='magnitude', absolute=True, log_y=True, title=None, figsize=None, station_ticks=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Plot selected TEMAVG windows as profiles along stations.

Parameters:
plot(ax=None)#

Draw selected gate profiles and return the axes.

class pycsamt.tdem.PlotTEMDashboard(avg, zplot, soundings, *, title='TDEM profile dashboard', figsize=(12.0, 9.0), station_ticks=None, style=None, verbose=0, logger=None)#

Bases: TDEMPlotBase

Create a compact multi-panel TDEM real-data dashboard.

Parameters:
plot()#

Draw dashboard and return the figure.

pycsamt.tdem.is_temavg_file(path)#

Return True when path looks like a TEMAVG file.

Parameters:

path (str | Path)

Return type:

bool

pycsamt.tdem.is_tem_z_file(path)#

Return True when path looks like a TEMAVG .Z file.

Parameters:

path (str | Path)

Return type:

bool

pycsamt.tdem.is_tem_log_file(path)#

Return True when path looks like a TEMAVG log.

Parameters:

path (str | Path)

Return type:

bool

pycsamt.tdem.read_temavg_survey(path, *, pattern='*.AVG', coordinate_file=None, verbose=0, logger=None)#

Read a directory of Zonge TEMAVG processed files.

Parameters:
  • path (path-like) – Directory containing TEMAVG .AVG files and optional companion files such as .LOG, .Z, and .mde.

  • pattern (str, default “*.AVG”) – Glob pattern used to select processed average files.

  • coordinate_file (path-like, optional) – Profile/point coordinate file. If omitted, the reader looks for common coordinate-table names in path.

  • verbose (int)

  • logger (object | None)

Returns:

Parsed survey collection.

Return type:

TEMSurvey

Examples

>>> from pycsamt.tdem import read_temavg_survey
>>> survey = read_temavg_survey("data/TEMAVG/JIANGSU")
>>> len(survey.stations) > 0
True
pycsamt.tdem.read_tem_coordinates(path, *, verbose=0, logger=None)#

Read a TEM profile/point coordinate table.

Parameters:
  • path (path-like) – Coordinate file in CSV, TSV, XLS, or XLSX format.

  • verbose (int)

  • logger (object | None)

Returns:

Parsed coordinates keyed by (profile, point).

Return type:

TEMCoordinateTable

pycsamt.tdem.read_temavg_soundings(path, *, pattern='*.AVG', coordinate_file=None, stems=None, component='Hz', frequency=None, data_column='magnitude', magnitude_unit='uV/A', data_type='voltage', rx_turns=1, tx_turns=1, min_gates=1, verbose=0, logger=None)#

Read a TEMAVG folder and return station soundings.

This helper performs the first half of the TEMAVG pipeline: parse a survey folder, attach coordinates when available, and build one TEMSounding per station.

Parameters:
  • path (path-like) – Folder containing TEMAVG .AVG files.

  • pattern (str, default “*.AVG”) – Glob pattern used to select processed average files.

  • coordinate_file (path-like, optional) – Coordinate table to attach by (profile, station). If omitted, common coordinate filenames are discovered automatically.

  • stems (list of str, optional) – File stems to convert, for example ["TEM100"]. When omitted, all parsed .AVG files are used.

  • component (str, default "Hz") – TEMAVG component to select.

  • frequency (float, optional) – Repetition frequency to select.

  • data_column ({"magnitude"}, default "magnitude") – TEMAVG transient column used for the sounding decay.

  • magnitude_unit (str, default "uV/A") – Unit of the TEMAVG magnitude column.

  • data_type (str, default "voltage") – Data convention stored in each sounding.

  • rx_turns (int, default 1) – Receiver and transmitter turn counts.

  • tx_turns (int, default 1) – Receiver and transmitter turn counts.

  • min_gates (int, default 1) – Minimum number of selected gates required per station.

  • verbose (int)

  • logger (object | None)

Returns:

Station-wise soundings ready for transformation.

Return type:

list of TEMSounding

pycsamt.tdem.transform_temavg_survey(path, *, pattern='*.AVG', coordinate_file=None, stems=None, component='Hz', frequency=None, data_column='magnitude', magnitude_unit='uV/A', data_type='voltage', rx_turns=1, tx_turns=1, min_gates=1, method='late_time', freq_convention='skin_depth', phase_mode='homogeneous', loop_geometry_correction=True, return_collection=False, savepath=None, verbose=0, logger=None)#

Run a complete TEMAVG-to-frequency workflow.

The function reads a TEMAVG survey folder, builds station soundings, transforms them to pseudo-frequency apparent resistivity and impedance, and optionally creates or writes EDI output.

Parameters:
  • path (path-like) – Folder containing TEMAVG .AVG files.

  • pattern (str, default “*.AVG”) – Glob pattern used to select processed average files.

  • coordinate_file (path-like, optional) – Coordinate table to attach by profile and station.

  • stems (list of str, optional) – File stems to convert. Use this to process one profile before scaling to a full survey folder.

  • component (str, default "Hz") – TEMAVG component to select.

  • frequency (float, optional) – Repetition frequency to select.

  • data_column ({"magnitude"}, default "magnitude") – TEMAVG transient column used for the sounding decay.

  • magnitude_unit (str, default "uV/A") – Unit of the TEMAVG magnitude column.

  • data_type (str, default "voltage") – Data convention stored in each sounding.

  • rx_turns (int, default 1) – Receiver and transmitter turn counts.

  • tx_turns (int, default 1) – Receiver and transmitter turn counts.

  • min_gates (int, default 1) – Minimum number of selected gates required per station.

  • method ({"late_time", "fourier"}, default "late_time") – Transformation method used by TEMtoEDI.

  • freq_convention (str, default "skin_depth") – Pseudo-frequency convention for late-time transforms.

  • phase_mode (str, default "homogeneous") – Phase model used for synthetic impedance.

  • loop_geometry_correction (bool, default True) – Whether to apply in-loop geometry corrections.

  • return_collection (bool, default False) – If True, also build an EDI collection in memory.

  • savepath (path-like, optional) – Directory where synthetic EDI files are written.

  • verbose (int)

  • logger (object | None)

Returns:

Bundle containing the parsed survey, station soundings, transform results, and optional EDI outputs.

Return type:

TEMAVGConversion

Examples

>>> from pycsamt.tdem import transform_temavg_survey
>>> out = transform_temavg_survey(
...     "data/TEMAVG/JIANGSU",
...     stems=["TEM100"],
... )
>>> out.n_soundings > 0
True
pycsamt.tdem.plot_decay(soundings, **kwargs)#

Plot TEM decay curves.

pycsamt.tdem.plot_elevation_profile(data, **kwargs)#

Plot station elevation along TEM survey profiles.

pycsamt.tdem.plot_transformed_rho(data, **kwargs)#

Plot transformed apparent resistivity and phase.

pycsamt.tdem.plot_temavg_section(data, **kwargs)#

Plot a TEMAVG pseudo-section.

pycsamt.tdem.plot_tem_z_section(data, **kwargs)#

Plot a TEMAVG .Z pseudo-section.

pycsamt.tdem.plot_survey_map(data, **kwargs)#

Plot station coordinates from a TEM survey.

pycsamt.tdem.plot_survey_overview(data, **kwargs)#

Plot a TEM survey map with an elevation-profile panel.

pycsamt.tdem.plot_gate_profile(data, **kwargs)#

Plot selected TEMAVG gate profiles.

pycsamt.tdem.plot_tem_dashboard(avg, zplot, soundings, **kwargs)#

Plot a compact TDEM dashboard.

class pycsamt.tdem.LateTimeTransform(freq_convention='skin_depth', phase_mode='homogeneous', drop_nan=True, loop_geometry_correction=True, in_loop_n_iter=3, waveform_correction=True, verbose=0, logger=None)#

Bases: PyCSAMTObject

Convert TEM soundings to frequency-domain apparent impedance using the late-time apparent-resistivity approximation.

Three loop configurations are handled automatically based on the offset and loop_dims attributes of each TEMSounding:

  • central / coincident loop (offset == 0): standard Ward & Hohmann (1988) formula.

  • in-loop off-centre receiver (0 < offset < inner_radius): Biot-Savart geometric correction applied to the effective moment.

  • separated / offset loop (offset inner_radius): offset dipole formula with \(d^3\) denominator.

Parameters:
  • freq_convention (str) – Time-to-pseudo-frequency mapping: "skin_depth" (default) or "diffusion".

  • phase_mode (str) – MT phase estimate: "homogeneous" (default, 45°) or "weidelt" (dispersion relation).

  • drop_nan (bool) – Remove gates with undefined ρ_a. Default True.

  • loop_geometry_correction (bool) – Apply the Biot-Savart in-loop correction when the receiver is off-centre. Set False to use the central-loop formula for all configurations (legacy behaviour). Default True.

  • in_loop_n_iter (int) – Number of iterations for the time-dependent geometry correction (see _rho_a_in_loop()). 0 uses the static Biot-Savart approximation only. Default 3.

  • waveform_correction (bool) – Apply first-order waveform deconvolution when sounding.waveform is set (Fitterman & Stewart 1986). Supports RampWaveform (analytic), HalfSineWaveform, and CustomWaveform (both numerical). SquareWaveform is a no-op (ideal step-off). Default True.

  • verbose (int)

  • logger (object | None)

Examples

Central-loop sounding:

>>> import numpy as np
>>> from pycsamt.tdem import TEMSounding
>>> from pycsamt.tdem.transform import LateTimeTransform
>>> t = np.logspace(-5, -2, 30)
>>> M = 8.0 * 100.0 ** 2
>>> MU0_loc = 4e-7 * np.pi
>>> dBdt = M * MU0_loc**2.5 / (10*np.sqrt(np.pi)*100.**1.5*t**2.5)
>>> snd = TEMSounding(t, dBdt, current=8.0, tx_area=100.**2)
>>> tr = LateTimeTransform()
>>> result = tr.transform(snd)
>>> result["freq"].shape
(30,)

Offset-loop sounding:

>>> snd_off = TEMSounding(t, dBdt, current=8.0, tx_area=100.**2,
...                       offset=500.0, loop_dims=(100.0,))
>>> result_off = tr.transform(snd_off)
transform(sounding)#

Transform one TEMSounding to frequency-domain arrays.

Parameters:

sounding (TEMSounding)

Returns:

freq, Z, Z_err, rho_a, phase_xy, station_name, x, y, elevation, loop_config.

Return type:

dict with keys

transform_many(soundings)#

Transform a list of soundings. Returns a list of result dicts.

Parameters:

soundings (Sequence[TEMSounding])

Return type:

list[dict]

class pycsamt.tdem.FourierTransform(n_freq=50, freq_min=None, freq_max=None, n_aux=200, n_interp=400, waveform_correction=True, drop_nan=True, verbose=0, logger=None)#

Bases: PyCSAMTObject

Rigorous TDEM → MT impedance via numerical Fourier cosine transform and Kramers-Kronig reconstruction (Meju 1996; Christensen 1990).

The 1-D step-off forward relation gives:

\[\frac{\partial B_z}{\partial t}(t) = \frac{2M}{\pi} \int_0^\infty \omega\,\mathrm{Im}[K(\omega)]\,\cos(\omega t)\,\mathrm{d}\omega\]

Inverting by the half-range cosine transform:

\[\mathrm{Im}[K(\omega)] = \frac{1}{M\omega} \int_0^\infty \frac{\partial B_z}{\partial t}(t) \cos(\omega t)\,\mathrm{d}t\]

The real part \(\mathrm{Re}[K(\omega)]\) is recovered via the Kramers-Kronig relation, then:

\[Z(\omega) = i\omega\mu_0 K(\omega),\qquad \rho_a(\omega) = \omega\mu_0\,|K(\omega)|^2\]
Parameters:
  • n_freq (int) – Number of output frequency points. Default 50.

  • freq_min (float or None) – Minimum output frequency [Hz] (None → auto from time gates).

  • freq_max (float or None) – Maximum output frequency [Hz] (None → auto from time gates).

  • n_aux (int) – Auxiliary frequency points for the K-K integral (≥ 4 × n_freq). Default 200.

  • n_interp (int) – Interpolation grid for the cosine transform (0 = disabled). Default 400.

  • waveform_correction (bool) – Apply first-order waveform deconvolution (Fitterman & Stewart 1986) when sounding.waveform is set. Supports all waveform types via _apply_waveform_correction(). Default True.

  • drop_nan (bool) – Remove output frequencies with undefined ρ_a. Default True.

  • verbose (int)

  • logger (object | None)

Examples

>>> import numpy as np
>>> from pycsamt.tdem import TEMSounding
>>> from pycsamt.tdem.transform import FourierTransform
>>> t = np.logspace(-5, -2, 40)
>>> MU0_v = 4e-7 * np.pi; rho0 = 100.0; M = 8.0 * 1e4
>>> dBdt = M * MU0_v**2.5 / (10*np.sqrt(np.pi)*rho0**1.5*t**2.5)
>>> snd = TEMSounding(t, dBdt, current=8.0, tx_area=1e4)
>>> res = FourierTransform(n_freq=30).transform(snd)
>>> np.isfinite(res["rho_a"]).all()
True

References

transform(sounding)#

Transform one TEMSounding to frequency-domain arrays.

Returns the same dict structure as LateTimeTransform.transform() plus key "method": "fourier".

Parameters:

sounding (TEMSounding)

Return type:

dict

transform_many(soundings)#

Transform a list of soundings. Returns a list of result dicts.

Parameters:

soundings (Sequence[TEMSounding])

Return type:

list[dict]

class pycsamt.tdem.TEMtoEDI(method='late_time', freq_convention='skin_depth', phase_mode='homogeneous', loop_geometry_correction=True, out_dir='edi_out/tem', verbose=0, logger=None)#

Bases: PyCSAMTObject

Convert one or more TEM soundings to a EDICollection.

Wraps either LateTimeTransform (default) or FourierTransform and writes one synthetic EDI file per sounding into out_dir.

All three loop configurations (central, in-loop, offset) are handled automatically via LateTimeTransform.

Parameters:
  • method (str) – "late_time" (default) or "fourier".

  • freq_convention (str) – "skin_depth" (default) or "diffusion".

  • phase_mode (str) – "homogeneous" (default) or "weidelt".

  • loop_geometry_correction (bool) – Forward to LateTimeTransform. Default True.

  • out_dir (str or Path) – EDI output directory. Default "edi_out/tem".

  • verbose (int) – Verbosity. Default 0.

  • logger (object | None)

Examples

Central-loop:

>>> from pycsamt.tdem import TEMSounding, TEMtoEDI
>>> import numpy as np
>>> t = np.logspace(-5, -2, 25)
>>> dBdt = 5e-5 * t ** (-5.0 / 2.0)
>>> snd = TEMSounding(t, dBdt, current=8.0, tx_area=1e4,
...                   station_name="S01")
>>> conv = TEMtoEDI(method="late_time")
>>> coll = conv.transform(snd)

Offset (separated) loop — just set offset:

>>> snd_off = TEMSounding(t, dBdt, current=8.0, tx_area=1e4,
...                       offset=500.0, loop_dims=(100.0,),
...                       station_name="S01")
>>> coll_off = conv.transform(snd_off)
transform(sounding)#
Parameters:

sounding (TEMSounding)

transform_many(soundings)#
Parameters:

soundings (Sequence[TEMSounding])

save(sounding_or_soundings, path=None)#

Transform and write EDI files. Returns list of written paths.

class pycsamt.tdem.SquareWaveform(base_frequency=25.0, duty_cycle=0.5, verbose=0, logger=None)#

Bases: _WaveformBase

Ideal square-wave transmitter current (zero ramp time).

The waveform alternates between +I and −I at base_frequency Hz. For late-time TEM processing the waveform is treated as an ideal step turn-off, so this is the appropriate choice when ramp effects are negligible.

Parameters:
  • base_frequency (float) – Fundamental repetition rate in Hz (e.g. 25 Hz for ZongeGDP).

  • duty_cycle (float, optional) – Fraction of the half-period spent at full current. Default 0.5 (50 % duty cycle → symmetric square wave).

  • verbose (int)

  • logger (object | None)

Examples

>>> from pycsamt.tdem.waveform import SquareWaveform
>>> wf = SquareWaveform(base_frequency=25.0)
>>> wf.half_period
0.02
base_frequency: float = 25.0#
duty_cycle: float = 0.5#
verbose: int = 0#
logger: object | None = None#
current_at(t)#

Return the normalised transmitter current (0–1) at times t.

Parameters:

t (array-like) – Times in seconds relative to the switch-off event at t = 0. Negative values are on-time; positive values are off-time.

Returns:

Current envelope (dimensionless, in [0, 1]).

Return type:

np.ndarray

class pycsamt.tdem.RampWaveform(base_frequency=25.0, ramp_off=0.0001, ramp_on=0.0, duty_cycle=0.5, verbose=0, logger=None)#

Bases: _WaveformBase

Transmitter current with a finite linear ramp on switch-off.

The current decays linearly from 1 to 0 over ramp_off seconds starting at t = 0 (the nominal switch-off instant). This is the waveform required for accurate early-time TEM processing where the ramp duration is comparable to the first measurement gates.

Parameters:
  • base_frequency (float) – Fundamental repetition rate in Hz.

  • ramp_off (float) – Duration of the current turn-off ramp in seconds.

  • ramp_on (float, optional) – Duration of the current turn-on ramp in seconds. Rarely needed; default 0.0 (ideal step turn-on).

  • duty_cycle (float, optional) – Fraction of the half-period at full current (before ramp). Default 0.5.

  • verbose (int)

  • logger (object | None)

Examples

>>> from pycsamt.tdem.waveform import RampWaveform
>>> wf = RampWaveform(base_frequency=25.0, ramp_off=1e-4)
>>> wf.ramp_off
0.0001
base_frequency: float = 25.0#
ramp_off: float = 0.0001#
ramp_on: float = 0.0#
duty_cycle: float = 0.5#
verbose: int = 0#
logger: object | None = None#
current_at(t)#

Return the normalised transmitter current (0–1) at times t.

Parameters:

t (array-like) – Times in seconds relative to the switch-off event at t = 0. Negative values are on-time; positive values are off-time.

Returns:

Current envelope (dimensionless, in [0, 1]).

Return type:

np.ndarray

class pycsamt.tdem.HalfSineWaveform(base_frequency=30.0, verbose=0, logger=None)#

Bases: _WaveformBase

Half-sine transmitter current (used by some CSEM / airborne systems).

Parameters:
  • base_frequency (float) – Fundamental repetition rate in Hz.

  • verbose (int)

  • logger (object | None)

Examples

>>> from pycsamt.tdem.waveform import HalfSineWaveform
>>> wf = HalfSineWaveform(base_frequency=30.0)
>>> round(wf.half_period, 6)
0.016667
base_frequency: float = 30.0#
verbose: int = 0#
logger: object | None = None#
current_at(t)#

Return the normalised transmitter current (0–1) at times t.

Parameters:

t (array-like) – Times in seconds relative to the switch-off event at t = 0. Negative values are on-time; positive values are off-time.

Returns:

Current envelope (dimensionless, in [0, 1]).

Return type:

np.ndarray

class pycsamt.tdem.CustomWaveform(t_waveform, i_waveform, *, base_frequency=25.0, verbose=0, logger=None)#

Bases: _WaveformBase

User-defined waveform supplied as paired time/current arrays.

Parameters:
  • t_waveform (array-like of float) – Time samples in seconds (relative to switch-off at t = 0).

  • i_waveform (array-like of float) – Normalised current values (0–1) at each t_waveform sample.

  • base_frequency (float) – Fundamental repetition rate in Hz.

  • verbose (int)

  • logger (object | None)

Examples

>>> import numpy as np
>>> from pycsamt.tdem.waveform import CustomWaveform
>>> t = np.linspace(-0.02, 0.02, 200)
>>> I = np.where(t < 0, 1.0, 0.0)
>>> wf = CustomWaveform(t, I, base_frequency=25.0)
property base_frequency: float#
current_at(t)#

Return the normalised transmitter current (0–1) at times t.

Parameters:

t (array-like) – Times in seconds relative to the switch-off event at t = 0. Negative values are on-time; positive values are off-time.

Returns:

Current envelope (dimensionless, in [0, 1]).

Return type:

np.ndarray

TDEM Modules#

pycsamt.tdem.avg

Readers for Zonge TEMAVG processed .AVG files.

pycsamt.tdem.coordinates

Coordinate readers for TEM survey station tables.

pycsamt.tdem.io

TEM data readers.

pycsamt.tdem.log

Readers for Zonge TEMAVG processing .LOG files.

pycsamt.tdem.plot

Visualization helpers for time-domain EM data.

pycsamt.tdem.reader

pycsamt.tdem.reader

pycsamt.tdem.survey

Folder-level readers for time-domain EM surveys.

pycsamt.tdem.transform

TEM time-domain → frequency-domain transforms.

pycsamt.tdem.waveform

Transmitter waveform models for TEM systems.

pycsamt.tdem.workflow

High-level TEMAVG survey conversion workflows.

pycsamt.tdem.zplot

Readers for Zonge TEMAVG contour .Z files.