Skip to content

Commit cc0ed94

Browse files
jiajunagentclaude
andcommitted
docs: MFSL 架构设计 v2.0——双库独立标签 + 8 维体系 + 标签内嵌 MSP
核心变更(vs v1): - 标签内嵌 MSP 文件(行业标准),不依赖外部 CSV 查询 - spectral_metadata.csv 降为只读索引(从 MSP 生成的衍生物) - 两个库各自拥有完整 8 维标签,不互相依赖 - 8 维:chemical_class/application/sample/source/confidence/instrument/polarity/reg_lists - 4 层标签填充策略(库级别→MSP 字段→原始库提取→ClassyFire API) - 只用可信来源填充,不猜不推测 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0c1d86d commit cc0ed94

1 file changed

Lines changed: 330 additions & 0 deletions

File tree

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
# MFSL 数据库架构设计 v2.0
2+
3+
> 确认日期:2026-03-24
4+
> 状态:待确认
5+
> 替代:2026-03-23-mfsl-architecture-upgrade-design.md(v1,已过时)
6+
7+
---
8+
9+
## 1. 总体架构
10+
11+
MFSL(MetaboFlow Spectral Library)是一个独立的数据资产,由两个核心库组成。两个库各自拥有完整的 8 维标签体系,通过 InChIKey 关联但不互相依赖。
12+
13+
### 1.1 三层结构
14+
15+
```
16+
Layer 1: 数据层
17+
├── deduplicated/*.msp 质谱库:60 万条 MS2 谱图峰数据(标签内嵌)
18+
└── compound_metadata.csv 化合物库:96 万条化合物属性(= Level 3 数据)
19+
20+
Layer 2: 索引层
21+
└── spectral_metadata.csv 质谱库的只读快速索引(从 MSP 自动生成)
22+
23+
Layer 3: 文档层
24+
└── DATABASE_MANUAL.md 来源清单 + 构建方法 + 架构说明
25+
```
26+
27+
### 1.2 双库关系
28+
29+
```
30+
质谱库 (Level 2) 化合物库 (Level 3)
31+
deduplicated/*.msp compound_metadata.csv
32+
60 万条谱图 96 万条化合物
33+
每条内嵌 8 维标签 每条有 8 维标签
34+
数据:peaks(碎裂谱图) 数据:exact_mass(精确质量)
35+
用途:MS2 谱图匹配 用途:MS1 精确质量匹配
36+
│ │
37+
└──── InChIKey(前 14 位)────────────────┘
38+
增值关联,非必须依赖
39+
```
40+
41+
**核心原则:**
42+
- 两个库各自独立——质谱库的标签不依赖化合物库查询,化合物库的标签不依赖质谱库
43+
- InChIKey 关联是增值查询——有就补充更多信息,没有也不影响基础标签和搜索
44+
- 标签内嵌 MSP 文件——行业标准做法(MassBank/GNPS/MoNA/FragHub 均如此)
45+
- spectral_metadata.csv 是 MSP 的衍生物——从 MSP 文件自动生成,不是数据源
46+
47+
### 1.3 注释匹配流程
48+
49+
```
50+
用户选标签过滤(如 chemical_class=pfas, application=environmental_monitoring)
51+
52+
├─→ Level 2: 在 spectral_metadata.csv 按标签过滤
53+
│ → 拿到目标谱图 ID 列表
54+
│ → 只加载对应 MSP 条目做 MS2 余弦匹配
55+
│ → 命中的 feature 标注 msi_level=2
56+
57+
├─→ Level 2.5: SIRIUS/CSI:FingerID(Level 2 未命中的 features)
58+
│ → 结构预测,msi_level=3
59+
60+
├─→ Level 3: 在 compound_metadata.csv 按标签过滤
61+
│ → 只对 Level 2 未命中的 features 做精确质量匹配
62+
│ → 命中的标注 msi_level=3
63+
64+
└─→ Level 4: 分子式推算(纯算法,无需库)
65+
→ 仍未注释的标注 msi_level=4
66+
67+
用户不选标签 → 不过滤,搜全库
68+
```
69+
70+
---
71+
72+
## 2. 八维标签体系
73+
74+
### 2.1 标签定义
75+
76+
| # | 维度 | 回答的问题 | 适用范围 | 存储位置 |
77+
|---|------|-----------|---------|---------|
78+
| 1 | `chemical_class` | 化学结构属于什么类? | 所有 | MSP + compound_metadata |
79+
| 2 | `application` | 在什么领域被关注? | 所有 | MSP + compound_metadata |
80+
| 3 | `sample` | 样本基质/生物来源? | 所有 | MSP + compound_metadata |
81+
| 4 | `source` | 数据来自哪些数据库? | 所有 | MSP(Sources 字段)+ compound_metadata(sources 字段) |
82+
| 5 | `confidence` | 谱图可信度? | 谱图级 | MSP |
83+
| 6 | `instrument` | 什么仪器采集的? | 谱图级 | MSP |
84+
| 7 | `polarity` | 离子模式? | 谱图级 | MSP |
85+
| 8 | `reg_lists` | 属于哪些监管清单? | 所有 | MSP + compound_metadata |
86+
87+
### 2.2 标签值域
88+
89+
**chemical_class**(对齐 ClassyFire/NPClassifier):
90+
metabolite, lipid, fatty_acid, terpenoid, alkaloid, amino_acid_peptide, carbohydrate, steroid, nucleoside, glycan, polyketide, shikimate_phenylpropanoid, organophosphate, organohalogen, pfas, pesticide, natural_product, unknown
91+
92+
**application**
93+
pharmaceutical, environmental_monitoring, food_safety, forensic, toxicology, agrochemical, general
94+
95+
**sample**
96+
human, plant, microbial, marine, animal, water, soil, air, blood, urine, food, synthetic, natural, unknown
97+
98+
**source**
99+
massbank, gnps, hmdb, isdb, norman, msnlib, msdial, nist, respect, foodb, embl-mcf(多值分号分隔)
100+
101+
**confidence**
102+
experimental, predicted, mixed
103+
104+
**instrument**
105+
orbitrap, qtof, qqq, ion_trap, tof, ei, dart, predicted, mixed
106+
107+
**polarity**
108+
positive, negative
109+
110+
**reg_lists**
111+
norman_susdat, eu_watch_list, stockholm_pops, epa_pfas_master, epa_ccl5, cal_prop65, edc_list, pmt_list, sin_list, pesticide_list, pharmaceutical_list, drinking_water_contaminant, food_contact(多值分号分隔)
112+
113+
### 2.3 标签规则
114+
115+
- **有就标,没有就空。不猜、不推测、不用低可信度方法补。**
116+
- 允许多值——`application=pharmaceutical;environmental_monitoring`
117+
- 允许空值——空表示"未知",比不准确的标签更好
118+
- 标签来源必须可追溯——每个标签的填充方法在本文档 §4 中记录
119+
120+
---
121+
122+
## 3. 文件格式
123+
124+
### 3.1 MSP 谱图文件(标签内嵌)
125+
126+
```
127+
Name: Caffeine
128+
PrecursorMZ: 195.0877
129+
Precursor_type: [M+H]+
130+
Ion_mode: POSITIVE
131+
Collision_energy: 20
132+
Formula: C8H10N4O2
133+
InChIKey: RYYVLZVUVIJVGH-UHFFFAOYSA-N
134+
SMILES: CN1C=NC2=C1C(=O)N(C(=O)N2C)C
135+
Instrument_type: Orbitrap
136+
Sources: massbank_orbitrap_positive.msp; hmdb_predicted_positive.msp
137+
Source_count: 2
138+
Quality_score: 100
139+
Tags: chemical_class=alkaloid; application=pharmaceutical; sample=human; confidence=experimental; instrument=orbitrap; polarity=positive
140+
Num Peaks: 15
141+
53.0386 1234
142+
...
143+
```
144+
145+
`Tags:` 字段是新增的统一标签行,8 维标签用分号分隔的 key=value 格式存储。
146+
147+
### 3.2 compound_metadata.csv
148+
149+
| 字段 | 说明 |
150+
|------|------|
151+
| inchikey | 主键 |
152+
| name | 化合物名称 |
153+
| formula | 分子式 |
154+
| exact_mass | 精确质量(Level 3 匹配数据) |
155+
| smiles | SMILES 结构式 |
156+
| chemical_class | 化学类别 |
157+
| application | 应用场景 |
158+
| sample | 样本基质 |
159+
| reg_lists | 监管清单 |
160+
| sources | 数据库来源 |
161+
| kegg_id | KEGG ID |
162+
| hmdb_id | HMDB ID |
163+
| chebi_id | ChEBI ID |
164+
| lipidmaps_id | LipidMaps ID |
165+
| cas_number | CAS 号 |
166+
167+
### 3.3 spectral_metadata.csv(只读索引,从 MSP 生成)
168+
169+
| 字段 | 说明 |
170+
|------|------|
171+
| spectrum_id | 唯一标识 |
172+
| inchikey | InChIKey(关联化合物库) |
173+
| name | 化合物名称 |
174+
| precursor_mz | 前体离子质量 |
175+
| precursor_type | 加合离子类型 |
176+
| formula | 分子式 |
177+
| collision_energy | 碰撞能量 |
178+
| file_source | MSP 文件名 |
179+
| num_peaks | 峰数量 |
180+
| quality_score | 质量评分 |
181+
| chemical_class | 化学类别 |
182+
| application | 应用场景 |
183+
| sample | 样本基质 |
184+
| confidence | 可信度 |
185+
| instrument | 仪器类型 |
186+
| polarity | 离子模式 |
187+
| reg_lists | 监管清单 |
188+
| sources | 数据库来源 |
189+
190+
**生成方式**`scripts/build_spectral_metadata.py` 解析所有 MSP 文件,提取 header 字段 + Tags 行,写入 CSV。任何时候可以从 MSP 文件重新生成。
191+
192+
---
193+
194+
## 4. 标签填充策略
195+
196+
### 4.1 只使用可信来源
197+
198+
标签填充遵循"有就标,没有就空"原则。以下是每个标签维度的可信填充方法:
199+
200+
### 4.2 四层填充(按优先级)
201+
202+
**Layer 1:库级别确定性标注(零成本,100% 可信)**
203+
204+
整个库的定位决定了部分标签,无需逐条判断:
205+
206+
| 来源 | 确定性标签 |
207+
|------|-----------|
208+
| NORMAN 全部 | application=environmental_monitoring; confidence=predicted |
209+
| ISDB 全部 | chemical_class=natural_product; confidence=predicted |
210+
| HMDB experimental | confidence=experimental |
211+
| HMDB predicted | confidence=predicted |
212+
| MSnLib MCE Drug | application=pharmaceutical; confidence=experimental |
213+
| MSnLib NIH NP | chemical_class=natural_product; confidence=experimental |
214+
| MSnLib Otava Pep | chemical_class=amino_acid_peptide; confidence=experimental |
215+
| FooDB | application=food_safety; sample=food; confidence=experimental |
216+
| ReSpect | sample=plant; confidence=experimental |
217+
| NIST EPA | application=environmental_monitoring; confidence=experimental |
218+
| NIST Glycan | chemical_class=glycan; confidence=experimental |
219+
| NIST DART | confidence=experimental |
220+
221+
**Layer 2:MSP 文件已有字段(直接读取,100% 可信)**
222+
223+
| MSP 字段 | 映射到标签 | 覆盖来源 |
224+
|---------|-----------|---------|
225+
| Ion_mode | polarity | 全部(100%) |
226+
| Sources | source | 全部(100%) |
227+
| Instrument_type | instrument | MassBank, HMDB, MS-DIAL, MSnLib, FooDB, ReSpect |
228+
| ONTOLOGY(MS-DIAL) | chemical_class | MS-DIAL(93%) |
229+
230+
**Layer 3:从原始库重新提取(需额外下载/处理,100% 可信)**
231+
232+
| 来源 | 可提取标签 | 方法 |
233+
|------|-----------|------|
234+
| HMDB metabolites XML | chemical_class(ClassyFire 四级), sample(biofluid/tissue) | 下载 hmdb_metabolites.xml,InChIKey 关联 |
235+
| MassBank 原始记录 | chemical_class(CH$COMPOUND_CLASS + ChemOnt) | 下载 2025 版原始记录,重新提取 |
236+
| ReSpect SQL dump | chemical_class(化合物类), sample(植物种属) | 从原始数据重新提取 |
237+
| LipidMaps CSV | chemical_class(三级脂质分类) | 本地 CSV 已有,InChIKey 关联 |
238+
| NORMAN SusDat | reg_lists(130+ S-list 映射) | 已完成 |
239+
240+
**Layer 4:ClassyFire/NPClassifier API 计算(确定性算法,可信)**
241+
242+
对有 SMILES 但仍缺 chemical_class 的谱图/化合物:
243+
- ClassyFire API:`http://classyfire.wishartlab.com/entities/{InChIKey}.json`
244+
- NPClassifier API:`https://npclassifier.gnps2.org/classify?smiles={SMILES}`
245+
- 两者都是基于化学结构规则的确定性分类,不是统计预测
246+
247+
### 4.3 不使用的方法
248+
249+
- ❌ PubChem Name 模糊查询(命中率低,结果不可靠)
250+
- ❌ 从一个库的标签"推测"另一个库的标签
251+
- ❌ 任何统计/机器学习预测方法
252+
253+
---
254+
255+
## 5. 去重机制
256+
257+
### 5.1 去重键
258+
259+
`InChIKey前14位 + Precursor_type`
260+
261+
前 14 位代表分子骨架(connectivity layer),忽略立体化学。同一化合物的不同立体异构体共享去重键。
262+
263+
### 5.2 去重流程
264+
265+
1. 所有来源的谱图按去重键分组
266+
2. 同组内按 Quality_score(8 维评分,0-100)+ 峰数排序
267+
3. 保留质量最高的一条谱图的 peaks 数据
268+
4. 被丢弃谱图的元数据合并到保留谱图:
269+
- `Sources`:记录所有来源文件名
270+
- `Source_count`:来源数量
271+
- `Synonyms`:补充化合物别名
272+
- 缺失的 formula/collision_energy 从被丢弃谱图补充
273+
274+
### 5.3 无 InChIKey 的谱图
275+
276+
不参与去重,全部保留。标注完整的谱图级标签(confidence/instrument/polarity),化合物级标签留空。
277+
278+
---
279+
280+
## 6. 跨产品使用
281+
282+
MFSL 是独立数据资产,MetaboFlow 和 PonylabASMS 各自复制一份使用。
283+
284+
| | MetaboFlow | PonylabASMS |
285+
|---|---|---|
286+
| 搜索引擎 | matchms (cosine) | Flash Entropy Search |
287+
| 复制内容 | deduplicated/*.msp + compound_metadata.csv | 同左 |
288+
| 标签过滤 | annot-worker 读 spectral_metadata → 过滤 ID → 加载 MSP | spectral_search.py 读 Tags 字段 |
289+
| 自有扩展 || eCPIN CFM-ID 预测库 |
290+
291+
MFSL 的架构与搜索引擎无关——它只负责存储、索引、标签,不绑定匹配算法。
292+
293+
---
294+
295+
## 7. 物理文件结构
296+
297+
```
298+
~/spectral_libraries/
299+
├── DATABASE_MANUAL.md # 文档(含来源清单,原 registry.csv 内容并入)
300+
├── spectral_metadata.csv # 谱图索引(只读,从 MSP 生成)
301+
├── compound_metadata.csv # 化合物元数据(= Level 3 数据)
302+
├── deduplicated/ # MSP 峰数据(标签内嵌)
303+
│ ├── massbank_orbitrap_positive.msp
304+
│ ├── norman_positive.msp
305+
│ └── ... (50 个文件)
306+
├── norman_susdat/ # NORMAN SusDat 原始下载
307+
├── scripts/ # 构建/维护脚本
308+
│ ├── rebuild_compound_metadata.py
309+
│ ├── dedup_and_quality.py
310+
│ ├── build_spectral_metadata.py
311+
│ ├── fill_tags_msp.py # 标签写入 MSP
312+
│ ├── fill_norman_tags.py
313+
│ └── backfill_smiles_pubchem.py
314+
└── raw/ # 原始下载文件(存档)
315+
```
316+
317+
---
318+
319+
## 8. 设计决策记录
320+
321+
| 决策 | 理由 |
322+
|------|------|
323+
| 标签内嵌 MSP 而非仅存 CSV | 行业标准(MassBank/GNPS/MoNA/FragHub),自包含,不会 MSP/CSV 不同步 |
324+
| spectral_metadata.csv 是衍生物 | 从 MSP 自动生成,用于快速统计和前端展示,不是搜索必经环节 |
325+
| 8 维标签全部适用所有化合物 | reg_lists 对非环境化合物为空值,但保留维度的统一性 |
326+
| InChIKey 前 14 位跨库匹配 | 前 14 位是分子骨架,立体异构体共享,跨库匹配率从 35% 提升到 65% |
327+
| 标签只用可信来源填充 | 不猜、不推测——原始库字段、库级别确定性标注、ClassyFire API |
328+
| 两个库各自独立标签 | 质谱库 65% 谱图的化合物不在化合物库里,依赖查询会导致大量标签缺失 |
329+
| registry.csv 并入 DATABASE_MANUAL | spectral_metadata.csv 已覆盖其索引功能,registry 降为文档 |
330+
| 去重保留来源追溯 | Sources 字段记录所有数据库来源,去重不丢信息 |

0 commit comments

Comments
 (0)