pycsamt.inversion.data#
Data containers for physics-based EM inversion workflows.
Classes
|
Normalized EM observation container. |
- class pycsamt.inversion.data.EMData(method='mt', frequencies=None, times=None, rho_a=None, phase=None, values=None, errors=None, station_names=<factory>, station_x=None, source=None, metadata=<factory>)[source]#
Bases:
PyCSAMTObject,MetadataMixinNormalized EM observation container.
EMDatais the backend-neutral observation object used bypycsamt.inversion. It keeps natural-source and time-domain EM data in one small shape contract so built-in, optional, and external backends can share the same input API.Shape convention#
Frequency-domain
rho_aandphasearrays may be one-dimensional for a single station or two-dimensional with shape(n_stations, n_frequencies). TDEMvaluesarrays may be one-dimensional for a single sounding or two-dimensional with shape(n_soundings, n_times). Station metadata, when provided, must match the first dimension of these arrays.- param method:
Survey method represented by the observations. The value is normalized to lower case. Natural-source methods require frequency-domain responses;
"tdem"requires time-gate decay values.- type method:
{“mt”, “amt”, “csamt”, “emap”, “tdem”}, default “mt”
- param frequencies:
Frequency samples in hertz for MT, AMT, CSAMT, and EMAP responses. Values must be strictly positive. The aliases
freqs,freq,frequency, and period arrays viaperiodsare accepted by coercion helpers.- type frequencies:
array-like of float, optional
- param times:
Time-gate samples in seconds for TDEM data. Values must be strictly positive. Sounding objects may expose these as
time_gates,times, ortime.- type times:
array-like of float, optional
- param rho_a:
Apparent resistivity in ohm metres. One-dimensional arrays represent one station. Two-dimensional arrays represent
(n_stations, n_samples); if a response object provides(n_samples, n_stations), coercion transposes it when the frequency count makes the orientation unambiguous. Common aliases includerhoa,app_res, andapparent_resistivity.- type rho_a:
array-like of float, optional
- param phase:
Impedance phase in degrees, using the same shape convention as
rho_a. The aliasphiis accepted by object coercion.- type phase:
array-like of float, optional
- param values:
Generic observed values. This is primarily used for TDEM decay data such as
dBz_dt/dbdtarrays. One-dimensional arrays represent one sounding; two-dimensional arrays represent(n_soundings, n_times).- type values:
array-like of float, optional
- param errors:
Absolute observation uncertainties with the same sample axis as the corresponding data. If omitted, backends derive errors from
InversionConfigerror floors and component-specificErrorModelsettings.- type errors:
array-like of float, optional
- param station_names:
Station or sounding labels. The length must match the number of station rows in the data. Mapping aliases include
stations; response-object aliases includestation_names,stations,site_names, andnames.- type station_names:
sequence of str, optional
- param station_x:
Profile-coordinate positions in metres. The length must match the number of station rows. Object coercion also checks aliases such as
x,x_stations,easting,longitude, andlon.- type station_x:
array-like of float, optional
- param source:
Original data object, collection, survey, or path retained for provenance and backend adapters. It is not modified by
EMData.- type source:
object, optional
- param metadata:
Free-form provenance metadata. Object readers copy
metadataormetadictionaries when available and add areadertag describing the coercion path.- type metadata:
dict, optional
Notes
Use
EMData.coerce()at API boundaries. It accepts dictionaries, response-like objects, station collections, TDEM sounding collections, and TDEM survey objects exposingto_soundings(). The original input object is kept insourcefor provenance and backend-specific adapters.Examples
Build one MT/AMT/CSAMT station from a mapping:
>>> from pycsamt.inversion.data import EMData >>> data = EMData.from_dict({ ... "method": "mt", ... "freqs": [1.0, 10.0, 100.0], ... "rho_a": [100.0, 120.0, 140.0], ... "phase": [45.0, 47.0, 49.0], ... "stations": ["S01"], ... }) >>> data.has_mt_response True
Build a stitched profile from station rows:
>>> from pycsamt.inversion.data import EMData >>> profile = EMData.coerce({ ... "method": "amt", ... "freqs": [1.0, 10.0], ... "rho_a": [[100.0, 120.0], [90.0, 115.0]], ... "phase": [[45.0, 47.0], [43.0, 46.0]], ... "station_x": [0.0, 500.0], ... "station_names": ["A01", "A02"], ... }) >>> profile.n_stations 2
Build TDEM data from time gates and decay values:
>>> from pycsamt.inversion.data import EMData >>> tdem = EMData.coerce({ ... "method": "tdem", ... "times": [1e-5, 1e-4, 1e-3], ... "values": [1e-8, 2e-9, 5e-10], ... }) >>> tdem.has_tdem_response True
References
- classmethod from_dict(data, **overrides)[source]#
Build
EMDatafrom a mapping.- Parameters:
data (mapping) – Mapping with observation fields. Keys may include
method,freqs/frequencies,periods,rho_a,phase,times,values,errors,stations/station_names,station_x, andmetadata.**overrides – Field values that override keys read from
data. This is useful when a caller wants to forcemethodor attach metadata while preserving the original observation mapping.
- Returns:
Normalized observation container.
- Return type:
Notes
The aliases
freqsandstationsare normalized tofrequenciesandstation_names.periodsare converted to frequency in hertz.Examples
>>> from pycsamt.inversion.data import EMData >>> data = EMData.from_dict({ ... "method": "mt", ... "freqs": [1.0, 10.0], ... "rho_a": [100.0, 120.0], ... "phase": [45.0, 47.0], ... "stations": ["S01"], ... }) >>> data.frequencies.tolist() [1.0, 10.0] >>> data.station_names ['S01']
- classmethod coerce(data, *, method='mt')[source]#
Return data as an
EMDatainstance.- Parameters:
data (EMData, mapping, response object, sounding object, survey object, or sequence) – Input converted to
EMData. Supported objects include natural-source response objects with frequency and rho/phase attributes; station collections of such objects; TDEM sounding objects exposing time gates and decay values; and survey objects exposingto_soundings().method (str, default "mt") – Fallback method used when data does not declare its own method. TDEM sounding/survey inputs are automatically promoted to
"tdem".
- Returns:
Existing
EMDatainstances are returned unchanged. Recognized objects are parsed into normalized arrays. Unrecognized non-null inputs are retained assourceon an otherwise empty container so backend adapters can still inspect them.- Return type:
- Raises:
ValueError – If station collections have incompatible frequency counts, TDEM soundings have incompatible time gates, or normalized arrays fail validation.
Examples
Coerce a response-like object:
>>> import numpy as np >>> from pycsamt.inversion.data import EMData >>> class Response: ... freqs = np.array([1.0, 10.0]) ... rho_a = np.array([100.0, 120.0]) ... phase = np.array([45.0, 47.0]) ... station_name = "S01" >>> data = EMData.coerce(Response(), method="mt") >>> data.station_names ['S01']
Coerce a small TDEM survey object exposing
to_soundings():>>> import numpy as np >>> from pycsamt.inversion.data import EMData >>> class Sounding: ... station_name = "T01" ... time_gates = np.array([1e-5, 1e-4]) ... data = np.array([1e-8, 2e-9]) >>> class Survey: ... def to_soundings(self): ... return [Sounding()] >>> tdem = EMData.coerce(Survey()) >>> tdem.method 'tdem'