pycsamt.site.profile#
Functions
|
Infer the survey line azimuth from a collection of sites. |
Classes
|
Profile(origin, azimuth, chainages=None, spacing_stats=None, |
- pycsamt.site.profile.infer_line_orientation(sites)[source]#
Infer the survey line azimuth from a collection of sites.
This estimates the dominant line axis that best explains the site distribution. The estimate uses PCA on local Cartesian offsets derived from geographic coordinates. The result is an azimuth in degrees where 0 deg is north and 90 deg is east.
- Parameters:
sites (iterable of objects) – Items may be EDI-like objects or wrappers exposing an
.ediattribute. Site names and coordinates are resolved usingpycsamt.site.utils.station_name()andpycsamt.site.utils.get_coords().- Returns:
Azimuth in degrees, 0 deg north and 90 deg east. Because eigenvectors are sign-ambiguous, the orientation is defined modulo 180 deg (e.g., 45 deg and 225 deg are the same axis).
- Return type:
Notes
Local offsets \((x, y)\) are built with a small-extent flat-Earth approximation about the mean latitude \(lat_0\) and longitude \(lon_0\):
\[ \begin{align}\begin{aligned}x = (lon - lon_0) * M\_PER\_DEG * cos(lat\_0)\\y = (lat - lat_0) * M\_PER\_DEG\end{aligned}\end{align} \]The principal component with the largest variance gives the line axis in the local frame \((x=east, y=north)\). It is then converted to an azimuth (0 deg north, 90 deg east).
Examples
>>> from pycsamt.site.profile import infer_line_orientation >>> class Head: ... def __init__(self, lat, lon, name): ... self.lat, self.lon, self.dataid = lat, lon, name ... >>> class EDI: ... def __init__(self, name, lat, lon): ... self._h = Head(lat, lon, name) ... def get_section(self, key): ... return self._h if key == "head" else None ... >>> east = [EDI(f"S{i}", 0.0, i*0.01) for i in range(5)] >>> az = infer_line_orientation(east) >>> 80.0 <= az <= 100.0 True
See also
pycsamt.site.profile.Profile,pycsamt.site.location.Coord,pycsamt.site.location.chainage_along,pycsamt.site.utils.get_coords,pycsamt.site.utils.station_nameReferences
- class pycsamt.site.profile.Profile(origin, azimuth, chainages=<factory>, spacing_stats=<factory>, gaps=<factory>)[source]#
Bases:
object- Profile(origin, azimuth, chainages=None, spacing_stats=None,
gaps=None)
Describe a 1-D survey line (profile) built from site locations. Stores the origin, line azimuth, per-site chainages, spacing statistics, and detected large gaps.
The azimuth follows the convention 0 deg north, 90 deg east. Chainages are in meters and are computed consistently with
pycsamt.site.location.chainage_along().- Parameters:
origin (pycsamt.site.location.Coord) – Origin coordinate used for chainage computations.
azimuth (float) – Line azimuth in degrees, 0 deg north, 90 deg east.
chainages (dict, optional) – Mapping
{station_name: chainage_m}. Usually filled viaProfile.from_sites().spacing_stats (dict, optional) – Precomputed spacing metrics. Filled automatically when chainages are set or updated.
gaps (list of tuple, optional) – Large spacing gaps as
[(s_left, s_right), ...]in meters.
- Variables:
origin (Coord) – Profile origin coordinate.
azimuth (float) – Profile azimuth (deg).
chainages (dict) – Per-site chainages in meters.
spacing_stats (dict) – Keys include
spacing_mean,spacing_med,spacing_min,spacing_max(meters).gaps (list of tuple) – Detected large gaps as chainage intervals (meters).
Notes
Chainage for a site with local offsets \((x,y)\) relative to the origin and profile azimuth \(A\) is
\[s = x * cos(A) + y * sin(A)\]Examples
>>> from pycsamt.site.profile import Profile >>> from pycsamt.site.location import Coord >>> class Head: ... def __init__(self, lat, lon, name): ... self.lat, self.lon, self.dataid = lat, lon, name ... >>> class EDI: ... def __init__(self, name, lat, lon): ... self._h = Head(lat, lon, name) ... def get_section(self, key): ... return self._h if key == "head" else None ... >>> sites = [EDI("A", 0.0, 0.00), ... EDI("B", 0.0, 0.01), ... EDI("C", 0.0, 0.02)] >>> prof = Profile.from_sites(sites) >>> round(prof.azimuth) in (89, 90, 91) True
See also
pycsamt.site.profile.infer_line_orientation,pycsamt.site.location.Coord,pycsamt.site.location.chainage_along- classmethod from_sites(sites, *, origin=None, azimuth=None)[source]#
Build a profile from an iterable of sites. If
originis omitted, the first site with finite coordinates is used. Ifazimuthis omitted, it is inferred withinfer_line_orientation().- Parameters:
- Returns:
Profile with per-site chainages and spacing statistics computed.
- Return type:
Notes
Coordinates and names are obtained via
pycsamt.site.utils.get_coords()andpycsamt.site.utils.station_name(). Chainages are computed withpycsamt.site.location.chainage_along().Examples
>>> from pycsamt.site.profile import Profile >>> prof = Profile.from_sites([]) >>> isinstance(prof, Profile) True
- sort_sites(sites)[source]#
Return the input sites ordered by chainage along the profile. Sites without finite chainage are dropped.
- Parameters:
sites (iterable) – Same accepted types as
Profile.from_sites().- Returns:
The subset of input sites sorted by increasing chainage.
- Return type:
Examples
>>> sorted_sites = prof.sort_sites(sites) >>> isinstance(sorted_sites, list) True
- slice(s_min, s_max)[source]#
Return chainages within the window
s_min <= s <= s_maxas a dict ordered by chainage.- Parameters:
- Returns:
Mapping
{station_name: chainage_m}, ordered by chainage.- Return type:
Examples
>>> win = prof.slice(500.0, 1500.0) >>> isinstance(win, dict) True
- resample(step)[source]#
Build a regular chainage grid between the current minimum and maximum chainage (inclusive of the minimum). If
step <= 0, an empty array is returned.- Parameters:
step (float) – Grid spacing in meters.
- Returns:
1-D array of chainage locations in meters.
- Return type:
Examples
>>> grid = prof.resample(250.0) >>> (grid.ndim, grid.dtype.kind) == (1, 'f') True
- summary()[source]#
Return a compact summary of the profile and its spacing statistics.
- Returns:
Keys include
n_sites,s_min,s_max,n_gaps, and entries fromspacing_stats(spacing_mean,spacing_med,spacing_min,spacing_max).- Return type:
Examples
>>> info = prof.summary() >>> set(["n_sites", "n_gaps"]).issubset(info.keys()) True