uncertainty-and-units
Track physical units and propagate measurement uncertainty in scientific calculations using pint and uncertainties. Use for unit conversion and dimensional checking, GUM uncertainty budgets, Type A and Type B evaluation, coverage factors and expanded uncertainty, Monte Carlo propagation, significant
By k-dense-ai · 476 installs
npx skills add k-dense-ai/scientific-agent-skills --skill uncertainty-and-units
Source repository · Upstream listing
Uncertainty and units
Scope
Use this skill whenever a calculation carries physical units or a reported number needs
an uncertainty. Concretely:
converting between units, including conversions that need a physical context
(wavelength to photon energy, mass to amount of substance, energy to temperature);
propagating uncertainty through a measurement model, with or without correlated inputs;
building a GUM uncertainty budget from calibration certificates, specifications, and
repeatability data;
choosing a coverage factor and deciding whether k = 2 is defensible;
rounding and writing a result so a reader knows what the ± means;
extracting parameter uncertainties from a curve fit without discarding correlations;
reviewing existing analysis code for silent unit and uncertainty defects;
checking that a dimensionally consistent answer is also physically possible — the
order of magnitude, the dimensionless group, and the regime it implies.
This skill covers the metrology and the two libraries that implement it. It does not
cover statistical inference, model selection, or study design — see statistical analysis ,
statistical power , and experimental design .
Current release and installation
Verified 2026 10 01:
pint 0.26.1 , released 2026 09 10; requires Python 3.12+.
uncertainties 3.2.3 , released 2025 04 21; requires Python 3.8+.
NumPy 2.5.3 and SciPy 1.18.1 ; both require Python 3.12+.
scipy.constants in SciPy 1.18.1 serves CODATA 2022 . SciPy 1.11 and earlier
served CODATA 2018; the switch to CODATA 2022 occurred in SciPy 1.15.
pint pandas and pint xarray add unit aware columns and arrays and are separate
installs.
Non negotiable workflow
1. Attach units at input and strip them only at output. Convert at function
boundaries with ureg.wraps or m as("unit") , never mid calculation.
2. Write the measurement model explicitly before computing anything, including
corrections whose estimated value is zero. A correction left out of the model leaves
its uncertainty out of the budget.
3. Give every input four things : an estimate, a standard uncertainty, the
distribution the uncertainty came from, and its degrees of freedom.
4. Convert Type B statements with the right divisor. A certificate's expanded
uncertainty divides by its stated k ; rectangular limits divide by sqrt(3) .
5. Identify correlations before combining. A shared calibration, instrument correction, or fit can induce correlation;
quantify shared components instead of assuming every pair is correlated.
6. Compute sensitivity coefficients , and read the budget from c i u(x i) rather
than from the raw uncertainties.
7. Check the linearization. Compare propagated distributions with the GUM interval when in doubt.
Establish Monte Carlo numerical stability before a JCGM 101 clause 8 claim;
neither method validates the measurement model or the assigned input PDFs.
8. Justify coverage. A Student t factor from effective degrees of freedom
is an approximation requiring suitable distributional assumptions.
9. Round the uncertainty first, then the value to the same decimal place.
10. State what the ± is — standard or expanded, with k , the coverage probability,
and the method.
11. Sanity check the magnitude before reporting. A dimensionally consistent result can
still be impossible. Compare it against a known scale or a dimensionless group, and
confirm every assumption you relied on still holds in that regime.
The failures this skill exists to prevent
Each of the following runs without error and produces a plausible number.
A unit stripped at an unknown scale
.magnitude returns whatever the quantity happened to be carrying. Name the unit at the
point of extraction, every time.
Offset temperature arithmetic
Celsius and Fahrenheit are interval scales. An uncertainty on a temperature is always a
difference and belongs in a delta unit: converting 20 ± 0.5 degC to Fahrenheit
gives 68 degF ± 0.9 delta degF , two different conversions on one line.
Logarithmic units that add by multiplying
That is 10 mW × 10 mW, not 20 mW and not 13 dBm. Nothing raises. Convert to a linear
unit before any arithmetic.
A correlation destroyed by a round trip
Rebuilding a variable from its nominal value and standard deviation creates an
independent variable. So does any serialization that passes through a pair of floats.
Use correlated values(values, covariance matrix) to rebuild a correlated set.
A covariance matrix silently rescaled
The default rescales pcov by the reduced chi square. Relative weights from sigma still affect the fit and covariance: equality with an unweighted fit holds for constant sigma , not generally for heteroscedastic inputs. On
one synthetic straight line fit the two give [0.0364, 0.2154] and [0.0477, 0.2820] —
a 31% difference. Pass absolute sigma=True whenever sigma holds real standard
uncertainties.
A linearization that was never checked
For y = x² with x = 1.0 ± 0.5 , the GUM framework gives y = 1.0 , u c = 1.0 , and a
95% interval of [ 0.96, 2.96] — mostly negative, for a squared quantity. Monte Carlo
gives a mean of 1.25, u c = 1.06 , and a shortest 95% interval of [0, 3.32] . Nothing
in a linear propagation library will tell you this happened.
Bundled local CLIs
All helpers run offline, reject URLs and symlinks, bound their inputs, write output
atomically with private permissions, and refuse to overwrite without force .
propagate uncertainty.py
Runs both propagation methods on the same numerical model and compares interval
endpoints. This fixed trial diagnostic does not implement the adaptive stabilization
in JCGM 101 7.9/8.2 and never labels the GUM result fully validated.
Each variable is name=value,standard uncertainty[,distribution[,dof]] , where the
distribution is normal , rectangular , triangular , arcsine , or exact and controls
Monte Carlo sampling only. Here mass is in g and lengths in cm: unit is
a report label, not dimensional validation or conversion. JSON variable units are
also labels; convert inputs to a consistent numerical model first. Correlations go in as correlation "a,b=0.9" . A JSON
spec file holds the same model for anything long lived.
The joint normal sampler supports positive semidefinite correlation matrices, including
perfect correlations. Other joint distributions need a separate sampler. Correlated
finite dof inputs are refused because independent input Welch Satterthwaite is invalid.
For independent finite dof inputs the CLI's MC PDFs remain fixed: dof affects the
GUM factor only, not MC sampling. A small sample t input needs a separate justified model.
The expression is parsed into an abstract syntax tree and reduced by an explicit walk
over + / and a fixed list of functions. It is never compiled or executed.
The report gives the estimate, u c , sensitivity coefficients, the budget in percent,
effective degrees of freedom, k , U , both Monte Carlo coverage intervals, and the
endpoint agreement diagnostic. Repeat/increase sampling and verify model/PDF
assumptions before deciding what to report.
uncertainty budget.py
Combines components stated the way certificates and data sheets state them.
Each component names a distribution that fixes its divisor — expanded divides by its
coverage factor , rectangular by sqrt(3) , triangular by sqrt(6) , arcsine by
sqrt(2) , normal by 1 — with an optional sensitivity , dof , and relative: true .
The tool assumes independent components, requires an explicit factor for expanded ,
and rejects nonzero exact components. It computes u c , effective degrees of freedom, k from
the t distribution, and U , and warns when a Type A component has no degrees of
freedom, when nu eff is small enough that k = 2 is wrong, when one component
dominates, and when a Type B component declared normal is probably an undivided
expanded uncertainty.
format result.py
Returns 12.346 ± 0.023 mm , 12.346(23) mm , the scientific and LaTeX forms, and the
sentence that has to accompany the number. Warns when one significant digit is requested
for an uncertainty beginning in 1 or 2, and when the uncertainty exceeds the estimate.
convert units.py
Carries the uncertainty through the conversion's local derivative. Some contexts
(such as wavelength to energy) are reciprocal, whereas others are proportional.
Context parameters ( mw , n ) are treated as exact; their uncertainties need an
explicit measurement model. Offset temperature uncertainty units are differences. Names the context in the
error message when a conversion needs one, and flags offset and logarithmic units.
list contexts shows what the registry defines.
audit units.py
Static review of existing analysis code. Parses, never imports or runs.
Rule Severity Detects
UNIT001 medium a second UnitRegistry in one module — cross registry ValueError
UNIT002 medium offset temperature units with no delta unit anywhere
UNIT003 high .magnitude without a preceding .to(...) or .m as(...)
UNIT004 medium logarithmic units, whose + multiplies
UNC001 high curve fit without absolute sigma
UNC002 medium np.std / np.var without ddof or NumPy's correction alias
UNC003 medium math or numpy functions in a module that uses uncertainties
UNC004 high a ufloat rebuilt from .nominal value and .std dev
CONST001 low a literal within 0.1% of a CODATA constant
Exit status is 1 when a finding meets fail on (default high ), which makes it usable
as a pre commit or CI check.
The rules are heuristics, so a false positive is suppressed with a directive comment —
trailing to cover its own line, or alone on a line to cover the next one:
audit units: ignore file CONST001 covers a whole module, and naming no rule
suppresses all of them. Suppressions are counted in the report rather than hidden, so a
file that silences everything still says so.
check plausibility.py
Dimensional consistency is not physical possibility. A cell 2 m across and a Reynolds
number of 4e7 in a capillary both pass every unit check. This tool tests a set of
quantities against dimensionless groups, characteristic scales, and illustrative typical value
bands, and verifies each formula's dimensionality before reporting a number.
group evaluates one of 14 dimensionless groups and names the regime it places the
system in; scale computes a characteristic scale such as a diffusion time, Debye
length, or Stokes settling velocity; band compares a supplied quantity against an
observed range. list prints the whole catalogue with the inputs each formula needs.
Physical constants ( k B , N A , R gas , g earth , and the rest) are available to every
formula without being supplied. Their nominal values come from scipy.constants ;
this plausibility helper does not propagate their uncertainties. g earth is standard
gravity, not a local measurement. Bands are screening heuristics, not physical limits.
The dimensionality check is the point. Passing a kinematic viscosity where the formula
needs a dynamic one — both called "viscosity", both tabulated for water, differing by a
factor of ρ — is refused before any number is computed:
Exit status is 1 when the verdict meets fail on (default implausible ; a value
within one decade of a band is questionable ). The thresholds are conventions with soft
edges and assume the geometry their correlation was fitted for — see
references/plausibility scales.md for the characteristic length to use in each case.
Choosing a propagation method
Situation Method
Linear or near linear model, normal ish inputs, large dof GUM framework alone
Any nonlinear