|
| 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