信息速览
INFOBOX — IGVF Catalog 一屏速览
维度 内容 本质 图数据库(节点 + 边),不是表 出资方 NIH / NHGRI 建设方 IGVF 数据协调中心(DACC) 规模 50+ 类集合、近 30 亿节点、超 75 亿条边(官方) 网页入口 catalog.igvf.orgAPI api.catalogkg.igvf.org/api(注意不是 api.catalog.igvf.org)端点数 文档列出 84 个 API 页面 查询方式 REST + Cypher 基因组版本 人类 GRCh38、小鼠 GRCm39 坐标约定 0-based, half-open 许可 数据 CC、软件 MIT 发表 Nucleic Acids Res 2026;54(D1):D1437–D1445 最该记住的一条 边比节点重要——方法(method)是边的一等属性
§1 速览:它到底是什么
1.1 一句话定义
IGVF Catalog 是 IGVF 联盟把「变异 → 功能」这条因果链拆成图结构之后,交给外界查询的那个出口。
它不是一个数据集,而是一个查询层:下面接着 50 多类数据集合,上面接着 84 个 REST 端点和一套 Cypher 查询界面。
1.2 它为什么不是「又一个变异注释库」
市面上变异注释库不少,gnomAD 给频率、ClinVar 给临床意义、dbNSFP 给保守性打分。IGVF Catalog 的不可替代之处不在注释本身,而在于它把「变异影响什么」这件事写成了边。
具体说,一条「基因-变异」边长这样(这是实测返回的真实结构):
{
"gene": "genes/ENSG00000012048",
"sequence_variant": "variants/NC_000017.11:43346664:A:C",
"effect_size": -0.501033,
"neg_log10_pvalue": 9.736517795947131,
"p_value": 1.83435e-10,
"z_score": -6.92279248950608,
"standard_error": 0.0743942,
"posterior_inclusion_probability": 0.00466353018478993,
"credible_set_min_r2": 0.868777982440479,
"method": "eQTL",
"source": "EBI",
"biological_context": "liver",
"biosample_term": "ontology_terms/UBERON_0001114",
"study": "studies/QTS000015",
"class": "observed data",
"label": "eQTL",
"name": "expression modulated by"
}
这条记录里有四项是普通变异注释库不会给的:
| 字段 | 为什么关键 |
|---|---|
effect_size + p_value |
不是"有没有关联",是"关联多强" |
method |
eQTL 还是 spliceQTL?同一个变异对同一个基因,两种方法的结论可以不同 |
biological_context |
liver——这个关联只在肝组织成立,不是全身 |
credible_set_min_r2 |
这个变异是可信集里的成员,还是仅仅与它连锁 |
决策卡:你该不该用它
你的问题 IGVF Catalog 能不能回答 这个变异影响哪个基因的表达? ✅ 能,且给效应量与组织 这个变异影响剪接吗? ✅ 能, method=spliceQTL这个变异在东亚人群的频率? ⚠️ 能,但注释原样继承 gnomAD,人群代表性受上游限制 这个变异和什么疾病相关? ✅ 能,来自 ClinGen / GenCC / Orphanet / GWAS 这个变异在哪个细胞类型是活跃的? ✅ 能,走 variants/genomic-elements与 biosample 端点这个变异会不会致病? ❌ 不能直接回答——它给关联与预测,不给致病性判定
换个角度,按你的处境看:
| 你的处境 | 它能帮你什么 |
|---|---|
| 手上有一批 GWAS 位点,想知道各自的分子机制线索 | 每个位点一条命令拿到 eQTL + 表型 + 调控元件三类边,不用跨七个库 |
| 做 eQTL 分析,需要找已有的显著关联做阳性对照 | 按基因查边,p_value 与 biological_context 直接可用 |
| 训变异效应预测模型,缺大规模标注 | 拿 class=observed data 的 MPRA/SGE 边,比自建便宜得多 |
| 做药物靶点评估,想知道变异与药物的既有证据 | variants/drugs 端点,来源 pharmGKB |
| 只想下一个变异注释表 | 不必用它——去 gnomAD 或 dbNSFP,更快更直接 |
| 要出临床报告 | 不要用它——它不做 ACMG 分级 |
一句话判断:当你的问题需要「跨两个以上实体类型」时才用它,单实体单属性的问题它有更简单的替代品。
1.3 一个贯穿全文的案例:rs7412
rs7412 是 APOE 的经典位点(决定 ε2 等位),也是"同一个位点在不同尺度上表现完全不同"的绝好样本。全文用它串起各层。
先看它在 Catalog 里的基础身份(实测):
{
"_id": "NC_000019.10:44908821:C:T",
"chr": "chr19",
"pos": 44908821,
"ref": "C",
"alt": "T",
"rsid": ["rs7412"],
"spdi": "NC_000019.10:44908821:C:T",
"source": "FAVOR",
"annotations": {
"gnomad_af_total": 0.0788183,
"gnomad_af_nfe": 0.080996,
"bravo_af": 0.0726
}
}
从这一条记录就能读出 IGVF Catalog 的组织方式:
_id是 SPDI 格式(序列标识:位置:参考:替代),不是 rsID。rsID 只是一个可查询的别名——这是图谱库的标准做法,因为 rsID 会合并、会拆分,SPDI 不会。annotations是一组频率,实测 rs80357906 这条记录里有 33 个键,其中 30 个是 gnomAD 的 ancestry × sex 分层。source是FAVOR——说明这条变异的注释来自外部资源,不是 IGVF 自己产的。
然后同样是 rs7412,换一个视角就完全不同。 查它的表型关联(实测):
| 表型 | 关联条数(前 100 条内) | 来源 |
|---|---|---|
| blood protein measurement | 23 | OpenTargets |
| total cholesterol measurement | 13 | OpenTargets |
| low density lipoprotein cholesterol measurement | 10 | OpenTargets |
| coronary artery disorder | 4 | OpenTargets |
| alzheimer disease | 3 | OpenTargets |
| longevity | 2 | OpenTargets |
其中 LDL 胆固醇那一条的统计量(实测):
phenotype_term: low density lipoprotein cholesterol measurement
study: studies/GCST90090990
neg_log10_pvalue: 208.69897000433602 ← 即 p ≈ 2e-209
beta: 0
source: OpenTargets
method: GWAS
注意
neg_log10_pvalue是 208.7,而beta是 0。 这不是数据错误,而是 GWAS 汇总统计里常见的现象:效应量未标准化或以 0 占位,但显著性是真的。 这类字段的不一致,正是 §7 要讲的第一条使用风险。
1.4 它不适合谁
| 你的需求 | 为什么不合适 |
|---|---|
| 下载原始测序数据 | 它不含读段,只有图关系。要去 data.igvf.org |
| 做全基因组关联分析 | 它是关联的汇总库,不是分析工具 |
| 需要表格式全量表 | 它是图,导出成表会丢掉边的语义 |
| 做临床报告 | 它给关联强度,不给致病性判定,不能替代 ACMG 分级 |
§2 数据构成与规格
2.1 官方公布的规模
来自 2026 年《Nucleic Acids Research》论文原文:
All data are organized within a graph database comprising over 50 types of data collections with nearly 3 billion nodes and over 7.5 billion edges.
拆成可核对的三个数:
| 指标 | 官方值 | 含义 |
|---|---|---|
| 数据集合类型 | 50+ | 不是 50 张表,是 50 多种「节点类型 + 边类型」 |
| 节点 | 近 30 亿 | 实体实例总数 |
| 边 | 超 75 亿 | 关系实例总数 |
边比节点多 2.5 倍,这个比例本身就说明问题:这是个关系密集型的图。平均每个节点挂 2.5 条边——意味着大部分节点的价值不在自身,而在它的连接。
对比一下:如果把 IGVF Catalog 当成表来用,你会得到 50 多张宽表;但按它本来的形状用,你会得到「从变异出发,两步走到疾病」这种查询能力。这是 §5 要讲的重点。
2.2 文档里列出的数据源
官方文档的 Data Sources 页列出了 Catalog 引用的门户文件,实测其中:
| 门户 | 文件条目数 |
|---|---|
ENCODE(ENCFF*) |
75 |
IGVF(IGVFFI*) |
56 |
这里的文件不是全量清单,而是"被边的 files_filesets 字段引用到的那些"。 换句话说,只有产生了边的文件才会出现在这里——没被任何边引用的文件,对图谱不可见。
每个文件记录带四个属性:
| 属性 | 例子 |
|---|---|
| Portal | encode |
| Format | bed / bigWig / bigInteract / txt |
| Assay | DNase-seq / TF ChIP-seq / MPRA |
| Lab | Jesse Engreitz, Stanford / Nadav Ahituv, UCSF |
| Status | released / archived |
Status 这一列值得单独说:实测清单里同时存在 released 和 archived。archived 的文件仍被边引用——意味着基于它的关联在数据层面还存在,但上游已不再维护。做长期依赖时,这一列必须看。
2.3 节点类型:官方文档给出的 17 类
从官方文档索引(llms.txt)里可以完整读出节点导航:
| 节点 | 标识符体系 | 实测示例 |
|---|---|---|
| Gene | Ensembl gene ID | ENSG00000012048(BRCA1) |
| Transcript | Ensembl transcript ID | ENST00000648701 |
| Variant | SPDI | NC_000019.10:44908821:C:T |
| Protein | Ensembl protein ID | ENSP00000373106 |
| Motif | HOCOMOCO ID | — |
| Phenotype | ontology term | ontology_terms/EFO_0004611 |
| Drug | — | — |
| Pathway | Reactome ID | — |
| GO Term | GO ID | — |
| Complex | — | — |
| PMID | PubMed ID | — |
| Ontology Terms | EFO / UBERON / MONDO / CLO / BAO / GO | AfPO_0000056 |
| Disease | MONDO / Orphanet | — |
| Study | GWAS Catalog study ID | studies/GCST90090990 |
| Region | 坐标区间 | — |
| Genomic Element | IGVF/ENCODE 元件 ID | — |
| Biosample | CL / UBERON | — |
17 类节点,但没有一类是"IGVF 私有"的命名——每一类都挂在公认的标识符体系上。这是它能与外部资源互操作的前提,也是 §7 讲"为什么它的关联可信"的依据。
2.4 一条基因记录的逐行解剖
实测 GET /api/genes?name=BRCA1 返回:
{
"_id": "ENSG00000012048",
"name": "BRCA1",
"chr": "chr17",
"start": 43044294,
"end": 43170245,
"gene_type": "protein_coding",
"strand": "-",
"hgnc": "HGNC:1100",
"entrez": "ENTREZ:672",
"source": "GENCODE",
"version": "v43",
"source_url": "https://ftp.ebi.ac.uk/pub/databases/gencode/Gencode_human/release_43/gencode.v43.chr_patch_hapl_scaff.annotation.gtf.gz",
"synonyms": ["RNF53", "BRCAI", "BRCC1", "FANCS", "PPP1R53", "PSCP", ...]
}
几个必须读出来的细节:
① start / end 用的是 0-based half-open。 43044294 到 43170245,实际长度是 43170245 - 43044294 = 125,951 bp。如果你按 1-based inclusive 去理解,会错一个碱基。 这不是小事——差一个碱基在剪接位点附近就可能是另一个结论。
② source 是 GENCODE,version 是 v43。 基因坐标不是 IGVF 自己算的,是 GENCODE 的版本快照。换 GENCODE 版本,坐标会变。 引用时必须带版本。
③ synonyms 里没有 BRCA1 本身。 别名列表是历史名与功能名。做基因名匹配时不要只查主名,,要查 synonyms。
④ 三个标识符并存:Ensembl(_id)、HGNC、Entrez。跨库关联时用哪个取决于对方用什么——这三个都存在,是为了不用做映射表。
2.5 一个必须知道的设计:坐标与基因组版本
官方 OpenAPI 描述里写得很明确:
Our database uses 0-based, half-open coordinates for genomic coordinates in the GRCh38 (human) and GRCm39 (mouse) reference genomes.
| 物种 | 参考基因组 | 坐标约定 |
|---|---|---|
| 人 | GRCh38 | 0-based, half-open |
| 小鼠 | GRCm39 | 0-based, half-open |
这里有一个细节容易被忽略:SPDI 格式里的序列号是带版本号的,如 NC_000019.10(GRCh38 的 19 号染色体第 10 版)。而 chr 字段只写 chr19,不带版本。 所以:
- 用
_id/spdi引用 → 版本明确,安全 - 用
chr+pos引用 → 版本隐含,必须自己记住是 GRCh38
这是"同一个变异两个字段表述"带来的实际风险。建议一律用
spdi或variant_id作为主键传递。
§3 身份层:一个变异在图上叫什么
3.1 五种标识符,五种用途
/variants 端点接受五种标识参数(实测均在 OpenAPI 中定义):
| 参数 | 格式 | 实测示例 | 什么时候用 |
|---|---|---|---|
spdi |
序列:位置:参考:替代 |
NC_000020.11:3658947:A:G |
最稳,版本明确 |
variant_id |
同 spdi | NC_000020.11:3658947:A:G |
同上(两者实测等价) |
hgvs |
HGVS 表达 | NC_000020.11:g.3658948A>G |
从论文里抄来的写法 |
rsid |
dbSNP rs 号 | rs80357906 |
从文献/芯片结果里来的 |
ca_id |
ClinGen Allele ID | CA739473472 |
从 ClinGen 体系来的 |
关键实测发现:hgvs 与 spdi 的位置相差 1。
同一条变异:
spdi = NC_000020.11:3658947:A:G ← 位置 3658947
hgvs = NC_000020.11:g.3658948A>G ← 位置 3658948
这不是错误,是两套坐标约定的必然结果:SPDI 用 0-based,HGVS 用 1-based。所以 hgvs 的位置永远比 spdi 大 1。
踩坑场景:你在论文里看到
g.3658948A>G,想确认是哪个变异,于是拿3658948去查spdi——查不到。要用hgvs=参数,或者手动减 1。
3.2 rsID 不是主键,是一个可查询的别名
实测 rs80357906 的返回:
{
"_id": "NC_000017.11:43057062:GGG:GGGG",
"rsid": ["rs80357906"],
"spdi": "NC_000017.11:43057062:GGG:GGGG",
"hgvs": "NC_000017.11:g.43057065_43057066insG"
}
rsid 是一个数组,不是字符串。原因:dbSNP 会合并位点,同一个变异可能历史上对应多个 rs 号。
这条记录还展示了一个更麻烦的情况:ref 是 GGG,alt 是 GGGG——这是插入,不是单碱基替换。而 hgvs 写的是 43057065_43057066insG,插入位点在两个碱基之间。
所以从 ref/alt 到 hgvs 不是简单拼接,中间的坐标换算由 Catalog 完成。这也是为什么应该用 spdi 传参——它是机械可算的,hgvs 不是。
3.3 一条变异记录里有什么
实测 rs80357906(BRCA2 的一个致病变异)的完整字段:
| 字段 | 值 | 说明 |
|---|---|---|
organism |
Homo sapiens |
物种 |
_id |
NC_000017.11:43057062:GGG:GGGG |
SPDI 主键 |
chr |
chr17 |
染色体(无版本) |
pos |
43057062 |
0-based 位置 |
rsid |
["rs80357906"] |
别名数组 |
ref / alt |
GGG / GGGG |
参考与替代序列 |
spdi |
同 _id |
— |
hgvs |
NC_000017.11:g.43057065_43057066insG |
1-based |
ca_id |
null |
这条没有 ClinGen Allele ID |
qual |
"." |
占位值 |
files_filesets |
null |
无关联文件集 |
annotations |
33 个键 | 频率与注释 |
source |
FAVOR |
注释来源 |
source_url |
http://favor.genohub.org/ |
— |
ca_id 是 null、qual 是 "."、files_filesets 是 null——三个字段都是空占位。 这说明:
字段存在不代表有值。 图谱类数据库的 schema 是"最大公约数",不是"每条记录都齐全"。做批量解析时,
null和"."必须都能处理。
3.4 把五种标识符串起来:一个实际的换算
看同一件事用五种写法各是什么样。这里用 §1.3 的案例:
| 写法 | 值 |
|---|---|
| rsID | rs7412 |
| SPDI | NC_000019.10:44908821:C:T |
variant_id |
NC_000019.10:44908821:C:T(与 SPDI 相同) |
| HGVS | NC_000019.10:g.44908822C>T |
| CA ID | 视该变异是否有 ClinGen 记录(rs80357906 实测为 null) |
位置差 1 在这里又出现了一次:SPDI 是 44908821,HGVS 是 44908822。
实测确认两条路都能查到同一条记录:
# 用 SPDI 查
curl "https://api.catalogkg.igvf.org/api/variants?spdi=NC_000019.10:44908821:C:T"
# → 1 条,_id = NC_000019.10:44908821:C:T
# 用 HGVS 查(注意 > 要编码成 %3E)
curl "https://api.catalogkg.igvf.org/api/variants?hgvs=NC_000019.10:g.44908822C%3ET"
# → 1 条,_id = NC_000019.10:44908821:C:T(返回的是同一条)
注意第二个请求里的
%3E。HGVS 写作C>T,但>在 URL 里必须编码。直接写>有些客户端会正常、有些会截断参数。 这是把 HGVS 传给 API 时最常见的失手点。
一张实用的换算表:
| 你手上有什么 | 怎么换成 SPDI |
|---|---|
| rsID | 直接查 ?rsid=,返回体里的 spdi 字段就是 |
| HGVS(1-based) | 位置减 1,或用 ?hgvs= 参数(推荐,让服务端算) |
论文里的 g. 写法 |
同上 |
| VCF 的一行 | chrom + pos + ref + alt,但需确认 VCF 的 pos 与 Catalog 的 pos 是否同基准 |
| 染色体+位置(无 ref/alt) | 换不了——SPDI 必须知道 ref/alt |
最后一行是硬约束:只知道
chr19:44908821是没法定出一条 SPDI 的,因为同一个位置可能有多种替代。必须走?region=区间查询,拿到候选列表再挑。
这是变异记录里信息最密的部分。实测 rs80357906 的 33 个键可以分成三类:
| 类别 | 键 | 数量 |
|---|---|---|
| gnomAD 总体频率 | gnomad_af_total、gnomad_af_raw、gnomad_af_female、gnomad_af_male |
4 |
| gnomAD 群体分层 | gnomad_af_{afr,ami,amr,asj,eas,fin,nfe,oth,sas} × 各含 total/female/male |
27 |
| BRAVO 频率 | bravo_af |
1 |
| 其他 | GENCODE_category |
1 |
群体分层这一块值得展开。 实测列出的群体缩写:
| 缩写 | 含义 |
|---|---|
afr |
非洲/非裔 |
ami |
阿米什 |
amr |
拉丁美洲混血 |
asj |
德系犹太人 |
eas |
东亚 |
fin |
芬兰 |
nfe |
非芬兰欧洲裔 |
oth |
其他 |
sas |
南亚 |
以 rs80357906(BRCA2 致病变异)为例,实际数据说明了什么:
| 群体 | gnomad_af |
|---|---|
| 总体 | 6.28e-05 |
nfe(欧洲裔) |
7.74e-05 |
asj(德系犹太人) |
9.05e-04 |
eas(东亚) |
0 |
afr(非洲) |
0 |
同一个变异,在德系犹太人里比在东亚人群中高一个数量级以上。 这是群体遗传学的常识,但在 Catalog 里的直接后果是:如果你用
gnomad_af_total做稀有性过滤,会把一个人群富集的变异误判为"全球都罕见"。
这条对做罕见病变异筛选的人尤其重要——§7 会把这一点列为使用局限。
3.5 annotations 里的 33 个键
这是变异记录里信息最密的部分。实测 rs80357906 的 33 个键可以分成三类:
| 类别 | 键 | 数量 |
|---|---|---|
| gnomAD 总体频率 | gnomad_af_total、gnomad_af_raw、gnomad_af_female、gnomad_af_male |
4 |
| gnomAD 群体分层 | gnomad_af_{afr,ami,amr,asj,eas,fin,nfe,oth,sas} × 各含 total/female/male |
27 |
| BRAVO 频率 | bravo_af |
1 |
| 其他 | GENCODE_category |
1 |
群体分层这一块值得展开。 实测列出的群体缩写:
| 缩写 | 含义 |
|---|---|
afr |
非洲/非裔 |
ami |
阿米什 |
amr |
拉丁美洲混血 |
asj |
德系犹太人 |
eas |
东亚 |
fin |
芬兰 |
nfe |
非芬兰欧洲裔 |
oth |
其他 |
sas |
南亚 |
以 rs80357906(BRCA2 致病变异)为例,实际数据说明了什么:
| 群体 | gnomad_af |
|---|---|
| 总体 | 6.28e-05 |
nfe(欧洲裔) |
7.74e-05 |
asj(德系犹太人) |
9.05e-04 |
eas(东亚) |
0 |
afr(非洲) |
0 |
同一个变异,在德系犹太人里比在东亚人群中高一个数量级以上。 这是群体遗传学的常识,但在 Catalog 里的直接后果是:如果你用
gnomad_af_total做稀有性过滤,会把一个人群富集的变异误判为"全球都罕见"。
这条对做罕见病变异筛选的人尤其重要——§7 会把这一点列为使用局限。
§4 关系层:边才是主角
4.1 为什么边比节点重要
在一个 30 亿节点、75 亿边的图里,节点是"名词",边是"动词"。而你真正要回答的问题,几乎都是动词形式的:
- 这个变异影响哪个基因?
- 这个基因关联什么疾病?
- 这个调控元件调控哪个基因?
- 这个药作用于什么靶点?
没有一条能在节点层面回答。
4.2 一条边的六个必备属性
以基因-变异边为例,一条完整的边必须能回答六个问题:
| 问题 | 字段 | 为什么必须有 |
|---|---|---|
| 哪两个实体? | gene + sequence_variant |
边的基本定义 |
| 什么关系? | name + label |
expression modulated by / associated with |
| 多强? | effect_size / p_value / z_score / neg_log10_pvalue |
判断可信度 |
| 用什么方法? | method |
eQTL ≠ spliceQTL ≠ GWAS ≠ MPRA |
| 在什么条件下? | biological_context / biosample_term |
组织特异性 |
| 是观测还是预测? | class |
observed data vs prediction |
method 和 class 这两个字段是 IGVF Catalog 最该被理解的设计。
4.3 method:同一个变异、同一个基因,两种方法两种结论
实测:查 BRCA1(ENSG00000012048)的基因-变异边,取前 500 条:
method |
条数 |
|---|---|
eQTL |
255 |
spliceQTL |
245 |
几乎各占一半。 这两个方法的差别是根本性的:
| 方法 | 测的是 | 一个变异可能表现为 |
|---|---|---|
eQTL |
基因表达量的变化 | 表达升高/降低 |
spliceQTL |
剪接异构体比例的变化 | 某个外显子跳跃/包含 |
一个变异完全可以「不影响总表达量,但改变剪接比例」。 如果你只取
eQTL,这个变异在你眼里就是"没有功能"。
这就是为什么必须按 method 分组,而不是把边一锅端。
4.4 source:谁的观测
同样这 500 条边,source 分布:
source |
条数 | 说明 |
|---|---|---|
AFGR |
267 | 来自 AFGR 项目(淋巴母细胞系为主) |
EBI |
233 | 来自 EBI 的 eQTL Catalogue |
biological_context 的分布直接对应上了:
biological_context |
条数 |
|---|---|
lymphoblastoid cell line |
267 |
liver |
195 |
iPSC |
37 |
adipose (visceral) |
1 |
267 条淋巴母细胞系,正好对应 267 条
source=AFGR。 这说明:在这个样本里,source和biological_context是强绑定的——每个数据源只测了少数几种组织。
对使用者的含义很直接:想找肝组织里的 BRCA1 eQTL,实际可用的边只有 195 条,且全部来自 EBI/eQTL Catalogue。“BRCA1 有 500 条 eQTL"是不准确的描述——应该说"在 Catalog 收录的这 500 条里,肝组织 195 条、淋巴母细胞系 267 条”。
4.5 class:观测 vs 预测,绝不能混
class 字段的取值(实测为 observed data):
| 值 | 含义 | 能不能当实验结果引 |
|---|---|---|
observed data |
实验或人群观测 | 能,但要注明来源与方法 |
prediction |
模型预测(如 ESM、MutPred2、rE2G) | 不能,只能说"某模型预测为…" |
官方站点首页明确区分了这两类内容:
Currently, the Catalog includes a preview of IGVF measurements and predictions, including:
- Saturation mutagenesis of coding variants in 10 genes (VAMP-seq, SGE)
- Variant effect predictions for all amino acid substitutions (MutPred2, ESM-v1)
- Enhancer-gene predictions from 1,460 ENCODE-rE2G datasets
- STARR-seq predictions of variant effects in (K562 cells) (BlueSTARR)
- MPRA measurements of variant effects
注意第三条:1,460 个 ENCODE-rE2G 数据集给出的是"预测"。 这个数字很大,容易被当成"1,460 个实验验证过的调控关系"。不是。
实操建议:任何从 IGVF Catalog 拉出来的边,第一件事是按
class分组。prediction的边可以用来排序、用来假设生成,不能用来做证据。
4.6 一个真实的多跳查询:从变异走到疾病
回到 §1.3 的案例。它的身份与频率已经看过,这里看它作为图的起点能走出什么。
第一跳:变异 → 表型。 实测(前 100 条,全部 source=OpenTargets、method=GWAS):
| 表型 | 条数 | 排序 |
|---|---|---|
| blood protein measurement | 23 | 1 |
| total cholesterol measurement | 13 | 2 |
| LDL cholesterol measurement | 10 | 3 |
| coronary artery disorder | 4 | 4 |
| pulse pressure measurement | 4 | 4 |
| alzheimer disease | 3 | 6 |
| ldl cholesterol change measurement | 3 | 6 |
| obsolete red blood cell distribution width | 2 | 8 |
| vitamin d measurement | 2 | 8 |
| longevity | 2 | 8 |
这张表最该被读出两件事:
第一,"blood protein measurement 有 23 条"是个陷阱。 这个表型太宽——它把 pQTL(蛋白定量性状基因座)都装进去了。23 条不代表 rs7412 影响 23 个蛋白,而是 23 项不同的蛋白测量各自与它关联。 想看具体是哪些蛋白,要展开 phenotype_id 与 study。
第二,beta = 0 但 p = 2e-209。 前面提过,这里再强调一次:IGVF Catalog 的 GWAS 边,效应量字段可能缺失或占位为 0。判断关联强度要用 p_value / neg_log10_pvalue,不要用 beta。
第三,出现了一个 obsolete_red blood cell distribution width。 obsolete 前缀说明这个 EFO 术语已废弃。说明本体映射是原样继承的,没有做废弃清理。 做本体层分析时要自己过滤掉 obsolete_ 开头的条目。
4.7 边的另一个来源:IGVF 联盟自己的实验
图谱里的边不只有外部资源来的。IGVF 联盟自己的实验产出的边,在 source 与 class 上都会不同。官方首页列出的是:
| 实验类型 | 产出什么边 |
|---|---|
| VAMP-seq / SGE(10 个基因的饱和突变) | 编码变异 → 蛋白丰度/功能 |
| MPRA | 变异 → 增强子活性 |
| STARR-seq / BlueSTARR | 变异 → 调控活性(K562 细胞) |
| CRISPR 筛选 | 基因 → 表型 |
这些是 Catalog 里唯一"IGVF 自产"的部分,其余都是整合外部资源。判断一条边是不是 IGVF 原创,看 source 与 files_filesets 是否指向 IGVFFI* 文件。
4.8 同一个案例在图上的三种走法
rs7412 在 Catalog 里可以走三条完全不同的路径,每条回答不同的问题。这三条路径的差别,就是"图"与"表"的差别。
走法 A:变异 → 基因(这条变异影响谁的表达)
rs7412
→ /variants?rsid=rs7412 拿到 SPDI: NC_000019.10:44908821:C:T
→ /variants/genes?variant_id=... 展开它关联的基因
实测这个调用对 rs7412 返回的是空数组。不是接口坏了,是这条变异在 Catalog 里没有 eQTL 类的基因边——它的证据来自 GWAS,不是 eQTL。
这本身就是一条重要情报:同一个位点在"表型关联"上有 100 条,在"基因表达关联"上可能是 0。两条边的覆盖范围不重叠,不能互相替代。
走法 B:变异 → 表型 → 基因(这条变异通过什么通路影响表型)
rs7412
→ /variants/phenotypes?rsid=rs7412 拿 100 条 GWAS 边
→ 取一条: phenotype_id = ontology_terms/EFO_0004611 (LDL 胆固醇)
→ /phenotypes/variants?phenotype_id=... 反向拿该表型的全部关联变异
→ 从这些变异里找落在基因区的,得到候选基因
这是 Catalog 真正擅长的路径:它不是"给你答案",而是"给你可以继续走的邻接关系"。
走法 C:变异 → 调控元件 → 基因(非编码区的机制假设)
rs7412
→ /variants/genomic-elements?variant_id=... 拿落在同一调控元件的变异
→ /genomic-elements/genes?... 拿这些元件预测调控的基因
实测这条同样返回空数组——rs7412 是编码区变异(APOE 外显子 4),本来就不在调控元件里。
三条走法,两条为空。这个结果本身就是结论:rs7412 的功能证据集中在"蛋白编码改变 → 表型"这条主轴上,不是在调控层。 如果你带着"非编码变异"的假设来查它,会一无所获——而这恰恰是理解这个位点该有的认知。
把三条走法并排看:
| 走法 | 查询 | rs7412 实测 | 说明什么 |
|---|---|---|---|
| A:变异→基因 | variants/genes |
空 | 无 eQTL 证据 |
| B:变异→表型 | variants/phenotypes |
100 条(截断,实际更多) | GWAS 证据充足 |
| C:变异→元件 | variants/genomic-elements |
空 | 不在调控元件内 |
一张图的价值,不在于它一定给你东西,而在于它能干净地告诉你「这条路没有」。 空数组是一个可信的否定回答——因为它意味着"这个图里没有这类边",而不是"查询失败"。前提是你确认参数写对了(§7.3)。
§5 接口层:怎么取
5.1 先纠正一个 URL:域名不是你想的那个
这是本节最该先看的一条。
| 你以为的 | 实际的 | 结果 |
|---|---|---|
api.catalog.igvf.org |
— | ❌ 502 / 504 |
| — | api.catalogkg.igvf.org |
✅ 200 |
实测 api.catalog.igvf.org 的所有路径(/api/v1/、/api/v1/graph、/api/v1/genes/...)全部返回 502 或 504,而正确域名下一个普通请求就通。
为什么会搞错:论文原文写的是 https://api.catalogkg.igvf.org/,但站点域名是 catalog.igvf.org。这两个名字不平行,凭直觉补出来的 api.catalog.igvf.org 是错的。
更麻烦的是官方文档自己的示例:OpenAPI 文件里 servers: - url: https://catalog-api-dev.demo.igvf.org/api,并且文档页顶部有一条警告:
This documentation targets the development Catalog API. The production base URL will replace this configuration in a future release.
所以文档示例里的 URL 也是不可用的。 三个 URL 里只有一个能通:
| URL | 状态 |
|---|---|
catalog-api-dev.demo.igvf.org/api |
文档示例,开发环境 |
api.catalog.igvf.org |
❌ 502/504(不存在) |
api.catalogkg.igvf.org/api |
✅ 生产环境 |
这一条建议单独记下来。 在找 API 地址上花的时间,往往比写代码还多。
5.2 路径风格:不是 RESTful 的资源路径
第一次用会踩的坑:/api/genes/ENSG00000139618 返回 404。
正确的写法是把过滤条件放成 query 参数:
# ❌ 404
curl "https://api.catalogkg.igvf.org/api/genes/ENSG00000139618"
# ✅ 200
curl "https://api.catalogkg.igvf.org/api/genes?name=BRCA1"
而且参数名有讲究——实测:
| 写法 | 结果 |
|---|---|
?name=BRCA2 |
✅ 正确返回 BRCA2 |
?gene_name=BRCA2 |
❌ 静默忽略,返回列表第一条(TSPAN6) |
?id=ENSG00000139618 |
❌ 静默忽略,返回列表第一条 |
这是本条目最阴的一个坑:错的参数名不报错,返回一个 200 和一条看起来正常的记录。如果你没注意返回的是
TSPAN6而不是你要的基因,后面所有分析都建在错误数据上。防御办法:拿到结果后,核对返回记录的
_id/name是否等于你请求的那个。这一行断言能省掉大部分事故。
关系端点同理。 实测:
| 写法 | 结果 |
|---|---|
genes/variants?gene_id=ENSG00000012048 |
✅ 200,返回边 |
genes/ENSG00000012048/variants |
❌ 404 |
genes-variants?gene_id=... |
❌ 404 |
5.3 一个能跑的最小脚本
import json, urllib.parse, urllib.request
BASE = "https://api.catalogkg.igvf.org/api"
HEADERS = {"User-Agent": "igvf-client/1.0"}
def api(path, **params):
url = f"{BASE}/{path}"
if params:
url += "?" + urllib.parse.urlencode(params)
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=90) as r:
return json.load(r)
def get_gene(name):
"""按基因名查,返回唯一一条。注意参数名必须是 name。"""
rows = api("genes", name=name)
if not rows:
raise LookupError(f"未找到基因: {name}")
return rows[0]
if __name__ == "__main__":
g = get_gene("BRCA1")
assert g["name"] == "BRCA1", f"返回的不是 BRCA1: {g['name']}" # §5.2 的防御断言
print(g["_id"], g["chr"], g["start"], g["end"], g["gene_type"])
edges = api("genes/variants", gene_id=g["_id"], limit=5)
for e in edges:
print(e["method"], e["biological_context"], e["effect_size"], e["p_value"])
这段代码里有三处是刻意的:
| 位置 | 为什么这么写 |
|---|---|
params 用 urlencode |
基因名/组织名里有空格(如 Mus musculus),不编码会 400 |
assert g["name"] == "BRCA1" |
§5.2 的静默忽略防御 |
limit=5 显式给 |
默认 limit 未在文档明确,显式给避免拉全量 |
5.4 分页与 limit:不同端点上限不一样
实测到的真实情况:
| 端点 | limit 上限 |
超限行为 |
|---|---|---|
/variants |
500 | limit=5000 → 静默截断到实际条数 |
/variants/phenotypes |
100 | limit=500 → 只返回 100 |
分页是 0-based(官方文档明确写 “Pagination is 0-based”),实测 page=0/1/2 返回的位置区间依次后移,不重复。
def paged(path, page_size=100, max_pages=50, **params):
"""按页遍历。page_size 取 100 可兼容所有端点(/variants/phenotypes 上限 100)。"""
out = []
for p in range(max_pages):
rows = api(path, page=p, limit=page_size, **params)
if not rows:
break
out.extend(rows)
return out
page_size默认设成 100 而不是 500,是因为variants/phenotypes硬性封顶 100。 用 500 去请求它,你会静默拿到 100 条,然后以为"总共就这么多"。
5.5 region 查询:文档说的 10kb 限制并不真的存在
官方文档对 region 参数写的是:
region = chr1:1157520-1158189 (maximum length: 10kb)
实测这个限制没有被强制执行。 用 824kb 的区间请求,返回 500 条,位置跨度从 1,157,520 到 1,982,000:
# 请求 824kb 区间(换算成 bp 约 824,480)
curl "https://api.catalogkg.igvf.org/api/variants?region=chr1:1157520-2000000&limit=500"
# 实际返回 500 条,pos 从 1157520 到 1982000
这意味着什么:
- 好处:可以一次拉更大区间,不用切碎
- 风险:返回的 500 条可能不代表区间内的全部变异——它只是"前 500 条"。没有总数返回,你无法知道被截掉了多少
正确的做法:把大区间切成 ≤10kb 的小块循环查询,每块都翻页到空为止。不是因为 API 有限制,而是因为你需要保证不遗漏。 官方文档写 10kb 大概就是这个意思——它是"建议的查询粒度",不是"硬限制"。
5.6 一条必须遵守的筛选规则:organism 不能单独用
实测:
# ❌ 400
curl "https://api.catalogkg.igvf.org/api/variants?organism=Homo%20sapiens&limit=5"
# {"message":"At least one of these properties must be defined:
# spdi, hgvs, rsid, ca_id, variant_id, region","code":"BAD_REQUEST"}
# ✅ 200(region + organism 组合)
curl "https://api.catalogkg.igvf.org/api/variants?region=chr1:1157520-1158189&organism=Homo%20sapiens&limit=5"
这条错误信息其实很有用——它把"必须先给一个定位参数"这个设计讲清楚了:
/variants是「按位置取变异」的端点,不是「浏览变异」的端点。organism、GENCODE_category、mouse_strain都只是附加过滤,不能当主查询条件。
这与其他端点不同:/genes、/proteins、/ontology-terms 都可以无参数列表式拉取,只有 /variants 不行——因为它背后的变异数量是十亿级的。
顺带一个实测细节:GENCODE_category 与 rsid 组合返回空数组:
curl "https://api.catalogkg.igvf.org/api/variants?rsid=rs80357906&GENCODE_category=coding"
# []
不是没匹配到,是 GENCODE_category 这个注释字段在这条记录上没有值。 这个过滤条件依赖 annotations.GENCODE_category,而 rs80357906 的这个字段实测是 null。换 rs7412 试试也可以——同样没保证。 用之前先确认目标变异有没有这个注释。
5.7 Cypher:图查询的入口
Catalog 提供了 Cypher 查询界面(官方文档页 pages/cypher 与 Cypher Query Runner)。
这是它与普通 REST 库最大的区别:REST 端点给你预设好的问题,Cypher 让你自己组路径。
什么情况下值得用 Cypher 而不是 REST:
| 场景 | 适合 |
|---|---|
| 已知一个变异,想取它的所有关联 | REST(variants/phenotypes 等) |
| 已知一个基因,想取它的所有变异 | REST(genes/variants) |
| 想要「变异 → 基因 → 通路 → 药物」三段路径 | Cypher |
| 想看两类实体之间是否存在任意路径 | Cypher |
| 要做聚合统计(按 method 计数、按组织分组) | Cypher |
一个后端细节:实测 /api/studies 端点返回过一个内部错误:
{"message":"syntax error, unexpected SORT declaration near
'SORT record._key\n LIMIT 0, 25...' at position 4:5","code":"INTERNAL_SERVER_ERROR"}
record._key 和 SORT 是 ArangoDB 的 AQL 语法(不是 Neo4j 的 Cypher)。这说明 Catalog 底层用 ArangoDB,而上层提供的 Cypher 是转换层。
对使用者的实际影响:Cypher 查询可能有性能上限。这个
/api/studies的 500 错误,很可能是因为查询没走索引。做复杂多跳查询时,先用小范围验证,别直接在全图上跑。
§6 与库内条目的关系
6.1 它在库内的位置
| 库内相关条目 | 关系 |
|---|---|
| ENCODE | 上游:Catalog 的调控元件与 rE2G 预测来自 ENCODE |
| eQTL Catalogue | 上游:source=EBI 的边来自这里 |
| ClinVar / ClinGen | 上游:变异临床意义与疾病关联 |
| gnomAD | 上游:全部频率注释 |
| GTEx | 上游(间接):通过 eQTL Catalogue 与 AFGR 进入 |
| Reactome | 上游:通路 |
| HOCOMOCO | 上游:转录因子motif |
| Expression Atlas | 同级:都做"重处理后对外提供",但 Atlas 是表达谱,Catalog 是关联图 |
6.2 检索路径建议
从变异出发(最常见):
rsID / SPDI
→ /variants 拿基础身份 + 频率
→ /variants/phenotypes 拿 GWAS 关联
→ /variants/genes 拿 eQTL / spliceQTL
→ /variants/genomic-elements 拿调控元件
从基因出发:
基因名
→ /genes?name= 拿 Ensembl ID(必须核对返回)
→ /genes/variants 拿该基因的所有变异关联
→ /genes/diseases 拿疾病关联
→ /genes/pathways 拿通路
从表型出发:
EFO / MONDO 术语
→ /ontology-terms 确认术语 ID
→ /phenotypes/variants 拿关联变异
6.3 互链建议
本条目与以下库内条目互链:
- ENCODE:Catalog 的调控元件预测源头
- GWAS Catalog:表型关联源头
- gnomAD:频率注释源头
- Expression Atlas:同为"重处理对外提供",可对比
6.4 与其他"重处理层"的本质差别
库内已经收录了几个"重处理层"的库,把它们与 Catalog 并排看,能更清楚 Catalog 的位置:
| 库 | 它重处理的是什么 | 产出的形状 | 一条记录代表 |
|---|---|---|---|
| Expression Atlas | 公共表达数据 | 表达矩阵 | 一个实验 |
| Single Cell Expression Atlas | 单细胞数据 | 细胞×基因矩阵 | 一个实验 |
| BioSamples | 样本描述 | 键值对 | 一个样本 |
| IGVF Catalog | 关联关系 | 图 | 一条边 |
前三者的记录是"实体",Catalog 的记录是"关系"。
这个差别有实际后果:
| 你想做的事 | 前三者 | Catalog |
|---|---|---|
| 按条件筛出一批记录 | 直接 WHERE |
要先决定查哪种边 |
| 统计"有多少" | 数记录 | 数边,且不同边类型不可加总 |
| 导成一张表 | 天然是表 | 要拍平,会丢语义 |
| 表达"两个东西之间有路径" | 做不到 | 天生能做 |
所以 Catalog 不能当成"第 1,351 个数据集"来用。 它是一个查询层——你要问的不是"它里面有什么",而是"我想知道两个东西之间有没有关系"。这个定位差别,决定了它的上手曲线比前面几个库都陡。
§7 质量评估与局限性
7.0 阅读本节前需要知道的一件事
IGVF Catalog 的规模和它的可靠性不是同一件事。
30 亿节点、75 亿边的数字非常醒目,但这里面:
- 大部分节点是外部资源的镜像(基因来自 GENCODE、变异来自 FAVOR/dbSNP、本体来自 EFO/UBERON)
- IGVF 自产的部分只占少数(10 个基因的饱和突变、MPRA、STARR-seq)
- 边里有相当比例是
prediction而非observed data
所以正确的阅读方式是:Catalog 的价值在于「把已经存在的关系组织起来,方便查询」,而不是「提供了大量新知识」。 它的新知识在 IGVF 自己的实验里;它的规模在整合里。
这个认知差别很实际:如果你以为「75 亿条边 = 75 亿个已验证的生物学关系」,你会严重高估可用的证据量。
7.1 局限一:效应的量纲不同源,不能合并
同一列 effect_size,在不同 method 下含义完全不同:
| method | effect_size 的量纲 | 能不能跨方法比较 |
|---|---|---|
eQTL |
表达量(通常是标准化后的 log 值) | ❌ |
spliceQTL |
剪接比例 | ❌ |
GWAS |
表型单位(或 0 占位) | ❌ |
MPRA |
荧光/计数比值 | ❌ |
SGE |
细胞存活/富集分数 | ❌ |
实测的实例:rs7412 的 LDL 关联:
neg_log10_pvalue = 208.7 ← p ≈ 2e-209,极强
beta = 0 ← 效应量为 0 占位
如果按 effect_size 排序,这条极强的关联会排到最后。
正确做法:按
method分组,组内才比较。显著性统一用p_value或neg_log10_pvalue。排序用 p 值,不用 beta。
7.2 局限二:不同端点的返回上限不一致,且静默截断
实测:
| 端点 | 你以为能给多少 | 实际最多返回 |
|---|---|---|
/variants |
limit=5000 |
500 |
/variants/phenotypes |
limit=500 |
100 |
两种超限都是静默的——返回 200,返回一个合法的 JSON 数组,只是条数少了。
为什么危险:/variants/phenotypes 返回 100 条,看起来是个完整的列表。你会得出「rs7412 只有 100 个表型关联」的结论。实际翻页还能拿更多。
防御:翻页直到返回空数组,不要用单次结果当全量。
7.3 局限三:参数名错拼会静默返回错误数据
这是本条目最严重的可用性问题。
| 请求 | 你以为的 | 实际返回 |
|---|---|---|
?gene_name=BRCA2 |
BRCA2 | TSPAN6(列表第一条) |
?id=ENSG00000139618 |
该基因 | TSPAN6 |
/genes/ENSG00000139618 |
该基因 | 404(这个反而报错了) |
同一个错误,有时返回 404(好),有时返回错数据(坏)。
唯一可靠的防御是在代码里加断言:
g = api("genes", name="BRCA2")[0] assert g["name"] == "BRCA2"这一行断言的成本几乎为零,能拦住整类事故。
7.4 局限四:人口代表性受上游限制
annotations 里的 27 个 gnomAD 分层看起来很全,但分层的样本量极不均衡。
实测 rs80357906 的频率分布:
| 群体 | gnomad_af |
相对总体 |
|---|---|---|
| 总体 | 6.28e-05 | 1.0× |
nfe |
7.74e-05 | 1.2× |
asj |
9.05e-04 | 14.4× |
eas |
0 | 0 |
afr |
0 | 0 |
sas |
0 | 0 |
eas、afr、sas 全是 0——不代表这些群体里绝对没有,而是样本里没观测到。 在一个几万人的参考集里,频率低于 1e-5 的变异本来就观测不到。
实际后果:用「gnomad_af_total < 0.01」筛罕见变异,在东亚人群里会漏掉一批实际不罕见的位点。 Catalog 原样继承 gnomAD 的这个局限,没有补充。
7.5 局限五:本体层没有做废弃清理
实测 rs7412 的表型列表里出现了:
obsolete_red blood cell distribution width
obsolete_ 前缀是 OBO 本体的废弃标记。 说明:
- Catalog 保留了已废弃的术语,没有替换成现行术语
- 用这些术语做通路/富集分析会失败或得到空结果
防御:拉表型列表后,过滤掉
obsolete_开头的phenotype_term。
7.6 局限六:文档与生产环境不一致
三处实测到的偏差:
| 项目 | 文档说的 | 实际 |
|---|---|---|
| base URL | catalog-api-dev.demo.igvf.org/api |
api.catalogkg.igvf.org/api |
| region 上限 | maximum length: 10kb |
824kb 也能返回 |
limit 上限 |
“can not exceed 500” | /variants/phenotypes 封顶 100 |
官方自己在文档页顶部写了警告:
This documentation targets the development Catalog API. The production base URL will replace this configuration in a future release.
所以文档是"开发环境文档",不是生产环境文档。 遇到行为不符时,以实测为准。
7.7 局限七:Cypher 层有性能与稳定性边界
前面提到的 /api/studies 500 错误(AQL 语法错误泄漏)说明:
- 不是所有端点都稳定
- 复杂查询可能超时或报错
- 错误信息可能暴露内部实现,但对使用者没有帮助
实际建议:优先用 REST 端点。Cypher 只在 REST 表达不了的多跳场景下用,并且小范围先验证。
7.8 DAIMS 24 项数据就绪度评估
按 DAIMS(Data Aggregation and Interoperability Maturity Scorecard)逐项打分:
| # | 维度 | 判定 | 依据 |
|---|---|---|---|
| 1 | 数据集唯一标识 | ✅ | SPDI / Ensembl ID,全局唯一 |
| 2 | 版本标识 | ⚠️ | 有 GENCODE v43 等字段级版本,但 Catalog 自身无版本号 |
| 3 | 更新时间 | ⚠️ | 无全局 lastUpdated 字段 |
| 4 | 许可声明 | ✅ | 数据 CC、软件 MIT,官方明确 |
| 5 | 出处溯源 | ✅ | 每条边带 source + source_url |
| 6 | 引用方式 | ✅ | 有正式论文 DOI |
| 7 | 数据结构说明 | ✅ | OpenAPI + Mintlify 文档 |
| 8 | 字段级文档 | ✅ | OpenAPI 逐字段定义 |
| 9 | 机器可读格式 | ✅ | JSON |
| 10 | 批量获取 | ⚠️ | 只能翻页,无全量 dump |
| 11 | 增量更新 | ❌ | 无增量接口 |
| 12 | ID 稳定性 | ✅ | SPDI 稳定;rsID 会变,已正确处理成数组 |
| 13 | 跨库 ID 映射 | ✅ | Ensembl / HGNC / Entrez / UniProt 并存 |
| 14 | 本体使用 | ⚠️ | 用了标准本体,但未清理 obsolete |
| 15 | 缺失值语义 | ❌ | null / "." / 0 三种都可能表示缺失,未统一 |
| 16 | 单位声明 | ⚠️ | effect_size 无单位字段,靠 method 推断 |
| 17 | 质量控制标记 | ⚠️ | class 区分观测/预测,但无置信度分级 |
| 18 | 人群代表性说明 | ❌ | 未在数据层面标注 |
| 19 | 方法学文档 | ✅ | method 字段 + 文档 |
| 20 | 坐标体系说明 | ✅ | 明确 0-based half-open + GRCh38/GRCm39 |
| 21 | 错误处理 | ⚠️ | 有结构化错误码,但部分错误静默 |
| 22 | 速率限制说明 | ❌ | 未见文档化 |
| 23 | 可用性 SLA | ❌ | 未见声明 |
| 24 | 长期保存承诺 | ⚠️ | 有 NIH 资助,但无明确年限承诺 |
汇总:11 项满足 / 9 项部分 / 4 项不满足。
四项不满足里,最影响使用的是第 15 项(缺失值语义)和第 18 项(人群代表性)。 前者会让统计出错,后者会让解读出错。
7.9 外部验证矩阵
| 验证项 | 方法 | 结果 |
|---|---|---|
| API 可达性 | curl 三个候选域名 | 仅 api.catalogkg.igvf.org 通 |
| 基因查询正确性 | ?name=BRCA1 |
✅ 返回 ENSG00000012048,坐标 chr17:43044294-43170245 |
| 参数名容错 | ?gene_name= / ?id= |
❌ 静默返回错数据 |
| 变异多标识一致性 | rs80357906 的 spdi vs hgvs | 位置差 1(0-based vs 1-based),符合预期 |
| region 上限 | 824kb 区间 | 未拒绝,返回 500 条(文档说 10kb) |
| limit 上限 | 各端点 500/100 | 与文档部分不符 |
| 边结构完整性 | BRCA1 边 500 条 | 15 个字段齐全,method/source/context 均有值 |
| class 分布 | 抽样 | 均为 observed data;prediction 需专门筛 |
| 文档一致性 | llms.txt 索引 | 118 条,其中 84 条为 API 页面 |
| 规模声明 | 论文 vs 站点 | 30 亿节点 / 75 亿边,两处一致 |
§8 版本与生态
8.1 版本节奏:没有版本号,只有持续更新
IGVF Catalog 没有对外的版本号体系(OpenAPI 里有 version: 1.2.0 - DEV,但那是 API schema 的版本,不是数据版本)。
这对引用的实际含义:
- 你无法写「IGVF Catalog v2.1 的数据」
- 只能写「IGVF Catalog,访问日期 2026-10-25」
- 同一查询在两个月后可能返回不同结果
上游的版本是可以锁定的:
| 上游 | 版本字段 | 实测值 |
|---|---|---|
| GENCODE | version |
v43 |
| GWAS Catalog | version |
October 2022 (22.10) |
| gnomAD | 隐含在 annotations 键名 |
— |
做可复现研究时,把每条的
source+version一起存下来。 Catalog 不给你全局版本,但给了每条的出处。
8.2 它为什么存在:一个具体的缺口
官方首页把定位写得很清楚:
IGVF Catalog comprehensive repository designed to facilitate access to a wide range of genomic data, particularly focused on sequence variants, their associated genes, and regulatory elements.
它要填的缺口是:变异注释资源是分散的,且互相不连通。
具体说,一个研究者想知道「rs7412 影响了什么」,需要去:
| 问题 | 传统做法要去哪 |
|---|---|
| 频率多少 | gnomAD |
| 和什么病相关 | GWAS Catalog / ClinGen / OpenTargets |
| 影响哪个基因的表达 | GTEx / eQTL Catalogue |
| 影响剪接吗 | 另一个 eQTL 资源 |
| 在哪个细胞类型活跃 | ENCODE |
| 作用于什么药 | pharmGKB |
| 通路上下文 | Reactome |
七个资源,七套标识符,七种返回格式。 Catalog 做的事是:把这七个都挂到同一个 SPDI / Ensembl ID 上,然后给你一个入口。
这就是它不可替代的地方:不是它产出了新知识,而是它让"跨资源拼图"这件事从七次手工对齐变成一次查询。
8.3 它为什么能持续
三个可验证的支撑点:
第一,它挂在国家级计划上,不是课题级项目。
IGVF 由 NHGRI(NIH 下属) 资助,官方表述:
The NHGRI, an institute within the NIH, funds this collaborative program and brings together teams of investigators…
NHGRI 是机构级资助,不是三五年期的项目经费。 这决定了它的存续周期。
第二,它的规模来自整合,不是自产。
30 亿节点里,绝大多数来自 GENCODE、dbSNP/FAVOR、EFO/UBERON、gnomAD、ClinGen 等现成资源。整合的成本远低于自建。 这意味着维护负担可控。
第三,它已经进入引用链。
2026 年 NAR 数据库专刊收录(Nucleic Acids Res 2026;54(D1):D1437-D1445,DOI 10.1093/nar/gkaf1341)。进入 NAR 数据库专刊意味着被这个领域的引用生态接纳——后续论文引用它会成为惯例。
8.4 与同类的关系:不是竞争,是覆盖不同层
| 资源 | 主要形态 | 与 IGVF Catalog 的关系 |
|---|---|---|
| gnomAD | 频率表 | 被整合:Catalog 的 annotations 就是它 |
| GWAS Catalog | 关联表 | 被整合:phenotypes/variants 的主要来源 |
| OpenTargets | 靶点关联平台 | 被整合:source=OpenTargets |
| ClinVar | 临床意义 | 部分覆盖(通过 ClinGen) |
| ENCODE | 实验数据门户 | 被整合:调控元件与 rE2G |
| RegulomeDB | 调控变异打分 | 并列:官方首页把它列为相关应用 |
| GTEx | 表达 QTL 门户 | 间接整合:经 eQTL Catalogue |
注意最后一列:Catalog 与 RegulomeDB 是"并列"而非"包含"。 官方首页把 RegulomeDB、MaveDB、E2G、FAVOR 都列为 “Related Apps”——说明它们服务于不同的查询习惯,不是同一件事的重复。
8.5 在生态中的位置
联盟产出层: IGVF 实验(MPRA / STARR-seq / SGE / MAVE / 单细胞)
│
外部资源层: gnomAD · ClinGen · GenCC · GWAS · eQTL Catalogue
ENCODE · Reactome · HOCOMOCO · pharmGKB · FAVOR
│
▼
聚合层: IGVF Catalog(节点 + 边,本条目)
│
┌────────┼────────┐
▼ ▼ ▼
REST API Cypher 网页 UI
│
▼
应用层: IGVF-GPT · Variant Dashboard · 各 DACC 自建应用
Catalog 处在"聚合层",这是它唯一的位置。 它不生产数据,不分析数据,只负责把数据变成可查询的图。
这个位置决定了它的两个特性:规模大(因为聚合)、原创性低(因为聚合)。使用时要同时接受这两点。
8.6 用 rs7412 检验这个库的成熟度
§1.3 的案例、§3.4 的案例、§4.6 的案例、§4.8 的案例,同一个位点在四条线上被反复检验。把这四条线的实测结果汇总,恰好能当作这个库成熟度的一个横切面。
| 检验项 | rs7412 的实测结果 | 说明什么 |
|---|---|---|
| 身份层:能不能稳定定位 | ✅ SPDI/hgvs/rsid 三种写法都命中同一条 | 标识符体系成熟 |
| 频率层:有没有人群分层 | ✅ 33 个注释键,含 27 个 gnomAD 分层 | 继承了 gnomAD 的完整度 |
| 表型层:有没有 GWAS 关联 | ✅ 100 条(截断),10 类表型 | 覆盖充分 |
| 基因层:有没有 eQTL | ❌ 空数组 | 不是所有位点都有多组学证据 |
| 调控层:有没有元件关联 | ❌ 空数组 | 编码区变异本来就没有 |
| 数据洁净度 | ⚠️ 出现 obsolete_red blood cell distribution width |
本体未做废弃清理 |
| 数值一致性 | ⚠️ beta=0 但 p=2e-209 |
效应量字段不保证有值 |
七项里四项好、两项空、两项有瑕疵。 这个比例大致就是这个库现在的状态:主干(身份、频率、GWAS)扎实,支线(eQTL、调控)覆盖不均,细节(本体清理、缺失值语义)还需打磨。
这对使用者的含义很实际:如果你要做的分析依赖"多组学证据齐备",不要假设 Catalog 里每个位点都是全的。先用一个已知位点探一遍,看看你要的那类边在这个位点上有没有。 rs7412 这种研究极透的位点尚且缺 eQTL,其他位点只会更少。
8.7 项目沿革
| 时间 | 事件 |
|---|---|
| 2020 前后 | NHGRI 启动 IGVF 计划,设 DACC |
| 2024 | IGVF 联盟总体设计论文发表于 Nature(官方文档引用 s41586-024-07510-0) |
| 2025-12 | Catalog 论文在线发表 |
| 2026-01 | NAR 数据库专刊正式刊出(54(D1):D1437–D1445) |
| 2026-10 | 本条目实测:生产 API 可用,文档仍标注为 dev 环境 |
注意最后一行:到 2026 年 10 月,官方文档仍在说"本文档面向开发环境 API,生产 base URL 将在未来版本替换"。 这说明项目还在快速迭代期,文档滞后于实现是常态。
§9 使用指引
9.1 三种角色的路径
| 你是 | 建议路径 |
|---|---|
| 变异解读人员 | rsID → /variants 拿频率 → /variants/phenotypes 拿表型 → 逐个 phenotype_id 核对 |
| 功能基因组研究者 | 基因 → /genes/variants 拿 eQTL/spliceQTL,按 method 和 biological_context 分组 |
| 数据工程师 | 用 Cypher 做多跳,REST 做点查;所有查询加返回断言 |
9.2 一个完整的工作流:从 rsID 到一个可用的关联表
import json, urllib.parse, urllib.request, collections
BASE = "https://api.catalogkg.igvf.org/api"
HEADERS = {"User-Agent": "igvf-client/1.0"}
def api(path, **params):
url = f"{BASE}/{path}?" + urllib.parse.urlencode(params)
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=90) as r:
return json.load(r)
def variant_profile(rsid):
# 1. 基础身份与频率
vs = api("variants", rsid=rsid)
if not vs:
raise LookupError(rsid)
v = vs[0]
if rsid not in (v.get("rsid") or []):
raise ValueError(f"返回的变异不含 {rsid}: {v.get('rsid')}") # 防静默错配
# 2. 表型关联:翻页拿全,不用单次结果当全量
phen = []
for p in range(20):
rows = api("variants/phenotypes", rsid=rsid, page=p, limit=100)
if not rows:
break
phen.extend(rows)
# 3. 过滤废弃本体术语
phen = [x for x in phen if not str(x.get("phenotype_term", "")).startswith("obsolete_")]
# 4. 按方法来源分组统计
by_method = collections.Counter(x.get("method") for x in phen)
by_source = collections.Counter(x.get("source") for x in phen)
return {
"spdi": v["spdi"],
"chr": v["chr"],
"pos": v["pos"],
"gnomad_af_total": v["annotations"].get("gnomad_af_total"),
"n_phenotypes": len(phen),
"by_method": dict(by_method),
"by_source": dict(by_source),
}
if __name__ == "__main__":
print(json.dumps(variant_profile("rs7412"), ensure_ascii=False, indent=2))
这段代码的四个设计点,每一项都对应 §7 的一条局限:
| 代码 | 对付哪条局限 |
|---|---|
assert rsid in v["rsid"] |
§7.3 参数静默错配 |
| 循环翻页到空 | §7.2 静默截断 |
过滤 obsolete_ |
§7.5 本体未清理 |
by_method 分组 |
§7.1 量纲不同源 |
9.3 在 AI 流程中的位置
| 阶段 | 怎么用 |
|---|---|
| 假设生成 | 从变异出发拉表型,用 prediction 类的边排序候选 |
| 特征工程 | 每个变异的 gnomAD 分层频率、关联 eQTL 数量、关联组织数 |
| 训练数据标注 | 必须按 class 拆分:observed data 可作标签,prediction 只能作特征 |
| 结果解释 | 用 biological_context 说明关联的组织特异性 |
| 不能做的事 | 拿 prediction 当标签训练致病性预测模型 |
这一条值得重复:
class字段用法上最容易被忽视、后果又最严重。用预测结果当观测标签训练模型,是在训练一个拟合自己老师的模型。
9.4 引用与合规
| 项目 | 内容 |
|---|---|
| 建议引用 | Li D, Liu S, Assis PR, et al. The IGVF catalog—from genetic variation to function. Nucleic Acids Research. 2026;54(D1):D1437–D1445. doi:10.1093/nar/gkaf1341 |
| 数据许可 | Creative Commons(官方 OpenAPI 描述) |
| 软件许可 | MIT |
| 访问日期 | 必须记录(无全局版本号) |
| 上游条款 | gnomAD / ClinGen / pharmGKB 等各有条款,商用需逐个核对 |
§10 AI 使用声明
| 项目 | 声明 |
|---|---|
| 性质 | 整合型知识图谱,以图结构组织变异、基因、调控元件、表型、疾病、药物的关系 |
| 适合的用途 | 变异功能关联检索、跨资源拼图、特征工程、假设生成、组织特异性查询 |
| 不适合的用途 | 致病性判定、临床报告、原始数据下载、全基因组关联分析 |
| 关键前提 | class 必须区分 observed data 与 prediction;effect_size 不可跨 method 比较 |
| 伦理与合规 | 数据为群体汇总统计,不含个体标识信息;但人群分层不均,直接用于东亚人群解读需谨慎 |
| 引用要求 | 必须引用 NAR 论文并标注访问日期;用到上游资源时同时引用上游 |
| 版本状态 | 无全局版本号;文档仍标注为开发环境;API 与文档存在已知偏差 |
| 数据来源 | 美国 NIH / NHGRI,IGVF 联盟 DACC 建设 |
常见误读(避坑清单)
| 说法 | 实际 | 证据 |
|---|---|---|
| 「30 亿节点是 IGVF 自己产的数据」 | 绝大部分是 GENCODE / FAVOR / EFO 等外部资源的镜像 | source 字段,多数指向外部 |
| 「75 亿条边 = 75 亿个已验证关系」 | 其中相当比例是 prediction |
class 字段 |
| 「effect_size 可以跨方法排序」 | 量纲不同,eQTL/GWAS/MPRA 完全不可比 | rs7412 的 beta=0 但 p=2e-209 |
| 「API 在 api.catalog.igvf.org」 | 正确域名是 api.catalogkg.igvf.org |
前者实测 502/504 |
| 「?gene_name= 能查基因」 | 会被静默忽略,返回列表第一条 | 实测返回 TSPAN6 |
| 「limit=500 就能拿 500 条」 | /variants/phenotypes 封顶 100,静默截断 |
实测 limit=500 只返回 100 |
| 「region 最多 10kb」 | 文档有写,但未强制;824kb 也能返回 | 实测返回 500 条,跨度 824kb |
| 「gnomad_af_total 能代表全球稀有性」 | 受上游样本构成限制,东亚常见位点可能显示为 0 | rs80357906 的 eas/afr/sas 全为 0 |
| 「表型列表是干净的」 | 含 obsolete_ 前缀的废弃本体术语 |
rs7412 结果里的 obsolete_red blood cell distribution width |
| 「坐标是 1-based」 | 全库 0-based, half-open | 官方 OpenAPI 声明 |
FAQ
Q1:IGVF Catalog 和 IGVF 数据门户(data.igvf.org)是一回事吗?
不是。数据门户是原始文件与处理管道的入口(FASTQ、BAM、bed 等);Catalog 是这些文件被分析后的关系图。要下文件去门户,要查关系来 Catalog。
Q2:我应该用 REST 还是 Cypher?
单点查询用 REST(快、有文档、字段稳定);多跳路径用 Cypher(REST 表达不了)。官方文档也把 Cypher 定位为「查询运行器」,不是主入口。
Q3:为什么一个变异查出来 rsid 是数组?
dbSNP 会合并位点,同一个变异历史上可能对应多个 rs 号。所以 Catalog 用数组而不是单值——这是正确处理,不是 bug。
Q4:spdi 和 hgvs 位置差 1,哪个对?
两个都对,只是坐标基准不同:SPDI 0-based、HGVS 1-based。传参时用哪个都行,但别混用。
Q5:为什么 organism=Homo sapiens 单独查会 400?
/variants 是「按位置取变异」的端点,必须给一个定位参数(spdi/hgvs/rsid/ca_id/variant_id/region)。organism 只是附加过滤。
Q6:files_filesets 是 null 意味着什么?
这条记录没有关联到具体文件。可能原因:来自外部资源汇总(如 FAVOR)、或该变异没有 IGVF 实验覆盖。不代表数据有问题。
Q7:能用来做临床变异解读吗?
不能直接用于出具报告。Catalog 给的是关联强度与组织特异性,不给 ACMG 分级所需的证据权重。合规做法是把它作为辅助证据,最终判定走 ClinVar/ClinGen + ACMG 规则。
Q8:多久更新一次?
官方未公布固定节奏,从 API 的 cache-control: max-age=86400 看,至少每日刷新。但数据层面的更新频率未文档化——引用时必须记访问日期。
Q9:小鼠数据能用吗?
能,但覆盖远小于人类。organism 支持 Mus musculus,mouse_strain 支持 7 个常见品系(129S1_SvImJ、A_J、CAST_EiJ、NOD_ShiLtJ、NZO_HlLtJ、PWK_PhJ、WSB_EiJ)。参考基因组是 GRCm39。
Q10:为什么 /api/studies 会 500?
实测返回的是 AQL 语法错误(SORT record._key),说明该端点查询未正确构造。这是已知不稳定端点,避开它,从 phenotypes 边的 study 字段反查。
Q11:prediction 类的边有多少?
官方首页给出几个具体数字:MutPred2 与 ESM-v1 覆盖全部氨基酸替换的预测、ENCODE-rE2G 有 1,460 个数据集给出增强子-基因预测。这些量级远超观测数据,用之前必须按 class 筛。
Q12:和 RegulomeDB 有什么不同?
RegulomeDB 是非编码变异打分(把多个证据合成一个分数);Catalog 是关系图(保留每条关系的方法、组织、来源)。前者回答「这个变异有多可能调控」,后者回答「它调控谁、在什么组织、用什么方法测的」。
术语表
| 术语 | 含义 |
|---|---|
| SPDI | 序列:位置:参考:替代 格式的变异标识,0-based,版本明确 |
| HGVS | 人类基因组变异学会命名规范,1-based |
| rsID | dbSNP 的变异编号,会合并/拆分,不宜作主键 |
| CA ID | ClinGen Allele ID |
| eQTL | 表达数量性状基因座,变异与基因表达量的关联 |
| spliceQTL | 剪接数量性状基因座,变异与剪接比例的关联 |
| pQTL | 蛋白数量性状基因座 |
| GWAS | 全基因组关联分析 |
| MPRA | 大规模并行报告基因检测 |
| STARR-seq | 自转录活性调控区测序 |
| SGE | 饱和基因组编辑 |
| MAVE | 多路并行变异效应检测 |
| VAMP-seq | 变异丰度多重检测 |
| rE2G | ENCODE 的增强子-基因预测模型 |
| AFGR | 一个 eQTL 资源项目(淋巴母细胞系为主) |
| gnomAD | 基因组聚合数据库,群体频率来源 |
| FAVOR | 功能变异注释资源,Catalog 的注释来源之一 |
| EFO / UBERON / MONDO | 实验因子本体 / 解剖本体 / 疾病本体 |
| Cypher | 图查询语言(此处经转换层映射到 ArangoDB AQL) |
| 0-based half-open | 起始位置从 0 计、区间右端不含的坐标约定 |
| GRCh38 / GRCm39 | 人类 / 小鼠现行参考基因组版本 |
| observed data | 实验或人群实际观测到的数据 |
| prediction | 模型预测结果,非观测 |
| DACC | Data and Administrative Coordinating Center,数据与行政协调中心 |
附录 A:条目信息速查卡
| 项目 | 值 |
|---|---|
| 名称 | IGVF Catalog |
| 全称 | Impact of Genomic Variation on Function Catalog |
| 出资 | NIH / NHGRI |
| 建设 | IGVF DACC |
| 网页 | https://catalog.igvf.org |
| API(生产) | https://api.catalogkg.igvf.org/api |
| 文档 | https://docs.catalog.igvf.org/introduction |
| 文档索引 | https://docs.catalog.igvf.org/llms.txt |
| 数据门户 | https://data.igvf.org |
| 规模 | 50+ 集合 / 近 30 亿节点 / 超 75 亿边 |
| 节点类型 | 17 类 |
| API 文档页数 | 84 |
| 基因组版本 | GRCh38 / GRCm39 |
| 坐标 | 0-based half-open |
| 单端点上限 | /variants 500;/variants/phenotypes 100 |
| 许可 | 数据 CC / 软件 MIT |
| 论文 | NAR 2026;54(D1):D1437–D1445,doi:10.1093/nar/gkaf1341 |
附录 B:主要节点端点速查
| 实体 | 端点 | 查询参数示例 |
|---|---|---|
| 基因 | /api/genes |
?name=BRCA1 |
| 转录本 | /api/transcripts |
?limit=10 |
| 变异 | /api/variants |
?rsid=rs7412 / ?region=chr1:1-10000 |
| 蛋白 | /api/proteins |
?limit=10 |
| 本体术语 | /api/ontology-terms |
?limit=10 |
| 基因→变异 | /api/genes/variants |
?gene_id=ENSG00000012048 |
| 变异→表型 | /api/variants/phenotypes |
?rsid=rs7412 |
| 变异→基因 | /api/variants/genes |
?variant_id=... 或 ?rsid=... |
| 基因→转录本 | /api/genes/transcripts |
?gene_id=... |
附录 C:外部资源对照
| 资源 | 在 Catalog 里的体现 |
|---|---|
| GENCODE | 基因/转录本/蛋白节点,version 字段 |
| gnomAD | annotations.gnomad_af_* |
| BRAVO | annotations.bravo_af |
| FAVOR | 变异节点的 source |
| ClinGen | ca_id、疾病-基因边 |
| GenCC / Orphanet | 基因-疾病边 |
| GWAS Catalog | phenotypes/variants 的 study 字段 |
| eQTL Catalogue | source=EBI 的基因-变异边 |
| AFGR | source=AFGR 的基因-变异边 |
| OpenTargets | source=OpenTargets 的表型边 |
| ENCODE | 调控元件节点、rE2G 预测 |
| Reactome | 通路节点、通路-通路边 |
| HOCOMOCO | motif 节点 |
| pharmGKB | 药物-变异边 |
| EFO / UBERON / MONDO / CLO / BAO / GO | 本体术语节点 |
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- cosmic — 共享标签:基因组学与多组学 / 变异与注释
- clinvar — 共享标签:基因组学与多组学 / 变异与注释
- dbsnp — 共享标签:基因组学与多组学 / 变异与注释
- civic — 共享标签:基因组学与多组学 / 变异与注释
- ensembl — 共享标签:基因组学与多组学 / 变异与注释
- ipd-imght-hla — 共享标签:基因组学与多组学 / 变异与注释
- mgi — 共享标签:基因组学与多组学 / 变异与注释
- biosamples — 共享标签:基因组学与多组学 / 变异与注释
- clingen — 共享标签:基因组学与多组学 / 变异与注释
- sequence-ontology — 共享标签:基因组学与多组学 / 变异与注释
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

