Back to Claude Scientific Skills

Domain conversions and dimensional blind spots

skills/uncertainty-and-units/references/domain-conversions.md

2.57.08.4 KB
Original Source

Domain conversions and dimensional blind spots

Values below were produced with pint 0.25.3 and SciPy 1.18.0 (CODATA 2022). Anything marked exact is fixed by definition and carries zero uncertainty.

Dimensional analysis does not catch these

Two quantities with the same dimensions convert freely, whether or not the conversion means anything.

PairShared dimensionWhat pint doesWhy it matters
gray and sievertL²T⁻²converts 1:1, silentlySv includes a radiation weighting factor; the numbers coincide only for photons and electrons
newton-metre and jouleML²T⁻²converts 1:1, silentlytorque is a vector product, energy a scalar; adding them is meaningless
hertz and becquerelT⁻¹converts 1:1, silentlyone is periodic, the other stochastic
radian and dimensionlessnoneradians vanishsin(x) needs radians; a degrees value that lost its unit is silently wrong
mol/L and mol/kgdifferentraisesmolarity and molality are genuinely different quantities
mg/L and ppmdifferentraisesequal only for dilute aqueous solutions near 1 g/mL

The last two raise because they are dimensionally distinct. The first four are the dangerous ones: no tool will warn you.

Energy ladder

Molecular science quotes the same energy in at least six units, three of which are per-mole and therefore need the Avogadro constant.

FromToFactor
1 eVkJ/mol96.48533212331002
1 hartreeeV27.21138624598103
1 hartreekcal/mol627.5094740628942
1 cm⁻¹eV1.2398419843320026e-4
1 cm⁻¹K (as E/k_B)1.4387768775039336
k_B T at 298.15 KeV0.02569257912108585
k_B T at 298.15 KkJ/mol2.478957029602389
1 cal (thermochemical)J4.184 (exact)
1 cal_ITJ4.1868 (exact)

Two traps. First, per-mole and per-particle units are not dimensionally interchangeable: eV is an energy, kJ/mol is an energy per amount of substance, and the conversion needs N_A. Pint will refuse Q(1, "eV").to("kJ/mol") and accept Q(1, "eV * N_A").to("kJ/mol"). Second, there are two calories and a factor of 1.00067 between them; thermochemical is the default in chemistry, IT in engineering.

python
Q(1, "eV * N_A").to("kJ/mol")            # 96.48533212331002 kilojoule / mole
Q(1, "1/cm").to("eV", "sp")              # 0.00012398419843320026 electron_volt
Q(298.15, "K").to("eV", "boltzmann")     # 0.02569257912108585 electron_volt

Spectroscopy

Wavelength, frequency, wavenumber, and photon energy are related by physics, not by dimensional analysis, and the relations are reciprocal — an uncertainty does not convert by the same factor as the value.

python
Q(532, "nm").to("THz", "sp")     # 563.5196578947367 terahertz
Q(532, "nm").to("1/cm", "sp")    # 18796.992481203004 / centimeter
Q(532, "nm").to("eV", "sp")      # 2.3305300457368467 electron_volt

Because E = hc/λ, a constant wavelength uncertainty becomes an energy uncertainty that scales as 1/λ². Propagate through the relation, do not scale the uncertainty by the value's conversion factor. scripts/convert_units.py --uncertainty does this with the conversion's local derivative.

The sp context assumes vacuum unless given a refractive index: n=1.33 for water shifts a 532 nm frequency from 563.5 THz to 423.7 THz.

Concentration

QuantityUnitDepends on
Molaritymol/Ltemperature, through solution volume
Molalitymol/kg solventnothing — preferred for thermodynamics
Mole fractiondimensionlessnothing
Mass fraction, ppm(m/m)dimensionlessnothing
Volume fraction, ppm(v/v)dimensionlesstemperature
Mass concentrationmg/L, g/Ltemperature

"ppm" alone is ambiguous: mass/mass, volume/volume, and mol/mol differ by the ratio of densities or molar masses. In environmental water chemistry ppm conventionally means mg/L, which equals mg/kg only because dilute water is close to 1 kg/L. In gas analysis it conventionally means volume/volume. State which.

Pint treats ppm and percent as plain dimensionless scale factors (1e-6 and 0.01), which is right for arithmetic and gives no protection against mixing the three senses. Defining ureg.define("ppm_v = 1e-6 = ppmv") as a distinct unit does give protection.

Mass and amount of substance need the chemistry context and a molar mass:

python
Q(1, "g").to("mol", "chemistry", mw=Q(180.156, "g/mol"))   # 0.005550744909966918 mole

Pressure

FromTo PaNote
1 atm101325exact
1 bar100000exact
1 torr133.32236842105263atm/760, exact by definition
1 psi6894.7572931683635
1 mmHg133.322387415not identical to torr, differs in the 8th digit

Gauge and absolute pressure are different quantities and no unit library models the difference. "psig" and "psia" have the same dimensions; a gauge reading needs the ambient pressure added before it can be used in a gas law. Vacuum work, autoclave protocols, and chromatography backpressures are where this bites.

Radiation, magnetism, rotation

python
Q(1, "Ci").to("Bq")               # 37000000000.0 becquerel   (exact by definition)
Q(1, "gauss").to("T", "Gaussian") # 9.999999999338245e-05 tesla
Q(1, "rpm").to("rad/s")           # 0.10471975511965977 radian / second

Gauss fails without the Gaussian context: CGS electromagnetic units have different dimensions from SI ones, not merely different scales. Magnetic field strength H (A/m, oersted) and magnetic flux density B (T, gauss) are distinct quantities that literature routinely calls "the field".

Mass spectrometry

The unified atomic mass unit and the dalton are the same thing: 1 Da = 1.66053906892e-27 kg (CODATA 2022, relative standard uncertainty 3.1e-10).

m/z is conventionally reported as a dimensionless number: the ratio of mass in daltons to charge number. The thomson (Th) exists but is not SI and is rarely used. Treating m/z as a mass is wrong for any ion with z > 1, which is most of a protein spectrum.

Logarithmic quantities

pH, pKa, dB, and magnitudes are logarithms of ratios. They do not add, average, or propagate like ordinary quantities:

  • the mean of pH 5 and pH 7 is not pH 6 — averaging requires converting to concentration, averaging, and converting back;
  • a standard deviation in pH units is a relative standard deviation in concentration;
  • adding two dB quantities multiplies the underlying linear quantities (see pint-recipes.md);
  • decibel scales differ by reference: dBm references 1 mW, dBW references 1 W, dBV references 1 V, and dB alone references nothing until you say so.

Temperature

Kelvin and rankine are ratio scales and behave normally. Celsius and Fahrenheit are interval scales: 20 degC is not "twice" 10 degC, and their differences live in delta_degC / delta_degF. See pint-recipes.md for what pint permits.

Absolute zero is exactly 273.15 K below 0 degC — scipy.constants.zero_Celsius.

Constants: which values, and which uncertainties

The 2019 SI redefinition fixed several constants exactly, so their relative standard uncertainty is zero and no future CODATA release will change them:

ConstantExact value
speed of light in vacuum, c299792458 m/s
Planck constant, h6.62607015e-34 J/Hz
elementary charge, e1.602176634e-19 C
Boltzmann constant, k1.380649e-23 J/K
Avogadro constant, N_A6.02214076e23 /mol

Everything else is a measured recommended value that moves between CODATA releases — electron mass, the gravitational constant, the fine-structure constant, the Rydberg constant, and every derived quantity built from them.

python
import scipy.constants as constants

constants.value("electron mass")       # 9.1093837139e-31
constants.unit("electron mass")        # kg
constants.precision("electron mass")   # 3.07e-10  relative standard uncertainty
constants.precision("Planck constant") # 0.0       exact by definition

scipy.constants in SciPy 1.18.0 defaults to CODATA 2022; SciPy 1.11 and earlier served CODATA 2018. Hard-coding a constant pins you to whichever release you copied it from and discards its uncertainty entirely. scripts/audit_units.py flags literals that match a known constant (CONST001).

Note also that constants.precision returns a relative standard uncertainty. The absolute standard uncertainty is value * precision.