pycsamt.metadata.survey#

pycsamt.metadata.survey#

Campaign-level survey descriptor.

SurveyMeta captures the essential context of an MT/AMT/CSAMT/TEM measurement campaign — who, what, when, where — as a first-class Python object. It serialises to / deserialises from JSON and YAML, can be built directly from a Sites collection, and can push its fields into an EDI >HEAD section.

Quick start#

from pycsamt.metadata.survey import SurveyMeta, BBox

meta = SurveyMeta(
    name="WILLY_2023",
    project="Copper-gold exploration",
    operator="EarthAI-Tech",
    method="AMT",
    bbox=BBox(lat_min=27.8, lat_max=28.9,
              lon_min=101.5, lon_max=103.2),
)

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

# round-trip to JSON
meta.to_json("survey.json")
meta3 = SurveyMeta.from_json("survey.json")

Classes

BBox(lat_min, lat_max, lon_min, lon_max)

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

SurveyMeta(name[, project, operator, ...])

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

class pycsamt.metadata.survey.BBox(lat_min, lat_max, lon_min, lon_max)[source]#

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][source]#

Return (lat, lon) centre of the box.

property area_deg2: float[source]#

Return the area of the box in squared degrees.

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

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

Parameters:
Return type:

bool

to_dict()[source]#
Return type:

dict[str, float]

classmethod from_dict(d)[source]#
Parameters:

d (dict[str, Any])

Return type:

BBox

classmethod from_coords(lats, lons)[source]#

Build a tight bounding box from lists of coordinates.

Parameters:
Return type:

BBox

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

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[source]#

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

property is_complete: bool[source]#

Return True when all key descriptors are populated.

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

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)[source]#

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()[source]#

Return all fields as a plain JSON-serialisable dict.

Return type:

dict[str, Any]

classmethod from_dict(d)[source]#

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

Parameters:

d (dict[str, Any])

Return type:

SurveyMeta

to_json(path=None)[source]#

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

Parameters:

path (str | Path | None)

Return type:

str

classmethod from_json(path)[source]#

Load from a JSON file.

Parameters:

path (str | Path)

Return type:

SurveyMeta

to_yaml(path=None)[source]#

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

Parameters:

path (str | Path | None)

Return type:

str

classmethod from_yaml(path)[source]#

Load from a YAML file.

Parameters:

path (str | Path)

Return type:

SurveyMeta

summary()[source]#

Return a compact one-paragraph summary string.

Return type:

str