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#
Load raw TEM data with a reader from
pycsamt.tdem.io.(Optional) attach a transmitter waveform from
pycsamt.tdem.waveform.Convert to frequency domain with
TEMtoEDI.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,MetadataMixinUnified TEM file reader with format auto-detection.
TEMReaderis a thin orchestration layer over the individual format functions inpycsamt.tdem.io. It adds:Auto-detection —
read(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 namedread_*methods always take priority over instance defaults.Verbose / logger — set
verbose=1for INFO messages orverbose=2for DEBUG. Pass a customlogging.Loggervia theloggerparameter.Result cache — set
store=Trueto accumulate all results inresultskeyed 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
resultswhenTrue. DefaultFalse.verbose (int) – Verbosity level: 0 = silent, 1 = INFO, 2 = DEBUG.
logger (logging.Logger or None) – Custom logger. If
Nonea 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
- 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:
fmt (str or None) – Explicit format key. One of
"xyz","temavg","tem_z","tem_log","geosoft","amira","zonge","walkttem". WhenNonethe 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, alistofTEMSounding, aTEMAVG, etc.- Return type:
- Raises:
ValueError – If fmt is given but not in
formats.
- read_xyz(path, **kwargs)#
Read a generic XYZ / CSV TEM sounding.
See
pycsamt.tdem.io.read_xyz()for parameter details.- Parameters:
- Return type:
- read_temavg(path, **kwargs)#
Read a Zonge TEMAVG processed
.AVGfile.See
pycsamt.tdem.io.read_temavg()for parameter details.
- read_tem_z(path, **kwargs)#
Read a Zonge TEMAVG contour
.Zfile.See
pycsamt.tdem.io.read_tem_z()for parameter details.
- read_tem_log(path, **kwargs)#
Read a Zonge TEMAVG processing
.LOGfile.See
pycsamt.tdem.io.read_tem_log()for parameter details.
- read_geosoft_dat(path, **kwargs)#
Read a Geosoft Oasis Montaj
.datfile.See
pycsamt.tdem.io.read_geosoft_dat()for parameter details.- Parameters:
- Return type:
- read_amira(path, **kwargs)#
Read an AMIRA / EMIT
.temfile.See
pycsamt.tdem.io.read_amira()for parameter details.- Parameters:
- Return type:
- read_zonge(path, **kwargs)#
Read a Zonge GDP
.avg/.temsounding file.See
pycsamt.tdem.io.read_zonge()for parameter details.- Parameters:
- Return type:
- read_walkttem(path, **kwargs)#
Read a WalkTEM / Aarhus Workbench
.temfile.See
pycsamt.tdem.io.read_walkttem()for parameter details.- Parameters:
- Return type:
- read_batch(paths, *, fmt=None, **kwargs)#
Read multiple files and return a mapping of path → result.
- configure(**kwargs)#
Update acquisition defaults in-place.
Returns self for chaining:
reader.configure(current=6.6, loop_side=40.0).read("file.tem")
- 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:
PyCSAMTObjectContainer 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 passnp.pi * r**2.data_type (str, optional) –
Describes
dataunits."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_areaandrx_turnsso 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.0means 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
>HEADblock.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
datavalue, same units asdata. When provided, it propagates to the EDI impedance variance arrays.waveform (object, optional) – Transmitter waveform descriptor (a
SquareWaveformorRampWaveforminstance). Required only for the rigorous Fourier-domain transform.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
- rx_position: tuple[float, float] | None = None#
2-D receiver offset
(rx, ry)in metres from the loop centre. When set, it overrides the scalaroffsetfor the Biot-Savart in-loop correction.None(default) falls back to(offset, 0).
- rx_offset: tuple[float, float] | None = None#
Alias for
rx_positionkept for reader and transform callers.
- dBdt()#
Return \(\partial B_z / \partial t\) in T s⁻¹.
Converts from
data_typeto normalised dB/dt. RaisesValueErrorfor"normalized_voltage"(needs further physical context).- Return type:
- 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, ortx_areadirectly.- Parameters:
- Return type:
- class pycsamt.tdem.TEMAVG(path, metadata=<factory>, records=<factory>, version=None, dated=None, processed=None, verbose=0, logger=None)#
Bases:
PyCSAMTObjectProcessed content of one Zonge TEMAVG
.AVGfile.TEMAVGreads 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]
- records: list[TEMAVGRecord]#
- classmethod read(path, *, verbose=0, logger=None)#
Read a Zonge TEMAVG
.AVGfile.- Parameters:
- Returns:
Parsed TEMAVG file.
- Return type:
- rows_for_station(station)#
Return all gate rows for one station value.
- Parameters:
station (float)
- Return type:
- 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
TEMSoundingper 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
componentare 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
TEMSoundingdata 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 soundingx,y, andelevationfields.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, andcomponent.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_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:
objectOne processed TEMAVG gate value.
- Parameters:
skip (int) – TEMAVG skip or block flag stored in the first column.
tx (float) – Transmitter identifier from the
Txcolumn.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
Ampscolumn.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.
- class pycsamt.tdem.TEMCoordinate(profile, point, gauss_x, gauss_y, x, y, elevation, remark='')#
Bases:
objectCoordinate 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.
- class pycsamt.tdem.TEMCoordinateTable(path, coordinates=<factory>, verbose=0, logger=None)#
Bases:
PyCSAMTObjectCollection of TEM station coordinates.
- Parameters:
path (pathlib.Path) – Source coordinate file.
coordinates (dict) – Coordinate records keyed by
(profile, point).verbose (int)
logger (object | 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
.xlsfiles are read withpandas.read_excel()whenxlrdis installed, otherwise LibreOffice is used as a conversion fallback when available.verbose (int)
logger (object | None)
- Returns:
Parsed coordinate table.
- Return type:
- get(profile, point)#
Return coordinate metadata for
profileandpoint.- Parameters:
- Return type:
TEMCoordinate | None
- 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:
PyCSAMTObjectParsed TEMAVG processing log.
TEMLogstores 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
.LOGfile.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)
- records: list[TEMLogRecord]#
- classmethod read(path, *, verbose=0, logger=None)#
Read a TEMAVG
.LOGprocessing file.
- 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:
objectOne 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
Window1column.rx_moment (float) – Receiver moment or area value from the
RxMomentcolumn.time_base (str) – Time-base or clock sample label from the
Tscolumn.
- class pycsamt.tdem.TEMSurvey(root, avg_files=<factory>, z_files=<factory>, log_files=<factory>, coordinates=None, companion_files=<factory>, verbose=0, logger=None)#
Bases:
PyCSAMTObjectCollection 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
.AVGfiles keyed by file stem.z_files (dict of str to TEMZPlot) – Parsed
.Zcontour files keyed by file stem.log_files (dict of str to TEMLog) – Parsed
.LOGprocessing 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
- coordinates: TEMCoordinateTable | None = None#
- to_dataframe()#
Return all parsed rows as a
pandas.DataFrame.
- 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
TEMSoundingobjects.- Parameters:
stems (list of str, optional) – File stems to export. When omitted, all parsed
.AVGfiles 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
componentare 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_typerepresentation.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
LateTimeTransformorTEMtoEDI.- Return type:
list of TEMSounding
- class pycsamt.tdem.TEMAVGConversion(survey, soundings, results=<factory>, collection=None, written_paths=<factory>, verbose=0, logger=None)#
Bases:
PyCSAMTObjectResult 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
savepathis supplied.verbose (int)
logger (object | None)
- soundings: list[TEMSounding]#
- class pycsamt.tdem.TEMZPlot(path, metadata=<factory>, records=<factory>, version=None, processed=None, verbose=0, logger=None)#
Bases:
PyCSAMTObjectParsed content of one TEMAVG contour
.Zfile..Zfiles 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.AVGmagnitude column was exported correctly.- Parameters:
path (pathlib.Path) – Source
.Zfile.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
- records: list[TEMZRecord]#
- classmethod read(path, *, verbose=0, logger=None)#
Read a TEMAVG contour
.Zfile.
- rows_for_station(station)#
Return all contour rows for one station value.
- Parameters:
station (float)
- Return type:
- to_dataframe()#
Return the parsed contour table as a DataFrame.
- class pycsamt.tdem.TEMZRecord(line, station, time, magnitude, frequency, window)#
Bases:
objectOne row from a TEMAVG contour
.Zfile.- 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.
- 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:
PyCSAMTObjectShared style values for TDEM figures.
- 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:
PyCSAMTObjectStation-axis tick configuration for TDEM plots.
- Parameters:
- compute_every(n, figwidth_in=10.0, max_label_len=4)#
Return the station tick step.
- class pycsamt.tdem.PlotDecayCurve(soundings, *, title=None, figsize=None, y_mode='dBdt', show_error=True, style=None, verbose=0, logger=None)#
Bases:
TDEMPlotBasePlot 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:
TDEMPlotBasePlot 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:
TDEMPlotBasePlot 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:
TDEMPlotBasePlot a TEMAVG pseudo-section from station-gate records.
- Parameters:
value (str)
y (str)
log_value (bool)
absolute (bool)
cmap (str | None)
title (str | None)
section (str | SectionStyle)
station_ticks (StationTickConfig | None)
style (TDEMPlotStyle | None)
verbose (int)
logger (object | None)
- 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:
TDEMPlotBasePlot a ZPLOT
.Zpseudo-section.- Parameters:
value (str)
y (str)
log_value (bool)
absolute (bool)
cmap (str | None)
title (str | None)
section (str | SectionStyle)
station_ticks (StationTickConfig | None)
style (TDEMPlotStyle | None)
verbose (int)
logger (object | None)
- 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:
TDEMPlotBasePlot TEM station coordinates from a survey or coordinate table.
- Parameters:
color_by (str)
annotate (bool)
contour (bool)
contour_labels (bool)
marker_preset (str)
marker_size (float | None)
marker_alpha (float | None)
padding (float)
colorbar_size (str)
colorbar_pad (float)
colorbar_max_ticks (int | None)
cmap (str | None)
title (str | None)
style (TDEMPlotStyle | None)
verbose (int)
logger (object | None)
- 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:
TDEMPlotBasePlot 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:
TDEMPlotBasePlot 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:
TDEMPlotBaseCreate a compact multi-panel TDEM real-data dashboard.
- Parameters:
title (str)
station_ticks (StationTickConfig | None)
style (TDEMPlotStyle | None)
verbose (int)
logger (object | None)
- plot()#
Draw dashboard and return the figure.
- pycsamt.tdem.is_temavg_file(path)#
Return
Truewhenpathlooks like a TEMAVG file.
- pycsamt.tdem.is_tem_z_file(path)#
Return
Truewhenpathlooks like a TEMAVG.Zfile.
- pycsamt.tdem.is_tem_log_file(path)#
Return
Truewhenpathlooks like a TEMAVG log.
- 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
.AVGfiles 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:
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:
- Returns:
Parsed coordinates keyed by
(profile, point).- Return type:
- 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
TEMSoundingper station.- Parameters:
path (path-like) – Folder containing TEMAVG
.AVGfiles.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.AVGfiles 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
.AVGfiles.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:
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
.Zpseudo-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:
PyCSAMTObjectConvert TEM soundings to frequency-domain apparent impedance using the late-time apparent-resistivity approximation.
Three loop configurations are handled automatically based on the
offsetandloop_dimsattributes of eachTEMSounding: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
Falseto use the central-loop formula for all configurations (legacy behaviour). DefaultTrue.in_loop_n_iter (int) – Number of iterations for the time-dependent geometry correction (see
_rho_a_in_loop()).0uses the static Biot-Savart approximation only. Default 3.waveform_correction (bool) – Apply first-order waveform deconvolution when
sounding.waveformis set (Fitterman & Stewart 1986). SupportsRampWaveform(analytic),HalfSineWaveform, andCustomWaveform(both numerical).SquareWaveformis a no-op (ideal step-off). DefaultTrue.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
TEMSoundingto 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:
- 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:
PyCSAMTObjectRigorous 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.waveformis set. Supports all waveform types via_apply_waveform_correction(). DefaultTrue.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
TEMSoundingto frequency-domain arrays.Returns the same dict structure as
LateTimeTransform.transform()plus key"method": "fourier".- Parameters:
sounding (TEMSounding)
- Return type:
- transform_many(soundings)#
Transform a list of soundings. Returns a list of result dicts.
- Parameters:
soundings (Sequence[TEMSounding])
- Return type:
- 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:
PyCSAMTObjectConvert one or more TEM soundings to a
EDICollection.Wraps either
LateTimeTransform(default) orFourierTransformand writes one synthetic EDI file per sounding intoout_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. DefaultTrue.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:
_WaveformBaseIdeal square-wave transmitter current (zero ramp time).
The waveform alternates between +I and −I at
base_frequencyHz. 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:
Examples
>>> from pycsamt.tdem.waveform import SquareWaveform >>> wf = SquareWaveform(base_frequency=25.0) >>> wf.half_period 0.02
- 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:
_WaveformBaseTransmitter current with a finite linear ramp on switch-off.
The current decays linearly from 1 to 0 over
ramp_offseconds 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
- 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:
_WaveformBaseHalf-sine transmitter current (used by some CSEM / airborne systems).
- Parameters:
Examples
>>> from pycsamt.tdem.waveform import HalfSineWaveform >>> wf = HalfSineWaveform(base_frequency=30.0) >>> round(wf.half_period, 6) 0.016667
- 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:
_WaveformBaseUser-defined waveform supplied as paired time/current arrays.
- Parameters:
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)
- 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#
Readers for Zonge TEMAVG processed |
|
Coordinate readers for TEM survey station tables. |
|
TEM data readers. |
|
Readers for Zonge TEMAVG processing |
|
Visualization helpers for time-domain EM data. |
|
pycsamt.tdem.reader |
|
Folder-level readers for time-domain EM surveys. |
|
TEM time-domain → frequency-domain transforms. |
|
Transmitter waveform models for TEM systems. |
|
High-level TEMAVG survey conversion workflows. |
|
Readers for Zonge TEMAVG contour |