pycsamt.metadata#

Survey, frequency, quality, instrument, geology, and rock metadata helpers.

Survey metadata, frequency bands, references, and software provenance.

class pycsamt.metadata.Reference(author, title, journal=None, year=None, volume=None, pages=None, doi=None, extra=<factory>)#

Bases: object

Bibliographic reference information.

Variables:
  • author (str) – Author list, e.g. “Doe, J.; Smith, A.”.

  • title (str) – Title of the work.

  • journal (Optional[str]) – Journal or publication name.

  • year (Optional[int]) – Year of publication.

  • volume (Optional[str]) – Volume number or identifier.

  • pages (Optional[str]) – Page range, e.g. “123–130”.

  • doi (Optional[str]) – Digital Object Identifier, e.g. “10.1000/xyz123”.

  • extra (Dict[str, Any]) – Any additional fields.

Parameters:
author: str#
title: str#
journal: str | None = None#
year: int | None = None#
volume: str | None = None#
pages: str | None = None#
doi: str | None = None#
extra: dict[str, Any]#
DOI_PATTERN = re.compile('^10\\.\\d{4,9}/[-._;()/:A-Z0-9]+$', re.IGNORECASE)#
to_dict()#

Return all reference fields as a dict.

Return type:

dict[str, Any]

classmethod from_dict(data)#

Construct a Reference from a dict.

Parameters:

data (dict[str, Any])

Return type:

Reference

to_bibtex(key)#

Export this reference as a BibTeX entry.

Parameters:

key (str) – Citation key, e.g. “Doe2021”.

Returns:

Multi-line BibTeX entry.

Return type:

str

class pycsamt.metadata.CopyrightInfo(release_status, conditions_of_use, reference=<factory>, extra=<factory>)#

Bases: object

Copyright and usage conditions.

Variables:
  • release_status (str) – e.g. “open”, “public”, “proprietary”.

  • conditions_of_use (str) – Text describing usage terms.

  • reference (Reference) – Citation for data source.

  • extra (Dict[str, Any]) – Additional fields.

Parameters:
release_status: str#
conditions_of_use: str#
reference: Reference#
extra: dict[str, Any]#
to_dict()#
Return type:

dict[str, Any]

class pycsamt.metadata.Person(name=None, email=None, organization=None, organization_url=None, extra=<factory>)#

Bases: object

Person contact information.

Variables:
  • name (Optional[str])

  • email (Optional[str])

  • organization (Optional[str])

  • organization_url (Optional[str])

  • extra (Dict[str, Any])

Parameters:
  • name (str | None)

  • email (str | None)

  • organization (str | None)

  • organization_url (str | None)

  • extra (dict[str, Any])

name: str | None = None#
email: str | None = None#
organization: str | None = None#
organization_url: str | None = None#
extra: dict[str, Any]#
to_dict()#
Return type:

dict[str, Any]

class pycsamt.metadata.Software(name, version=None, release=None, author=<factory>, extra=<factory>)#

Bases: object

Software metadata.

Variables:
Parameters:
name: str#
version: str | None = None#
release: str | None = None#
author: Person#
extra: dict[str, Any]#
to_dict()#
Return type:

dict[str, Any]

class pycsamt.metadata.RockProperties#

Bases: object

Access and query geological rock metadata:
  • resistivity ranges

  • plotting hatch patterns

Examples

>>> rp = RockProperties()
>>> rp.get_resistivity("shale")
[50.12, 32.0]
>>> pattern, color = rp.get_pattern("shale")
"=", (0.0, 0.0, 0.7)
property resistivity_ranges: dict[str, list[float]]#

All resistivity ranges keyed by rock name.

property hatch_patterns: dict[str, tuple[str, tuple[float, float, float]]]#

All hatch patterns keyed by rock name.

get_resistivity(rock)#

Return [max, min] resistivity for a given rock.

Raises KeyError if rock not found.

Parameters:

rock (str)

Return type:

list[float]

get_pattern(rock)#

Return (hatch, color) tuple for a given rock.

Raises KeyError if rock not found.

Parameters:

rock (str)

Return type:

tuple[str, tuple[float, float, float]]

find_matching_rocks(keyword)#

Return list of rock names containing keyword (case‑insensitive).

Parameters:

keyword (str)

Return type:

list[str]

class pycsamt.metadata.BBox(lat_min, lat_max, lon_min, lon_max)#

Bases: object

Geographic bounding box in decimal degrees (WGS-84 default).

Parameters:
  • lat_min (float) – Latitude bounds in decimal degrees (south → north).

  • lat_max (float) – Latitude bounds in decimal degrees (south → north).

  • lon_min (float) – Longitude bounds in decimal degrees (west → east).

  • lon_max (float) – Longitude bounds in decimal degrees (west → east).

Examples

bbox = BBox(27.8, 28.9, 101.5, 103.2)
assert 28.0 in bbox           # latitude membership test
print(bbox.centre)            # (28.35, 102.35)
print(bbox.area_deg2)         # 1.1 × 1.7 ≈ 1.87 deg²
lat_min: float#
lat_max: float#
lon_min: float#
lon_max: float#
property centre: tuple[float, float]#

Return (lat, lon) centre of the box.

property area_deg2: float#

Return the area of the box in squared degrees.

property span_lat: float#
property span_lon: float#
contains(lat, lon)#

Return True when (lat, lon) lies inside or on the boundary.

Parameters:
Return type:

bool

to_dict()#
Return type:

dict[str, float]

classmethod from_dict(d)#
Parameters:

d (dict[str, Any])

Return type:

BBox

classmethod from_coords(lats, lons)#

Build a tight bounding box from lists of coordinates.

Parameters:
Return type:

BBox

class pycsamt.metadata.SurveyMeta(name, project=None, operator=None, method='MT', bbox=None, date_start=None, date_end=None, crs='WGS84', n_stations=None, notes='', extra=<factory>)#

Bases: object

Campaign-level descriptor for an MT/AMT/CSAMT/TEM survey.

Parameters:
  • name (str) – Short survey identifier (e.g. "WILLY_L18_2023").

  • project (str, optional) – Parent project name (e.g. "Copper-gold exploration").

  • operator (str, optional) – Acquisition company or institution.

  • method (str, default "MT") – EM method: "MT", "AMT", "CSAMT", "TEM", "CSEM", "BBMT", "LAMT", or "LMT".

  • bbox (BBox, optional) – Geographic bounding box of all station locations.

  • date_start (date, optional) – First day of field acquisition.

  • date_end (date, optional) – Last day of field acquisition.

  • crs (str, default "WGS84") – Coordinate reference system name.

  • n_stations (int, optional) – Total number of stations.

  • notes (str) – Free-form annotation.

  • extra (dict) – Arbitrary additional fields preserved on round-trips.

Examples

meta = SurveyMeta(
    name="WILLY_L18",
    project="Phase-III drill targeting",
    operator="EarthAI-Tech",
    method="AMT",
    bbox=BBox(27.8, 28.9, 101.5, 103.2),
    n_stations=128,
)
print(meta.duration_days)   # None (no dates set)

# build from a Sites collection:
meta2 = SurveyMeta.from_sites(sites, name="survey_A")

# JSON round-trip:
meta.to_json("survey_meta.json")
meta3 = SurveyMeta.from_json("survey_meta.json")
name: str#
project: str | None = None#
operator: str | None = None#
method: str = 'MT'#
bbox: BBox | None = None#
date_start: date | None = None#
date_end: date | None = None#
crs: str = 'WGS84'#
n_stations: int | None = None#
notes: str = ''#
extra: dict[str, Any]#
property duration_days: int | None#

Number of acquisition days, or None when dates are incomplete.

property is_complete: bool#

Return True when all key descriptors are populated.

classmethod from_sites(sites, name='survey', method='MT', **kwargs)#

Build a SurveyMeta from a Sites collection.

Parameters:
  • sites (Any) – Sites or any iterable of Site-like objects exposing .coords (lat, lon, elev).

  • name (str) – Survey name to assign.

  • method (str) – EM method label.

  • **kwargs – Additional fields forwarded to the constructor.

Return type:

SurveyMeta

update_edi_head(head)#

Push survey fields into an EDI Head.

Only non-None fields are written so existing values are not overwritten unless a replacement is explicitly provided.

Parameters:

head (Head) – An EDI Head instance.

Return type:

None

to_dict()#

Return all fields as a plain JSON-serialisable dict.

Return type:

dict[str, Any]

classmethod from_dict(d)#

Reconstruct from a plain dict (as produced by to_dict()).

Parameters:

d (dict[str, Any])

Return type:

SurveyMeta

to_json(path=None)#

Serialise to a JSON string (optionally write to path).

Parameters:

path (str | Path | None)

Return type:

str

classmethod from_json(path)#

Load from a JSON file.

Parameters:

path (str | Path)

Return type:

SurveyMeta

to_yaml(path=None)#

Serialise to a YAML string (optionally write to path).

Parameters:

path (str | Path | None)

Return type:

str

classmethod from_yaml(path)#

Load from a YAML file.

Parameters:

path (str | Path)

Return type:

SurveyMeta

summary()#

Return a compact one-paragraph summary string.

Return type:

str

class pycsamt.metadata.Formation(name, resistivity_range, depth_range, n_layers_range, description='', rock_types=<factory>, extra=<factory>)#

Bases: object

A named geological scenario for layered-Earth modelling.

Parameters:
  • name (str) – Unique identifier (lower-case, e.g. "sedimentary").

  • resistivity_range (tuple[float, float]) – Expected resistivity interval (Ω·m) as (rho_min, rho_max).

  • depth_range (tuple[float, float]) – Typical investigation depth range (m) as (depth_min, depth_max).

  • n_layers_range (tuple[int, int]) – Plausible number of layers for synthetic generation, (n_min, n_max).

  • description (str) – Free-text geological description.

  • rock_types (list[str]) – Rock type names that correspond to entries in GEO_ROCK_RESISTIVITY.

  • extra (dict) – Arbitrary additional parameters preserved on round-trips.

Examples

f = Formation(
    name="hydrothermal",
    resistivity_range=(1.0, 1e3),
    depth_range=(200, 3000),
    n_layers_range=(3, 6),
    description="Hydrothermal alteration zone",
)
print(f.rho_mid, f.log_rho_range)
name: str#
resistivity_range: tuple[float, float]#
depth_range: tuple[float, float]#
n_layers_range: tuple[int, int]#
description: str = ''#
rock_types: list[str]#
extra: dict[str, Any]#
property log_rho_range: tuple[float, float]#

Log10-resistivity interval (log_rho_min, log_rho_max).

property rho_mid: float#

Geometric-mean resistivity (Ω·m).

property depth_mid: float#

Arithmetic-mean depth (m).

property n_layers_mid: int#

Midpoint of the n_layers range, rounded.

to_prior()#

Return a dict compatible with LayeredModel.from_geology(name).

The returned dict has keys n_layers, log_rho_range, depth_max_range, and description — exactly the format expected by GEOLOGY_PRIORS in forward/synthetic.py.

Return type:

dict[str, Any]

to_dict()#
Return type:

dict[str, Any]

classmethod from_dict(d)#
Parameters:

d (dict[str, Any])

Return type:

Formation

classmethod from_prior(name, prior)#

Build a Formation from a GEOLOGY_PRIORS entry.

Parameters:
Return type:

Formation

class pycsamt.metadata.GeologyCatalog(formations=None)#

Bases: object

Registry of geological formations for layered-Earth modelling.

Parameters:

formations (list of Formation, optional) – Initial formations. When omitted the built-in catalog is loaded.

Examples

from pycsamt.metadata.geology import CATALOG

# list all names
print(CATALOG.names())

# look up by name
f = CATALOG.get("sedimentary")

# find closest by resistivity
matches = CATALOG.lookup_by_resistivity(50.0, n=3)

# add a custom formation
CATALOG.add(Formation(
    name="custom",
    resistivity_range=(5.0, 200.0),
    depth_range=(100, 500),
    n_layers_range=(3, 5),
))

# export to a pandas DataFrame
df = CATALOG.to_dataframe()
add(formation)#

Register formation, overwriting any existing entry with the same name.

Parameters:

formation (Formation)

Return type:

None

remove(name)#

Remove formation by name (raises KeyError when absent).

Parameters:

name (str)

Return type:

None

reset()#

Restore the built-in catalog, discarding custom additions.

Return type:

None

get(name)#

Return the Formation for name.

Raises:

KeyError – When name is not in the catalog.

Parameters:

name (str)

Return type:

Formation

names()#

Return a sorted list of all registered formation names.

Return type:

list[str]

lookup_by_resistivity(rho, n=3)#

Return the n formations whose resistivity range best covers rho.

Matching priority:

  1. Formations whose interval contains rho (sorted by narrowest range).

  2. Formations nearest to rho in log10 space.

Parameters:
  • rho (float) – Query resistivity in Ω·m.

  • n (int) – Maximum number of results to return.

Return type:

list[Formation]

lookup_by_depth(depth_m, n=3)#

Return formations whose depth range contains depth_m (metres).

Parameters:
Return type:

list[Formation]

lookup_by_rock_type(rock_type)#

Return formations that list rock_type in their rock_types.

Parameters:

rock_type (str)

Return type:

list[Formation]

all_scenarios()#

Return a copy of the internal store (name → Formation).

Return type:

dict[str, Formation]

to_prior(name)#

Return a GEOLOGY_PRIORS-compatible dict for name.

This is the adapter used by from_geology().

Parameters:

name (str)

Return type:

dict[str, Any]

to_dataframe(*, api=None)#

Return a pandas.DataFrame with one row per formation.

Parameters:

api (bool | None)

Return type:

Any

pycsamt.metadata.geology_prior(name)#

Return a GEOLOGY_PRIORS-compatible dict for name.

This is a drop-in replacement for direct access to the old GEOLOGY_PRIORS dict in forward/synthetic.py.

Parameters:

name (str) – Formation name (case-insensitive).

Returns:

Keys: n_layers, log_rho_range, depth_max_range, description.

Return type:

dict

class pycsamt.metadata.QualityFlag(*values)#

Bases: str, Enum

Data-quality classification for one component or a whole station.

Variables:
  • GOOD ("good") – Coverage ≥ 90 %; component is reliable for inversion.

  • PARTIAL ("partial") – 50 % ≤ coverage < 90 %; component has significant gaps.

  • POOR ("poor") – 0 % < coverage < 50 %; component is largely missing or noisy.

  • MISSING ("missing") – Zero finite values; component is absent.

GOOD = 'good'#
PARTIAL = 'partial'#
POOR = 'poor'#
MISSING = 'missing'#
classmethod from_coverage(coverage)#

Return the flag that matches coverage (0–1).

Parameters:

coverage (float)

Return type:

QualityFlag

property rank: int#

Numeric severity rank (0 = worst, 3 = best).

classmethod worst(flags)#

Return the worst (lowest-rank) flag in flags.

Parameters:

flags (list[QualityFlag])

Return type:

QualityFlag

classmethod best(flags)#

Return the best (highest-rank) flag in flags.

Parameters:

flags (list[QualityFlag])

Return type:

QualityFlag

class pycsamt.metadata.ComponentQuality(name, coverage, n_valid, n_total, snr_mean=None, snr_std=None)#

Bases: object

Quality metrics for a single impedance component.

Parameters:
  • name (str) – Component label: "Zxx", "Zxy", "Zyx", "Zyy", or "Tipper".

  • coverage (float) – Fraction of finite values in the frequency range (0–1).

  • n_valid (int) – Number of frequencies with finite values.

  • n_total (int) – Total number of frequencies.

  • flag (QualityFlag) – Auto-computed classification from coverage.

  • snr_mean (float, optional) – Mean signal-to-noise ratio (dB) when available.

  • snr_std (float, optional) – Standard deviation of the SNR (dB) when available.

Examples

cq = ComponentQuality.from_array("Zxy", z_arr)
print(cq.flag)          # QualityFlag.GOOD
print(cq.pct_str)       # "100%"
name: str#
coverage: float#
n_valid: int#
n_total: int#
flag: QualityFlag#
snr_mean: float | None = None#
snr_std: float | None = None#
property pct_str: str#

Coverage as a formatted percentage string.

classmethod from_array(name, arr, snr=None)#

Compute quality from a raw array.

Parameters:
  • name (str) – Component label.

  • arr (array-like or None) – Raw complex or real impedance values; shape (n,) or (n, 2, 2) (only the relevant component is expected).

  • snr (array-like, optional) – Per-frequency SNR values in dB (same length as arr).

Return type:

ComponentQuality

to_dict()#
Return type:

dict[str, Any]

class pycsamt.metadata.DataQuality(station, n_freq, freq_min=None, freq_max=None, components=<factory>)#

Bases: object

Data-quality summary for a single MT station.

Parameters:
  • station (str) – Station identifier.

  • n_freq (int) – Total number of frequencies.

  • freq_min (float, optional) – Minimum frequency (Hz).

  • freq_max (float, optional) – Maximum frequency (Hz).

  • components (list of ComponentQuality) – Per-component quality records.

  • overall (QualityFlag) – Worst flag across all present components (auto-computed).

Examples

dq = DataQuality.from_site(site)
print(dq.overall)
print(dq.get("Zxy").coverage)
df_row = dq.to_dict()
station: str#
n_freq: int#
freq_min: float | None = None#
freq_max: float | None = None#
components: list[ComponentQuality]#
overall: QualityFlag#
classmethod from_site(site)#

Build a DataQuality from a Site-like object.

Accepts any object exposing .name, .freq, .z, and .tipper (as per SiteMixin).

Parameters:

site (Any)

Return type:

DataQuality

classmethod from_edi(edi_path)#

Build from a spectra/impedance EDI file path.

Parameters:

edi_path (Any)

Return type:

DataQuality

get(name)#

Return ComponentQuality for name, or None.

Parameters:

name (str)

Return type:

ComponentQuality | None

property z_components: list[ComponentQuality]#

Return only the Z-tensor component records.

property has_tipper: bool#
property mean_coverage: float#

Mean coverage across all components that have data.

summary()#

Return a compact multi-line summary.

Return type:

str

to_dict()#
Return type:

dict[str, Any]

pycsamt.metadata.assess_collection(sites)#

Compute DataQuality for every site in sites.

Parameters:

sites (Any) – Iterable of Site-like objects (e.g. Sites).

Return type:

list of DataQuality

pycsamt.metadata.quality_dataframe(sites, *, api=None)#

Return a pandas.DataFrame with one quality row per station.

Columns: station, n_freq, freq_min, freq_max, overall, mean_coverage, and one cov_<component> column per impedance component.

Parameters:
Return type:

Any

class pycsamt.metadata.FrequencyBand(name, label, f_min, f_max, method, doi_ref_rho=100.0, notes='')#

Bases: object

Specification of an EM geophysical frequency band.

Parameters:
  • name (str) – Short identifier, e.g. "AMT".

  • label (str) – Human-readable name, e.g. "Audio-frequency MT".

  • f_min (float) – Minimum operational frequency in Hz.

  • f_max (float) – Maximum operational frequency in Hz.

  • method (str) – EM acquisition method: "MT", "AMT", "CSAMT", "TEM", "CSEM", etc.

  • doi_ref_rho (float, default 100.0) – Reference resistivity (Ω·m) used to compute DOI estimates via the skin-depth formula.

  • notes (str) – Optional annotation.

  • attributes (Computed)

  • -------------------

  • period_min (float) – Period bounds derived from f_max and f_min.

  • period_max (float) – Period bounds derived from f_max and f_min.

  • n_decades (float) – Number of frequency decades spanned by the band.

Examples

b = MT_BANDS["AMT"]
print(b.f_min, b.f_max)          # 10.0  100000.0
print(b.period_range)            # (1e-5, 0.1) s
print(b.doi_range_m())           # DOI at 100 Ω·m
print(b.doi_range_m(rho=10.0))   # DOI at 10 Ω·m

# log-spaced frequencies
freqs = b.logspace(30)

# test membership
assert 1000.0 in b
name: str#
label: str#
f_min: float#
f_max: float#
method: str#
doi_ref_rho: float = 100.0#
notes: str = ''#
property period_min: float#

Minimum period in seconds (= 1 / f_max).

property period_max: float#

Maximum period in seconds (= 1 / f_min).

property period_range: tuple[float, float]#

(period_min, period_max) in seconds.

property frequency_range: tuple[float, float]#

(f_min, f_max) in Hz.

property n_decades: float#

Number of frequency decades in the band.

skin_depth_m(f, rho=None)#

Skin depth δ (m) at frequency f and resistivity rho.

Formula: δ ≈ 503.3 √(ρ / f)

Parameters:
  • f (float) – Frequency in Hz.

  • rho (float, optional) – Resistivity in Ω·m; defaults to doi_ref_rho.

Return type:

float

doi_range_m(rho=None)#

Return the (shallow, deep) depth-of-investigation estimate in metres.

Shallow DOI corresponds to f_max; deep DOI to f_min.

Parameters:

rho (float, optional) – Resistivity in Ω·m; defaults to doi_ref_rho.

Return type:

tuple[float, float]

logspace(n=30)#

Return n log-spaced frequencies inside the band (Hz).

Parameters:

n (int, default 30) – Number of frequencies.

Return type:

ndarray

contains(f)#

Return True when f (Hz) lies within the band.

Parameters:

f (float)

Return type:

bool

overlaps(other)#

Return True when self and other share any frequency.

Parameters:

other (FrequencyBand)

Return type:

bool

intersection(other)#

Return the (f_min, f_max) intersection with other, or None.

Parameters:

other (FrequencyBand)

Return type:

tuple[float, float] | None

clip_frequencies(freqs)#

Return only those elements of freqs that lie inside the band.

Parameters:

freqs (Any)

Return type:

ndarray

to_dict()#
Return type:

dict[str, Any]

pycsamt.metadata.band_for_frequency(f, registry=None)#

Return all bands in the registry that contain f Hz.

Parameters:
  • f (float) – Query frequency in Hz.

  • registry (dict, optional) – Registry to search; defaults to REGISTRY.

Returns:

Sorted from narrowest to widest (fewest to most decades).

Return type:

list of FrequencyBand

pycsamt.metadata.frequency_range(method, registry=None)#

Return (f_min, f_max) for a named method or band.

Parameters:
  • method (str) – Band name (e.g. "AMT") or method string (e.g. "CSAMT"). Case-insensitive. When multiple bands share the same method, the union range is returned.

  • registry (dict, optional) – Registry to search; defaults to REGISTRY.

Returns:

(f_min, f_max) in Hz.

Return type:

tuple[float, float]

Raises:

KeyError – When method is not found in any band.

pycsamt.metadata.doi_estimate(f, rho=100.0)#

Return the skin-depth DOI estimate in metres at frequency f.

Parameters:
  • f (float) – Frequency in Hz.

  • rho (float, default 100.0) – Reference resistivity in Ω·m.

Return type:

float

pycsamt.metadata.register_band(band)#

Add or replace a FrequencyBand in the global registry.

Parameters:

band (FrequencyBand) – The band to register under band.name.

Return type:

None

class pycsamt.metadata.SensorSpec(sensor_type='induction_coil', model='', frequency_range=None, notes='')#

Bases: object

Specification for a single sensor (magnetic or electric).

Parameters:
  • sensor_type ({"induction_coil", "fluxgate", "electrode", "other"}) – Physical transducer principle.

  • model (str) – Manufacturer model string, e.g. "MTC-150H".

  • frequency_range (tuple[float, float] or None) – (f_min, f_max) in Hz that the sensor is rated for.

  • notes (str) – Free-text annotation (calibration file name, mounting details, etc.).

Examples

>>> s = SensorSpec("induction_coil", "MTC-150H", (1e-5, 1e4))
>>> s.covers(0.1)
True
>>> s.covers(1e6)
False
sensor_type: Literal['induction_coil', 'fluxgate', 'electrode', 'other'] = 'induction_coil'#
model: str = ''#
frequency_range: tuple[float, float] | None = None#
notes: str = ''#
covers(frequency_hz)#

Return True if frequency_hz lies within the rated band.

Parameters:

frequency_hz (float)

Return type:

bool

class pycsamt.metadata.InstrumentMeta(system='', serial=None, magnetic_sensor=None, electric_sensor=None, software_version='', notes='')#

Bases: object

Structured descriptor for an EM acquisition system.

Parameters:
  • system (str) – Human-readable system name, e.g. "Phoenix V8" or "Metronix ADU-07e".

  • serial (str or None) – Logger serial number or site-specific tag.

  • magnetic_sensor (SensorSpec or None) – Magnetic-field transducer (H field) specification.

  • electric_sensor (SensorSpec or None) – Electric-field transducer (E field) specification.

  • software_version (str) – Processing / acquisition software version string.

  • notes (str) – Free-text annotation (calibration date, operator remarks, …).

Notes

The class deliberately stays thin — only fields that appear (or could appear) in a standard EDI >HEAD block or in a compact YAML survey manifest are stored here. Calibration tables belong in separate files referenced by notes.

Examples

>>> from pycsamt.metadata.instrument import InstrumentMeta
>>> inst = InstrumentMeta(system="Phoenix V8", serial="V8-00123")
>>> inst.to_head_fields()
{'acqby': 'Phoenix V8 / V8-00123', 'progvers': 'pyCSAMT'}
system: str = ''#
serial: str | None = None#
magnetic_sensor: SensorSpec | None = None#
electric_sensor: SensorSpec | None = None#
software_version: str = ''#
notes: str = ''#
property label: str#

"<system> / <serial>" or just system.

Type:

Short identifier

summary()#

Return a multi-line human-readable summary.

Return type:

str

to_head_fields()#

Return a dict of EDI >HEAD key-value pairs.

The mapping is:

acqby    ← system / serial  (or just system)
progvers ← software_version (or the package default)
Returns:

Ready to pass to update().

Return type:

dict

classmethod from_head(head)#

Construct from a Head object.

Only acqby and progvers are extracted; sensor details cannot be inferred from the EDI header alone.

Parameters:

head (Any) – A pycsamt.seg.heads.Head instance (or any object with acqby and progvers string attributes).

Return type:

InstrumentMeta

classmethod from_preset(name)#

Build from a named preset in KNOWN_SYSTEMS.

Parameters:

name (str) – Case-insensitive preset key, e.g. "phoenix_v8".

Return type:

InstrumentMeta

Raises:

KeyError – If name is not in KNOWN_SYSTEMS.

Examples

>>> inst = InstrumentMeta.from_preset("lemi_424")
>>> inst.system
'LEMI-424'
to_dict()#

Serialise to a plain dict (JSON-safe).

Return type:

dict[str, Any]

to_json(indent=2)#

Serialise to a JSON string.

Parameters:

indent (int)

Return type:

str

classmethod from_json(s)#

Deserialise from a JSON string.

Parameters:

s (str)

Return type:

InstrumentMeta

to_yaml()#

Serialise to a YAML string (requires PyYAML).

Return type:

str

classmethod from_yaml(s)#

Deserialise from a YAML string (requires PyYAML).

Parameters:

s (str)

Return type:

InstrumentMeta

save(path, fmt='json')#

Write to path as JSON or YAML.

Parameters:
  • path (str) – Destination file path.

  • fmt ({"json", "yaml"})

Return type:

None

classmethod load(path)#

Load from a JSON or YAML file (format detected by extension).

Parameters:

path (str)

Return type:

InstrumentMeta

pycsamt.metadata.known_system(name)#

Shortcut for InstrumentMeta.from_preset().

Parameters:

name (str) – Preset key (case-insensitive, spaces/hyphens treated as underscores).

Return type:

InstrumentMeta

Examples

>>> from pycsamt.metadata.instrument import known_system
>>> inst = known_system("phoenix_v8")
>>> inst.system
'Phoenix V8'
pycsamt.metadata.list_presets()#

Return sorted list of available preset keys.

Examples

>>> from pycsamt.metadata.instrument import list_presets
>>> list_presets()
['geometrics_stratagem', 'generic_fluxgate', 'lemi_424', ...]
Return type:

list

Metadata Modules#

pycsamt.metadata.frequency

pycsamt.metadata.frequency

pycsamt.metadata.geology

pycsamt.metadata.geology

pycsamt.metadata.instrument

pycsamt.metadata.instrument

pycsamt.metadata.quality

pycsamt.metadata.quality

pycsamt.metadata.rocks

pycsamt.metadata.survey

pycsamt.metadata.survey

Frequency Helpers#

pycsamt.metadata.frequency.doi_estimate(f, rho=100.0)[source]#

Return the skin-depth DOI estimate in metres at frequency f.

Parameters:
  • f (float) – Frequency in Hz.

  • rho (float, default 100.0) – Reference resistivity in Ω·m.

Return type:

float