pycsamt.seg.collection#

Classes

CollectionMixin()

Utilities for working with collections of EDIFile objects.

EDICollection([items, verbose])

High-level collection of EDIFile objects with integrated loading and summarization.

class pycsamt.seg.collection.CollectionMixin[source]#

Bases: ParseMixin

Utilities for working with collections of EDIFile objects.

The mixin adds non-IO helpers that operate on a set of items already loaded in memory. Typical operations include filtering, mapping, grouping, and summarizing. It is designed to be combined with a small container base, such as CBBase.

Parameters:

None – This is a mixin. It does not define its own public constructor parameters.

Variables:
  • items (dict) – Mapping from collection key (for example the station id) to EDIFile. Expected to be provided by the host collection.

  • order (list of str) – Insertion order of keys. Used to preserve stable iteration and deterministic summaries.

Notes

The mixin focuses on pure-Python transformations. The typical methods provided by implementations include:

  • select(keys=None, predicate=None) : return a new view with items that match the keys or satisfy the boolean predicate.

  • map(func) : apply a callable to each EDIFile and collect the results in a list.

  • groupby(keyfunc) : bucket items by a user-defined key and return a mapping to lists of EDIFile.

  • summary(fields=('station', 'n_freq', ...)) : build a compact table of common attributes for quick inspection.

These helpers do not read from disk and do not mutate EDIFile content unless explicitly documented by the host class.

Examples

Filter by station prefix and compute sample counts:

view = coll.select(
    predicate=lambda ed: ed.station.startswith('A')
)
counts = view.map(lambda ed: ed.Z.n_freq)

Group by presence of tipper and list stations:

groups = coll.groupby(
    lambda ed: ed.Tip.tipper is not None
)
stations_with_tip = [ed.station for ed in
                     groups.get(True, [])]

See also

EDICollection

Concrete collection that mixes this class with a container and a loader.

CBBase

Minimal container used by collections.

CoreParser

Parser used to build EDIFile objects.

EDIFile

Single-file reader and writer.

References

add_from(sources, *, recursive=True, strict=False, on_dup='replace', verbose=None)[source]#
Parameters:
Return type:

CollectionMixin

select(stations)[source]#
Parameters:

stations (Sequence[str])

Return type:

EDICollection

where(fn)[source]#
Parameters:

fn (Callable[[EDIFile], bool])

Return type:

EDICollection

sort(key='station', *, reverse=False)[source]#
Parameters:
Return type:

EDICollection

property paths: list[str][source]#
nf_stats()[source]#
Return type:

dict

class pycsamt.seg.collection.EDICollection(items=None, *, verbose=0)[source]#

Bases: CBBase, CollectionMixin

High-level collection of EDIFile objects with integrated loading and summarization.

The class couples the small container CBBase with CoreParser to discover, read, and manage many EDI files at once. Items are indexed by station id or by absolute path, with a configurable duplicate policy.

Parameters:
  • sources (path-like or sequence of path-like, optional) – Files, folders, or glob patterns to load. When omitted the collection is created empty. Use load() later to populate it.

  • recursive (bool, default True) – Recurse into subdirectories when scanning folders.

  • on_dup ({‘replace’, ‘keep’}, default 'replace') – Duplicate policy for items that share the same key. With 'replace' the last item wins. With 'keep' the first item is preserved.

  • index_by ({‘station’, ‘path’}, default 'station') – Key used to index items. When 'station' the EDIFile.station is preferred with a fallback to file path if unspecified.

  • strict (bool, default False) – If True read errors are raised. If False they are captured and available via errors().

  • verbose (int, default 0) – Verbosity forwarded to the underlying EDIFile readers.

  • items (Iterable[EDIFile] | None)

Variables:
  • parser (CoreParser) – Internal parser used by load(). Exposed for advanced scenarios or diagnostics.

  • items (dict) – Mapping from key to EDIFile.

  • order (list of str) – Insertion order of collection keys.

  • meta (dict) – Free-form metadata that client code can populate.

load(sources)#

Discover and read items. Merges into the current collection while respecting the duplicate policy.

select(keys=None, predicate=None)#

Return a filtered view. Provided by CollectionMixin.

map(func)#

Apply a callable to each item and collect results.

groupby(keyfunc)#

Group items by a user function, returning a dict of lists.

summary(fields=('station', 'n_freq', 'has_tipper'))#

Build a compact per-item table suitable for logging or quick inspection.

errors()#

Return a list of (path, exception) pairs from the last load() call.

Notes

The class aims to be pragmatic. Loading is done with a single pass of CoreParser. Summaries are built from lightweight attributes that are cheap to access, such as station, number of frequencies, and section presence. Heavy analysis should be implemented outside the collection to keep the API small.

Examples

Load a folder, keep first duplicates, and summarize:

coll = EDICollection(
    sources=['data/edi'],
    on_dup='keep', recursive=True
)
tbl = coll.summary(
    fields=('station', 'n_freq', 'tipper')
)
for row in tbl:
    print(row)

Add more files later and filter by predicate:

coll.load(['more/*.edi'])
mt_only = coll.select(
    predicate=lambda ed: ed.has_section('mtsect')
)
stations = mt_only.map(lambda ed: ed.station)

See also

CoreParser

Multi-source reader used by load().

CBBase

Base container that stores items and preserves order.

ParseMixin

Discovery utilities employed by the parser.

EDIFile

Single EDI reader and writer stored in the collection.

References

classmethod from_sources(sources, *, recursive=True, strict=False, on_dup='replace', verbose=0)[source]#
Parameters:
Return type:

EDICollection

merge(other, *, on_dup='replace')[source]#
Parameters:
Return type:

EDICollection

get(site, what, default=None)[source]#

Quick extractor for a single field/array. ‘what’ supports:

  • ‘freq’, ‘z’, ‘zxx’,’zxy’,’zyx’,’zyy’

  • ‘tip’,’tx’,’ty’

  • ‘station’,’dataid’,’lat’,’lon’,’elev’

  • ‘path’,’filename’

  • ‘spectra’,’timeseries’

Parameters:
Return type:

object | None

set(site, *, edi=None, update=None)[source]#

Replace or mutate a site’s EDI.

  • If ‘edi’ is given, replace the stored object.

  • Else apply ‘update’ fields on the existing object: keys: ‘station’,’dataid’,’lat’,’lon’,’elev’,’z’,

    ‘freq’,’tip’,’spectra’,’timeseries’

Parameters:
Return type:

EDIFile

adjust(site, *, dlat=None, dlon=None, lat=None, lon=None, elev=None, rename=None)[source]#

Shift or set position and/or rename station.

Parameters:
Return type:

EDIFile

export(output_dir, *, file_pattern='{station}.edi', **edi_write_kwargs)[source]#

Exports all EDIFile items to a directory with advanced options.

This method orchestrates the writing of each EDIFile in the collection to a specified directory, with flexible naming and clear error reporting.

Parameters:
  • output_dir (Pathish) – The path to the directory where EDI files will be saved. It will be created if it does not exist.

  • file_pattern (str, default="{station}.edi") – A format string for output filenames. Can use attributes like {station}.

  • **edi_write_kwargs – Keyword arguments to be passed directly to each EDIFile.write() call (e.g., datatype=”mt”, synthesize_spectra=True).

Returns:

A dictionary with two keys: - ‘successful’: A list of paths to successfully written files. - ‘failed’: A list of tuples, where each tuple contains the

station name and the error that occurred during writing.

Return type:

dict

fetch(site=None, lat=None, lon=None, tol=0.001, first=False, strict=False, policy=None, **kwargs)[source]#

Fetch EDI files by station, coordinates, or other metadata.

This method searches the collection for EDIFile objects by station name, geographic coordinates, or any attribute exposed on the EDI or its >HEAD section.

Parameters:
  • site (str or int or float, optional) – Station selector. Case-insensitive. Numeric-like values are normalized using the active StationNamePolicy and station-variant expansion. Variants tried include the raw token, integer form, zero-padded prefix form (e.g. S150), and common ×10 slips (1500 <-> 150).

  • lat (float, optional) – Latitude in decimal degrees. Compared against the >HEAD field lat using the tolerance tol.

  • lon (float, optional) – Longitude in decimal degrees. Compared against the >HEAD field long using the tolerance tol.

  • tol (float, default 0.001) – Absolute tolerance (decimal degrees) used when matching lat and lon.

  • first (bool, default False) – If True, return only the first matching object or None if no match (unless strict=True, see Raises). If False, return a list of all matches (possibly empty).

  • strict (bool, default False) – If True and no match is found, raise SiteError with a helpful message suggesting <collection>.stations().

  • policy (StationNamePolicy, optional) – Custom naming policy. Defaults to get_config() .station_policy.

  • **kwargs (Any) – Additional attribute filters. Keys are matched (case-insensitive) first on the EDI object, then on its head section. String values compare in a case-insensitive way; non-strings compare by equality.

Returns:

If first=True, an EDIFile or None when no match and strict=False. If first=False, a list of matches (possibly empty).

Return type:

EDIFile or list of EDIFile or None

Raises:

SiteError – Raised when no match is found and strict=True. The error message lists available stations and suggests calling <collection>.stations().

Notes

  • Station matching expands candidate variants using the active StationNamePolicy and a small set of robust transforms (integer form, zero-padded with prefix, and common ×10 slips).

  • Geographic matching uses absolute tolerance on decimal degrees and compares against >HEAD fields lat and long.

  • Arbitrary filters in **kwargs are applied after station and coordinate tests. String comparisons are case-insensitive; other types use equality.

Examples

>>> # List available stations
>>> coll.stations()
['S150', 'S200', 'S250', 'S300', ...]
>>> # Fetch a single station by numeric label
>>> ed = coll.fetch(site=150, first=True)
>>> # Enforce a helpful error when not found
>>> coll.fetch(site='S999', first=True, strict=True)
Traceback (most recent call last):
    ...
SiteError: No station found. Try one of: ...
>>> # Fetch by coordinates within tolerance
>>> ed = coll.fetch(lat=-22.37, lon=139.19, first=True)
>>> # Filter by metadata on >HEAD (case-insensitive)
>>> zs = coll.fetch(acqby='Zonge')

See also

pycsamt.core.config.StationNamePolicy, pycsamt.core.config.ensure_station, pycsamt.seg.collection.EDICollection.stations, pycsamt.seg.collection.EDICollection._resolve

References

property sites: list[str][source]#

Returns a list of best-effort station names for each item.

property latitude: ndarray[source]#

Returns a numpy array of latitudes (np.nan for missing values).

property longitude: ndarray[source]#

Returns a numpy array of longitudes (np.nan for missing values).