Module 01 — EGFR 活性与分子身份:一个可靠的研究起点

数据:TeachOpenCADD T001(Volkamer Lab,固定提交 4efdbd36723b5d07960142e15df393d7c6df2ba1) 靶点:人 EGFR(UniProt P00533,ChEMBL CHEMBL203,基因 EGFR) 生成时间:2026-09-11T16:37:42Z(复核修正后重生成) 脚本:scripts/01_curate_egfr_activity_identity.py 本版说明:已按 CADD skill 的 public-data 方法说明逐项复核来源推断、化学身份表述、教程编号与图注,修正处见第 11 节。


一句话结论

我们建立了一个 5568 个带 EGFR IC50 测量记录的分子 的研究起点:活性值、结构身份、描述符都经过核对并保存成可复用表。 两件事必须分清:

而"有 IC50 记录"不等于"已确证是 EGFR 抑制剂":本队列的 pIC50 覆盖 1.60–11.52,弱的那些(IC50 到 25 mM)本就说明并非每个成员都是有效抑制剂。


1. 输入说明了什么:一行活性到底代表什么

TeachOpenCADD T001 的数据包里有两类文件,角色不同:

文件 角色 内容
T001_query_chembl/data/EGFR_bioactivities_CHEMBL27.csv.zip 原始查询快照 7178 条活性记录,14 列,含实验 ID 与描述
T001_query_chembl/data/EGFR_compounds.csv(≡..._ea055ef.csv) 冻结教学队列 5568 个分子,仅 分子ID / IC50 / 单位 / SMILES / pIC50
public-query-cache/* 带日期的公开查询观测 ChEMBL / PubChem / UniProt 的历史查询结果

原始快照本身已是筛选后的结果:7178 条记录全部满足 target=CHEMBL203、type=IC50、relation== '='、assay_type='B'。因此 T001 的这几个"过滤器"在这份快照里没有再删除任何一行。

真正被单位条件删掉的是 65 条非 nM 记录,构成为:58 条 µg/mL + 6 条 /µM + 1 条单位缺失(standard_units 为 NaN)。

一个关键但易被忽略的语义:IC50 是依赖实验条件的量。这份快照来自 745 个不同实验,描述里包含野生型 EGFR、L858R 突变、L858R/T790M 双突变、以及 A431 细胞等完全不同的条件。而冻结教学队列把 assay_chembl_id 丢掉了。所以冻结队列里的 IC50 是"某一次实验条件下的一个数",不同分子的数值不可当作同一条件下的可比测量。

原始快照里没有任何 >、< 这类删失关系(relation 全为 =),因此本数据不存在需要保留的删失边界。


2. 关键选择 A:从 IC50 得到 pIC50

把 nM 的 IC50 转成对数尺度:

pIC50 = 9 − log10(IC50 / nM)

对数尺度让"1 个单位 = 10 倍":pIC50 相差 1,活性相差 10 倍。5568 个分子的 IC50 从 0.003 nM 到 25 000 000 nM,跨越 9.92 个数量级——这正是必须用对数的原因。

教程编号更正:本报告保留的 pIC50 ≥ 6.3 阈值,其来源是下游 T007/T027 的分类基准,不是 T001(T001 只做 ChEMBL 查询与整理)。它对应 IC50 ≤ 501 nM,是一个来源定义的标签口径,不是通用生物学分界。按它对本次队列做平衡:≥6.3 有 3256 个(58.5%),<6.3 有 2312 个(41.5%)。


3. 关键选择 B:两条分支,以及"能排除什么、不能证明什么"

按 T001 文档化的规则,我从原始快照重建了一条"整理分支":

7178 条原始记录
 → 7178  (type=IC50)
 → 7178  (relation '=')
 → 7178  (assay_type B)
 → 7113  (standard_units = nM)          ← 唯一一次真正的剔除(65 条非 nM)
 → 7113  (standard_value 数值非空)       ← 无剔除
 → 5451  (每分子取源顺序第一条)

把重建分支与冻结队列按分子 ID 对齐:

对账结果 数量
两分支共有 5444
├ pIC50 完全一致 5311
└ pIC50 不同 133
仅存在于冻结队列 124
仅存在于重建分支 7

3.1 我们对那 133 个"数值不同"的分子做了什么检验

方法说明要求:"在原始记录里找不到该值"只能排除"选了那一条记录",不能排除 median / mean 这类可能落在观测值之间的聚合——必须逐一实测。 因此我直接检验了被点名的记录级规则(结果见 data/aggregation_rule_tests.csv):

被检验的规则 能解释的差异分子数 / 133
first(源顺序首条) 0
last(末条) 0
min / max 0 / 0
median / mean 0 / 0
gmean(几何均值) 0
median_log10(对数中位数) 0
任意单条原始记录 1

另有一个更强的结构性事实:133 个里有 122 个分子在原始文件中只有 1 条记录。对它们而言,任何"从记录里挑选或聚合"的规则都只能得到那一个值,所以这些差异从定义上就不可能由文件内规则产生。

3.2 结论(严格区分事实与成因)

因此处理方式是:保留冻结队列作为主交付表(教学基准与标签在它身上),把重建分支单独保存并标注,并把实测差异与未决成因分开记录。


4. 关键选择 C:分子身份怎么定义,以及"没有 @ 不等于没有手性"

身份核对用 InChIKey(分子身份的国际标准哈希),而不是字符串比较 SMILES:

关于手性,必须小心一个常见误判:SMILES 里没有 @ 不等于这个分子没有手性(它可能本来就无手性中心)。


5. 公开数据库核对:查了什么、什么时候查的

5.1 复用的历史缓存(不必重新请求)

public-query-cache/PROVENANCE.json 记录:查询时间 2026-09-11T15:33:30Z – 15:37:02Z(UTC),76 个 HTTP 请求全部 200,来源为 UniProt REST、ChEMBL REST、PubChem PUG REST。样本是"pIC50 最高的 8 个 + 最低的 8 个 + 随机 12 个(seed 42)+ 吉非替尼/厄洛替尼"去重后的 30 个分子——它不是全队列的随机抽检。

把这些历史观测与本地 RDKit 计算逐条对账(属于"复核旧观测",不是新的在线验证):

核对项 结果
靶点身份(UniProt P00533 / ChEMBL CHEMBL203) 一致
30 个分子的 PubChem InChIKey vs 本地 InChIKey 30/30 完整一致
gefitinib 相似性 top10(CID 123631, Threshold=75, MaxRecords=10) 10 条命中

5.2 一次性小样本在线复核(当前状态)

为确认"缓存放今天是否仍成立",做了一次小样本在线复核:2026-09-11T16:20:57Z – 16:22:10Z(UTC),24 个请求全部 200。

合计 12/12 一致。这只说明受检样本的观测与查询可复用,不能外推为整个队列已通过审计。

5.3 相似性观测怎么读(这里最容易过度解读)

gefitinib(CHEMBL939,CID 123631)的 top10 命中中,有 5 个在冻结队列里(厄洛替尼、拉帕替尼、凡德他尼、吉非替尼、博舒替尼),5 个不在(阿夫唑嗪、哌唑嗪、多沙唑嗪、特拉唑嗪、曲美沙特)。

已修正的错误表述:此前的报告写过"这 5 个靶点不同、环系也不同"。环系核对(data/pubchem_similarity_crosscheck.csv)显示这是错的:

由此得到本节真正想教的结论,且只陈述被证据支持的部分:

  1. 共享片段 ≠ 共享靶点:5 个队列外命中与 gefitinib 共享喹唑啉,但在这张 EGFR 表里没有它们的记录;而队列内的博舒替尼反而不含喹唑啉。
  2. "不在队列里"不等于"不作用于 EGFR":队列归属只反映这份表里有没有它的 IC50 记录,不能用来判断它有没有 EGFR 活性或临床适应症。因此本报告不主张这 5 个化合物的具体靶点类别(本次尝试用公开来源核对它们药理分类未返回有效内容,故不作为结论采用)。
  3. 两个阈值不可互换:图上横轴是本地重算的 Morgan(r=2) Tanimoto,而 PubChem 的 Threshold=75 用的是 PubChem 自己的指纹——两者不是同一个量,所以 75 这条线不能画在 Morgan 轴上。

6. 组图解读

四张图按"问题 → 证据"组织,每张图旁边都有同名 .csv 存放画图背后的真实数据。

图 1|队列概览:活性长什么样

fig1

图 2|两条分支的重建与对账

fig2

图 3|化学空间与身份/表示标志

fig3

图 4|公开身份核对与相似性观测

fig4


7. 局限清单(务必随数据一起传递)

  1. 活性不可跨实验直接比较:数据来自 745 个实验,冻结队列又丢弃了实验 ID 与描述;pIC50 只能作为"某次测量"的记录。
  2. 两条分支关系未定:重建不能复现冻结队列是已测事实;但"不同下载/版本"是未证成因。124 / 7 个分子只存在于单一分支,133 个共享分子数值不同且 132 个无法用被测记录级规则解释。不要把两条分支结果混在一张表里统计。
  3. 有记录 ≠ 已验证抑制剂:进入队列只表示"该表里有它的 EGFR IC50 记录",不证明其活性、选择性或成药性。
  4. 手性不完整:526 个分子存在潜在但未指定的手性中心,会影响基于 3D 的后续步骤。
  5. 表示未标准化:保留了 167 个多片段分子与 4 个净电荷非零分子,未做去盐/中性化/互变异构枚举;多片段不必然是盐。
  6. 公开核对是范围结论:缓存 76 次 + 在线 24 次请求都在样本上成立,不等于全队列审计;且"队列外"只说明该表无记录,不说明无活性。
  7. 相似性命中 ≠ 同一靶点:环系核对显示 9/10 命中共享喹唑啉,但队列内外的划分与环系并不一一对应(博舒替尼即反例)。

8. 保存了什么,怎么复用

module-01/
├─ REPORT.md                      ← 本文
├─ data/
│   ├─ egfr_activity_curated.csv          ← 主交付表(5568 分子 + 身份 + 描述符 + 标签)
│   ├─ egfr_activity_reconstructed_from_raw.csv  ← 重建分支(单独标注)
│   ├─ cohort_reconciliation.csv          ← 两分支逐分子对账
│   ├─ reconciliation_mismatch_diagnosis.csv  ← 133 个数值不同的逐分子诊断
│   ├─ aggregation_rule_tests.csv         ← 被点名的记录级规则逐一实测结果
│   ├─ pubchem_identity_crosscheck.csv    ← 30 条身份核对
│   ├─ pubchem_similarity_crosscheck.csv  ← gefitinib 相似性核对(含环系核对列)
│   ├─ raw_assay_source_mix.csv           ← 原始快照的实验来源结构
│   ├─ curation_funnel_reconstructed.csv  ← 整理漏斗
│   ├─ input_inventory.csv                ← 输入 SHA256 清单
│   ├─ live_identity_check.csv            ← 在线复核结果
│   └─ dictionary.md                      ← 数据字典
├─ figures/                       ← 4 张组图 PNG + 每张同名 sidecar CSV
├─ report/
│   ├─ summary.json               ← 机器可读汇总
│   └─ api_verification_log.csv   ← 在线请求日志(URL/状态/耗时/时间)
└─ scripts/
    └─ 01_curate_egfr_activity_identity.py   ← 可复用脚本

复现(可离线;--live-check 才联网):

python scripts/01_curate_egfr_activity_identity.py \
    --input-root <data/cadd-tutorial-inputs> \
    --out        <module-01>

9. 下一步可以做什么


10. 溯源与许可


11. 本次复核修正记录

按 public-data 方法说明复核后,修正如下:

# 位置 原表述(问题) 修正后 依据
1 开头结论 "5568 个 EGFR 抑制剂分子" "5568 个带 EGFR IC50 记录的分子" 有 IC50 记录不构成已验证抑制剂
2 开头结论 / 第 3 节 "来自不同的数据下载/版本,不是同源父子关系" 只陈述"重建不能复现冻结文件";成因未定,不证明不同下载/版本 方法说明:mismatch 不证明 download/release 不同;须区分实测差异与未决成因
3 第 3 节 仅凭"记录里找不到该值"就称排除了文件内聚合 逐一直接实测 first/last/min/max/median/mean/gmean/median_log10;并指出 122/133 只有 1 条记录 方法说明:须直接检验被点名的聚合规则
4 第 1 节 "65 条非 nM(58 µg/mL、6 /µM)" 补充 "+1 条单位缺失" 实测 58+6+1=65
5 第 2 节 把 6.3 阈值称作"T001 教学基准" 归到 T007/T027 下游分类基准 方法说明:6.3 应归 T007/T027,非 T001
6 第 4 节 "同一骨架的 4 个立体异构体" "连通性相同的 4 个立体异构体" connectivity 层不是 Murcko 骨架
7 第 4 节 "带电荷 4 个" "净形式电荷非零 4 个" 非零总电荷计的是净带电分子
8 第 4 节 直接称多片段为"含盐" "多片段(可能是盐)";数片段不能判定盐 计数片段不等于识别盐
9 第 5.3 节 / 图 4B "这 5 个靶点不同、环系也不同" 删除环系断言:9/10 命中含喹唑啉(含 5 个队列外者),博舒替尼为反例 本地环系与 MCS 核对
10 第 5.3 节 断言队列内 5 个都是 EGFR/ERBB 家族抑制剂 删除;只陈述"在该表里有 IC50 记录" 队列归属≠主要靶点
11 第 9 节 "T013 的复合物" 结构材料走 T008 及相关章节 方法说明:T013 是 PubChem 查询
12 图 4B 图注 "10 个命中均共享喹唑啉环" "9/10 含喹唑啉环(博舒替尼为喹啉类)" 实测 9/10