Gtars 区间重叠与集合代数实战指南:Overlap、计数、Consensus 语义全解析
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
本文基于仓库 skills/gtars/references/overlap.md(验证日期 2026-07-23,针对 Python
gtars==0.9.2与 Rust/CLIgtars==0.9.0)撰写,并补充仓库内配套源码与测试证据。你将掌握:Gtars 中 0-based half-open 区间的精确重叠判据、Python 定向 overlap 查询、基于碱基对(bp)的集合度量、Rust 索引 API、CLIoverlaprs的真实行为、consensus 的合并语义,以及避免数据泄漏与资源失控的工程实践。
一、先从区间语义说起:什么才算"重叠"
Gtars 全部区间运算建立在0-based、half-open坐标系上:start包含、end不包含。两个有效区间重叠的充要条件是:
a.start < b.end and b.start < a.end也就是说[0,10)与[9,20)重叠(交集为[9,10)),但与相邻的[10,20)不重叠——相邻区间只"接触"而不"相交"。这个细节决定了后续所有 API 的行为差异。
在把任何 BED 喂给 Gtars 之前,必须在外部完成四类校验:
- Assembly 声明:记录确切的 assembly 版本(如
GRCh38.p14)与 chromosome-sizes 文件的 SHA-256,绝不从文件名或chr前缀推断 assembly; - contig 名称精确匹配:
1与chr1、alt 位点、decoy、线粒体别名不可互换; - 坐标合法性:要求
start < end,且不超出染色体长度上界; - Gtars 坐标上限:Rust 侧坐标为
u32,任何start/end超过4,294,967,295的输入都必须先被拒绝。
仓库为此提供了零依赖的校验工具 scripts/bed_validator.py,它逐行执行上述契约,输出结构化 JSON 报告,并且不重写输入、不联网:
python3 -B scripts/bed_validator.py \ --input data.bed.gz \ --assembly GRCh38.p14 \ --chrom-sizes GRCh38.p14.chrom.sizes \ --require-sorted其底层实现在 scripts/_common.py 的inspect_bed()中:识别fewer_than_three_columns、coordinate_exceeds_gtars_u32、end_before_start、end_beyond_contig、unknown_contig等错误码,同时将重复区间、区间互相重叠、乱序行作为 warning 上报。测试 tests/gtars/test_scripts.py 验证了end_beyond_contig与 URL 路径被拒绝的行为。
关键区分:overlap 查询与 reduction 回答的是不同问题。overlap/query 方法使用上述普通 half-open 判据;
reduce()合并的是重叠且相邻的区间;union()对拼接后的集合做 reduce;而 consensus 先 reduce union,因此相邻性可以把多个 replicate 的支持域合并到一起。
二、Python 定向 Overlap 查询:counts、flags、indices、subset
Gtars 的 Python 绑定把"查询区间集合"与"被查询区间集合"视为有方向性的(directional)。核心用法:
from gtars.models import RegionSet query = RegionSet("query.bed") universe = RegionSet("universe.bed") counts = query.count_overlaps(universe) any_hit = query.any_overlaps(universe) hit_indices = query.find_overlaps(universe) query_with_hits = query.subset_by_overlaps(universe)方向性语义务必记牢:
counts[i]:与第i个query区间重叠的 universe 区间数量(一个整数);any_hit[i]:第i个 query 区间是否有至少一个命中的布尔值;hit_indices[i]:命中区间在内存中 universe的 0-based 下标列表;subset_by_overlaps:只保留有一个及以上命中的 query 区间。
行号对齐陷阱
两个文件型集合在构造时都会被排序(Python 0.9.2 中RegionSet(path)按染色体字典序、再按数值 start 排序)。因此这些返回数组的下标对应的是排序后的行序,而非原文件行号。若需要把结果与原始记录对应,必须携带一个独立的稳定标识符(例如 BED 第 4 列的 peak ID),绝不能直接按行号 join。相关说明见 references/python-api.md 与 SKILL.md 中的 genomic data contract。
拿到真实的交集坐标
如果目标是交集的碱基对片段而不是计数:
pieces = query.intersect_all(universe)intersect_all对每个重叠对计算[max(starts), min(ends)),即所有相交片段本身。它与pintersect有本质区别:pintersect按下标位置把两个集合逐行配对(取决于构造后是否被排序),并非基因组意义上的 all-vs-all 求交。
三、基于碱基对的集合度量:Jaccard、Coverage、Overlap Coefficient
当关心的是"多少 bp 被覆盖"而非"多少条区间命中"时,使用以下度量接口:
reduced = query.reduce() difference = query.setdiff(universe) combined = query.concat(universe) union = query.union(universe) pairwise = query.pintersect(universe) jaccard = query.jaccard(universe) covered_fraction = query.coverage(universe) overlap_coefficient = query.overlap_coefficient(universe)各度量的精确定义:
| 度量 | 定义 | 备注 |
|---|---|---|
| Jaccard | intersection_bp / union_bp | 交集 bp 与并集 bp 之比 |
| Coverage | query 中被子集覆盖的 bp 占比 | 在重叠归一化(reduce)后计算,取值[0,1] |
| Overlap coefficient | intersection_bp / min(query_bp, universe_bp) | 与小集合之比,放大部分重叠 |
concat | 不合并,直接拼接 | 与union不同 |
union | 对拼接结果做 reduce | 得到最小合并集 |
setdiff | 从 query 中减去 universe 的 bp | 可能把 query 区间切碎成多段 |
需要特别警惕的是空集与零分母的边界行为:jaccard的并集为 0、overlap_coefficient的较小集合为 0 时,度量值依赖具体实现。务必在固定的 pinned 版本(gtars==0.9.2)上用小型合成数据先验证,再用于正式结论。
注意coverage是"被覆盖的 bp 占比",不是信号覆盖度,也不会生成 WIG/bigWig 文件——生成信号轨道请走 CLIuniwig(见 references/cli.md)。
四、Rust 索引 API:构建一次、查询多次
需要高性能批量查询时,Rust 侧提供IndexedRegionSet。仓库文档给出的精确依赖声明是:
[dependencies] gtars = { version = "=0.9.0", default-features = false, features = [ "core", "overlaprs" ] }采用 build-once/query-many 模式:
use gtars::core::models::RegionSet; use gtars::overlaprs::IndexedRegionSet; use std::error::Error; fn main() -> Result<(), Box<dyn Error>> { let universe = RegionSet::try_from("universe.bed")?; let query = RegionSet::try_from("query.bed")?; let index = IndexedRegionSet::new(universe); let counts = index.count_overlaps(&query, None); let flags = index.any_overlaps(&query, None); let hits = index.find_overlaps(&query, None); assert_eq!(counts.len(), query.len()); assert_eq!(flags.len(), query.len()); assert_eq!(hits.len(), query.len()); Ok(()) }三个方法的返回值长度都与 query 区间数一致——这是排齐(row-aligned)输出的硬保证,可作为集成测试中的天然断言。可选的第二参数是组件 API 的区域过滤器(region filter),None表示查询所有区域;该参数的具体签名以 0.9.0 wrapper 选中的gtars-overlaprs 0.6.0组件文档为准。
Rust 侧同样要求 pinned 精确版本:gtarsmeta-crate 的默认 feature 集为空,必须显式开启core与overlaprs。SKILL.md 中给出了包含更多模块的完整 feature 组合示例,见 SKILL.md。
五、CLIoverlaprs的真实面目:它不是计数命令
很多用户会直觉认为 CLI 的overlaprs与 Pythoncount_overlaps等价——事实并非如此。当前(0.9.0)CLI 形式:
gtars overlaprs \ --query query.bed \ --universe universe.bed \ --backend bits行为要点:
- 合法 backend 为
bits与ailist,handler 默认bits; - 输出是每个重叠的 universe 区间以 BED3 形式逐行写向 stdout;
- 不输出 query 坐标、query ID、universe ID,也不输出每条 query 的计数;
- 因此同一个 universe 区间被多次命中时,输出中无法区分——重复命中不可辨识。
需要按行对齐的计数时,必须使用 Pythoncount_overlaps。另外 0.9.0 的--streaming标志虽然被解析,但 tagged handler并不读取它,不要据此宣称更低的运行内存。CLI 选项的完整清单(-q/--query、-u/--universe、-e/--backend)见 references/cli.md。
先规划、再执行:非执行式本地计划
由于上述语义差异与资源风险,仓库强调先构建一个不执行任何命令的本地计划,经人工复核后再放行:
python3 -B scripts/execution_plan.py \ --operation overlap \ --query query.bed \ --universe universe.bed \ --assembly GRCh38.p14 \ --chrom-sizes GRCh38.p14.chrom.sizes该脚本(scripts/execution_plan.py)不 import gtars、不运行子进程、不写文件,只输出固定 argv 模板、输入 SHA-256、记录数与错误清单。其内部对overlap操作生成如下模板并明示 stdout 语义:
"interface": "cli", "argv_template": ["gtars", "overlaprs", "--query", "<query-bed>", "--universe", "<universe-bed>", "--backend", "bits"], "stdout": "one BED3 universe-hit row per overlap; query IDs and counts are not emitted"而对count操作则规划为 Python 接口query.count_overlaps(universe),返回"每个 query 区间一个整数"。这一设计直接体现了前面强调的语义分工。测试 tests/gtars/test_scripts.py 验证了 overlap 计划模板以["gtars", "overlaprs"]开头,且整个规划过程没有执行任何命令。
六、Consensus 语义:集合级支持,不是碱基级支持
Consensus 用于把多个生物学重复(replicate)合并为一份"共信区间"集。Python 侧:
from gtars.genomic_distributions import consensus rows = consensus([replicate_a, replicate_b, replicate_c])CLI 侧:
gtars consensus \ --beds replicate_a.bed replicate_b.bed replicate_c.bed \ --min-count 2 \ --output consensus.bed--beds至少需要两个路径;--min-count默认 1,过滤发生在 consensus 计算之后,且必须为正数,并应验证其不超过输入集合个数。输出为 BED4 格式chr, start, end, count,按染色体/start 排序。
算法四步走
- 拼接所有集合(concat);
- 把所有区间 reduce 成不重叠的并集,合并相邻区间;
- 对每个 union 区间,统计有多少个输入集合与之至少有一个重叠;
- 返回
chr, start, end, count。
由此得出一个反直觉但至关重要的结论:它不会在每个支持度变化处切分区间。例如部分重叠的[0,10)与[5,15)会产出 union[0,15)、count 为 2——即使两侧的 edge 其实只被一个集合支持。也就是说,consensus 的count是"合并后 union 组件上的集合级支持数",不是逐碱基支持度。任何把 count 解读为 per-base 支持的做法都是错误的。
这与reduce()的"合并重叠和相邻区间"策略一脉相承(见 SKILL.md 的 genomic data contract 第 6 条)。执行计划脚本对 consensus 操作记录的语义原话是:"reduce the union (including adjacent intervals), then count input sets having any overlap with each union interval"(scripts/execution_plan.py)。
七、Replicates 与数据泄漏:共识集构建的红线
把 consensus/universe 用于下游模型(如 tokenizer、fragment scoring、peak 调用)之前,必须遵守以下隔离原则:
- 先定义分组:在构建 consensus 之前,明确 biological replicate / donor / patient 分组;
- 同一病人的所有样本必须落在同一 split:train/validation/test 以病人为单位切分,技术重复与生物重复不得跨 split 拆分;
- 只用训练集构建共识:训练 consensus/universe 只能由训练 replicate 生成;
- 禁止用留出集调参:不得用 held-out 数据的 overlap 计数去调
--min-count、merge gap、blacklist 处理或 backend 参数; - 如实报告支持度:应分别报告每个 replicate 的支持情况与排除记录——一个合并后的 consensus 绝不等于"每个碱基都被每个 replicate 支持"。
这一原则在 SKILL.md 的 "Sensitive metadata and leakage" 一节被强化:先按 patient/donor 冻结 split,再考虑 replicate 聚合;禁止先构造全量 universe 再切分,否则验证/测试位点的 locus 支持信息会泄漏进训练过程。
八、扩展与资源边界:索引、内存、输出都可能爆炸
RegionSet会把完整区间向量加载进内存并排序,因此规模控制是工程落地的前置条件:
- 索引内存随 universe 规模线性增长;
- hit 输出规模可能远大于两侧输入:它与"重叠对"数量成正比,最坏情况下是 O(query × universe) 量级;
- 必须在外部设置输入字节数/记录数、输出行数/字节数、内存与墙钟时间上限;
- backend 切换必须经过验证:
bits与ailist语义应当等价,但切换到新 backend 前,必须在有代表性的训练数据上 pilot 两个后端,验证相同语义与确定性结果排序; - stdout 只能重定向到已批准的、不存在的输出路径,并在任务完成后核对输出。
仓库的安全基线与这些约束一一对应:scripts/_common.py 定义了硬上限HARD_MAX_BYTES = 8 GiB、HARD_MAX_RECORDS = 10,000,000、MAX_COORDINATE = 2**32 - 1,并在读取 BED 时对 gzip 解压后字节数、行字节数与记录数做三重限制;执行计划与校验脚本默认--max-bytes 512 MiB、--max-records 1,000,000(见 scripts/bed_validator.py)。tests/gtars/test_static.py 通过 AST 静态分析确保这些脚本不 import gtars/requests/socket 等危险能力,从结构上保证辅助工具本身不会执行网络或子进程。
九、已移除的过时 API:别再用旧技能的表面名字
0.9.2 Python 包不再提供以下旧技能里出现过的接口:
gtars.igd.build_index、igd.queryfilter_overlapping、filter_non_overlappingoverlap_fraction、overlap_coverage
CLI 侧igd只剩create与search两个子命令(不再是build/query/count),详见 references/cli.md。此外,过时的gtars.RegionSet顶层导入、RegionSet.from_bed、gtars overlaprs overlap/count/filter/subtract等旧命令形式也一律不要使用。以当前 0.9.2 / 0.9.0 的真实 API 表面为准,遇到旧教程中的名字先对照本仓库的 references/python-api.md 与 references/cli.md 核实。
十、实践清单:安全完成一次 overlap/consensus 工作流
综合以上语义与源码约束,推荐的工作流如下:
- 冻结版本:Python
gtars==0.9.2(Python 3.10+),Rust/CLIgtars==0.9.0(Rust Edition 2024 工具链);用 lockfile 与 SHA-256 记录所有产物(安装示例见 SKILL.md); - 验证输入:用 scripts/bed_validator.py 检查 assembly、contig、bounds、u32 上限与排序;
- 选择接口:需要逐 query 计数用 Python
count_overlaps;需要交集片段用intersect_all;需要 bp 级度量用jaccard/coverage/overlap_coefficient;需要批量 BED3 hit 输出用 CLIoverlaprs --backend bits|ailist; - 规划先行:用 scripts/execution_plan.py 生成非执行式计划并人工复核(
--operation overlap、--operation count、--operation consensus均有对应模板); - 隔离 split:以 patient/donor 为单位冻结划分,consensus 只由训练 replicate 构建;
- 限定资源:外部设置输入/输出/内存/时间上限,stdout 只写已批准的不存在路径;
- 复核语义:对空集、零分母、相邻区间、部分重叠等边界用固定版本的小型合成数据验证后再正式运行。
以上全部结论均可对照 references/overlap.md、references/python-api.md、references/cli.md 及 scripts/execution_plan.py、scripts/_common.py、tests/gtars/test_scripts.py 在仓库内逐一复现与验证。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考