# MacrolactoneDB 验证、碎片库分析与 Tylosin 枚举报告 本文档把 `temp.csv` 的验证筛选、侧链碎片库生成、碎片大小分析、16 元环位点提取,以及 tylosin 枚举结果串成一条完整数据链路。目标是让没有上下文的读者也能直接理解: 1. 原始数据如何从 11,036 个分子收缩到标准大环内酯集合。 2. 为什么最终碎片库只有 4,451 个母体进入可拼接片段分析。 3. 为什么后续侧链筛选采用 `>3` 重原子作为下限。 4. 16 元环的 `3/4/12/13` 位点碎片是如何导出并用于 tylosin 枚举的。 ## 结果文件一览 | 文件 | 作用 | |---|---| | [validation_output/summary.csv](/Users/lingyuzeng/project/macro_split/validation_output/summary.csv) | 逐分子验证结果与 `processing_status` | | [validation_output/summary_statistics.json](/Users/lingyuzeng/project/macro_split/validation_output/summary_statistics.json) | 验证统计汇总 | | [validation_output/fragments.db](/Users/lingyuzeng/project/macro_split/validation_output/fragments.db) | 验证阶段 SQLite 数据库 | | [validation_output/fragment_library.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library.csv) | 统一碎片库导出 | | [validation_output/fragment_library_analysis/fragment_atom_count_summary.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_summary.csv) | 碎片原子数概览,含最大值 | | [validation_output/fragment_library_analysis/fragment_atom_count_frequency.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_frequency.csv) | 原子数频率分布 | | [validation_output/fragment_library_analysis/fragment_atom_count_filter_candidates.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_filter_candidates.csv) | 不同下限阈值的删减效果 | | [validation_output/fragment_library_analysis/analysis_summary.txt](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/analysis_summary.txt) | 文字版分析摘要 | | [validation_output/ring16_position_fragment_exports/pos3_fragments_dedup.csv](/Users/lingyuzeng/project/macro_split/validation_output/ring16_position_fragment_exports/pos3_fragments_dedup.csv) | 16 元环 3 位碎片库 | | [validation_output/ring16_position_fragment_exports/pos4_fragments_dedup.csv](/Users/lingyuzeng/project/macro_split/validation_output/ring16_position_fragment_exports/pos4_fragments_dedup.csv) | 16 元环 4 位碎片库 | | [validation_output/ring16_position_fragment_exports/pos12_fragments_dedup.csv](/Users/lingyuzeng/project/macro_split/validation_output/ring16_position_fragment_exports/pos12_fragments_dedup.csv) | 16 元环 12 位碎片库 | | [validation_output/ring16_position_fragment_exports/pos13_fragments_dedup.csv](/Users/lingyuzeng/project/macro_split/validation_output/ring16_position_fragment_exports/pos13_fragments_dedup.csv) | 16 元环 13 位碎片库 | | [validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_unique_products.csv](/Users/lingyuzeng/project/macro_split/validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_unique_products.csv) | tylosin 枚举唯一产物 | | [validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_fix_pos13.sqlite](/Users/lingyuzeng/project/macro_split/validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_fix_pos13.sqlite) | tylosin 枚举 provenance 数据库 | ## 数据流总览 ```mermaid flowchart TD A["data/MacrolactoneDB/ring12_20/temp.csv
11,036 个分子"] --> B["classify_macrocycle()
standard / non-standard / not"] B -->|standard_macrolactone| C["逐个标准大环内酯做 canonical numbering"] B -->|non_standard_macrocycle / not_macrolactone| D["processing_status = skipped"] C --> E["遍历 position > 2 的环位点"] E --> F["collect_fragmentable_side_chain_atoms()
只保留单锚点可拼接侧链"] F -->|None| G["丢弃该裂解尝试"] F -->|atoms returned| H["build_fragment_with_isotope()
生成 labeled / plain SMILES"] H --> I["写入 side_chain_fragments"] H --> J["写入 fragment_library_entries
source_type = validation_extract"] J --> K["fragment_library.csv / fragments.db"] K --> L["按 plain SMILES 计算重原子数"] L --> M["全库阈值分析 + 位点多样性分析"] M --> N["导出 ring16_position_fragment_exports/"] N --> O["tylosin scheme_b_fix_pos13 枚举"] ``` ## 1. 术语与编号规则 | 术语 | 含义 | |---|---| | `canonical numbering` | `1 = 内酯羰基碳`,`2 = 相邻酯氧`,`3..N` 按从 2 位出发沿环唯一遍历顺序编号 | | `mirror mapping` | 16 元环固定镜像关系,`3→16`、`4→15`、`5→14`、`6→13`、`7→12`、`8→11`、`9→10` | | `standard_macrolactone` | 只有一个可唯一确认的 12-20 元 lactone 环,且 `3..N` 全部为碳 | | `non_standard_macrocycle` | 有重叠候选环,或者 `3..N` 位置出现非碳原子,属于桥环 / 稠环 / 非标准大环 | | `not_macrolactone` | 找不到有效的 12-20 元 lactone 环 | | `cleavage_position` | 侧链连接到环上的位置编号 | | `splice_ready` | 该碎片是单锚点、可直接用于重新拼接的碎片 | | `fragment_smiles_plain` | 去掉 isotope 但保留 dummy 原子 `*` 的碎片 SMILES | | `fragment_smiles_labeled` | 带 isotope 的碎片 SMILES,例如 `[13*]...` | 这里特别强调一点:碎片去重时考虑了 dummy 原子 `*`,但**不**把 dummy 上的 isotope 作为唯一性依据。也就是说,`*C`、`*O` 这类结构会按 `plain SMILES` 去重,但 `[`13*`]...` 这类位置标签不会把同一 plain 结构拆成多个独立 chemotype。 ## 2. 从 `temp.csv` 到标准大环内酯 原始输入文件是 [data/MacrolactoneDB/ring12_20/temp.csv](/Users/lingyuzeng/project/macro_split/data/MacrolactoneDB/ring12_20/temp.csv),共 **11,036** 个分子。 ### 2.1 分类结果 | 分类 | 数量 | 占总输入比例 | |---|---:|---:| | `non_standard_macrocycle` | 6,336 | 57.41% | | `standard_macrolactone` | 4,482 | 40.61% | | `not_macrolactone` | 218 | 1.98% | 这一步的关键不是“有没有大环”本身,而是“是否满足标准大环内酯定义”: 1. 必须存在 12-20 元 lactone 候选环。 2. 候选环必须唯一,不能是多个重叠候选。 3. 环上 `3..N` 必须全部是碳。 因此,很多结构虽然是宏环,但会因为桥环、稠环、杂原子插入或候选不唯一而被排除在 `standard_macrolactone` 之外。 ### 2.2 标准大环内酯的 ring size 分布 在 **4,482** 个标准大环内酯中,ring size 分布如下: | ring size | 数量 | 占标准集比例 | |---|---:|---:| | 12 | 426 | 9.50% | | 13 | 198 | 4.42% | | 14 | 2,478 | 55.29% | | 15 | 43 | 0.96% | | 16 | 1,111 | 24.79% | | 17 | 42 | 0.94% | | 18 | 140 | 3.12% | | 19 | 6 | 0.13% | | 20 | 38 | 0.85% | 这个分布说明,当前验证集中最主要的标准大环内酯集中在 **14 元环** 和 **16 元环**,其中 14 元环超过一半,16 元环接近四分之一。 ### 2.3 为什么 4,482 会进一步变成 4,451 这 4,482 个标准大环内酯里,有 **31 个分子没有任何可拼接侧链碎片**,因此不会进入 `fragment_library.csv`。 换句话说: | 阶段 | 数量 | 占标准集比例 | |---|---:|---:| | `standard_macrolactone` 总数 | 4,482 | 100.00% | | 至少产生 1 条侧链碎片 | 4,451 | 99.31% | | `num_sidechains = 0` | 31 | 0.69% | 这 31 个分子不是“分类失败”,而是“分类成功但没有通过侧链可拼接过滤”。它们的 `cleavage_positions` 为空,说明在 `position > 2` 的环位点上,没有找到满足规则的外侧链。 ### 2.4 实际进入碎片库的 ring size 分布 在最终 **4,451** 个 fragment-bearing 母体中,ring size 分布如下: | ring size | 数量 | 占 fragment-bearing 母体比例 | |---|---:|---:| | 12 | 422 | 9.48% | | 13 | 191 | 4.29% | | 14 | 2,475 | 55.61% | | 15 | 41 | 0.92% | | 16 | 1,105 | 24.83% | | 17 | 36 | 0.81% | | 18 | 139 | 3.12% | | 19 | 4 | 0.09% | | 20 | 38 | 0.85% | 这张表才是后续碎片库真正的母体分布,因为它排除了那 31 个“标准但无侧链”的分子。 ## 3. 碎片库如何生成 碎片库的生成逻辑在验证流程中完成,结果写入: | 输出 | 含义 | |---|---| | [validation_output/fragment_library.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library.csv) | 统一碎片库导出 | | [validation_output/fragments.db](/Users/lingyuzeng/project/macro_split/validation_output/fragments.db) | `parent_molecules`、`side_chain_fragments`、`fragment_library_entries` 等表 | 对每个 `standard_macrolactone`,程序会: 1. 先做 canonical numbering。 2. 只遍历 `position > 2` 的位点。 3. 跳过环内原子和 intrinsic lactone neighbor。 4. 用 `collect_fragmentable_side_chain_atoms()` 识别单锚点、可拼接侧链。 5. 用 `build_fragment_with_isotope()` 生成 `fragment_smiles_labeled` 和 `fragment_smiles_plain`。 6. 只有 `Chem.MolFromSmiles(plain_smiles)` 可解析时,碎片才会写入数据库和 CSV。 因此,这份库并不是“把所有侧链都随意裂开”,而是“只保留单锚点、可重拼接、SMILES 合法的侧链碎片”。 ## 4. 统一碎片库的规模与去重 `fragment_library.csv` 的核心统计如下: | 指标 | 数值 | |---|---:| | 行数 | 34,829 | | 去重母体数 | 4,451 | | 唯一 `fragment_smiles_plain` 数 | 1,852 | | 唯一 `fragment_smiles_labeled` 数 | 2,051 | 这里最容易误解的一点是:`1,852` 不是“把 dummy 原子去掉以后才算出来的”,而是按 `fragment_smiles_plain` 去重得到的。`plain` 仍然保留 dummy 原子 `*`,只是去掉了 isotope 标签,因此: 1. `*C` 和 `*O` 这样的结构会被当成不同碎片。 2. `[13*]C` 和 `[16*]C` 会因为 isotope 标签被抹掉而收敛成同一个 plain 结构。 换言之,`1,852` 说明的是“**去掉位置标签后的 chemotype 数量**”,而不是“把 dummy 原子也删掉后的数量”。 ### 4.1 高频碎片 当前库里最常见的 plain 碎片是: | 碎片 | 计数 | 占总行数比例 | |---|---:|---:| | `*C` | 15,927 | 45.73% | | `*O` | 4,722 | 13.56% | | `*=O` | 3,167 | 9.09% | | `*CC` | 2,261 | 6.49% | 这四类最简单的碎片合计已经占到总行数的绝大部分。它们非常适合解释为什么后续要使用 `>3` 重原子作为设计相关下限,因为库里真正占量的是大量一到三原子的“噪声型”片段,而不是高信息密度的大碎片。 ### 4.2 为何 `1852` 仍然不算“小” `34,829` 条行数去重后剩 `1,852` 个 unique plain SMILES,并不反常,原因是: 1. 很多碎片在不同母体、不同位置上会重复出现。 2. 小碎片的复用率极高,尤其是 `*C`、`*O`、`*=O`、`*CC` 这类。 3. 只要保留 dummy 原子 `*`,就会把“裸碎片”与“带连接点的片段”区分开来,因此 unique 数不会无限压缩。 ## 5. 侧链筛选阈值:为什么下限是 `>3` 重原子 关于你关心的“上限和下限”: 1. **下限是明确的**:后续设计相关侧链分析采用 `>3` 重原子。 2. **上限不是硬编码规则**:当前代码和报告没有设置统一的碎片上限。 3. **如果问当前库的经验上沿**:`fragment_atom_count_summary.csv` 显示最大重原子数是 **48**,`p95 = 14`,`p99 = 27`。 ### 5.1 结果文件位置 如果你要找“上限是多少”的依据,应该看这几个文件: | 文件 | 作用 | |---|---| | [fragment_atom_count_summary.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_summary.csv) | 给出 `max_atom_count = 48`、`p95 = 14`、`p99 = 27` 等摘要 | | [fragment_atom_count_frequency.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_frequency.csv) | 给出每个原子数的频次分布 | | [fragment_atom_count_filter_candidates.csv](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_filter_candidates.csv) | 给出不同下限阈值的删减效果 | | [analysis_summary.txt](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/analysis_summary.txt) | 文字版摘要,最适合快速引用 | ### 5.2 为什么下限选 `>3` 阈值候选表显示: | 下限规则 | 删除行数 | 删除行比例 | 删除 unique fragments | |---|---:|---:|---:| | `<=1` | 23,994 | 68.89% | 10 | | `<=2` | 28,069 | 80.59% | 26 | | `<=3` | 28,550 | 81.97% | 52 | | `<=4` | 29,045 | 83.39% | 88 | | `<=5` | 29,272 | 84.04% | 141 | 这组数据给出的结论非常清楚: 1. `<=3` 已经去掉了 **82%** 左右的记录。 2. 但它只去掉了 **2.8%** 的 unique fragments。 3. 换句话说,低于等于 3 重原子的碎片主要贡献的是“行数噪声”,不是“结构多样性”。 所以,`>3` 是一个很自然的设计相关下限,因为它把大量单原子、双原子、三原子碎片排除掉,同时尽可能保留更像“真实取代基”的片段。 ### 5.3 上限为什么不设成硬规则 当前库的重原子数分布是长尾的,最大值到 48,但: 1. 大于 14 的片段已经属于少数。 2. 大于 27 的片段更是极少。 3. 这些长尾片段中仍可能包含糖环、杂环、稠环等有意义的单锚点片段。 因此,当前项目更适合把上限当作“任务依赖的经验裁剪”,而不是“全局硬上限”。 如果你必须写一个论文里的操作性描述,可以这样写: > 本研究采用 `>3` 重原子作为设计相关侧链下限;上限不做全局硬截断,仅在具体下游任务中按库规模与化学可解释性进行任务特异性裁剪。当前库的经验分布显示重原子数最大为 48,95% 分位数为 14,99% 分位数为 27。 这个表述比“固定上限 = 某个整数”更稳妥,也更符合当前代码和数据实际。 ## 6. 16 元环的位点碎片提取 16 元环是本项目里最重要的 ring size 之一,后续位点导出固定在 canonical 位置 `3/4/12/13`。 ### 6.1 位点导出数量 `validation_output/ring16_position_fragment_exports/` 下四个导出文件的 unique fragment 数量如下: | 位点 | unique fragment 数 | |---|---:| | 3 | 121 | | 4 | 70 | | 12 | 99 | | 13 | 198 | 所以,你前面问的“3、4、12 位置是不是 121、70、99?”答案是:**对,正确**。如果把 13 位也算上,那么 13 位是 **198** 条 unique fragments。 ### 6.2 对应的全量与设计相关子集 | 位点 | 全量碎片数 | unique plain SMILES | `>3` 重原子后碎片数 | `>3` unique plain SMILES | |---|---:|---:|---:|---:| | 3 | 1,048 | 121 | 269 | 117 | | 4 | 595 | 70 | 269 | 63 | | 12 | 930 | 99 | 177 | 83 | | 13 | 876 | 198 | 709 | 193 | 这说明: 1. 13 位在天然库里最丰富。 2. 3 位和 4 位的 unique chemotype 也不低。 3. 12 位虽然总量不如 13 位,但设计相关子集仍然相当可观。 ### 6.3 位置编号与文献标签的关系 由于项目统一使用 canonical numbering,16 元环的这四个位点在文献视角下可以理解为镜像位置: | canonical position | literature-style mirrored label | |---|---| | 3 | 16 | | 4 | 15 | | 12 | 7 | | 13 | 6 | 因此,当前数据里最富集的 canonical 位点 `13, 3, 4, 12`,对应文献常说的 `6, 16, 15, 7` 一组方向镜像标签。 ## 7. tylosin 的枚举结果 本项目里 tylosin 的枚举结果保存在: | 文件 | 含义 | |---|---| | [validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_unique_products.csv](/Users/lingyuzeng/project/macro_split/validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_unique_products.csv) | 唯一产物表 | | [validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_fix_pos13.sqlite](/Users/lingyuzeng/project/macro_split/validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/tylosin_scheme_b_fix_pos13.sqlite) | 组合 provenance 与运行元数据 | | [validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/README.md](/Users/lingyuzeng/project/macro_split/validation_output/enumeration/per_scaffold/tylosin/scheme_b_fix_pos13/README.md) | 运行说明 | ### 7.1 枚举设定 该结果对应 `scheme_b_fix_pos13`,核心设定是: | 参数 | 值 | |---|---:| | `reference_slug` | `tylosin` | | `replace_positions` | `[3, 4, 12, 13]` | | `fixed_positions` | `[13]` | | `candidate_counts` | `{3: 121, 4: 70, 12: 99}` | 这意味着: 1. 13 位的糖基保持不变。 2. 只对 3、4、12 位进行枚举。 3. 拼接空间是这三个位点片段库的笛卡尔积。 ### 7.2 枚举规模 | 指标 | 数值 | |---|---:| | 尝试组合数 | 838,530 | | 成功拼接数 | 838,530 | | 去重后唯一产物数 | 810,810 | | 合并掉的重复组合数 | 27,720 | | 重复率 | 3.31% | 这里最关键的一点是: `838,530 = 121 × 70 × 99` 所以原始组合数就是 3 个位点片段库的直积。去重后变成 810,810,说明有一小部分不同组合最终坍缩成了同一个 canonical product SMILES。 ### 7.3 唯一产物分布 `occurrence_count` 的分布是: | occurrence_count | 唯一产物数 | |---|---:| | 1 | 790,020 | | 2 | 13,860 | | 3 | 6,930 | 这说明大多数 unique product 都只对应单一路径,但也有一部分产物由多个组合收敛而来。 ## 8. 可以直接写进论文的结论 ### 8.1 验证与碎片库生成 在 MacrolactoneDB `ring12_20` 验证集中,11,036 个输入分子经分类后得到 4,482 个 `standard_macrolactone`,其中 31 个标准大环没有任何可拼接侧链碎片,最终形成 4,451 个 fragment-bearing 母体和 34,829 条可拼接碎片记录。 ### 8.2 侧链筛选阈值 碎片大小分布极度右偏,`*C`、`*O`、`*=O`、`*CC` 四类最简单碎片已占据绝大多数记录。基于当前库的频率分布,建议将 `>3` 重原子作为后续设计相关侧链的下限;同时,当前库没有全局硬上限,最高观察值为 48 重原子,95% 分位数为 14,99% 分位数为 27。 ### 8.3 16 元环位点 在 canonical 16 元环编号下,`3/4/12/13` 位导出的 unique fragments 数分别为 121、70、99、198。若按文献镜像标签表达,则对应 `16/15/7/6` 位。 ### 8.4 tylosin 枚举 以 tylosin 为参考骨架、固定 13 位糖基不变时,`3/4/12` 位枚举共产生 838,530 个组合,去重后得到 810,810 个 unique products,重复折叠率为 3.31%。 ## 9. 推荐的图表引用 | 图 | 文件 | |---|---| | 全库碎片原子数分布 | [fragment_atom_count_distribution.png](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/fragment_atom_count_distribution.png) | | 16 元环位点数量对比 | [ring16_position_count_comparison.png](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/ring16_position_count_comparison.png) | | 16 元环设计相关碎片 boxplot | [ring16_position_atom_count_boxplot_gt3.png](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/ring16_position_atom_count_boxplot_gt3.png) | | 16 元环位点多样性图 | [ring16_position_diversity_gt3.png](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/ring16_position_diversity_gt3.png) | | 16 元环药化热点对比 | [ring16_medchem_hotspot_comparison.png](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/ring16_medchem_hotspot_comparison.png) | | 16 元环环状侧链敏感性 | [ring16_position_ring_sensitivity.png](/Users/lingyuzeng/project/macro_split/validation_output/fragment_library_analysis/ring16_position_ring_sensitivity.png) | ## 10. 一句话总结 这条链路的核心结论是:`temp.csv` 中 11,036 个分子经过标准大环内酯筛选后,真正进入可拼接碎片库的是 4,451 个母体、34,829 条碎片;碎片大小分布强烈偏向 1-3 重原子小片段,因此后续设计分析采用 `>3` 重原子作为下限,而 16 元环的 3、4、12、13 位碎片与 tylosin 的 fixed-pos13 枚举结果一起构成了后续论文中最重要的参数和设计依据。