pycsamt.format.adapters.generic#
Generic array-based -> PCSF adapter, for any AI/DL inversion result.
Every other module in pycsamt.format.adapters converts a specific
solver’s own in-memory result object (Occam2D’s InversionResult, ModEM’s
ModEmModel3D, MARE2DEM’s TriMesh). This module needs none of that:
it builds a PCSFModel straight from plain
numpy arrays, so a UNet, a GCN, a ResNet, or any third-party AI/DL
inversion tool – with zero dependency on pycsamt’s own
pycsamt.ai subpackage – can publish its result as a citable,
reproducible .pcsf/.pcsm file others can reload and check.
Three functions, one per non-multiline geometry kind:
grid2d_to_pcsf()– a regular 2-D section (e.g. a UNet slice).grid3d_to_pcsf()– a regular 3-D volume (e.g. a 3-D CNN/ResNet).mesh_to_pcsf()– a triangular mesh, per-node or per-cell (e.g. a GCN predicting one value per graph vertex).
An AI model producing several 2-D lines with real cross-strike offsets
already has a home: pycsamt.format.multiline.build_multiline_pcsf(),
whose source_backend is already free text – no changes needed there.
All three functions share the same trailing keyword surface as the
solver-specific adapters (station identity/position, elevation/topography
via the same smart topo= resolver, an origin/rotation “offset” for
placing the result in real-world space, uncertainty/sensitivity, iteration
history, and free-form survey/model metadata), so an AI-produced file gets
the same spatial richness a real solver’s file gets – see
pycsamt.format.provenance for the accompanying ML-provenance
convention (architecture/framework/checkpoint/hyperparameters).
Functions
|
Build a |
|
Build a |
|
Build a |
- pycsamt.format.adapters.generic.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)[source]
Build a
grid2dPCSFModelfrom 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 samepycsamt.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 asresistivity_nativeand the canonical linearresistivityis 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_*/topoparameter 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 nostation_elevations/topocombination 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 smarttopo=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 smarttopo=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 smarttopo=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 smarttopo=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 smarttopo=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 smarttopo=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 smarttopo=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"]– seepycsamt.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:
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.generic.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)[source]
Build a
grid3dPCSFModelfrom 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_shapefor 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)
topo (Any)
epsg (int | None)
utm_zone (Any | None)
latlon (bool)
on_mismatch (str)
provenance (ModelProvenance | Mapping[str, Any] | None)
source_backend (str)
created_by (str)
crs (str | None)
description (str)
- Return type:
: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_zadditionally 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_zadditionally accepted here, matching a native 3-D station table).crs (str | None) – Same meaning as
grid2d_to_pcsf()’s identical parameters (station_y/station_zadditionally accepted here, matching a native 3-D station table).description (str) – Same meaning as
grid2d_to_pcsf()’s identical parameters (station_y/station_zadditionally 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_zadditionally 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)
topo (Any)
epsg (int | None)
utm_zone (Any | None)
latlon (bool)
on_mismatch (str)
provenance (ModelProvenance | Mapping[str, Any] | None)
source_backend (str)
- Return type:
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.generic.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)[source]
Build a
mesh_unstructuredPCSFModelfrom 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-triangleresistivityis 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-triangleresistivityis 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-triangleresistivityis 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)
topo (Any)
epsg (int | None)
utm_zone (Any | None)
latlon (bool)
on_mismatch (str)
provenance (ModelProvenance | Mapping[str, Any] | None)
source_backend (str)
created_by (str)
crs (str | None)
description (str)
- Return type:
: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. Amesh’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-suppliedstations).- 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 (mirrorspycsamt.format.adapters.mare2dem.mare2dem_to_pcsf()’s own caller-suppliedstations).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 (mirrorspycsamt.format.adapters.mare2dem.mare2dem_to_pcsf()’s own caller-suppliedstations).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)
topo (Any)
epsg (int | None)
utm_zone (Any | None)
latlon (bool)
on_mismatch (str)
provenance (ModelProvenance | Mapping[str, Any] | None)
source_backend (str)
created_by (str)
crs (str | None)
- Return type:
- 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'