参考谱不该锁在一家手里 — MassBank 质谱谱库联盟

十三万条谱 / 两万化合物 / 61 个贡献方代码

来源 https://massbank.eu/MassBank/发布时间: 2026-10-27最后更新: 2026-10-27 阅读 19
参考谱不该锁在一家手里 — MassBank 质谱谱库联盟

信息速览

数据集名称参考谱不该锁在一家手里 — MassBank 质谱谱库联盟
数据类型元数据,本体映射,文献引用,补充材料
规模不适用(参考谱记录,一行对应一张谱而非一个人)
接入方式https://massbank.eu/MassBank/
AI 就绪度

小分子鉴定的起点往往很朴素:手上有一张 MS/MS 谱,想知道它是什么。算法能做的只是把这张谱和已知的谱摆在一起比高低,而"已知的谱"不会自己长出来——它得有人拿标准品上机、调好碰撞能、把峰表记下来,并且愿意公开。参考谱库的价值不在算法多聪明,而在有没有人愿意把自己的测量结果交出来。

这些谱过去散在论文补充材料、实验室硬盘和厂商的封闭谱库里。MassBank 的做法是把每条谱压成一个纯文本记录:谁贡献、谁署名、用哪种许可,全写在记录里;再由多个门户把同一批记录聚起来,对外提供检索与接口。它 2006 年起于日本,2010 年的论文给出第一份公开快照,欧洲节点后来交由德国 UFZ 托管,两个门户现在跑的是同一套软件。

代价同样明确:它是一个参考谱登记处,不是训练集。规模靠一家一家实验室攒,碰撞能、仪器、元数据完整度都不齐,同一种化合物还会有很多条记录。一屏速览见下表。

维度 内容
全名 MassBank(Mass Spectral DataBase)
定位 面向小分子鉴定的开放质谱参考谱库,分布式贡献、集中检索
发起时间 2006 年起于日本,官方门户现不重复标注建站日期
代表论文 Horai et al., J Mass Spectrom, 2010, 45(7):703–714
数据版本 2025.10(元数据时间戳 2025-10-24)
门户软件版本 v2025.12.1(欧洲与日本两个门户同一版本)
谱记录数 元数据接口 134,756 条;记录计数接口 139,006 条
化合物数 20,549 种(官方元数据接口)
贡献方代码 61 个(官方筛选器列出)
仪器类型 52 种(官方筛选器列出)
谱层级 MS、MS2、MS3、MS4、MSn 五档,MS2 为主
离子极性 POSITIVE 与 NEGATIVE 两种
记录格式 MassBank record 纯文本,规范 2.6.0(2022-05-13)
记录结尾 固定 //,记录之间可直接拼接成一个大文件
许可 逐条声明,CC0 / CC BY / CC BY-NC / CC BY-NC-SA / CC BY-SA
获取方式 两个门户的网页检索、REST 接口、GitHub 仓库、Zenodo 快照

§1 它要解决的具体麻烦

1.1 参考谱的真正成本在测量,不在存储

一张高分辨 MS/MS 谱的信息密度很低:几十到几百个峰,每个峰只有质荷比和强度两个数。存下来占不了多少空间,贵的是产生它的过程——标准品采购、仪器占用、方法开发、人工判读。所以参考谱天然稀缺,而且天然分散:谁有标准品谁才有谱,谁有仪器谁才能打谱。一家实验室通常只覆盖自己关心的那一类化合物:做农药的有一批农药谱,做胆汁酸的有一批胆汁酸谱,做香料的有一批萜类谱。

MassBank 要解决的不是"存不下",而是"凑不齐"。它的答案是把记录格式做成可交换的:字段固定、语义固定、结尾固定,任何一家实验室按规范整理出的文本,都能被同一套软件读进去、被同一个门户检索出来。这件事听起来朴素,但它决定了三件事——贡献的门槛足够低,因此愿意交数据的人多;记录的语义足够硬,因此第三人能复现筛选条件;许可写在记录里,因此使用边界不用去猜。

明白了这一层,就能理解它为什么既不像数据库那样有统一的数据字典,也不像数据集那样有固定的版本标签。它是一个由格式规范维系的联盟,而不是一个由采集计划维系的工程。

1.2 三条常见的错误期待

第一条,期待它是"能直接喂进模型的训练集"。它没有训练集与测试集的划分,也没有化合物级去重。一条记录就是一张谱,同一种化合物可能有几十条。把它当训练集用不是不行,但划分口径得自己定,而且要按化合物分组(§7.3)。

第二条,期待它是"定量库"。记录里的强度是相对强度,最高峰归一到一个固定上限,其余按比例缩放。两张谱的同一峰强度相差十倍,可能只是进样量不同、离子化效率不同,读不出浓度。定量要靠标曲,不靠谱库。

第三条,期待它有一套唯一的权威计数。欧洲门户的元数据接口说十三万余条,记录计数接口说十三万九千余条,日本门户又给出另一个数字。这不是谁写错了,而是三个接口各自回答不同的问题:元数据回答"这一版收录了多少",计数接口回答"这个端点能返回多少条",日本门户回答"这个节点上挂了多少条"。引用时必须写明出处(§2.1)。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
用已知标准品谱反查未知物 十三万余条带前体离子与峰表的参考谱 够,且是免费方案里覆盖最广的一档
训练谱图相似度或分子指纹模型 大量同化合物多条件下的谱对 可做,但必须按化合物分组划分
做非靶向筛查的候选列表 化合物标识、加合物、仪器条件 够做候选生成,不够做确证
定量分析 相对强度 不够,没有浓度、没有内标、没有响应因子
拿到原始质谱文件做重处理 只有峰表 不够,原始文件不在库里
追溯一条谱是怎么打出来的 仪器、电离方式、碰撞能、色谱条件 部分够,字段完整度因贡献方而异
找特定物种、特定组织的谱 可选的物种与样本字段 覆盖很少,多数记录没有填
商用产品里内嵌谱库 逐条许可,含 CC BY 与 CC0 够,但要先按许可字段过滤

1.4 你的处境与它能帮到的事

你的处境 它能帮你什么 下一步该做什么
你手上有一批 LC-HRMS 数据,做完峰提取后不知道哪些峰值得往下追 提供带前体离子与加合物的参考谱,可先做候选生成 先用前体质量筛一遍,再用碎片谱打分,最后按打分排序人工看
你在做代谢物注释,缺一个不收费的谱库 全量可下、许可清晰、格式统一 按许可字段过滤后落地成表(§5.4),记录版本号
你要评估某个相似度算法在真实谱库上的表现 同一化合物多条件谱,天然构成难例 按化合物分组划分,报告同化合物与跨化合物的两组指标
你要给论文补一张"化合物鉴定依据"的表 每条记录有独立编号与可引用的许可 直接引用 ACCESSION,不要只引库名
你在搭建内部谱库,想复用外部记录的元数据 字段语义由 PSI-MS 词表对齐 用 PSI-MS 的 accession 做映射,别照抄中文标签(§4.2)
你在选型:MassBank、MoNA、NIST 之间挑一个 免费、可批量、可版本化,但不带保留指数与定量信息 先明确你要的是覆盖广度还是注释深度(§6.3)

1.5 一句话判断

它是一份由许多实验室共同签字的测量记录,价值在于"每条谱都能追到是谁在什么条件下打的",而不在于"数量够不够大"。

1.6 不适合谁:四条边界

不适合拿它做定量。 峰强度是相对值,没有浓度、没有内标、没有响应因子。用它算含量,等于把不同进样量、不同离子化效率的谱当成同一把尺子。

不适合拿它当唯一的鉴定依据。 谱库匹配只能给候选,不能给确证。同分异构体在 MS2 上常常几乎一样,真正确证需要标准品共流出或更高级的谱学手段。

不适合不做许可筛选就商用。 记录级许可包含 CC BY-NC 与 CC BY-NC-SA 两类,这两种不允许商业使用。把它们混进产品,问题不在技术侧。

不适合做跨仪器的碰撞能优化研究。 碰撞能字段的单位与口径由各实验室自定,同一字段里可能同时存在伏特、电子伏特与仪器百分比,横向比较没有共同基准(§7.3)。

§2 数据构成与规格

2.1 计数口径与它们各自的含义

先把数字的口径分清,后面所有讨论才不会打架。官方有几处可核对的位置:三处给出条数,一处给出结构维度。它们的回答对象不同。

位置 返回什么 数值 含义
欧洲门户 /MassBank-api/metadata 版本、时间戳、谱数、化合物数 谱 134,756 / 化合物 20,549 这一版记录集收录的规模
欧洲门户 /MassBank-api/records/count 一个整数 139,006 该端点可返回的记录条数
日本门户 /MassBank-api/records/count 一个整数 102,494 该节点挂载的记录条数
欧洲门户 /MassBank-api/filter/browse 筛选维度与取值 贡献方 61 / 仪器类型 52 记录集的结构维度

前两个数字都出自官方,差额四千二百余条的构成官方没有说明。合理的推测与弃用记录(记录里带 DEPRECATED 标记的那些)是否计入有关,但这是推测,不是官方口径,引用时以两个数并列的方式写最稳妥。日本门户的数字更小,原因是节点各自维护自己的一份挂载集合,欧洲门户收录的贡献方里包含了日本机构(检索结果里能看到 RIKEN、Chubu_Univ 这类代码),日本门户则不覆盖欧洲那些贡献方。

这也解释了一个常见困惑:为什么同一条记录在两个门户上都能搜到,但两个门户的总数对不上。联盟的结构决定了没有"唯一真值",只有"某个节点在某个时刻的视图"。

2.2 字段与记录的完整字典

MassBank record 不是表格的一行,而是一段有固定标签的文本。规范 2.6.0 把字段分成六组:记录特定信息(无前缀)、化学信息(CH$)、样本信息(SP$)、分析条件(AC$)、质谱描述(MS$)、峰数据(PK$)。下表按组列出常用标签。

标签 组 强制 含义 使用注意
ACCESSION 记录 是 记录编号,三段式 MSBNK-贡献方-自定 全库唯一,引用时用它
RECORD_TITLE 记录 是 化合物名 + 仪器类型 + 谱层级 由其他字段拼成,不要当自由文本解析
DATE 记录 是 创建或最后修改日期 格式为 YYYY.MM.DD
AUTHORS 记录 是 作者与单位,可带 MARC 角色标记 署名依据,不是联系人
LICENSE 记录 是 五种 CC 许可之一 商用前必须筛这一列
COPYRIGHT 记录 否 版权声明 与许可不是一回事
PUBLICATION 记录 否 关联论文,常带 DOI 追方法学时用
PROJECT 记录 否 所属项目 可用来分组
COMMENT 记录 否 备注,方括号标关系如 [Merging] 合并谱的线索在这里
COMMENT: CONFIDENCE 记录 否 注释级别,如 Level 1 引自 Schymanski 分级
CH$NAME 化学 是 化合物名,可多条 异构体要写清立体化学
CH$COMPOUND_CLASS 化学 否 化合物类别 命名不统一,别当受控词表
CH$FORMULA 化学 是 分子式(Hill 系统) 带电分子用方括号
CH$EXACT_MASS 化学 是 单同位素质量 与 compound.mass 不是同一概念
CH$SMILES 化学 是 异构 SMILES 非规范 SMILES,重建结构要再标准化
CH$IUPAC 化学 是 实际存的是 InChI 字段名与内容不一致,注意
CH$LINK 化学 否 外部库标识,如 InChIKey 跨库连接靠它
SP$SCIENTIFIC_NAME 样本 否 物种学名 覆盖率低
SP$SAMPLE 样本 否 样本制备信息 自由文本
AC$INSTRUMENT 条件 是 仪器厂商与型号 自由文本,需自行归一
AC$INSTRUMENT_TYPE 条件 是 分离-电离-分析器三段式 可枚举,适合做分组键
AC$MASS_SPECTROMETRY: MS_TYPE 条件 是 MS / MS2 / MS3 / MS4 / MSn 只有这五个取值
AC$MASS_SPECTROMETRY: ION_MODE 条件 是 POSITIVE 或 NEGATIVE 只有两个取值
COLLISION_ENERGY 条件 否 碰撞能 单位不统一,不能直接比
AC$CHROMATOGRAPHY: RETENTION_TIME 条件 否 保留时间 无单位字段,靠上下文
MS$FOCUSED_ION: PRECURSOR_M/Z 描述 否 前体离子质荷比 谱层级高于 MS 时才有
MS$FOCUSED_ION: PRECURSOR_TYPE 描述 否 加合物,如 [M-H]- 语法固定,可解析
MS$DATA_PROCESSING 描述 否 处理方式与软件 判断是否做过背景扣除
PK$SPLASH 峰 是 谱图哈希 2016-03 起强制
PK$NUM_PEAK 峰 是 峰总数 与峰表行数应一致
PK$PEAK 峰 是 峰表,首行是列名 强度为相对值,上限 999
PK$ANNOTATION 峰 否 峰的分子式注释 覆盖率不高
// 结尾 是 记录结束标记 可据此安全切分大文件

这张表里有两处容易读错的地方,值得单独指出。CH$IUPAC 这个名字会让人以为是 IUPAC 命名,实际存的是 InChI 字符串;规范化命名并没有单独字段。CH$EXACT_MASS 与接口 JSON 里的 compound.mass 也不是同一个数:前者是单同位素质量,后者在部分记录里保留了更多位或按分子量给出,做质量匹配时要用前者。

2.3 一条记录的完整解剖

取一条真实记录,编号 MSBNK-RIKEN-PR309430,来自 RIKEN 的贡献。它的原始文本只有两三千字节,读起来像一封格式信:

ACCESSION: MSBNK-RIKEN-PR309430
RECORD_TITLE: 1-Isothiocyanato-4-(methylsulfinyl)-butane; LC-ESI-QTOF; MS2
DATE: 2019.03.28
AUTHORS: Tetsuya Mori, Center for Sustainable Resource Science, RIKEN
LICENSE: CC BY-NC-SA
COMMENT: Annotation level-1
CH$NAME: 1-Isothiocyanato-4-(methylsulfinyl)-butane
CH$FORMULA: C6H11NOS2
CH$EXACT_MASS: 177.29
CH$SMILES: CS(=O)CCCCN=C=S
CH$IUPAC: InChI=1S/C6H11NOS2/c1-10(8)5-3-2-4-7-6-9/h2-5H2,1H3
CH$LINK: INCHIKEY SUVMJBTUFCVSAD-UHFFFAOYSA-N
AC$INSTRUMENT_TYPE: LC-ESI-QTOF
AC$MASS_SPECTROMETRY: MS_TYPE MS2
AC$MASS_SPECTROMETRY: ION_MODE NEGATIVE
AC$MASS_SPECTROMETRY: COLLISION_ENERGY 6V
AC$CHROMATOGRAPHY: RETENTION_TIME 3.7
MS$FOCUSED_ION: PRECURSOR_TYPE [M-H]-
MS$FOCUSED_ION: PRECURSOR_M/Z 176.02093
PK$SPLASH: splash10-03di-0900000000-2a3ac4853d1f9a29d107
PK$NUM_PEAK: 4
PK$PEAK: m/z int. rel.int.
  112.02596 112.0 999
  113.02395 41.0 366
  113.03277 54.0 482
  176.02054 24.0 214
//

读这条记录的正确顺序是从下往上:先看峰表,四个峰,基峰在 112.026,相对强度 999;再看前体离子 176.021 与加合物 [M-H]-,说明这是负离子模式下的去质子化分子;再看碰撞能 6V 与仪器类型 LC-ESI-QTOF,说明这是一张低能量碰撞的 QTOF 谱;最后看化合物层,分子式 C6H11NOS2,精确质量 177.29,比前体多一个氢,正好对上 [M-H]-。

LICENSE: CC BY-NC-SA 这一行单独拎出来说,因为它决定这条记录能不能进商业产品。同一条记录若被标成 CC BY,用法就完全不同。这也是为什么把全库一次性下下来直接用的做法有风险:许可不是一个全局属性,而是每一行的属性。

解析这段文本不需要专门的库,按标签切就行:

import re

def parse_massbank(text):
    rec, peaks, in_peak = {}, [], False
    for line in text.splitlines():
        if line.startswith('//'):
            break
        if in_peak and line.startswith('  '):
            mz, inten, rel = line.split()
            peaks.append((float(mz), float(inten), int(rel)))
            continue
        if line.startswith('PK$PEAK'):
            in_peak = True
            continue
        m = re.match(r'^([A-Z$: _]+):\s*(.*)$', line)
        if m:
            rec[m.group(1).strip()] = m.group(2).strip()
    rec['PEAKS'] = peaks
    return rec

with open('MSBNK-RIKEN-PR309430.txt', encoding='utf-8') as f:
    r = parse_massbank(f.read())

print(r['ACCESSION'], r['LICENSE'], len(r['PEAKS']))
print(r['MS$FOCUSED_ION: PRECURSOR_M/Z'], r['PEAKS'][0])

这段代码只处理单行标签与峰表,够用于绝大多数记录。要处理 PK$ANNOTATION 这种多行块,得再加一层缩进判断;要处理 COMMENT 重复出现的情况,得把它收成列表而不是覆盖。

2.4 记录都是些什么谱

官方的筛选器只暴露四个维度,说明记录集的分类骨架相当窄:贡献方、仪器类型、谱层级、离子极性。这四列基本决定了一条记录能被怎么用。

维度 取值个数 取值 对使用的意义
谱层级 5 MS、MS2、MS3、MS4、MSn 决定能否做碎片谱比对,MS1 只能做精确质量匹配
离子极性 2 POSITIVE、NEGATIVE 正负离子谱不能混在一张表里比较
仪器类型 52 如 LC-ESI-QTOF、GC-EI-EB 决定碰撞能是否可比、峰形是否可比
贡献方 61 机构代码,如 RIKEN、EPA 决定元数据风格与许可分布

谱层级里有 MS1,这一点常被忽略。MS1 记录是未做碎裂的全扫描谱,峰以母离子、同位素峰与加合物为主,没有碎片峰,用途与 MS2 完全不同:它适合做精确质量筛查与同位素模式判断,不适合做结构推断。把 MS1 与 MS2 混在同一个比对流程里,会得到一半没有意义的相似度分数。

2.5 与同类资源的字段差异

对比项 MassBank MassBank of North America NIST 谱库 GNPS 谱库
获取方式 门户 + 接口 + 仓库 + 快照 门户检索 商业授权 门户 + 接口
记录格式 自有纯文本,规范公开 平台自有格式 厂商二进制 以 msp 为主
许可 逐条 CC 许可 平台统一条款 商业许可 逐条或平台条款
谱层级 MS 到 MSn 以 MS2 为主 以 EI 与 MS2 为主 以 MS2 为主
保留指数 部分记录有 部分记录有 EI 库常带 不统一
定量信息 无 无 无 无
化合物级去重 无 无 有 部分

这张表要说明的只有一句:MassBank 在"格式公开、许可逐条、可版本化"这三点上最彻底,在"化合物级整理"上最不彻底。它的强项是机器可读与法律清晰,弱项是开箱即用的整洁度。

2.6 文本记录与接口 JSON 的对应关系

同一条记录有两种形态:仓库里的纯文本,和接口返回的 JSON。两者的字段不是一一对应的,混用会出错。

文本标签 JSON 路径 形态差异
ACCESSION accession 一致
RECORD_TITLE title 一致
DATE date.created / date.updated 文本只有一个日期,JSON 拆成三个
AUTHORS authors[].name 文本一行串起,JSON 拆成数组,单位混在姓名项里
LICENSE license 一致,但 JSON 去掉了前缀
PUBLICATION publication 一致
CH$NAME compound.names[] 文本可多行,JSON 是数组
CH$FORMULA compound.formula 一致
CH$EXACT_MASS compound.mass 数值类型不同,精度也可能不同
CH$SMILES compound.smiles 一致
CH$IUPAC compound.inchi 名称与内容错位,两边都一样
CH$LINK compound.link[] 文本一行一条,JSON 是 {database, identifier} 对象
AC$INSTRUMENT acquisition.instrument 一致
AC$INSTRUMENT_TYPE acquisition.instrument_type 一致
AC$MASS_SPECTROMETRY: MS_TYPE acquisition.mass_spectrometry.ms_type 一致
各类 AC$ 子标签 subtags[].subtag / .value 键值对数组,顺序不保证
MS$FOCUSED_ION mass_spectrometry.focused_ion[] 同上,且层级不在 acquisition 之下
PK$SPLASH peak.splash 一致
PK$NUM_PEAK peak.numPeak 大小写不同
PK$PEAK peak.peak.values[] 每峰变成 {id, mz, intensity, rel}

这张表里有两处必须留意。一是 MS$FOCUSED_ION 在 JSON 里挂在顶层 mass_spectrometry 下,与 acquisition.mass_spectrometry 不是一个对象,写代码时容易取空。二是在案例记录里,CAPILLARY_VOLTAGE、COLUMN_NAME 这些本该属于不同分组的子标签,被一并放进了 acquisition.chromatography 数组,靠 subtag 名字区分,不能靠数组名推断语义。

想确认一条记录到底有哪些子标签,最稳的办法是把它两边的形态都取一遍对照,而不是信文档里的分组。这一点对做解析器的人尤其重要:按文档写死的分组,会在部分记录上直接丢掉字段。

§3 它是谁的数据:一个联盟而不是一家机构

3.1 日本节点:从 MSSJ 的服务器开始

日本门户自称 MSSJ MassBank,MSSJ 是日本质谱学会。这个出身决定了它的早期形态:由学会牵头,各大学与研究所各自维护自己的数据服务器,门户只做索引与检索。Horai 等人在 2010 年的论文里把这种结构写得很清楚——分布式数据库,每个研究组提供自己的数据、跑自己的服务器,使用者可以取全部数据,也可以按实验条件取子集。

这种结构在当时是必然选择:2000 年代中期没有集中托管的条件,也没有统一的云存储,唯一可行的是各管一段。它留下的痕迹至今可见:贡献方代码里大量是大学与研究所的缩写,元数据风格差异明显,同一种仪器的写法能有好几种。

3.2 欧洲节点:UFZ 托管,DFG 出钱

欧洲门户由德国亥姆霍兹环境研究中心(UFZ,莱比锡)托管与分发,门户首页明确写了这一点。资助方是德国研究基金会 DFG,通过 NFDI4Chem 项目支持,项目号 441958208。这两个信息很实用:一是解释了为什么欧洲门户的接口最完整(有元数据、筛选、搜索、导出四类端点),二是给出了一个稳定的运维主体——托管在国家级研究中心,不会因为某个课题结题就消失。

两个门户跑同一套门户软件,版本号也一致(v2025.12.1)。这意味着接口路径、返回结构、字段命名在两个域名下是一样的,写代码时可以只改主机名。

3.3 北美方向是另一套账

北美有 MassBank of North America(MoNA),站点在加州大学戴维斯分校的 Fiehn 实验室名下,名字沿用 MassBank,但它是独立平台、独立计数、独立条款。本文给出的所有数字都不包含它。

把三者混为一谈是常见错误:搜"MassBank 有多少条谱",中文与英文结果里经常把 MoNA 的数字和 MassBank 的数字并列,读者会以为那是同一个库的两种说法。它们不是。

3.4 版本与发布节奏

时间 事件 依据
2006 项目在日本起步 项目方与后续综述的通行叙述,门户当前页面不再标注
2010-07 Horai 等人论文发表,给出首份公开快照 J Mass Spectrom 45(7):703–714
2016-03 记录规范改为默认 CC BY,新增 SPLASH 与 InChIKey 字段 记录格式规范版本历史
2022-05 现行 2.6.0 规范,ACCESSION 改为三段式 记录格式规范版本历史
2025-10 数据版本 2025.10,元数据时间戳 2025-10-24 官方元数据接口
2025-12 门户软件版本 v2025.12.1 两个门户首页内嵌配置
持续 每次发布在 Zenodo 归档不可变快照 仓库徽章与 Zenodo 记录

版本这件事对复现很重要。数据每年出若干版,记录会新增、会被标弃用、会被修订,但编号不变。写论文时如果只写"MassBank",三年后没人能复原你的实验。正确写法是写版本号加日期,必要时给 Zenodo DOI(§9.3)。

3.5 一条记录进入库要经过什么

贡献流程是这套体系里最不显眼、却最能说明其性质的部分。它不是"发邮件给管理员",而是一条完整的软件工程流水线。

步骤 做什么 出问题会怎样
生成 用官方推荐的 RMassBank 把仪器输出转成记录 手工整理容易漏字段
本地校验 用 MassBank-cli-tools 里的 Validator 跑一遍 合并前就能发现格式错误
提交 fork 仓库,在 dev 分支新增文件,向 dev 提拉取请求 直接改主分支会被拒
自动校验 拉取请求触发持续集成,对全部记录再跑一次 校验不通过则不合入
人工审查 维护者看元数据是否合理、许可是否合规 常见退回原因是许可缺失
合并发布 并入主分支,随版本发布并归档到 Zenodo 编号一经分配不再更改

这条流水线解释了三个现象。第一,为什么记录格式能被严格遵守——格式检查是自动的,不合格进不来。第二,为什么元数据完整度参差——校验只查必填项,可选字段填不填全凭贡献方自觉。第三,为什么普通使用者很难直接补一条记录——要会 fork、会跑 Java 工具、会写规范格式,门槛不低。

也正因为如此,缺谱这件事的最短解法不是等官方扩充,而是自己按规范整理后提一个拉取请求。官方文档明确写了这条路径,也接受用 issue 沟通的方式。

§4 它最独特的东西:一条记录就是一份可交换的合同

4.1 为什么坚持纯文本

现代谱库大多用二进制或数据库存储,MassBank 到今天仍然以一行行文本为主。这个选择有三层好处,也有代价。

好处之一是审查成本低。一条记录出问题,打开文本就能看见是哪个标签写错了,不需要专用工具。官方因此能把校验做成自动化:每次提交都跑 Validator,标签顺序不对、必填项缺失、数值格式不合规,都会在合并前被拦下(§3、§5.1)。

好处之二是可拼接。记录以 // 结尾,任意多条记录可以 cat 成一个大文件,也可以按贡献方切成小文件,不需要索引。批量处理时这一点很省事。

好处之三是可归档。纯文本的快照几十年后仍能读,不依赖某个软件版本。Zenodo 上的归档因此有意义。

代价是体积与解析成本。同样信息量下,文本比二进制大好几倍;解析要自己写,或者依赖社区工具。这是它不如商业库"开箱即用"的直接原因。

4.2 PSI-MS 受控词表:让字段能被机器对齐

MassBank 的字段名是自有的,但它与蛋白质组学标准组织 HUPO-PSI 的质谱受控词表(PSI-MS)建立了交叉引用。规范里给出了映射表,形如 [MS, MS:1000443, Mass Analyzer Type, Orbitrap] 的方括号写法是通用语法:第一个位置是词表缩写,第二个是 accession,第三个是名称,第四个是值。

MassBank 概念 PSI-MS 术语 accession
仪器型号 Instrument model MS:1000031
电离方式 ionization type MS:1000008
分析器类型 Mass Analyzer Type MS:1000443
离子极性 scan polarity MS:1000465
碰撞气 Collision gas MS:1000419
解离方法 dissociation method MS:1000044
质量分辨率 mass resolution MS:1000011
保留时间 Retention time MS:1000016
前体离子质荷比 precursor m/z MS:1000504
加合物类型 adduct ion MS:1000353
谱层级 ms level MS:1000511
数据处理 Data processing MS:1000543

这张表的价值在于跨库对接。当你要把 MassBank 的记录和另一套用 PSI-MS 标注的数据合并时,按 accession 对齐比按字段名对齐可靠得多——字段名在不同库里叫法五花八门,accession 是稳定的。

需要提醒的是,这个映射是规范层面的,不是每条记录都带方括号写法。实际记录里大量字段仍是 MassBank 自有写法,做映射时要按规范和仪器类型自行推断,不要指望直接抽取。

4.3 SPLASH:给一张谱算一个指纹

SPLASH 是谱图的哈希标识符,2016 年 3 月起成为 MassBank 记录的必填项。它的作用类似于文件的校验和:同一张谱无论被谁转发、被存成什么格式,只要峰表一致,SPLASH 就一致。

属性 说明
字段名 PK$SPLASH
强制起始 2016 年 3 月
形态 splash10- 前缀 + 分段编码,如 splash10-03di-0900000000-2a3ac4853d1f9a29d107
计算依据 峰表(质荷比与强度),与元数据无关
主要用途 去重、跨库对齐、缓存键
局限 峰表稍有差异即不同,不同碰撞能的两张谱不会同哈希

我在案例记录上看到的那串 splash10-03di-... 就是它。用 SPLASH 做去重很直接:同一化合物在不同实验室打出来的谱,哈希不同,说明确实不是同一张谱;同一张谱被两个贡献方各交了一份,哈希相同,可以只留一条。这比按化合物名去重精确得多,也比按峰表逐点比对快得多。

4.4 案例:一条来自 RIKEN 的四峰谱

回到 §2.3 那条记录。它只有四个峰,看起来信息量很小,但它把 MassBank 的几个设计意图同时展示了。

第一,它证明了"记录 = 一次测量"这个单位。同一种化合物(萝卜硫素类的降解产物)在别处肯定还有别的记录,可能来自不同仪器、不同碰撞能、不同加合物。库不负责合并它们,只负责让每条都可追溯。

第二,它的 COMMENT: Annotation level-1 说明注释级别被写进了记录。这个分级来自 Schymanski 等人的框架,Level 1 意味着有标准品对照。看到这一行,你就知道这条谱的可信度高于没有标注的那些。

第三,它的许可是 CC BY-NC-SA,不是默认的 CC BY。这条记录不能进商业产品。如果只按库名判断可用性,就会踩到这个坑。

第四,它的元数据很全:色谱柱、流动相梯度、流速、脱溶剂气温度都写了。同一批记录里,很多记录只有仪器与前体离子,色谱条件为空。这种完整度差异不是格式问题,是贡献方的习惯问题(§7.3)。

§4.4 的案例在后文还会出现两次:一次在 §5.4 讲怎么把它解析成表,一次在 §7.3 讲元数据完整度为什么不能当质量指标。

4.5 边界条件:什么情况下这套设计不再有效

条件 是否适用 判断依据
你要做跨库谱图检索 适用 SPLASH 与 PSI-MS 映射提供了对齐基础
你要做跨仪器的强度比较 不适用 相对强度与离子化效率强相关
你要按碰撞能做条件筛选 谨慎 单位不统一,须先按仪器类型分组
你要做化合物级唯一谱 不适用 库不做合并,需自建去重口径
你要追溯样品前处理 部分适用 SP$SAMPLE 是自由文本且覆盖率低
你要做法规级确证 不适用 谱库匹配只给候选,不构成确证

§5 怎么拿到:四个入口与它们各自的坑

5.1 四个入口的分工

入口 地址 适合什么 代价
网页检索 两个门户首页 查单个化合物、看谱图 不适合批量
REST 接口 /MassBank-api/ 下若干端点 程序化取数、按条件筛 全量返回体积大
GitHub 仓库 MassBank/MassBank-data 拿原始文本、看变更历史 仓库较大,克隆慢
Zenodo 快照 固定 DOI 复现某次分析 只有发布时的版本

四个入口给的是同一份数据的不同形态,选哪个取决于你要的是"最新"还是"可复现"。要可复现就用 Zenodo 的固定 DOI;要最新就用接口或仓库主分支;要单条记录就用网页。

5.2 先看元数据,再看记录

任何批量任务的第一步都应该是读元数据,因为它同时告诉你版本、规模与时间戳。三个字段就够定位:

#-- 版本、谱数、化合物数一次取回
curl -s https://massbank.eu/MassBank-api/metadata \
  | python3.11 -c "import sys,json; d=json.load(sys.stdin); \
print(d['version'], d['timestamp'], d['spectra_count'], d['compound_count'])"

#-- 结构维度:贡献方、仪器类型、谱层级、极性
curl -s https://massbank.eu/MassBank-api/filter/browse \
  | python3.11 -c "import sys,json; d=json.load(sys.stdin); \
print({k: len(v) for k, v in d.items()})"

第二条命令返回的四个键,就是官方承认的四个筛选维度。写筛选逻辑时只用这四个,别自己发明维度去请求。

5.3 全量 JSON 与条件检索

/records 端点会一次性返回整个记录集,体积在二十多兆,适合一次拉完再本地处理;/records/search 端点按筛选条件返回子集,适合只要一小块。要留意的是,/records 虽然接受 page 与 size 参数,实际并不分页——传了也照旧返回全量。

import json
import urllib.request

BASE = 'https://massbank.eu/MassBank-api'

def get_all():
    with urllib.request.urlopen(f'{BASE}/records', timeout=300) as r:
        return json.load(r)

def search(contributor=None, ms_type=None, ion_mode=None):
    q = []
    if contributor:
        q.append('contributor=' + ','.join(contributor))
    if ms_type:
        q.append('ms_type=' + ','.join(ms_type))
    if ion_mode:
        q.append('ion_mode=' + ion_mode)
    url = f'{BASE}/records/search?' + '&'.join(q)
    with urllib.request.urlopen(url, timeout=120) as r:
        return json.load(r)['data']

hits = search(contributor=['EPA'], ms_type=['MS2'])
print(len(hits), hits[0]['accession'])

search 返回的每一项只有编号与原子数这类索引信息,拿不到峰表。要峰表得再按编号取单条记录,或者直接下全量。这一点与很多人的预期不同,容易在写循环时把请求数放大几十倍。

5.4 把记录解析成可训练的表

拿到记录之后,第一件事是摊平成表。摊平的关键不是解析技巧,而是想清楚一行代表什么。下面是按"一行一条记录"的口径:

import json
import pandas as pd

with open('massbank_all.json', encoding='utf-8') as f:
    recs = json.load(f)

rows = []
for r in recs:
    if r.get('deprecated'):
        continue
    ms = r.get('acquisition', {}).get('mass_spectrometry', {})
    peaks = r.get('peak', {}).get('peak', {})
    rows.append({
        'accession': r['accession'],
        'name': (r.get('compound', {}).get('names') or [''])[0],
        'formula': r.get('compound', {}).get('formula', ''),
        'exact_mass': r.get('compound', {}).get('mass'),
        'license': r.get('license', ''),
        'ms_type': ms.get('ms_type', ''),
        'ion_mode': ms.get('ion_mode', ''),
        'instrument_type': r.get('acquisition', {}).get('instrument_type', ''),
        'precursor_mz': next((s['value'] for s in r.get('mass_spectrometry', {})
                              .get('focused_ion', []) if s['subtag'] == 'PRECURSOR_M/Z'), None),
        'splash': r.get('peak', {}).get('splash', ''),
        'n_peak': r.get('peak', {}).get('numPeak', 0),
    })

df = pd.DataFrame(rows)
print(df.shape, df['license'].isna().mean())
print(df.head(3).to_string())

这段代码有两个刻意的处理:跳过带 deprecated 的记录,因为弃用记录的内容可能无效;用 next(...) 取前体离子,因为 focused_ion 是个子标签列表,位置不固定。把这两点写进代码,比事后补数据要省事。

摊平之后,拿 §4.4 的案例那一行对照一下:accession 应是 MSBNK-RIKEN-PR309430,splash 应以 splash10- 开头,n_peak 应是 4。三处都对得上,说明解析没有丢字段。

5.5 去重与合并:三个层次

拿到表之后最常见的下一步是去重,而去重的口径决定后面的所有结论。至少有三种口径,各自解决不同问题。

层次 依据 解决什么 用什么
谱级 SPLASH 同一张谱被重复提交 PK$SPLASH 精确匹配
记录级 ACCESSION 同一条记录出现在多个导出里 编号精确匹配
化合物级 InChIKey 同一种化合物的多条谱聚成一组 CH$LINK 里的 InChIKey

第三层最容易被做错。按化合物名去重会把异构体合并,按分子式去重会把同分异构体合并,只有 InChIKey 能区分立体化学。谱库任务里这个区别很关键:同分异构体的 MS2 往往高度相似,正是难例的来源;如果去重时把它们合并了,难例就消失了,指标会虚高。

import pandas as pd

df = df[df['license'].isin(['CC0', 'CC BY'])]      #-- 商用口径,按需改
df = df.drop_duplicates(subset='splash')            #-- 谱级去重
df['inchikey'] = df['accession'].map(ikey_of)       #-- 由 CH$LINK 取 InChIKey 的映射函数

print(df['inchikey'].nunique(), len(df))

最后一行打印的两个数,前一个是化合物数,后一个是记录数。两者之比就是平均每种化合物有几条谱。这个比例决定了按化合物分组划分数据集时,每组有多少样本可用。

5.6 六个最容易出错的地方

位置 错误写法 后果 正确做法
计数 拿一个接口的数字当唯一真值 与另一处官方数字对不上 写明接口与版本(§2.1)
分页 给 /records 传 page/size 以为分页了,实际拉全量 接受全量,或改用 search
许可 假定全库同一个许可 混入 CC BY-NC 记录 先按 license 过滤
去重 按化合物名去重 异构体被合并,难例消失 用 InChIKey
划分 按记录随机切分 同化合物谱泄漏到两侧 按 InChIKey 分组
单位 直接比较碰撞能数值 跨仪器的比较无意义 按仪器类型分组后再比

§6 与库内条目的关系

6.1 关系图谱

本站已有的质谱相关词条,多数站在"原始数据"这一侧,MassBank 站在"参考谱"这一侧。两者的差别不是格式,而是数据在实验流程里的位置。

词条 数据类型 与 MassBank 的关系
PRIDE 蛋白质组学原始谱文件 同为质谱数据,但对象是肽与蛋白,不是小分子;它存原始文件,MassBank 存峰表
MassIVE 蛋白质组学与代谢组学原始数据仓 上下游关系:MassIVE 存原始文件,MassBank 存整理后的参考谱
PaxDb 蛋白质丰度汇总 无直接交集,只是同样依赖质谱测量
代谢组学与化学信息学词条 化合物结构、性质、通路 互补:那些给"分子是什么",MassBank 给"分子打出来什么样"

这条关系线可以用一句话概括:原始数据仓回答"这个实验怎么做的",参考谱库回答"这个分子长什么样"。 两者都需要,但不能互相替代。想复现一次实验,去原始数据仓;想鉴定一个未知峰,来参考谱库。

6.2 检索路径

你要找的东西 检索词 会落到哪里
小分子 MS/MS 参考谱 mass spectral library、MS2 reference 本词条
原始质谱文件 proteomics repository、raw files PRIDE、MassIVE
蛋白质丰度 protein abundance PaxDb
化合物结构信息 chemical structure、InChIKey 化学信息学类词条
谱图哈希标准 SPLASH、spectral hash §4.3
质谱受控词表 PSI-MS、controlled vocabulary §4.2

6.3 与其他谱库的分工判据

任务 主粮仓该用什么 MassBank 的位置 原因
未知物候选生成 MassBank 或 GNPS 一类开放库 主力之一 覆盖广、免费、可批量
EI 谱比对 NIST 一类商业库 辅助 MassBank 的 EI 记录比例不高
保留指数辅助定性 带保留指数的专用库 辅助 保留指数覆盖不全
定量方法开发 自建标准曲线 不适用 无浓度信息
谱图算法评测 MassBank 加自建难例 主力 同化合物多条件谱天然构成难例
法规确证 标准品与高分辨多级谱 仅作候选 谱库匹配不构成确证

这张表的第一行是大多数人的真实处境:他们需要一个不收费、能批量下、许可清楚的库来做候选生成,MassBank 正好在这个位置。被高估的用法是最后一行,把谱库匹配当成确证结论。

6.4 库内没有对应词条时怎么判断

本站的词条按数据集组织,一个数据集一条。如果你想找的东西不是"一个库",而是"一类数据",判断路径要换一种走法:先看你要的数据在实验流程的哪一段,再找那一段对应的仓或库。

鉴定流程大致可以切成四段:样品与实验条件、原始谱文件、整理后的谱表、化合物结构与性质。MassBank 只覆盖第三段与第四段的一部分,前两段要另找地方。这不是它的缺陷,而是分工——它从不声称保存原始文件,也不声称保存样品前处理记录。

流程段 该找什么类型的资源 本词条是否覆盖
样品与前处理 研究方案库、样本元数据仓 不覆盖
原始谱文件 原始数据仓 不覆盖
整理后的谱表 参考谱库 覆盖,主体
化合物结构与性质 化学信息学数据库 部分覆盖,靠 InChIKey 外链

把这张表与 §6.1 的关系图对起来看,就能回答一个很实际的问题:为什么在原始数据仓里下载了文件,仍然鉴定不出东西。因为原始文件里没有参考谱,只有你自己的测量;要鉴定,必须再拿一份别人的测量来比。

§7 质量评估与局限性

7.0 阅读本节前的一个前置校正

先纠正一个常见的误判:把"格式合规"当成"数据质量高"。MassBank 的每条记录都过了官方的 Validator,标签顺序、必填项、数值格式都合规,但这只证明它写得对,不证明它测得准。格式合规是语法层面的事,测量质量是实验层面的事,两者之间没有必然关系。

这个校正会改变后面的读法。一条记录可能格式完美、字段齐全,但碰撞能标的是仪器百分比,另一条格式同样完美、碰撞能标的是伏特,两者放在一张表里做数值比较,结论一定是错的。所以本节把质量拆成两条线来看:一条是格式与元数据,一条是实验可比性。

7.1 五维评分(DAIMS)

按 DAIMS 的常用维度打分,每项 1–5 分,针对"作为小分子鉴定的参考谱资源"这个用途:

维度 分数 理由
数据规模 4 十三万余条谱、两万余种化合物,开放库里属第一梯队
元数据质量 3 字段设计完整,但实际填充率因贡献方差异很大
任务适配 5 小分子 MS/MS 候选生成几乎没有更合适的免费选择
文档完整 5 格式规范公开到标签级,接口有元数据端点
可获取性 5 四个入口、无需注册、许可逐条可查

合计 22 分(满分 25)。扣分集中在元数据质量上,原因不是设计不好,而是执行层面无法强制统一:规范能规定字段名,规定不了每个实验室都把色谱条件填全。

7.2 两条质量线:写得对,与测得准

层次 由谁保证 能查到什么 查不到什么
语法 官方 Validator 自动校验 标签顺序、必填项、数值格式 数值是否真实
语义 贡献方自填 仪器、条件、化合物标识 填写是否完整
实验 贡献方的实验设计 采集方法与参数 是否做过重复测量
可比性 无人保证 同一仪器类型内大致可比 跨仪器的定量可比

第二行到第四行是逐级衰减的。Validator 能拦下写错的记录,拦不住填得不全的记录,更管不了两家实验室用不同方法测同一个化合物。使用者要做的判断是:在你要用的那个子集里,衰减到了哪一级。

7.3 已知的、可枚举的偏差

偏差 表现 影响
碰撞能口径不一 同一字段里混有伏特、电子伏特、百分比 跨仪器比较无效
元数据完整度参差 部分记录缺色谱条件、缺前体离子 按字段筛选会系统性丢掉老记录
同化合物多记录 一种化合物几十条谱 不做分组会让评测虚高
仪器分布不均 QTOF 与离子阱占比高 对其他仪器类型的泛化有限
化合物类别偏斜 天然产物、农药、环境污染物较多 药物与临床代谢物覆盖相对薄
记录年代跨度大 2006 年至今 早期记录的字段与现在不同
合并谱与单谱并存 同一化合物既有合并谱又有原始谱 检索结果出现重复观感

第三行与第七行值得展开。第三行说的泄漏机制很直接:如果按记录随机划分训练集与测试集,同一种化合物在 A 实验室打的谱进了训练集,在 B 实验室打的进了测试集,模型只要学会"这个化合物的碎片模式"就能拿高分,而这个能力在遇到全新化合物时毫无用处。正确做法是按 InChIKey 分组,同一种化合物只进一侧。§4.4 的案例就是被泄漏的那一侧:它只是一条记录,同一种化合物在库里还有别的记录,按记录切分必然把它们分到两边。

第七行说的是合并谱。早期 MassBank 会把同一化合物在不同碰撞条件下的多条谱合并成一条,论文里报告过这一步把相似度 0.6 处的鉴定准确率提高了两成左右。合并谱在库里以 COMMENT 里的标记区分,做去重时要按标记处理,不能简单当成重复记录删掉。

7.4 外部验证矩阵

验证角色 做法 讲得通的地方 风险
谱图匹配算法评测 用库内同化合物谱构造正样本,跨化合物构造负样本 正负样本都来自真实采集 负样本难度不均,热门化合物负样本偏多
跨库一致性检验 与 MoNA、GNPS 的交集做交叉验证 三方独立整理,错误不易共现 交集部分的记录可能同源
注释流程基准 用带 Level 1 标注的记录做金标准 有标准品对照,标签可信 Level 1 记录占比不高
保留时间预测 用带保留时间的记录训练 数据量大 色谱条件不统一,跨柱不可比

第三行是它被低估的用法。记录里的注释级别是少数能直接当质量标签用的字段:Level 1 意味着有标准品,Level 2 意味着有图书馆谱或诊断碎片,级别越低可信度越弱。用 Level 1 子集做金标准,比用全库做金标准要稳。

7.5 它为何能持续:贡献比采集便宜

MassBank 没有靠一次性大额投入建成,它靠的是一个经济学上很稳的结构:对贡献方来说,交数据的成本远低于自己建库维护的成本;对使用方来说,免费拿到一份格式统一的库,比逐个实验室去要数据便宜得多。中间的门户只承担索引与托管,不承担采集。

这个结构一旦转起来就很难停:贡献方越多,库越有用;库越有用,贡献方越愿意交。它不依赖某一笔经费,只依赖托管方愿意长期运维——欧洲节点由 UFZ 承担、DFG 资助,日本节点由学会承担,两边都不需要靠卖数据回本。

反过来说,它的规模上限也在这里:库里有什么,取决于有人愿意交什么。冷门化合物、罕见加合物、特殊仪器条件下的谱,永远不会自动出现。

§8 生态位与历史

8.1 从分布式服务器到统一门户

2000 年代中期的版本是"各管一段":每个研究组跑自己的服务器,门户只做联邦检索。Horai 等人在 2010 年的论文里给出的快照可以说明当时的规模感——十六个研究组贡献,几万条谱,覆盖代谢物、挥发物与合成药物三类。

那篇论文里还有两个设计细节值得记住,因为它们今天仍在起作用。一是相似度算法用加权余弦,权重指数是针对 ESI-MS2 数据调过的,不是通用的固定值;把同一套参数直接套到 EI 谱上,效果会变差。二是它提出了"合并谱":把同一化合物在不同碰撞条件下的多条谱并成一条,论文报告这一步在相似度 0.6 处把鉴定的精确率提高两成左右。今天库里仍能找到合并谱与原始谱并存的痕迹,做去重时绕不开(§7.3)。

阶段 形态 主要问题
2006–2010 分布式服务器,联邦检索 各站点稳定性不一,检索慢
2010–2016 记录格式逐步收紧,门户集中化 元数据风格差异大
2016–2022 默认 CC BY,SPLASH 与 InChIKey 强制 老记录需回填
2022 至今 三段式编号、语义化版本、GitHub 工作流 规模增长依赖贡献方

2016 年那次改动是分水岭:把默认许可定为 CC BY、把 SPLASH 设为必填、把 InChIKey 加进链接字段。三件事都指向同一个目标——让记录能被机器批量使用而不产生法律与技术歧义。此后的增长更多来自流程改进:提交走 GitHub 拉取请求,校验自动化,发布归档到 Zenodo。

8.2 与商业库的分工

商业谱库(NIST 一类)的优势在整理度:化合物级去重、保留指数齐全、检索软件成熟。它的劣势在封闭:买不到就不能用,买了也不能改,版本不可追溯。MassBank 走的是相反的路:整理度差一档,但完全开放、可批量、可版本化。

维度 MassBank 商业谱库
许可 逐条 CC 一次性商业授权
覆盖 以 LC-MS/MS 为主 EI 谱更全
整理度 记录级,不合并 化合物级,已合并
可修改 可,提拉取请求 不可
版本复现 版本号 + Zenodo DOI 按购买批次

对多数代谢组学实验室来说,两者是搭配使用的:日常筛查用开放库,法规或发表级确证用商业库或标准品。

8.3 生态位:基础设施,不是产品

角色 商业谱库 MassBank
定位 产品 基础设施
谁维护 厂商 联盟 + 托管机构
增长动力 销售 贡献
失败模式 版本停更 贡献枯竭

把它当基础设施看,很多设计就说得通了:为什么坚持纯文本(可长期保存)、为什么许可逐条写(贡献方各自负责)、为什么不做化合物级合并(合并是有争议的判断,交给使用者)。

8.4 谁在用它,用来做什么

从公开文献的用法看,使用者集中在三类:做非靶向筛查的环境与分析化学组(用库做候选生成)、做注释工具的方法组(用库做基准与训练)、做数据库互联的团队(用 SPLASH 与 InChIKey 做跨库对齐)。第三类最少,但正是它把 MassBank 从一个库变成了一个节点。

§9 使用指引

9.1 三种角色的路径

角色 第一天 第一周 注意事项
分析化学研究者 用网页检索若干目标化合物,看谱图与条件 按化合物整理候选表,标注注释级别 别把 MS1 与 MS2 混在一张表里比
方法开发者 拉元数据确认版本,拉全量建本地表 按 InChIKey 分组做划分,跑基线 先定许可口径再定数据口径
数据工程师 读格式规范 2.6.0,写解析器 建增量同步,用 SPLASH 做去重 记录会改,编号不变,要按版本对齐

9.2 一条最短的可用流程

#-- 1. 固定版本,留下可复现的凭据
curl -s https://massbank.eu/MassBank-api/metadata -o metadata.json
python3.11 -c "import json;d=json.load(open('metadata.json'));print(d['version'],d['timestamp'])"

#-- 2. 拉全量,落地为本地文件
curl -s https://massbank.eu/MassBank-api/records -o massbank_all.json
ls -lh massbank_all.json

#-- 3. 拉一条记录看结构
curl -s https://massbank.eu/MassBank-api/records/MSBNK-RIKEN-PR309430 -o one.json
import json

with open('one.json', encoding='utf-8') as f:
    r = json.load(f)

peaks = r['peak']['peak']['values']
print(r['accession'], r['license'], r['peak']['splash'])
print(len(peaks), peaks[0])

第二步的下载在普通网络下要几分钟,文件二十多兆。落地之后所有处理都在本地做,不要再反复请求接口——这既慢又容易触发限流。

9.3 引用方式

引用对象 内容
数据集 MassBank, version 2025.10. 访问日期。
方法学论文 Horai H, et al. MassBank: a public repository for sharing mass spectral data for life sciences. J Mass Spectrom. 2010;45(7):703–714. doi:10.1002/jms.1777
单条记录 用 ACCESSION 引用,如 MSBNK-RIKEN-PR309430,并注明该条记录的 LICENSE
归档快照 Zenodo DOI 10.5281/zenodo.19590880
门户 欧洲门户 massbank.eu;日本门户 massbank.jp

写论文时建议同时给出:版本号、访问日期、许可筛选条件、以及是否包含日本节点。少写任何一项,别人都无法复现你的子集。

§10 AI 使用声明

项目 声明
文本生成 本文由 AI 辅助撰写,结构与事实由编辑核对
数字来源 规模、结构、边界三类数字来自官方门户接口与官方格式文档
接口核验 元数据、计数、筛选、搜索四个端点经直接请求确认
记录核验 案例记录 MSBNK-RIKEN-PR309430 的原文与接口返回逐字段比对
论文信息 仅参考 Europe PMC 摘要,未读全文
未核实内容 两个官方计数差额的具体构成、各许可在库中的实际占比
图像 无配图;封面为生成式提示词,不含真实谱图
免责 本文不构成分析化学或临床建议;使用须遵守记录级许可

常见误读(避坑清单)

说法 实际 证据
「MassBank 只有十三万条,另一个数字是错的」 两个数字都出自官方不同端点,差额构成未说明 §2.1 的三口径表
「全部记录都是 CC BY,随便用」 逐条声明,含 CC BY-NC 与 CC BY-NC-SA 案例记录许可为 CC BY-NC-SA
「它就是一个能下载的谱库文件」 四个入口、四种形态,版本各不相同 §5.1 入口表
「碰撞能可以直接排序比较」 单位与口径由各实验室自定 规范未约定碰撞能单位
「同一种化合物搜出很多条是重复数据」 一条记录对应一次测量,不重复 §4.4 的案例
「它是定量库」 强度为相对强度,无浓度信息 峰表仅三列:m/z、强度、相对强度
「MS1 和 MS2 可以混着比」 谱层级不同,相似度不可比 筛选器把 MS_TYPE 单列为一个维度
「超过校验就说明数据可信」 Validator 只查语法,不查实验质量 §7.2 的两条线
「按记录随机划分训练测试就行」 同化合物多记录会泄漏 §7.3 第三条偏差

FAQ

Q1:MassBank 到底有多少条谱?为什么有两个数字?
官方元数据接口在 2025.10 版给出十三万余条,记录计数接口返回十三万九千余条。两者都出自官方,差额的构成没有官方说明,通常与弃用记录是否计入有关。引用时写清端点与版本。

Q2:它能直接训练谱图相似度模型吗?
可以,但划分要按化合物做。同一种化合物常有几十条来自不同实验室、不同碰撞能的记录,按记录随机切分会把同源谱分到两侧,指标会明显偏高。

Q3:碰撞能可以跨记录比较吗?
不能。不同厂商对碰撞能的定义与单位不同,同一字段里可能同时出现伏特、电子伏特与仪器百分比。跨仪器比较前要按仪器类型分组,或者干脆改用碎片谱形态比对。

Q4:为什么一种化合物能搜到很多条记录?
一条记录对应一张谱。不同实验室、不同仪器、不同加合物、不同碰撞能各出一条。早期还有合并谱机制,把同化合物的多条谱并成一条,合并谱与单谱在库里并存。

Q5:许可写着 CC BY-NC 的记录能商用吗?
不能。LICENSE 是强制字段,取值可能是 CC0、CC BY、CC BY-NC、CC BY-NC-SA、CC BY-SA 五种之一。商用前先按字段过滤。

Q6:它和 MoNA、GNPS 是什么关系?
MoNA 是北美独立平台,沿用 MassBank 格式与编号习惯,但计数与条款自成一套;GNPS 是另一个以社区上传为主的谱库平台。三者的数字不能混着引用。

Q7:为什么有些记录没有 SPLASH?
SPLASH 是 2016 年 3 月起才强制。更早的记录如果没有回填,就没有这个字段。去重时要对缺失值留一条退路。

Q8:库里有原始质谱文件吗?
没有。只有整理后的峰表与元数据。要原始文件得去 PRIDE、MassIVE 一类的原始数据仓。

Q9:怎么引用单条记录?
用 ACCESSION,例如 MSBNK-RIKEN-PR309430,并注明这条记录的许可。只引库名不足以定位你用的是哪张谱。

Q10:数据多久更新一次?
官方按版本发布,元数据接口带版本号与时间戳,每次发布在 Zenodo 归档快照。复现性要求高时用 Zenodo 的固定 DOI。

Q11:它对中国本土化合物覆盖如何?
官方没有按地区给出覆盖统计。从贡献方构成看,日本机构贡献较多,中药材与天然产物相关记录相对丰富,但这一点只能定性判断。

Q12:能不能只用 MS1 记录做筛查?
可以。MS1 记录是未做碎裂的全扫描谱,峰以母离子与同位素峰为主,适合精确质量筛查,不适合结构推断。用的时候要把 MS_TYPE 限定为 MS,别和 MS2 混在一张表里。

术语表

术语 解释
MassBank record 一条记录对应一张谱的纯文本载体,以 // 结尾
ACCESSION 记录编号,三段式 MSBNK-贡献方-自定
贡献方代码 记录编号中段的机构缩写,官方筛选器列出 61 个
MS1 未做碎裂的全扫描谱,峰以母离子与同位素为主
MS2 母离子再碎裂一次得到的碎片谱,库中主体
MSn 多级碎裂,n 可到 4 以上
前体离子 被选中并碎裂的离子,记录其质荷比与加合物类型
加合物 如 [M-H]-、[M+H]+,决定前体质量与母体质量的关系
碰撞能 碎裂能量的设置值,单位与口径因仪器而异
相对强度 以基峰为上限归一后的强度,无浓度含义
基峰 一张谱中最强的峰,相对强度取上限值
SPLASH 谱图哈希,用于去重与跨库对齐
PSI-MS 蛋白质组学标准组织维护的质谱受控词表
受控词表 字段名与取值被标准化的词表,便于机器对齐
InChI 化合物结构的标准文本表示,含立体化学
InChIKey InChI 的定长哈希,常作化合物主键
SMILES 化合物结构的线性表示,写法不唯一
精确质量 单同位素质量,用于高分辨质量匹配
ChemOnt 化合物分类本体,记录里以 CH$LINK 引用
注释级别 鉴定可信度分级,Level 1 表示有标准品对照
合并谱 把同化合物多条谱并成一条的产物
弃用记录 带 DEPRECATED 标记、内容可能无效的记录
Validator 官方记录校验工具,随提交自动运行
Zenodo 快照 每次发布归档的不可变数据副本

附录 A:核心数字核对表

项 值 来源 来源层级
谱记录数(元数据口径) 134,756 /MassBank-api/metadata 官方接口
化合物数 20,549 /MassBank-api/metadata 官方接口
谱记录数(计数接口) 139,006 /MassBank-api/records/count 官方接口
日本门户记录数 102,494 massbank.jp/MassBank-api/records/count 官方接口
数据版本 2025.10 元数据接口 官方接口
元数据时间戳 2025-10-24 元数据接口 官方接口
门户软件版本 v2025.12.1 门户首页内嵌配置 官方页面
贡献方代码数 61 /filter/browse 官方接口
仪器类型数 52 /filter/browse 官方接口
谱层级取值 5(MS、MS2、MS3、MS4、MSn) /filter/browse 官方接口
离子极性取值 2(POSITIVE、NEGATIVE) /filter/browse 官方接口
记录格式规范版本 2.6.0 官方格式文档 官方文档
规范发布日期 2022-05-13 官方格式文档 官方文档
默认许可起始 2016-03 官方格式文档版本历史 官方文档
SPLASH 强制起始 2016-03 官方格式文档 官方文档
Zenodo 归档 DOI 10.5281/zenodo.19590880 Zenodo 官方归档
起始年份 2006 项目方与综述的通行叙述 二手

附录 B:数字的来源分层

第一层,官方接口与官方文档。 谱数、化合物数、贡献方数、仪器类型数、谱层级取值、格式规范版本、许可清单、SPLASH 强制起始时间,这些全部可以在官方接口或官方格式文档里逐字核对,附录 A 已标注具体端点。

第二层,论文摘要。 2010 年论文给出的首份快照规模、分布式服务器结构、加权余弦相似度的做法、合并谱对鉴定准确率的提升幅度,来自 Europe PMC 返回的摘要。摘要能支撑"作者当时这样描述",不能支撑"现在仍然如此"。

第三层,二手与未核实。 2006 年这个起始年份来自项目方与后续综述的通行叙述,当前门户页面不再重复标注,本文按二手处理。两个官方计数之间的差额构成、各许可在库中的实际占比、化合物类别的地区分布,均未核实,正文相应位置只做定性表述或明确标注口径。

附录 C:完整参考文献

编号 文献 链接 用途
1 欧洲门户首页 https://massbank.eu/MassBank/ 定位、托管方、资助信息
2 日本门户首页 https://massbank.jp/MassBank/ 节点身份与记录计数
3 元数据接口 https://massbank.eu/MassBank-api/metadata 版本、谱数、化合物数
4 筛选接口 https://massbank.eu/MassBank-api/filter/browse 贡献方、仪器类型、谱层级、极性
5 记录计数接口 https://massbank.eu/MassBank-api/records/count 计数口径对照
6 记录格式规范 2.6.0 https://github.com/MassBank/MassBank-documentation/blob/dev/MassBankRecordFormat.md 字段字典、许可、SPLASH
7 贡献者文档 https://massbank.github.io/MassBank-documentation/contributor_documentation.html 提交流程、Validator
8 用户文档 https://massbank.github.io/MassBank-documentation/user_documentation.html 格式转换与导出工具
9 记录仓库 https://github.com/MassBank/MassBank-data 原始文本、目录结构
10 Zenodo 归档 https://doi.org/10.5281/zenodo.19590880 可复现快照
11 Horai et al. 2010 https://doi.org/10.1002/jms.1777 方法学与首份快照
12 MassBank of North America https://mona.fiehnlab.ucdavis.edu/ 北美方向的独立平台

附录 D:任务代码

任务一:把全量记录摊平成化合物级索引

import json
from collections import defaultdict

with open('massbank_all.json', encoding='utf-8') as f:
    recs = json.load(f)

by_key = defaultdict(list)
for r in recs:
    if r.get('deprecated'):
        continue
    links = r.get('compound', {}).get('link', [])
    ikey = next((l['identifier'] for l in links
                 if l.get('database', '').upper() == 'INCHIKEY'), None)
    if not ikey:
        continue
    by_key[ikey].append({
        'accession': r['accession'],
        'ms_type': r.get('acquisition', {}).get('mass_spectrometry', {}).get('ms_type'),
        'license': r.get('license'),
        'splash': r.get('peak', {}).get('splash'),
    })

multi = {k: v for k, v in by_key.items() if len(v) > 1}
print(len(by_key), len(multi))
print(list(multi.items())[0])

这段代码的输出有两个用途:化合物总数告诉你库的覆盖面,多记录化合物数告诉你做分组划分时有多少组有足够样本。

任务二:用余弦相似度做一次谱图比对

import numpy as np

def to_vector(peaks, bins=2000, mz_max=1000.0):
    v = np.zeros(bins, dtype='float32')
    for peak in peaks:
        idx = min(int(peak['mz'] / mz_max * bins), bins - 1)
        v[idx] = max(v[idx], float(peak['rel']))
    return v

def cosine(a, b):
    na, nb = np.linalg.norm(a), np.linalg.norm(b)
    if na == 0 or nb == 0:
        return 0.0
    return float(np.dot(a, b) / (na * nb))

query = to_vector([{'mz': 112.02596, 'rel': 999}, {'mz': 113.02395, 'rel': 366}])
target = to_vector([{'mz': 112.02596, 'rel': 999}, {'mz': 113.02395, 'rel': 366}])
print(round(cosine(query, target), 4))

第二段代码是最小可运行版本,用来验证管线是否跑通。正式使用时要把分箱换成按质荷比容差匹配,并加入质量权重——论文摘要里提到的加权余弦,权重指数是针对 ESI-MS2 数据优化过的,不是固定的 1。

附录 E:如果只记五件事

序号 记住什么 为什么
1 一条记录 = 一张谱,不是一种化合物 决定了去重与划分口径
2 许可逐条声明,五种取值 商用前必须按字段过滤
3 碰撞能不能跨仪器比 决定条件筛选该怎么做
4 两个官方计数并存,引用要写端点 避免与他人数字打架
5 版本 + Zenodo DOI 才是可复现的引用 记录会改,编号不会

编辑说明

本篇的核对时间为 2026 年 10 月 27 日。核对方式为直接请求欧洲与日本两个门户的元数据、计数、筛选、搜索四类端点,逐字段比对一条真实记录(MSBNK-RIKEN-PR309430)的原文与接口返回;格式细节取自官方 MassBank Record Format 2.6.0 文档;论文侧只检索 Europe PMC 摘要,未读全文。

未覆盖的内容包括:两个官方计数之间差额的具体构成、五种许可在库中的实际占比、化合物类别的地区分布、各贡献方的记录量排名。这些都需要下载全量后做分布统计,按本项目的写作纪律不做。

关于起始年份:当前门户页面不再标注建站日期,2006 年这一说法来自项目方与后续综述的通行叙述,因此在附录 A 中标为二手来源,正文相应处也作了限定。若后续官方文档给出明确日期,应以官方为准。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • hmdb — 共享标签:药物发现与化学 / 化学信息学 / 代谢组学
  • anpdb — 共享标签:药物发现与化学 / 化学信息学 / 代谢组学
  • foodb — 共享标签:药物发现与化学 / 化学信息学 / 代谢组学
  • chebi — 共享标签:药物发现与化学 / 化学信息学 / 代谢组学
  • lotus-ref — 共享标签:药物发现与化学 / 化学信息学 / 代谢组学
  • mona — 共享标签:化学信息学 / 代谢组学
  • zinc — 共享标签:药物发现与化学 / 化学信息学
  • pdbbind — 共享标签:药物发现与化学 / 化学信息学
  • toxcast — 共享标签:药物发现与化学 / 化学信息学
  • davis — 共享标签:药物发现与化学 / 化学信息学

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集