关于 fair-simulation-packager
FAIR Simulation Packager 是一款 Python 技能,用于为材料模拟结果创建可复现性清单。它盘点输入和输出文件、计算现存文件的哈希,并记录引擎、单位和结构标识,供研究人员及协作者使用。
主要功能
- 01生成模拟清单
- 02盘点输入与输出文件
- 03计算现存文件的 SHA-256
- 04记录引擎、单位和结构元数据
- 05提示缺失文件
适用场景
- 01整理模拟结果以供交接
- 02记录重新运行所需文件
- 03检查清单完整性
- 04找出缺失的模拟产物
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ heshamfs/ materials-simulation-skills --skill fair-simulation-packager安装后在 Claude Code 中输入/fair-simulation-packager确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdevals/evals.jsonevals/files/data.lmpin.lammpslog.lammpsOUTCARPOSCARreferences/fair_manifest.mdscripts/fair_packager.py详细介绍
FAIR Simulation Packager
目标
为材料模拟结果构建一个精简的可复现性清单,让其他人或 Agent 能够了解运行了什么、使用了哪些输入,以及应如何解读输出。
要求
- Python 3.10+
- 无外部依赖
- 可在 Linux、macOS 和 Windows 上运行
需要收集的输入
| 输入 | 说明 | 示例 |
|---|---|---|
| 项目名称 | 易于理解的打包名称 | al-cu-diffusion-study |
| 引擎 | 模拟代码 | LAMMPS、VASP、MOOSE |
| 输入文件 | 重运行所需的文件 | in.lammps,data.lmp |
| 输出文件 | 验证结果所需的文件 | log.lammps,traj.dump |
| 结构 ID | 数据库或本地标识符 | mp-149 |
| 单位 | 字段与单位的对应关系 | energy=eV,length=angstrom |
决策指南
- 始终包含输入文件、输出文件、代码版本和单位。
- 为本地存在的每个文件包含哈希值。
- 使用 Materials Project、NOMAD、OPTIMADE、CIF、POSCAR 或内部数据库记录时,包含结构标识符。
- 将缺失文件记录为警告,而不是静默忽略。
脚本输出
scripts/fair_packager.py --json 会打印一个包含两个顶层键的封装对象:
inputs:回显已解析的 CLI 参数(注意:inputs.inputs是通过--inputs传入的原始逗号分隔字符串,而不是逐个文件的记录)。results:包含单个键manifest。
results.manifest 包含以下字段:
project_name、engine、engine_version、structure_id、unitsfile_inventory,包含inputs和outputs,每项都是逐个文件的记录列表(path、exists;文件存在时还包含size_bytes和sha256)missing_files:磁盘上不存在的路径provenance(working_directory、manifest_schema)fair_checks:has_inputs、has_outputs、has_units、has_engine_version和has_hashes_for_existing_files(值为true/false;当不存在文件时为null,表示该检查不适用)recommended_next_steps
在 results.manifest.<field> 处解析字段。指定 --out PATH 时,写入 PATH 的只有裸 manifest 对象(不包含 inputs/results 封装)。
工作流
python3 skills/data-management/fair-simulation-packager/scripts/fair_packager.py \
--project-name al-cu-diffusion \
--engine LAMMPS \
--inputs in.lammps,data.lmp \
--outputs log.lammps,traj.dump \
--units energy=eV,length=angstrom,time=ps \
--structure-id local:alcu-cell-001 \
--json
仅当用户希望将清单写入文件时,才使用 --out manifest.json。
错误处理
缺失文件会报告在 missing_files 中(退出代码为 0)。无效输入会导致程序停止,退出代码为 2:单位条目格式错误、字段包含控制字符、字段长度超过 4096 个字符、输入或输出条目超过 1000 个,或文件大于 500 MB。请注意,普通文件路径(包括绝对路径和包含 .. 的路径)均可接受并会被列入清单;此工具仅读取文件内容以计算元数据和 SHA-256 哈希值。
限制
此技能会创建元数据清单,但不会将内容上传至 NOMAD、Materials Project 或 OPTIMADE 提供方。
验证清单
- 确认
fair_checks.has_hashes_for_existing_files为true(不是null或false);null表示磁盘上不存在任何列出的文件,因此在信任清单之前,请在文件实际所在的目录中重新运行。 - 检查
missing_files并确认其为空,或为每个条目记录明确原因——每个缺失路径都意味着某个输入/输出虽已列出,却未计算哈希,因此该包目前不可复现。 - 从
results.manifest.file_inventory中抽查至少一个sha256,并使用同一文件的独立sha256sum/Get-FileHash结果进行核对,以确认记录的摘要与磁盘上的文件内容相符。 - 确认
engine_version是真实版本字符串,而不是默认值"unknown";请传入--engine-version,以便该包记录准确的代码构建版本。 - 确认
units非空,且报告的每个量(能量、长度、时间等)都有对应条目,以免下游使用者不得不猜测单位制。 - 如果使用了 Materials Project / NOMAD / OPTIMADE / CIF / POSCAR 结构,请确认已填写
structure_id,以便恢复结构身份信息。 - 使用
--out PATH时,打开PATH并确认其中保存的是裸manifest对象(而不是inputs/results封装对象),且没有向工作目录之外的非预期路径写入文件。
常见误区与自我开脱
| 看似省事的做法 | 错在哪里/应该怎么做 |
|---|---|
| “程序以 0 退出,所以该包是完整的。” | 退出码 0 只表示没有验证错误;缺失文件会记录在 missing_files 中,且退出码仍为 0。在信任完整性之前,请检查 missing_files 和 fair_checks。 |
“has_hashes_for_existing_files 是 null,也差不多等于 true。” | null 表示 磁盘上不存在任何列出的文件——没有文件被计算哈希。请从正确的目录重新运行,以便找到文件并实际计算摘要。 |
“跳过 --engine-version 吧,记录引擎名称就够了。” | 脚本会将 engine_version 默认设为 "unknown",从而悄无声息地破坏可复现性。请务必传入具体的构建版本。 |
“从 JSON 解析 inputs.inputs,就能得到每个文件的记录。” | inputs.inputs 是原样回显的逗号分隔 CLI 字符串,并非记录。请从 results.manifest.file_inventory.inputs/outputs 中读取每个文件的数据。 |
| “清单记录了结构,因此整个运行都可复现。” | 此技能只会盘点文件、哈希、单位和 ID。它不会记录代码提交、容器摘要或解析器版本——请按照 recommended_next_steps 操作,并自行补充这些信息。 |
“绝对路径或 .. 会被拒绝,因此清单受到沙箱保护。” | 路径不受沙箱限制——绝对路径和含 .. 的路径都会按原样纳入清单,而且 --out 可以写入工作目录之外。请确认传入的路径符合预期。 |
安全性
输入验证
--project-name和--engine为必填项,去除空白字符后不得为空;若值为空,则程序以退出码 2 终止。--project-name、--engine、--structure-id(如果提供)以及每个文件路径都会检查控制字符(ord < 32)和 4096 个字符的最大长度;任一条件不满足都会导致程序以退出码 2 终止。--inputs和--outputs会按逗号拆分,每项最多允许 1000 个条目;超出数量限制会导致程序以退出码 2 终止。--units条目必须采用key=value格式;键和值都必须匹配允许列表^[A-Za-z0-9_.:/@+-]+$。缺少=或键/值不匹配都会导致程序以退出码 2 终止。- 没有数值输入,因此不会执行有限性/正值数值检查。
文件访问
- 脚本以 1 MB 为块读取每个现有输入/输出文件,以计算其
size_bytes和 SHA-256 哈希;不存在的文件会被记录,但不会读取。 - 大于 500 MB 的文件会导致脚本在计算哈希前以退出代码 2 停止。
- 除非指定
--out PATH,否则脚本不会写入任何文件;指定后,脚本会向该路径恰好写入一个文件(原始清单 JSON);否则所有输出都会写入标准输出。 - 路径不会受到沙箱限制:对于清点的文件和
--out,均接受绝对路径和包含..的路径。如果--out指向工作目录之外,文件会按要求写入该位置。
工具限制
- 使用
Bash运行随附的scripts/fair_packager.py。 - 声明了
Read、Write、Grep和Glob,以便该技能在指导用户时检查工作目录,并读取或写入清单/元数据文件;脚本本身不会调用这些工具,而是直接执行所有文件 I/O。
安全措施
- 不使用
eval、exec、os.system或subprocess调用;脚本不会调用外部 shell 命令,并使用argparse解析参数。 - 输出通过
json.dumps以 JSON 格式生成(未指定--json时则输出简短的纯文本摘要)。 - DoS 上限可限制资源使用:每个文件 500 MB,每个输入/输出列表 1000 个条目,每个字段 4096 个字符。
参考资料
- 建议的清单字段请参阅
references/fair_manifest.md。
版本历史
- 1.2.0:通过将脚本的精确
--json输出(每个文件的sha256/size_bytes、units、structure_id、engine_version、missing_files,以及三态字段has_hashes_for_existing_files)与已提交的evals/files/测试样例进行比对,使 eval 用例具有区分度。 - 1.1.0:记录实际的
--json封装格式;将has_hashes_for_existing_files改为三态(不存在文件时为null);添加条目数 (1000)和字段长度(4096)上限;修正错误处理和安全性说明,使其符合实际路径行为。 - 1.0.0:初始版 FAIR 模拟打包技能。
评论
支持 Markdown