Uncertainty quantification#

Every hydro-geophysical number carries the uncertainty of the petrophysical assumptions behind it. MonteCarloHydro propagates priors on the rock-physics parameters (pore-water resistivity, cementation exponent, …) through the whole workflow, producing P10/P50/P90 maps and profiles instead of single values. This example quantifies the uncertainty on the synthetic section’s aquifer properties.

Monte-Carlo propagation#

UncertaintyBounds sets the prior ranges; each draw re-runs the hydro model, and run aggregates the ensemble into an UncertaintyResult with percentile maps and coefficient-of-variation fields.

from _interp_data import demo_model

from pycsamt.interp import (
    MonteCarloHydro,
    PetrophysicalConfig,
    UncertaintyBounds,
)

# Use the uncertainty section (2nd figure) as the card thumbnail.

rm = demo_model()
cfg = PetrophysicalConfig(rho_w=20.0, porosity_prior=0.25)
bounds = UncertaintyBounds(rho_w_range=(10.0, 60.0), m_range=(1.6, 2.2))
unc = MonteCarloHydro(rm, cfg, bounds, n_samples=200).run()

import numpy as np

print("worst-case CV of K:", round(float(np.nanmax(unc.cv_K)), 2))
print(
    "water-table P10-P90 spread (m), first 5:",
    np.round((unc.p90_wt - unc.p10_wt)[:5], 1),
)
worst-case CV of K: 0.89
water-table P10-P90 spread (m), first 5: [0. 0. 0. 0. 0.]

Uncertainty section#

PlotUncertaintySection pairs the P50 estimate (top) with its spread (bottom) for a chosen quantity — so a confident, high-K aquifer cell is visibly distinct from a high-K cell that is merely a lucky draw.

from pycsamt.interp.plot import (
    PlotUncertaintyHistogram,
    PlotUncertaintyProfile,
    PlotUncertaintySection,
)

PlotUncertaintySection(unc, quantity="K").plot()
Uncertainty section — K  [  N=200], P50 estimate, Uncertainty spread
<Figure size 1300x800 with 4 Axes>

Water-table and transmissivity with error bands#

PlotUncertaintyProfile is the water-table / transmissivity profile from Hydro-geophysics: aquifer properties, now with P10-P90 envelopes — the honest version of a well-siting figure.

PlotUncertaintyProfile(unc, reference_depth=20.0).plot()
WT & T uncertainty profile  [  N=200]
<Figure size 1300x600 with 2 Axes>

Distribution of a target property#

PlotUncertaintyHistogram shows the full ensemble distribution of a scalar target (e.g. peak transmissivity), making the shape of the uncertainty — skew, multi-modality — explicit rather than collapsing it to a single error bar.

PlotUncertaintyHistogram(unc).plot()
Posterior histogram — water table  [N=200], S00, S07, S014, S021, S028, S035
<Figure size 1200x700 with 6 Axes>

Reading it. Uncertainty is largest where the aquifer is thin or its resistivity sits near a unit boundary, and smallest in the thick clean sand — so report calibrated P10-P90 ranges, not point values, whenever the interpretation feeds a drilling or management decision. This closes the interpretation workflow: model -> lithology -> hydrogeology -> properties -> calibration -> monitoring -> uncertainty.

Total running time of the script: (0 minutes 8.550 seconds)

Gallery generated by Sphinx-Gallery