2.23.3.1. pycsamt.format.adapters#

Per-backend converters into pycsamt.format.schema.PCSFModel.

Occam2D (Phase 2), ModEM 3-D (Phase 3), and MARE2DEM (Phase 4) are implemented, per PYCSAMT-PCSF-INVERSION-FORMAT-PLAN.md. DUHI has no separate adapter — its own output only becomes a final resistivity model once folded back into an Occam2D run, so it rides occam2d_to_pcsf().

pycsamt.format.adapters.generic is a fourth, solver-agnostic path for any other AI/DL inversion result (a UNet, a GCN, a ResNet, or a third party’s own model) whose output is itself the final resistivity model — no dependency on any pycsamt result class, only plain arrays.

pycsamt.format.adapters.occam2d_to_pcsf(result, *, station_elevations=None, station_lonlat=None, topo=None, epsg=None, utm_zone=None, latlon=False, on_mismatch='raise', survey=None, origin=None, azimuth_deg=None, created_by='', crs=None, description='')

Convert an Occam2D InversionResult to a PCSFModel.

Parameters:
  • result (InversionResult) – A loaded Occam2D post-inversion result (workdir scanned, rho_2d and mesh populated).

  • station_elevations (mapping of str to float, optional) – station_name -> elevation (m), e.g. from pycsamt.map.topo.fetch_elevations() or a survey’s own EDI-derived topography. Occam2D itself carries no elevation, so this is the only way PCSFModel.topography gets populated. Stations without a known elevation are recorded as nan rather than a fabricated flat value.

  • station_lonlat (mapping of str to (lon, lat), optional) – station_name -> (longitude, latitude), WGS84 decimal degrees – e.g. from the same EDI headers a pycsamt.metadata.SurveyMeta or pycsamt.map._core.StationRecord would carry. Occam2D itself has no real-world coordinate concept (only mesh-local chainage, recovered into Grid2DGeometry.x/ StationTable’s own x), so this is the only way a single Occam2D line’s PCSF file becomes self-sufficiently geo-referenced – without it, placing this line on a real basemap needs a separate known_stations match at pycsamt.map.MapView.from_pcsf() load time instead. Superseded per-station by topo when both are given (see below); a station topo has no data for still falls back to this mapping.

  • topo (path-like, TopoTable, Sites/MapData-like, or mapping, optional) – A “smart” real-coordinate source resolved via pycsamt.format.topo_source.resolve_topo() — a .bln/.csv/.stn topo file, an already-geo-located Sites/MapData object (e.g. pycsamt.map.load_lines(edi_folder)), or a plain {station_name: (lon, lat[, elevation])} mapping. A name-less source (a bare .bln, or a .csv without a station column) is matched positionally, in ResistivityModel.station_names’s own along-profile order, and therefore requires exactly one point per station (see on_mismatch). When given, topo’s own lon/lat/ elevation take precedence over station_lonlat/ station_elevations for every station it resolves — with a UserWarning if both were supplied, so the override is never silent; a station topo has no data for keeps whatever station_lonlat/station_elevations already gave it. Passing None (the default) leaves this adapter’s behaviour exactly as it was before topo existed.

  • epsg (optional) – Forwarded to pycsamt.format.topo_source.resolve_topo() for a topo file storing projected easting/northing rather than lon/lat (.stn files always do; a .csv/.bln does when its columns/units are projected). Ignored unless topo is given and actually needs conversion.

  • utm_zone (optional) – Forwarded to pycsamt.format.topo_source.resolve_topo() for a topo file storing projected easting/northing rather than lon/lat (.stn files always do; a .csv/.bln does when its columns/units are projected). Ignored unless topo is given and actually needs conversion.

  • latlon (bool, default False) – .bln topo files only: set True when the file’s own x, y columns are already lon, lat (a .bln carries no CRS metadata to detect this from).

  • on_mismatch ({"raise", "warn"}, default "raise") – How a topo station-count mismatch is handled for a name-less (positional) source — see pycsamt.format.topo_source.attribute_topo().

  • survey (SurveyMeta or mapping, optional) – Survey-level metadata (e.g. a pycsamt.metadata.SurveyMeta). Stored via its own to_dict() when available, otherwise copied as a plain mapping.

  • origin (ndarray or sequence of float, optional) – Real-world (x, y) offset for the profile, when known.

  • azimuth_deg (float, optional) – Profile bearing, when known.

  • created_by (str, optional) – Passed straight through to PCSFModel.

  • crs (str, optional) – Passed straight through to PCSFModel.

  • description (str, optional) – Passed straight through to PCSFModel.

Returns:

geometry.kind == "grid2d", canonical linear-ohm.m resistivity in PCSFModel.resistivity, the original log10 grid preserved in PCSFModel.resistivity_native, and iteration history (RMS, roughness, Lagrange multiplier, step size) from InversionResult.log when available.

Return type:

PCSFModel

Raises:

ValueError – If result has no rho_2d/mesh (mirrors ResistivityModel.from_occam2d()’s own check).

Examples

>>> from pycsamt.models.occam2d.results import InversionResult
>>> from pycsamt.format.adapters.occam2d import occam2d_to_pcsf
>>> from pycsamt.format import write_pcsf
>>> result = InversionResult(workdir="data/occam2D")
>>> model = occam2d_to_pcsf(result)
>>> write_pcsf(model, "occam2d_run.pcsf")
pycsamt.format.adapters.modem3d_to_pcsf(result, *, model=None, data=None, station_elevations=None, air_threshold_ohm_m=100000000.0, station_z_convention='auto', topo=None, epsg=None, utm_zone=None, latlon=False, on_mismatch='raise', survey=None, created_by='', crs=None, description='')

Convert a ModEM 3-D InversionResult to a PCSFModel.

Parameters:
  • result (InversionResult) – A loaded ModEM working directory (result.mode == "3d").

  • model (ModEmModel3D, optional) – Model to convert. Defaults to result.model_final, falling back to result.model_initial when no final model was parsed.

  • data (ModEmData, optional) – Source of station coordinates. Defaults to result.data_obs, falling back to result.data_pred. None when neither is available (PCSFModel.stations stays None rather than fabricating positions).

  • station_elevations (mapping of str to float, optional) – station_name -> elevation (m), overriding ModEM’s own station z (commonly a flat 0.0 placeholder — a real ModEM .dat file carries no topography). Matched stations also populate PCSFModel.topography; unmatched stations keep their real recorded z as-is (0.0 is a genuine value here, not “unknown”, unlike Occam2D’s equivalent parameter). Superseded per-station by topo when both are given.

  • air_threshold_ohm_m (float or None, default 1e8) – Cell resistivity (ohm.m) above which a cell is treated as ModEM’s above-topography “air” / padding fill rather than resolved earth, and set to nan in the canonical PCSFModel.resistivity. ModEM leaves the model cells above the real ground surface filled with air-like resistivity (1e8-1e13 ohm.m) even when the run declares no dedicated air layers (n_air == 0), and those cells otherwise hijack any auto colour scale (e.g. MapView’s fence view), crushing the real earth into a featureless band. PCSFModel.resistivity_native keeps the source model’s raw natural-log array unchanged for provenance. Leading complete air layers detected this way are also written to Grid3DGeometry.n_air (when the source model reported 0); metadata["air_mask"] records what was done. Pass None for an exact, unmasked passthrough of every cell.

  • station_z_convention ({"auto", "elevation", "depth_down"}, default "auto") – How to read a ModEM .dat file’s own Z(m) station column. ModEM’s model z-axis points downward, so a populated station Z is a depth below a datum, not an elevation – copied verbatim into StationTable.z it makes MapView’s topography drape render hills as hollows. "depth_down" forces the flip to an elevation (datum - Z; the datum is read from an ... m a.s.l. hint in the file’s # comments when present, else the deepest station is taken as 0 and the result is a relative elevation). "elevation" trusts the column as-is (what pycsamt’s own ModEM writer produces). "auto" (default) flips only when the .dat comment says the column is a positive-down depth; a flat all-zero column is always left untouched. metadata["station_z"] records the outcome.

  • topo (path-like, TopoTable, Sites/MapData-like, or mapping, optional) – A “smart” real-coordinate source resolved via pycsamt.format.topo_source.resolve_topo() – see pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s identical parameter for the full description. When given, it takes precedence over both station_elevations and the .dat file’s own GG_Lat/GG_Lon for every station it resolves (with a UserWarning if either was also supplied); a station it has no data for keeps its existing value. None (the default) leaves this adapter’s behaviour unaffected.

  • epsg (int | None) – Forwarded to pycsamt.format.topo_source.resolve_topo(); see occam2d_to_pcsf’s identical parameters.

  • utm_zone (Any | None) – Forwarded to pycsamt.format.topo_source.resolve_topo(); see occam2d_to_pcsf’s identical parameters.

  • latlon (bool) – Forwarded to pycsamt.format.topo_source.resolve_topo(); see occam2d_to_pcsf’s identical parameters.

  • on_mismatch (str) – Forwarded to pycsamt.format.topo_source.resolve_topo(); see occam2d_to_pcsf’s identical parameters.

  • survey (SurveyMeta or mapping, optional) – Survey-level metadata, stored the same way as in pycsamt.format.adapters.occam2d.occam2d_to_pcsf().

  • created_by (str, optional) – Passed straight through to PCSFModel.

  • crs (str, optional) – Passed straight through to PCSFModel.

  • description (str, optional) – Passed straight through to PCSFModel.

Returns:

geometry.kind == "grid3d", canonical linear-ohm.m resistivity in PCSFModel.resistivity (model.rho_linear, with above-topography air fill set to nan – see air_threshold_ohm_m), the original natural-log grid preserved unchanged in PCSFModel.resistivity_native, and iteration history (RMS, objective, model norm, Lagrange multiplier, step-size scaling alpha) from InversionResult.log when available. PCSFModel.stations’s lon/lat are populated from data’s own GG_Lat/GG_Lon columns (ModEmData.site_lonlat) when present, so the file is self-sufficiently geo-referenced without needing a separate known_stations match at load time. StationTable.z is a positive-up elevation – ModEM’s positive-down Z column is flipped when needed (see station_z_convention), so MapView’s topography drape shows hills as hills.

Return type:

PCSFModel

Raises:

ValueError – If result is not a 3-D ModEM result, or no model (explicit or resolved from result) is available.

Examples

>>> from pycsamt.models.modem.results import InversionResult
>>> from pycsamt.format.adapters.modem3d import modem3d_to_pcsf
>>> from pycsamt.format import write_pcsf
>>> result = InversionResult("modem_run")
>>> model = modem3d_to_pcsf(result)
>>> write_pcsf(model, "modem3d_run.pcsf")
pycsamt.format.adapters.mare2dem_to_pcsf(result, mesh, *, stations=None, survey=None, created_by='', crs=None, description='')

Convert a MARE2DEM InversionResult to a PCSFModel.

Parameters:
  • result (InversionResult) – A loaded MARE2DEM working directory with a readable .resistivity file (result.model).

  • mesh (TriMesh) – The real triangular mesh paired with result — the caller provides it (e.g. from pycsamt.models.mare2dem.tri_mesh.tri_mesh_from_poly(), or an in-process constrained triangulation of the run’s own .poly PSLG) since InversionResult does not load one itself. mesh.region_ids must be populated and must match the 1-based region numbering of result.model.resistivity.

  • stations (StationTable, optional) – MARE2DEM’s EMData/EMDataFile receiver geometry has no single reliable per-point name across its MT/CSEM/DC variants, so station identity is not auto-derived here — pass a pre-built table when the caller already has one (e.g. via pycsamt.models.mare2dem.geom.area_of_interest.survey_points() plus the caller’s own naming). Set its lon/lat (e.g. from the same EDI headers the receiver positions were derived from) to make the file self-sufficiently geo-referenced too — the same field pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s station_lonlat and pycsamt.format.adapters.modem3d.modem3d_to_pcsf()’s own GG_Lat/GG_Lon passthrough populate.

  • survey (SurveyMeta or mapping, optional) – Survey-level metadata, stored the same way as in the other adapters in this package.

  • created_by (str, optional) – Passed straight through to PCSFModel.

  • crs (str, optional) – Passed straight through to PCSFModel.

  • description (str, optional) – Passed straight through to PCSFModel.

Returns:

geometry.kind == "mesh_unstructured". Canonical resistivity is the per-triangle array expanded from result.model.resistivity via mesh.region_ids; the compact per-region table itself is kept in PCSFModel.resistivity_by_region. MARE2DEM’s .resistivity file is already linear ohm.m (confirmed against a real compiled binary — see ResistivityFile’s own docstring), so no resistivity_native/encoding conversion applies here.

Return type:

PCSFModel

Raises:

ValueError – If result has no resistivity model, mesh has no region_ids, a region id falls outside the resistivity table’s range, or the source is anisotropic (only isotropic MARE2DEM models are supported by this adapter today).

Examples

>>> from pycsamt.models.mare2dem.results import InversionResult
>>> from pycsamt.models.mare2dem.tri_mesh import tri_mesh_from_poly
>>> from pycsamt.format.adapters.mare2dem import mare2dem_to_pcsf
>>> from pycsamt.format import write_pcsf
>>> result = InversionResult("mare2dem_run")
>>> mesh = tri_mesh_from_poly("mare2dem_run/mesh.1.poly")
>>> model = mare2dem_to_pcsf(result, mesh)
>>> write_pcsf(model, "mare2dem_run.pcsf")
pycsamt.format.adapters.grid2d_to_pcsf(resistivity, x, z, *, encoding='linear', x_nodes=None, z_nodes=None, origin=None, azimuth_deg=None, uncertainty=None, sensitivity=None, stations=None, topography=None, station_names=None, station_x=None, station_elevations=None, station_lonlat=None, topo=None, epsg=None, utm_zone=None, latlon=False, on_mismatch='raise', history=None, provenance=None, survey=None, source_backend='ai', created_by='', crs=None, description='', metadata=None)

Build a grid2d PCSFModel from a bare AI/DL prediction.

The natural fit for a 2-D model (e.g. a UNet trained on inversion sections): give it its predicted array plus the coordinates it was predicted on, and it becomes the exact same on-disk artifact pycsamt.format.adapters.occam2d.occam2d_to_pcsf() produces for a real Occam2D run – readable by the same pycsamt.format.read_pcsf(), app/mapview, and the web 3-D view.

Parameters:
  • resistivity (array-like, shape (n_z, n_x)) – The model’s predicted resistivity, in whatever encoding it was trained/predicted in.

  • x (array-like) – Cell-centre coordinates (metres) matching Grid2DGeometry.

  • z (array-like) – Cell-centre coordinates (metres) matching Grid2DGeometry.

  • encoding ({"linear", "log10", "ln"}, default "linear") – Encoding of resistivity. Many DL models predict log-resistivity for training stability; when not "linear", the given array is kept verbatim as resistivity_native and the canonical linear resistivity is derived automatically.

  • x_nodes (Any) – Forwarded to Grid2DGeometry. origin/azimuth_deg are this geometry’s own “offset” – the real-world placement of an otherwise locally-referenced section.

  • z_nodes (Any) – Forwarded to Grid2DGeometry. origin/azimuth_deg are this geometry’s own “offset” – the real-world placement of an otherwise locally-referenced section.

  • origin (Any) – Forwarded to Grid2DGeometry. origin/azimuth_deg are this geometry’s own “offset” – the real-world placement of an otherwise locally-referenced section.

  • azimuth_deg (float | None) – Forwarded to Grid2DGeometry. origin/azimuth_deg are this geometry’s own “offset” – the real-world placement of an otherwise locally-referenced section.

  • uncertainty (array-like, optional) – Same shape as resistivity – a direct fit for a predictive standard deviation from an MC-dropout/Bayesian model.

  • sensitivity (array-like, optional) – Same shape as resistivity – a direct fit for a predictive standard deviation from an MC-dropout/Bayesian model.

  • stations (StationTable, optional) – A pre-built table, used as-is when given (bypasses every station_*/topo parameter below).

  • topography (TopographyPerStation or TopographyRaster, optional) – A pre-built topography, used as-is when given – e.g. a DEM raster from pycsamt.format.topography.topography_from_grid(), which no station_elevations/topo combination below can produce.

  • station_names (sequence, optional) – Station identity and along-profile chainage (same frame as x).

  • station_x (sequence, optional) – Station identity and along-profile chainage (same frame as x).

  • station_elevations (Mapping[str, float] | None) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • station_lonlat (Mapping[str, tuple[float, float]] | None) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • topo (Any) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • epsg (int | None) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • utm_zone (Any | None) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • latlon (bool) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • on_mismatch (str) – Identical to pycsamt.format.adapters.occam2d.occam2d_to_pcsf()’s own parameters of the same name – see that function’s docstring for the full description of the smart topo= resolver.

  • history (mapping of str to array-like, optional) – Per-iteration/per-epoch series (e.g. training/validation loss).

  • provenance (ModelProvenance or mapping, optional) – Folded into metadata["model_provenance"] – see pycsamt.format.provenance.

  • survey (Any | Mapping[str, Any] | None) – Passed through to PCSFModel; source_backend defaults to "ai" but any free-text string is accepted (e.g. "unet", "gcn", "resnet", a third party’s own name).

  • source_backend (str) – Passed through to PCSFModel; source_backend defaults to "ai" but any free-text string is accepted (e.g. "unet", "gcn", "resnet", a third party’s own name).

  • created_by (str) – Passed through to PCSFModel; source_backend defaults to "ai" but any free-text string is accepted (e.g. "unet", "gcn", "resnet", a third party’s own name).

  • crs (str | None) – Passed through to PCSFModel; source_backend defaults to "ai" but any free-text string is accepted (e.g. "unet", "gcn", "resnet", a third party’s own name).

  • description (str) – Passed through to PCSFModel; source_backend defaults to "ai" but any free-text string is accepted (e.g. "unet", "gcn", "resnet", a third party’s own name).

  • metadata (Mapping[str, Any] | None) – Passed through to PCSFModel; source_backend defaults to "ai" but any free-text string is accepted (e.g. "unet", "gcn", "resnet", a third party’s own name).

Return type:

PCSFModel

Examples

>>> import numpy as np
>>> from pycsamt.format.adapters.generic import grid2d_to_pcsf
>>> model = grid2d_to_pcsf(
...     resistivity=np.array([[2.0, 2.1], [1.7, 1.8]]),
...     x=np.array([0.0, 100.0]), z=np.array([10.0, 50.0]),
...     encoding="log10", source_backend="unet",
... )
>>> model.kind, model.source_backend
('grid2d', 'unet')
pycsamt.format.adapters.grid3d_to_pcsf(resistivity, x, y, z, *, encoding='linear', x_nodes=None, y_nodes=None, z_nodes=None, origin=None, rotation_deg=0.0, n_air=0, uncertainty=None, sensitivity=None, stations=None, topography=None, station_names=None, station_x=None, station_y=None, station_z=None, station_elevations=None, station_lonlat=None, topo=None, epsg=None, utm_zone=None, latlon=False, on_mismatch='raise', history=None, provenance=None, survey=None, source_backend='ai', created_by='', crs=None, description='', metadata=None)

Build a grid3d PCSFModel from a bare AI/DL prediction.

The natural fit for a volumetric model (a 3-D CNN/ResNet-style architecture predicting a full tensor volume): the resulting file is the same artifact pycsamt.format.adapters.modem3d.modem3d_to_pcsf() produces for a real ModEM 3-D run.

Parameters:
  • resistivity (array-like, shape (n_z, n_y, n_x)) – The model’s predicted resistivity (see resistivity_shape for this axis order – ModEM’s own native convention).

  • x (array-like) – Cell-centre coordinates (metres).

  • y (array-like) – Cell-centre coordinates (metres).

  • z (array-like) – Cell-centre coordinates (metres).

  • encoding ({"linear", "log10", "ln"}, default "linear") – See grid2d_to_pcsf()’s identical parameter.

  • x_nodes (Any) – Forwarded to Grid3DGeometry. origin/rotation_deg are this geometry’s “offset” – real-world placement and bearing of an otherwise locally-referenced volume.

  • y_nodes (Any) – Forwarded to Grid3DGeometry. origin/rotation_deg are this geometry’s “offset” – real-world placement and bearing of an otherwise locally-referenced volume.

  • z_nodes (Any) – Forwarded to Grid3DGeometry. origin/rotation_deg are this geometry’s “offset” – real-world placement and bearing of an otherwise locally-referenced volume.

  • origin (Any) – Forwarded to Grid3DGeometry. origin/rotation_deg are this geometry’s “offset” – real-world placement and bearing of an otherwise locally-referenced volume.

  • rotation_deg (float) – Forwarded to Grid3DGeometry. origin/rotation_deg are this geometry’s “offset” – real-world placement and bearing of an otherwise locally-referenced volume.

  • n_air (int) – Forwarded to Grid3DGeometry. origin/rotation_deg are this geometry’s “offset” – real-world placement and bearing of an otherwise locally-referenced volume.

  • uncertainty (Any)

  • sensitivity (Any)

  • stations (StationTable | None)

  • topography (TopographyPerStation | TopographyRaster | None)

  • station_names (Sequence[str] | None)

  • station_x (Sequence[float] | None)

  • station_y (Sequence[float] | None)

  • station_z (Sequence[float] | None)

  • station_elevations (Mapping[str, float] | None)

  • station_lonlat (Mapping[str, tuple[float, float]] | None)

  • topo (Any)

  • epsg (int | None)

  • utm_zone (Any | None)

  • latlon (bool)

  • on_mismatch (str)

  • history (Mapping[str, Any] | None)

  • provenance (ModelProvenance | Mapping[str, Any] | None)

  • survey (Any | Mapping[str, Any] | None)

  • source_backend (str)

  • created_by (str)

  • crs (str | None)

  • description (str)

  • metadata (Mapping[str, Any] | None)

Return type:

PCSFModel

:param : :param station_x: :param station_y: :param station_z: :param station_elevations: :param station_lonlat: :param : :param topo: :param epsg: :param utm_zone: :param latlon: :param on_mismatch: :param history: :param provenance: :param survey: :param : :param source_backend: Same meaning as grid2d_to_pcsf()’s identical parameters

(station_y/station_z additionally accepted here, matching a native 3-D station table).

Parameters:
  • created_by (str) – Same meaning as grid2d_to_pcsf()’s identical parameters (station_y/station_z additionally accepted here, matching a native 3-D station table).

  • crs (str | None) – Same meaning as grid2d_to_pcsf()’s identical parameters (station_y/station_z additionally accepted here, matching a native 3-D station table).

  • description (str) – Same meaning as grid2d_to_pcsf()’s identical parameters (station_y/station_z additionally accepted here, matching a native 3-D station table).

  • metadata (Mapping[str, Any] | None) – Same meaning as grid2d_to_pcsf()’s identical parameters (station_y/station_z additionally accepted here, matching a native 3-D station table).

  • resistivity (Any)

  • x (Any)

  • y (Any)

  • z (Any)

  • encoding (str)

  • x_nodes (Any)

  • y_nodes (Any)

  • z_nodes (Any)

  • origin (Any)

  • rotation_deg (float)

  • n_air (int)

  • uncertainty (Any)

  • sensitivity (Any)

  • stations (StationTable | None)

  • topography (TopographyPerStation | TopographyRaster | None)

  • station_names (Sequence[str] | None)

  • station_x (Sequence[float] | None)

  • station_y (Sequence[float] | None)

  • station_z (Sequence[float] | None)

  • station_elevations (Mapping[str, float] | None)

  • station_lonlat (Mapping[str, tuple[float, float]] | None)

  • topo (Any)

  • epsg (int | None)

  • utm_zone (Any | None)

  • latlon (bool)

  • on_mismatch (str)

  • history (Mapping[str, Any] | None)

  • provenance (ModelProvenance | Mapping[str, Any] | None)

  • survey (Any | Mapping[str, Any] | None)

  • source_backend (str)

Return type:

PCSFModel

Examples

>>> import numpy as np
>>> from pycsamt.format.adapters.generic import grid3d_to_pcsf
>>> model = grid3d_to_pcsf(
...     resistivity=np.full((2, 2, 2), 100.0),
...     x=np.array([0.0, 100.0]), y=np.array([0.0, 100.0]),
...     z=np.array([10.0, 50.0]), source_backend="resnet",
... )
>>> model.kind
'grid3d'
pycsamt.format.adapters.mesh_to_pcsf(nodes, connectivity, *, region_ids=None, resistivity=None, resistivity_by_node=None, resistivity_by_region=None, encoding='linear', plane='xz', uncertainty=None, sensitivity=None, stations=None, topography=None, station_names=None, station_x=None, station_y=None, station_z=None, station_elevations=None, station_lonlat=None, topo=None, epsg=None, utm_zone=None, latlon=False, on_mismatch='raise', history=None, provenance=None, survey=None, source_backend='ai', created_by='', crs=None, description='', metadata=None)

Build a mesh_unstructured PCSFModel from a bare AI/DL prediction on a triangular mesh.

The natural fit for a graph-based model (a GCN predicting one value per mesh vertex/graph node), but also works for any model that already predicts per-triangle or per-region values on a mesh it did not itself generate (e.g. a caller-supplied mesh from pycsamt.models.mare2dem.tri_mesh.tri_mesh_from_poly()).

Parameters:
  • nodes (array-like, shape (n, 2) or (n, 3)) – Mesh node coordinates, metres.

  • connectivity (array-like, shape (m, 3), int) – Triangle node indices.

  • region_ids (array-like, shape (m,), int, optional) – Per-triangle region id. Defaults to all-zeros (a single, generic region – “no region structure”) when omitted.

  • resistivity (array-like, optional) – At least one is required. resistivity is per-triangle/per-cell (shape (m,)); resistivity_by_node is per-vertex (shape (n,), the natural GCN output); resistivity_by_region is a compact per-region table (shape (n_regions,)). Precedence when more than one is given: resistivity > resistivity_by_node > resistivity_by_region – the first present is treated as the canonical source (encoding applies to it), and the canonical per-triangle resistivity is derived from it: taken as-is, or averaged from its 3 vertex values per triangle (documented arithmetic mean, see _node_values_to_triangles()), or expanded via 0-based region_ids (see _expand_region_resistivity()). Any of the other two tables also given alongside the canonical source is stored as-is, assumed already linear ohm.m.

  • resistivity_by_node (array-like, optional) – At least one is required. resistivity is per-triangle/per-cell (shape (m,)); resistivity_by_node is per-vertex (shape (n,), the natural GCN output); resistivity_by_region is a compact per-region table (shape (n_regions,)). Precedence when more than one is given: resistivity > resistivity_by_node > resistivity_by_region – the first present is treated as the canonical source (encoding applies to it), and the canonical per-triangle resistivity is derived from it: taken as-is, or averaged from its 3 vertex values per triangle (documented arithmetic mean, see _node_values_to_triangles()), or expanded via 0-based region_ids (see _expand_region_resistivity()). Any of the other two tables also given alongside the canonical source is stored as-is, assumed already linear ohm.m.

  • resistivity_by_region (array-like, optional) – At least one is required. resistivity is per-triangle/per-cell (shape (m,)); resistivity_by_node is per-vertex (shape (n,), the natural GCN output); resistivity_by_region is a compact per-region table (shape (n_regions,)). Precedence when more than one is given: resistivity > resistivity_by_node > resistivity_by_region – the first present is treated as the canonical source (encoding applies to it), and the canonical per-triangle resistivity is derived from it: taken as-is, or averaged from its 3 vertex values per triangle (documented arithmetic mean, see _node_values_to_triangles()), or expanded via 0-based region_ids (see _expand_region_resistivity()). Any of the other two tables also given alongside the canonical source is stored as-is, assumed already linear ohm.m.

  • encoding ({"linear", "log10", "ln"}, default "linear") – Encoding of whichever of the three resistivity arrays above is the canonical source (see precedence above).

  • plane ({"xz", "xy", "3d"}, default "xz") – Forwarded to UnstructuredMeshGeometry.

  • uncertainty (array-like, optional) – Same shape as the canonical per-triangle resistivity.

  • sensitivity (array-like, optional) – Same shape as the canonical per-triangle resistivity.

  • stations (StationTable | None)

  • topography (TopographyPerStation | TopographyRaster | None)

  • station_names (Sequence[str] | None)

  • station_x (Sequence[float] | None)

  • station_y (Sequence[float] | None)

  • station_z (Sequence[float] | None)

  • station_elevations (Mapping[str, float] | None)

  • station_lonlat (Mapping[str, tuple[float, float]] | None)

  • topo (Any)

  • epsg (int | None)

  • utm_zone (Any | None)

  • latlon (bool)

  • on_mismatch (str)

  • history (Mapping[str, Any] | None)

  • provenance (ModelProvenance | Mapping[str, Any] | None)

  • survey (Any | Mapping[str, Any] | None)

  • source_backend (str)

  • created_by (str)

  • crs (str | None)

  • description (str)

  • metadata (Mapping[str, Any] | None)

Return type:

PCSFModel

:param : :param station_elevations: :param station_lonlat: :param topo: :param epsg: :param utm_zone: :param latlon: :param : :param on_mismatch: :param history: :param provenance: :param survey: :param source_backend: :param created_by: :param : :param crs: Same meaning as grid3d_to_pcsf()’s identical parameters. A

mesh’s own node coordinates already carry real position – these are for naming/geo-referencing discrete receivers distinct from the mesh nodes (mirrors pycsamt.format.adapters.mare2dem.mare2dem_to_pcsf()’s own caller-supplied stations).

Parameters:
  • description (str) – Same meaning as grid3d_to_pcsf()’s identical parameters. A mesh’s own node coordinates already carry real position – these are for naming/geo-referencing discrete receivers distinct from the mesh nodes (mirrors pycsamt.format.adapters.mare2dem.mare2dem_to_pcsf()’s own caller-supplied stations).

  • metadata (Mapping[str, Any] | None) – Same meaning as grid3d_to_pcsf()’s identical parameters. A mesh’s own node coordinates already carry real position – these are for naming/geo-referencing discrete receivers distinct from the mesh nodes (mirrors pycsamt.format.adapters.mare2dem.mare2dem_to_pcsf()’s own caller-supplied stations).

  • nodes (Any)

  • connectivity (Any)

  • region_ids (Any)

  • resistivity (Any)

  • resistivity_by_node (Any)

  • resistivity_by_region (Any)

  • encoding (str)

  • plane (str)

  • uncertainty (Any)

  • sensitivity (Any)

  • stations (StationTable | None)

  • topography (TopographyPerStation | TopographyRaster | None)

  • station_names (Sequence[str] | None)

  • station_x (Sequence[float] | None)

  • station_y (Sequence[float] | None)

  • station_z (Sequence[float] | None)

  • station_elevations (Mapping[str, float] | None)

  • station_lonlat (Mapping[str, tuple[float, float]] | None)

  • topo (Any)

  • epsg (int | None)

  • utm_zone (Any | None)

  • latlon (bool)

  • on_mismatch (str)

  • history (Mapping[str, Any] | None)

  • provenance (ModelProvenance | Mapping[str, Any] | None)

  • survey (Any | Mapping[str, Any] | None)

  • source_backend (str)

  • created_by (str)

  • crs (str | None)

Return type:

PCSFModel

Raises:

ValueError – If none of resistivity/resistivity_by_node/resistivity_by_region is given, or region_ids falls outside the resistivity-by-region table’s range.

Examples

>>> import numpy as np
>>> from pycsamt.format.adapters.generic import mesh_to_pcsf
>>> nodes = np.array([[0., 0.], [1., 0.], [0., 1.], [1., 1.]])
>>> connectivity = np.array([[0, 1, 2], [1, 3, 2]])
>>> node_values = np.array([1.0, 2.0, 3.0, 4.0])  # log10, one per node
>>> model = mesh_to_pcsf(
...     nodes, connectivity, resistivity_by_node=node_values,
...     encoding="log10", source_backend="gcn",
... )
>>> model.kind
'mesh_unstructured'