2.14.2.3. pycsamt.emtools.mobilemt#
MobileMT-specific processing, diagnostics, and plotting.
MobileMT (Prikhodko et al. 2022) is a natural-source airborne EM technology built on a fundamentally different scientific object than ZTEM/AFMAG: three orthogonal airborne magnetic coils (\(H_x, H_y, H_z\)) referenced to a fixed-ground horizontal electric dipole pair (\(E_x, E_y\)), giving a complex admittance tensor
– the reciprocal relation of the classical MT impedance tensor
\(Z\) (which gives \(E\) from \(H\)), not a tipper. This
is why pycsamt.airborne.mobilemt maps it onto a dedicated
mobilemt_admittance TransferFunction of
shape (nf, 3, 2) rather than onto
z or
tipper, and why converting it to an
EDI/Site is refused outright
(EMTF.to_edi raises EMTFEDIConversionError for this
transfer-function type – see
pycsamt.airborne.mobilemt.tests.test_mobilemt_interop). Every
emtools module before this one accepts and returns
Sites; this module cannot honestly do
that, so it works instead on the container hierarchy that already
carries MobileMT’s real scientific content:
AirborneEMDataset ->
AirborneEMLine ->
AirborneEMRecord. The public functions
below accept a dataset (or one line, normalized through
ensure_mobilemt_dataset(), this module’s ensure_sites
counterpart) and return either a tidy table or a
AirborneEMDataset – the closest honest
analogue of the rest of emtools’s “sites in, sites/table out”
contract.
ensure_mobilemt_dataset() also accepts anything
ensure_asites() does – an
AirborneSites/
AirborneSite, or a bare path/directory
of EMTF-XML files – regrouping it into an
AirborneEMDataset by each site’s
line_id (a fresh,
single-line grouping when that is unset) so a
AirborneSites produced elsewhere in
emtools – or a directory of raw MobileMT EMTF-XML – can flow
straight into this module without an intermediate
AirborneEMDataset construction step. This
is deliberately one-directional, unlike ZTEM/AFMAG’s
ensure_any_sites: the module still only ever returns a dataset
(never AirborneSites), since its
functions are organized around flight lines
(plot_mobilemt_admittance_profile() and friends plot one line’s
along-line chainage), not a flat station list.
Two kinds of quantity are computed here, and the distinction is kept visible in every column name:
Scale-invariant tensor diagnostics –
admittance_skew_table()(a Swift 1967-style skew ratio, \(|Y_{xx}+Y_{yy}| /|Y_{xy}-Y_{yx}|\), applied to the horizontal 2x2 admittance submatrix by direct algebraic analogy to the same ratio already used for the impedance tensor). Being a ratio of magnitudes, it needs no absolute physical constant and is safe to compute directly from any admittance tensor.Theoretical apparent conductivity/phase –
admittance_determinant_table()’stheoretical_*columns. In the co-located-sensor limit, the MobileMT admittance tensor equals the classical MT admittance \(Z^{-1}\) (stated explicitly by Zhdanov et al. 2024 and Sattel et al. 2019). Applying that identity to pyCSAMT’s own, already-shipped and tested Berdichevsky-determinant convention for \(Z\) (pycsamt.z.resphase.ResPhase’sres_det/phase_det, \(\rho_a = 0.2\,|\det Z|/f\), \(\varphi = \arg\sqrt{\det Z}\)) gives, by direct algebraic substitution (\(\det Y = 1/\det Z\)):\[\sigma_a = 5\,f\,|\det Y|, \qquad \varphi_a = -\arg\sqrt{\det Y}\]This is a derived theoretical quantity, not a reproduction of MobileMT’s proprietary processed apparent-conductivity product –
build_mobilemt_record()’s own docstring explicitly declines to derive that vendor quantity (“a verified delivery schema is required before pyCSAMT should codify its exact exported representation”), and this module respects that same restraint by never presenting the derivedtheoretical_*columns as the vendor product. When a record already carries the vendor-deliveredfields["apparent_conductivity"], every table here reports it alongside asapparent_conductivity_native_Smfor direct comparison, andplot_mobilemt_conductivity_psection()can plot either one explicitly via itssourceargument.
References
Prikhodko, A., Bagrianski, A., Kuzmin, P., and Sirohey, A. (2022). Natural field airborne electromagnetics – history of development and current exploration capabilities. Minerals, 12(5), 583.
Sattel, D., Witherly, K., and Kaminski, V. (2019). A brief analysis of MobileMT data. SEG International Exposition and Annual Meeting, D043S102R007.
Zhdanov, M. S., Gribenko, A., Prikhodko, A., Sabra, H. E., Jorgensen, M., and Cox, L. H. (2024). Three-dimensional MobileMT and TMI data inversions for mineral exploration. 1st ASEG DISCOVER Symposium.
Swift, C. M. (1967). A magnetotelluric investigation of an electrical conductivity anomaly in the southwestern United States. PhD thesis, MIT.
Functions
|
Return the theoretical Berdichevsky-determinant admittance table. |
|
Return a Swift (1967)-style skew table for the admittance tensor. |
|
Return a tidy per-(line, sample, frequency) admittance table. |
|
Normalize a dataset or single line to an |
|
Mask admittance/conductivity outside the usable MobileMT band. |
|
Plot one admittance component along one flight line. |
|
Plot an apparent-conductivity pseudosection for one flight line. |
|
Plot the admittance skew profile along one flight line. |
- pycsamt.emtools.mobilemt.ensure_mobilemt_dataset(obj)[source]
Normalize a dataset or single line to an
AirborneEMDataset.The single entry-point validator for every public function in this module, mirroring the role
ensure_sites()plays for the rest ofemtools.- Parameters:
obj (AirborneEMDataset or AirborneEMLine or AirborneSites or AirborneSite or str or pathlib.Path) – Accepted as-is when already a dataset; a single line is wrapped in a new one-line dataset. An
AirborneSites/AirborneSite, or a path to a single EMTF-XML file or a directory of them, is first coerced viaensure_asites()and then regrouped into flight lines byline_id(see_dataset_from_asites()).- Return type:
- Raises:
TypeError – If obj is none of the accepted types.
- pycsamt.emtools.mobilemt.admittance_table(dataset)[source]
Return a tidy per-(line, sample, frequency) admittance table.
- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().- Returns:
Columns:
line_id,sample_id,x_m(chainage along the flight line, see_station_positions()’s along-profile convention),freq_hz,period_s, the real/imaginary parts of every entry of the horizontal 2x2 admittance (Yxx,Yxy,Yyx,Yyy) and of the vertical-field row (Yhzx,Yhzy), andapparent_conductivity_native_Sm– the vendor-delivered processed field (MOBILEMT_APPARENT_CONDUCTIVITY_FIELD) when present,NaNotherwise.- Return type:
- pycsamt.emtools.mobilemt.admittance_determinant_table(dataset)[source]
Return the theoretical Berdichevsky-determinant admittance table.
See the module docstring for the full derivation. In brief, using the horizontal 2x2 admittance submatrix \(Y = \begin{pmatrix}Y_{xx}&Y_{xy}\\Y_{yx}&Y_{yy}\end{pmatrix}\) and the co-located-sensor identity \(Y=Z^{-1}\) (Zhdanov et al. 2024; Sattel et al. 2019), applying pyCSAMT’s own \(Z\)-determinant convention (
pycsamt.z.resphase.ResPhase) by substitution gives:\[Y_{\mathrm{eff}} = \sqrt{\det Y}, \qquad \sigma_a = 5\,f\,|Y_{\mathrm{eff}}|^2, \qquad \varphi_a = -\arg(Y_{\mathrm{eff}})\]- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().- Returns:
Columns:
line_id,sample_id,x_m,freq_hz,period_s,det_abs(\(|\det Y|\)),theoretical_sigma_a_Sm,theoretical_rho_a_ohm_m(\(1/\sigma_a\)),theoretical_phase_deg, andapparent_conductivity_native_Sm(the vendor-delivered field, for direct comparison,NaNwhen absent). Samples with a non-finite determinant are omitted.- Return type:
Notes
The
theoretical_*columns are a derived quantity assuming ideal co-located sensors; they are not a reproduction of MobileMT’s proprietary processed apparent-conductivity output. Preferapparent_conductivity_native_Smwhenever it is present.
- pycsamt.emtools.mobilemt.admittance_skew_table(dataset)[source]
Return a Swift (1967)-style skew table for the admittance tensor.
\[\mathrm{skew} = \frac{|Y_{xx} + Y_{yy}|}{|Y_{xy} - Y_{yx}|}\]applied to the horizontal 2x2 admittance submatrix by direct algebraic analogy to the identical ratio already used for the impedance tensor elsewhere in pyCSAMT. Being a ratio of magnitudes, it needs no absolute physical constant and is safe to compute directly, unlike
admittance_determinant_table()’stheoretical_*columns. Large values flag departures from an ideal 1D/2D-consistent admittance tensor (instrument coupling, cultural noise, genuinely 3-D structure).- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().- Returns:
Columns:
line_id,sample_id,x_m,freq_hz,period_s,skew. Non-finite values are omitted.- Return type:
- pycsamt.emtools.mobilemt.mask_outside_mobilemt_band(dataset, *, band_hz=None, system_spec=None, inplace=False)[source]
Mask admittance/conductivity outside the usable MobileMT band.
Reuses the published usable bandwidth already carried by
MobileMTSystemSpec(defaultnominal_frequency_range_hzof 19-26,000 Hz) rather than inventing a new band definition. This is the one function in this module meant to sit inside a processing pipeline (dataset in, dataset out) rather than only produce a diagnostic table – the closest analogue here toflag_motion_susceptible_band()andmask_outside_ztem_band().Unlike those two functions, only masking is offered (no
action="drop"): eachAirborneEMRecordpackages its admittance transfer function and any auxiliary per-frequency fields (variance, covariances, native apparent conductivity) around one shared period axis, and safely dropping frequencies would require rebuilding all of them consistently. Masking withnanneeds no such reconstruction and never confuses “known bad” with a physical zero.- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().band_hz ((float, float), optional) – Explicit
(low, high)band in Hz. Mutually exclusive with system_spec; when neither is given, a defaultMobileMTSystemSpec’snominal_frequency_range_hzis used.system_spec (MobileMTSystemSpec, optional) – Survey-specific system metadata to read the band from.
inplace (bool, default False) – When
False(default), a deep copy of dataset is masked and returned, leaving the input untouched.
- Returns:
The (optionally new) dataset with out-of-band admittance values and native apparent-conductivity samples set to
nan.- Return type:
- Raises:
ValueError – If both band_hz and system_spec are given.
TypeError – If system_spec is given and is not a
MobileMTSystemSpec.
- pycsamt.emtools.mobilemt.plot_mobilemt_admittance_profile(dataset, *, line_id=None, component='det', part='abs', frequency_hz=None, period_s=None, figsize=(9.5, 4.0), ax=None)[source]
Plot one admittance component along one flight line.
- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().line_id (str, optional) – Flight line to plot; defaults to the first line in dataset.
component ({"xx", "xy", "yx", "yy", "hzx", "hzy", "det"}, default "det") – Admittance entry to plot, or
"det"for the horizontal 2x2 determinant (seeadmittance_determinant_table()).part ({"real", "imag", "abs"}, default "abs")
frequency_hz (float, optional) – Reference frequency/period; nearest available value is used per sample. At most one may be given; the median frequency is used when neither is given.
period_s (float, optional) – Reference frequency/period; nearest available value is used per sample. At most one may be given; the median frequency is used when neither is given.
figsize ((float, float), default (9.5, 4.0)) – Used only when ax is not supplied.
ax (matplotlib.axes.Axes, optional) – Existing axes to draw on.
- Return type:
- pycsamt.emtools.mobilemt.plot_mobilemt_conductivity_psection(dataset, *, line_id=None, source='theoretical', cmap='viridis', clim=None, clim_pct=(2.0, 98.0), figsize=(9.0, 5.0), ax=None)[source]
Plot an apparent-conductivity pseudosection for one flight line.
- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().line_id (str, optional) – Flight line to plot; defaults to the first line in dataset.
source ({"theoretical", "native"}, default "theoretical") –
"theoretical"plotsadmittance_determinant_table()’s derivedtheoretical_sigma_a_Sm(see the module docstring for the caveat);"native"plots the vendor-deliveredapparent_conductivity_native_Smfield, when present.cmap (str, default "viridis")
clim ((float, float), optional) – Explicit color limits; overrides clim_pct.
clim_pct ((float, float), default (2.0, 98.0)) – Percentile color limits when clim is not given.
figsize ((float, float), default (9.0, 5.0)) – Used only when ax is not supplied.
ax (matplotlib.axes.Axes, optional) – Existing axes to draw on.
- Return type:
- Raises:
ValueError – If source is not
"theoretical"or"native".
- pycsamt.emtools.mobilemt.plot_mobilemt_skew_profile(dataset, *, line_id=None, frequency_hz=None, period_s=None, figsize=(9.5, 4.0), ax=None)[source]
Plot the admittance skew profile along one flight line.
See
admittance_skew_table()for the underlying formula.- Parameters:
dataset (AirborneEMDataset or AirborneEMLine) – Anything accepted by
ensure_mobilemt_dataset().line_id (str, optional) – Flight line to plot; defaults to the first line in dataset.
frequency_hz (float, optional) – Reference frequency/period; nearest available value is used per sample. At most one may be given; the median frequency is used when neither is given.
period_s (float, optional) – Reference frequency/period; nearest available value is used per sample. At most one may be given; the median frequency is used when neither is given.
figsize ((float, float), default (9.5, 4.0)) – Used only when ax is not supplied.
ax (matplotlib.axes.Axes, optional) – Existing axes to draw on.
- Return type: