The pycsamt.inversion package provides a backend-neutral interface
for EM inversion. It includes runnable built-in layered-earth inversions
for MT/AMT/CSAMT and TDEM soundings, stitched station-by-station 2-D
sections, and adapter backends for existing Occam2D and ModEM workflows.
SimPEG and pyGIMLi are registered lazily for optional numerical backends.
EMData is the backend-neutral observation object used by
pycsamt.inversion. It keeps natural-source and time-domain EM data in one
small shape contract so built-in, optional, and external backends can share the
same input API.
Frequency-domain rho_a and phase arrays may be one-dimensional for a
single station or two-dimensional with shape (n_stations,n_frequencies).
TDEM values arrays may be one-dimensional for a single sounding or
two-dimensional with shape (n_soundings,n_times). Station metadata, when
provided, must match the first dimension of these arrays.
param method:
Survey method represented by the observations. The value is normalized to
lower case. Natural-source methods require frequency-domain responses;
"tdem" requires time-gate decay values.
Frequency samples in hertz for MT, AMT, CSAMT, and EMAP responses. Values
must be strictly positive. The aliases freqs, freq, frequency,
and period arrays via periods are accepted by coercion helpers.
type frequencies:
array-like of float, optional
param times:
Time-gate samples in seconds for TDEM data. Values must be strictly
positive. Sounding objects may expose these as time_gates, times,
or time.
type times:
array-like of float, optional
param rho_a:
Apparent resistivity in ohm metres. One-dimensional arrays represent one
station. Two-dimensional arrays represent (n_stations,n_samples); if a
response object provides (n_samples,n_stations), coercion transposes it
when the frequency count makes the orientation unambiguous. Common aliases
include rhoa, app_res, and apparent_resistivity.
type rho_a:
array-like of float, optional
param phase:
Impedance phase in degrees, using the same shape convention as rho_a.
The alias phi is accepted by object coercion.
type phase:
array-like of float, optional
param values:
Generic observed values. This is primarily used for TDEM decay data such as
dBz_dt/dbdt arrays. One-dimensional arrays represent one sounding;
two-dimensional arrays represent (n_soundings,n_times).
type values:
array-like of float, optional
param errors:
Absolute observation uncertainties with the same sample axis as the
corresponding data. If omitted, backends derive errors from
InversionConfig error floors and component-specific
ErrorModel settings.
type errors:
array-like of float, optional
param station_names:
Station or sounding labels. The length must match the number of station
rows in the data. Mapping aliases include stations; response-object
aliases include station_names, stations, site_names, and
names.
type station_names:
sequence of str, optional
param station_x:
Profile-coordinate positions in metres. The length must match the number
of station rows. Object coercion also checks aliases such as x,
x_stations, easting, longitude, and lon.
type station_x:
array-like of float, optional
param source:
Original data object, collection, survey, or path retained for provenance
and backend adapters. It is not modified by EMData.
type source:
object, optional
param metadata:
Free-form provenance metadata. Object readers copy metadata or meta
dictionaries when available and add a reader tag describing the coercion
path.
type metadata:
dict, optional
Notes
Use EMData.coerce() at API boundaries. It accepts dictionaries,
response-like objects, station collections, TDEM sounding collections, and TDEM
survey objects exposing to_soundings(). The original input object is kept in
source for provenance and backend-specific adapters.
data (mapping) – Mapping with observation fields. Keys may include method,
freqs/frequencies, periods, rho_a, phase,
times, values, errors, stations/station_names,
station_x, and metadata.
**overrides – Field values that override keys read from data. This is useful
when a caller wants to force method or attach metadata while
preserving the original observation mapping.
data (EMData, mapping, response object, sounding object, survey object, or sequence) – Input converted to EMData. Supported objects include
natural-source response objects with frequency and rho/phase
attributes; station collections of such objects; TDEM sounding
objects exposing time gates and decay values; and survey objects
exposing to_soundings().
method (str, default "mt") – Fallback method used when data does not declare its own method.
TDEM sounding/survey inputs are automatically promoted to
"tdem".
Returns:
Existing EMData instances are returned unchanged. Recognized
objects are parsed into normalized arrays. Unrecognized non-null
inputs are retained as source on an otherwise empty container so
backend adapters can still inspect them.
ValueError – If station collections have incompatible frequency counts, TDEM
soundings have incompatible time gates, or normalized arrays fail
validation.
Component-aware data-error settings for inversion backends.
ErrorModel centralizes the floors used when packing objective functions for
the built-in, SimPEG, pyGIMLi, Occam2D, and ModEM adapters. It supports
component-specific relative/absolute floors and boolean masks used to exclude
stations, frequencies, time gates, or individual samples.
min_error (float, default 1e-12) – Global lower bound applied to all returned errors.
masks (dict, optional) – Component or station masks. Supported keys include component names such as
"rho", "phase", "tdem", and station-level keys
"station"/"station_mask".
Notes
Configuration helpers read overrides from backend_options and nested
backend_options["error_model"] dictionaries. Explicit observed-data errors
can still be passed to errors() or component_errors().
values (array-like) – Observed or predicted values used to scale relative error floors.
component (str) – Component name. Common aliases include "rho", "rho_a",
"phase", "tdem", "dbdt", and "impedance".
explicit (array-like, optional) – Explicit absolute errors. When provided, component floor settings
are bypassed except for the global min_error lower bound.
relative (bool, default False) – If True, return relative errors by dividing absolute errors by
abs(values) with min_error protection.
InversionHistory stores backend-neutral iteration diagnostics. Built-in
solvers record fields such as iteration, phi_d, phi_m,
objective, rms, regularization weight, and model norm. Optional or
external backends can map native logs into the same record structure.
Parameters:
records (list of dict, optional) – One dictionary per iteration or residual evaluation. Numeric fields can be
converted to arrays with arrays().
metadata (dict, optional) – Free-form provenance metadata such as backend mode or station index.
method ({"mt", "amt", "csamt", "emap", "tdem"}, default "mt") – Electromagnetic method to invert. Natural-source methods use frequency,
apparent-resistivity, and phase observations. TDEM uses time-gate decay
observations. The value is normalized to lower case and is used with
dimension to select the backend execution path.
dimension ({"1d", "2d", "3d"}, default "1d") – Inversion dimensionality. One-dimensional runs recover layered-earth
models. Two-dimensional runs produce section models either by stitched
station inversions or by the built-in finite-difference profile mode.
Three-dimensional execution is delegated to optional or external engines.
backend ({"builtin", "simpeg", "pygimli", "occam2d", "modem"}, default "builtin") – Inversion engine. "builtin" is dependency-light and runnable for
local smoke studies. "simpeg" and "pygimli" are optional physics
engines imported only when selected. "occam2d" and "modem" prepare,
validate, and optionally run external workflows.
data (mapping, object, sequence, or path-like, optional) – Observed EM data. Mappings can contain freqs/frequencies,
rho_a/phase, or times/values for TDEM. Station collections,
response-like objects, and survey objects exposing to_soundings() are
coerced through pycsamt.inversion.EMData.
workdir (path-like, default "pycsamt_inversion") – Directory used for backend files, logs, and prepared external-run inputs.
Local backends store provenance here when they create products. External
adapters resolve runner files relative to this folder.
n_layers (int, default 4) – Number of layered-earth cells for 1-D style parameterizations, including
the final halfspace. Built-in 1-D and stitched 2-D workflows use this value
unless a supplied starting model defines its own layer count.
starting_model (StartingModel, mapping, or object, optional) – Initial layered model. Resistivities are linear ohm-m values and
thicknesses are metres. Mappings may use singular or plural keys such as
resistivity/resistivities and thickness/thicknesses.
reference_model (StartingModel, mapping, or object, optional) – Model used as the reference for damped or smooth regularization when the
selected backend supports it. If omitted, solvers regularize against their
starting model or backend-native default.
error_floor (float, default 0.05) – Relative error floor for amplitude-like components when explicit errors
are unavailable. A value of 0.05 means five percent. More detailed
rho, phase, impedance, TDEM, and station-mask rules can be supplied through
backend_options["error_model"].
include_phase (bool, default True) – Whether built-in natural-source objectives include phase observations in
addition to apparent resistivity.
phase_error (float, default 3.0) – Absolute phase uncertainty in degrees used by MT/AMT/CSAMT objectives when
phase errors are unavailable.
regularization ({"none", "smooth", "damped", "blocky"}, default "smooth") – Regularization family used by runnable backends. Shared helpers map this
vocabulary to built-in residual penalties, pyGIMLi lam values, and
SimPEG weighted least-squares settings where possible.
max_iter (int, default 80) – Maximum local optimizer iterations or backend iteration request. External
adapters may write this value into native control files or record it as
lifecycle metadata depending on the backend.
tol (float, default 1e-5) – Local optimizer termination tolerance used by runnable backends.
bounds (dict, optional) – Optional parameter bounds. Built-in layered inversions understand
log10_rho and log10_thickness bounds. Other engines may interpret
backend-specific bound keys through backend_options.
run_external (bool, default False) – Whether external adapters are allowed to launch compiled executables.
When False, Occam2D and ModEM prepare and validate inputs, assemble
commands, and return a ready/prepared result without running the binary.
backend_options (dict, optional) – Backend-specific options. Common entries include mesh controls, component
selection, profile_mode, error-model overrides, SimPEG/pyGIMLi knobs,
and external runner file names or executable settings. Unknown keys are
passed through to the selected backend.
InversionMesh is the common mesh metadata object carried by
pycsamt.inversion.results.InversionResult. Numerical engines may
keep their real discretization object in native while exposing common
profile/depth centers through x_centers and z_centers.
Parameters:
dimension ({"1d", "2d", "3d"}, default "1d") – Mesh dimensionality represented by this descriptor.
x_centers (array-like of float, optional) – Horizontal/profile cell centers in metres. For 1-D meshes this is
usually [0.0].
z_centers (array-like of float, optional) – Depth cell centers in metres, positive downward.
native (object, optional) – Backend-native mesh/grid object, for example a SimPEG TensorMesh or
built-in forward Grid2D.
metadata (dict, optional) – Free-form mesh provenance such as builder name, backend engine, padding,
or core-cell shape.
InversionResult is the common result object returned by every inversion
backend. It stores recovered models, predicted responses, misfit diagnostics,
uncertainty, convergence history, generated files, backend-native objects, and
free-form metadata while exposing conversion hooks for plotting, exporting, and
hydrogeophysical interpretation.
Parameters:
method (str) – EM method label such as "mt", "amt", "csamt", "emap", or
"tdem".
2-D result arrays are passed through directly. A recovered 1-D
layered model is expanded to one column so the interpretation API can
consume it uniformly.
Returns:
Unified 2-D log10 resistivity model with profile and depth
coordinates.
Backend-neutral uncertainty and sensitivity diagnostics.
InversionUncertainty stores uncertainty products in a common shape for
exports, plots, and interpretation. Built-in solvers currently provide proxy
diagnostics from least-squares Jacobians; optional engines may attach richer
posterior or sensitivity products over time.
config (InversionConfig or dict, optional) – Complete inversion configuration. Dictionaries are converted to
pycsamt.inversion.config.InversionConfig. Keyword arguments
override matching configuration fields. If omitted, keyword arguments are
used to build a default configuration.
**kw – Configuration fields that override values supplied by config. Common
keys include method, dimension, backend, data,
starting_model, max_iter, regularization, and
backend_options.
Returns:
result – Backend-neutral inversion output. It stores the recovered model, mesh,
predicted response, RMS/objective values, files, warnings, native backend
objects, uncertainty diagnostics, convergence history, and metadata.
The workflow does not mutate caller-provided data. A per-call data override can
be supplied to run(), which is convenient for applying the same
configuration to multiple soundings or profiles.
data (mapping, object, sequence, or path-like, optional) – Optional data override for this call. When omitted, config.data
is used. Accepted values are backend-dependent but normally pass
through pycsamt.inversion.data.EMData.coerce.
Returns:
Backend-neutral result containing recovered model, RMS/objective
diagnostics, files, warnings, uncertainty, history, and native
backend objects when available.
Regularization stores the model-structure penalty vocabulary shared by
built-in, SimPEG, and pyGIMLi inversion paths. The residual helpers operate on
model-parameter arrays, usually log-domain resistivity values, and return
unweighted structure residuals that can be multiplied by a global scalar such
as \(\sqrt{\lambda}\).
For a smooth model \(m\), the penalty contains finite differences such as
For damped/reference regularization, a smallness term
\(\alpha_s\|m-m_{ref}\|_2^2\) is added. For "blocky" models, the
finite differences are normalized by
\(\sqrt{(\Delta m)^2 + \epsilon^2}\) to reduce sensitivity to sharp
edges.
Parameters:
kind ({"none", "smooth", "damped", "blocky"}, default "smooth") – Regularization family. "none" disables the penalty, "smooth"
penalizes model roughness, "damped" combines smallness/reference and
roughness terms, and "blocky" applies an edge-preserving normalized
gradient penalty.
alpha_s (float, default 1.0) – Smallness or reference-model weight. This controls residual terms of the
form \(m - m_{ref}\) when damping/reference regularization is active.
alpha_x (float, default 1.0) – Lateral roughness weight applied along the profile or X axis.
alpha_z (float, default 1.0) – Vertical roughness weight applied along the depth or Z axis.
reference_weight (float, default 0.0) – Extra multiplier for the reference-model term. When a reference model is
provided, values below one are promoted to one for damped/smallness terms.
metadata (dict, optional) – Free-form provenance metadata attached to the regularization settings.
Notes
This class stores relative penalty settings only. The scalar objective weight
is read separately by regularization_weight(), while pyGIMLi-specific
lambda handling is read by pygimli_lambda().
Examples
Build a smoothness penalty for a 2-D log-resistivity model:
Resistivities are linear ohm-m values. The final layer is a halfspace, so
len(thicknesses) must equal len(resistivities)-1.
ReferenceModel is currently an alias of StartingModel. Use it when the
same layer container is being supplied as a regularization reference rather than
as an optimizer starting point.
Parameters:
resistivities (array-like of float) – Layer resistivities in ohm metres. Values must be strictly positive. The
last value represents the bottom halfspace.
thicknesses (array-like of float) – Layer thicknesses in metres. Values must be strictly positive and the array
length must be len(resistivities)-1 because the final layer is a
halfspace.
name (str, optional) – Human-readable model label recorded with the object and passed to forward
model adapters where supported.
metadata (dict, optional) – Free-form provenance metadata attached to the model.
Notes
The model is deliberately small and backend-neutral. Built-in solvers optimize
log10(resistivity) and log10(thickness) internally, but this public
container stores physical linear values in ohm metres and metres.
Examples
Build a three-layer model with a conductive target over a resistive basement:
data (mapping) – Model mapping. Accepted keys are resistivity or
resistivities for layer resistivity, thickness or
thicknesses for layer thickness, plus optional name and
metadata.
value (StartingModel, mapping, object, or None) – Input model. Existing StartingModel instances are returned
unchanged. Mappings are read by from_dict(). Generic objects
may expose resistivity/resistivities and
thickness/thicknesses attributes.
n_layers (int, default 4) – Number of layers used only when value is None and a default
model must be created.
ValueError – If resistivities or thicknesses are not 1-D, if fewer than two
resistivity layers are supplied, if thickness count does not equal
len(resistivities)-1, or if any value is non-positive.
Build a 1-D TensorMesh-like object and positive-downward centres.
This helper centralizes the depth discretization used by optional engines
such as SimPEG. The caller supplies the actual TensorMesh class so this
module stays free of optional dependencies.
Parameters:
start (object) – Starting model exposing n_layers, resistivities, and
thicknesses.
options (dict, optional) – Mesh controls. Recognized keys include n_cells, depth_max,
origin, min_cell_size, and growth_factor.
Build a 3-D TensorMesh-like object around station coordinates.
The helper constructs uniform horizontal cells around the station footprint
and geometrically growing depth cells. It is used by optional 3-D physics
paths while keeping the native mesh class injectable.
Parameters:
station_x (array-like of float) – Station coordinates in metres.
station_y (array-like of float) – Station coordinates in metres.
options (dict, optional) – Mesh controls. Recognized keys include x_pad, y_pad,
depth_max, nx, ny, nz, min_cell_size, and
growth_factor.
centers (dict of ndarray) – Cell-center arrays with keys "x", "y", "z", and
"z_depth". z follows the native mesh coordinate with depth
negative; z_depth is positive downward.
Build the finite-difference 2-D grid used by built-in inversion.
This builder creates the starting Grid2D-like object for the built-in
finite-difference MT/AMT/CSAMT profile inversion. It shifts station
coordinates into the grid coordinate system, adds optional lateral/depth
padding, and expands the layered starting model into a 2-D resistivity
array.
Parameters:
start (object) – Starting model exposing resistivities and thicknesses.
station_x (array-like of float) – Station positions along profile in metres. At least two distinct
stations are required.
options (dict, optional) – Grid controls. Recognized keys include nx/fd2d_nx,
n_pad/fd2d_n_pad, pad_factor, x_margin, x_max, and
halfspace_thickness.
options (dict, optional) – Mesh options. Recognized keys are min_cell_size and
growth_factor. Defaults are chosen conservatively from
depth_max and n_cells.
Returns:
Positive cell widths in metres.
Return type:
ndarray
Raises:
ValueError – If depth_max, n_cells, min_cell_size, or growth_factor
are not positive.
Build an ErrorModel from inversion config options.
Parameters:
cfg (object) – Inversion config-like object exposing error_floor, phase_error,
and optional backend_options. Overrides may be placed directly in
backend_options or inside backend_options["error_model"].
Return unweighted residual terms for smooth/damped/blocky penalties.
values are normally log-domain model parameters. The returned vector
already contains the square-root alpha factors; callers can multiply by
a global scalar such as sqrt(regularization_weight).
Parameters:
values (array-like) – Model parameter array. One-dimensional arrays are treated as depth
profiles. Two-dimensional arrays are treated as (z,x) sections.
reference (array-like, optional) – Reference model with the same shape as values or broadcastable to
that shape.
regularization (Regularization, optional) – Regularization settings. If omitted, Regularization() is used.
blocky_eps (float, default 1e-2) – Stabilization value in the blocky normalized-gradient penalty.
axes (tuple of {"x", "z"}, optional) – Axes on which to compute roughness. Defaults to ("z",) for 1-D
arrays and ("x","z") for 2-D or higher arrays.
Returns:
Concatenated residual vector. Empty when kind="none" or all active
penalty terms have zero weight.
This convenience function is equivalent to
InversionWorkflow(config,**kw).run(). It is useful in scripts,
notebooks, tests, and demos where the workflow object does not need to be
reused.