2.12.1.3. pycsamt.zonge.components#
pycsamt.zonge.components#
Top-level module that aggregates all Zonge data components into a single namespace for convenient importing.
This module re-exports all primary component classes for handling various aspects of Zonge AVG data, including measurements, survey geometry, core scientific values (resistivity, phase, impedance), and quality-control metrics.
- class pycsamt.zonge.components.Frequency(data=None, meta=None, *, name=None)
Bases:
AVGComponentBaseFrequency axis manager (Hz) for AVG tables.
2.12.1.3. Goals#
Read from legacy and modern frames (column aliases handled)
Enforce positivity (> 0 Hz) while tolerating missing markers
Offer stable unique grids across stations/components
Provide a compact to_xarray() for downstream use
Notes
Legacy decimals like ‘.5’ are parsed correctly.
Missing values (‘*’, ‘’, None) become NaN and are ignored in summaries. Non-positive numeric entries raise FrequencyError.
- read(source, meta=None, **kws)
Load frequency values from a tidy frame or a flat vector.
If source is a DataFrame, we try to keep station / comp when present. Otherwise we inject conservative defaults: station=NaN, comp=’ExHy’.
- write()
Emit a compact CSV block with the contextual columns that we manage (station, freq, comp), suitable for round-tripping.
- unique(*, sort=True, dropna=True, rtol=1e-06, atol=1e-12)
Unique global frequency grid with tolerance deduplication.
- by_station(*, rtol=1e-06, atol=1e-12)
Per-station unique frequency grids (sorted).
- property n_unique: int
Number of unique frequencies in the table.
- static logspace(decade_start, decade_stop, n_points)
Canonical log-spaced grid (10**start → 10**stop), inclusive.
- class pycsamt.zonge.components.Amps(data=None, meta=None, *, name=None)
Bases:
AVGComponentBaseTransmitter current amplitude container (unit: A).
The class normalises the
ampscolumn to numeric, tracks a few useful stats, and can (optionally) export itself as a small CSV block. Context columns are preserved.Examples
>>> amps = Amps.from_avg((df, meta)) >>> amps.stats.mean 12.7 >>> ds = amps.to_xarray() # optional grid for convenience
- read(source, meta=None)
Parse source and populate the
ampscolumn as float.Non-numeric entries (‘*’, blanks) become NaN. Context columns (station/freq/comp) are kept when present.
- property stats: _AmpStats
Return min/max/mean/median/count snapshot.
- as_series()
Return the
ampscolumn as a Series (copy).- Return type:
- to_frame()
Return a small table with context +
ampsonly.- Return type:
- to_xarray(*, coords=('station', 'freq', 'comp'), attrs=None)
Optional convenience: grid the column into an xarray dataset (dims: station × freq × comp) with a single data-variable called
amps.
- class pycsamt.zonge.components.CompMeas(data=None, meta=None, *, name=None, verbose=0)
Bases:
AVGComponentBaseEnumeration/validator for classical CSAMT component labels.
The class guarantees a canonical
compcolumn with allowed values (case-sensitive):{'ExHy','ExHx','EyHy','EyHx'}. A few common case variants are accepted and normalized.2.12.1.3. Typical usage#
>>> cm = CompMeas.from_avg((df, meta)) >>> cm.unique ['ExHy'] # for a scalar survey with one component
- read(source, meta=None)
Ensure a normalised
compcolumn exists.If missing, default to ‘ExHy’ (legacy kind-1 style).
If present, normalise values and validate membership.
- write()
Serialise the component block as a compact CSV fragment.
Only the context columns and
compare emitted to keep files readable. Disk I/O is the caller’s responsibility.
- class pycsamt.zonge.components.Station(unit='m', normalize=False, allow_ragged=True, values=<factory>, names=<factory>, index_by_value=<factory>, index_by_name=<factory>)
Bases:
AVGComponentBaseOne-dimensional survey-line geometry container.
This component reads the station coordinate from a tidy AVG frame (usually column
'station'), validates and stores unique positions, and (optionally) normalizes the origin to zero. It also derives a stable set of header keys ($Stn.*) for round-tripping modern headers.2.12.1.3. Key features#
Accepts either a DataFrame (from AVG parsers) or raw arrays.
Handles ragged frequency coverage (no equal-count requirement).
Tracks units; internal helpers can work in metres when desired.
Derives $Stn.Beg / $Stn.Inc / $Stn.Left / $Stn.Right if grid-like.
Exposes dictionary mappings useful for downstream selection.
Notes
We do not modify the caller’s AVG frame; we keep our own view in
self._framethat at minimum contains a numeric'station'column and (if relevant) a'station_m'column when the input length unit is feet (‘ft’) and conversion to metres is helpful.- unit: str
- normalize: bool
- allow_ragged: bool
- values: ndarray
- read(source, meta=None, *, unit=None, names=None, normalize=None, allow_ragged=None)
Populate the component from source.
- Parameters:
source (DataFrame | Sequence[float] | ndarray) – DataFrame with a
'station'column or a 1-D array of station values (possibly repeated across frequencies).meta (Mapping[str, Any] | None) – Optional file metadata. If provided and
unitis None, we trymeta['Unit.Length']for (‘m’|’ft’).unit (str | None) – Length unit of source values. Defaults to ‘m’ or to
meta['Unit.Length']when available.names (Sequence[str] | None) – Optional labels for unique station positions. If omitted, we auto-generate: ‘S00’, ‘S01’, …
normalize (bool | None) – When True, shift the origin so the first station is 0.0.
allow_ragged (bool | None) – When False, all stations must have identical row counts (one per frequency). When True (default), ragged coverage is allowed.
- Return type:
None
- write()
Emit a small, human-friendly header preamble plus a CSV of the station coordinate. This is mainly useful for diagnostics and tests; full file writing should be orchestrated at a higher level.
- property n_unique: int
Number of unique station positions.
- label_map()
Map station numeric value → generated label (e.g., ‘S03’).
- to_keywords()
Derive a stable set of $Stn.* keys from current geometry:
Stn.Beg : first station
Stn.Inc : increment (when grid-like)
Stn.Left : left edge (min)
Stn.Right : right edge (max)
For convenience, we also mirror GDP-station versions when increment is grid-like: Stn.GdpBeg / Stn.GdpInc.
- class pycsamt.zonge.components.Resistivity(data=None, meta=None, *, name=None, verbose=False)
Bases:
TensorBaseApparent resistivity (\(\rho_a\)) per component.
This is a scalar variable (one number per row), but the class inherits the tensor-alignment logic so values land in the appropriate \(2\times 2\) slot given by
comp.2.12.1.3. Recognized source columns (legacy + modern)#
ARes.mag(modern)Resistivity(legacy tables)rho/Rho/ares.mag(variants)
Canonical internal column:
'rho'.- ivar VAR_NAME:
Canonical column in
AVGComponentBase.frame("rho").- vartype VAR_NAME:
str
- ivar ALIASES:
Ordered alias list used during
read().- vartype ALIASES:
tuple[str, …]
- ivar UNIT_ATTR:
Dataset attribute used for units (
"Unit.Rho").- vartype UNIT_ATTR:
str
- VAR_NAME: str = 'rho'
- UNIT_ATTR: str = 'Unit.Rho'
- read(source, meta=None, **kws)
Parse source and produce a compact frame with
station, freq, comp, rho. Coordinates are injected conservatively when absent (station=NaN,comp='ExHy').
- write(*, float_fmt='%.6g', na_rep='')
Serialise to a compact CSV block with a small meta preamble (units + timestamp).
- class pycsamt.zonge.components.Phase(data=None, meta=None, *, name=None, verbose=False)
Bases:
TensorBaseImpedance phase (\(\varphi\)) per component.
This class manages the impedance phase data, inheriting from
TensorBaseto allow its scalar values to be aligned into a \(2 \times 2\) tensor-like grid based on the component label.Notes
Values are typically reported in milliradians in modern CSAVGW tables (
Unit.Phase='mrad'). Use theconvert_unit()method to switch to degrees when desired.The internal canonical column name for phase data is
phase.Recognized source columns:
Z.phz(modern)Phase(legacy)phase,ZPHZ(common variants)
- Variables:
- Parameters:
Examples
>>> from pycsamt.zonge import Phase >>> import pandas as pd >>> data = {"freq": [1024], "phase": [1000]} >>> p = Phase() >>> p.read(pd.DataFrame(data)) >>> p.frame["phase"].iloc[0] 1000.0 >>> p.convert_unit("deg") >>> p.frame["phase"].iloc[0] 57.2957...
See also
ResistivityManages apparent resistivity data.
TensorBaseThe base class providing
- VAR_NAME: str = 'phase'
- UNIT_ATTR: str = 'Unit.Phase'
- read(source, meta=None, **kws)
Parse source and produce a compact frame with
station, freq, comp, phase. Coordinates are injected conservatively when absent (station=NaN,comp='ExHy').Unit.Phasedefaults to'mrad'.
- write(*, float_fmt='%.6g', na_rep='')
Serialise to a compact CSV block with a meta preamble carrying
Unit.Phaseand a UTC timestamp.
- to_xarray(*, coords=('station', 'freq', 'comp'), attrs=None)
Convert to an
xarray.Datasetwith one data variable (phase). Attributes include a stable unit hint underUnit.Phase.
- convert_unit(target='mrad')
Convert the phase values in place between \(\mathrm{mrad}\) and \(\mathrm{deg}\) and update
Unit.PhaseinAVGComponentBase.meta.\[1~\mathrm{mrad} = \frac{180}{\pi \cdot 1000}~\mathrm{deg}\]- Parameters:
target (str)
- Return type:
None
- class pycsamt.zonge.components.Z(data=None, meta=None, *, name=None, verbose=0)
Bases:
TensorBaseComplex impedance tensor (Z) component.
This class reads a tidy AVG table and computes the complex impedance Z from apparent resistivity (\(\rho_a\)) and impedance phase (\(\phi\)). It provides properties to access the complex tensor, its real and imaginary parts, and the propagated error.
The impedance is calculated using the standard formula [1]:
\[Z = \sqrt{\rho_a \cdot \omega \cdot \mu_0} \cdot e^{i \cdot \phi}\]where \(\omega = 2\pi f\).
- Variables:
z (pd.Series) – The complex impedance \(Z\) in Ohms [Ω].
z_imag (z_real,) – The real and imaginary parts of the impedance tensor.
z_err (pd.Series) – The propagated error in the magnitude of \(Z\), \(|dZ|\), in Ohms [Ω].
z_yy (z_xx, z_xy, z_yx,) – Convenience properties to access the individual components of the complex impedance tensor.
- Parameters:
Examples
>>> from pycsamt.zonge import Z >>> from pycsamt.zonge.avg import AVG >>> avg = AVG.from_file("data/avg/K2.avg") >>> z_component = avg.z >>> # Get the complex impedance for all measurements >>> complex_z_values = z_component.z >>> # Get only the Z_xy component >>> z_xy = z_component.z_xy
References
See also
TensorBaseThe parent class providing tensor-shaping logic.
- read(source, meta=None, **kws)
Read and prepare data for impedance calculation.
- property z: Series
Complex impedance Z [Ω].
- property z_real: Series
Real part of the impedance tensor, Z’ [Ω].
- property z_imag: Series
Imaginary part of the impedance tensor, Z’’ [Ω].
- property z_err: Series
Propagated error in the magnitude of Z, |dZ| [Ω].
Calculated via standard error propagation from the relative error in resistivity (dρ/ρ) and the absolute error in phase (dφ).
\[|dZ| \approx \sqrt{ (\frac{\partial |Z|}{\partial \rho} d\rho)^2 + (|Z| d\phi)^2 }\]Since phase errors are often dominant and uncorrelated, a simpler estimate is often used:
\[|dZ| \approx \frac{1}{2} |Z| \frac{d\rho}{\rho}\]
- property z_xx: Series
Complex impedance for the Zxx component.
- property z_xy: Series
Complex impedance for the Zxy component.
- property z_yx: Series
Complex impedance for the Zyx component.
- property z_yy: Series
Complex impedance for the Zyy component.
- property z_xx_err: Series
Propagated error for the Zxx component.
- property z_xy_err: Series
Propagated error for the Zxy component.
- property z_yx_err: Series
Propagated error for the Zyx component.
- property z_yy_err: Series
Propagated error for the Zyy component.
- to_tensor(*, var='z', station=None, agg='mean', fill_value=nan, sort_freq=True, align='union')
Convert impedance data into a 2x2 tensor.
- to_xarray(*, var='z', station=None, agg='mean', fill_value=nan, attrs=None)
Return a 3D or 4D xarray.DataArray.
- class pycsamt.zonge.components.PcEmag(data=None, meta=None, *, name=None, verbose=False)
Bases:
PercentVarBasePercent error on electric-field magnitude, \(|E|\).
This component normalizes legacy aliases into a canonical variable named
pc_emag:'%Emag'(legacy AMTAVG/MTEdit),'E.%err'(CSAVGW / modern),case-sensitive exact matches are used.
Notes
Values are stored in percent; the dataset attribute
Unit.Percentis set to'%'when exporting toxarray.Dataset.- Parameters:
- class pycsamt.zonge.components.PcHmag(data=None, meta=None, *, name=None, verbose=False)
Bases:
PercentVarBasePercent error on magnetic-field magnitude, \(|H|\).
This component normalizes legacy aliases into a canonical variable named
pc_hmag:'%Hmag'(legacy AMTAVG/MTEdit),'B.%err'(CSAVGW, whereBdenotes the H-field),'H.%err'(rare but seen).
Notes
Values are stored in percent; the dataset attribute
Unit.Percentis set to'%'when exporting toxarray.Dataset.- Parameters:
- class pycsamt.zonge.components.PcRho(data=None, meta=None, *, name=None, verbose=False)
Bases:
PercentVarBasePercent error on apparent resistivity, \(\rho_a\).
This component normalizes legacy aliases into a canonical variable named
pc_rho:'%Rho'(legacy AMTAVG/MTEdit),'ARes.%err'(CSAVGW),'rho.%err'(modern lower-case variant).
Notes
Values are stored in percent; the dataset attribute
Unit.Percentis set to'%'when exporting toxarray.Dataset.- Parameters:
- class pycsamt.zonge.components.SEphz(data=None, meta=None, *, name=None, verbose=False)
Bases:
PhaseStdBaseStandard deviation of E-phase.
2.12.1.3. Recognised source columns#
sEphzE.perr
Internal canonical column:
'sephz'.
- class pycsamt.zonge.components.SHphz(data=None, meta=None, *, name=None, verbose=False)
Bases:
PhaseStdBaseStandard deviation of H-phase.
2.12.1.3. Recognised source columns#
sHphzH.perr
Internal canonical column:
'shphz'.
- class pycsamt.zonge.components.SPhz(data=None, meta=None, *, name=None, verbose=False)
Bases:
PhaseStdBaseStandard deviation of impedance phase (
Z).2.12.1.3. Recognised source columns#
sPhzZ.perr
Internal canonical column:
'sphz'.