mcpField
G
genvarloader

genvarloader

github.com/mcvickerlabデータ・データベース31135 回インストール4 週間前に更新
リポジトリ

genvarloader について

GenVarLoaderは、参照配列とバリアントから個人別ハプロタイプを再構築し、機能ゲノムトラックを再配置するPythonライブラリです。可変長出力に対応し、複数のバリアント保存形式を扱えます。

主な機能

  1. 01個人別ハプロタイプの再構築
  2. 02BigWig・テーブルトラックの再配置
  3. 03BCF、PGEN、SVAR、SVAR2への対応
  4. 04既存データセットへのトラック追加
  5. 05可変長ゲノム出力の読み取り

活用シーン

  1. 01指定領域とサンプルのゲノムデータセット作成
  2. 02挿入・欠失を反映したハプロタイプの読み取り
  3. 03複数データセットでのバリアントソースの再利用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mcvickerlab/genvarloader --skill genvarloader

インストール後、Claude Code で/genvarloaderを入力して読み込まれたか確認します。

詳細

GenVarLoader 公開 API

GenVarLoader(gvl)は、参照配列 + バリアント + BigWig/Table トラックから、個人ごとのハプロタイプを再構築し、機能ゲノミクストラックをオンザフライで再アラインメントします。個人ごとのゲノムをディスクに書き出すことはありません。可変長の出力が常態です(インデルにより長さは領域およびサンプルに依存します)。

このスキルは、ポインタを多用した概要です。シンボル名は、権威ある docstring やソースの場所へリンクしています。

エンドツーエンドの流れ

import genvarloader as gvl

# 1. Preprocess variants outside Python (see "Variant preprocessing")
# 2. Write the dataset
gvl.write(
    path="ds.gvl",
    bed="rois.bed",
    variants="normed.bcf",  # or .pgen, or .svar directory
    tracks=[gvl.BigWigs.from_table("signal", "bw_table.tsv")],
    max_jitter=128,
)

# 3. Open and configure (chainable fluent API)
ds = (
    gvl.Dataset
    .open("ds.gvl", reference="ref.fa")
    .with_seqs("haplotypes")
    .with_tracks(["signal"])
    .with_insertion_fill(gvl.Repeat5pNormalized())
    .with_len(2048)  # or "ragged" / "variable"
    .with_settings(jitter=32, deterministic=False)
)

# 4. Eager indexing: dataset[region_idx, sample_idx]
batch = ds[0:8, :]  # shape depends on with_* state — see "Output shapes"

バリアント前処理の要件

gvl.write に渡すバリアントは、必ず左寄せ、バイアレリック、原子的(MNP や複合 MNP-インデルを含まない)であり、シンボリック(<DEL>、<INS>、…)およびブレイクエンドの ALT アレルを含まないものでなければなりません。gvl はすべての ALT をリテラルのハプロタイプ配列へ展開するため、シンボリックやブレイクエンドのレコードを再構築できません。VCF、PGEN、SVAR のいずれの入力でも、これらが存在する場合、gvl.write は ValueError を発生させます(マルチアレリック、シンボリック、ブレイクエンドのバリアントのクラス別件数付き)。VCF はインデックス化されている必要があります。

# VCF/BCF
bcftools norm -f ref.fa \
    -a --atom-overlaps . \
    -m -any --multi-overlaps . \
    -O b -o normed.bcf in.vcf.gz
bcftools index normed.bcf

# PGEN
plink2 --make-bpgen --pfile in --out tmp
plink2 --make-pgen --normalize --ref-from-fa --fa ref.fa --bpfile tmp --out normed

正規のレシピと BED/BigWig テーブルのレイアウトについては docs/source/write.md を参照してください。

SVAR と BCF/PGEN のどちらを使うか

.svar は(genoray による)スパースな列指向のバリアントアーカイブです。BCF や PGEN とまったく同じように gvl.write(variants="x.svar") に渡してください。結果として得られるデータセットは、バリアントごとの配列を重複させる代わりにバックリファレンスを保存します。

SVAR を使うのは次の場合です:

  • 読み取り時のアレル頻度フィルタリングが必要な場合(Dataset.open(min_af=..., max_af=...) は .svar のみでサポートされます。.svar2 をバックエンドとするデータセットでは NotImplementedError が発生します)。
  • 多くのデータセットが同じバリアントソースを共有する場合 — SVAR は variant_idxs.npy/dosages.npy/variants.arrow を各 .gvl ディレクトリへ重複させることを避けられます。
  • 集団規模で作業しており、コンパクトなオンディスクのバリアントストレージを求める場合。

BCF/PGEN を直接使うのは、単発のデータセットがあり、AF フィルタリングが不要な場合です。

正規化された VCF/PGEN から genoray で SVAR を作成します:

from genoray import VCF, SparseVar

SparseVar.from_vcf("normed.svar", VCF("normed.bcf"), max_mem="4g")  # writes a .svar/ directory

SVAR は Dataset.open 時に、metadata.json → 呼び出し側の svar= 引数 → 記録された相対パス → 記録された絶対パス → 兄弟の *.svar の順で解決されます。docs/source/format.md(「open 時の SVAR 解決」)と _dataset/_svar_link.py を参照してください。レガシーなシンボリックリンクベースの SVAR レイアウト: gvl.migrate_svar_link(path) を一度実行してアップグレードしてください。

.svar2 — 読み取りバウンドのスパースバリアント形式

.svar2 は genoray のより新しいスパースな列指向のバリアントストアです。.svar、BCF、PGEN とまったく同じように gvl.write に渡してください — gvl.write(path, bed, variants="cohort.svar2") または variants=SparseVar2("cohort.svar2") のように。.svar と同様、データセットはバリアントごとの配列を重複させる代わりにバックリファレンス(metadata.json → svar2_link)を保存するため、.svar2 ストアは読み取り時にアクセス可能なままでなければなりません。

.svar(その読み取りパスは区間探索木 + クエリ対象ウィンドウに対する読み取りごとの密な union を構築します)とは異なり、.svar2 をバックエンドとするデータセットは読み取りバウンドのパスで再構築します: gvl.write は、バリアントを保持する各 (region, sample, ploid) の var-key ウィンドウを <dataset>/genotypes/svar2_ranges/ の下にキャッシュし(データセットの選択されたサンプルに合わせてサイズ設定され、.svar2 コホート全体ではありません)— スパースな region-CSR テーブルとして、空でないウィンドウあたり 28 バイト、コホート規模では小さなもの(All of Us chr22 グリッドで約 504 MB。下記の「よくある落とし穴」の箇条書きを参照)— そして読み取り時に gvl はそのキャッシュから直接ギャザーし、オール Rust のカーネルを呼び出します — 区間探索木の構築も、読み取りごとの密な union の再構築もありません。.svar2 ストアは通常、特に大規模コホートでは、.svar よりもディスク上で小さくなります。docs/source/faq.md を参照してください。

.svar2 は Dataset.open 時に .svar と同じ順序で解決されます: 呼び出し側の svar2= 引数 → 記録された相対パス → 記録された絶対パス → 兄弟の *.svar2。Dataset.open(path, svar2=<override>) は svar= を反映します。docs/source/format.md(「open 時の .svar2 解決」)を参照してください。 フェーズ 1 のスコープ — サポートされない組み合わせは NotImplementedError を発生させます。 .svar2 をバックエンドとするデータセットは、4 つの出力モードすべて(haplotypes、variants、variant-windows、ハプロタイプ再整合された tracks)を .svar/union-oracle バックエンドとバイト単位で同一にサポートし(純粋な欠失の ALT バイトを除く — 以下を参照)、with_seqs("variant-windows")(ref="window"、alt ∈ {"window", "allele"})、unphased_union("variants" と "variant-windows" の両方の出力に対して)、および var_fields で選択された store INFO/FORMAT フィールド(同じく "variants" と "variant-windows" の両方に対して。以下の Dataset.open の var_fields を参照)はすべて .svar2 用に完全に配線されています。プレーンなハプロタイプ出力は、スプライシング、var_filter="exonic"、および負鎖領域の自動逆相補化もサポートします。以下はまだ配線されておらず、黙って誤計算する代わりに明確なエラーを発生させます:

  • variants、variant-windows、またはハプロタイプ再整合されたトラックを用いたスプライシング。
  • 非ハプロタイプ出力またはハプロタイプ再整合されたトラックを用いた var_filter="exonic"。
  • min_af / max_af フィルタリング。
  • annotated ハプロタイプ(with_seqs("annotated"))。
  • VarWindowOpt(ref="allele")(ベアアレル REF モード。.svar2 の上流でもブロックされます — REF アレルは保存されません)。
  • ハプロタイプ再整合されたトラックを用いた逆相補化。
  • 固定長(整数の output_length)のハプロタイプ再整合 トラック出力(固定長でのプレーンなハプロタイプ出力は問題ありません — ガードされているのはトラックカーネルのみです)。
  • max_jitter>0 で書き込まれた、または jitter>0 で読み込まれたデータセットに対する variants / variant-windows 出力(読み込み境界のデコードはジッター後のウィンドウに右クリップしません。ハプロタイプとトラックは影響を受けず、ジッターを完全にサポートします)。
  • .svar2 バリアントソースに対する gvl.write(..., extend_to_length=False)(書き込み時。NotImplementedError を発生させます — .svar2 ソースはデフォルトの extend_to_length=True を使用する必要があります)。

(1 回のクエリで複数のコンティグにまたがるトラックに対する FlankSample の挿入フィルは、現在サポートされており、.svar バックエンドとバイト単位で同一です — issue #267。)

variants/variant-windows の ALT バイトは純粋な欠失において .svar と異なります(バグではなくフォーマットの慣習)。 純粋な欠失(例: VCF GTA>G)の場合、.svar データセットに対する with_seqs("variants") は VCF アンカーベースを ALT(b"G")として返しますが、.svar2 データセットはアトマイズされた空の ALT(b"")を返します — これが genoray の .svar2 フォーマットが純粋な欠失を表現する方法です。同じ慣習は with_seqs("variant-windows") にも引き継がれます: ref_window は .svar/.svar2 間でバイト単位で同一ですが、alt/alt_window は同じ理由で純粋な欠失レコードにおいて異なります。再構築されたハプロタイプは両バックエンド間でバイト単位で同一です(どちらもシーケンスを構築する際に ALT を同一に消費します)。生のアレル/ウィンドウのバイトのみが純粋な欠失レコードにおいて異なります。docs/source/faq.md を参照してください。

シンボリック/ブレークエンドバリアントは .svar と同様に拒否されますが、.svar2 では拒否が上流、つまり .svar2 変換時に発生します(store フォーマットがそれらを表現できないため) — .svar2 はすでにフィルタリングされたソースから構築する必要があります。gvl は、マテリアライズされた .svar に対して再フィルタリングできないのと同様に、マテリアライズされた .svar2 に対しても再フィルタリングできません。

gvl.write — 主な引数

gvl.write(
    path,
    bed,
    variants=None,
    tracks=None,
    annot_tracks=None,
    samples=None,
    max_jitter=None,
    overwrite=False,
    max_mem="4g",
    extend_to_length=True,
)

注目すべき点:

  • bed: chrom, chromStart, chromEnd(0 始まり)を持つパスまたは polars DataFrame。オプションの strand(+/-/.)は読み取り時の逆相補鎖変換を制御します。追加の列は Dataset.regions 上で保持されます。
  • tracks: gvl.BigWigs(またはそのリスト)、あるいは gvl.Table。それぞれが一意の .name を持つ必要があります。BigWigs にはサンプル→パスのマッピングが必要です(dict、または sample、path 列を持つテーブル。BigWigs.from_table を参照)。gvl.Table は Rust の COITrees オーバーラップエンジンに支えられた中核的なインターバルトラックソースです(0 始まりの半開区間座標)。gvl.write の tracks= または annot_tracks= ソースとして直接渡せます。
  • annot_tracks: dict[str, str | Path | pl.DataFrame | pl.LazyFrame] | None — サンプルに依存しないアノテーショントラックで、<path>/annot_intervals/<name>/ に書き込まれます。各値はインターバルテーブルまたは bigWig ファイルへのパス、あるいは BED 風の列(chrom、chromStart、chromEnd、score)を持つ polars DataFrame/LazyFrame のいずれかです。アノテーショントラックはサンプルに依存しないため、サンプルごとのバリアントソースなしで読み取れます。
  • max_jitter: 読み取り時の最大ジッター。各リージョンの両側で保存データをこの塩基数分だけパディングするため、任意の j <= max_jitter に対して Dataset.with_settings(jitter=j) が機能します。
  • extend_to_length=True は、すべてのハプロタイプがリージョン長以上になるまで BED の終端を越えて読み取り続けます(欠失によって出力が短くなる場合に重要)。短いハプロタイプで許容できるなら、より高速な書き込みのために False に設定します。.svar2 バリアントソースではサポートされていません — そこでは extend_to_length=False は NotImplementedError を発生させます。無効化できるのは BCF/PGEN/.svar ソースのみです。
  • samples: 含めるサンプル。None(デフォルト)は variants とすべての tracks を通じて利用可能なすべてのサンプルを取得します。いずれの場合もデータセットのサンプル順序はその選択の辞書順ソートであり、表現型テーブルが通常持つ数値順ではありません("1000" は "999" より前にソートされます)。外部テーブルは位置ではなく名前で Dataset.samples に合わせてください。
  • variants とすべての tracks を通じてサンプルを内部結合します。

並列処理: gvl.write は書き込みカテゴリごとに並列化されるようになりました。バリアントが最初に(逐次的に)処理されます。次に、サンプルごとの tracks と annot_tracks が並行して実行されます(joblib loky バックエンド)。max_mem の予算は、並行して実行されるカテゴリ間で分割されます。

max_mem と .svar2: .svar2 バリアントソースの場合、max_mem は、遺伝子型範囲キャッシュを生成する際に gvl.write が読み取る genoray チャンクストリームを制限します — 範囲はコンティグ全体を一度にではなく、予算に収まるサイズのサンプルごとのチャンクで生成されます。これは、コンティグごとのエントリアキュムレータ(最大のコンティグでエントリあたり約 60 バイトがピークになります。以下の「よくある落とし穴」を参照)も、永続的な genotypes/svar2_ranges/ キャッシュのディスク上のサイズ(リージョン内で観測されたバリアント数に比例し、regions x samples x ploidy ではありません)も制限しません。これらはディスク容量によって左右されます(format.md を参照)。

ソース: python/genvarloader/_dataset/_write.py。

アトミックな作成: gvl.write はプライベートな兄弟一時ディレクトリにビルドし、アトミックな os.replace で公開します。ベストエフォートの filelock は、並列ジョブが同じ宛先を共有する場合の冗長な再ビルドを回避しますが、正確性はリネームに依存します — ロックは勧告的なものにすぎません。データセットは自動再ビルドされません。ディスク上の成果物が欠落しているか破損している場合は、gvl.write を再実行してください。

対象外: genoray の .gvi インデックスファイルと pysam の .fai/.gzi インデックスファイルはこれらのライブラリによって作成され、gvl のアトミック/ロック付き作成ではカバーされません。これらのファイルのインデックス作成をトリガーする並行ジョブは、上流ライブラリの動作に依存します。

gvl.update — 既存のデータセットにトラックを追加する

gvl.update(
    dataset,          # str | Path | Dataset
    tracks=None,      # BigWigs | Table | Sequence[BigWigs | Table] | None
    annot_tracks=None,  # dict[str, str | Path | pl.DataFrame | pl.LazyFrame] | None
    *,
    overwrite=False,
    max_mem="4g",
) -> None

既存のオンディスク GVL データセットに、最初から書き直すことなくトラックを追加します。

  • dataset: データセットディレクトリへのパス、または開かれた Dataset(その .path が使用されます)。開いているデータセットは update 中に読み取ることができますが、再度開くまで新しいトラックは反映されません。
  • tracks: サンプルごとの BigWigs または Table ソース。トラックのサンプル集合はデータセットのサンプル集合と完全に一致している必要があります(不足も余分も不可)。サンプルは自動的にデータセットの順序に並べ替えられます。<path>/intervals/<track>/ に書き込まれます。
  • annot_tracks: サンプルに依存しないソースで、gvl.write の annot_tracks と同一です(インターバルテーブルへのパス、bigWig へのパス、または BED ライクなカラムを持つ polars DataFrame/LazyFrame)。<path>/annot_intervals/<name>/ に書き込まれます。
  • overwrite=True: 同名の既存トラックを置き換えます。False(デフォルト)の場合、名前がすでに存在すると FileExistsError を発生させます。
  • max_mem: おおよそのメモリ予算で、同時に実行されるカテゴリ間で分割されます。

各トラックのサブディレクトリはアトミックに公開されます(一時的な兄弟ディレクトリに構築され、その後 os.replace で所定の位置に移動されます)ので、読み取り側が書きかけのトラックを目にすることはありません。

ソース: python/genvarloader/_dataset/_write.py。

gvl.concat — オンディスクデータセットをマージする

gvl.concat(
    path,              # str | Path — destination directory
    datasets,          # Sequence[str | Path | Dataset] — 2+ inputs
    axis,               # "regions" | "samples"
    *,
    overwrite=False,
    max_mem="4g",       # advisory; accepted for symmetry with gvl.write
) -> None

すべてが単一のバリアントソースを共有するデータセットをマージします — 同じ PGEN/VCF バリアントテーブル(バックエンドの種類だけでなく、コンテンツフィンガープリントによってチェックされます)、または同じ .svar/.svar2 ストアです。異なるバリアントソースから構築されたデータセットをマージすると ValueError を発生させます。少なくとも 2 つの入力を必要とします。

  • axis="regions": 入力は同一のサンプルを同一の順序で持つ必要があります。それらのリージョンは連結されます(コンティグ/位置でソートされます)。
  • axis="samples": 入力は同一のリージョンと互いに素なサンプル集合を持つ必要があります。それらのサンプルはソートされた順序にマージされます。

どちらの軸も、ジェノタイプとともにサンプルごとのトラックとアノテーショントラックをマージします。対応バックエンド: PGEN/VCF、.svar、.svar2。PGEN/VCF ソースの場合、variants.arrow は最初の入力からハードリンクされ、フィンガープリントがマージ後の metadata.json に記録されます。Dataset.open はそれを再検証するため、バリアントインデックスの帯域外での書き換えは、黙って誤解決される代わりにエラーを発生させます。

コスト: gvl.concat は何も再導出せずにバイトをストリームするため、そのコストは計算ではなく I/O に比例します — マージ後のデータセットのほぼ全体のサイズを移動します。計画はストリーミングで行われ、メモリはリージョン数とサンプル数の積ではなく和に比例してスケールするため、常駐コストはマージ後のオフセット配列(マージ後の (region, sample[, ploid]) スロットごとに 1 つの int64)に入力自身のオフセット配列(入力がマージ後のグリッドを分割するため、合わせておおよそその 2 倍)を加えたものであり、マージ計画ではありません。ルーチンのステップとしてではなく、ジェノタイプを最初から再抽出するという代替手段に対する場合にのみ価値があります。完全なコストの議論と、コンティグシャードされた .svar2 ワークフロー向けのストアレベルの代替手段である genoray.SparseVar2.concat については、docs/source/write.md の「Merging datasets」を参照してください。

ソース: python/genvarloader/_dataset/_concat.py、_concat_validate.py。

Dataset.open — 主要な引数

gvl.Dataset.open(
    path, reference=None, jitter=0, rng=None,
    deterministic=True, rc_neg=True,
    min_af=None, max_af=None,           # .svar only — raises NotImplementedError on .svar2
    region_names=None,
    splice_info=None,                    # see "Spliced haplotypes"
    var_filter=None,                     # None | "exonic"
    var_fields=None,                     # list[str] | None — see below
    *, svar=None, svar2=None,
)

reference= を指定しない場合、ジェノタイプのみのデータセットはデフォルトで "variants" ビューで開きます(RaggedVariants を生成します) — Dataset.open(path) はそのまま動作し、with_seqs は不要です。"haplotypes"、"annotated"、"reference" の各ビューはすべて reference を必要とします。reference のないデータセットで with_seqs を介してそれらを要求すると、明確な ValueError を発生させます。svar= は記録された SVAR の場所を上書きします。svar2= は .svar2 ベースのデータセットに対して同様の役割を果たします。 with_settings(dummy_variant=...) — すべての空の (region, sample, ploid) バリアントグループに gvl.DummyVariant を挿入し、すべてのグループが少なくとも 1 つのバリアントを持つようにします。空のグループのみを埋め、空でないグループは変更されません。"variants" と "variant-windows" の両方の出力種別で有効です。dummy_variant が設定されていて出力種別がそれ以外("haplotypes"、"annotated"、"reference"、または seqs なし)の場合、インデックス作成時に ValueError が発生します — このチェックは with_seqs との順序に依存しません。False はダミーパディングを無効にし、None(デフォルト)は現在の設定を変更しません。出力がサポートされていない種別のときに dummy_variant=False を設定しても、無害なノーオペレーションです。

トークン出力(付随する FlatVariants.flank_tokens と "variant-windows" のフィールド ref_window/alt_window/ベア ref/alt)では、各空グループのダミーエントリは、設定された unknown_token(アルファベット外のバイトがマップされるユーザー指定の整数 — アルファベット非依存なので、DNA/RNA では N、アミノ酸では X がこれにトークン化されます)で完全に埋められます。DummyVariant.ref/.alt バイトはダミーアレルのバイト長のみを決定し、トークン値は決定しません。空の (region, sample, ploid) グループごとの充填長: 付随する flank_tokens → 2·flank_length 個の unknown トークン、ref_window/alt_window → 2·flank_length + len(dummy allele) 個の unknown トークン、ベア ref/alt → len(dummy allele) 個の unknown トークン。(デフォルトの b"N" アレル → 長さ 1。)

スカラーフィールド(start/ilen/dosage/info[...])は従来どおり DummyVariant の値から埋められます。ダミーの充填は "variants" 出力アレルの逆相補化の前にのみ適用されるため、b"N" 以外のダミーアレルは実際のアレルと同様に負鎖領域で逆相補化されます — デフォルトの b"N" は逆相補不変です。フランクトークンとバリアントウィンドウのトークンバッファは参照向きであり、逆相補化はされません。

with_settings(unphased_union=...) — 保存された二倍体ハプロタイプを単一の一倍体配列に折り畳みます: (region, sample) ごとのコールされた ALT の和集合です。True の場合、ds.ploidy は 1 を報告し(保存された 2 の代わり)、n_variants(...) は単一の倍数性スロット(形状 (..., 1))を報告し、カウントはハプロタイプごとの単純な合計に等しくなります(ホムコールはハプロタイプごとに 1 回ずつ、計 2 回現れ、重複排除はありません)。"variants" と "variant-windows" の出力は倍数性 1 でデコードされます。ALT の出現はハプロタイプ間で連結され、ソートも重複排除も行われません。フェーズは破棄されます — 非フェーズの体細胞コールの一倍体体細胞モデリングを目的としています。ジェノタイプを持つデータセットが必要です(参照のみのデータセットでは ValueError が発生します)。"haplotypes" / "annotated" 出力とは互換性がありません — with_seqs("haplotypes") または with_seqs("annotated")(あるいはこれらのいずれかがアクティブな出力種別のときにこのフラグを設定すること)は ValueError を発生させます。issue #222 を参照してください。

フォーマット検証: Dataset.open はデータセットの format_version と構造的整合性(ファイルの存在 + サイズ)を検証します。破損したデータセットは ValueError を発生させ、gvl.write での再生成を促します。データセットは自動再構築されません。

フォーマットバージョンゲート (2.0): 現在のオンディスクフォーマットは 2.0.0 です。genvarloader < 2.0 で書き込まれたデータセット(またはバージョンなしのデータセット)を開くと、gvl.migrate(path) を指すメッセージの ValueError が発生します。より新しいメジャーで書き込まれたデータセットは、genvarloader のアップグレードを促す ValueError を発生させます。gvl.migrate(path) を一度実行すると、2.0 以前のデータセットをその場でアップグレードします — ストリーミング方式で(ピーク時の追加ディスクは 1 トラック分のインターバルストア)、冪等で、クラッシュセーフです(すべてのトラックの struct-of-arrays ファイルが永続化された後にのみメタデータが更新され、その後古い array-of-structs ファイルが削除されます)。変換するのはトラックインターバルのストレージのみで、ジェノタイプ、リージョン、参照は変更されません。

  • var_fields: list[str] | None — RaggedVariants 出力に含めるバリアントフィールド。デフォルトは最小限の有用なセット ["alt", "ilen", "start"] です。追加の名前(例: "ref"、"dosage"、またはソースバリアントテーブル内の任意の数値情報カラム)を渡すと、オープン時にそれらを先行して読み込みます。Dataset.available_var_fields のサブセットである必要があります。後から Dataset.with_settings(var_fields=...) で再設定でき、新たに要求されたカラムは遅延読み込みされます。"dosage" は明示的に要求する必要があります — ディスク上に dosages.npy が存在する場合でも、自動的に追加されることはありません。組み込みフィールド(alt、start、ref、ilen、dosage)およびバリアントごとの INFO カラムに加えて、genoray の .svar は任意の per-call(Number=G)FORMAT フィールドを <svar>/metadata.json["fields"] に登録できます。これらは Dataset.available_var_fields に現れ、Dataset.open(..., var_fields=[...]) または with_settings(var_fields=[...]) で要求できます。それぞれが variants、variant-windows、flat 出力において、ジェノタイプに対応する per-call のラグドフィールドとして現れます。FORMAT フィールドは同名の INFO カラムをシャドウします。

    .svar2 では、available_var_fields は ["alt", "ilen", "start"] に、その .svar2 が書き込まれた際のストアフィールドを加えたものです — "ref" と "dosage" は .svar2 ソースで利用可能なフィールドではなく、いずれかを要求するとエラーになります(これらは BCF/PGEN/.svar でのみ有効です)。それ以外に、var_fields はストア自体のスカラー数値 INFO/FORMAT フィールドも公開します — それらは .svar2 が genoray.SparseVar2.from_vcf(info_fields=[...], format_fields=[...]) を介して書き込まれた際のものです(そこでは裸の str 名も機能します)。そもそも .svar2 ストアに存在できるのはスカラー数値フィールドのみです — Number=1 または Number=A の INFO/FORMAT Type=Integer/Float、および INFO Type=Flag(bool として保存)で、それ以外は書き込み時に genoray によって拒否され、gvl には到達しません。gvl はストアが既に保持しているものを読み取るだけです — フィールドを追加することはできず、ストアが持っていないフィールドを再要求するとエラーになります(available_var_fields に存在しないため)。Dataset.available_var_fields は各ストアフィールドのキーを公開し、それは genoray.SparseVar2.available_fields を情報源とします。ストアの INFO/FORMAT 名前空間で一意であれば裸のフィールド名、そうでなければ "INFO/<name>" / "FORMAT/<name>" となります。組み込み名(alt/start/ref/ilen/dosage)が常に優先されます — たとえば alt という名前のストアフィールドは決して公開されず、組み込みをシャドウすることはできません。値はストアの dtype を正確に保ち、拡張は行いません(i32 フィールドは int32 に、f32 フィールドは float32 にデコードされます)。また VCF に存在しないエントリは、ストアに保存されたデフォルトをそのまま保持します(デフォルトを宣言せずに定義された float フィールドでは NaN)。両方のエントリポイントは同じ svar2 再構築器にルーティングされます: gvl.Dataset.open(path, reference=..., var_fields=[...]) および ds.with_seqs("variants")/.with_settings(var_fields=[...])。両方の出力モードでサポートされています: "variants"(フィールドは返された RaggedVariants に現れ、たとえば rv["AF"]、alt/start/ilen のバリアントオフセットを共有します)および "variant-windows"(フィールドは win.fields["AF"] に start/ilen と並んで現れます)。FORMAT フィールドの値は、その行が属するサンプルの値です(サンプル 0 ではありません)。空の (region, sample, ploid) グループは、他のスカラーフィールドと同じ DummyVariant.info[<key>] メカニズム(上記の with_settings(dummy_variant=...) を参照)を介して各ストアフィールドを埋めます。ユーザー指定の値があればそれを使用し、そうでなければ float カラムには NaN、整数カラムには 0 を使用します。

出力モード — with_seqs × with_tracks

with_seqs(kind) はシーケンス出力チャネルを選択します:

kind返すもの使用する場面
"reference"参照配列 (S1)ベースライン / パーソナライズなし
"haplotypes"インデルを含むパーソナライズされたハプロタイプ (S1)標準的なバリアントを考慮したモデリング
"annotated"AnnotatedHaps (haps + var_idxs + ref_coords)バリアント/参照座標にマッピングし直す必要がある場合
"variants"RaggedVariants (バリアントのみ、配列なし)バリアント中心のタスク
"variant-windows"FlatVariantWindows (アレルごとのウィンドウ/アレルトークンバッファ。フラットモードのみ)各バリアント周辺のトークン化されたモデル入力
None配列なしトラックのみのデータセット

"variant-windows" には VarWindowOpt の第2引数 (with_seqs("variant-windows", gvl.VarWindowOpt(...)))、with_output_format("flat")、および参照ゲノムが必要です。with_settings からフランク設定を継承しません。

variant-windows は with_settings(realign_tracks=False) が設定されている場合、トラックと組み合わせることができます。返されるトラック/インターバルは参照座標 (そのまま) です。Float トラックは FlatRagged として、インターバルトラックは FlatIntervals として返されます。

with_tracks(tracks=..., kind=...) はトラックを選択します:

  • tracks: None (デフォルト)、False (無効化)、単一の名前、または名前のリスト。
  • kind: "tracks" (再アラインメントされた数値) または "intervals" (生のインターバル表現)。

トラックのハプロタイプ座標への再アラインメントは with_settings(realign_tracks=True) (デフォルト) で制御されます。参照座標 (「そのまま」) のトラックには realign_tracks=False を設定します。realign_tracks=False は、バリアントを考慮した任意の seq モードでの kind="intervals"、および variant-windows + トラックの場合に必須です。with_insertion_fill には realign_tracks=True が必要です。

with_settings(parallel=...) — このデータセットの読み取りの並列化ポリシーです。True は Rust カーネルを強制的にマルチスレッド化し、False は強制的に直列化し、"auto" (デフォルト) は出力サイズに基づいてバッチごとに決定します。明示的な True/False は GVL_FORCE_PARALLEL 環境変数を上書きします — 優先順位は 明示的な設定 > 環境変数 > サイズゲート — そのため、スクリプトの並列化は周囲の状態に依存せず、スクリプトから読み取ることができます。"auto" は環境変数に委ねるため、これを設定しないデータセットはこれまでと同じように動作します。この設定はデータセットごとであり、データローダーのワーカープロセスにも引き継がれます。これは並列化を行うかどうかを制御するもので、スレッド数ではありません。ワーカー数は rayon がグローバルプールの初期化時に GVL_NUM_THREADS を読み取るためインポート時に固定され、データセットごとに変えることはできません。issue #352 を参照してください。

with_len(L) は出力形状を制御します:

  • "ragged" (デフォルト): gvl.Ragged を返します (アイテムごとに可変長)。
  • "variable": バッチ内の最長アイテムに右パディングされた NumPy 配列 (seqs では N、トラックでは 0)。
  • 整数 L: 固定長。ジッター/ランダムシフト/切り詰め/よりパーソナライズされたデータでのパディングを組み合わせて L を満たします。L + 2·jitter ≤ min(region_length) + 2·max_jitter を満たす必要があります。

with_len に基づいて RaggedDataset または ArrayDataset (凍結されたデータクラスビュー) のいずれかを返します。図については docs/source/dataset.md を参照してください。

with_output_format(fmt) は eager インデックスによって返されるコンテナ型を選択します:

fmt返されるコンテナ型デフォルト?
"ragged"Ragged / RaggedVariants / RaggedAnnotatedHaps (すべて seqpro._core.Ragged ベース)はい
"flat"純粋な numpy の FlatRagged / FlatVariants / FlatAnnotatedHaps / FlatIntervalsいいえ
"flat" モードではホットパスに無駄がなく、返されるコンテナは .data(フラットな numpy 配列)と .offsets(int64)を保持します。すべてのフラット型には、_core.Ragged ベースの形式に戻す .to_ragged() があります。密化へのエスケープハッチは型ごとに異なります。FlatRagged には .to_fixed(length) と .to_padded(pad_value) があり、FlatAnnotatedHaps には .to_fixed(length) と .to_padded()(引数なし — フィールドごとの pad デフォルトを使用)があります。FlatVariants/FlatAlleles は .to_ragged() のみを公開します(加えて .reshape/.squeeze)。
ds_flat = ds.with_output_format("flat")
result = ds_flat[0:8, :]   # FlatRagged or FlatAnnotatedHaps or FlatVariants
# direct tensorization — no awkward round-trip
import torch
t = torch.from_numpy(result.data)
# or convert back
ragged = result.to_ragged()

with_output_format は with_len および subset_to と直交し、これらと組み合わせて使用できます。

スコープに関する注意: "flat" モードでは、kind="intervals" のトラックは FlatIntervals を返します(.to_ragged() → RaggedIntervals、フィールド .starts/.ends/.values はそれぞれ FlatRagged)。Float(数値)トラックはフラットモードで FlatRagged を返します。seqs/haplotypes/annotated-haps/reference および variants の出力もこれまでどおりフラット化されます。

Flat variants の追加機能 — 同乗するフランクトークンとバリアントウィンドウ:

import seqpro as sp
import genvarloader as gvl

# Both paths need tracks disabled — the flat variants/windows channel is not
# produced when tracks are active (see gotchas).

# (a) ride-along flank tokens on the "variants" output
fv = (ds.with_tracks(False).with_seqs("variants").with_output_format("flat")
        .with_settings(flank_length=128, token_alphabet=sp.DNA.alphabet,
                       unknown_token=len(sp.DNA)))[0:8]
fv.flank_tokens          # FlatRagged, shape (b, p, ~v, 2*128), or None if not configured

# (b) per-allele windows: ref as a flanked window, alt as a bare tokenized allele
fw = (ds.with_tracks(False).with_output_format("flat")
        .with_seqs("variant-windows",
                   gvl.VarWindowOpt(flank_length=128, token_alphabet=sp.DNA.alphabet,
                                    unknown_token=len(sp.DNA), ref="window", alt="allele")))[0:8]
fw.ref_window            # flanked ref window tokens (two-level token buffer)
fw.alt                   # bare alt allele tokens (no flanks); fw.alt_window is None
fw.ref_window.shape      # the window buffer's own shape: (b, p, ~v, ~len)

同乗する FlatVariants.flank_tokens(with_seqs("variants") + with_settings(flank_length=L, token_alphabet=..., unknown_token=...)): 返される FlatVariants に形状 (b, p, ~v, 2L) の FlatRagged を追加します。バリアントごとに、バッファは [flank5 | flank3] の参照コンテキストトークン(それぞれ長さ L)を保持します。座標規則: flank5 = [start-L, start)、flank3 = [end, end+L)(ここで end = start - min(ilen, 0) + 1)。token_alphabet(str、bytes、または seqpro.NucleotideAlphabet — 例: sp.alphabets.DNA / sp.DNA.alphabet。with_settings/build_token_lut の境界で bytes に正規化されます)と unknown_token(int)が一緒になって 256 エントリの byte→token LUT を構築します(seqpro 形式): 各アルファベットバイト → その 0 ベースのインデックス。その他のすべてのバイト(N や範囲外のパディングを含む)→ unknown_token。flank_length=0/None で無効化されます。token_alphabet と unknown_token は両方同時に設定する必要があります。トークンの dtype は、最大トークン ID ≤ 255 の場合は uint8、それ以外は int32 です。オフセットは int64 です。with_settings(dummy_variant=...) が設定されている場合、各空の (region, sample, ploid) グループの flank_tokens 行は、unknown_token が 2L 個連続したものになります。

VarWindowOpt / FlatVariantWindows(with_seqs("variant-windows", opt)): 各バリアントは、VarWindowOpt.ref / VarWindowOpt.alt ∈ {"window", "allele"} を介して ref と alt に対して独立に選択される 2 つのモードのいずれかで、固定長のトークンバッファを取得します:

  • "window": フランク付き + トークン化 — ref-window = トークン化された [start-L, end+L) の参照リード。alt-window = トークン化された flank5 · alt-allele · flank3 のアセンブリ。
  • "allele": フランクなしの、トークン化された裸のアレル(ref または alt の塩基)。

FlatVariantWindows は .ref_window / .ref のちょうど一方(他方は None)と、.alt_window / .alt のちょうど一方(他方は None)を設定します。.fields はスカラーの FlatRagged の dict です(start/ilen/dosage/info。生のバイトアレルは除外されます)。フランクとウィンドウは参照指向です — rc_neg=True であっても逆相補化されません。"variant-windows" ではスプライシングはサポートされません。with_settings(dummy_variant=...) が設定されている場合、各空の (region, sample, ploid) グループは、すべて unknown_token のエントリ 1 つでパディングされます: ref_window/alt_window("window" モード)では長さ 2·flank_length + len(dummy allele) トークン、裸の ref/alt("allele" モード)では len(dummy allele) トークンです。

トラック挿入フィル(haps と tracks が同時に存在する場合のみ)

インデルにより、トラック長が参照長と異なる場合があります。Dataset.with_insertion_fill(fill) は、挿入された位置に何を書き込むかを制御します。これは、データセットがハプロタイプとトラックの両方を返す場合にのみ有効です。純粋な参照(pure-ref)および純粋なハプロタイプ(pure-hap)のデータセットでは無視されます(適用しようとするとエラーが発生します)。

ストラテジー動作
gvl.Repeat5p() (デフォルト)バリアント POS の値を挿入領域全体に繰り返します。
gvl.Repeat5pNormalized()track[POS] / (insertion_len + 1) を繰り返します。合計を保持します。
gvl.Constant(value=nan)挿入領域全体で定数値(デフォルトは NaN)を使用します。
gvl.FlankSample(flank_width=5)POS 周辺の 2·flank_width+1 のウィンドウから、復元抽出でリサンプリングします。
gvl.Interpolate(order=1)両側の参照値の間で多項式補間(次数 1/2/3)を行います。

単一のストラテジーを渡す(すべてのトラックに適用)か、dict[track_name, strategy] を渡します(欠落しているトラックは Repeat5p にフォールバックします)。ソース: python/genvarloader/_dataset/_insertion_fill.py。

スプライスされたハプロタイプ

スプライシングは Dataset.open でオプトインします(または with_settings 経由)。これは 1 つのトランスクリプトの BED 行をグループ化し、サンプルごとにエクソンレベルの配列/トラックを連結します。

splice_bed = gvl.get_splice_bed("annotation.gtf", transcript_support_level="1")
gvl.write(path="splice.gvl", bed=splice_bed, variants="normed.svar")

sds = gvl.Dataset.open(
    "splice.gvl",
    reference="ref.fa",
    splice_info=("transcript_id", "exon_number"),  # tuple = (group_col, order_col)
    var_filter="exonic",  # optional: drop intronic variants
)

splice_info は以下を受け付けます:

  • カラム名の文字列(単一のグループ化カラム、順序は BED 行の順序から推測されます)、または
  • (group_col, order_col) タプル(明示的な順序付け、例えばエクソン番号)。

get_splice_bed は TSL フィルタリングとオプションの「CDS 長が 3 の倍数」フィルタを用いて GTF→BED を実行します。独自のスプライス BED を作成するには、BED に transcript_id(または任意のグループ化カラム)と exon_number カラムを含めるだけです。docs/source/splicing.ipynb を参照してください。

RefDataset のスプライシング

gvl.RefDataset は Dataset.open と同じ splice_info 引数を受け付けます。トランスクリプト ID のカラム名(行がすでにスプライス順になっている場合)か、エクソンを並べ替えるための (group_col, sort_col) タプルを渡します。with_settings(splice_info=False) は既存の RefDataset でスプライシングを無効化します。再度有効化するには新しい値を渡してください。スプライシングには output_length が {"ragged", "variable"} であること、jitter=0、deterministic=True が必要です。subset_to(transcript_ids) は Dataset と同様に動作します。

ref = gvl.Reference.from_path("hg38.fa.bgz")
bed = gvl.get_splice_bed("annotations.gtf")
ref_ds = gvl.RefDataset(ref, bed, splice_info="transcript_id")
seqs = ref_ds[:]  # Ragged[S1], one row per transcript

サイトのみのバリアント(例: ClinVar)

gvl.sites_vcf_to_table(vcf) → pl.DataFrame(二対立 SNP のみ)を使用し、ArrayDataset[AnnotatedHaps, ...] を gvl.DatasetWithSites(ds, sites, max_variants_per_region=1) でラップします。(wt_haps, mut_haps, flags[, tracks]) を返します。flags は適用済み / 重複により削除 / 既存をエンコードします。_variants/_sitesonly.py を参照してください。

データローダーのプリフェッチ (to_dataloader の mode=...)

Dataset.to_dataloader() は、フェッチを粗くするためのオプションの mode を受け付けます。gvl のスループットはフェッチサイズに応じてスケールするため(内部のマルチスレッド化がオーバーヘッドを償却します)、1 回の大きな dataset[r_idx, s_idx] 呼び出しをミニバッチにスライスするほうが、バッチごとの多数の小さな呼び出しよりも優れた性能を発揮します。

loader = ds.to_dataloader(
    batch_size=32,
    mode="double_buffered",   # or "buffered", or None
    buffer_bytes=2 * 1024**3, # total RAM budget; split across slots in double mode
    copy=True,                # zero-copy opt-out (default True = safe)
    heartbeat_seconds=60.0,   # double_buffered: max wait per chunk before liveness check
)

モード:

  • None(デフォルト) — 通常の torch.utils.data.DataLoader。既存の動作です。
  • "buffered" — メインプロセスが呼び出しごとに 1 つのチャンクをフェッチし(buffer_bytes に合わせてサイズ設定)、ミニバッチにスライスします。再充填のレイテンシは見えますが、多数のバッチにわたって償却されます。
  • "double_buffered" — サブプロセスのプロデューサーが一方の shm スロットを埋める間に、コンシューマーがもう一方を排出します。再充填のレイテンシが隠蔽されます。ファイルベースの Dataset.open(path) が必要です。

フラット出力はバッファリングモードと組み合わせられます。 ds.with_output_format("flat").to_dataloader(mode="buffered" | "double_buffered") は、Ragged / RaggedVariants の代わりに Flat* ミニバッチ(FlatRagged / FlatVariants / FlatAnnotatedHaps / FlatVariantWindows)を生成し、トランスポート経路での不格好さはゼロです — double_buffered プロデューサーはフラットバッファを書き込み、コンシューマーは再ラップせずにそれらを読み戻します。各バッチは .to_fixed(length) / .to_padded(pad) で密化するか、batch.data / batch.offsets を torch.from_numpy でラップします(オフセットは int64 です。torch の Nested テンソルにするには int32 にキャストしてください)。.to_ragged() で _core.Ragged を基盤とする型に再ラップします(ragged モードと要素単位で同一です)。モードの前提条件は変わりません。double_buffered は依然としてファイルベースの Dataset.open(path) を必要とし、依然としてスプライスされたデータセットとデフォルト以外の insertion_fill を拒否し、ハプロタイプ/アノテーション付き出力には依然として deterministic=True が必要です。"variant-windows" 出力(with_seqs("variant-windows", VarWindowOpt(...)))および同行フランクトークンを持つフラットな "variants" 出力(with_settings(flank_length=...))は、mode="buffered" と mode="double_buffered" の両方でサポートされ、mode=None とバイト単位で同一です — dummy_variant が設定されている場合も含みます(プロデューサーサブプロセスがそれを再生し、空グループのダミー充填は double_buffered のスロットサイズ計算に含まれます)。

前提条件(いずれも構築時に ValueError を発生させます):

  • with_seqs in {"haplotypes", "annotated"} には deterministic=True が必要です(with_settings(deterministic=True) で設定)。reference および variants モードには決定性の要件はありません。
  • スプライスされたデータセットはサポートされません。
  • num_workers > 0 は拒否されます — 新しいローダーが並行処理戦略そのものです。
  • 正確なフットプリントがスロットごとの容量を超える単一のミニバッチは、問題のあるサイズと是正用のパラメータ(batch_size↓、buffer_bytes↑)とともに発生させます。

フットプリントは Dataset._output_bytes_per_instance(...) を介して正確に計算されます(haplotype_lengths、n_variants、アレルオフセットテーブルを使用) — Zipf スタイルの最悪ケースの余裕はありません。

その他の公開サーフェス(一行説明)

  • gvl.Reference.from_path(fasta, contigs=None, in_memory=True) — FASTA (.fa/.fa.bgz へのパス、または .gvlfa キャッシュディレクトリ) をラップします。隣接する .gvlfa キャッシュディレクトリをビルド/再利用します (自己記述的で、フィンガープリント検証済み。レガシーな .fa.gvl キャッシュは自動移行されます)。キャッシュはベストエフォートのロックの下でアトミックに (一時ファイル + os.replace) ビルドされるため、1 つのリファレンスを共有する並行ビルダーは安全です。キャッシュは古くなった場合や存在しない場合、そのソースから自動再ビルドされます。in_memory=False はメモリマップからオンデマンドで読み取ります (RAM 使用量が少ない) が、FASTA のコンティグ順序を保持するため、contigs は None か、FASTA の完全な順序と正確に一致する必要があります — contigs の並べ替えや部分集合化には in_memory=True が必要です (そうでない場合は ValueError を送出します)。
  • gvl.read_bedlike(path) / gvl.with_length(bed, L) — BED ヘルパー (seqpro から再エクスポート)。
  • gvl.Ragged、gvl.RaggedAnnotatedHaps、gvl.RaggedVariants、gvl.RaggedIntervals — ragged 戻り値コンテナ。すべて seqpro.rag.Ragged (_core.Ragged Rust バックエンド) に支えられており、awkward ではありません。RaggedVariants は seqpro.rag.Ragged のサブクラス (class RaggedVariants(seqpro.rag.Ragged)) であるため、isinstance(rv, Ragged) is True です。構造メソッド — インデックス操作、reshape、squeeze、to_packed — は基底から継承され、RaggedVariants 型を保持します (位置/構造操作は RaggedVariants を返します)。文字列キー (rv["start"]) は裸の Ragged フィールドを返し、RaggedVariants ではありません。reshape は新しい形状を、展開した int として — 例えば rv.reshape(1, 2, None) — あるいは単一のタプルとして rv.reshape((1, 2, None)) 受け取ります。基底の Ragged シグネチャは両方を受け付けます。squeeze(axis=None) は実際の軸圧縮 (基底セマンティクス) です — 任意のサイズ 1 の軸を圧縮し、固定の「軸 0 を落とす」ではありません。int インデックスは先頭軸を潰し (numpy と整合)、スライス/配列インデックスはそれを保持します。アレルフィールド (rv.alt[b][h]、rv.ref[b][h]) のインデックス操作は、そのハプロタイプのアレルをバリアントごとに返し、rv.start[b][h] / rv.ilen[b][h] と 1 対 1 で整列するため、zip(rv.start[b][h], rv.alt[b][h]) は各位置をそれ自身のアレルとペアにします。これには seqpro >= 0.22 が必要です。それより古い seqpro では、同じ式がグループのすべてのアレルを連結した単一の bytes を返し、マルチバイト (indel) アレルを含むグループではスカラーフィールドとの整列が暗黙に崩れていました。名前付きプロパティ (.alt、.ref、.start、.ilen、.end) が主要なアクセスポイントです。追加フィールド (例えば AF、カスタム FORMAT フィールド) も rv["field"] または rv.field (__getattr__ 経由) でアクセスできます。RaggedVariants 自体は __eq__ を定義していません (ラッパーレベルの == は Python のオブジェクト同一性であり、要素ごとではありません)。内容を比較するには個々のフィールドを比較してください — 例えば rv["alt"] == other_alt や rv.start == other_start — これらは seqpro.rag.Ragged の ufunc ベース (要素ごと) の比較を使用します。RaggedVariants に保持されるドメインメソッド: .rc_()、.pad()、.to_nested_tensor_batch()。派生読み取り専用プロパティ: .ilen、.end。フィールド: .alt、.ref、.start、.dosage。
  • gvl.FlatRagged — Ragged のフラット版: .data (フラットな numpy 配列)、.offsets (int64)、.shape。メソッド: .to_ragged()、.to_fixed(length)、.to_padded(pad_value)、.reshape(shape)、.squeeze(axis)。ソース: python/genvarloader/_flat.py。
  • gvl.FlatIntervals — with_tracks(kind="intervals") + with_output_format("flat") が返すフラットバッファのインターバルコンテナ。フィールド .starts/.ends/.values は FlatRagged。.to_ragged() → RaggedIntervals、.reshape(...)、.squeeze(...)、.shape。ソース: python/genvarloader/_ragged.py。
  • gvl.FlatAnnotatedHaps — RaggedAnnotatedHaps のフラット版: フィールド .haps、.var_idxs、.ref_coords (それぞれ FlatRagged)。メソッド: .to_ragged()、.to_fixed(length)、.to_padded()、.reshape(shape)、.squeeze(axis)。ソース: python/genvarloader/_flat.py。
  • gvl.FlatVariants — RaggedVariants のフラット版: .fields はフィールド名を FlatRagged (スカラーフィールド: start/ilen/dosage/info) または FlatAlleles (alt/ref) にマッピングする dict。.shape は fields["start"].shape に委譲します。.flank_tokens: 形状 (b, p, ~v, 2L) のオプションの同行 FlatRagged (with_settings(flank_length=L, ...) が設定されている場合に設定され、それ以外は None)。メソッド: .to_ragged()、.reshape(shape)、.squeeze(axis)。ソース: python/genvarloader/_dataset/_flat_variants.py。
  • gvl.FlatAlleles — アレルフィールド用の 2 レベルのフラットバイト文字列: .byte_data (uint8)、.seq_offsets (バリアントごとのバイトオフセット、int64)、.var_offsets ((バッチ×倍数性) 行ごとのバリアントオフセット、int64)、.shape。メソッド: .to_ragged()、.reshape(shape)、.squeeze(axis)。ソース: python/genvarloader/_dataset/_flat_variants.py。
  • gvl.FlatVariantWindows — フラットモードで with_seqs("variant-windows", VarWindowOpt(...)) が返すもの。.fields: スカラー FlatRagged の dict (start/ilen/dosage/info。生のバイトアレルは破棄されます)。アレルごとのトークンバッファ — .ref_window (フランク付き ref ウィンドウ、"window" モード) または .ref (裸の ref アレルトークン、"allele" モード) のいずれか 1 つだけが設定されます。.alt_window / .alt も同様です。各非 None バッファは形状 (b, p, ~v, ~len) の 2 レベルトークンバッファ (内部 _FlatWindow であり、公開 FlatRagged ではありません) で、独自の .to_ragged() を持ちます。コンテナの .shape は fields["start"].shape に委譲します。メソッド: .to_ragged() (ragged パーツの dict を返す)、.reshape(shape)、.squeeze(axis)。ソース: python/genvarloader/_dataset/_flat_variants.py。
  • gvl.VarWindowOpt — with_seqs("variant-windows", ...) 用のフローズン設定 dataclass。フィールド: flank_length (int)、token_alphabet (str | bytes | sp.NucleotideAlphabet、例えば sp.alphabets.DNA。構築時に bytes に正規化)、unknown_token (int)、ref ∈ {"window","allele"}、alt ∈ {"window","allele"}。ref と alt は独立に選択されます。"window" = フランク付き + トークン化されたリファレンスリード (ref) または flank·alt·flank のアセンブリ (alt)、"allele" = フランクなしの裸のトークン化アレル。ソース: python/genvarloader/_dataset/_flat_variants.py。
  • gvl.DummyVariant — with_settings(dummy_variant=...) で使用するフローズン dataclass。フィールドとデフォルト: start: int = -1、ilen: int = 0、dosage: float = 0.0、ref: bytes = b"N"、alt: bytes = b"N"、info: dict = {}。指定されていない info キーは、整数カラムでは 0、浮動小数点カラムでは NaN にデフォルト設定されます。ソース: python/genvarloader/_dataset/_flat_variants.py。
  • gvl.migrate(path) — 2.0 より前の (struct-of-arrays の) データセットをフォーマット 2.0 (struct-of-arrays) にその場でアップグレードします。ストリーミング、冪等、クラッシュセーフ。intervals/<track>/ と annot_intervals/<track>/ のインターバルストレージを変換し、metadata.json を更新します。すでに 2.0 のデータセットでは no-op (残存する AoS のクリーンアップを伴う) です。ソース: python/genvarloader/_dataset/_migrate.py。(レガシーな SVAR シンボリックリンクレイアウトをアップグレードする gvl.migrate_svar_link とは異なります。)
  • gvl.to_nested_tensor(ragged) — PyTorch のネストテンソルに変換します (torch が必要)。
  • gvl.get_dummy_dataset() — 例/テスト用の小さなインメモリデータセット。
  • gvl.RefDataset — リファレンスのみのデータセット (ジェノタイプなし)。
  • gvl.Table — Rust の COITrees オーバーラップエンジンに支えられたコアのインターバルトラックソース。0 始まりの半開座標。正の幅のインターバルを前提とします。gvl.write と gvl.update の tracks= または annot_tracks= ソースとして直接使用できます。追加のインストールは不要です — コアパッケージの一部として同梱されています。ブルートフォースの numpy オラクル + プロパティテストによる CI カバレッジがあります。
  • gvl.data_registry.fetch(name) — 公開テスト/デモデータセットをダウンロードします。 完全なリストは python/genvarloader/__init__.py の __all__ にあります。

ディスク上のレイアウト(クイックリファレンス)

ds.gvl/
├── metadata.json              # version, samples, contigs, ploidy, max_jitter, svar_link?
├── input_regions.arrow        # BED + region index map
├── genotypes/                 # variant_idxs.npy, dosages.npy, variants.arrow
│                              # (absent when sourced from .svar; see svar_link)
│                              # svar2_ranges/ present iff sourced from .svar2 (see svar2_link)
├── intervals/<track>/         # per-sample track data (BigWigs / Table)
└── annot_intervals/<track>/   # sample-independent annotation track data

フォーマット 2.0 では、各 intervals/<track>/(および annot_intervals/<track>/)ディレクトリは、その間隔を struct-of-arrays として保存します — 3 つの連続ファイル starts.npy(int32)、ends.npy(int32)、values.npy(float32)が 1 つの offsets.npy(int64)を共有し、フォーマット 1.x の単一の intervals.npy レコード配列を置き換えます。これにより、連続した memmap が Python→Rust の境界をゼロコピーで越えられます。1.x データセットは gvl.migrate(path) でアップグレードしてください(上記のフォーマットバージョンゲートを参照)。

完全なスキーマ、バージョニング、SVAR リンクの詳細については docs/source/format.md を参照してください。

次に参照すべき場所

目的…参照先…
エンドツーエンドの RNA-seq の例docs/source/geuvadis.ipynb
スプライシングのチュートリアルdocs/source/splicing.ipynb
ディープラーニング評価パイプラインdocs/source/basenji2_eval.ipynb
BED / BigWig / bcftools のレシピdocs/source/write.md
Dataset の形状、ragged/var/fixeddocs/source/dataset.md
ディスク上のフォーマット + SVAR 解決docs/source/format.md
FAQ(with_* の設計、型付け)docs/source/faq.md
自動生成リファレンスdocs/source/api.md → https://genvarloader.readthedocs.io
gvl.write / gvl.update の内部python/genvarloader/_dataset/_write.py
gvl.concat の内部 + 前提条件python/genvarloader/_dataset/_concat.py、_concat_validate.py
シャーディングビルド / マージのワークフローdocs/source/write.md(「データセットのマージ」)、docs/source/faq.md
トラック再アラインメントの内部python/genvarloader/_dataset/_tracks.py、_reconstruct.py
挿入フィルの内部python/genvarloader/_dataset/_insertion_fill.py
SVAR 逆参照 / マイグレーションpython/genvarloader/_dataset/_svar_link.py
.svar2 逆参照 / 読み取りバウンドの配線python/genvarloader/_dataset/_svar2_link.py、_svar2_haps.py
.svar2 スパース範囲キャッシュのレイアウト(書き込み/読み取り/concat)python/genvarloader/_dataset/_svar2_ranges.py
フォーマット 1.x → 2.0 マイグレーションの内部python/genvarloader/_dataset/_migrate.py
フラットバッファの ragged コンテナpython/genvarloader/_flat.py
フラットバリアント + アレル型python/genvarloader/_dataset/_flat_variants.py
フランク取得 + トークン化 + ウィンドウpython/genvarloader/_dataset/_flat_flanks.py

よくある落とし穴

  • 2.0 より前のデータセットは、開く前に一度マイグレーションする必要があります。 Dataset.open は、genvarloader < 2.0 (またはバージョンなし) で書き込まれたあらゆるデータセットを ValueError で拒否し、gvl.migrate(path) を指し示します。これを一度実行してください (その場で、冪等、クラッシュセーフ)。より新しいメジャーバージョンで書き込まれたデータセットは、別の ValueError を発生させ、genvarloader のアップグレードを求めます。なお、gvl.migrate (フォーマットのアップグレード) は gvl.migrate_svar_link (SVAR シンボリックリンクレイアウトのアップグレード) とは異なります。
  • gvl.update は開いているデータセットをホットリロードしません。 gvl.update の実行前に開かれた Dataset インスタンスは、新しいトラックを認識しません。反映させるにはデータセットを再度開いてください。更新自体は、リーダーがアクティブな間に実行しても安全です。各トラックはアトミックに公開されるため、リーダーが書き込み途中のトラックを目にすることはありません。
  • Dataset.write_annot_tracks は削除されました。 代わりに gvl.update(dataset, annot_tracks={"name": source}) を使用するか、作成時に gvl.write に annot_tracks= を渡してください。
  • gvl.Table はコアの公開 API です。 追加のインストールは不要です。Rust の COITrees オーバーラップエンジンを使用し、CI でカバーされています。gvl.Table としてインポートしてください (トップレベルのパッケージから再エクスポートされています)。
  • シンボリック / ブレークエンドバリアントはスキップされず、拒否されます。 gvl.write の前にそれらを除去してください — 例えば bcftools view -e 'ALT~"<" || ALT~"\["' (SV とブレークエンドを削除)、または filter=genoray.exprs.is_biallelic & ~genoray.exprs.is_symbolic & ~genoray.exprs.is_breakend を指定して genoray リーダーを構築します。SVAR 入力は、あらかじめフィルタリングされたソースから構築する必要があります。gvl はマテリアライズされた .svar を検証できますが、再フィルタリングはできないためです。.svar2 の場合、同じバリアントは gvl.write 時ではなく .svar2 変換時に上流で (genoray によって) 拒否されます — ストアフォーマットはそれらをそもそも表現できません。
  • .svar2 には Phase-1 の未サポートの組み合わせマトリクスがあります。 min_af/max_af、annotated ハプロタイプ、VarWindowOpt(ref="allele")、非ハプロタイプ/トラック出力でのスプライシングまたは var_filter="exonic"、逆相補または固定長のハプロタイプ再アラインメントトラック、ジッター付きの variants/variant-windows 出力 (書き込み時の max_jitter>0 または読み取り時の jitter>0)、書き込み時の extend_to_length=False はすべて、.svar2 ベースのデータセットでは暗黙に誤計算するのではなく NotImplementedError を発生させます。プレーンなハプロタイプは、スプライシング、エクソンフィルタリング、ネガティブ鎖の逆相補をサポートします。with_seqs("variant-windows")、unphased_union、var_fields で選択されたストア INFO/FORMAT フィールド ("variants" と "variant-windows" の両方)、およびマルチコンティグの FlankSample トラック充填 (issue #267) も .svar2 でサポートされています。上記の「.svar2 — 読み取りバウンドのスパースバリアントフォーマット」を参照してください。
  • .svar2 の variants/variant-windows の ALT バイトは、純粋な欠失の場合に .svar と異なります。 .svar は VCF アンカーベースを保持します (GTA>G に対して b"G")。.svar2 はアトマイズされた空の ALT (b"") をデコードします。再構築されたハプロタイプはどちらの場合もバイト単位で同一です。ref_window もバイト単位で同一です — 純粋な欠失レコードで異なるのは生の ALT/alt_window バイトのみです。
  • ジェノタイプのみのデータセットを reference= なしで開くと、"haplotypes" ではなく "variants" ビュー (RaggedVariants) がデフォルトになります。参照なしで利用できるのは "variants" のみです。参照が提供されていない場合、with_seqs("haplotypes" | "annotated" | "reference") は ValueError を発生させます。
  • with_insertion_fill は、データセットでハプロタイプとトラックの両方がアクティブでない限り発生します。
  • min_af / max_af は .svar のみでサポートされています。SVAR ベースでないデータセット (プレーンな BCF/PGEN) は RuntimeError を発生させます。.svar2 ベースのデータセットは特に NotImplementedError を発生させます。
  • with_len(L) には L + 2·jitter ≤ min(region_length) + 2·max_jitter が必要です — write 時に max_jitter を適切に設定してください。
  • トラックは一意の .name を持つ必要があります。オンディスクのレイアウトは intervals/<name>/ です。
  • BED の strand が . の場合は + として扱われます。逆相補は rc_neg=True (デフォルト) かつ strand == "-" のときに自動的に行われます。
  • スプライシングはエクソンのフラットな BED に対する読み取り時の設定です — gvl.write の前にエクソンを事前に連結しないでください。
  • 書き込み時の extend_to_length=False は、欠失が存在する場合に BED 領域より短いハプロタイプを生成します。ダウンストリームのコードは < 領域長を許容する必要があります。.svar2 バリアントソースにはオプションではありません — gvl.write(..., variants=<.svar2>, extend_to_length=False) は NotImplementedError を発生させます。
  • 期待した RaggedVariants 出力に dosage フィールドがない場合は、var_fields を確認してください — ディスク上に dosages.npy が存在していても、dosage は明示的に要求する必要があります。
  • アレルフィールドはバリアントごとにインデックスされ、seqpro>=0.22 が必要です。 rv.alt[b][h] はバリアントごとに 1 つのアレルを返し、rv.start[b][h] と一致します。seqpro <0.22 では、グループのアレルが 1 つの bytes として連結されて返されていました — これは SNP のみのデータでは見えない不一致であり (すべてのアレルが 1 バイトなのでカウントが一致します)、ウィンドウにインデルが入って初めて現れます。gvl は seqpro>=0.22 を要求します。連結された塊が見える場合は、まずインストールされている seqpro のバージョンを確認してください。
  • FlatRagged / FlatVariants のオフセットは int64 です。PyTorch のネストテンソルは int32 オフセットを要求します — torch.nested.narrow に渡す前に .astype(np.int32) または tensor.to(torch.int32) でキャストしてください。
  • kind="intervals" は再アラインメントできません。バリアント対応の seq モード (haplotypes/annotated/variants/variant-windows) と組み合わせると、with_settings(realign_tracks=False) でない限り発生します。(破壊的変更: haplotypes+intervals は以前、デフォルトで再アラインメントされていない intervals を暗黙に返していました。)
  • with_insertion_fill は realign_tracks=False のときに発生します。
  • with_seqs("variant-windows") には VarWindowOpt の第 2 引数、with_output_format("flat")、および参照ゲノムが必要です。"ragged" モードでのクエリは発生します。with_settings からフランク設定を継承しません。
  • フラットなライドアロングフランクトークンにはトラックを無効化する必要があります。 FlatVariants.flank_tokens ("variants" 出力へのライドアロング) は純粋なフラットバリアントチャネルでのみ生成されます — トラックがアクティブな場合、variants 出力はラギッドな RaggedVariants にフォールバックします (flank_tokens はありません)。ライドアロングには with_tracks(False) を呼び出してください。"variant-windows" は with_settings(realign_tracks=False) を介してトラックと組み合わせることができます (トラックはウィンドウ出力と並んで参照座標で返されます)。
  • フランクトークン (FlatVariants.flank_tokens) とバリアントウィンドウ (FlatVariantWindows) は参照指向です — rc_neg=True であっても逆相補されません。RC されるのは FlatVariants / RaggedVariants の alt/ref アレルフィールドのみです (そのスカラーフィールド、フランクトークン、ウィンドウは RC されません)。
  • トークンの dtype は、最大トークン ID ≤ 255 の場合は uint8、それ以外は int32 です。オフセットは int64 です。
  • VarWindowOpt(ref="allele") (ベアアレルモード) にはディスク上の REF アレルが必要です。FlatVariants への flank_length ライドアロングには、token_alphabet と unknown_token を同じまたは以前の with_settings 呼び出しで一緒に設定する必要があります。
  • dummy_variant パディングは "variants" と "variant-windows" の両方の出力に適用されます。dummy_variant=<DummyVariant> を設定してから他の kind ("haplotypes"、"annotated"、"reference"、または seqs なし) でインデックスすると ValueError を発生させます。トークンフィールド (flank_tokens、ref_window/alt_window、ベアの ref/alt) の場合、ダミー充填はすべて unknown_token です — DummyVariant.ref/.alt バイトはダミーアレルのバイト長を設定するだけで、トークン値は設定しません。サポートされていない出力 kind での dummy_variant=False は暗黙に無視されます。
  • b"N" でない DummyVariant.alt (または .ref) は、実際のバリアントアレルとまったく同様に、ネガティブ鎖領域で逆相補されます。デフォルトの b"N" は rc 不変です。鎖に中立なセンチネルが必要な場合はこれを使用してください。
  • unphased_union=True + with_seqs("haplotypes") / with_seqs("annotated") は発生します — unphased_union は "variants" / "variant-windows" 出力にのみ適用されます。
  • .svar2 のレンジキャッシュの書き込み時アキュムレータは max_mem で制限されません。 .svar2 ソースを指定した gvl.write は、永続的な genotypes/svar2_ranges/ キャッシュをスパースな リージョン CSR テーブルとして構築します — 空でない (region, sample, ploid) ウィンドウあたり 28 バイト、All of Us chr22 グリッドで約 504 MB、コホート規模では小さい ( format.md を参照)。残るメモリの驚きは書き込み時です: max_mem は genoray のチャンクストリームを制限しますが、コンティグごとのエントリアキュムレータは制限しません。これは最大のコンティグでエントリあたりおよそ 60 バイトでピークに達します — チャンクごとの (region int32, cell int32, 24-byte entry) ブロックとマージされた (cell, entry) 出力が同時に存在します (chr22 で約 1.1 GB、最大のコンティグで 1 桁台前半の GB)。
  • Dataset.samples は数値ではなく辞書順にソートされます。 桁数が混在する整数のような ID を持つコホートは、フェノタイプテーブルが通常持つ数値ソートとは異なる順序になります (文字列として "1000" < "999")。両者の間の位置ベースの結合は暗黙に誤りになります。サンプル名で結合してください。
  • gvl.concat には 1 つの共有バリアントソースと少なくとも 2 つの入力が必要です。 バリアントソースの不一致 (バックエンドの種類だけでなくフィンガープリントでチェック)、サンプルセット/順序が異なる axis="regions"、またはリージョンが異なる、もしくはサンプルが重複する axis="samples" はすべて、バイトが移動する前に ValueError を発生させます。マージされたデータセットのほぼ全体のサイズをシーケンシャル IO 速度で移動します — 日常的なステップではありません。

このスキルのメンテナンス

PR がパブリック API(python/genvarloader/__init__.py の __all__ に含まれるもの、または gvl.write、Dataset.open、もしくは任意の Dataset.with_* メソッドの docstring/シグネチャ)を変更する場合は常に、作成者はこの SKILL.md も更新する必要があります。新しいパブリックシンボルの追加、シンボルの削除、引数の名前変更、デフォルト値の変更、新しい出力モードはすべて対象です。CLAUDE.md はこれをコントリビューションチェックリストの一部として義務付けています。

コメント