mcpField
U
uncertainty-and-units

uncertainty-and-units

github.com/kalarislabs数据与数据库7745 次安装4 天前更新
代码仓库

关于 uncertainty-and-units

uncertainty-and-units 是面向科学计算与测量分析的技能,帮助研究人员处理单位换算、不确定度传播和结果报告。它附带离线命令行工具,可审查分析代码并检查结果的合理性。

主要功能

  1. 01物理单位换算与上下文转换
  2. 02GUM 不确定度预算
  3. 03GUM 与蒙特卡洛传播比较
  4. 04结果格式化与有效位数处理
  5. 05静态审查单位及不确定度问题
  6. 06量纲与物理合理性检查

适用场景

  1. 01为测量模型计算不确定度
  2. 02从校准证书构建不确定度预算
  3. 03审查拟合协方差及单位处理代码
  4. 04检查计算结果的量级与物理可能性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill uncertainty-and-units

安装后在 Claude Code 中输入/uncertainty-and-units确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
domain-conversions.md
gum-methodology.md
pint-recipes.md
plausibility-scales.md
reporting-rules.md
uncertainties-recipes.md
scripts/
_common.py
audit_units.py
check_plausibility.py
convert_units.py
format_result.py
propagate_uncertainty.py
uncertainty_budget.py

详细介绍

不确定度与单位

范围

只要计算涉及物理单位,或报告的数值需要附带不确定度,就使用此技能。具体包括:

  • 单位换算,包括需要物理背景的换算(波长到光子能量、质量到物质的量、能量到温度);
  • 通过测量模型传播不确定度,无论输入是否相关;
  • 根据校准证书、规格和重复性数据编制 GUM 不确定度预算;
  • 选择覆盖因子,并判断 k = 2 是否合理;
  • 对结果进行舍入和表述,让读者清楚 ± 的含义;
  • 从曲线拟合中提取参数不确定度,同时保留相关性;
  • 检查现有分析代码中是否存在隐蔽的单位和不确定度缺陷;
  • 检查量纲一致的答案在物理上是否也可能成立——包括数量级、无量纲群及其所指示的状态范围。

此技能涵盖计量学及用于实现计量学的两个库。不涵盖统计推断、模型选择或研究设计——请参阅 statistical-analysis、statistical-power 和 experimental-design。

当前版本与安装

已于 2026-07-26 验证:

  • pint 0.25.3,于 2026-03-19 发布;需要 Python 3.11+。
  • uncertainties 3.2.3,于 2025-04-21 发布;需要 Python 3.8+。
  • NumPy 2.5.1 和 SciPy 1.18.0;两者都需要 Python 3.12+。
  • SciPy 1.18.0 中的 scipy.constants 使用 CODATA 2022。SciPy 1.11 及更早版本使用的是 CODATA 2018,两者有若干推荐值不同。
uv venv --python 3.13
source .venv/bin/activate
uv pip install "pint==0.25.3" "uncertainties==3.2.3" "numpy==2.5.1" "scipy==1.18.0"

pint-pandas 和 pint-xarray 可添加带单位的列和数组,需单独安装。

不可妥协的工作流程

  1. 在输入时附加单位,只在输出时移除单位。 在函数边界处使用 ureg.wraps 或 m_as("unit") 进行转换,切勿在计算过程中途转换。
  2. 在进行任何计算前明确写出测量模型,包括估计值为零的修正量。模型中遗漏的修正量,其不确定度也会从预算中遗漏。
  3. 为每个输入提供四项内容:估计值、标准不确定度、不确定度所依据的分布,以及自由度。
  4. 用正确的除数换算 B 类说明。 证书中的扩展不确定度应除以其标明的 k;矩形分布的限值应除以 sqrt(3)。
  5. 合成前识别相关性。 通过同一标准校准、使用同一仪器测量或来自同一拟合的数据,彼此相关。
  6. 计算灵敏度系数,并根据 c_i * u(x_i) 而非原始不确定度读取预算。
  7. 检查线性化。 在 GUM 框架分析的同时运行蒙特卡洛,并依据 JCGM 101 第 8 条进行比较。若不符合要求,则报告蒙特卡洛结果。
  8. 根据有效自由度选择 k,不要凭习惯选择。
  9. 先舍入不确定度,再将数值舍入到相同的小数位。
  10. 说明 ± 的含义——是标准不确定度还是扩展不确定度,并注明 k、覆盖概率和方法。
  11. 报告前检查数量级是否合理。 量纲一致的结果仍可能不可能成立。将其与已知尺度或无量纲群比较,并确认所依赖的每项假设在该状态范围内仍然成立。

此技能旨在防止的问题

以下每种情况都能正常运行,并产生看似合理的数值。

单位被移除时尺度不明确
length = (12.7 * ureg.mm).magnitude          # 12.7 -- of what?
length = (12.7 * ureg.mm).m_as("m")          # 0.0127 metres, stated

.magnitude 返回的是该数量当时所带的数值。每次提取时都要明确指定单位。

偏移温标的运算
Q(20, "degC") + Q(5, "degC")     # OffsetUnitCalculusError -- correctly refused
Q(20, "degC") + Q(5, "delta_degC")   # 25 degree_Celsius
Q(25, "degC") - Q(20, "degC")        # 5 delta_degree_Celsius

摄氏度和华氏度是区间尺度。温度的不确定度始终是差值,必须使用 delta_ 单位:将 20 ± 0.5 degC 转换为华氏度,结果为 68 degF ± 0.9 delta_degF;同一行中进行了两种不同的换算。

可通过乘法相加的对数单位
Q(10, "dBm") + Q(10, "dBm")   # 0.0001 kilogram**2 * meter**4 / second**6

这是 10 mW × 10 mW,不是 20 mW,也不是 13 dBm。没有任何量被提升。进行任何算术运算前,先转换为线性单位。

往返转换破坏了相关性
x = ufloat(1.0, 0.1)
x - x                                     # 0.0+/-0
x - ufloat(x.nominal_value, x.std_dev)    # 0.00+/-0.14

根据变量的标称值和标准差重建变量,会得到一个独立变量。任何经由一对浮点数进行的序列化也会如此。使用 correlated_values(values, covariance_matrix) 重建相关变量集。

协方差矩阵被静默缩放
popt, pcov = curve_fit(f, x, y, sigma=sigma)                        # default
popt, pcov = curve_fit(f, x, y, sigma=sigma, absolute_sigma=True)

默认设置会根据缩减卡方对 pcov 进行缩放,因此参数不确定度会吸收拟合优度的影响,并与完全不传入 sigma 时的结果一致。在一次合成直线拟合中,两者分别得到 [0.0364, 0.2154] 和 [0.0477, 0.2820],相差 31%。只要 sigma 中包含真实的标准不确定度,就传入 absolute_sigma=True。

从未验证过的线性化

对于 y = x² 且 x = 1.0 ± 0.5,GUM 框架给出的结果为 y = 1.0、u_c = 1.0,95% 区间为 [-0.96, 2.96]——对于平方量来说,大部分区间都为负值。蒙特卡洛方法得到的均值为 1.25、u_c = 1.06,最短 95% 区间为 [0, 3.32]。线性传播库不会告诉你发生了这种情况。

随附的本地 CLI

所有辅助工具均可离线运行,会拒绝 URL 和符号链接、限制输入大小、以私有权限原子写入输出,并且不会在没有 --force 的情况下覆盖文件。

python skills/uncertainty-and-units/scripts/propagate_uncertainty.py --help
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --help
python skills/uncertainty-and-units/scripts/format_result.py --help
python skills/uncertainty-and-units/scripts/convert_units.py --help
python skills/uncertainty-and-units/scripts/audit_units.py --help
python skills/uncertainty-and-units/scripts/check_plausibility.py --help
propagate_uncertainty.py

对同一模型运行两种传播方法,并应用 JCGM 101 第 8 条验证测试。

python skills/uncertainty-and-units/scripts/propagate_uncertainty.py \
  --expression "m / (pi * (d / 2) ** 2 * h)" \
  --variable "m=250.0,0.05" \
  --variable "d=20.0,0.02,rectangular" \
  --variable "h=40.0,0.05,rectangular" \
  --measurand density --unit "g/cm3" --format markdown

每个 --variable 的格式为 name=value,standard_uncertainty[,distribution[,dof]],其中分布为 normal、rectangular、triangular、arcsine 或 exact,仅用于控制蒙特卡洛采样。相关性通过 --correlation "a,b=0.9" 输入。较长期使用的模型可保存在 JSON --spec 文件中。

表达式会被解析为抽象语法树,并通过显式遍历处理 + - * / ** 和固定的函数列表。它绝不会被编译或执行。

报告会给出估计值、u_c、灵敏度系数、以百分比表示的不确定度预算、有效自由度、k、U、两个蒙特卡洛覆盖区间,以及线性化结果是否可以报告的判定。

uncertainty_budget.py

合并按证书和数据表惯用方式给出的分量。

python skills/uncertainty-and-units/scripts/uncertainty_budget.py --template > budget.json
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --spec budget.json --format markdown

每个分量都要指定一个 distribution,以确定其除数:expanded 除以其 coverage_factor,rectangular 除以 sqrt(3),triangular 除以 sqrt(6),arcsine 除以 sqrt(2),normal 除以 1;还可选填 sensitivity、dof 和 relative: true。该工具会计算 u_c、Welch-Satterthwaite 有效自由度、基于 t 分布的 k 以及 U;当 A 类分量缺少自由度、nu_eff 太小而导致 k = 2 不适用、某个分量占主导,或声明为 normal 的 B 类分量很可能是尚未除算的扩展不确定度时,会发出警告。

format_result.py
python skills/uncertainty-and-units/scripts/format_result.py \
  --value 12.34567 --uncertainty 0.02345 --unit mm \
  --coverage-factor 2.26 --coverage-probability 0.95

返回 12.346 ± 0.023 mm、12.346(23) mm、科学计数法和 LaTeX 格式,以及必须随数值一同给出的句子。当请求的不确定度只有一位有效数字且首位为 1 或 2,或不确定度超过估计值时,会发出警告。

convert_units.py
python skills/uncertainty-and-units/scripts/convert_units.py \
  --value 532 --unit nm --to eV --context spectroscopy --uncertainty 0.5

python skills/uncertainty-and-units/scripts/convert_units.py \
  --value 1.0 --unit g --to mol --context chemistry --context-parameter "mw=180.156 g/mol"

通过转换的局部导数传递不确定度;这很重要,因为上下文转换是倒数关系,而非比例关系。当转换需要上下文时,错误消息会指出上下文名称,并标记带偏移量和对数单位。--list-contexts 会显示注册表中定义的上下文。

audit_units.py

对现有分析代码进行静态审查。只解析,不导入或运行。

python skills/uncertainty-and-units/scripts/audit_units.py \
  --input analysis.py --format markdown --fail-on medium
规则严重性检测内容
UNIT001中一个模块中出现第二个 UnitRegistry——可能导致跨注册表 ValueError
UNIT002中存在偏移温度单位,但任何位置都没有 delta_ 单位
UNIT003高使用 .magnitude 前没有先调用 .to(...) 或 .m_as(...)
UNIT004中对数单位,其 + 运算实际执行乘法
UNC001高使用 curve_fit 时未指定 absolute_sigma
UNC002中使用 np.std / np.var 时未指定 ddof
UNC003中使用 uncertainties 的模块中调用了 math 或 numpy 函数
UNC004高使用 .nominal_value 和 .std_dev 重新构造 ufloat
CONST001低字面值与 CODATA 常数相差不超过 0.1%

当发现项达到 --fail-on(默认为 high)时,退出状态为 1,因此可用作 提交前检查或 CI 检查。

这些规则采用启发式方法,因此可通过指令注释抑制误报——注释放在行尾时覆盖该行, 单独占一行时覆盖下一行:

value = quantity.magnitude  # audit-units: ignore UNIT003 -- already converted upstream

# audit-units: ignore UNC003 -- the argument here is a plain float array
scaled = np.log10(counts)

# audit-units: ignore-file CONST001 可覆盖整个模块;不指定规则名称 则会抑制所有规则。抑制项会计入报告,而非隐藏,因此即使某个文件抑制了所有规则, 报告也会明确指出这一点。

check_plausibility.py

量纲一致并不代表物理上合理。宽 2 m 的单元格和毛细管中 4e7 的雷诺数都能通过所有单位检查。此工具将一组量与无量纲群、特征尺度和整理过的数量级范围进行比较,并在报告数值前验证每个公式的量纲。

python skills/uncertainty-and-units/scripts/check_plausibility.py \
  --quantity "density=1060 kg/m**3" --quantity "velocity=0.5 mm/s" \
  --quantity "length=8 um" --quantity "viscosity=3.5 mPa*s" \
  --group reynolds --format markdown
# Re = 0.001211 -- laminar (circular pipe, length = diameter)

python skills/uncertainty-and-units/scripts/check_plausibility.py \
  --quantity "diameter=2 m" --band "eukaryotic_cell_diameter=diameter"
# implausible: 4.3 decades outside the 5-100 um range

--group 用于计算 14 个无量纲群之一,并指出系统所处的状态区间;--scale 用于计算特征尺度,例如扩散时间、德拜长度或斯托克斯沉降速度;--band 用于将给定量与观测范围进行比较。--list 会打印完整目录以及每个公式所需的输入。

所有公式都可直接使用物理常数(k_B、N_A、R_gas、g_earth 等),无需提供;这些常数在运行时从 scipy.constants 读取,而非写成字面值,因此会随 SciPy 附带的 CODATA 版本更新。

量纲检查才是重点。如果公式需要动力黏度,却传入运动黏度——两者都称为“黏度”,都列于水的参数表中,且相差因子 ρ——工具会在计算任何数值前拒绝:

error: viscosity must have dimensionality [mass] / ([length] * [time]),
       but m²/s is [length] ** 2 / [time]

当判定达到 --fail-on(默认为 implausible)时,退出状态为 1;落在范围一个数量级以内的值会被判为 questionable。这些阈值是带有模糊边界的约定,并假设几何形状与拟合相关式时一致——每种情况应使用的特征长度,请参阅 references/plausibility-scales.md。

选择传播方法

情况方法
线性或近线性模型、输入近似正态且自由度较大仅使用 GUM 框架
输入在 ±2u 范围内存在任何非线性两种方法都运行,并应用第 8 条检验
任一输入的相对不确定度超过约 20%蒙特卡洛
矩形分布或其他非正态分量占主导蒙特卡洛
输出有下界(方差、浓度、平方量)蒙特卡洛
输出分布不对称蒙特卡洛,使用最短覆盖区间
输入相关两者皆可,但需提供协方差矩阵,而非仅提供标准不确定度

即使模型完全线性,只要矩形分布贡献占主导,就无法通过第 8 条检验:框架中的 k = 1.96 会对近似梯形的输出覆盖过宽。 估计值和 u_c 仍然正确;只有区间过宽。

常量

切勿凭记忆输入常量。2019 年 SI 重新定义精确固定了 c、h、e、k 和 N_A,因此它们的相对标准不确定度为零;其他所有值都是测量值,会随 CODATA 版本更新而变化。

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

precision 返回的是相对标准不确定度;乘以数值即可得到绝对标准不确定度。

参考文件

  • references/gum-methodology.md — A 类和 B 类评定、分布除数、传播定律、Welch-Satterthwaite 方法、框架失效的情况、蒙特卡洛程序,以及第 8 条验证测试。
  • references/pint-recipes.md — 注册表、偏移单位和对数单位、上下文、使用 wraps 和 check 强制边界、NumPy 互操作、自定义单位、格式化。
  • references/uncertainties-recipes.md — 变量标识和相关性、correlated_values、umath 和 unumpy、格式规范、拟合协方差矩阵,以及该软件包的局限。
  • references/domain-conversions.md — 能量阶梯、光谱学、浓度、压力、辐射和磁学、质谱、对数量,以及维度相同但含义不同的量对。
  • references/reporting-rules.md — 舍入、表示法、结果必须附带的句子、图表中的 SD、SEM 与 CI、未检出值,以及符合性判定规则。
  • references/plausibility-scales.md — 特征长度的选择、无量纲组合及其各自约束的建模假设、特征尺度、观测量级范围及其来源,以及每个阈值的注意事项。

有日期的来源

核查日期:2026-07-26:

相关技能

  • astropy:用于天文学和天体物理工作流的核心 Python 库,支持 Astropy API,包括单位/量、坐标、FITS I/O、表格……

评论

支持 Markdown