2.25.3.1. pycsamt.ai.inversion#
Supervised, physics-informed (PINN), and hybrid neural-network inverters for 1-D/2-D/3-D EM inversion, plus uncertainty calibration, static-shift/skew reliability weighting for the DUHI hybrid AI-physics pathway, and experiment/run configuration.
pycsamt.ai.inversion#
High-level AI-based EM inversion workflows.
- class pycsamt.ai.inversion.InversionConfig(arch='resnet', n_layers=5, solver='mt1d', device=None, include_phase=True, log_thickness=True, augment_noise=0.02, epochs=100, batch_size=256, lr=0.001, weight_decay=1e-05, patience=20, min_delta=1e-05, val_frac=0.1, grad_clip=1.0, seed=None, checkpoint_dir='checkpoints', checkpoint_name='em_inverter', save_best=True, verbose=True)#
Bases:
objectCollect settings that define a 1-D AI-based EM inversion run.
InversionConfigis the configuration object forEMInverter1D. It covers four concern areas: network architecture, training hyperparameters, regularisation, and checkpoint management.The recommended workflow:
Generate a template with
write_template().Edit the values in the generated file.
Load the edited file with
from_file().Optionally call
validate()to catch range errors.Call
to_inverter()to instantiate a ready-to-fitEMInverter1D.Pass
to_fit_kwargs()toinv.fit(dataset, **cfg.to_fit_kwargs()).
- Parameters:
arch ({'resnet', 'cnn1d', 'fcn'}) – Network architecture.
n_layers (int) – Number of earth layers (including halfspace).
solver ({'mt1d', 'csamt1d', 'tem1d'}) – Forward solver this inverter targets.
device (str or None) – Compute device;
Noneauto-detects (CUDA > MPS > CPU).include_phase (bool) – Include impedance phase in the input feature vector.
log_thickness (bool) – Apply log10 to thickness targets during training.
augment_noise (float) – On-the-fly per-epoch noise augmentation level.
epochs (int) – Maximum training epochs.
batch_size (int) – Mini-batch size.
lr (float) – Initial Adam learning rate.
weight_decay (float) – Adam L2 regularisation coefficient.
patience (int) – Early-stopping patience (epochs without improvement).
min_delta (float) – Minimum validation-loss decrease to count as an improvement.
val_frac (float) – Fraction of data used for validation.
grad_clip (float or None) – Gradient-norm clipping threshold;
Nonedisables clipping.seed (int or None) – Random seed for train/val split.
checkpoint_dir (str or None) – Directory for checkpoint files;
Nonedisables auto-saving.checkpoint_name (str) – Base file name for checkpoints (without extension).
save_best (bool) – Auto-save the best checkpoint after training.
verbose (bool) – Print training progress.
Examples
Default configuration (ResNet, 5 layers, MT1D):
>>> cfg = InversionConfig() >>> cfg.arch 'resnet'
Deep ResNet for a crystalline-crust survey:
>>> cfg = InversionConfig( ... arch="resnet", ... n_layers=6, ... solver="mt1d", ... epochs=300, ... lr=5e-4, ... seed=0, ... )
Round-trip template:
>>> path = InversionConfig.write_template("inv_config.yml") >>> cfg = InversionConfig.from_file(path) >>> cfg.solver 'mt1d'
Snapshot a fitted inverter:
>>> cfg = InversionConfig.from_inverter(inv) >>> cfg.write_template("run_snapshot.py")
- validate()#
Check parameter ranges and raise
ValueErroron errors.- Raises:
ValueError – Descriptive message pointing to the offending parameter.
- Return type:
None
- to_inverter()#
Instantiate a
EMInverter1D.Returns an untrained inverter configured according to the architecture and feature settings stored in this config. Call
inv.fit(dataset, **cfg.to_fit_kwargs())to train it.- Return type:
Examples
>>> cfg = InversionConfig(arch="cnn1d", n_layers=4, epochs=50) >>> inv = cfg.to_inverter() >>> type(inv).__name__ 'EMInverter1D'
- to_fit_kwargs()#
Assemble keyword arguments for
EMInverter1D.fit().The returned dict is ready to be unpacked directly:
inv = cfg.to_inverter() inv.fit(dataset, **cfg.to_fit_kwargs())
- Returns:
Keys:
epochs,batch_size,lr,patience,val_frac,grad_clip,seed,verbose.- Return type:
Notes
weight_decayandmin_deltaareEMTrainerparameters not currently exposed throughEMInverter1D.fit. They are stored inInversionConfigfor documentation and round-trip reproducibility but are not included in the returned dict.
- checkpoint_path()#
Return the full checkpoint file path, or
Noneif disabled.- Return type:
pathlib.Path or None
- classmethod from_inverter(inv)#
Snapshot a fitted (or unfitted) inverter’s architecture settings.
Creates an
InversionConfigwhose architecture and feature fields match those of inv. Training hyperparameters are reset to their defaults because the inverter does not record them after training.Use this to generate a reproducible record of a training run:
cfg = InversionConfig.from_inverter(inv) cfg.write_template("run_snapshot.py")
- Parameters:
inv (EMInverter1D) – Source inverter (fitted or unfitted).
- Return type:
- to_template(path='inversion_config.py', *, fmt=None)#
Write this configuration to an annotated source-of-truth file.
- Parameters:
path (path-like, default "inversion_config.py") – Destination file. The suffix selects the output format (
.py,.json,.yml).fmt ({"py", "json", "yml", "yaml"}, optional) – Explicit format override.
- Return type:
- classmethod write_template(path='inversion_config.py', *, fmt=None)#
Generate a documented source-of-truth configuration file.
Creates a file with default parameter values and an inline comment for every parameter. Edit the file, then load with
from_file().- Parameters:
path (path-like, default "inversion_config.py") – Destination file.
fmt ({"py", "json", "yml", "yaml"}, optional) – Explicit format override.
- Return type:
Examples
>>> from pycsamt.ai.inversion.config import InversionConfig >>> path = InversionConfig.write_template("my_inv.yml") >>> path.suffix '.yml'
- classmethod from_file(path, *, strict=True)#
Load a configuration from a source-of-truth file.
- Parameters:
path (path-like) – Python, JSON, YML, or YAML file generated by
write_template()or following the same structure.strict (bool, default True) – If
True, unknown keys raiseValueError. IfFalse, unknown keys are silently ignored.
- Return type:
Examples
>>> InversionConfig.write_template("inv_config.json") PosixPath('inv_config.json') >>> cfg = InversionConfig.from_file("inv_config.json") >>> cfg.arch 'resnet'
- classmethod read(path, *, strict=True)#
Alias — matches the convention used by ModEmConfig and OccamConfig.
- Parameters:
- Return type:
- class pycsamt.ai.inversion.RunConfig(forward=<factory>, inversion=<factory>, name='', description='')#
Bases:
objectBundle a
ForwardConfigand anInversionConfiginto one source-of-truth experiment file.- Parameters:
forward (ForwardConfig) – Dataset generation and solver settings.
inversion (InversionConfig) – Network architecture and training settings.
name (str) – Short experiment identifier written into the file header.
description (str) – Optional free-text note describing the experiment.
Notes
validate()checks internal consistency between the two sub-configs:forward.solver == inversion.solverforward.include_phase == inversion.include_phaseFixed layer count (
n_layers_min == n_layers_max) must matchinversion.n_layers.
Examples
Default run (MT1D, ResNet, 5 layers):
>>> run = RunConfig() >>> run.forward.solver 'mt1d' >>> run.inversion.arch 'resnet'
Custom experiment:
>>> run = RunConfig( ... forward=ForwardConfig(solver="mt1d", n_samples=20_000, seed=1), ... inversion=InversionConfig(arch="resnet", n_layers=5, epochs=200), ... name="mt1d_resnet_20k", ... ) >>> run.validate()
Write a template, edit it, reload:
>>> path = RunConfig.write_template("experiment_01.yml") >>> run = RunConfig.from_file(path)
- forward: ForwardConfig#
- inversion: InversionConfig#
- validate()#
Validate both sub-configs and their mutual consistency.
- Raises:
ValueError – Descriptive message pointing to the offending parameter or the cross-config inconsistency.
- Return type:
None
- to_dataset_kwargs()#
Return kwargs for
generate_dataset().Delegates to
ForwardConfig.to_dataset_kwargs().
- to_inverter()#
Return a configured, untrained
EMInverter1D.Delegates to
InversionConfig.to_inverter().
- to_fit_kwargs()#
Return kwargs for
fit().Delegates to
InversionConfig.to_fit_kwargs().
- checkpoint_path()#
Return the checkpoint file path, or
Noneif disabled.Delegates to
InversionConfig.checkpoint_path().- Return type:
Path | None
- to_template(path='run_config.py', *, fmt=None)#
Write this run configuration to an annotated source-of-truth file.
- Parameters:
path (path-like, default "run_config.py") – Destination. The suffix selects the format (
.py,.json,.yml).fmt ({"py", "json", "yml", "yaml"}, optional) – Explicit format override.
- Return type:
- classmethod write_template(path='run_config.py', *, fmt=None, name='', description='')#
Generate a documented source-of-truth run configuration file.
Writes a single file covering both dataset generation and network training with default parameter values and an inline comment for every parameter.
- Parameters:
- Return type:
Examples
>>> from pycsamt.ai.inversion.run_config import RunConfig >>> path = RunConfig.write_template("experiment_01.yml") >>> path.suffix '.yml'
- classmethod from_file(path, *, strict=True)#
Load a run configuration from a source-of-truth file.
- Parameters:
path (path-like) – Python, JSON, YML, or YAML file generated by
write_template()or following the same structure.strict (bool, default True) – If
True, unknown parameter keys raiseValueError. IfFalse, unknown keys are silently ignored.
- Return type:
Examples
>>> RunConfig.write_template("run.json") PosixPath('run.json') >>> run = RunConfig.from_file("run.json") >>> run.forward.solver 'mt1d' >>> run.inversion.arch 'resnet'
- classmethod read(path, *, strict=True)#
Alias — matches the convention used by ModEmConfig, OccamConfig, ForwardConfig.
- class pycsamt.ai.inversion.PINNInverter1D(sites, *, solver='mt1d', n_layers=10, depth_max=2000.0, smoothness_weight=0.01, lr=0.01, device=None, comp='xy', recursive=True, on_dup='replace', verbose=0)#
Bases:
BasePINNInverterPhysics-informed 1-D EM inversion.
Fits a layered Earth model to observed MT/CSAMT apparent resistivity and phase by gradient descent. No labelled training data is required.
- Parameters:
sites (Any) – Path,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable. Station data are extracted at construction time.solver ({'mt1d', 'csamt1d'}) – EM physics solver (TEM not supported).
n_layers (int, default 10) – Number of earth layers including the halfspace.
depth_max (float, default 2000.0) – Approximate investigation depth in metres, used to set equal initial layer thicknesses.
smoothness_weight (float, default 0.01) – Regularisation weight \(\lambda\) on the first-difference of log-resistivity.
lr (float, default 1e-2) – Adam learning rate.
device (str or None) – Torch device. Auto-detects CUDA/CPU if None.
comp ({'xy', 'yx', 'xx', 'yy'}, default 'xy') – Impedance tensor component to use.
recursive (bool, default True) – Passed to
ensure_sites.on_dup (str, default 'replace') – Passed to
ensure_sites.verbose (int, default 0) – Verbosity level for site loading.
- fit(epochs=500, *, verbose=True, log_every=100)#
Run the physics-informed optimisation.
- predict()#
Return fitted layered models for all stations.
- Returns:
models – One per station, same order as
stations.- Return type:
list of LayeredModel
- residuals()#
Compute observed vs predicted data for all sites.
- Returns:
Columns: station, freq, rho_obs, rho_pred, phase_obs, phase_pred.
- Return type:
- loss_curves()#
Return the Adam loss history for all stations.
- Returns:
Columns: station, epoch, loss.
- Return type:
- class pycsamt.ai.inversion.PINNInverter2D(sites, *, n_layers=10, depth_max=2000.0, n_freqs=32, mode='te', smoothness_weight=0.01, lateral_weight=0.005, epochs=300, lr=0.01, comp_te='xy', comp_tm='yx', device=None, recursive=True, on_dup='replace', verbose=0)#
Bases:
BasePINNInverterPhysics-informed 2-D MT inversion.
Optimises a pseudo-2D resistivity section by minimising the data misfit with the 1-D MT forward plus lateral and vertical smoothness penalties.
- Parameters:
sites (Any) – Path,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable.n_layers (int, default 10) – Number of model layers per station.
depth_max (float, default 2000.0) – Target maximum depth in metres.
n_freqs (int, default 32) – Frequency-grid points for the common grid.
mode ({'te', 'tm', 'both'}, default 'te') – Which observed polarisation to use.
'both'averages TE and TM data misfits.smoothness_weight (float, default 0.01) – Vertical smoothness weight \(\lambda_z\).
lateral_weight (float, default 0.005) – Lateral smoothness weight \(\lambda_x\).
epochs (int, default 300) – Adam iterations.
lr (float, default 1e-2) – Adam learning rate.
comp_te (str, default
'xy') – Impedance tensor component for TE mode.comp_tm (str, default
'yx') – Impedance tensor component for TM mode.device (str or None) – Torch compute device (auto-detects if None).
recursive (bool, default True)
on_dup (str, default
'replace')verbose (int, default 0)
- fit(*, verbose=True, log_every=50)#
Run the joint 2-D physics-informed inversion.
- resistivity_section(*, as_log10=True)#
Return the 2-D resistivity section.
- Parameters:
as_log10 (bool, default True) – If True return log10(rho); else linear rho.
- Return type:
ndarray (n_layers, n_stations)
- thickness_section()#
Return layer thicknesses in metres.
- Return type:
ndarray (n_layers-1, n_stations)
- convergence_curve()#
Return Adam loss history.
- Returns:
Columns: epoch, loss.
- Return type:
- residuals()#
Observed vs predicted data fit.
- Returns:
Columns: station, freq, rho_obs, rho_pred, phase_obs, phase_pred.
- Return type:
- class pycsamt.ai.inversion.PINNInverter3D(sites, *, n_layers=10, depth_max=2000.0, n_freqs=32, mode='te', smoothness_weight=0.01, graph_weight=0.005, radius=5000.0, adjacency=None, station_coords=None, station_spacing=500.0, epochs=300, lr=0.01, comp_te='xy', comp_tm='yx', device=None, recursive=True, on_dup='replace', verbose=0)#
Bases:
BasePINNInverterPhysics-informed quasi-3D MT inversion.
Optimises a per-station 1-D column model for all stations simultaneously using the 1-D MT forward with graph-Laplacian spatial smoothness coupling neighbour stations through their shared adjacency.
- Parameters:
sites (Any) – Path,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable.n_layers (int, default 10) – Number of model layers per station.
depth_max (float, default 2000.0) – Target maximum depth in metres.
n_freqs (int, default 32) – Frequency-grid points for the common grid.
mode ({'te', 'tm', 'both'}, default 'te') – Which polarisation to fit.
smoothness_weight (float, default 0.01) – Vertical smoothness weight.
graph_weight (float, default 0.005) – Graph-Laplacian spatial smoothness weight.
radius (float, default 5000.0) – Edge radius in metres used to build the station adjacency when adjacency is None.
adjacency (ndarray (S, S) or None) – Pre-computed normalised adjacency matrix. When
Noneit is built from station positions withbuild_adjacency().station_coords (ndarray (S, 2) or None) – Explicit
(x, y)station positions [m]. Auto-extracted from site metadata if None.station_spacing (float, default 500.0) – Uniform grid spacing [m] used when no geographic coordinates are available.
epochs (int, default 300) – Adam iterations.
lr (float, default 1e-2) – Adam learning rate.
comp_te (str, default
'xy')comp_tm (str, default
'yx')device (str or None)
recursive (bool, default True)
on_dup (str, default
'replace')verbose (int, default 0)
- fit(*, verbose=True, log_every=50)#
Run the joint 3-D physics-informed inversion.
- resistivity_volume(*, as_log10=True)#
Return the quasi-3D resistivity volume.
- Returns:
Column
iis the 1-D model at stationiin the same order asstations.- Return type:
ndarray (n_layers, n_stations)
- Parameters:
as_log10 (bool)
- thickness_volume()#
Return layer thicknesses in metres.
- Return type:
ndarray (n_layers-1, n_stations)
- convergence_curve()#
Return Adam loss history.
- Returns:
Columns: epoch, loss.
- Return type:
- residuals()#
Observed vs predicted data fit.
- Returns:
Columns: station, freq, rho_obs, rho_pred, phase_obs, phase_pred.
- Return type:
- class pycsamt.ai.inversion.HybridInverter1D(sites, ai_inverter, *, solver='mt1d', max_iter=200, smoothness_weight=0.005, lr=0.005, device=None, comp='xy', n_freqs=32, recursive=True, on_dup='replace', verbose=0)#
Bases:
BaseHybridInverterTwo-stage hybrid AI + physics 1-D inversion.
- Parameters:
sites (Any) – Path,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable.ai_inverter (EMInverter1D or str or Path) – Pre-trained supervised inverter (fitted
EMInverter1D) or path to a saved.npzcheckpoint.solver ({'mt1d', 'csamt1d'}, default 'mt1d') – EM physics used in the refinement step.
max_iter (int, default 200) – Adam iterations for the physics refinement.
smoothness_weight (float, default 0.005) – Regularisation weight on log-resistivity first differences.
lr (float, default 5e-3) – Adam learning rate for Stage 2.
device (str or None) – Torch device. Auto-detects CUDA/CPU if None.
comp ({'xy', 'yx', 'xx', 'yy'}, default 'xy') – Impedance component for observed data.
n_freqs (int, default 32) – Frequency-grid size for EMInverter1D input.
recursive (bool, default True)
on_dup (str, default 'replace')
verbose (int, default 0)
- fit(*, verbose=True, log_every=50)#
Run both inversion stages.
- predict()#
Return Stage-2 refined layered models.
- Return type:
list of LayeredModel
- stage1_models()#
Return Stage-1 (AI-only) layered models.
These are the AI starting points before physics refinement.
- Return type:
list of LayeredModel
- convergence_curves()#
Return Stage-2 Adam loss history.
- Returns:
Columns: station, epoch, loss.
- Return type:
- residuals(stage=2)#
Observed vs predicted data fit.
- Parameters:
stage ({1, 2}, default 2) – Which stage’s models to evaluate.
- Returns:
Columns: station, freq, rho_obs, rho_pred, phase_obs, phase_pred.
- Return type:
- class pycsamt.ai.inversion.HybridInverter2D(sites, ai_inverter, *, n_layers=None, depth_max=2000.0, n_freqs=32, mode='te', smoothness_weight=0.005, lateral_weight=0.003, epochs=150, lr=0.005, comp_te='xy', comp_tm='yx', device=None, recursive=True, on_dup='replace', verbose=0)#
Bases:
BaseHybridInverterTwo-stage hybrid AI + physics 2-D inversion.
- Parameters:
sites (Any) – Path,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable.ai_inverter (EMInverter2D or str or Path) – Pre-trained
EMInverter2D(fitted) or path to a.npzcheckpoint.n_layers (int or None) – Layers per station in Stage 2. Defaults to
ai_inverter.n_depth.depth_max (float, default 2000.0) – Total depth for uniform thickness init when Stage 1 does not provide thicknesses.
n_freqs (int, default 32) – Frequency-grid size for the panel and the shared optimisation grid.
mode ({'te', 'tm', 'both'}, default 'te') – Data polarisation used in Stage 2.
smoothness_weight (float, default 0.005) – Vertical smoothness weight.
lateral_weight (float, default 0.003) – Lateral smoothness weight.
epochs (int, default 150) – Adam iterations for Stage 2.
lr (float, default 5e-3) – Adam learning rate for Stage 2.
comp_te (str, default
'xy')comp_tm (str, default
'yx')device (str or None)
recursive (bool, default True)
on_dup (str, default
'replace')verbose (int, default 0)
- fit(*, verbose=True, log_every=50)#
Run both inversion stages.
- resistivity_section(*, as_log10=True)#
Return the Stage-2 2-D resistivity section.
- Parameters:
as_log10 (bool, default True)
- Return type:
ndarray (n_layers, n_stations)
- thickness_section()#
Return Stage-2 layer thicknesses in metres.
- Return type:
ndarray (n_layers-1, n_stations)
- stage1_section(*, as_log10=True)#
Return the Stage-1 AI 2-D section.
- Parameters:
as_log10 (bool, default True)
- Return type:
ndarray (n_layers, n_stations)
- convergence_curve()#
Return Stage-2 Adam loss history.
- Returns:
Columns: epoch, loss.
- Return type:
- residuals(stage=2)#
Observed vs predicted data fit.
- Parameters:
stage ({1, 2}, default 2) – Which stage’s models to evaluate.
- Returns:
Columns: station, freq, rho_obs, rho_pred, phase_obs, phase_pred.
- Return type:
- pycsamt.ai.inversion.map_ai_grid_to_occam(grid, model, mesh, x_coordinates=None, z_coordinates=None)#
Map a regular AI grid to Occam parameter order.
AI values are bilinearly interpolated to physical Occam cell centres. Values within each model-parameter rectangle are then averaged with finite-element cell area as weight:
\[\bar m_j = \frac{\sum_{k \in G_j} m_k A_k} {\sum_{k \in G_j} A_k},\]where \(G_j\) is parameter group \(j\) and \(A_k\) is the area of mesh cell \(k\). Air layers are excluded, and the returned vector follows the layer-major order used by Occam startup and iteration files.
- Parameters:
grid (array-like of float, shape (n_depth, n_horizontal)) – Finite AI values on a regular or explicitly coordinated grid. Values are typically log10 resistivity or predictive standard deviation.
model (OccamModel) – Populated Occam model definition. Horizontal parameter codes give the number of mesh cells spanned, and
n_mergegives the number of earth rows spanned vertically.mesh (OccamMesh) – Populated Occam finite-element mesh supplying physical cell widths, layer thicknesses, node positions, and air-layer count.
x_coordinates (array-like of float, optional) – Strictly increasing horizontal coordinates of AI grid columns, in the same coordinate system as
mesh.x_nodes. The length must equalgrid.shape[1]. If omitted, uniformly spaced cell centres spanning the complete Occam horizontal domain are used.z_coordinates (array-like of float, optional) – Strictly increasing AI depth coordinates, positive downward from the earth surface. The length must equal
grid.shape[0]. If omitted, uniformly spaced cell centres spanning the Occam earth domain are used.
- Returns:
Area-weighted values in Occam layer-major parameter order.
- Return type:
numpy.ndarray of float, shape (model.n_params,)
- Raises:
TypeError – Raised when
modelormeshlacks the required Occam geometry interface.ValueError – Raised for invalid grids or coordinates, non-positive mesh dimensions, model groups inconsistent with the mesh, or a returned parameter count inconsistent with
model.n_params.
Notes
Values outside the supplied AI coordinate range use nearest-edge extrapolation through
numpy.interp(). Publication workflows should normally supply coordinates spanning the complete inversion domain so extrapolation is unnecessary.The mapping averages log10 resistivity when
gridis in log10 units. It therefore preserves the parameterization optimized by Occam rather than arithmetic resistivity.When
gridcontains predictive standard deviation, the same area-weighted spatial averaging is applied. This treats uncertainty as a spatial field and does not assume independent AI pixels; it is therefore not a standard-error reduction by the number of cells.See also
pycsamt.ai.inversion.duhi2d.DUHIInverter2DUses this mapper for AI means and standard deviations.
pycsamt.models.occam2d.OccamModelDefines the parameter grouping traversed here.
pycsamt.models.occam2d.OccamMeshDefines the physical cell areas used as weights.
Examples
Map a grid after reading an Occam project:
>>> from pycsamt.ai.inversion.mapping2d import ( ... map_ai_grid_to_occam, ... ) >>> from pycsamt.models.occam2d import OccamMesh, OccamModel >>> mesh = OccamMesh.read("occam_run/Occam2DMesh") >>> model = OccamModel.read("occam_run/Occam2DModel") >>> parameters = map_ai_grid_to_occam( ... ai_grid, ... model, ... mesh, ... x_coordinates=ai_x, ... z_coordinates=ai_z, ... ) >>> parameters.shape == (model.n_params,) True
- pycsamt.ai.inversion.dimensionality_reliability(beta_deg, *, beta_scale_deg=5.0, minimum=0.0)#
Convert phase-tensor skew into compatibility with 2-D physics.
- Parameters:
beta_deg (array-like of float) – Phase-tensor skew angles in degrees. Non-finite entries receive the configured minimum reliability.
beta_scale_deg (float, default=5.0) – Positive skew scale \(\beta_0\). Reliability equals
exp(-1)at this absolute skew.minimum (float, default=0.0) – Lower bound in the closed interval
[0, 1].
- Returns:
Reliability values with the same shape as
beta_deg.- Return type:
- Raises:
ValueError – If the input is empty or scalar controls are invalid.
Examples
>>> dimensionality_reliability([0.0, 5.0]).round(6).tolist() [1.0, 0.367879]
- pycsamt.ai.inversion.combine_observation_reliability(measurement, dimensionality, *, minimum=0.0)#
Return bounded measurement-by-dimensionality reliability.
- Parameters:
measurement (array-like of float) – Reliability factors in
[0, 1]. Inputs must be broadcastable to one common shape.dimensionality (array-like of float) – Reliability factors in
[0, 1]. Inputs must be broadcastable to one common shape.minimum (float, default=0.0) – Lower bound applied after multiplication.
- Returns:
Broadcast product clipped to
[minimum, 1].- Return type:
- Raises:
ValueError – If inputs are empty, non-finite, outside
[0, 1], or cannot be broadcast together.
Examples
>>> combine_observation_reliability( ... [0.8, 0.5], [0.5, 0.2] ... ).tolist() [0.4, 0.1]
- class pycsamt.ai.inversion.HybridInverter3D(sites, ai_inverter, *, n_layers=None, depth_max=2000.0, n_freqs=32, mode='te', smoothness_weight=0.005, graph_weight=0.003, radius=5000.0, adjacency=None, station_coords=None, station_spacing=500.0, epochs=150, lr=0.005, comp_te='xy', comp_tm='yx', device=None, recursive=True, on_dup='replace', verbose=0)#
Bases:
BaseHybridInverterTwo-stage hybrid AI + physics quasi-3D inversion.
- Parameters:
sites (Any) – Path,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable.ai_inverter (GCNInverter3D or str or Path) – Pre-trained (fitted)
GCNInverter3Dor path to a.npzcheckpoint.n_layers (int or None) – Layers per station for Stage 2. Defaults to
ai_inverter.n_layers.depth_max (float, default 2000.0) – Target depth for uniform thickness init.
n_freqs (int, default 32) – Frequency-grid size for Stage 2 optimisation.
mode ({'te', 'tm', 'both'}, default 'te') – Polarisation used in Stage 2.
smoothness_weight (float, default 0.005) – Vertical smoothness weight for Stage 2.
graph_weight (float, default 0.003) – Graph spatial smoothness weight.
radius (float, default 5000.0) – Edge radius [m] for adjacency construction.
adjacency (ndarray (S, S) or None) – Pre-computed adjacency. Built from station positions if
None.station_coords (ndarray (S, 2) or None) – Explicit
(x, y)positions [m].station_spacing (float, default 500.0) – Fallback uniform grid spacing [m].
epochs (int, default 150) – Adam iterations for Stage 2.
lr (float, default 5e-3) – Adam learning rate for Stage 2.
comp_te (str, default
'xy')comp_tm (str, default
'yx')device (str or None)
recursive (bool, default True)
on_dup (str, default
'replace')verbose (int, default 0)
- fit(*, verbose=True, log_every=50)#
Run both inversion stages.
- resistivity_volume(*, as_log10=True)#
Return the Stage-2 quasi-3D volume.
- Return type:
ndarray (n_layers, n_stations)
- Parameters:
as_log10 (bool)
- thickness_volume()#
Return Stage-2 layer thicknesses [m].
- Return type:
ndarray (n_layers-1, n_stations)
- stage1_volume(*, as_log10=True)#
Return the Stage-1 GCN quasi-3D volume.
- Return type:
ndarray (n_layers, n_stations)
- Parameters:
as_log10 (bool)
- convergence_curve()#
Return Stage-2 Adam loss history.
- Returns:
Columns: epoch, loss.
- Return type:
- residuals(stage=2)#
Observed vs predicted data fit.
- Parameters:
stage ({1, 2}, default 2)
- Returns:
Columns: station, stage, freq, rho_obs, rho_pred, phase_obs, phase_pred.
- Return type:
- class pycsamt.ai.inversion.SiteObs1D(name, freq, rho_obs, phase_obs)#
Bases:
objectObserved 1-D MT/CSAMT data for one station.
- Parameters:
name (str) – Station identifier.
freq (ndarray (n_f,)) – Frequencies in Hz, sorted high to low.
rho_obs (ndarray (n_f,)) – Apparent resistivity in Ohm.m.
phase_obs (ndarray (n_f,)) – Impedance phase in degrees.
- class pycsamt.ai.inversion.SiteObs2D(name, freq, rho_te, phase_te, rho_tm, phase_tm)#
Bases:
objectObserved 2-D MT profile data for one station.
- Parameters:
name (str) – Station identifier.
freq (ndarray (n_f,)) – Frequencies in Hz, sorted high to low.
rho_te (ndarray (n_f,)) – TE apparent resistivity in Ohm.m (Zxy convention).
phase_te (ndarray (n_f,)) – TE phase in degrees.
rho_tm (ndarray (n_f,)) – TM apparent resistivity in Ohm.m (Zyx convention).
phase_tm (ndarray (n_f,)) – TM phase magnitude in degrees (absolute value stored).
- pycsamt.ai.inversion.sites_to_obs_1d(sites, *, comp='xy', recursive=True, on_dup='replace', strict=False, verbose=0)#
Convert any site input to observed-data containers.
- Parameters:
sites (Any) – Path, glob,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable of any of the above.comp ({'xy', 'yx', 'xx', 'yy'}, default 'xy') – Impedance tensor component to extract.
recursive (bool) – Forwarded to
ensure_sites.on_dup (str) – Forwarded to
ensure_sites.strict (bool) – Forwarded to
ensure_sites.verbose (int) – Forwarded to
ensure_sites.
- Returns:
One entry per valid station.
- Return type:
- Raises:
ValueError – If comp is invalid or no valid site data survives extraction.
- pycsamt.ai.inversion.sites_to_obs_2d(sites, *, comp_te='xy', comp_tm='yx', recursive=True, on_dup='replace', strict=False, verbose=0)#
Convert any site input to 2-D observation containers.
- Parameters:
sites (Any) – Path, glob,
EDIFile,EDICollection,Site,Sites,APISurvey, or iterable of any of the above.comp_te (str, default
'xy') – Tensor component treated as TE mode.comp_tm (str, default
'yx') – Tensor component treated as TM mode.recursive (bool) – Forwarded to
ensure_sites.on_dup (str) – Forwarded to
ensure_sites.strict (bool) – Forwarded to
ensure_sites.verbose (int) – Forwarded to
ensure_sites.
- Returns:
One entry per valid station, same order as input.
- Return type:
- Raises:
ValueError – If no valid station data is found.
- pycsamt.ai.inversion.sites_to_features_1d(sites, *, comp='xy', n_freqs=32, freq_min=None, freq_max=None, recursive=True, on_dup='replace', strict=False, verbose=0)#
Convert any site input to an ML feature matrix.
The feature layout matches
to_array()so the result is directly compatible with a fittedEMInverter1D:X = [log10(rho_f1), ..., log10(rho_fn), phase_f1, ..., phase_fn]
- Parameters:
sites (Any) – Same accepted types as
sites_to_obs_1d().comp (str, default
'xy') – Tensor component.n_freqs (int, default 32) – Frequencies in the common interpolation grid.
freq_min (float or None) – Override the auto-detected frequency range.
freq_max (float or None) – Override the auto-detected frequency range.
recursive (bool)
on_dup (str)
strict (bool)
verbose (int)
- Returns:
X (ndarray, shape (n_stations, 2*n_freqs)) – Block-format feature matrix (rho block first, then phase block).
freqs (ndarray, shape (n_freqs,)) – Common frequency grid in Hz.
names (list of str) – Station names in the same row order as
X.
- Return type:
- pycsamt.ai.inversion.sites_to_panel_2d(sites, *, n_freqs=32, n_components=4, comp_te='xy', comp_tm='yx', freq_min=None, freq_max=None, recursive=True, on_dup='replace', strict=False, verbose=0)#
Build an
EMInverter2Dinput panel from sites.- Returns:
X_panel (ndarray) – Shape
(1, n_components, n_freqs, n_stations). Channel layout (forn_components=4):[log10(rho_te), phase_te, log10(rho_tm), phase_tm]. Forn_components=2: TE channels only.freqs (ndarray (n_freqs,)) – Common frequency grid in Hz (high to low).
names (list of str) – Station names in the same column order as
X_panel.
- Parameters:
- Return type:
- pycsamt.ai.inversion.sites_to_coords_3d(sites, *, station_spacing=500.0, recursive=True, on_dup='replace', verbose=0)#
Extract station (x, y) positions in metres.
Tries
site.coords(lat, lon); falls back to a uniform grid when coordinates are missing or all zero.- Parameters:
sites (Any) – Same accepted types as
sites_to_obs_1d().station_spacing (float, default 500.0) – Spacing in metres used when coordinates are unavailable (uniform-grid fallback).
recursive (bool) – Forwarded to
ensure_sites.on_dup (str) – Forwarded to
ensure_sites.verbose (int) – Forwarded to
ensure_sites.
- Returns:
xy – Station (x, y) positions in metres.
- Return type:
ndarray (n_stations, 2)
- pycsamt.ai.inversion.obs_to_features_1d(obs, n_freqs=32, *, freq_min=None, freq_max=None)#
Build a feature matrix from a list of obs objects.
Works with both
SiteObs1D(usesrho_obs,phase_obs) andSiteObs2D(usesrho_te,phase_te). Skipsensure_sites, so it is safe to call with pre-extracted obs lists.
|
End-to-end 1-D EM inversion workflow. |
|
EMInverter2D — high-level U-Net–based 2-D MT inversion pipeline. |
|
GCNInverter3D — graph-convolutional 3-D MT spatial inversion. |
|
EnsembleInverter — deep ensemble for uncertainty-aware EM inversion. |
|
JointInverter — multi-modal / multi-physics joint inversion. |
|
Calibrated uncertainty quantification for EM neural-network inverters. |
|
Physics-informed 1-D MT/CSAMT inversion. |
|
Physics-informed AI 2-D MT inversion. |
|
Physics-informed AI 3-D MT inversion. |
|
Hybrid AI + physics 1-D MT/CSAMT inversion. |
|
Hybrid AI + physics 2-D MT inversion. |
|
Hybrid AI + physics quasi-3D MT inversion. |
|
Dual-Uncertainty Hybrid Inversion preparation for Occam2D. |
|
Geometry-aware mapping between regular AI and Occam2D grids. |
|
Observation-reliability factors for two-dimensional inversion. |
|
Configuration for pyCSAMT 1-D AI-based EM inversion. |
|
End-to-end run configuration for pyCSAMT AI inversion. |
|
Parameter-validation schemas for AI inversion interfaces. |