mcpField
T
tiledbvcf

tiledbvcf

github.com/k-dense-ai数据与数据库55.1k1.9k 次安装2 天前更新
代码仓库

关于 tiledbvcf

面向基因组学团队的 TileDB-VCF 技能,介绍如何存储和增量导入队列 VCF 数据,并按样本或基因组区间查询及导出子集。内容也强调坐标、基因型和统计数据的解释边界;它不执行变异联合调用或关联分析。

主要功能

  1. 01创建队列变异数据集
  2. 02增量导入带索引的 VCF/BCF
  3. 03按样本和区间查询记录
  4. 04导出 VCF、BCF 或表格
  5. 05计算变异统计和样本 QC

适用场景

  1. 01逐步汇集多个样本的变异记录
  2. 02提取特定样本与基因组区间
  3. 03导出数据供下游基因组分析
  4. 04检查队列统计及样本 QC

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/k-dense-ai/scientific-agent-skills --skill tiledbvcf

安装后在 Claude Code 中输入/tiledbvcf确认已加载。

附带文件references/verification.md

详细介绍

TileDB-VCF

何时使用

用于队列变异存储、增量样本摄入、区间查询,以及为下游基因组学导出子集。TileDB-VCF 存储记录;它不执行联合变异检出、关联检验、标准化或群体结构校正。仅凭数据集大小并不能决定云执行是否合适:应对预期的样本、区域和属性工作负载进行基准测试。

本技能针对已发布的 TileDB-VCF 0.40.3。原生 Python/CLI 检查在 macOS ARM64 上使用了两个合成的单样本 VCF。云客户端 0.14.4 的契约已对照其发布的 wheel 和模拟分发进行了检查;托管的查询和作业未执行。参见安装与验证说明。

安装并验证原生技术栈

在本次审查时,tiledbvcf Python 发行版尚未发布到 PyPI。官方 tiledb Conda 频道为 macOS ARM64、macOS x86-64 和 Linux x86-64 提供 tiledbvcf-py 0.40.3,支持 Python 3.9-3.12 构建。PyPI 上的 tiledb 是 TileDB-Py,不会安装 TileDB-VCF。原生 Apple Silicon 不再需要强制设置 CONDA_SUBDIR=osx-64。

对于已测试的 macOS ARM64 环境,以下版本固定可避免在原本成功的当前 Conda 求解中出现版本化库导入失败:

conda create -n tiledb-vcf -c tiledb -c conda-forge \
  python=3.12 tiledbvcf-py=0.40.3 \
  azure-core-cpp=1.16.2 azure-storage-blobs-cpp=12.16.0 \
  azure-storage-files-datalake-cpp=12.14.0 capnproto=1.4.0 c-blosc2=2.23.1
conda activate tiledb-vcf
python -c 'import tiledbvcf; print(tiledbvcf.version)'
tiledbvcf version

已执行等效的 Micromamba 求解/安装。这些额外的 ABI 固定是经过验证的 macOS ARM64 变通方案,并非对所有平台的断言。请为生产环境保留已求解的环境。其他平台的安装和官方 Docker 镜像是在上游记录的可选方案,此处未测试。

准备并创建队列

  1. 记录参考组装、contig 命名/长度、调用器、标准化规则、样本身份和文件校验和。不要混用组装,也不要假设 1 和 chr1 等价。确认各输入的头部兼容。
  2. 每个输入必须包含一个样本,按坐标排序,并具有索引。使用 BGZF 压缩的 VCF 或 BCF,并配有匹配的 .csi/.tbi。检查 bcftools query -l sample1.vcf.gz;文件名不是样本标识符。
  3. 显式创建数据集,然后摄入。单独打开 mode="w" 不会创建其 schema。在创建时物化频繁读取的字段。
  4. 在扩展之前,验证一个小的已知区间和一次往返导出。

对于现有的已排序纯文本 VCF(每个输入运行一次;输出名称必须是新的):

bcftools view -Oz -o sample1.vcf.gz sample1.vcf
bcftools index -c sample1.vcf.gz
bcftools view -Oz -o sample2.vcf.gz sample2.vcf
bcftools index -c sample2.vcf.gz

以下本地示例使用样本 ID S1 和 S2、contig chr1 以及坐标 1-100 进行了演练;在实际数据中替换为已验证的 ID 和区间。

import tiledbvcf

uri = "cohort"
config = {"sm.compute_concurrency_level": "2", "sm.io_concurrency_level": "2"}
with tiledbvcf.Dataset(uri, mode="w", tiledb_config=config) as ds:
    ds.create_dataset(extra_attrs=["fmt_GT", "fmt_DP"])
    ds.ingest_samples(
        ["sample1.vcf.gz"], threads=2, total_memory_budget_mb=512
    )

# Incremental ingestion uses the existing dataset; do not call create_dataset again.
with tiledbvcf.Dataset(uri, mode="w", tiledb_config=config) as ds:
    ds.ingest_samples(
        ["sample2.vcf.gz"], threads=2, total_memory_budget_mb=512
    )

schema-v4 数据数组具有 contig、起始坐标和样本维度;头部和可选统计信息是数据集组中的独立数组。未显式物化的字段保留在 INFO/FORMAT 负载中。诸如 pos_start 之类的查询名称不必与原始存储列名匹配。

上游支持并行线程/进程摄入。分配不同的样本工作与坐标生命周期/维护操作;不要盲目重新摄入样本。resume=True 支持中断的摄入,而非任意的重复校正。

完整查询并正确解释坐标

接口坐标约定
Python regions=["chr1:10-14"]1-based,闭区间
返回的 pos_start、pos_end1-based,包含记录端点
BED 输入与 query_bed_start、query_bed_end0-based,半开区间
0.40.3 中 read_variant_stats() / read_allele_count() 的 pos 列0-based;连接到 VCF POS 前需加一

查询返回的是重叠的记录,而不仅仅是起始位置落在区间内的记录。跨越位置 10-14 的缺失会出现在 chr1:14-14 中,且 pos_start=10。对于 BED [13,14),等价的字符串为 chr1:14-14。Python 区域解析器要求显式的 contig:start-end;本版本中裸 "chr1" 会被拒绝。整条 contig 查询请使用已知的 contig 长度。

cfg = tiledbvcf.ReadConfig(memory_budget_mb=128, tiledb_config=config)
attrs = ["sample_name", "contig", "pos_start", "pos_end", "alleles", "fmt_GT"]
with tiledbvcf.Dataset(uri, cfg=cfg) as ds:
    assert {"S1", "S2"}.issubset(ds.samples())
    assert set(attrs).issubset(ds.attributes())
    for batch in ds.read_iter(
        attrs=attrs, regions=["chr1:1-100"], samples=["S1", "S2"]
    ):
        print(batch)  # Replace with a bounded consumer or partitioned output.
  • read() 返回 pandas DataFrame;read_arrow() 返回 PyArrow Table。两者都可能只返回受内存限制的第一批。请用 continue_read() / continue_read_arrow() 继续,直到 read_completed(),或对普通 DataFrame 查询使用 read_iter()。当结果无法放入内存时,避免拼接所有批次。
  • ReadConfig(memory_budget_mb=...) 控制读取;写入请使用 ingest_samples(total_memory_budget_mb=...)。读取预算不是进程 RSS 上限。limit 会截断总输出;它不是分页大小。
  • sample_partition=(0, 2) 选择两个分区中的第零个。同样,region_partition=(index, number_of_partitions) 对查询区域进行分区;这些元组不是坐标边界、瓦片范围或样本容量。
  • 0.40.3 在后续调用省略 bed_file 时会保留 BED 选择状态。当更改 BED/区域输入时,请打开新的 Dataset 进行独立查询。
  • fmt_GT 包含等位基因索引:0 表示 REF,正值索引 ALT,-1 表示缺失。请保留多等位基因身份与倍性;不要将每个正整数都视作双等位基因剂量,也不要把缺失调用视作参考。仅凭整数列表无法编码原始的定相 GT 字符串。

导出并验证

from pathlib import Path

Path("exported").mkdir(exist_ok=True)
with tiledbvcf.Dataset(uri, cfg=cfg) as ds:
    ds.export(
        samples=["S1"], regions=["chr1:1-100"],
        output_format="v", output_dir="exported",
    )

Python 导出格式:v VCF、z 压缩 VCF、u 未压缩 BCF、b 压缩 BCF。merge=False 写入按样本划分的文件;merge=True 需要合并的 output_path。合并导出不是联合调用。在进行需要索引的下游访问前,请对导出文件重新建立索引。比较样本 ID、contig、记录数、等位基因、INFO/FORMAT 值以及缺失/定相基因型;语义往返保留并不意味着压缩或头部字节级一致。

CLI 接受位置参数形式的样本路径或 --samples-file(每行一个 URI),而不是逗号分隔的 --samples 参数:

tiledbvcf create --uri cli_cohort
tiledbvcf store --uri cli_cohort --threads 2 --total-memory-budget-mb 512 \
  -- sample1.vcf.gz sample2.vcf.gz
tiledbvcf list --uri cli_cohort
tiledbvcf stat --uri cli_cohort
tiledbvcf export --uri cli_cohort --regions chr1:1-100 \
  --sample-names S1,S2 -Ot --tsv-fields 'SAMPLE,CHR,POS,REF,ALT,F:GT' \
  --output-path variants.tsv

-- 可保护位置路径免受 --tiledb-config 这类可变长度选项的影响。请检查预期产物与样本数,以及退出码:在审查的 CLI 中,无效的 store 命令返回退出码零,同时打印错误。TSV 字段中 FORMAT/GT 使用 F:GT,INFO/DP 使用 I:DP。

队列统计与 QC

with tiledbvcf.Dataset(uri, cfg=cfg) as ds:
    stats = ds.read_variant_stats(regions=["chr1:1-100"], drop_ref=True)
    stats["vcf_pos"] = stats["pos"] + 1
    print(stats[["contig", "vcf_pos", "alleles", "ac", "an", "af"]])

qc = tiledbvcf.sample_qc(uri, samples=["S1"], config=config)
print(qc)

统计数组在创建时默认启用;较早或已禁用的数组可能不支持这些操作。read_variant_stats 没有 samples 参数。较早的 read_allele_frequency(dataset_uri, region) 包装函数只接受单个 region,并委托给已弃用的单数参数;请优先使用上面的 Dataset 方法。sample_qc 的第一个参数是 dataset_uri,而非 uri。

ac、an 和 af 值汇总的是已摄入的队列,而非选定的祖源或查询样本子集。在测试版本中,read(samples=[...], set_af_filter=">0.6") 过滤器仍使用队列 AF。请基于正确选定的调用,并结合显式的缺失、倍性、可调用区域和 gVCF 参考块策略,计算子组频率。使用合适的已调用等位基因分母,而非一律使用 2 * number_of_samples;缺失的 VCF 记录并不能证明存在纯合参考调用。QC 指标和稀疏存储并不能确立 GWAS 就绪性,也不能确立科学有效性。

对象存储与 TileDB Cloud

直接存储使用 s3://bucket/path、azure://container/path 或 gcs://bucket/path,由已安装的 TileDB 后端及其提供商凭证支持。这不会自动分布计算。请使用提供商的凭证链或受限配置,并验证对数据集和源索引的访问权限。TileDB Cloud 令牌与存储桶凭证不同。下面的远程存储示例仅为说明性示例,经过源验证,并非经过身份验证的端到端测试。

在兼容环境中安装 tiledb-cloud==0.14.4。其 life-sciences extra 会添加 TileDB-SOMA,而不是 TileDB-VCF。在导入客户端之前,通过执行环境提供 TILEDB_REST_TOKEN;如有需要,TILEDB_REST_HOST 可选择自定义部署。不要将令牌嵌入代码中,也不要打印配置。

# Illustrative: requires an accessible registered cohort and a billing namespace.
import tiledb.cloud
import tiledb.cloud.vcf

cloud_cfg = tiledb.cloud.Config()
with tiledbvcf.Dataset("tiledb://my-namespace/cohort", tiledb_config=cloud_cfg) as ds:
    sample_names = ds.samples()

result = tiledb.cloud.vcf.read(
    dataset_uri="tiledb://my-namespace/cohort",
    config=cloud_cfg, attrs=["sample_name", "pos_start", "fmt_GT"],
    regions=["chr1:1-100"], samples=sample_names[:2],
    num_region_partitions=1, namespace="my-namespace", max_workers=2,
)
frame = result.to_pandas()  # read returns an Arrow table, not a DataFrame.

分布式读取会组装 Arrow 结果,并可能占用大量 worker/client 内存。请限制请求的 region/sample 和 worker 数量;分区并不能使最终拼接结果免于内存占用。这是 SDK 任务执行,而非分页式 VCF REST-list API。

# Illustrative, mutating cloud job: use only for an authorized ingestion task.
submission = tiledb.cloud.vcf.ingest(
    dataset_uri="s3://my-bucket/cohort",
    sample_list_uri="s3://my-bucket/inputs/sample-uris.txt",
    namespace="my-namespace", acn="registered-storage-role",
    register_name="cohort", max_samples=2,
    ingest_resources={"cpu": "2", "memory": "4Gi"},
)
print(submission["graph_id"])

仅使用 search_uri、sample_list_uri 或 metadata_uri 三者之一;文件搜索模式作用于 search_uri。注册需要访问凭证名称(acn)。vcf.ingest 以异步方式提交,并返回 {"status": "started", "graph_id": ...};跟踪该 graph 直至最终成功,并在声称完成前验证已摄入的样本。没有已发布的 ingest_vcf_dataset(source=..., output=...) API。定价、可用性、安全控制和部署义务需以当前账户/服务条款为准。

官方参考

评论

支持 Markdown