2.8.1.1. pycsamt.site.base#
Functions
|
Unwrap site-like inputs to raw EDI objects. |
|
Coerce an arbitrary EDI-like input into a |
Classes
|
High-level wrapper for a single MT/CSAMT site backed by an |
|
Lightweight wrapper exposing station-centric accessors and utilities for a single |
|
Container for multiple |
- class pycsamt.site.base.SiteMixin(source, *, on_loss='warn')[source]
Bases:
CoreObjectLightweight 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.EDIFileParsed SEG-EDI container.
pycsamt.site.base.SiteConcrete site wrapper that enforces a stable ID.
pycsamt.site.base.SitesCollection helper for multiple sites.
References
[SiteMixin-1]SEG EDI Format. Society of Exploration Geophysicists. Commonly used magnetotelluric exchange format.
- Parameters:
source (Any)
on_loss (str)
- property backend: str[source]
Which backend natively constructed this site.
- Returns:
"edi"or"xml". The other representation is always available too (seeediandtf) but is lazily materialized and cached on first access.- Return type:
- property edi: EDIFile[source]
The underlying
EDIFile.- Returns:
When this site was constructed from an EDI object, the same object every time. When constructed from an
EMTFXML document, an EDI view is materialized on first access viapycsamt.emtf.converters.edi.emtf_to_edi()and cached, so this always returns the same object on repeated access (safe for in-place mutation and identity-keyed caches elsewhere in the codebase).- Return type:
Notes
Materializing from XML may emit a
DataLossWarning(or raise, depending onon_losspassed at construction) if the source document holds metadata the historical EDI format cannot represent.
- property tf: Any[source]
The underlying
EMTFdocument.- Returns:
When this site was constructed from an XML document, the same object every time. When constructed from an EDI object, a format-neutral view is materialized on first access via
pycsamt.emtf.converters.edi.edi_to_emtf()and cached (lossless – XML is a strict superset of EDI).- Return type:
See also
site_meta,site_layout,provenance,processing,copyright,quality_metaTypedmod:pycsamt.metadata accessors built on top of this document.
- property name: str[source]
Station identifier resolved from the EDI header or file stem.
- Returns:
Station name used for lookups and display.
- Return type:
Notes
The resolution order is defined in
_station_name(). XML-native sites resolve the name directly from theEMTFdocument without forcing EDI materialization.
- property coords: tuple[float, float, float][source]
Geographic coordinates of the site.
Notes
This accessor relies on
_get_coords()which parses EDI HEAD latitude, longitude and elevation. XML-native sites read directly from theEMTFdocument without forcing EDI materialization.
- property freq: Any[source]
Frequency vector extracted from the Z section.
- Returns:
One-dimensional array of frequencies in Hz, or
Noneif missing.- Return type:
array-like or None
See also
to_dataframeTabular 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, orNoneif 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
SiteMixin.z, orNoneif 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
Noneif 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
Noneif 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, orNoneif 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 anINFOsub-dict if present.- Return type:
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 onkind: -"z":Zxx, Zxy, Zyx, Zyy(complex values). -"resphase": pairs of columns per componentrho_*andphi_*."tipper":Tx, Ty.
- Return type:
- Raises:
ValueError – If
kindis 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_flagsQuick 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 isTrueif the array exists, has non-zero size, and all values are finite.- Return type:
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:
Trueif the component exists and has at least one finite value.- Return type:
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), andtipper(boolean).- Return type:
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:
- Returns:
The modified site (new instance unless
inplace).- Return type:
Notes
The method writes to EDI HEAD fields
dataid,station,sitename,name(best effort) and also updatesedi.name. Downstream containers that derive station IDs from the file stem may be configured to preferedi.nameto 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 isNone.inplace (bool, optional) – If
True, modify this instance. IfFalse, return a newSite. The default isFalse.
- Returns:
The modified site (new instance unless
inplace).- Return type:
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. IfFalse, return a newSite. The default isFalse.- Returns:
The modified site (new instance unless
inplace).- Return type:
Notes
The following arrays are replaced with empty arrays:
freq,z,z_error,rho, andphase. 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(source, *, on_loss='warn')[source]
Bases:
SiteMixinHigh-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.Sitealso accepts anEMTFXML document instead of an EDI object – seefrom_xml(). Either way,ediandtfare both always available: the representation not natively supplied is lazily materialized and cached from the other viapycsamt.emtf.converters.edi.edi_to_emtf()/emtf_to_edi, so every existing EDI-shaped accessor keeps working unchanged regardless of which format the site was built from.When constructed from EDI, the constructor normalizes EDI
HEADfields so thatdataid(and, if absent,station) matches the site stem resolved by_stem_from_edi(). If an in-memoryedi.nameexists, 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. XML-native sites keep the station identity already recorded in the document instead.- Parameters:
source (pycsamt.seg.edi.EDIFile or pycsamt.emtf.document.EMTF) – Parsed SEG-EDI container, or an EMTF XML document, holding one station. The EDI file may be constructed from disk or synthesized in memory.
on_loss ({"warn", "raise", "ignore"}, default "warn") – Policy applied if
ediis later materialized from an XML-native site and the document holds metadata the historical EDI format cannot represent.
- Variables:
edi (pycsamt.seg.edi.EDIFile) – Underlying (possibly lazily materialized) EDI object. Use with care; prefer the typed accessors of
SiteMixin(e.g.,freq,z).tf (pycsamt.emtf.document.EMTF) – Underlying (possibly lazily materialized) EMTF XML document. See also
site_meta,provenance,processing,site_layout,copyright,quality_meta.backend (str) –
"edi"or"xml"– which representation is native.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 thatdataidis 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 orderZxx, Zxy, Zyx, Zyy. Frequencies are 1D of lengthn. The tipper has two columnsTxandTy.- 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.SiteMixinMixin providing typed accessors and utilities.
pycsamt.site.base.SitesCollection helper for selection, slicing, and bulk edits.
pycsamt.seg.edi.EDIFileLow-level SEG-EDI container.
References
[Site-1]SEG EDI Format Specification. Society of Exploration Geophysicists. Exchange format for magnetotelluric and related EM data.
[Site-2]Chave, A. D., and Jones, A. G. (Eds.) (2012). The Magnetotelluric Method. Cambridge University Press.
[Site-3]Simpson, F., and Bahr, K. (2005). Practical Magnetotellurics. Cambridge University Press.
- classmethod from_edi(source, *, on_loss='warn')[source]
Construct a
Sitefrom an EDI object or a path to one.- Parameters:
source (pycsamt.seg.edi.EDIFile or str or pathlib.Path) – Parsed EDI object, or a path that will be read via
EDIFile(source).on_loss ({"warn", "raise", "ignore"}, default "warn") – Policy used if this site’s
tfis later materialized and something needs to be converted back.
- Returns:
A site backed natively by EDI.
- Return type:
See also
from_xmlConstruct from an EMTF XML document instead.
- classmethod from_xml(source, *, on_loss='warn')[source]
Construct a
Sitefrom an EMTF XML document or path.- Parameters:
source (pycsamt.emtf.document.EMTF or str or pathlib.Path) – Parsed EMTF document, or a path that will be read via
pycsamt.emtf.document.EMTF.from_xml().on_loss ({"warn", "raise", "ignore"}, default "warn") – Policy applied when this site’s
ediview is later materialized and the document holds metadata the historical EDI format cannot represent.
- Returns:
A site backed natively by the richer EMTF XML model;
z,freq,tipper, and friends keep working exactly as for an EDI-backed site (via a cached, lazily materialized EDI view), whiletf,site_meta,provenance, and related properties expose the full richer metadata.- Return type:
See also
from_ediConstruct from a SEG EDI object instead.
Site.to_xmlSerialize a site back to EMTF XML.
- to_xml(target=None, **kwargs)[source]
Serialize this site to EMTF XML.
- Parameters:
target (str or pathlib.Path, optional) – Destination path. If
None, the XML document is returned as a string instead of being written.**kwargs – Forwarded to
pycsamt.emtf.document.EMTF.write_xml()(whentargetis given) orpycsamt.emtf.document.EMTF.to_xml()(otherwise).
- Returns:
The XML document as a string when
targetisNone; otherwise the return value ofwrite_xml().- Return type:
str or Any
See also
from_xmlThe inverse constructor.
tfThe underlying
EMTFdocument used here.
- 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:
See also
pycsamt.site.base.to_edisGeneral unwrapping helper for
Site/Sitesand mixed inputs.
- class pycsamt.site.base.Sites(edic, *, on_loss='warn')[source]
Bases:
CoreObjectContainer for multiple
Siteobjects with convenient indexing, selection, and bulk edit operations.Siteswraps each providedEDIFileinto aSite, 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 viaedit_all().- Parameters:
edic (pycsamt.seg.collection.EDICollection or sequence of) –
- pycsamt.seg.edi.EDIFile, pycsamt.emtf.document.EMTF, or
Parsed EDI collection, or any sequence mixing EDI objects, EMTF XML documents, and already-constructed
Siteinstances. Items are wrapped intoSiteinstances (existingSiteitems are used as-is) in the order provided.on_loss (str)
- Variables:
_items (list of Site) – Internal sequence of sites. This is considered private. Iterate over
Sitesinstead of accessing it directly.
Notes
- Identity and lookup
Each site inside the container uses the same naming policy as
Site. Name-based lookups withsites["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-thSite.- 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=Trueto modify the container, otherwise a newSitesis 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 unlessinplace=Trueis requested.- Profile conversion
to_profile()attempts to build aProfilewhen 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 providesto_file, it is used; otherwise a placeholder is written.- Robustness and errors
__getitem__raisesKeyErrorwhen a name is not found. Preferget()to obtainNoneinstead.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.SiteSite wrapper used for each element in the container.
pycsamt.seg.collection.EDICollectionParsed collection produced by the core parser.
pycsamt.site.profile.ProfileOptional profile object produced by
to_profile().
References
[Sites-1]SEG EDI Format Specification. Society of Exploration Geophysicists.
[Sites-2]Chave, A. D., and Jones, A. G. (2012). The Magnetotelluric Method. Cambridge University Press.
[Sites-3]Simpson, F., and Bahr, K. (2005). Practical Magnetotellurics. Cambridge University Press.
- 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:
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
Noneif 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:
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
- property ordering: dict[str, Any][source]
Describe the most recent ordering decision for this container.
- ordered(by=None, *, inplace=False, min_linearity=None, max_cross_track_ratio=None, min_coordinate_fraction=None)[source]
Return sites in a deterministic spatial or identity order.
by='auto'applies chainage ordering only when the finite coordinates describe one credible, approximately straight survey line. Otherwise it preserves input order.by='chainage'forces projection onto the PCA profile axis; sites without usable coordinates are retained at the end in their original order.Other modes are
'input','station'(natural numeric station order),'latitude'/'lat', and'longitude'/'lon'. Station names remain identifiers and are never changed.
- to_edis(*, copy=False, progress=False, verbose=0)[source]
Return the underlying EDI objects as a list.
- Parameters:
- Returns:
EDI objects in site order.
- Return type:
See also
to_edicollectionReturn an
EDICollectioninstead.pycsamt.site.base.to_edisGeneral unwrapping helper.
- to_edicollection(*, copy=False, progress=False, verbose=0)[source]
Return the underlying EDI objects as an
EDICollection.- Parameters:
- Returns:
Collection built from the underlying EDI objects.
- Return type:
pycsamt.seg.collection.EDICollection
- to_emtf_list()[source]
Return the underlying EMTF XML documents as a list.
- Returns:
One document per site, in site order. EDI-native sites are lazily converted and cached via
Site.tf; XML-native sites are returned as-is, with no information loss.- Return type:
See also
write_xmlPersist these documents to a directory.
to_edisThe EDI-side equivalent.
- write_xml(outdir, **kwargs)[source]
Write one EMTF XML file per site into a directory.
- Parameters:
outdir (str or pathlib.Path) – Destination directory. It is created if missing.
**kwargs – Forwarded to
Site.to_xml()for each site.
- Returns:
Paths to the written files, named
"{station}.xml".- Return type:
list of pathlib.Path
See also
to_emtf_listIn-memory equivalent without writing to disk.
Sites.writeThe EDI-side equivalent.
- closest(lat, lon, tol=None)[source]
Find the closest site to a target coordinate using geodetic distance.
- Parameters:
- Returns:
Nearest site or
Noneif 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:
Examples
>>> sites.map(lambda s: s.name)[:2] ['E01', 'E02']
- rename(names, *, inplace=False, missing='raise', allow_duplicates=False)[source]
Rename stations from a mapping, sequence, or callable.
- update_metadata(updates, *, inplace=False, missing='raise', allow_duplicates=False)[source]
Apply declarative station, HEAD, INFO, and coordinate updates.
- 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_serieswheredfis the output ofsite.to_dataframe("z"). Rows where the mask isFalseare set toNaNin Z.inplace (bool, optional) – If
True, modify this container and return it. IfFalse, return a newSites. Default isFalse.
- Returns:
The edited container (possibly the same instance).
- Return type:
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
freqand 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.renamePer-site rename helper.
Site.to_dataframeSource 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. IfFalse, return a newSites. Default isFalse.
- Returns:
Container with updated coordinates.
- Return type:
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 returnsTrueare retained.
- Returns:
New container with the selected sites.
- Return type:
Notes
If neither
namesnorpredicateis 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 ofEDIFile, - a singleEDIFile, - 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:
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
Falseand a file already exists, raiseFileExistsError. IfTrue, overwrite. Default isFalse.
- Returns:
Paths to the written files.
- Return type:
list of pathlib.Path
- Raises:
FileExistsError – If a target file exists and
exist_okisFalse.
Notes
Serialization goes through
pycsamt.emtf.converters.edi.write_edi(), which writes the underlyingEDIFileto an exact target path (working aroundwrite()’s own default of deriving anew_-prefixed name under a localedi_out/directory when not given an explicitnew_edifn/savepath).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:
- Returns:
If
Profileis 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
dxanddyare 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.ProfileRich 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
Siteswrapper.This helper normalizes many inputs to a uniform
Sitesinterface:If
xis already aSitesinstance, it is returned unchanged.If
xis anEDICollectionor a sequence ofEDIFileobjects, a newSiteswrapper is created.If
xis 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
Sitessimply holds references to the same items.- Parameters:
- Returns:
A
Siteswrapper over the provided items.- Return type:
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.SitesWrapper providing per-site convenience methods.
pycsamt.site.base.Sites.from_anyAlternate 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 singleSite, aSitescollection, anEDICollection, 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 anEDICollection. 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.
replaceandkeepare forwarded to path loading.keep_first,keep_last, andraiseare enforced after collection construction.strict (bool, default False) – If
True, raise when an object cannot be unwrapped to EDI. IfFalse, 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:
Notes
The operation is shallow by default. It returns the same EDI objects wrapped by
SiteorSites. Passcopy=Truewhen 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_sitesWrap raw EDI-like inputs into
Sites.Site.to_ediConvenience method for one
Site.Sites.to_edisConvenience method for a
Sitescollection.