pycsamt.format.adapters.occam2d#

Occam2D -> PCSF adapter (Phase 2 of the PCSF format plan).

Converts a completed pycsamt.models.occam2d.results.InversionResult into a backend-neutral PCSFModel with a grid2d geometry. Built directly on pycsamt.interp._base.ResistivityModel.from_occam2d(), which already recovers real station chainage from Occam2D’s mesh-local coordinate frame (see that method’s docstring for the padding-symmetry argument) — this module reuses that correction rather than re-deriving it, and only adds the cell-edge (node) coordinates and history/station bookkeeping PCSF needs on top.

DUHI (pycsamt.ai.inversion) has no separate adapter: its output only becomes a real, final resistivity model once folded back into an Occam2D run (see mapping2d.map_ai_grid_to_occam), so a DUHI-produced InversionResult converts through this same function.

Functions

occam2d_to_pcsf(result, *[, ...])

Convert an Occam2D InversionResult to a PCSFModel.

pycsamt.format.adapters.occam2d.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='')[source]

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")