Follow-up from issue #277 Wave A Task 4 (annotated output / AnnotatedHaps for the streaming engines, PR TBD).
Context. RecordBackend::generate (src/record_stream/engine.rs) emits annot_v_idxs (dataset-GLOBAL variant ids per output position) by adding a per-window var_base (DecodedWindow::var_base, src/record_stream/transpose.rs) to the window-local ids fill_decoded_window produces. PgenWindowFiller::fill (src/record_stream/pgen.rs) sets this correctly and cheaply from var_start, a value already computed from the .pvar pre-scan's per-contig position table (contig_ranges/contig_pos).
VcfWindowFiller::fill (src/record_stream/vcf.rs) has no equivalent per-contig variant-count/position index — genoray's VcfRecordSource was not found to expose one cheaply — so it hard-codes slot.var_base = 0.
Why this is safe today. Every Wave A VCF annotated fixture (Task 4's test_streaming_annotated_parity.py, Task 5's same-POS fixtures) is single-contig with the region spanning the whole contig, so the window's first decoded variant IS dataset-global variant 0 and var_base = 0 is exact.
The gap. For any config where a VCF-backed StreamingDataset.with_seqs("annotated") window does NOT start at global variant 0 — a multi-contig cohort (2nd+ contig's variants are not global-0-based) or a region that doesn't cover a contig's first variant — annot_v_idxs would be silently WRONG (window-local ids reported as if global).
Action. Add a cheap per-contig variant-count/position table to VcfWindowFiller (analogous to PGEN's .pvar pre-scan — e.g. a lightweight header/index pass at VcfWindowFiller::new, mirroring how sample_indices is already resolved once at construction rather than per-window), then wire slot.var_base the same way PgenWindowFiller does. Add a multi-contig VCF annotated-output parity fixture to exercise the fixed case (mirroring svar1_multicontig_fixture, which already proves the SVAR1 var_base = 0 path is correct for multi-contig).
Add to the StreamingDataset project.
Follow-up from issue #277 Wave A Task 4 (annotated output /
AnnotatedHapsfor the streaming engines, PR TBD).Context.
RecordBackend::generate(src/record_stream/engine.rs) emitsannot_v_idxs(dataset-GLOBAL variant ids per output position) by adding a per-windowvar_base(DecodedWindow::var_base,src/record_stream/transpose.rs) to the window-local idsfill_decoded_windowproduces.PgenWindowFiller::fill(src/record_stream/pgen.rs) sets this correctly and cheaply fromvar_start, a value already computed from the.pvarpre-scan's per-contig position table (contig_ranges/contig_pos).VcfWindowFiller::fill(src/record_stream/vcf.rs) has no equivalent per-contig variant-count/position index — genoray'sVcfRecordSourcewas not found to expose one cheaply — so it hard-codesslot.var_base = 0.Why this is safe today. Every Wave A VCF annotated fixture (Task 4's
test_streaming_annotated_parity.py, Task 5's same-POS fixtures) is single-contig with the region spanning the whole contig, so the window's first decoded variant IS dataset-global variant 0 andvar_base = 0is exact.The gap. For any config where a VCF-backed
StreamingDataset.with_seqs("annotated")window does NOT start at global variant 0 — a multi-contig cohort (2nd+ contig's variants are not global-0-based) or a region that doesn't cover a contig's first variant —annot_v_idxswould be silently WRONG (window-local ids reported as if global).Action. Add a cheap per-contig variant-count/position table to
VcfWindowFiller(analogous to PGEN's.pvarpre-scan — e.g. a lightweight header/index pass atVcfWindowFiller::new, mirroring howsample_indicesis already resolved once at construction rather than per-window), then wireslot.var_basethe same wayPgenWindowFillerdoes. Add a multi-contig VCF annotated-output parity fixture to exercise the fixed case (mirroringsvar1_multicontig_fixture, which already proves the SVAR1var_base = 0path is correct for multi-contig).Add to the StreamingDataset project.