pycsamt.iot.bridge#

Bridge between IoT field telemetry and the pyCSAMT data model.

The rest of the pycsamt.iot subpackage is deliberately lean: it processes raw arrays and telemetry with numpy only and never imports the heavier pyCSAMT data model. That keeps import pycsamt.iot cheap on a field gateway. This module is the one place where the two worlds meet, so every data-model import (pycsamt.seg, pycsamt.site) is done lazily inside the functions that need it.

Two directions are supported.

Forward — acquisition to data model. Turn edge impedance estimates into first-class objects that the processing/inversion flow understands:

Reverse — data model to acquisition planning. Seed an IoT deployment from a previous survey so known station geometry can be re-occupied:

Example

>>> import numpy as np
>>> from pycsamt.iot.bridge import impedance_to_z, z_to_edi
>>> freq = np.logspace(4, 0, 12)
>>> zxy = (1 + 1j) * np.sqrt(freq)          # one scalar sounding
>>> z = impedance_to_z(zxy, freq, station="S01")
>>> path = z_to_edi(z, station="S01", lat=6.5, lon=3.4,
...                 savepath="edi_out")

Functions

build_edifile(z, *, station[, lat, lon, ...])

Assemble an in-memory EDIFile from an impedance tensor.

deployment_from_edis(sources, *, survey_id)

Seed a DeploymentConfig from an EDI survey.

edi_survey_table(sources, *[, api])

Return an EDI-survey summary as a pyCSAMT table.

emtools_qc(source[, impedance, freq, ...])

Route IoT-acquired impedance through pycsamt.emtools QC.

field_session_from_edis(sources, *, survey_id)

Seed a FieldSession from an EDI survey.

field_session_to_edifiles(session, impedance)

Build per-station EDIs from a session plus impedance estimates.

impedance_to_z(impedance, freq, *[, ...])

Build a Z from edge impedance estimates.

read_edi_survey(sources)

Read an EDI survey into per-station summary records.

z_to_edi(z, *, station[, savepath, ...])

Write an impedance tensor to a .edi file and return its path.

z_to_site(z, *, station[, lat, lon, ...])

Return an EDI-backed Site for z.

pycsamt.iot.bridge.impedance_to_z(impedance, freq, *, impedance_err=None, station=None, method=None, component='offdiag', aggregate='mean')[source]#

Build a Z from edge impedance estimates.

This is the natural continuation of the edge diagnostics: the field node already forms per-window impedance estimates (see assess_impedance_stability()); this turns them into the impedance-tensor container the processing and inversion flow consumes.

Parameters:
  • impedance (array-like of complex) –

    Accepted shapes, with n = len(freq):

    • (n,) — one scalar impedance per frequency, placed according to component (an off-diagonal antisymmetric tensor by default);

    • (n, 2, 2) — a full impedance tensor per frequency;

    • (n_windows, n) — per-window scalar estimates, aggregated across windows (error taken from the window spread);

    • (n_windows, n, 2, 2) — per-window tensors, aggregated;

    • (2, 2) — a single tensor (only when n == 1).

  • freq (array-like of float) – Strictly positive frequency vector in Hz.

  • impedance_err (array-like, optional) – Explicit absolute errors matching the aggregated impedance shape. Overrides any error derived from window spread.

  • station (str, optional) – Name attached to the returned Z.

  • method (str, optional) – Acquisition method ("amt", "mt", "csamt") recorded in the object metadata.

  • component ({'offdiag', 'xy', 'yx'}) – Placement for scalar inputs.

  • aggregate ({'mean', 'median'}) – Reduction across a window axis when one is present.

Return type:

pycsamt.z.z.Z

pycsamt.iot.bridge.build_edifile(z, *, station, lat=None, lon=None, elevation=None, method=None, acqby='pycsamt.iot', metadata=None)[source]#

Assemble an in-memory EDIFile from an impedance tensor.

The container carries the minimum valid SEG-EDI structure — a >HEAD block (station id and geometry), a >=MTSECT measurement section, and the impedance transfer function — so it round-trips through pycsamt.seg.edi.EDIFile.write().

Parameters:
  • z (pycsamt.z.z.Z) – Impedance tensor for one station.

  • station (str) – Station / DATAID label.

  • lat (float, optional) – Station location written to the EDI head.

  • lon (float, optional) – Station location written to the EDI head.

  • elevation (float, optional) – Station location written to the EDI head.

  • method (str, optional) – Acquisition method recorded as an EDI info note.

  • acqby (str) – ACQBY value; defaults to a pyCSAMT-IoT provenance tag.

  • metadata (mapping, optional) – Extra head attributes (e.g. county, prospect).

Return type:

pycsamt.seg.edi.EDIFile

pycsamt.iot.bridge.z_to_edi(z, *, station, savepath=None, filename=None, lat=None, lon=None, elevation=None, method=None, datatype=None, acqby='pycsamt.iot', metadata=None)[source]#

Write an impedance tensor to a .edi file and return its path.

See build_edifile() for the assembled structure. datatype is forwarded to pycsamt.seg.edi.EDIFile.write() and is auto-detected (MT) when left as None.

Parameters:
Return type:

str

pycsamt.iot.bridge.field_session_to_edifiles(session, impedance, freq=None, *, savepath=None, method=None, write=False, acqby='pycsamt.iot')[source]#

Build per-station EDIs from a session plus impedance estimates.

Station geometry (lat/lon/elevation) is taken from the session’s registered stations, so the resulting EDIs carry the field-recorded location without any manual bookkeeping.

Parameters:
  • session (pycsamt.iot.session.FieldSession) – Source of station geometry and the observed method.

  • impedance (mapping) – {station_id: value} where value is a Z, a (impedance_array, freq) pair, or an impedance array paired with the shared freq argument.

  • freq (array-like, optional) – Shared frequency vector used for array values that do not carry their own frequencies.

  • savepath (str, optional) – Directory for written files (used only when write=True).

  • method (str, optional) – Overrides the session method recorded in each EDI.

  • write (bool) – When True the EDIs are written and the returned mapping holds file paths; otherwise it holds in-memory EDIFile objects.

  • acqby (str) – ACQBY provenance tag.

Returns:

{station_id: EDIFile} or {station_id: path}.

Return type:

dict

pycsamt.iot.bridge.z_to_site(z, *, station, lat=None, lon=None, elevation=None, method=None)[source]#

Return an EDI-backed Site for z.

Unlike FieldSession.to_sites(), which returns acquisition descriptors, this yields a real Site built on an EDIFile and therefore requires the optional geospatial stack (pyproj).

Parameters:
Return type:

Any

pycsamt.iot.bridge.emtools_qc(source, impedance=None, freq=None, *, method=None, flags=False, api=None, **kwargs)[source]#

Route IoT-acquired impedance through pycsamt.emtools QC.

Running the same coherence/skew/SNR quality control that downstream processing uses keeps field-side and post-processing QC consistent, rather than having two independent notions of a “good” station.

Parameters:
  • source (FieldSession, site.Sites, or EDI source) – A FieldSession (with impedance), an already-built Sites collection, or any EDI source accepted by read_edi_survey() (directory, glob, file, EDIFile, …).

  • impedance (mapping, optional) – Per-station impedance, required when source is a session (see field_session_to_edifiles() for the accepted forms).

  • freq (array-like, optional) – Shared frequency vector for impedance arrays without their own.

  • method (str, optional) – Acquisition method recorded on the built EDIs.

  • flags (bool) – When True return pycsamt.emtools.qc.qc_flags() (per-station pass/flag verdicts); otherwise pycsamt.emtools.qc.build_qc_table() (the full QC metrics table).

  • api (bool, optional) – Forwarded to the emtools helper’s table wrapper.

  • **kwargs – Forwarded to the emtools helper (thresholds such as min_frac_ok, min_snr_med, max_skew_med).

Return type:

A pyCSAMT QC table (or flags table).

Notes

Requires the optional geospatial stack (pyproj), since emtools QC operates on EDI-backed sites.

pycsamt.iot.bridge.read_edi_survey(sources)[source]#

Read an EDI survey into per-station summary records.

Parameters:

sources (str, path, EDIFile, or iterable thereof) – A directory of .edi files, a glob pattern, a single file or EDIFile, or any iterable mixing these.

Returns:

One record per station with station, lat, lon, elevation, n_freq, f_min_hz, f_max_hz, and channels.

Return type:

list of dict

pycsamt.iot.bridge.edi_survey_table(sources, *, api=None)[source]#

Return an EDI-survey summary as a pyCSAMT table.

Parameters:
Return type:

Any

pycsamt.iot.bridge.field_session_from_edis(sources, *, survey_id, protocol='mqtt', role='sensor_node', operator=None, method=None, device_suffix='-node')[source]#

Seed a FieldSession from an EDI survey.

Every station in sources becomes a registered station (with its recorded geometry and channels) and a sensor node, ready to be re-occupied in a follow-up IoT-enabled campaign.

Parameters:
  • sources (str, path, EDIFile, or iterable thereof) – The EDI survey to import (see read_edi_survey()).

  • survey_id (str) – Identifier for the new session.

  • protocol (str) – Telemetry protocol assigned to each seeded device.

  • role (str) – Device role for each seeded node.

  • operator (str, optional) – Operator recorded on the session.

  • method (str, optional) – Acquisition method recorded on the session.

  • device_suffix (str) – Suffix appended to a station id to form its device id.

Return type:

pycsamt.iot.session.FieldSession

pycsamt.iot.bridge.deployment_from_edis(sources, *, survey_id, protocol='mqtt', role='sensor_node', capabilities=None, device_suffix='-node')[source]#

Seed a DeploymentConfig from an EDI survey.

A lighter-weight counterpart to field_session_from_edis() that returns just the deployment inventory (one device per station), useful for planning device provisioning from a prior survey’s station list.

Parameters:
Return type:

Any