pycsamt.ai.inversion.duhi2d#
Dual-Uncertainty Hybrid Inversion preparation for Occam2D.
This module connects two uncertainty descriptions to solver-native Occam2D inputs:
observation reliability modifies each datum error in data space;
AI predictive uncertainty modifies model prejudice in parameter space.
For datum error \(\sigma_i\) and reliability \(c_i\), the effective error is
For AI parameter mean \(\mu_j\), standard deviation \(\sigma_j\), uncertainty floor \(\sigma_0\), and AI weight \(\lambda_{\mathrm{AI}}\), the Occam prejudice amplitude is
The DUHIInverter2D object prepares these inputs but does not
execute the external solver. Execution remains the responsibility of
pycsamt.models.occam2d.OccamRunner or the common Occam2D
inversion backend.
Entry points#
apply_observation_reliability(errors, reliability)Convert nominal errors to reliability-weighted effective errors.
map_ai_grid_to_occam(grid, model, mesh)Map a coordinated 2-D AI grid to Occam parameter order.
DUHIInverter2D.prepare(builder, ...)Write a completed Occam2D project with both DUHI branches.
Functions
|
Return reliability-weighted effective datum errors. |
Classes
|
Prepare an Occam2D project for DUHI physics refinement. |
|
Summarize one completed DUHI Occam2D preparation. |
- class pycsamt.ai.inversion.duhi2d.DUHIPreparation(workdir, prejudice_file, data_file, model_file, startup_file, n_data, n_params, effective_error_min, effective_error_max, prejudice_weight_min, prejudice_weight_max, ai_initialized)[source]
Bases:
PyCSAMTObjectSummarize one completed DUHI Occam2D preparation.
- Parameters:
workdir (pathlib.Path) – Occam2D project directory modified by the preparation.
prejudice_file (pathlib.Path) – Written sparse prejudice file.
data_file (pathlib.Path) – Rewritten Occam data file containing effective errors.
model_file (pathlib.Path) – Rewritten model file referencing
prejudice_file.startup_file (pathlib.Path) – Rewritten startup file, optionally containing the AI mean.
n_data (int) – Number of Occam data rows weighted by reliability.
n_params (int) – Number of Occam model parameters receiving mapped AI values.
effective_error_min (float) – Minimum effective error after reliability weighting.
effective_error_max (float) – Maximum effective error after reliability weighting.
prejudice_weight_min (float) – Minimum mapped AI prejudice weight.
prejudice_weight_max (float) – Maximum mapped AI prejudice weight.
ai_initialized (bool) – Whether the AI mean replaced the startup parameter vector.
- Variables:
files (dict of str to pathlib.Path) – Mapping of solver input roles to generated paths.
Examples
A preparation result is returned by
DUHIInverter2D.prepare():result = inverter.prepare( builder, ai_mean=mean, ai_std=std, observation_reliability=reliability, ) result.files["prejudice"]
- workdir: Path
- prejudice_file: Path
- data_file: Path
- model_file: Path
- startup_file: Path
- n_data: int
- n_params: int
- effective_error_min: float
- effective_error_max: float
- prejudice_weight_min: float
- prejudice_weight_max: float
- ai_initialized: bool
- class pycsamt.ai.inversion.duhi2d.DUHIInverter2D(*, lambda_ai=1.0, sigma_ai_floor=0.05, reliability_floor=1e-06, prejudice_filename='DUHIPrejudice', grid_mapper=None, verbose=0)[source]
Bases:
PyCSAMTObjectPrepare an Occam2D project for DUHI physics refinement.
DUHIInverter2Dconverts observation reliability and ensemble AI uncertainty into solver-native Occam2D inputs. The object is a preparation-stage inversion component: it does not train a network and does not execute Occam2D.The preparation modifies a completed
InputBuilderproject in place. It performs four operations:replace nominal datum errors by reliability-weighted errors;
map AI mean and standard-deviation grids to Occam parameters;
optionally replace the startup vector with the AI mean; and
write uncertainty-dependent prejudice records and reference them from the Occam model file.
- Parameters:
lambda_ai (float, default 1.0) – Non-negative global multiplier for AI prejudice amplitudes. A value of zero writes no active prejudice records.
sigma_ai_floor (float, default 0.05) – Positive model-uncertainty floor in log10 resistivity. It prevents unbounded prejudice weights where ensemble spread is very small.
reliability_floor (float, default 1e-6) – Smallest observation reliability used in effective errors. It must lie in
(0, 1].prejudice_filename (str, default "DUHIPrejudice") – Solver-local prejudice filename. It must be a non-empty file name without directory components.
grid_mapper (callable, optional) – Function accepting
(grid, model, mesh, x_coordinates, z_coordinates)and returning a one-dimensional vector of lengthmodel.n_params. If omitted, the geometry-awaremap_ai_grid_to_occam()mapper is used.verbose (int or bool, default 0) – Verbosity level. Positive values print a compact completion message after preparation.
- Variables:
lambda_ai (float) – Global AI prejudice multiplier.
sigma_ai_floor (float) – Model-space uncertainty floor.
reliability_floor (float) – Data-space reliability floor.
prejudice_filename (str) – Native Occam prejudice filename.
grid_mapper (callable) – Active AI-grid to Occam-parameter mapping function.
verbose (int) – Integer verbosity level.
is_prepared (bool) – Whether
prepare()completed successfully.preparation (DUHIPreparation) – Most recent completed preparation result.
Notes
Instances are intentionally one-shot because the builder is modified in place. Reapplying reliability weights to an already prepared data table would compound error inflation. Create a new
DUHIInverter2Dand a freshInputBuilderfor each run.When AI coordinates are omitted, the default mapper infers uniform AI cell centres spanning the complete Occam horizontal and earth domains. Explicit coordinates are preferred for archived runs.
See also
EMInverter2DProduces learned 2-D model proposals.
EnsembleInverterProduces ensemble mean and predictive uncertainty.
OccamPrejudiceEncodes model targets and weights for the native solver.
pycsamt.models.occam2d.OccamRunnerExecutes a prepared Occam2D project.
Examples
Prepare a completed Occam2D project:
>>> from pycsamt.ai.inversion import DUHIInverter2D >>> inverter = DUHIInverter2D( ... lambda_ai=1.0, ... sigma_ai_floor=0.05, ... ) >>> result = inverter.prepare( ... builder, ... ai_mean=ensemble_mean, ... ai_std=ensemble_std, ... observation_reliability=reliability, ... ) >>> result.prejudice_file PosixPath('occam_run/DUHIPrejudice')
Supply a geometry-aware mapper:
>>> inverter = DUHIInverter2D( ... grid_mapper=physical_mesh_mapper, ... )
References
[DUHIInverter2D-1]deGroot-Hedlin, C., and Constable, S., “Occam’s inversion to generate smooth, two-dimensional models from magnetotelluric data”, Geophysics, 55(12), 1613-1624, 1990.
- validate()[source]
Validate DUHI preparation hyperparameters.
- Raises:
TypeError – Raised when
grid_mapperis not callable.ValueError – Raised when numerical controls are non-finite or outside their accepted ranges, or when
prejudice_filenameis empty or contains directory components.
- Return type:
None
See also
DUHIInverter2D.prepareValidates run-specific inputs after these controls.
Examples
>>> DUHIInverter2D(lambda_ai=0.5).validate()
- prepare(builder, *, ai_mean, ai_std, observation_reliability, ai_initialize=True, ai_x=None, ai_z=None)[source]
Apply both DUHI branches to completed Occam2D inputs.
- Parameters:
builder (InputBuilder) – Completed Occam2D input builder.
builder.is_readymust beTrueand its data, model, startup, configuration, and work directory must be populated. Compatible builder objects exposing the same interface are also accepted.ai_mean (array-like of float, shape (n_depth, n_horizontal)) – Finite ensemble-mean log10-resistivity grid.
ai_std (array-like of float, shape (n_depth, n_horizontal)) – Finite non-negative predictive standard-deviation grid. It must have the same shape as
ai_mean.observation_reliability (array-like of float, shape (n_data,)) – One reliability value in
[0, 1]for each Occam data row, in exactly the same order asdata_blocks.ai_initialize (bool, default True) – If
True, replaceStartup.param_valueswith the mapped AI mean. IfFalse, retain the existing startup vector while still writing the DUHI prejudice.ai_x (array-like of float, optional) – Horizontal coordinates of AI grid columns in the Occam mesh coordinate system. The length must equal
ai_mean.shape[1]. If omitted, uniform centres spanning the complete mesh width are inferred.ai_z (array-like of float, optional) – AI grid depth coordinates, positive downward from the earth surface. The length must equal
ai_mean.shape[0]. If omitted, uniform centres spanning the earth mesh depth are inferred.
- Returns:
Immutable summary containing generated paths, dimensions, effective-error bounds, prejudice-weight bounds, and the initialization choice.
- Return type:
- Raises:
RuntimeError – Raised when this one-shot object has already prepared a project.
TypeError – Raised when
builderdoes not expose the expected Occam2D input interface.ValueError – Raised when the builder is incomplete, AI grids are incompatible, reliability length is wrong, mapped vectors are invalid, or model/startup dimensions disagree.
Notes
The builder and its data, model, and startup objects are modified in place. The files are then rewritten sequentially using their standard Occam writers.
See also
apply_observation_reliabilityImplements the data-space transformation.
OccamPrejudice.from_denseBuilds the model-space sparse constraint.
DUHIInverter2D.preparationReturns the same result after successful preparation.
Examples
>>> result = inverter.prepare( ... builder, ... ai_mean=mean, ... ai_std=std, ... observation_reliability=reliability, ... ) >>> result.n_params 336
- property is_prepared: bool[source]
Return whether Occam2D inputs were prepared successfully.
- Returns:
Trueafterprepare()completes without error.- Return type:
Examples
>>> DUHIInverter2D().is_prepared False
- property preparation: DUHIPreparation[source]
Return the completed preparation summary.
- Returns:
Immutable result from the successful preparation.
- Return type:
- Raises:
RuntimeError – Raised when
prepare()has not completed.
Examples
>>> inverter.preparation DUHIPreparation(...)
- property prejudice: OccamPrejudice[source]
Return the generated sparse Occam prejudice object.
- Returns:
Generated model-space target and weight definition.
- Return type:
- Raises:
RuntimeError – Raised when
prepare()has not completed.
- property ai_mean_parameters: ndarray[source]
Return a copy of the mapped AI mean parameter vector.
- Returns:
AI mean in Occam layer-major parameter order.
- Return type:
numpy.ndarray of float, shape (n_params,)
- Raises:
RuntimeError – Raised when
prepare()has not completed.
- property ai_std_parameters: ndarray[source]
Return a copy of mapped AI standard deviations.
- Returns:
Predictive standard deviations in Occam parameter order.
- Return type:
numpy.ndarray of float, shape (n_params,)
- Raises:
RuntimeError – Raised when
prepare()has not completed.
- property prejudice_weights: ndarray[source]
Return a copy of mapped uncertainty-dependent weights.
- Returns:
Dense prejudice weights in Occam parameter order.
- Return type:
numpy.ndarray of float, shape (n_params,)
- Raises:
RuntimeError – Raised when
prepare()has not completed.
- summary(*, max_fields=None)[source]
Return a compact DUHI configuration and state summary.
- Parameters:
max_fields (int, optional) – Accepted for compatibility with
PyCSAMTObject. DUHI uses a fixed scientific summary and therefore ignores this value.- Returns:
One-line summary containing uncertainty controls and the preparation state.
- Return type:
Examples
>>> "unprepared" in DUHIInverter2D().summary() True
- pycsamt.ai.inversion.duhi2d.apply_observation_reliability(errors, reliability, *, reliability_floor=1e-06)[source]
Return reliability-weighted effective datum errors.
Nominal errors are divided by the square root of observation reliability. Low-reliability data therefore receive larger effective errors and exert less influence on the normalized data misfit. Inputs are not modified.
- Parameters:
errors (array-like of float) – Positive nominal standard errors. The returned array has the same shape.
reliability (array-like of float) – Reliability values in the closed interval
[0, 1]. The values must be broadcastable to the shape oferrors.reliability_floor (float, default 1e-6) – Smallest reliability used in the denominator. It must lie in
(0, 1]and prevents division by zero for rejected data.
- Returns:
Effective errors with the same shape as
errors.- Return type:
- Raises:
ValueError – Raised when inputs cannot be broadcast together, errors are non-finite or non-positive, reliability values are outside
[0, 1], or the floor is invalid.
Notes
A reliability of one leaves the nominal error unchanged. A reliability of zero uses
reliability_floorand therefore has a finite but potentially very small influence.See also
DUHIInverter2D.prepareApplies the transformation to an Occam data table.
Examples
>>> from pycsamt.ai.inversion.duhi2d import ( ... apply_observation_reliability, ... ) >>> apply_observation_reliability([2.0, 2.0], [1.0, 0.25]).tolist() [2.0, 4.0]
- pycsamt.ai.inversion.duhi2d.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