news 2026/9/10 19:31:57

Gtars Python API 0.9.2 完全指南:基因组区间模型、集合代数、Tokenization 与 refget 实操解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Gtars Python API 0.9.2 完全指南:基因组区间模型、集合代数、Tokenization 与 refget 实操解析

Gtars Python API 0.9.2 完全指南:基因组区间模型、集合代数、Tokenization 与 refget 实操解析

【免费下载链接】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

Gtars 是一套面向基因组区间(genomic interval)与参考序列处理的原生 Rust 实现,其 Python 绑定gtars==0.9.2通过 PyO3 扩展提供了RegionRegionSetTokenizerRefgetStore等核心对象。本文以仓库内 python-api.md 为骨架,结合 SKILL.md、overlap.md、tokenizers.md、refget.md 以及 bed_validator.py 等源码与测试,系统梳理 0.9.2 的精确导入面、已验证签名、构造规则、集合代数语义、consensus 实现、tokenizer 边界与错误处理约定,帮助你避免踩中旧版文档与真实运行时之间的 API 漂移陷阱。

版本基线与环境前提

本文所有结论均针对gtars==0.9.2(研究核验日期 2026-07-23)。该 PyPI 包要求Python 3.10+,且轮子内含PyO3 原生扩展——安装即意味着执行原生代码,因此仓库 SKILL.md 强调先核验官方发布者的不可变版本、平台标签、许可证与 SHA-256,再在隔离环境中安装。

推荐的隔离安装与版本断言流程如下:

uv venv --python 3.11 .venv-gtars uv pip install --dry-run --python .venv-gtars/bin/python "gtars==0.9.2" uv pip install --python .venv-gtars/bin/python "gtars==0.9.2" .venv-gtars/bin/python -c \ "import gtars; assert gtars.__version__ == '0.9.2'; print(gtars.__version__)"

版本事实速览(来自 SKILL.md 的 Verified snapshot):

  • Python 绑定:gtars==0.9.2Requires-Python >=3.10
  • Rust meta-crate:gtars=0.9.0(默认 feature 集为空);
  • CLI 二进制:gtars-cli=0.9.0,安装后命令名为gtars
  • 直接引用的 refget 组件:gtars-refget=0.9.1

上游刻意让 workspace crates、Python 绑定与 CLI 独立版本化,不要假设数字相同就是同一产物

Import surface:功能挂在子模块而非顶层

gtars0.9.2 的公开功能按子模块组织,官方文档和 0.9.2 stubs 推荐如下导入方式:

import gtars from gtars.models import Region, RegionSet from gtars.genomic_distributions import consensus from gtars.tokenizers import Tokenizer, tokenize_fragment_file from gtars.refget import RefgetStore, digest_fasta, digest_sequence

关键事实:

  • gtars.__version__0.9.2
  • RegionRegionSetTokenizerRefgetStore不是顶层导出类,必须从子模块导入;
  • Python 0.9.2不导出uniwigigdscoringfragsplitbbcache等 Python 子模块。信号轨道(signal track)生成等能力请走 CLI 或 Rust API,而不是在 Python 里寻找gtars.uniwig

已验证的方法签名清单

0.9.2 轮子在运行时报告的签名如下(python-api.md 的 Verified signatures 段):

Region(chr, start, end, rest) RegionSet(path) RegionSet.from_regions(regions, strands=None) RegionSet.from_vectors(chrs, starts, ends, strands=None) RegionSet.count_overlaps(self, other) RegionSet.coverage(self, other) Tokenizer(path) Tokenizer.from_bed(path) Tokenizer.from_pretrained(path) tokenize_fragment_file(file, tokenizer) consensus(region_sets) RefgetStore.open_local(path) RefgetStore.open_remote(cache_path, remote_url) RefgetStore.get_substring(self, seq_digest, start, end)

一个值得注意的细节:随轮子分发的.pyistub 文件遗漏了部分运行时方法(如from_vectorsdisjoinstrands以及若干 refget 加载方法)。核验此类遗漏时,应以标签版本(tagged)的 PyO3 源码与实际安装的运行时为准,而不是只信 stub。

Region:最小区间单元

Region是表示单个 BED 区间的核心对象:

from gtars.models import Region region = Region( chr="chr1", start=100, end=200, rest="peak_001\t500\t+", ) assert len(region) == 100 assert (region.chr, region.start, region.end) == ("chr1", 100, 200)

语义要点:

  • startend是 Rust 的u32,构造前应自行验证0 <= start < end <= contig_length
  • 构造函数本身不证明assembly 或 contig 兼容性,它只承载数据,不负责数据契约;
  • 相等性仅比较 chr/start/end,尾部rest内容不参与相等判断——这意味着两条坐标相同但注释不同的区间会被视为相等,做去重或集合运算时要留意。

RegionSet 的构造方式

从本地文件构造

from pathlib import Path from gtars.models import RegionSet path = Path("reviewed-input.bed.gz") if not path.is_file() or path.is_symlink(): raise ValueError("expected a reviewed local regular file") regions = RegionSet(str(path))

这里is_file()检查不只是错误提示的改进,而是一道安全边界:Python 构建启用了gtars-core的 HTTP feature,当传入字符串不是已存在的本地文件时,core 代码会尝试把它当作 URL 打开。因此构造前必须确认路径是本地常规文件,避免意外触发网络访问。

文件解析规则(来自 python-api.md):

  • 接受制表符分隔的 BED 类输入与.gz压缩文件;
  • 跳过browsertrack#行;
  • 若首行第二字段非数字,视为列头(column header);
  • 至少需要三列;
  • 第 4 列及之后的所有列合并为一个以制表符连接的Region.rest字符串;
  • 拒绝空区间集合
  • 加载时在内存中按「染色体字典序 + start 数值序」排序。

注意:原文件不会被改写,但输入行序不会保留在对象中。因此,如果你需要把查询结果与原始行号对齐,必须自行携带稳定标识符,而不能依赖构造后的索引位置。

从内存区间构造

from gtars.models import Region, RegionSet regions = RegionSet.from_regions( [ Region("chr1", 100, 200, None), Region("chr2", 300, 450, None), ], strands=["+", "-"], ) same = RegionSet.from_vectors( ["chr1", "chr2"], [100, 300], [200, 450], strands=["+", "-"], )

约束:所有坐标向量以及可选的 strand 向量长度必须相等;省略 strands 时,独立的 strand 向量会被初始化为"*"。注意,文件构造的RegionSet目前也会把独立 strand 向量初始化为"*"(即使 BED6 里有真实链向),所以当链向在科学上重要时,需要在外部单独保留与验证。

属性与可变性

n = len(regions) first = regions[0] # 支持负索引 identifier = regions.identifier file_digest = regions.file_digest header = regions.header strands = regions.strands regions.sort() # in-place;返回 None regions.to_bed("out.bed") regions.to_bed_gz("out.bed.gz") regions.to_bigbed("out.bb", "assembly.chrom.sizes")
  • identifier是对排序后的前三维内容计算的 MD5 类标识;file_digest则包含被保留的尾部列。两者都不能替代独立记录的 SHA-256 溯源哈希;
  • 由 regions/vectors 构造的集合,其path属性会抛出ValueError
  • 所有写出方法都会覆盖/创建指定输出文件,先确认输出策略再调用;
  • to_bigbed需要与每个 contig 及区间边界匹配的染色体长度文件。

区间统计与结构操作

widths = regions.widths() # list[int] same_widths = regions.region_widths() # 别名 mean_width = regions.mean_region_width() # 运行时返回 float length = regions.get_nucleotide_length() max_ends = regions.get_max_end_per_chr() stats = regions.chromosome_statistics() reduced = regions.reduce() disjoint = regions.disjoin() trimmed = regions.trim({"chr1": 248956422}) gaps = regions.gaps({"chr1": 248956422}) clusters = regions.cluster(max_gap=100)

几个必须牢记的语义细节:

  • reduce()合并重叠且相邻的区间——相邻(adjacent)也合并,这与普通 half-open 重叠([0,10)[10,20)不重叠)是两个不同的判定标准;
  • trim()会丢弃未知 contig 并夹紧越界端点;
  • 这些变换不做 liftover,且可能丢掉独立的 strand 向量;
  • promoters(upstream, downstream)目前是相对于每个区间 start 计算的,不是链向感知的 TSS 替代方案,需要链向语义时请独立建立 TSS 工作流;
  • neighbor_distances()nearest_neighbors()因为会跳过染色体上的单例区间,返回数量可能少于输入区间数,结果不是按行对齐的
  • distribution(n_bins=250, chrom_sizes=None)在缺少染色体长度时使用观测到的最大 end,导致不同文件之间的结果不可比;务必传入精确的 assembly 字典。传入 sizes 时未知/越界区间会被跳过,因此求和计数可能低于输入计数。

两两与全对(all-vs-all)操作

a = RegionSet("a.bed") b = RegionSet("b.bed") concatenated = a.concat(b) # 不合并 union = a.union(b) # 最小合并集 difference = a.setdiff(b) # 从 a 中减去 b 的碱基 pairwise = a.pintersect(b) # 按索引配对,而非基因组全对 all_pieces = a.intersect_all(b) # 每个基因组重叠片段 jaccard = a.jaccard(b) coverage = a.coverage(b) coefficient = a.overlap_coefficient(b) closest = a.closest(b)

指标口径(详见 overlap.md):

  • Jaccard =intersection_bp / union_bp
  • coverage=a 中被覆盖的碱基对 / a 合并后的碱基对,取值在[0,1]。它是碱基对集合度量,不是信号覆盖度,也不会产出 WIG/bigWig;
  • overlap coefficient =intersection_bp / min(query_bp, universe_bp)
  • concat不合并,union会合并;
  • setdiff可能把查询区间拆开;
  • pintersect依赖构造器排序后的索引位置配对,不是基因组全对相交

重叠查询方法是有方向性的:

counts = a.count_overlaps(b) # 对 a 中每个区间返回一个整数 flags = a.any_overlaps(b) # 对 a 中每个区间返回一个布尔 indices = a.find_overlaps(b) # 对 a 中每个区间返回 b 中的索引 subset = a.subset_by_overlaps(b) # 只保留至少命中一次的 a 区间
  • counts[i]是与查询区间i重叠的 universe 区间数量;
  • hit_indices[i]是内存中 universe 的 0-based 索引;
  • 文件构造的两侧集合都会被构造器排序,因此不要把这些数组直接对回原始未排序行号。

Consensus:共识区间语义

consensusgtars.genomic_distributions模块的绑定:

from gtars.genomic_distributions import consensus result = consensus([a, b]) # [{"chr": "chr1", "start": 100, "end": 500, "count": 2}, ...]

算法实现(overlap.md 与 python-api.md 一致):

  1. 拼接所有集合;
  2. reduce 成非重叠的合并 union 区间(包含相邻合并);
  3. 对每个 union 区间,统计有多少个输入集合至少重叠一次;
  4. 返回 BED4 形式的chr, start, end, count,按染色体/start 排序。

关键理解:consensus不会在每个支持度变化的边界处切分区间。例如部分重叠的[0,10)[5,15)会得到 union[0,15)且 count=2,尽管两侧边缘实际只有一个集合支持。这是"合并 union 组件的集合级支持数",不是 per-base 支持度。在解释count时必须使用这个精确含义。

Tokenizer 与片段边界

Tokenizer.tokenize()接受RegionSet或原生 extractor 接受的 region 对象:

from gtars.tokenizers import Tokenizer tokenizer = Tokenizer.from_bed("local-universe.bed") tokens = tokenizer.tokenize(a) ids = tokenizer(a)["input_ids"]

兼容性陷阱:虽然旧版文档有字符串列表示例,但已验证的 0.9.2 轮子拒绝["chr1:100-200"]这类字符串列表,因为原生 extractor 期望 region 对象。请传入RegionSetRegion对象。

Tokenizer(path)构造函数只自动识别.toml.bed.bed.gz三种文件;本地构造器读取本地文件并构建内存重叠索引。重叠索引会返回与每个查询区间重叠的所有universe 区间,因此一次查询可能产出 0、1 或多个 region token;若整体无重叠则返回 unknown token,未知 contig 同样落入 unknown 行为。

关于特殊 token、universe 顺序、远程下载与 fragment 文件行为的完整细节,见 tokenizers.md。几个核心事实:

  • Tokenizer.from_config期望TOML(非 YAML),配置形如universe = "universe.bed.gz",可选tokenizer_type = "bits""ailist"(默认bits);
  • 默认特殊 token 角色为unk, pad, mask, cls, bos, eos, sep
  • 对 N 行唯一 universe,测试实现得到N + 7个词表条目;不要硬编码来自其他 universe 的 ID;
  • Tokenizer.from_pretrained(name)在参数不是已存在本地目录时会访问 Hugging Face 并写入缓存,且签名不暴露 revision/cache 参数——默认不要直接调用,应先批准宿主、锁定不可变 revision、校验 SHA-256 后传入本地快照目录。

片段(fragment)tokenization 的当前绑定是:

from gtars.tokenizers import Tokenizer, tokenize_fragment_file tokenizer = Tokenizer.from_bed("training-universe.bed") by_barcode = tokenize_fragment_file("fragments.tsv.gz", tokenizer) # dict[str, list[int]]

tagged 实现要求每行至少 5 个空白分隔字段chrom start end barcode count,只使用前四维(第五个 count 字段被忽略),每个 barcode 列表会保留重复 ID——这与按 count 展开权重不同,使用前要确认这是否是你想要的加权方式。该函数会把所有 barcode 与 token 列表累积在内存中,处理单细胞数据前务必设置压缩/展开字节、行数、去重 barcode 数、每行 token 数等上限。

错误处理约定

0.9.2 包不导出旧版 skill 中虚构的gtars.FileNotFoundErrorInvalidFormatErrorParseError异常类。正确的做法是先验证、再只捕获与操作相关的窄内置/原生错误:

try: regions = RegionSet("reviewed-local.bed") except (OSError, RuntimeError, ValueError) as exc: raise RuntimeError("Gtars could not load the validated BED") from exc

不要用宽泛的except吞掉损坏行继续跑——数据契约问题应当失败并暴露。

0.9.2 中不存在的 API 清单

迁移旧代码时务必对照以下清单(python-api.md 的 "APIs that are not present"):

  • gtars.RegionSet(顶层)或RegionSet.from_bed
  • 旧名下的total_coveragefilter_by_sizefilter_by_chromosomeintersectsubtractsymmetric_difference
  • to_jsonfrom_json、NumPy 数组 getter、from_arrays
  • stream_bedmmap=Trueparallel=Trueparallel_apply
  • 全局set_optionoption_contextset_log_level
  • Python 的uniwigcoverage 对象。

SKILL.md 的 Migration traps 段还补充:gtars.RegionSetRegionSet.from_bedTreeTokenizergtars.igd.build_indexgtars.uniwig.coverage_from_bedgtars.RefgetStore(应为gtars.refget.RefgetStore)等旧示例对 0.9.2 均已失效;CLI 的uniwig generateigd buildscoring scorefragsplit cluster-split对 0.9.0 也已过时。

仓库配套:本地验证工具与测试佐证

数据契约先行

在使用任何 Python API 之前,仓库 SKILL.md 强制要求先明确基因组数据契约:

  1. 坐标:BED 为 0-based、half-open[start, end),要求0 <= start < end <= contig_length;Gtars 坐标为u32,拒绝超过4,294,967,295的值(scripts/_common.py 中MAX_COORDINATE = 2**32 - 1正是这一约束的实现);
  2. Assembly:记录 accession/版本与染色体长度文件或序列集合元数据的 SHA-256,禁止从文件名或chr前缀推断;
  3. Contig:名称精确比较,1chr1、alt 位点、decoy、线粒体别名都不可互换;
  4. 排序:保留原文件,按需对副本排序;PythonRegionSet(path)目前按字典序加载并排序;
  5. 链向:BED6 使用+/-/.,但文件构造的 PythonRegionSet独立 strand 向量初始化为*,且若干集合操作会丢链向;
  6. 重复/相邻:显式选择策略,reduce()与 consensus 合并重叠且相邻区间。

本地校验器 bed_validator.py

在构造RegionSet之前,可以先用仓库自带的依赖无关校验器做本地预检(bed_validator.py):

python3 -B scripts/bed_validator.py \ --input data.bed.gz \ --assembly GRCh38.p14 \ --chrom-sizes GRCh38.p14.chrom.sizes \ --require-sorted

该脚本只使用 Python 3.10+ 标准库、无网络、不写输出文件,并拒绝 URL、路径穿越、符号链接与特殊文件(scripts/_common.py)。它的默认上限为 512 MiB 字节与 1,000,000 条记录,--require-sorted会按 chrom.sizes 顺序加数值 start/end 检查排序,输出 JSON 报告且默认--path-mode redacted隐去路径、只报告计数与校验和(防止基因组坐标与样本路径泄漏)。

测试用例如何佐证 API 语义

仓库 tests/gtars/test_scripts.py 提供了不依赖 gtars 导入的合成测试,可作为理解 API 边界的最佳注脚:

  • test_valid_local_bed:合法 BED 校验通过、记录数为 2、输出不包含临时根目录路径(路径脱敏验证);
  • test_bad_bounds_and_url_are_rejectedchr1\t90\t101(end 超出 contig 长度)返回码 2 且报end_beyond_contig;URL 输入被拒绝且不泄漏文件名——这与RegionSet(path)的 HTTP 语义形成对照;
  • test_tokenizer_manifest_matches_exact_universe:2 行 universe 对应vocab_size = 9(即 N+7),且校验"universe 字节与顺序完全匹配",证实 token ID 对 universe 行内容与顺序字节级敏感;
  • test_refget_digest_validation_uses_known_acgt_digest:对ACGT计算sha512t24u得到已知值,验证序列摘要语义;
  • test_wheel_filename_and_checksum_are_screened_without_loading:校验轮子文件名与 SHA-256 清单时不加载原生代码、不解压归档,呼应"原生扩展即代码执行"的信任门。

refget 摘要与存储补充

虽然 python-api.md 只列出RefgetStore.open_localopen_remoteget_substring三个签名,完整构造器集合见 refget.md:in_memory()on_disk(cache_path)open_local(path)open_remote(cache_path, remote_url)store_exists(path)。摘要函数包括:

from gtars.refget import ( digest_fasta, digest_sequence, md5_digest, sha512t24u_digest, ) digest = sha512t24u_digest("ACGT") assert digest == "aKF498dAxcJAqme6QYQ7EZ07-fiw8Kw2" assert md5_digest("ACGT") == "f1f8f4bf413b16ad135722aa4591043e"

Gtars 返回不带前缀的 32 字符sha512t24u值,GA4GH refget 官方 ID 会加上SQ.前缀(SQ.aKF498dAxcJAqme6QYQ7EZ07-fiw8Kw2)。open_remote默认启用持久化、可做按需远程字节区间读取,但没有任何 revision/校验和/离线参数——调用前必须经过网络与缓存审批门。

一个端到端的本地工作流示例

综合以上 API 与仓库配套工具,一个合规的本地工作流可以组织为:

# 1. 数据契约预检(无网络、无输出文件) python3 -B scripts/bed_validator.py \ --input peaks.bed.gz --assembly GRCh38.p14 \ --chrom-sizes GRCh38.p14.chrom.sizes --require-sorted # 2. 干跑式执行计划(固定 argv 模板,绝不真正启动命令) python3 -B scripts/execution_plan.py \ --operation overlap --query query.bed --universe universe.bed \ --assembly GRCh38.p14 --chrom-sizes GRCh38.p14.chrom.sizes
from gtars.models import Region, RegionSet from gtars.genomic_distributions import consensus from gtars.tokenizers import Tokenizer query = RegionSet.from_regions( [Region(chr="chr1", start=100, end=200, rest=None)], strands=["+"], ) universe = RegionSet.from_vectors( ["chr1", "chr1"], [150, 500], [350, 600] ) counts = query.count_overlaps(universe) # 每个查询区间一个整数 flags = query.any_overlaps(universe) # 每个查询区间一个布尔 pieces = query.intersect_all(universe) # 每个重叠片段 [max(starts), min(ends)) fraction = query.coverage(universe) # 查询区间被覆盖的碱基比例 rows = consensus([query, universe]) # BED4: chr, start, end, count tokenizer = Tokenizer.from_bed("reviewed-universe.bed") encoding = tokenizer(query) # 重叠 tokenization + 编码 ids = encoding["input_ids"]

总结

Gtars Python 0.9.2 提供了完整、高性能的基因组区间建模能力,但其 API 面与旧版文档存在多处漂移:功能从子模块导入、文件构造即排序、reduce/consensus 合并相邻区间、tokenizer 只接受 region 对象、异常类不做包装、若干旧 API 已整体移除。在使用前,务必以 python-api.md 的签名清单与本文整理的行为细节为准,并结合 SKILL.md 的数据契约、bed_validator.py 的本地预检与 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 19:31:01

从计算机二级到系统结构:00后眼中的计算机红利与实践复盘

第一批感受到计算机红利的00后的年终总结2024年过完了&#xff0c;作为一个货真价实的00后&#xff0c;我终于能静下心来回看这一整年。印象最深的事情不是看了多少部电影、去了多少座城市&#xff0c;而是我发现自己成了一个“有问题先想到问计算机、有需求先想到用技术解决”…

作者头像 李华
网站建设 2026/9/10 19:29:09

AI代理上下文生命周期管理:从提示词到可运维软件资产

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 19:27:23

CANN/ge离线图编译执行Python示例指南

Sample Usage Guide 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、Tensor…

作者头像 李华
网站建设 2026/9/10 19:27:17

NX后处理获取当前刀具信息:UF_MOM_ask_mom与ask_string详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 19:26:17

LIMS系统如何推动实验室数字化转型与效率提升

1. 实验室数字化转型的必然选择&#xff08;开场白直接切入主题&#xff09;上周刚帮本地一家三甲医院检验科部署完优检云系统&#xff0c;他们的实验室主任老张拉着我感慨&#xff1a;"这套系统上线后&#xff0c;我们科室的样本流转效率提升了40%&#xff0c;报告差错率…

作者头像 李华