pycsamt.ai.validation.recovery#

Synthetic-recovery diagnostics for known-truth geological grids.

These diagnostics implement the M0 baseline metrics named in the AI-inversion plan: log-resistivity MAE/RMSE, structural similarity, and recovery broken down by depth. Inputs are predicted and true model arrays sharing one canonical geological-grid shape, e.g. (z, x) or (z, y, x) from GeologyGrid. Recovery diagnostics are only meaningful when the true model is known, i.e. on synthetic data; field-survey validation instead relies on response residuals.

All functions operate on plain NumPy arrays so the module stays importable without an optional deep-learning backend.

Functions

depth_profile_mae(y_pred, y_true, *[, axis, ...])

Return per-layer masked MAE along one grid axis.

depth_profile_rmse(y_pred, y_true, *[, ...])

Return per-layer masked RMSE along one grid axis.

recovery_report(y_pred, y_true, *[, valid, ...])

Summarize synthetic-recovery quality for one grid pair.

structural_similarity(y_pred, y_true, *[, ...])

Compute the mean structural similarity index (SSIM).

Classes

RecoveryReport(rmse, mae, r2, ssim, ...)

Immutable synthetic-recovery diagnostics for one grid pair.

class pycsamt.ai.validation.recovery.RecoveryReport(rmse, mae, r2, ssim, depth_rmse, depth_mae, n_valid, shape)[source]

Bases: object

Immutable synthetic-recovery diagnostics for one grid pair.

Parameters:
  • rmse (float) – Global masked root-mean-square and mean-absolute error.

  • mae (float) – Global masked root-mean-square and mean-absolute error.

  • r2 (float) – Coefficient of determination. nan when the true values are numerically constant, making R² undefined.

  • ssim (float or None) – Structural similarity index (Wang et al., 2004), or None when it was not requested or not computable, e.g. the grid is partially masked or smaller than the requested window.

  • depth_rmse (ndarray) – Per-layer RMSE/MAE along the requested depth axis.

  • depth_mae (ndarray) – Per-layer RMSE/MAE along the requested depth axis.

  • n_valid (int) – Number of cells included after masking.

  • shape (tuple of int) – Shape of the compared grids.

Examples

>>> import numpy as np
>>> pred = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> true = np.array([[1.0, 2.0], [3.0, 6.0]])
>>> report = recovery_report(pred, true, compute_ssim=False)
>>> report.n_valid, report.shape
(4, (2, 2))
rmse: float
mae: float
r2: float
ssim: float | None
depth_rmse: ndarray
depth_mae: ndarray
n_valid: int
shape: tuple[int, ...]
pycsamt.ai.validation.recovery.recovery_report(y_pred, y_true, *, valid=None, depth_axis=0, compute_ssim=True, ssim_window=7)[source]

Summarize synthetic-recovery quality for one grid pair.

Parameters:
  • y_pred (array-like) – Predicted and true model values sharing one 2-D or 3-D grid shape.

  • y_true (array-like) – Predicted and true model values sharing one 2-D or 3-D grid shape.

  • valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of both inputs.

  • depth_axis (int, default=0) – Grid axis passed to depth_profile_rmse() and depth_profile_mae().

  • compute_ssim (bool, default=True) – Attempt structural_similarity(). Skipped (ssim is None) when the grid is partially masked or smaller than ssim_window, since SSIM has no defined masking rule.

  • ssim_window (int, default=7) – Window forwarded to structural_similarity().

Returns:

Combined recovery diagnostics.

Return type:

RecoveryReport

Raises:

ValueError – If shapes mismatch, inputs are empty, or no cell is valid.

Examples

>>> import numpy as np
>>> pred = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> true = np.array([[1.0, 2.0], [3.0, 6.0]])
>>> report = recovery_report(pred, true, compute_ssim=False)
>>> round(report.rmse, 6), round(report.mae, 6)
(1.0, 0.5)
>>> round(report.r2, 6)
0.714286
pycsamt.ai.validation.recovery.structural_similarity(y_pred, y_true, *, window=7, data_range=None)[source]

Compute the mean structural similarity index (SSIM).

Uses the windowed luminance/contrast/structure formulation of Wang et al. (2004) with a uniform (box) window, evaluated on the interior of the grid to avoid boundary-filter artifacts.

Parameters:
  • y_pred (array-like) – Fully finite 2-D or 3-D grids sharing one shape. SSIM has no defined masking rule, so both must be complete.

  • y_true (array-like) – Fully finite 2-D or 3-D grids sharing one shape. SSIM has no defined masking rule, so both must be complete.

  • window (int, default=7) – Positive odd window size, no larger than the smallest grid axis.

  • data_range (float or None, optional) – Dynamic range of the compared values. Defaults to the range spanned by the combined y_pred/y_true values.

Returns:

Mean SSIM over the interior window positions, at most 1.0 for identical grids.

Return type:

float

Examples

>>> import numpy as np
>>> grid = np.arange(64, dtype=float).reshape(8, 8)
>>> structural_similarity(grid, grid, window=3)
1.0
pycsamt.ai.validation.recovery.depth_profile_rmse(y_pred, y_true, *, axis=0, valid=None)[source]

Return per-layer masked RMSE along one grid axis.

Parameters:
  • y_pred (array-like) – Predicted and true model values sharing one 2-D or 3-D grid shape.

  • y_true (array-like) – Predicted and true model values sharing one 2-D or 3-D grid shape.

  • axis (int, default=0) – Grid axis to break down by, typically depth (z).

  • valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of both inputs.

Returns:

RMSE for each layer; nan for a layer with no valid cells.

Return type:

ndarray, shape (y_pred.shape[axis],)

Examples

>>> import numpy as np
>>> pred = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> true = np.array([[1.0, 2.0], [3.0, 6.0]])
>>> depth_profile_rmse(pred, true).tolist()
[0.0, 1.4142135623730951]
pycsamt.ai.validation.recovery.depth_profile_mae(y_pred, y_true, *, axis=0, valid=None)[source]

Return per-layer masked MAE along one grid axis.

Parameters:
  • y_pred (array-like) – Predicted and true model values sharing one 2-D or 3-D grid shape.

  • y_true (array-like) – Predicted and true model values sharing one 2-D or 3-D grid shape.

  • axis (int, default=0) – Grid axis to break down by, typically depth (z).

  • valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of both inputs.

Returns:

MAE for each layer; nan for a layer with no valid cells.

Return type:

ndarray, shape (y_pred.shape[axis],)

Examples

>>> import numpy as np
>>> pred = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> true = np.array([[1.0, 2.0], [3.0, 6.0]])
>>> depth_profile_mae(pred, true).tolist()
[0.0, 1.0]