关于 hmdb-database
使用 Python 查询本地下载的 Human Metabolome Database XML,面向代谢组学研究者,涵盖代谢物属性、生物学背景、疾病关联、谱图和跨库标识符。
主要功能
- 01按 HMDB ID 或名称查找
- 02提取化学属性与分类
- 03检索通路和生物学位置
- 04查询疾病关联及浓度范围
- 05读取 MS 和 NMR 峰数据
- 06映射多个数据库的标识符
适用场景
- 01根据质谱数据筛选代谢物
- 02分析代谢物列表的相关通路
- 03研究疾病相关生物标志物
- 04生成跨数据库 ID 对照表
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill hmdb-database安装后在 Claude Code 中输入/hmdb-database确认已加载。
详细介绍
HMDB 数据库 — 本地 XML 访问
概述
通过使用 Python 的 ElementTree 解析本地下载的 XML,查询人类代谢组数据库(HMDB,包含 220,000 多条代谢物记录)。涵盖代谢物查找、化学性质、生物学背景(通路、酶、生物流体)、疾病/生物标志物关联、用于代谢物鉴定的光谱数据,以及与 KEGG、PubChem、ChEBI 和 DrugBank 的跨数据库 ID 映射。
适用场景
- 按 HMDB ID 或名称查找代谢物信息(描述、化学类别、细胞位置)
- 获取用于代谢组学分析的化学性质(分子量、分子式、SMILES、InChI、logP、PSA)
- 查找一组代谢物的通路关联和酶链接
- 查找代谢物所在的生物流体/组织(血液、尿液、CSF、唾液)
- 查询疾病关联和正常/异常浓度范围,用于生物标志物发现
- 提取 NMR 或 MS 光谱峰列表,用于代谢物鉴定
- 将 HMDB ID 映射到 KEGG、PubChem、ChEBI、DrugBank 或其他数据库
- 如需药物专属数据(相互作用、靶点、药理学),请改用
drugbank-database-access - 如需无需下载即可实时查询化合物性质,请改用
pubchem-compound-search
前置条件
- HMDB XML 下载:在 https://hmdb.ca/downloads 注册并下载
hmdb_metabolites.xml.zip(解压后约 6 GB) - Python 包:
lxml(XPath 速度更快)或标准库xml.etree.ElementTree、pandas - 没有公共 REST API:HMDB 没有可供程序调用的 REST API。所有访问都通过解析本地 XML 或使用网页界面完成
- R 包(可选):CRAN 上的
hmdbQuery提供了一些查询封装,但功能有限且已过时 - 速率限制:本地 XML 解析不适用。网页界面没有公开的速率限制说明,但不适用于抓取
pip install lxml pandas
快速入门
import xml.etree.ElementTree as ET
NS = {'hmdb': 'http://www.hmdb.ca'}
tree = ET.parse('hmdb_metabolites.xml') # 60-120s for full XML
root = tree.getroot()
# Build lookup index (HMDB ID + lowercase name -> element)
metabolite_index = {}
for met in root.findall('hmdb:metabolite', NS):
accession = met.find('hmdb:accession', NS)
name = met.find('hmdb:name', NS)
if accession is not None and accession.text:
metabolite_index[accession.text] = met
if name is not None and name.text:
metabolite_index[name.text.lower()] = met
def find_metabolite(query):
"""Find metabolite by HMDB ID or name (case-insensitive)."""
return metabolite_index.get(query) or metabolite_index.get(query.lower())
met = find_metabolite('HMDB0000122') # Glucose
name = met.find('hmdb:name', NS).text
formula = met.find('hmdb:chemical_formula', NS).text
print(f"{name}: {formula}")
# Glucose: C6H12O6
核心 API
1. XML 设置和代谢物查找
import xml.etree.ElementTree as ET
NS = {'hmdb': 'http://www.hmdb.ca'}
tree = ET.parse('hmdb_metabolites.xml')
root = tree.getroot()
print(f"Total metabolite entries: {len(root.findall('hmdb:metabolite', NS))}")
# Total metabolite entries: ~220000+
对于内存受限的环境,请使用 iterparse:
met_names = {}
for event, elem in ET.iterparse('hmdb_metabolites.xml', events=('end',)):
if elem.tag == '{http://www.hmdb.ca}metabolite':
acc = elem.find('{http://www.hmdb.ca}accession')
name = elem.find('{http://www.hmdb.ca}name')
if acc is not None and name is not None and acc.text and name.text:
met_names[acc.text] = name.text
elem.clear()
print(f"Parsed {len(met_names)} metabolites via iterparse")
2. 化学性质
def get_chemical_properties(met_element):
"""Extract chemical properties from a metabolite entry."""
def txt(path):
el = met_element.find(path, NS)
return el.text if el is not None and el.text else None
# Fields: accession, name, chemical_formula, average_molecular_weight,
# monisotopic_molecular_weight, smiles, inchi, inchikey, state, iupac_name
return {tag: txt(f'hmdb:{tag}') for tag in [
'accession', 'name', 'chemical_formula', 'average_molecular_weight',
'monisotopic_molecular_weight', 'smiles', 'inchi', 'inchikey', 'state']}
props = get_chemical_properties(find_metabolite('HMDB0000158')) # L-Tyrosine
print(f"{props['name']}: MW={props['average_molecular_weight']}, SMILES={props['smiles']}")
# Extract taxonomy / chemical classification (ClassyFire ontology)
def get_classification(met_element):
tax = met_element.find('hmdb:taxonomy', NS)
if tax is None:
return {}
def txt(tag):
el = tax.find(f'hmdb:{tag}', NS)
return el.text if el is not None and el.text else None
return {'kingdom': txt('kingdom'), 'super_class': txt('super_class'),
'class': txt('class'), 'sub_class': txt('sub_class'),
'direct_parent': txt('direct_parent')}
print(get_classification(find_metabolite('HMDB0000122')))
# {'kingdom': 'Organic compounds', 'super_class': 'Organooxygen compounds', ...}
3. 生物学背景
def get_pathways(met_element):
"""Extract metabolic pathway associations."""
pathways = []
for pw in met_element.findall('hmdb:pathways/hmdb:pathway', NS):
name = pw.find('hmdb:name', NS)
smpdb_id = pw.find('hmdb:smpdb_id', NS)
kegg_id = pw.find('hmdb:kegg_map_id', NS)
pathways.append({
'name': name.text if name is not None else None,
'smpdb_id': smpdb_id.text if smpdb_id is not None else None,
'kegg_map_id': kegg_id.text if kegg_id is not None else None,
})
return pathways
for pw in get_pathways(find_metabolite('HMDB0000122'))[:5]:
print(f" {pw['smpdb_id']}: {pw['name']}")
def get_biolocations(met_element):
"""Extract biofluid, tissue, and cellular locations."""
bp = 'hmdb:biological_properties/hmdb:'
def texts(path):
return [el.text for el in met_element.findall(path, NS) if el.text]
return {'biofluids': texts(f'{bp}biospecimen_locations/hmdb:biospecimen'),
'tissues': texts(f'{bp}tissue_locations/hmdb:tissue'),
'cellular': texts(f'{bp}cellular_locations/hmdb:cellular')}
locs = get_biolocations(find_metabolite('HMDB0000122'))
print(f"Glucose biofluids: {locs['biofluids']}")
def get_enzymes(met_element):
"""Extract associated enzymes/proteins with UniProt IDs."""
return [{'name': (p.find('hmdb:name', NS).text
if p.find('hmdb:name', NS) is not None else None),
'uniprot_id': (p.find('hmdb:uniprot_id', NS).text
if p.find('hmdb:uniprot_id', NS) is not None else None),
'gene_name': (p.find('hmdb:gene_name', NS).text
if p.find('hmdb:gene_name', NS) is not None else None)}
for p in met_element.findall('hmdb:protein_associations/hmdb:protein', NS)]
enz = get_enzymes(find_metabolite('HMDB0000122'))
print(f"Glucose-associated proteins: {len(enz)}")
for e in enz[:3]:
print(f" {e['gene_name']} ({e['uniprot_id']}): {e['name']}")
4. 疾病和生物标志物查询
def get_diseases(met_element):
"""Extract disease associations with OMIM IDs and PubMed references."""
diseases = []
for d in met_element.findall('hmdb:diseases/hmdb:disease', NS):
name = d.find('hmdb:name', NS)
omim = d.find('hmdb:omim_id', NS)
pmids = [r.find('hmdb:pubmed_id', NS).text
for r in d.findall('hmdb:references/hmdb:reference', NS)
if r.find('hmdb:pubmed_id', NS) is not None and r.find('hmdb:pubmed_id', NS).text]
diseases.append({'name': name.text if name is not None else None,
'omim_id': omim.text if omim is not None else None,
'pubmed_ids': pmids})
return diseases
diseases = get_diseases(find_metabolite('HMDB0000122'))
print(f"Glucose disease associations: {len(diseases)}")
for d in diseases[:3]:
print(f" {d['name']} (OMIM: {d['omim_id']})")
def get_concentrations(met_element, biospecimen='Blood'):
"""Extract normal/abnormal concentration data filtered by biospecimen."""
result = {'normal': [], 'abnormal': []}
for ctype, key in [('normal_concentrations', 'normal'),
('abnormal_concentrations', 'abnormal')]:
for c in met_element.findall(f'hmdb:{ctype}/hmdb:concentration', NS):
bio = c.find('hmdb:biospecimen', NS)
if bio is None or bio.text != biospecimen:
continue
def txt(tag):
el = c.find(f'hmdb:{tag}', NS)
return el.text if el is not None else None
result[key].append({'value': txt('concentration_value'),
'units': txt('concentration_units'),
'condition': txt('subject_condition')})
return result
conc = get_concentrations(find_metabolite('HMDB0000122'), 'Blood')
print(f"Glucose blood: {len(conc['normal'])} normal, {len(conc['abnormal'])} abnormal")
5. 光谱数据
def get_ms_spectra(met_element):
"""Extract MS/MS spectral peak lists (m/z + intensity)."""
spectra = []
for spec in met_element.findall('hmdb:spectra/hmdb:spectrum', NS):
stype = spec.find('hmdb:type', NS)
if stype is None or 'MS' not in (stype.text or ''):
continue
peaks = [{'mz': float(p.find('hmdb:mass_charge', NS).text),
'intensity': float(p.find('hmdb:intensity', NS).text or 0)}
for p in spec.findall('hmdb:ms_ms_peaks/hmdb:ms_ms_peak', NS)
if p.find('hmdb:mass_charge', NS) is not None
and p.find('hmdb:mass_charge', NS).text]
spectra.append({'type': stype.text, 'num_peaks': len(peaks), 'peaks': peaks})
return spectra
spectra = get_ms_spectra(find_metabolite('HMDB0000122'))
print(f"Glucose MS spectra: {len(spectra)}")
def get_nmr_spectra(met_element):
"""Extract NMR spectral peak lists (1H, 13C). Same pattern as MS above."""
spectra = []
for spec in met_element.findall('hmdb:spectra/hmdb:spectrum', NS):
stype = spec.find('hmdb:type', NS)
if stype is None or 'NMR' not in (stype.text or ''):
continue
nucleus = spec.find('hmdb:nucleus', NS)
shifts = [float(p.find('hmdb:chemical_shift', NS).text)
for p in spec.findall('hmdb:nmr_one_d_peaks/hmdb:nmr_one_d_peak', NS)
if p.find('hmdb:chemical_shift', NS) is not None
and p.find('hmdb:chemical_shift', NS).text]
spectra.append({'type': stype.text,
'nucleus': nucleus.text if nucleus is not None else None,
'num_peaks': len(shifts), 'chemical_shifts': shifts})
return spectra
nmr = get_nmr_spectra(find_metabolite('HMDB0000122'))
print(f"Glucose NMR spectra: {len(nmr)}")
6. 跨数据库映射
def get_external_ids(met_element):
"""Extract cross-database identifiers (KEGG, PubChem, ChEBI, DrugBank, CAS, etc.)."""
fields = {'kegg_id': 'KEGG', 'pubchem_compound_id': 'PubChem', 'chebi_id': 'ChEBI',
'drugbank_id': 'DrugBank', 'chemspider_id': 'ChemSpider',
'cas_registry_number': 'CAS', 'biocyc_id': 'BioCyc', 'pdb_id': 'PDB',
'foodb_id': 'FooDB', 'metlin_id': 'METLIN'}
ids = {}
for tag, label in fields.items():
el = met_element.find(f'hmdb:{tag}', NS)
if el is not None and el.text:
ids[label] = el.text
return ids
ids = get_external_ids(find_metabolite('HMDB0000122'))
print(f"Glucose cross-refs: {ids}")
# {'KEGG': 'C00031', 'PubChem': '5793', 'ChEBI': '17234', ...}
# Build cross-reference table for a metabolite list
import pandas as pd
queries = ['HMDB0000122', 'HMDB0000158', 'HMDB0000167', 'HMDB0000148']
rows = []
for q in queries:
m = find_metabolite(q)
if m is None: continue
ids = get_external_ids(m)
rows.append({'name': m.find('hmdb:name', NS).text, 'hmdb_id': q,
'kegg': ids.get('KEGG'), 'pubchem': ids.get('PubChem'),
'chebi': ids.get('ChEBI')})
print(pd.DataFrame(rows).to_string(index=False))
关键概念
HMDB XML 条目结构
| 部分 | XPath | 内容 |
|---|---|---|
| 标识信息 | hmdb:accession、hmdb:name、hmdb:iupac_name | 主要标识符 |
| 化学信息 | hmdb:chemical_formula、hmdb:smiles、hmdb:inchi | 结构描述符 |
| 性质 | hmdb:average_molecular_weight、hmdb:state | 物理性质 |
| 分类 | hmdb:taxonomy/hmdb:kingdom、class 等 | 化学分类 |
| 生物学信息 | hmdb:biological_properties | 生物流体、组织、细胞位置 |
| 通路 | hmdb:pathways/hmdb:pathway | SMPDB + KEGG 通路链接 |
| 酶 | hmdb:protein_associations/hmdb:protein | 关联蛋白质/酶 |
| 疾病 | hmdb:diseases/hmdb:disease | 疾病关联 + OMIM ID |
| 浓度 | hmdb:normal_concentrations、hmdb:abnormal_concentrations | 生物标志物参考范围 |
| 光谱 | hmdb:spectra/hmdb:spectrum | NMR、MS/MS 峰列表 |
| 外部 ID | hmdb:kegg_id、hmdb:pubchem_compound_id 等 | 跨数据库标识符 |
| 本体 | hmdb:ontology | 生理/处置/过程角色 |
数据字段完整性
并非所有条目都包含全部字段。字段覆盖率因代谢物类别而异:
| 字段类别 | 大致覆盖率 | 说明 |
|---|---|---|
| 登录号、名称、分子式 | ~100% | 始终存在 |
| SMILES、InChI、MW | ~90% | 部分脂质和复杂代谢物缺失 |
| 分类学/分类 | ~85% | 来自 ClassyFire 的化学本体 |
| 生物流体分布位置 | ~60% | 常见人体代谢物的数据最完整 |
| 通路 | ~40% | 经整理的 SMPDB + KEGG 链接 |
| 蛋白质关联 | ~35% | 酶-代谢物关系 |
| 疾病关联 | ~25% | 主要针对生物标志物代谢物 |
| 正常浓度 | ~20% | 临床代谢物的参考范围 |
| MS/MS 谱图 | ~15% | 实验谱图库 |
| NMR 谱图 | ~10% | 1H 和 13C 化学位移数据 |
文件格式比较
| 格式 | 文件 | 大小 | 最适用场景 |
|---|---|---|---|
| 完整 XML | hmdb_metabolites.xml | ~6 GB | 访问完整数据(所有字段) |
| SDF | structures.sdf | ~200 MB | 化学结构 + 基本属性 |
| CSV | 各类导出文件 | ~50-500 MB | 表格数据(属性、浓度) |
| FASTA | hmdb_proteins.fasta | ~50 MB | 蛋白质序列查询 |
常见工作流
工作流 1:通过质谱进行代谢物鉴定
目标:使用分子量,将观测到的 m/z 值与候选代谢物进行匹配。假设已从快速入门中获取 root、NS。
import pandas as pd
observed_mz = 180.063 # [M+H]+ for glucose
adduct_mass = 1.00728 # H+ adduct
target_mw = observed_mz - adduct_mass
tolerance_da = 0.01
candidates = []
for met in root.findall('hmdb:metabolite', NS):
mw_el = met.find('hmdb:monisotopic_molecular_weight', NS)
if mw_el is None or not mw_el.text:
continue
mw = float(mw_el.text)
if abs(mw - target_mw) <= tolerance_da:
candidates.append({
'hmdb_id': met.find('hmdb:accession', NS).text,
'name': met.find('hmdb:name', NS).text,
'mw': mw, 'delta_da': abs(mw - target_mw),
'formula': (met.find('hmdb:chemical_formula', NS).text
if met.find('hmdb:chemical_formula', NS) is not None else None),
})
df = pd.DataFrame(candidates).sort_values('delta_da')
print(f"Candidates within {tolerance_da} Da of {target_mw:.3f}: {len(df)}")
print(df.head(10).to_string(index=False))
工作流 2:发现疾病生物标志物
目标:查找与某种疾病相关的所有代谢物及其浓度变化。假设已从快速入门中获取 root、NS。
import pandas as pd
disease_query = 'diabetes'
biomarkers = []
for met in root.findall('hmdb:metabolite', NS):
for d in met.findall('hmdb:diseases/hmdb:disease', NS):
dname = d.find('hmdb:name', NS)
if dname is None or not dname.text:
continue
if disease_query.lower() not in dname.text.lower():
continue
abnormal = [c for c in met.findall(
'hmdb:abnormal_concentrations/hmdb:concentration', NS)
if c.find('hmdb:subject_condition', NS) is not None
and disease_query.lower() in
(c.find('hmdb:subject_condition', NS).text or '').lower()]
biomarkers.append({
'hmdb_id': met.find('hmdb:accession', NS).text,
'metabolite': met.find('hmdb:name', NS).text,
'disease': dname.text,
'abnormal_measurements': len(abnormal),
})
df = pd.DataFrame(biomarkers).drop_duplicates(['hmdb_id', 'disease'])
print(f"Metabolites linked to '{disease_query}': {len(df)}")
print(df.sort_values('abnormal_measurements', ascending=False).head(15).to_string(index=False))
工作流 3:根据代谢物列表进行通路富集分析
目标:给定已鉴定代谢物列表,查找过度代表的通路。假设已从快速入门中获取 metabolite_index。
from collections import Counter
import pandas as pd
hit_ids = ['HMDB0000122', 'HMDB0000158', 'HMDB0000167',
'HMDB0000148', 'HMDB0000064', 'HMDB0000161']
hit_pathways = Counter()
for hid in hit_ids:
met = metabolite_index.get(hid)
if met is None:
continue
for pw in met.findall('hmdb:pathways/hmdb:pathway', NS):
pw_name = pw.find('hmdb:name', NS)
if pw_name is not None and pw_name.text:
hit_pathways[pw_name.text] += 1
enriched = [(pw, count) for pw, count in hit_pathways.most_common() if count >= 2]
df = pd.DataFrame(enriched, columns=['Pathway', 'Hit_Count'])
print(f"Pathways with 2+ hits from {len(hit_ids)} metabolites:")
print(df.to_string(index=False))
关键参数
| 参数 | 函数/端点 | 默认值 | 说明 |
|---|---|---|---|
NS(命名空间字典) | 所有 XPath 查询 | {'hmdb': 'http://www.hmdb.ca'} | 所有 find/findall 调用都必须提供 |
tolerance_da | MW 匹配 | 0.01 | 代谢物 ID 匹配的质量容差,单位为道尔顿 |
biospecimen | get_concentrations() | 'Blood' | 筛选条件:Blood、Urine、Cerebrospinal Fluid (CSF)、Saliva 等 |
events | ET.iterparse() | ('end',) | 解析事件;使用 ('end',) 可在遇到结束标签时触发 |
| 加合物质量 | MS 鉴定 | 不定 | 1.00728 [M+H]+、22.9892 [M+Na]+、-1.00728 [M-H]- |
target_type | 谱图查询 | 'MS' 或 'NMR' | 按类型字符串筛选谱图 |
最佳实践
- 启动时构建内存索引:只解析一次(60-120s),按 HMDB ID 和小写名称构建字典。不要在循环中重新解析
- 始终传入命名空间字典:每个
find()/findall()都需要NS = {'hmdb': 'http://www.hmdb.ca'}。省略该参数会返回空结果 - 内存受限时使用 iterparse:完整 XML 需要约 8-12 GB RAM。使用 iterparse 中的
elem.clear()增量处理 - 处理 None 和空文本:许多可选字段可能不存在。访问前始终检查
el is not None and el.text - MS 匹配使用单同位素质量:
monisotopic_molecular_weight适用于质谱;其他计算使用average_molecular_weight - 大型搜索前按化学类别预筛选:使用分类学/分类,在遍历全部 220K+ 条目之前缩小搜索范围
常用方法
方法:将所有代谢物属性导出为 CSV
适用场景:创建包含所有代谢物关键属性的扁平表格。
import pandas as pd
records = []
for met in root.findall('hmdb:metabolite', NS):
def txt(p):
el = met.find(p, NS)
return el.text if el is not None and el.text else None
records.append({'hmdb_id': txt('hmdb:accession'), 'name': txt('hmdb:name'),
'formula': txt('hmdb:chemical_formula'),
'avg_mw': txt('hmdb:average_molecular_weight'),
'smiles': txt('hmdb:smiles')})
pd.DataFrame(records).to_csv('hmdb_properties.csv', index=False)
print(f"Exported {len(records)} metabolites")
方法:按生物流体查找代谢物
适用场景:获取在特定生物流体中检测到的所有代谢物(例如,临床筛查中的尿液)。
biofluid = 'Urine'
urine_mets = []
for met in root.findall('hmdb:metabolite', NS):
for bf in met.findall(
'hmdb:biological_properties/hmdb:biospecimen_locations/hmdb:biospecimen', NS):
if bf.text and bf.text == biofluid:
urine_mets.append({
'hmdb_id': met.find('hmdb:accession', NS).text,
'name': met.find('hmdb:name', NS).text,
})
break
print(f"Metabolites in {biofluid}: {len(urine_mets)}")
方法:化学类别分布
适用场景:汇总命中列表或整个数据库中的代谢物化学类别。
from collections import Counter
class_counts = Counter()
for met in root.findall('hmdb:metabolite', NS):
tax = met.find('hmdb:taxonomy', NS)
if tax is not None:
sc = tax.find('hmdb:super_class', NS)
if sc is not None and sc.text:
class_counts[sc.text] += 1
print(dict(class_counts.most_common(10)))
故障排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
对已知元素调用 find() 返回 None | 缺少 XML 命名空间 | 始终传入 NS = {'hmdb': 'http://www.hmdb.ca'} |
解析完整 XML 时出现 MemoryError | 需要约 8-12 GB 内存 | 使用 ET.iterparse() 和 elem.clear() |
| 启动缓慢(>120s) | 解析 6 GB XML | 只解析一次并构建索引字典;避免重复解析 |
| 按名称未找到代谢物 | 区分大小写或存在同义词 | 统一转换为小写;直接尝试 HMDB ID |
| 某代谢物的谱图为空 | 并非所有条目都有谱图(覆盖率约为 10-15%) | 查看覆盖率表;使用 METLIN 或 MassBank 获取更多谱图 |
| 缺少浓度数据 | 仅涵盖研究充分的临床代谢物(约 20%) | 与 MetaboAnalyst 或文献交叉核对 |
| 同一化合物存在重复条目 | 次级登录号(HMDB00XXXXX 与 HMDB0000XXXX) | 使用 accession(主登录号),而不是 secondary_accessions |
ET.iterparse 缺少数据 | 过早调用 elem.clear() | 仅在从元素中提取完所有所需字段后再清除 |
随附资源
独立条目。原始参考文件 hmdb_data_fields.md(268 行,包含字段目录及 XML 元素名称和说明)已整合至上文“核心概念”中的“HMDB XML 条目结构”表和“数据字段完整性”表。字段目录中各元素的 XML 标签名称已在核心 API 代码块中展示。原文中未包含的内容:Web 界面说明(非程序化内容)。
相关技能
- drugbank-database-access -- 药物专属数据(相互作用、靶点、药理学),采用类似的本地 XML 解析模式
- pubchem-compound-search -- 无需下载即可查询实时化合物属性;PubChemPy REST API
- kegg-database -- 通路和化合物数据库,提供 REST API,可交叉查询 HMDB 通路匹配结果
- matchms-spectral-matching -- 与参考库进行谱图相似性匹配;可补充 HMDB 谱图数据
- pyopenms-mass-spectrometry -- 完整的 LC-MS/MS 处理流程;使用 HMDB 执行代谢物鉴定步骤
参考资料
- HMDB 网站和下载: https://hmdb.ca/
- Wishart DS 等(2022)。HMDB 5.0:2022 年人类代谢组数据库。Nucleic Acids Res. 50(D1):D801-D816. https://doi.org/10.1093/nar/gkab1062
- HMDB 数据下载页: https://hmdb.ca/downloads
- MetaboAnalyst(配套工具): https://www.metaboanalyst.ca/