2.29.3.5. pycsamt.topo.section#

One-call topography-embedded 2-D resistivity section plots.

This module generalizes the terrain-following pipeline in pycsamt.topo.extract/pycsamt.topo.drape/ pycsamt.topo.overlay into a single entry point that accepts any pycsamt resistivity model or inversion result and any source of station topography, then renders a colour section that drapes correctly over real terrain.

Two rendering modes are supported, mirroring the two modes already provided by pycsamt.topo.overlay:

kind="pcolormesh" (default)

A profile-distance vs. elevation section. The flat depth grid is warped into terrain-following coordinates with drape_section() and the terrain surface is drawn with draw_topo_section().

kind="imshow"

A station-index vs. depth pseudosection. The colour grid is left flat (depth increasing downward) and a compact elevation profile strip is inserted above the axes with draw_topo_strip().

Accepted model inputs#

Accepted topography inputs#

  • sites — any Sites / EDI collection accepted by extract_elevation().

  • elevation (+ optional chainage) — explicit arrays.

  • Model-derived — inferred from air-like cells (log10(rho) above air_log10_threshold) when neither of the above is given. This is a relative terrain profile (no absolute vertical datum) unless sites/elevation supply one.

Examples

Plot a backend-neutral inversion result with topography from its source EDI collection:

>>> from pycsamt.topo import plot_topo_section
>>> ax = plot_topo_section(result, sites=sites, depth_max=1500.0)

Plot an AI 3-D inversion result, depth-cropped to 1.5 km, as a pseudosection with an elevation strip:

>>> ax = plot_topo_section(
...     agent_result, sites=sites, kind="imshow",
...     model_unit="km", depth_max=1.5,
... )

Build the data without plotting (e.g. for a custom figure):

>>> from pycsamt.topo import build_topo_section
>>> section = build_topo_section(model, sites=sites)
>>> section.values.shape

Functions

build_topo_section(model, *[, sites, ...])

Resolve a model + topography source into a terrain-draped section.

extract_grid(model, *[, station_x, ...])

Adapt any supported 2-D inversion result into a flat GridInfo.

plot_topo_array(x_centers, z_centers, values, *)

Drape an arbitrary 2-D scalar field over real topography.

plot_topo_section(model, *[, ax, kind, ...])

Plot a resistivity model or inversion result draped over topography.

Classes

GridInfo(x_centers, z_centers, rho_log10, ...)

Adapter output — a flat cell-centre resistivity grid.

TopoSection(x_nodes_km, z_draped_km, values, ...)

Resolved, terrain-embedded 2-D resistivity section.

class pycsamt.topo.section.TopoSection(x_nodes_km, z_draped_km, values, x_centers_km, z_centers_km, z_nodes_km, chainage_km, elev_km, surface_km, station_x_km, station_names, depth_min_km, depth_max_km, exaggeration, log_rho, method, rms, topo_source)[source]

Bases: object

Resolved, terrain-embedded 2-D resistivity section.

Returned by build_topo_section(). Carries both the terrain-draped grid (for pcolormesh) and the flat cell-centre grid plus raw topography arrays (for imshow / custom plots).

Variables:
  • x_nodes_km (ndarray, shape (n_x+1,)) – Profile-distance pcolormesh node positions (km).

  • z_draped_km (ndarray, shape (n_z+1, n_x+1)) – Terrain-following elevation node grid (km a.s.l.), ready for ax.pcolormesh(x_nodes_km, z_draped_km, values).

  • values (ndarray, shape (n_z, n_x)) – Cell values — log10(rho) when log_rho=True, linear resistivity otherwise. NaN-masked above terrain when clip_above_surface=True.

  • z_centers_km (x_centers_km,) – Flat (undraped) cell-centre coordinates (km), post depth-crop.

  • z_nodes_km (ndarray, shape (n_z+1,)) – Flat (undraped) depth node positions (km), post depth-crop.

  • elev_km (chainage_km,) – Resolved topography source arrays (one value per topography sample point — station count, which may differ from n_x).

  • surface_km (ndarray, shape (n_x+1,)) – Terrain elevation interpolated to x_nodes_km (km a.s.l.).

  • station_x_km (ndarray) – Marker x-positions (km) for station pins.

  • station_names (list of str) – Station labels, aligned with station_x_km.

  • depth_max_km (depth_min_km,) – Effective (post-crop) depth range, km below the flat datum.

  • exaggeration (float) – Vertical exaggeration applied while draping.

  • log_rho (bool) – Whether values is log10(rho) (True) or linear rho.

  • method (str) – Source model tag ("occam2d", "modem", "ai", …).

  • rms (float) – Inversion RMS misfit, if available; nan otherwise.

  • topo_source (str) – Which topography source was actually used: "sites", "array", "model", or "flat".

Parameters:
x_nodes_km: ndarray
z_draped_km: ndarray
values: ndarray
x_centers_km: ndarray
z_centers_km: ndarray
z_nodes_km: ndarray
chainage_km: ndarray
elev_km: ndarray
surface_km: ndarray
station_x_km: ndarray
station_names: list[str]
depth_min_km: float
depth_max_km: float
exaggeration: float
log_rho: bool
method: str
rms: float
topo_source: str
pycsamt.topo.section.build_topo_section(model, *, sites=None, elevation=None, chainage=None, station_names=None, station_x=None, topo_source='auto', model_unit='m', depth_min=0.0, depth_max=None, exaggeration=1.0, log_rho=True, interp_method='linear', clip_above_surface=True, smooth_sigma=None, air_log10_threshold=5.0)[source]

Resolve a model + topography source into a terrain-draped section.

This is the data-building half of plot_topo_section() — use it directly when you want the resolved arrays without a figure.

Parameters:
  • model (object) – Any of the input forms documented in the module docstring: a (x_centers, z_centers, rho_2d) tuple, a pycsamt.interp.ResistivityModel, a backend-neutral or native Occam2D/ModEM InversionResult, or an AI agent result exposing pred_rho.

  • sites (object, optional) – Station/EDI collection to extract chainage + elevation from (see pycsamt.topo.extract). Takes priority over elevation when topo_source="auto".

  • elevation (array_like, optional) – Explicit per-station elevation (m a.s.l.). Paired with chainage (km); if chainage is omitted, the model’s own station positions are used.

  • chainage (array_like, optional) – Explicit per-station along-profile distance (km). Only used together with elevation.

  • station_names (sequence of str, optional) – Overrides the station labels carried by model / sites.

  • station_x (array_like, optional) – Overrides the marker x-positions carried by model.

  • topo_source ({"auto", "sites", "array", "model"}) – Which topography source to use. "auto" prefers sites, then elevation, then model-derived (air-cell) inference, then falls back to a flat datum with a warning.

  • model_unit ({"m", "km"}) – Unit of model’s coordinate arrays (and of depth_min / depth_max). Ignored for AI-style results, whose depths_km/coordinates are always treated as km.

  • depth_min (float, optional) – Depth window to display, in model_unit units. None keeps the full depth range.

  • depth_max (float, optional) – Depth window to display, in model_unit units. None keeps the full depth range.

  • exaggeration (float, default 1.0) – Vertical exaggeration applied to the terrain relief.

  • log_rho (bool, default True) – Keep values as log10(rho). False converts to linear Ω·m (10 ** log10_rho).

  • interp_method ({"linear", "cubic", "nearest"}) – Elevation interpolation method, forwarded to interp_elev().

  • clip_above_surface (bool, default True) – NaN-mask cells that lie above the local terrain surface.

  • smooth_sigma (float or (float, float), optional) – Gaussian-smoothing sigma (depth, distance), applied to values before draping. Requires scipy; silently skipped with a warning when scipy is unavailable.

  • air_log10_threshold (float, default 5.0) – log10(rho) threshold used for model-derived terrain inference (topo_source in {"auto", "model"}).

Return type:

TopoSection

Raises:
  • TypeError – If model is not a recognised input form.

  • ValueError – If topo_source is invalid, or is forced to a source that cannot be resolved (e.g. "sites" without sites).

pycsamt.topo.section.plot_topo_section(model, *, ax=None, kind='pcolormesh', sites=None, elevation=None, chainage=None, station_names=None, station_x=None, topo_source='auto', model_unit='m', depth_min=0.0, depth_max=None, exaggeration=1.0, log_rho=True, interp_method='linear', clip_above_surface=True, smooth_sigma=None, air_log10_threshold=5.0, cmap='jet_r', vmin=None, vmax=None, vmin_percentile=2.0, vmax_percentile=98.0, colorbar=True, section='inversion', show_stations=True, show_station_names=True, topo_cfg=None, station_marker=None, dark=False, title=None, figsize=None, savepath=None, savefig_kw=None, return_data=False)[source]

Plot a resistivity model or inversion result draped over topography.

A single entry point that accepts any of the model forms described in the pycsamt.topo.section module docstring (raw arrays, pycsamt.interp.ResistivityModel, backend-neutral or native Occam2D/ModEM InversionResult, AI agent results) together with any topography source (sites, explicit arrays, or model-derived inference), and renders a publication-style section using the shared pycsamt.api styling (pycsamt.api.section.PYCSAMT_SECTION, pycsamt.api.station.PYCSAMT_STATION_RENDERING).

Parameters:
  • model (object) – See the module docstring for accepted forms.

  • ax (matplotlib Axes, optional) – Existing axes to draw into. A new figure/axes is created when omitted, sized via the selected section style.

  • kind ({"pcolormesh", "imshow"}) – "pcolormesh" drapes the grid over real terrain (profile distance vs. elevation). "imshow" keeps a flat station-index vs. depth pseudosection with a compact elevation strip inserted above it.

  • sites (Any) – Topography source, forwarded to build_topo_section().

  • elevation (Any) – Topography source, forwarded to build_topo_section().

  • chainage (Any) – Topography source, forwarded to build_topo_section().

  • station_names (Sequence[str] | None) – Topography source, forwarded to build_topo_section().

  • station_x (Any) – Topography source, forwarded to build_topo_section().

  • topo_source (str) – Topography-resolution and unit controls, forwarded to build_topo_section().

  • model_unit (str) – Topography-resolution and unit controls, forwarded to build_topo_section().

  • depth_min (float) – Depth window and vertical exaggeration, forwarded to build_topo_section().

  • depth_max (float | None) – Depth window and vertical exaggeration, forwarded to build_topo_section().

  • exaggeration (float) – Depth window and vertical exaggeration, forwarded to build_topo_section().

  • log_rho (bool) – Value scaling and grid-building controls, forwarded to build_topo_section() — see its docstring for details.

  • interp_method (str) – Value scaling and grid-building controls, forwarded to build_topo_section() — see its docstring for details.

  • clip_above_surface (bool) – Value scaling and grid-building controls, forwarded to build_topo_section() — see its docstring for details.

  • smooth_sigma (float | tuple[float, float] | None) – Value scaling and grid-building controls, forwarded to build_topo_section() — see its docstring for details.

  • air_log10_threshold (float) – Value scaling and grid-building controls, forwarded to build_topo_section() — see its docstring for details.

  • cmap (str, default "jet_r") – Matplotlib colormap.

  • vmin (float, optional) – Explicit colour-scale limits. When omitted, computed from vmin_percentile / vmax_percentile of the visible values.

  • vmax (float, optional) – Explicit colour-scale limits. When omitted, computed from vmin_percentile / vmax_percentile of the visible values.

  • vmin_percentile (float, default 2.0, 98.0) – Percentile bounds used to auto-scale the colour map.

  • vmax_percentile (float, default 2.0, 98.0) – Percentile bounds used to auto-scale the colour map.

  • colorbar (bool, default True) – Draw a colorbar using the shared section colorbar style.

  • section (str or pycsamt.api.section.SectionStyle, default "inversion") – Section style preset name or explicit style object.

  • show_stations (bool, default True) – Draw station markers (pins for pcolormesh, the elevation strip’s markers for imshow).

  • show_station_names (bool, default True) – Draw station name labels alongside the markers.

  • topo_cfg (pycsamt.topo.config.TopoConfig, optional) – Full terrain-rendering style override (fill colour/alpha, line style, marker pad, …). Defaults to a config that only toggles station_pins_at_surface from show_stations and turns off the above-surface fill (see Notes).

  • station_marker (pycsamt.api.station.StationMarkerStyle, optional) – Station-pin style override, forwarded to draw_topo_section() / draw_topo_strip(). Defaults to a white-filled, black-edged marker sized for legibility against a busy cmap background; pass a StationMarkerStyle to override.

  • dark (bool, default False) – Use light-on-dark label colours for the terrain overlay.

  • title (str, optional) – Axes title. Defaults to a method/rms/topo-source summary.

  • figsize ((float, float), optional) – Explicit figure size, overriding the section style’s sizing.

  • savepath (str, optional) – Save the figure via pycsamt.api.plot.save_fig().

  • savefig_kw (dict, optional) – Extra keyword arguments forwarded to save_fig.

  • return_data (bool, default False) – When True, return (ax, TopoSection) instead of ax.

Returns:

Or (ax, TopoSection) when return_data=True.

Return type:

matplotlib.axes.Axes

Examples

>>> from pycsamt.topo import plot_topo_section
>>> ax = plot_topo_section(result, sites=sites)

Cropped to the shallow 1.5 km and rendered as a pseudosection:

>>> ax = plot_topo_section(
...     result,
...     sites=sites,
...     kind="imshow",
...     depth_max=1500.0,
... )
pycsamt.topo.section.plot_topo_array(x_centers, z_centers, values, *, ax=None, elevation, station_x=None, chainage=None, station_names=None, model_unit='m', depth_min=0.0, depth_max=None, exaggeration=1.0, clip_above_surface=True, cmap='viridis', vmin=None, vmax=None, colorbar=True, cbar_label='', show_stations=True, show_station_names=True, station_marker=None, dark=False, title=None, figsize=None)[source]

Drape an arbitrary 2-D scalar field over real topography.

The terrain-following counterpart of plot_topo_section() for grids that are not log10(resistivity) — a calibration misfit map, a sensitivity map, a depth-of-investigation mask, anything defined on the same (x_centers, z_centers) grid as a resistivity model but carrying its own physical units and colour scale. Uses the same drape_section() warp and draw_topo_section() terrain overlay (and the same default inversion station marker) as plot_topo_section(), without ever assuming the values are resistivity or applying a log10 transform.

Parameters:
  • x_centers (array_like) – Cell-centre coordinates of values, in model_unit.

  • z_centers (array_like) – Cell-centre coordinates of values, in model_unit.

  • values (ndarray, shape (n_z, n_x)) – The scalar field, plotted and colour-mapped exactly as given.

  • ax (matplotlib.axes.Axes, optional) – Existing axes to draw into. A new figure/axes is created when omitted.

  • elevation (array_like) – Terrain elevation (m a.s.l.) matching chainage (or station_x when chainage is omitted).

  • station_x (array_like, optional) – Station positions for the marker pins, in model_unit. Defaults to chainage.

  • chainage (array_like, optional) – Along-profile positions matching elevation, in model_unit. Defaults to station_x. One of the two is required.

  • station_names (sequence of str, optional)

  • model_unit ({"m", "km"})

  • depth_min (float) – Depth window to display, in model_unit. Defaults to the full range of z_centers.

  • depth_max (float) – Depth window to display, in model_unit. Defaults to the full range of z_centers.

  • exaggeration (float) – Vertical exaggeration applied to both the terrain and the depth axis.

  • clip_above_surface (bool) – Mask cells above the local terrain surface to NaN.

  • cmap (colour-scale controls forwarded to pcolormesh.)

  • vmin (colour-scale controls forwarded to pcolormesh.)

  • vmax (colour-scale controls forwarded to pcolormesh.)

  • colorbar (bool)

  • cbar_label (str) – Colorbar label. Unlike plot_topo_section(), this is never inferred — there is no single physical quantity to assume — so pass the correct label explicitly.

  • show_stations (bool)

  • show_station_names (bool)

  • station_marker (pycsamt.api.station.StationMarkerStyle, optional) – Defaults to the shared inversion marker (white-filled, black-edged downward triangle), matching plot_topo_section().

  • dark (bool)

  • title (str, optional)

  • figsize ((float, float), optional) – Used only when ax is omitted.

Return type:

matplotlib.axes.Axes

Examples

>>> import numpy as np
>>> from pycsamt.topo.section import plot_topo_array
>>> x = np.linspace(0.0, 900.0, 10)
>>> z = np.linspace(10.0, 500.0, 8)
>>> values = np.full((8, 10), 5.0)
>>> elev = 100.0 + 10.0 * np.sin(x / 300.0)
>>> ax = plot_topo_array(
...     x, z, values, elevation=elev, station_x=x,
...     cmap="RdYlBu_r", vmin=0.0, vmax=20.0, cbar_label="G (%)",
... )
>>> ax.get_ylabel()
'Elevation (km)'
class pycsamt.topo.section.GridInfo(x_centers, z_centers, rho_log10, station_x, station_names, method, rms, unit)[source]

Bases: object

Adapter output — a flat cell-centre resistivity grid.

Returned by extract_grid(), the single “accept any 2-D inversion result” normalizer shared across the package (topography draping here, pycsamt.interp.ResistivityModel.from_any(), pycsamt.interp.export’s Surfer writers, …).

Parameters:
x_centers: ndarray
z_centers: ndarray
rho_log10: ndarray
station_x: ndarray
station_names: list[str]
method: str
rms: float
unit: str
pycsamt.topo.section.extract_grid(model, *, station_x=None, station_names=None, unit='m')[source]

Adapt any supported 2-D inversion result into a flat GridInfo.

This is the single “accept anything” normalizer behind build_topo_section()/plot_topo_section(), pycsamt.interp.ResistivityModel.from_any(), and pycsamt.interp.export’s Surfer writers — promoted to public so those callers do not need a private cross-module import.

Parameters:
  • model (object) – Any of the forms listed in this module’s docstring under “Accepted model inputs” (a raw (x_centers, z_centers, rho_2d) triple, ResistivityModel, a backend-neutral InversionResult, a native Occam2D or 2-D ModEM InversionResult, or an AI agent result exposing pred_rho).

  • station_x (array_like, optional) – Overrides the station positions carried by model.

  • station_names (sequence of str, optional) – Overrides the station labels carried by model.

  • unit ({"m", "km"}) – Unit of model’s own coordinates when model is a raw (x_centers, z_centers, rho_2d) triple. Ignored for input forms that carry their own unit.

Return type:

GridInfo

Raises:
  • TypeError – If model is not a recognised input form.

  • NotImplementedError – For a native MARE2DEM result (unstructured triangular mesh — regrid onto a regular grid first).

  • ValueError – For a native 3-D ModEM result (extract a 2-D cut first).

Examples

>>> import numpy as np
>>> from pycsamt.topo.section import extract_grid
>>> x = np.array([0.0, 100.0, 200.0])
>>> z = np.array([10.0, 50.0])
>>> rho_log10 = np.array([[2.0, 2.1, 2.2], [2.5, 2.6, 2.7]])
>>> info = extract_grid((x, z, rho_log10))
>>> info.method, info.unit
('array', 'm')