pycsamt.site.base#

Functions

to_edis(x, *[, as_collection, copy, ...])

Unwrap site-like inputs to raw EDI objects.

to_sites(x, *[, recursive, on_dup, strict, ...])

Coerce an arbitrary EDI-like input into a Sites wrapper.

Classes

Site(edi)

High-level wrapper for a single MT/CSAMT site backed by an EDIFile.

SiteMixin(edi)

Lightweight wrapper exposing station-centric accessors and utilities for a single EDIFile.

Sites(edic)

Container for multiple Site objects with convenient indexing, selection, and bulk edit operations.

class pycsamt.site.base.SiteMixin(edi)[source]#

Bases: CoreObject

Lightweight wrapper exposing station-centric accessors and utilities for a single EDIFile.

The mixin normalizes common site operations around the underlying EDI content, including coordinate handling, impedance arrays, tipper, derived resistivity/phase, and convenient export to pandas.DataFrame.

Notes

The station name is resolved from EDI HEAD fields in the following order: dataid, station, sitename, name, STATION. If none is present, the file stem is used. See _station_name().

The Z tensor is treated as an array of shape (n, 2, 2) or flattened to (n, 4) as needed. The order is: Zxx, Zxy, Zyx, Zyy.

See also

pycsamt.seg.edi.EDIFile

Parsed SEG-EDI container.

pycsamt.site.base.Site

Concrete site wrapper that enforces a stable ID.

pycsamt.site.base.Sites

Collection helper for multiple sites.

References

Parameters:

edi (EDIFile)

property name: str[source]#

Station identifier resolved from the EDI header or file stem.

Returns:

Station name used for lookups and display.

Return type:

str

Notes

The resolution order is defined in _station_name().

property coords: tuple[float, float, float][source]#

Geographic coordinates of the site.

Returns:

A 3-tuple (lat, lon, elev) in decimal degrees and meters.

Return type:

tuple of float

Notes

This accessor relies on _get_coords() which parses EDI HEAD latitude, longitude and elevation.

property freq: Any[source]#

Frequency vector extracted from the Z section.

Returns:

One-dimensional array of frequencies in Hz, or None if missing.

Return type:

array-like or None

See also

to_dataframe

Tabular export of arrays at each frequency.

property z: Any[source]#

Complex impedance tensor across frequencies.

Returns:

Array with shape (n, 2, 2) or flattened to (n, 4) depending on context, or None if absent.

Return type:

array-like or None

Notes

Flattening order is Zxx, Zxy, Zyx, Zyy.

property z_err: Any[source]#

Uncertainty associated with the impedance tensor.

Returns:

Error array aligned with :pyattr:`z`, or None if absent.

Return type:

array-like or None

property rho: Any[source]#

Apparent resistivity derived from the impedance tensor.

Returns:

Resistivity values per component and frequency, or None if not computed or absent.

Return type:

array-like or None

Notes

Derived fields may be recomputed downstream when the Z tensor or frequency vector is updated.

property phase: Any[source]#

Impedance phase (degrees) derived from the tensor.

Returns:

Phase values per component and frequency, or None if not computed or absent.

Return type:

array-like or None

property tipper: Any[source]#

Vertical magnetic transfer function (tipper).

Returns:

Two columns (Tx, Ty) per frequency, or None if missing.

Return type:

array-like or None

property meta: dict[str, Any][source]#

Minimal metadata snapshot collected from the EDI.

Returns:

Dictionary that may include station, name, lat, lon, elev, dataid, sitename, and an INFO sub-dict if present.

Return type:

dict

Notes

Values are read on a best-effort basis and non-existing keys are omitted.

to_dataframe(kind='z', *, api=None)[source]#

Export core arrays to a tidy pandas.DataFrame.

Parameters:
  • kind ({"z", "imp", "impedance", "resphase", "rp",) – “rho_phase”, “tip”, “tipper”, “t”}, optional Selects which quantity to export. The default is "z".

  • api (bool | None)

Returns:

Frame indexed by frequency (name "f"). Columns depend on kind: - "z": Zxx, Zxy, Zyx, Zyy (complex values). - "resphase": pairs of columns per component

rho_* and phi_*.

  • "tipper": Tx, Ty.

Return type:

pandas.DataFrame

Raises:

ValueError – If kind is not recognized.

Notes

Missing arrays yield empty frames with the correct index.

Examples

>>> df = site.to_dataframe("z")
>>> df.columns
Index(["Zxx","Zxy","Zyx","Zyy"], dtype="object")

See also

quality_flags

Quick presence checks of available arrays.

quality_flags()[source]#

Report presence and basic validity of key arrays.

Returns:

Flags: has_freq, has_z, has_z_err, has_rho, has_phase, has_tipper. A flag is True if the array exists, has non-zero size, and all values are finite.

Return type:

dict

Examples

>>> site.quality_flags()["has_z"]
True
has_component(comp)[source]#

Check if a given component contains any finite value.

Parameters:

comp (str) – One of "Zxx", "Zxy", "Zyx", "Zyy" for impedance, or "tip", "tx", "ty", "tipper" for tipper.

Returns:

True if the component exists and has at least one finite value.

Return type:

bool

Notes

Component names are case-insensitive.

Examples

>>> site.has_component("Zxy")
True
summary()[source]#

Summarize site identity, geometry, and data coverage.

Returns:

Keys include: name, nfreq, lat, lon, elev, components (present Z components), and tipper (boolean).

Return type:

dict

Examples

>>> s = site.summary()
>>> s["name"], s["nfreq"]
('E01', 37)
rename(new, *, inplace=False)[source]#

Set a new station identifier across common header fields.

Parameters:
  • new (str) – New station name or ID.

  • inplace (bool, optional) – If True, modify this instance. If False, return a new Site. The default is False.

Returns:

The modified site (new instance unless inplace).

Return type:

Site

Notes

The method writes to EDI HEAD fields dataid, station, sitename, name (best effort) and also updates edi.name. Downstream containers that derive station IDs from the file stem may be configured to prefer edi.name to preserve the rename.

Examples

>>> s2 = site.rename("X_E01")
>>> s2.name
'X_E01'
set_coords(lat, lon, elev=None, *, inplace=False)[source]#

Update the site coordinates in the EDI HEAD section.

Parameters:
  • lat (float) – Latitude in decimal degrees.

  • lon (float) – Longitude in decimal degrees.

  • elev (float, optional) – Elevation in meters. If None, elevation is left unchanged. The default is None.

  • inplace (bool, optional) – If True, modify this instance. If False, return a new Site. The default is False.

Returns:

The modified site (new instance unless inplace).

Return type:

Site

Notes

Latitude and longitude are validated by utility functions to ensure plausible values.

Examples

>>> site = site.set_coords(10.0, 20.0, 100.0)
>>> site.coords
(10.0, 20.0, 100.0)
set_empty(*, inplace=False)[source]#

Clear Z-related arrays to an empty dataset.

Parameters:

inplace (bool, optional) – If True, modify this instance. If False, return a new Site. The default is False.

Returns:

The modified site (new instance unless inplace).

Return type:

Site

Notes

The following arrays are replaced with empty arrays: freq, z, z_error, rho, and phase. Use this to initialize a skeleton record without data.

Examples

>>> s2 = site.set_empty()
>>> s2.to_dataframe("z").empty
True
class pycsamt.site.base.Site(edi)[source]#

Bases: SiteMixin

High-level wrapper for a single MT/CSAMT site backed by an EDIFile. The class enforces a stable, file-stem-based station identifier and exposes convenient accessors for coordinates, impedance Z, tipper, and derived quantities.

The constructor normalizes EDI HEAD fields so that dataid (and, if absent, station) matches the site stem resolved by _stem_from_edi(). If an in-memory edi.name exists, the stem may prefer it so that a prior rename is preserved. This normalization improves name-based indexing, deterministic selection, and downstream joins in collections.

Parameters:

edi (pycsamt.seg.edi.EDIFile) – Parsed SEG-EDI container holding one station. The file may be constructed from disk or synthesized in memory.

Variables:
  • edi (pycsamt.seg.edi.EDIFile) – Underlying EDI object. Use with care; prefer the typed accessors of SiteMixin (e.g., freq, z).

  • name (str) – Normalized station identifier. By default this equals the file stem, unless a previous explicit rename is in effect.

  • coords (tuple of float) – Geographic location as (lat, lon, elev). Latitude and longitude are in degrees; elevation is in meters.

Notes

Identity policy

The site identity is derived from header fields in the following order: dataid, station, sitename, name, STATION. If none are present, the file stem is used. The constructor ensures that dataid is set to the resolved stem to stabilize lookups.

Array conventions

The impedance tensor \(Z\) may be represented as a 3D array with shape (n, 2, 2) or flattened to (n, 4) in the component order Zxx, Zxy, Zyx, Zyy. Frequencies are 1D of length n. The tipper has two columns Tx and Ty.

Derived fields

Apparent resistivity and phase are derived from \(Z\) and the frequency vector. When Z or frequency slices are applied, recomputation is triggered after arrays are aligned to avoid inconsistent shapes.

Robustness

Accessors are defensive. Missing arrays produce empty frames or None. Coordinates are validated for range using utility checks.

Examples

Basic construction and inspection
>>> from pycsamt.seg.edi import EDIFile
>>> from pycsamt.site.base import Site
>>> e = EDIFile("E01.edi")        # parse from disk
>>> s = Site(e)
>>> s.name
'E01'
>>> s.coords
(..., ..., ...)
>>> s.summary()["nfreq"] >= 0
True
Tabular export
>>> from pycsamt.site.base import Site
>>> dfz = s.to_dataframe("z")
>>> list(dfz.columns)
['Zxx', 'Zxy', 'Zyx', 'Zyy']
>>> dfrp = s.to_dataframe("resphase")
>>> sorted([c for c in dfrp.columns if c.startswith("rho_")])[:2]
['rho_zxx', 'rho_zxy']
Rename without mutating the original instance
>>> s2 = s.rename("X_E01")   # returns a new Site
>>> s2.name
'X_E01'
>>> s.name  # original unchanged
'E01'
Coordinate update
>>> s3 = s.set_coords(10.0, 20.0, 100.0)
>>> s3.coords
(10.0, 20.0, 100.0)
With a collection
>>> from pycsamt.site.base import Sites
>>> e2 = EDIFile("E02.edi")
>>> col = Sites([s.edi, Site(e2).edi])
>>> [t.name for t in col]
['E01', 'E02']
>>> col["E02"].summary()["name"]
'E02'

See also

pycsamt.site.base.SiteMixin

Mixin providing typed accessors and utilities.

pycsamt.site.base.Sites

Collection helper for selection, slicing, and bulk edits.

pycsamt.seg.edi.EDIFile

Low-level SEG-EDI container.

References

to_edi(*, copy=False)[source]#

Return the underlying EDI object.

Parameters:

copy (bool, default False) – If True, return a best-effort deep copy of the wrapped EDI object. If copying fails, the original object is returned.

Returns:

EDI object wrapped by this Site.

Return type:

pycsamt.seg.edi.EDIFile

See also

pycsamt.site.base.to_edis

General unwrapping helper for Site/Sites and mixed inputs.

class pycsamt.site.base.Sites(edic)[source]#

Bases: CoreObject

Container for multiple Site objects with convenient indexing, selection, and bulk edit operations.

Sites wraps each provided EDIFile into a Site, ensuring that station identity is normalized consistently. You can iterate, index by integer, or look up by case-insensitive station name. Bulk operations such as renaming, frequency slicing, and masking are provided via edit_all().

Parameters:

edic (pycsamt.seg.collection.EDICollection or sequence of) – pycsamt.seg.edi.EDIFile Parsed EDI collection or any sequence of EDI objects. Items are wrapped into Site instances in the order provided.

Variables:

_items (list of Site) – Internal sequence of sites. This is considered private. Iterate over Sites instead of accessing it directly.

Notes

Identity and lookup

Each site inside the container uses the same naming policy as Site. Name-based lookups with sites["E01"] are case-insensitive and match the normalized station name. If duplicates exist, the first match is returned.

Order preservation

Ordering of input items is preserved. Integer indexing with sites[i] retrieves the i-th Site.

Bulk edits

edit_all() supports three common operations: - rename: compute a new name from the old name. - freq_slice: apply a frequency slice (slice)

consistently across Z, freq, errors, and derived fields.

  • mask: apply a boolean mask to the Z tensor rows.

Use inplace=True to modify the container, otherwise a new Sites is returned.

Geospatial helpers

closest() uses geodetic distance to find the nearest site to a given latitude and longitude. Sites with missing or non-finite coordinates are skipped.

Topography integration

with_topography() aligns site coordinates and elevation with a user-provided frame, returning a new container unless inplace=True is requested.

Profile conversion

to_profile() attempts to build a Profile when that optional dependency is available. Otherwise, a lightweight dict describing a chainage-ordered sequence is returned.

Persistence

write() emits one EDI file per site into a target directory. If an EDI object provides to_file, it is used; otherwise a placeholder is written.

Robustness and errors
  • __getitem__ raises KeyError when a name is not found. Prefer get() to obtain None instead.

  • Bulk operations ignore missing arrays on a best-effort basis so that other arrays can still be processed.

Examples

Build from a few EDI files
>>> from pycsamt.seg.edi import EDIFile
>>> from pycsamt.site.base import Sites
>>> e1, e2 = EDIFile("E01.edi"), EDIFile("E02.edi")
>>> sites = Sites([e1, e2])
>>> len(sites)
2
>>> [s.name for s in sites]
['E01', 'E02']
Indexing and lookup
>>> sites[0].name
'E01'
>>> sites["e02"].name
'E02'
>>> sites.get("missing") is None
True
Bulk rename without mutating the original container
>>> def rnm(n):
...     return "X_" + n
>>> out = sites.edit_all(rename=rnm, inplace=False)
>>> [s.name for s in out]
['X_E01', 'X_E02']
>>> [s.name for s in sites]
['E01', 'E02']
Frequency slice across all arrays
>>> sl = slice(1, None)  # drop the first frequency
>>> out2 = sites.edit_all(freq_slice=sl, inplace=False)
>>> f0 = sites["E01"].freq
>>> f1 = out2["E01"].freq
>>> len(f1) == len(f0) - 1
True
Selection by names or predicate
>>> subset = sites.select(names=["E02"])
>>> [s.name for s in subset]
['E02']
>>> # predicate: keep sites with tipper available
>>> subset2 = sites.select(predicate=lambda s: s.has_component("tipper"))
>>> isinstance(subset2, Sites)
True
Nearest station to a target location
>>> near = sites.closest(lat=10.0, lon=20.0, tol=None)
>>> near is None or hasattr(near, "name")
True
Persist to a directory
>>> import tempfile, pathlib
>>> tmp = pathlib.Path(tempfile.mkdtemp())
>>> out_paths = sites.write(tmp, template="{station}.edi", exist_ok=True)
>>> all(p.exists() for p in out_paths)
True

See also

pycsamt.site.base.Site

Site wrapper used for each element in the container.

pycsamt.seg.collection.EDICollection

Parsed collection produced by the core parser.

pycsamt.site.profile.Profile

Optional profile object produced by to_profile().

References

property edic: list[EDIFile][source]#
by_index(i)[source]#

Retrieve a site by zero-based index.

Parameters:

i (int) – Position in the container.

Returns:

The site at the requested index.

Return type:

Site

Examples

>>> sites.by_index(0).name == sites[0].name
True
get(name)[source]#

Safe lookup by case-insensitive station name.

Parameters:

name (str) – Station identifier to find.

Returns:

Matching site, or None if not present.

Return type:

Site or None

Examples

>>> sites.get("missing") is None
True
>>> sites.get("E01").name
'E01'

See also

__getitem__

Raises on missing names.

as_list()[source]#

Return the underlying list of EDI objects.

Returns:

The EDI objects corresponding to each site.

Return type:

list of pycsamt.seg.edi.EDIFile

Notes

This is useful when passing the dataset to utilities that operate on EDI-level structures rather than on sites.

Examples

>>> edis = sites.as_list()
>>> hasattr(edis[0], "get_section")
True
to_edis(*, copy=False, progress=False, verbose=0)[source]#

Return the underlying EDI objects as a list.

Parameters:
  • copy (bool, default False) – If True, return best-effort deep copies of the EDI objects.

  • progress (bool or {'auto'}, default False) – Enable progress display while unwrapping.

  • verbose (int, default 0) – Verbosity forwarded to progress/reporting helpers.

Returns:

EDI objects in site order.

Return type:

list of pycsamt.seg.edi.EDIFile

See also

to_edicollection

Return an EDICollection instead.

pycsamt.site.base.to_edis

General unwrapping helper.

to_edicollection(*, copy=False, progress=False, verbose=0)[source]#

Return the underlying EDI objects as an EDICollection.

Parameters:
  • copy (bool, default False) – If True, return best-effort deep copies of the EDI objects.

  • progress (bool or {'auto'}, default False) – Enable progress display while unwrapping.

  • verbose (int, default 0) – Verbosity assigned to the returned collection.

Returns:

Collection built from the underlying EDI objects.

Return type:

pycsamt.seg.collection.EDICollection

closest(lat, lon, tol=None)[source]#

Find the closest site to a target coordinate using geodetic distance.

Parameters:
  • lat (float) – Target latitude in decimal degrees.

  • lon (float) – Target longitude in decimal degrees.

  • tol (float, optional) – Maximum allowed distance in meters. If provided and the nearest site is farther than tol, return None. The default is None.

Returns:

Nearest site or None if all sites are too far or lack valid coordinates.

Return type:

Site or None

Notes

Coordinates are validated. Sites with non-finite values are skipped. Distance is computed in meters using a geodetic model.

Examples

>>> near = sites.closest(10.0, 20.0)
>>> near is None or hasattr(near, "name")
True
>>> sites.closest(0.0, 0.0, tol=1.0) is None
True
map(fn)[source]#

Apply a function to every site and collect the results.

Parameters:

fn (callable) – Function of signature fn(site) -> Any.

Returns:

Results collected in order.

Return type:

list

Examples

>>> sites.map(lambda s: s.name)[:2]
['E01', 'E02']
edit_all(*, rename=None, freq_slice=None, mask=None, inplace=False)[source]#

Bulk-edit all sites with optional rename, frequency slicing, and tensor masking.

Parameters:
  • rename (callable, optional) – Function rename(old_name) -> new_name. If provided, each site is renamed accordingly.

  • freq_slice (slice, optional) – Row-wise slice applied consistently to frequency, impedance Z, errors, and derived arrays.

  • mask (callable, optional) – Function mask(df) -> bool_series where df is the output of site.to_dataframe("z"). Rows where the mask is False are set to NaN in Z.

  • inplace (bool, optional) – If True, modify this container and return it. If False, return a new Sites. Default is False.

Returns:

The edited container (possibly the same instance).

Return type:

Sites

Notes

  • When inplace=False, sites are shallow-cloned so that edits do not affect the original container.

  • Frequency slicing is applied atomically to avoid temporary shape mismatches between freq and Z-derived arrays.

  • Missing arrays are tolerated on a best-effort basis.

Examples

Rename with a prefix
>>> def rnm(n): return "X_" + n
>>> out = sites.edit_all(rename=rnm)
>>> [s.name for s in out][:2]
['X_E01', 'X_E02']
Slice away the first frequency
>>> sl = slice(1, None)
>>> out2 = sites.edit_all(freq_slice=sl)
>>> len(out2["E01"].freq) == len(sites["E01"].freq) - 1
True
Mask the top half of rows in Z
>>> def top_half(frame):
...     m = np.ones(len(frame), dtype=bool)
...     m[: len(frame) // 2] = False
...     return m
>>> out3 = sites.edit_all(mask=top_half)
>>> df = out3["E01"].to_dataframe("z")
>>> np.isnan(df.iloc[0].values).all()
True

See also

Site.rename

Per-site rename helper.

Site.to_dataframe

Source for building masks.

with_topography(frame, *, inplace=False)[source]#

Align site coordinates and elevation from a tabular frame.

Parameters:
  • frame (Any) – A table-like object (e.g., pandas.DataFrame) with station identifiers and columns for latitude, longitude, and elevation. Column names are resolved by the topography utility.

  • inplace (bool, optional) – If True, modify this container and return it. If False, return a new Sites. Default is False.

Returns:

Container with updated coordinates.

Return type:

Sites

Notes

Sites are matched by normalized station identifiers. The operation is performed on a best-effort basis; unmatched stations are left unchanged.

Examples

>>> import pandas as pd
>>> df = pd.DataFrame({
...   "station": ["E01", "E02"],
...   "latitude": [10.0, 11.0],
...   "longitude": [20.0, 21.0],
...   "elevation": [100.0, 200.0],
... })
>>> out = sites.with_topography(df, inplace=False)
>>> tuple(round(v, 3) for v in out["E01"].coords)
(10.0, 20.0, 100.0)
select(names=None, predicate=None)[source]#

Filter sites by explicit names or by a boolean predicate.

Parameters:
  • names (sequence of str, optional) – Case-insensitive station names to retain. If provided, this takes precedence over predicate.

  • predicate (callable, optional) – Function predicate(site) -> bool. Sites for which the function returns True are retained.

Returns:

New container with the selected sites.

Return type:

Sites

Notes

If neither names nor predicate is provided, the method returns a shallow copy of the current container.

Examples

>>> subset = sites.select(names=["E02"])
>>> [s.name for s in subset]
['E02']
>>> subset2 = sites.select(predicate=lambda s: s.has_component("Zxy"))
>>> isinstance(subset2, Sites)
True
classmethod from_any(source, topo_src=None)[source]#

Construct a container from heterogeneous inputs by using a normalized loading session.

Parameters:
  • source (Any) – Input that can be understood by the loader. Supported cases include: - an EDICollection, - a list of EDIFile, - a single EDIFile, - or an iterable that yields EDIs.

  • topo_src (Any, optional) – Optional topography source passed to the session for use during loading. The default is None.

Returns:

Parsed container. Returns an empty container if the input cannot be interpreted.

Return type:

Sites

Notes

The method uses normalize_session() to handle parsing, discovery, and optional topography alignment in a consistent way.

Examples

>>> from pycsamt.seg.collection import EDICollection
>>> # edicol = ...  # suppose we already parsed a folder
>>> # sites = Sites.from_any(edicol)
>>> # isinstance(sites, Sites)
True
write(outdir, *, template='{station}.edi', exist_ok=False)[source]#

Write one EDI file per site to a directory.

Parameters:
  • outdir (str or pathlib.Path) – Destination directory. It is created if missing.

  • template (str, optional) – Filename template. The token {station} is replaced by the normalized station name. Default is "{station}.edi".

  • exist_ok (bool, optional) – If False and a file already exists, raise FileExistsError. If True, overwrite. Default is False.

Returns:

Paths to the written files.

Return type:

list of pathlib.Path

Raises:

FileExistsError – If a target file exists and exist_ok is False.

Notes

If an EDI object implements to_file, it is used to serialize. Otherwise a small placeholder file is written.

Examples

>>> import tempfile, pathlib
>>> tmp = pathlib.Path(tempfile.mkdtemp())
>>> paths = sites.write(tmp, exist_ok=True)
>>> all(p.exists() for p in paths)
True
to_profile(origin, azimuth, *, crs=None)[source]#

Convert sites to a 1D profile aligned with a specified azimuth, returning either a rich Profile object or a lightweight fallback.

Parameters:
  • origin (tuple of float) – (lat, lon) in decimal degrees defining the profile origin.

  • azimuth (float) – Profile azimuth in degrees. North is 0 and angles increase clockwise.

  • crs (int, optional) – Optional CRS code for libraries that require it. Not used in the lightweight fallback. Default is None.

Returns:

If Profile is available, a Profile is returned. Otherwise a dict is returned with keys "origin", "azimuth", and "sites" in chainage order.

Return type:

Profile or dict

Notes

The fallback computes local chainage by a flat approximation around origin:

\[\begin{split}ch = dx * \\sin(az) + dy * \\cos(az)\end{split}\]

where dx and dy are metric offsets relative to the origin. Sites lacking valid coordinates are skipped.

Examples

>>> prof = sites.to_profile(origin=(0.0, 0.0), azimuth=90.0)
>>> hasattr(prof, "chainages") or isinstance(prof, dict)
True

See also

pycsamt.site.profile.Profile

Rich profile object when available.

pycsamt.site.base.to_sites(x, *, recursive=True, on_dup='replace', strict=False, verbose=0)[source]#

Coerce an arbitrary EDI-like input into a Sites wrapper.

This helper normalizes many inputs to a uniform Sites interface:

  • If x is already a Sites instance, it is returned unchanged.

  • If x is an EDICollection or a sequence of EDIFile objects, a new Sites wrapper is created.

  • If x is an iterable yielding EDI-like items, they are collected and wrapped.

The operation is light-weight and does not deep-copy the underlying EDI objects. The returned Sites simply holds references to the same items.

Parameters:
  • x (Any) – A Sites instance, an EDICollection, a sequence of EDIFile objects, or an iterable yielding EDI-like items.

  • recursive (bool)

  • on_dup (str)

  • strict (bool)

  • verbose (int)

Returns:

A Sites wrapper over the provided items.

Return type:

pycsamt.site.base.Sites

Notes

Use this utility at API boundaries to conveniently accept multiple input forms while providing a consistent downstream interface. If you need independent copies of the underlying data, perform your own cloning before calling to_sites.

Examples

Wrap a list of EDIFile objects:

>>> from pycsamt.site.selection import to_sites
>>> s = to_sites([e1, e2, e3])
>>> len(s)
3

Wrap an existing Sites (no-op):

>>> s2 = to_sites(s)
>>> s2 is s
True

Wrap an EDICollection:

>>> s3 = to_sites(coll)  # coll is an EDICollection
>>> [t.name for t in s3]
['A01', 'A02']

See also

pycsamt.site.base.Sites

Wrapper providing per-site convenience methods.

pycsamt.site.base.Sites.from_any

Alternate constructor with session normalization.

pycsamt.site.base.to_edis(x, *, as_collection=False, copy=False, recursive=True, on_dup='replace', strict=False, verbose=0, progress=False)[source]#

Unwrap site-like inputs to raw EDI objects.

This is the inverse boundary of to_sites(). It accepts a single Site, a Sites collection, an EDICollection, raw EDI objects, path-like inputs, or mixed iterables containing those forms. The returned objects are the underlying EDI containers used by low-level writers, exporters, and EM processing functions.

Parameters:
  • x (Any) – Site-like input to unwrap. Supported values include Site, Sites, EDIFile, EDICollection, path-like inputs, or iterables containing site/EDI-like objects.

  • as_collection (bool, default False) – If True, return an EDICollection. Otherwise a single input returns one EDI object and multi-item inputs return a list.

  • copy (bool, default False) – If True, return best-effort deep copies of the EDI objects. If copying fails for an item, that item is returned unchanged.

  • recursive (bool, default True) – Forwarded to path-like discovery through EDICollection.

  • on_dup ({'replace', 'keep', 'keep_first', 'keep_last', 'raise'}, default 'replace') – Duplicate station policy. replace and keep are forwarded to path loading. keep_first, keep_last, and raise are enforced after collection construction.

  • strict (bool, default False) – If True, raise when an object cannot be unwrapped to EDI. If False, invalid items are skipped.

  • verbose (int, default 0) – Verbosity forwarded to collection construction and duplicate policy diagnostics.

  • progress (bool or {'auto'}, default False) – Enable progress display while unwrapping iterable inputs.

Returns:

Raw EDI object(s), depending on the input shape and as_collection.

Return type:

EDIFile, list of EDIFile, or EDICollection

Notes

The operation is shallow by default. It returns the same EDI objects wrapped by Site or Sites. Pass copy=True when the caller should be able to mutate the returned objects independently.

Examples

>>> from pycsamt.site.base import Site, Sites, to_edis
>>> site = Site(edi)
>>> raw = to_edis(site)
>>> raw is edi
True
>>> raws = to_edis(Sites([edi]))
>>> len(raws)
1
>>> coll = to_edis(Sites([edi]), as_collection=True)
>>> len(coll)
1

See also

to_sites

Wrap raw EDI-like inputs into Sites.

Site.to_edi

Convenience method for one Site.

Sites.to_edis

Convenience method for a Sites collection.