Propagating thickness uncertainty#
Compare the effect of a specified substrate-thickness uncertainty with detector noise in a synthetic dispersive retrieval.
Inputs and method#
The script generates a 3 fs pulse at 300 nm through 100 µm of fused silica,
adds seeded detector noise, and retrieves at the central thickness from a 4 fs
Gaussian start with the lbfgs-ad solver. The fundamental spectrum is supplied
as a spectral-match target, as an independently measured spectrum would be in an
experiment; here it is the exact spectrum. The script then runs 40 thickness and
40 parametric replicates with fixed seeds and the same solver settings. The 128 fs
time window contains the ±45 fs delay scan and the dispersed pulse.
Run from a source checkout:
uv run python examples/example_thickness_uncertainty.py
Calculation and output#
The cell below loads and executes the runnable script itself. Expand it to inspect
the source, or download example_thickness_uncertainty.py.
Generated files are isolated in a temporary directory for this documentation run.
Base retrieval: R = 0.3544%, FWHM = 2.97 fs, edge energy = 8.3e-18
FWHM = 2.97 ± 0.01 fs (1σ from substrate thickness 100.000 ± 5.000 µm, systematic, B=40)
FWHM = 2.97 ± 0.00 fs (1σ statistical, parametric, B=40, warm-started; systematic uncertainty not included)
Total: FWHM = 2.965 ± 0.008 fs (stat ⊕ thickness; thickness 0.008 fs, stat 0.0017 fs)
Generating FWHM = 3.00 fs; compare bias with spread.
Wrote thickness_uncertainty.png
Interpretation and limits#
The base retrieval returns 2.97 fs for the generating 3.00 fs pulse. The thickness replicates lie on a smooth curve: the FWHM falls steadily as the assumed thickness grows, and the trace error is smallest at the true 100 µm. The thickness prior of 100 ± 5 µm adds ±0.008 fs to the FWHM, while the parametric bootstrap gives 0.0013 fs. The substrate term dominates the error budget by about a factor of six, the situation for thin deep-UV substrates that this example is modelled on. The statistical bootstrap alone would understate the uncertainty.
Why the spectrum and lbfgs-ad#
The grid spans twice the carrier frequency, so most trace rows contain only
noise. Without a spectral target, both lbfgs-ad and the default warm-lbfgs
reproduce that noise by putting about 3 % of the spectral energy into the
outermost frequency bins, where the trace carries no signal. Their trace error
then falls to about 0.31 %, below the 0.354 % of the true pulse, and the FWHM
lands anywhere from about 1.9 to 3.2 fs depending on the start and assumed
thickness. The thickness replicates then scatter between about 1 and 3.5 fs.
Supplying the spectrum switches on croak’s default spectral-match penalty
(reg_spectrum), which ties the retrieved amplitude to the measured band.
warm-lbfgs begins with a COPRA warm-up that has no spectral penalty; even with
the target it ends at 3.16 fs and a trace error of 0.350 %, slightly below that
of the true pulse. lbfgs-ad starts the penalised fit directly.
On your own retrievals, check croak.edge_energy_fraction(): a few per cent
indicates this failure. Supply the measured fundamental spectrum: pass
lam_spec/Ilam_spec to croak.load_and_clean(), and
croak.retrieve_from_tracedata() uses it as the target.
Running this on your own data#
A session saved from the GUI as options.toml already records the loader,
preprocessing and a dispersive retrieval, including the material and central
thickness. Set the uncertainty method to "thickness" with your measured 1σ and
replay it headlessly:
from dataclasses import replace
import croak
options = croak.SessionOptions.from_toml("options.toml")
options = options.with_(
uncertainty=replace(options.uncertainty, method="thickness", thickness_sigma_um=0.539)
)
session = croak.run_session(options, stages=("load", "preproc", "retrieve", "uncertainty"))
print(session.uncertainty.summary())
The central thickness is options.retrieve.thickness_um, and the retrieval must
be dispersive. To call croak.thickness_bootstrap() directly, pass it
session.result and session.tracedata.trace, with the material, quadrature
npoints and algorithm the retrieval used. In the GUI the same estimate is
stage 5 with method “thickness”. See saving and loading.
Limits#
The plot shows the duration’s conditional sensitivity to the assumed thickness
prior. Forty replicates demonstrate the method but are too few for precise tail
probabilities. The printed quadrature combination approximates independent,
roughly Gaussian contributions; for skewed distributions use
croak.uncertainty.combine_uncertainties() and assess dependence explicitly.
Residual-based noise can include model error. Neither the statistical spread nor
the combined value is automatically a calibrated experimental interval. Read
uncertainty methods and
their assumptions.