From deb6990332e33fc8069e6b35acee063373a9dcc0 Mon Sep 17 00:00:00 2001 From: carstenerickson Date: Sat, 16 May 2026 12:05:38 -0700 Subject: [PATCH] view -R: opt into htslib dense single-base BED auto-promotion (#2557) Wires bcftools view into the new BCF_SR_AUTO_TARGETS_FROM_REGIONS htslib opt (see samtools/htslib for the underlying sniffer and streaming- targets routing). When -R FILE is given and no -T is set, view sets the opt before calling bcf_sr_set_regions(); htslib's sniffer then decides per-file whether to promote. Why gate on !targets_list: BCF_SR_AUTO_TARGETS_FROM_REGIONS populates readers->targets, which conflicts with a subsequent bcf_sr_set_targets() call. Always-on would silently break the -R FILE -T OTHER workflow, so the opt is suppressed whenever a -t/-T was given. The new --no-regions-fastpath suppresses the opt unconditionally for users that hit corner cases the sniffer accepts incorrectly. End-to-end measurements (synthetic single-base BED, 10bp avg spacing, matching VCF; bcftools 1.23.1-dirty, macOS arm64): N=100K: 11.67s -> 0.17s (69x) N=1M : 156.60s -> 0.73s (215x) The N=1M result puts the production HGDP+1kGP / AADR / PGS panel cases within minutes instead of hours. --no-regions-fastpath, --regions-file without an index, and -R FILE -T OTHER all preserve the existing seek-per-region default. Regression test test_vcf_view_regions_fastpath asserts byte-identical output across the fastpath, --no-regions-fastpath, and -T paths on a 300-entry single-base fixture (>= htslib SNIFF_LINES=256 so the sniffer accepts). Tracks #2557. --- NEWS | 13 + test/regions-fastpath.bed | 300 +++++++++++++++++++ test/regions-fastpath.out | 300 +++++++++++++++++++ test/regions-fastpath.vcf | 606 ++++++++++++++++++++++++++++++++++++++ test/test.pl | 25 ++ vcfview.c | 13 + 6 files changed, 1257 insertions(+) create mode 100644 test/regions-fastpath.bed create mode 100644 test/regions-fastpath.out create mode 100644 test/regions-fastpath.vcf diff --git a/NEWS b/NEWS index e97f6340f..babcc3824 100644 --- a/NEWS +++ b/NEWS @@ -79,6 +79,19 @@ Changes affecting specific commands: bcftools +trio-dnm3 --use-ALM +* bcftools view + + - `-R FILE` now opts into htslib's `BCF_SR_AUTO_TARGETS_FROM_REGIONS` + when no `-T` is given. Dense single-base BEDs (HGDP+1kGP, AADR 1240k, + PGS Catalog and similar panels) are routed through the streaming- + targets path instead of doing one tabix iterator setup per BED entry; + the htslib-side sniffer decides per-file whether the file qualifies, + and small / sparse / wide BEDs fall back to the existing seek-per- + region default. Pass `--no-regions-fastpath` to disable. Production + panels see roughly 200-300x speedups at the bcftools-view level (1M + entries: 156 s → 0.7 s on the synthetic reproducer). Requires the + matching htslib change (samtools/htslib PR for #2557). + ## Release 1.23.1 (18th March 2026) diff --git a/test/regions-fastpath.bed b/test/regions-fastpath.bed new file mode 100644 index 000000000..628e24d4c --- /dev/null +++ b/test/regions-fastpath.bed @@ -0,0 +1,300 @@ +1 99 100 +1 199 200 +1 299 300 +1 399 400 +1 499 500 +1 599 600 +1 699 700 +1 799 800 +1 899 900 +1 999 1000 +1 1099 1100 +1 1199 1200 +1 1299 1300 +1 1399 1400 +1 1499 1500 +1 1599 1600 +1 1699 1700 +1 1799 1800 +1 1899 1900 +1 1999 2000 +1 2099 2100 +1 2199 2200 +1 2299 2300 +1 2399 2400 +1 2499 2500 +1 2599 2600 +1 2699 2700 +1 2799 2800 +1 2899 2900 +1 2999 3000 +1 3099 3100 +1 3199 3200 +1 3299 3300 +1 3399 3400 +1 3499 3500 +1 3599 3600 +1 3699 3700 +1 3799 3800 +1 3899 3900 +1 3999 4000 +1 4099 4100 +1 4199 4200 +1 4299 4300 +1 4399 4400 +1 4499 4500 +1 4599 4600 +1 4699 4700 +1 4799 4800 +1 4899 4900 +1 4999 5000 +1 5099 5100 +1 5199 5200 +1 5299 5300 +1 5399 5400 +1 5499 5500 +1 5599 5600 +1 5699 5700 +1 5799 5800 +1 5899 5900 +1 5999 6000 +1 6099 6100 +1 6199 6200 +1 6299 6300 +1 6399 6400 +1 6499 6500 +1 6599 6600 +1 6699 6700 +1 6799 6800 +1 6899 6900 +1 6999 7000 +1 7099 7100 +1 7199 7200 +1 7299 7300 +1 7399 7400 +1 7499 7500 +1 7599 7600 +1 7699 7700 +1 7799 7800 +1 7899 7900 +1 7999 8000 +1 8099 8100 +1 8199 8200 +1 8299 8300 +1 8399 8400 +1 8499 8500 +1 8599 8600 +1 8699 8700 +1 8799 8800 +1 8899 8900 +1 8999 9000 +1 9099 9100 +1 9199 9200 +1 9299 9300 +1 9399 9400 +1 9499 9500 +1 9599 9600 +1 9699 9700 +1 9799 9800 +1 9899 9900 +1 9999 10000 +2 99 100 +2 199 200 +2 299 300 +2 399 400 +2 499 500 +2 599 600 +2 699 700 +2 799 800 +2 899 900 +2 999 1000 +2 1099 1100 +2 1199 1200 +2 1299 1300 +2 1399 1400 +2 1499 1500 +2 1599 1600 +2 1699 1700 +2 1799 1800 +2 1899 1900 +2 1999 2000 +2 2099 2100 +2 2199 2200 +2 2299 2300 +2 2399 2400 +2 2499 2500 +2 2599 2600 +2 2699 2700 +2 2799 2800 +2 2899 2900 +2 2999 3000 +2 3099 3100 +2 3199 3200 +2 3299 3300 +2 3399 3400 +2 3499 3500 +2 3599 3600 +2 3699 3700 +2 3799 3800 +2 3899 3900 +2 3999 4000 +2 4099 4100 +2 4199 4200 +2 4299 4300 +2 4399 4400 +2 4499 4500 +2 4599 4600 +2 4699 4700 +2 4799 4800 +2 4899 4900 +2 4999 5000 +2 5099 5100 +2 5199 5200 +2 5299 5300 +2 5399 5400 +2 5499 5500 +2 5599 5600 +2 5699 5700 +2 5799 5800 +2 5899 5900 +2 5999 6000 +2 6099 6100 +2 6199 6200 +2 6299 6300 +2 6399 6400 +2 6499 6500 +2 6599 6600 +2 6699 6700 +2 6799 6800 +2 6899 6900 +2 6999 7000 +2 7099 7100 +2 7199 7200 +2 7299 7300 +2 7399 7400 +2 7499 7500 +2 7599 7600 +2 7699 7700 +2 7799 7800 +2 7899 7900 +2 7999 8000 +2 8099 8100 +2 8199 8200 +2 8299 8300 +2 8399 8400 +2 8499 8500 +2 8599 8600 +2 8699 8700 +2 8799 8800 +2 8899 8900 +2 8999 9000 +2 9099 9100 +2 9199 9200 +2 9299 9300 +2 9399 9400 +2 9499 9500 +2 9599 9600 +2 9699 9700 +2 9799 9800 +2 9899 9900 +2 9999 10000 +3 99 100 +3 199 200 +3 299 300 +3 399 400 +3 499 500 +3 599 600 +3 699 700 +3 799 800 +3 899 900 +3 999 1000 +3 1099 1100 +3 1199 1200 +3 1299 1300 +3 1399 1400 +3 1499 1500 +3 1599 1600 +3 1699 1700 +3 1799 1800 +3 1899 1900 +3 1999 2000 +3 2099 2100 +3 2199 2200 +3 2299 2300 +3 2399 2400 +3 2499 2500 +3 2599 2600 +3 2699 2700 +3 2799 2800 +3 2899 2900 +3 2999 3000 +3 3099 3100 +3 3199 3200 +3 3299 3300 +3 3399 3400 +3 3499 3500 +3 3599 3600 +3 3699 3700 +3 3799 3800 +3 3899 3900 +3 3999 4000 +3 4099 4100 +3 4199 4200 +3 4299 4300 +3 4399 4400 +3 4499 4500 +3 4599 4600 +3 4699 4700 +3 4799 4800 +3 4899 4900 +3 4999 5000 +3 5099 5100 +3 5199 5200 +3 5299 5300 +3 5399 5400 +3 5499 5500 +3 5599 5600 +3 5699 5700 +3 5799 5800 +3 5899 5900 +3 5999 6000 +3 6099 6100 +3 6199 6200 +3 6299 6300 +3 6399 6400 +3 6499 6500 +3 6599 6600 +3 6699 6700 +3 6799 6800 +3 6899 6900 +3 6999 7000 +3 7099 7100 +3 7199 7200 +3 7299 7300 +3 7399 7400 +3 7499 7500 +3 7599 7600 +3 7699 7700 +3 7799 7800 +3 7899 7900 +3 7999 8000 +3 8099 8100 +3 8199 8200 +3 8299 8300 +3 8399 8400 +3 8499 8500 +3 8599 8600 +3 8699 8700 +3 8799 8800 +3 8899 8900 +3 8999 9000 +3 9099 9100 +3 9199 9200 +3 9299 9300 +3 9399 9400 +3 9499 9500 +3 9599 9600 +3 9699 9700 +3 9799 9800 +3 9899 9900 +3 9999 10000 diff --git a/test/regions-fastpath.out b/test/regions-fastpath.out new file mode 100644 index 000000000..d388ce35e --- /dev/null +++ b/test/regions-fastpath.out @@ -0,0 +1,300 @@ +1 100 . A G 100 PASS . GT 0/1 +1 200 . A G 100 PASS . GT 0/1 +1 300 . A G 100 PASS . GT 0/1 +1 400 . A G 100 PASS . GT 0/1 +1 500 . A G 100 PASS . GT 0/1 +1 600 . A G 100 PASS . GT 0/1 +1 700 . A G 100 PASS . GT 0/1 +1 800 . A G 100 PASS . GT 0/1 +1 900 . A G 100 PASS . GT 0/1 +1 1000 . A G 100 PASS . GT 0/1 +1 1100 . A G 100 PASS . GT 0/1 +1 1200 . A G 100 PASS . GT 0/1 +1 1300 . A G 100 PASS . GT 0/1 +1 1400 . A G 100 PASS . GT 0/1 +1 1500 . A G 100 PASS . GT 0/1 +1 1600 . A G 100 PASS . GT 0/1 +1 1700 . A G 100 PASS . GT 0/1 +1 1800 . A G 100 PASS . GT 0/1 +1 1900 . A G 100 PASS . GT 0/1 +1 2000 . A G 100 PASS . GT 0/1 +1 2100 . A G 100 PASS . GT 0/1 +1 2200 . A G 100 PASS . GT 0/1 +1 2300 . A G 100 PASS . GT 0/1 +1 2400 . A G 100 PASS . GT 0/1 +1 2500 . A G 100 PASS . GT 0/1 +1 2600 . A G 100 PASS . GT 0/1 +1 2700 . A G 100 PASS . GT 0/1 +1 2800 . A G 100 PASS . GT 0/1 +1 2900 . A G 100 PASS . GT 0/1 +1 3000 . A G 100 PASS . GT 0/1 +1 3100 . A G 100 PASS . GT 0/1 +1 3200 . A G 100 PASS . GT 0/1 +1 3300 . A G 100 PASS . GT 0/1 +1 3400 . A G 100 PASS . GT 0/1 +1 3500 . A G 100 PASS . GT 0/1 +1 3600 . A G 100 PASS . GT 0/1 +1 3700 . A G 100 PASS . GT 0/1 +1 3800 . A G 100 PASS . GT 0/1 +1 3900 . A G 100 PASS . GT 0/1 +1 4000 . A G 100 PASS . GT 0/1 +1 4100 . A G 100 PASS . GT 0/1 +1 4200 . A G 100 PASS . GT 0/1 +1 4300 . A G 100 PASS . GT 0/1 +1 4400 . A G 100 PASS . GT 0/1 +1 4500 . A G 100 PASS . GT 0/1 +1 4600 . A G 100 PASS . GT 0/1 +1 4700 . A G 100 PASS . GT 0/1 +1 4800 . A G 100 PASS . GT 0/1 +1 4900 . A G 100 PASS . GT 0/1 +1 5000 . A G 100 PASS . GT 0/1 +1 5100 . A G 100 PASS . GT 0/1 +1 5200 . A G 100 PASS . GT 0/1 +1 5300 . A G 100 PASS . GT 0/1 +1 5400 . A G 100 PASS . GT 0/1 +1 5500 . A G 100 PASS . GT 0/1 +1 5600 . A G 100 PASS . GT 0/1 +1 5700 . A G 100 PASS . GT 0/1 +1 5800 . A G 100 PASS . GT 0/1 +1 5900 . A G 100 PASS . GT 0/1 +1 6000 . A G 100 PASS . GT 0/1 +1 6100 . A G 100 PASS . GT 0/1 +1 6200 . A G 100 PASS . GT 0/1 +1 6300 . A G 100 PASS . GT 0/1 +1 6400 . A G 100 PASS . GT 0/1 +1 6500 . A G 100 PASS . GT 0/1 +1 6600 . A G 100 PASS . GT 0/1 +1 6700 . A G 100 PASS . GT 0/1 +1 6800 . A G 100 PASS . GT 0/1 +1 6900 . A G 100 PASS . GT 0/1 +1 7000 . A G 100 PASS . GT 0/1 +1 7100 . A G 100 PASS . GT 0/1 +1 7200 . A G 100 PASS . GT 0/1 +1 7300 . A G 100 PASS . GT 0/1 +1 7400 . A G 100 PASS . GT 0/1 +1 7500 . A G 100 PASS . GT 0/1 +1 7600 . A G 100 PASS . GT 0/1 +1 7700 . A G 100 PASS . GT 0/1 +1 7800 . A G 100 PASS . GT 0/1 +1 7900 . A G 100 PASS . GT 0/1 +1 8000 . A G 100 PASS . GT 0/1 +1 8100 . A G 100 PASS . GT 0/1 +1 8200 . A G 100 PASS . GT 0/1 +1 8300 . A G 100 PASS . GT 0/1 +1 8400 . A G 100 PASS . GT 0/1 +1 8500 . A G 100 PASS . GT 0/1 +1 8600 . A G 100 PASS . GT 0/1 +1 8700 . A G 100 PASS . GT 0/1 +1 8800 . A G 100 PASS . GT 0/1 +1 8900 . A G 100 PASS . GT 0/1 +1 9000 . A G 100 PASS . GT 0/1 +1 9100 . A G 100 PASS . GT 0/1 +1 9200 . A G 100 PASS . GT 0/1 +1 9300 . A G 100 PASS . GT 0/1 +1 9400 . A G 100 PASS . GT 0/1 +1 9500 . A G 100 PASS . GT 0/1 +1 9600 . A G 100 PASS . GT 0/1 +1 9700 . A G 100 PASS . GT 0/1 +1 9800 . A G 100 PASS . GT 0/1 +1 9900 . A G 100 PASS . GT 0/1 +1 10000 . A G 100 PASS . GT 0/1 +2 100 . A G 100 PASS . GT 0/1 +2 200 . A G 100 PASS . GT 0/1 +2 300 . A G 100 PASS . GT 0/1 +2 400 . A G 100 PASS . GT 0/1 +2 500 . A G 100 PASS . GT 0/1 +2 600 . A G 100 PASS . GT 0/1 +2 700 . A G 100 PASS . GT 0/1 +2 800 . A G 100 PASS . GT 0/1 +2 900 . A G 100 PASS . GT 0/1 +2 1000 . A G 100 PASS . GT 0/1 +2 1100 . A G 100 PASS . GT 0/1 +2 1200 . A G 100 PASS . GT 0/1 +2 1300 . A G 100 PASS . GT 0/1 +2 1400 . A G 100 PASS . GT 0/1 +2 1500 . A G 100 PASS . GT 0/1 +2 1600 . A G 100 PASS . GT 0/1 +2 1700 . A G 100 PASS . GT 0/1 +2 1800 . A G 100 PASS . GT 0/1 +2 1900 . A G 100 PASS . GT 0/1 +2 2000 . A G 100 PASS . GT 0/1 +2 2100 . A G 100 PASS . GT 0/1 +2 2200 . A G 100 PASS . GT 0/1 +2 2300 . A G 100 PASS . GT 0/1 +2 2400 . A G 100 PASS . GT 0/1 +2 2500 . A G 100 PASS . GT 0/1 +2 2600 . A G 100 PASS . GT 0/1 +2 2700 . A G 100 PASS . GT 0/1 +2 2800 . A G 100 PASS . GT 0/1 +2 2900 . A G 100 PASS . GT 0/1 +2 3000 . A G 100 PASS . GT 0/1 +2 3100 . A G 100 PASS . GT 0/1 +2 3200 . A G 100 PASS . GT 0/1 +2 3300 . A G 100 PASS . GT 0/1 +2 3400 . A G 100 PASS . GT 0/1 +2 3500 . A G 100 PASS . GT 0/1 +2 3600 . A G 100 PASS . GT 0/1 +2 3700 . A G 100 PASS . GT 0/1 +2 3800 . A G 100 PASS . GT 0/1 +2 3900 . A G 100 PASS . GT 0/1 +2 4000 . A G 100 PASS . GT 0/1 +2 4100 . A G 100 PASS . GT 0/1 +2 4200 . A G 100 PASS . GT 0/1 +2 4300 . A G 100 PASS . GT 0/1 +2 4400 . A G 100 PASS . GT 0/1 +2 4500 . A G 100 PASS . GT 0/1 +2 4600 . A G 100 PASS . GT 0/1 +2 4700 . A G 100 PASS . GT 0/1 +2 4800 . A G 100 PASS . GT 0/1 +2 4900 . A G 100 PASS . GT 0/1 +2 5000 . A G 100 PASS . GT 0/1 +2 5100 . A G 100 PASS . GT 0/1 +2 5200 . A G 100 PASS . GT 0/1 +2 5300 . A G 100 PASS . GT 0/1 +2 5400 . A G 100 PASS . GT 0/1 +2 5500 . A G 100 PASS . GT 0/1 +2 5600 . A G 100 PASS . GT 0/1 +2 5700 . A G 100 PASS . GT 0/1 +2 5800 . A G 100 PASS . GT 0/1 +2 5900 . A G 100 PASS . GT 0/1 +2 6000 . A G 100 PASS . GT 0/1 +2 6100 . A G 100 PASS . GT 0/1 +2 6200 . A G 100 PASS . GT 0/1 +2 6300 . A G 100 PASS . GT 0/1 +2 6400 . A G 100 PASS . GT 0/1 +2 6500 . A G 100 PASS . GT 0/1 +2 6600 . A G 100 PASS . GT 0/1 +2 6700 . A G 100 PASS . GT 0/1 +2 6800 . A G 100 PASS . GT 0/1 +2 6900 . A G 100 PASS . GT 0/1 +2 7000 . A G 100 PASS . GT 0/1 +2 7100 . A G 100 PASS . GT 0/1 +2 7200 . A G 100 PASS . GT 0/1 +2 7300 . A G 100 PASS . GT 0/1 +2 7400 . A G 100 PASS . GT 0/1 +2 7500 . A G 100 PASS . GT 0/1 +2 7600 . A G 100 PASS . GT 0/1 +2 7700 . A G 100 PASS . GT 0/1 +2 7800 . A G 100 PASS . GT 0/1 +2 7900 . A G 100 PASS . GT 0/1 +2 8000 . A G 100 PASS . GT 0/1 +2 8100 . A G 100 PASS . GT 0/1 +2 8200 . A G 100 PASS . GT 0/1 +2 8300 . A G 100 PASS . GT 0/1 +2 8400 . A G 100 PASS . GT 0/1 +2 8500 . A G 100 PASS . GT 0/1 +2 8600 . A G 100 PASS . GT 0/1 +2 8700 . A G 100 PASS . GT 0/1 +2 8800 . A G 100 PASS . GT 0/1 +2 8900 . A G 100 PASS . GT 0/1 +2 9000 . A G 100 PASS . GT 0/1 +2 9100 . A G 100 PASS . GT 0/1 +2 9200 . A G 100 PASS . GT 0/1 +2 9300 . A G 100 PASS . GT 0/1 +2 9400 . A G 100 PASS . GT 0/1 +2 9500 . A G 100 PASS . GT 0/1 +2 9600 . A G 100 PASS . GT 0/1 +2 9700 . A G 100 PASS . GT 0/1 +2 9800 . A G 100 PASS . GT 0/1 +2 9900 . A G 100 PASS . GT 0/1 +2 10000 . A G 100 PASS . GT 0/1 +3 100 . A G 100 PASS . GT 0/1 +3 200 . A G 100 PASS . GT 0/1 +3 300 . A G 100 PASS . GT 0/1 +3 400 . A G 100 PASS . GT 0/1 +3 500 . A G 100 PASS . GT 0/1 +3 600 . A G 100 PASS . GT 0/1 +3 700 . A G 100 PASS . GT 0/1 +3 800 . A G 100 PASS . GT 0/1 +3 900 . A G 100 PASS . GT 0/1 +3 1000 . A G 100 PASS . GT 0/1 +3 1100 . A G 100 PASS . GT 0/1 +3 1200 . A G 100 PASS . GT 0/1 +3 1300 . A G 100 PASS . GT 0/1 +3 1400 . A G 100 PASS . GT 0/1 +3 1500 . A G 100 PASS . GT 0/1 +3 1600 . A G 100 PASS . GT 0/1 +3 1700 . A G 100 PASS . GT 0/1 +3 1800 . A G 100 PASS . GT 0/1 +3 1900 . A G 100 PASS . GT 0/1 +3 2000 . A G 100 PASS . GT 0/1 +3 2100 . A G 100 PASS . GT 0/1 +3 2200 . A G 100 PASS . GT 0/1 +3 2300 . A G 100 PASS . GT 0/1 +3 2400 . A G 100 PASS . GT 0/1 +3 2500 . A G 100 PASS . GT 0/1 +3 2600 . A G 100 PASS . GT 0/1 +3 2700 . A G 100 PASS . GT 0/1 +3 2800 . A G 100 PASS . GT 0/1 +3 2900 . A G 100 PASS . GT 0/1 +3 3000 . A G 100 PASS . GT 0/1 +3 3100 . A G 100 PASS . GT 0/1 +3 3200 . A G 100 PASS . GT 0/1 +3 3300 . A G 100 PASS . GT 0/1 +3 3400 . A G 100 PASS . GT 0/1 +3 3500 . A G 100 PASS . GT 0/1 +3 3600 . A G 100 PASS . GT 0/1 +3 3700 . A G 100 PASS . GT 0/1 +3 3800 . A G 100 PASS . GT 0/1 +3 3900 . A G 100 PASS . GT 0/1 +3 4000 . A G 100 PASS . GT 0/1 +3 4100 . A G 100 PASS . GT 0/1 +3 4200 . A G 100 PASS . GT 0/1 +3 4300 . A G 100 PASS . GT 0/1 +3 4400 . A G 100 PASS . GT 0/1 +3 4500 . A G 100 PASS . GT 0/1 +3 4600 . A G 100 PASS . GT 0/1 +3 4700 . A G 100 PASS . GT 0/1 +3 4800 . A G 100 PASS . GT 0/1 +3 4900 . A G 100 PASS . GT 0/1 +3 5000 . A G 100 PASS . GT 0/1 +3 5100 . A G 100 PASS . GT 0/1 +3 5200 . A G 100 PASS . GT 0/1 +3 5300 . A G 100 PASS . GT 0/1 +3 5400 . A G 100 PASS . GT 0/1 +3 5500 . A G 100 PASS . GT 0/1 +3 5600 . A G 100 PASS . GT 0/1 +3 5700 . A G 100 PASS . GT 0/1 +3 5800 . A G 100 PASS . GT 0/1 +3 5900 . A G 100 PASS . GT 0/1 +3 6000 . A G 100 PASS . GT 0/1 +3 6100 . A G 100 PASS . GT 0/1 +3 6200 . A G 100 PASS . GT 0/1 +3 6300 . A G 100 PASS . GT 0/1 +3 6400 . A G 100 PASS . GT 0/1 +3 6500 . A G 100 PASS . GT 0/1 +3 6600 . A G 100 PASS . GT 0/1 +3 6700 . A G 100 PASS . GT 0/1 +3 6800 . A G 100 PASS . GT 0/1 +3 6900 . A G 100 PASS . GT 0/1 +3 7000 . A G 100 PASS . GT 0/1 +3 7100 . A G 100 PASS . GT 0/1 +3 7200 . A G 100 PASS . GT 0/1 +3 7300 . A G 100 PASS . GT 0/1 +3 7400 . A G 100 PASS . GT 0/1 +3 7500 . A G 100 PASS . GT 0/1 +3 7600 . A G 100 PASS . GT 0/1 +3 7700 . A G 100 PASS . GT 0/1 +3 7800 . A G 100 PASS . GT 0/1 +3 7900 . A G 100 PASS . GT 0/1 +3 8000 . A G 100 PASS . GT 0/1 +3 8100 . A G 100 PASS . GT 0/1 +3 8200 . A G 100 PASS . GT 0/1 +3 8300 . A G 100 PASS . GT 0/1 +3 8400 . A G 100 PASS . GT 0/1 +3 8500 . A G 100 PASS . GT 0/1 +3 8600 . A G 100 PASS . GT 0/1 +3 8700 . A G 100 PASS . GT 0/1 +3 8800 . A G 100 PASS . GT 0/1 +3 8900 . A G 100 PASS . GT 0/1 +3 9000 . A G 100 PASS . GT 0/1 +3 9100 . A G 100 PASS . GT 0/1 +3 9200 . A G 100 PASS . GT 0/1 +3 9300 . A G 100 PASS . GT 0/1 +3 9400 . A G 100 PASS . GT 0/1 +3 9500 . A G 100 PASS . GT 0/1 +3 9600 . A G 100 PASS . GT 0/1 +3 9700 . A G 100 PASS . GT 0/1 +3 9800 . A G 100 PASS . GT 0/1 +3 9900 . A G 100 PASS . GT 0/1 +3 10000 . A G 100 PASS . GT 0/1 diff --git a/test/regions-fastpath.vcf b/test/regions-fastpath.vcf new file mode 100644 index 000000000..39f2b044a --- /dev/null +++ b/test/regions-fastpath.vcf @@ -0,0 +1,606 @@ +##fileformat=VCFv4.2 +##contig= +##contig= +##contig= +##FORMAT= +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT S1 +1 100 . A G 100 PASS . GT 0/1 +1 150 . A G 100 PASS . GT 0/1 +1 200 . A G 100 PASS . GT 0/1 +1 250 . A G 100 PASS . GT 0/1 +1 300 . A G 100 PASS . GT 0/1 +1 350 . A G 100 PASS . GT 0/1 +1 400 . A G 100 PASS . GT 0/1 +1 450 . A G 100 PASS . GT 0/1 +1 500 . A G 100 PASS . GT 0/1 +1 550 . A G 100 PASS . GT 0/1 +1 600 . A G 100 PASS . GT 0/1 +1 650 . A G 100 PASS . GT 0/1 +1 700 . A G 100 PASS . GT 0/1 +1 750 . A G 100 PASS . GT 0/1 +1 800 . A G 100 PASS . GT 0/1 +1 850 . A G 100 PASS . GT 0/1 +1 900 . A G 100 PASS . GT 0/1 +1 950 . A G 100 PASS . GT 0/1 +1 1000 . A G 100 PASS . GT 0/1 +1 1050 . A G 100 PASS . GT 0/1 +1 1100 . A G 100 PASS . GT 0/1 +1 1150 . A G 100 PASS . GT 0/1 +1 1200 . A G 100 PASS . GT 0/1 +1 1250 . A G 100 PASS . GT 0/1 +1 1300 . A G 100 PASS . GT 0/1 +1 1350 . A G 100 PASS . GT 0/1 +1 1400 . A G 100 PASS . GT 0/1 +1 1450 . A G 100 PASS . GT 0/1 +1 1500 . A G 100 PASS . GT 0/1 +1 1550 . A G 100 PASS . GT 0/1 +1 1600 . A G 100 PASS . GT 0/1 +1 1650 . A G 100 PASS . GT 0/1 +1 1700 . A G 100 PASS . GT 0/1 +1 1750 . A G 100 PASS . GT 0/1 +1 1800 . A G 100 PASS . GT 0/1 +1 1850 . A G 100 PASS . GT 0/1 +1 1900 . A G 100 PASS . GT 0/1 +1 1950 . A G 100 PASS . GT 0/1 +1 2000 . A G 100 PASS . GT 0/1 +1 2050 . A G 100 PASS . GT 0/1 +1 2100 . A G 100 PASS . GT 0/1 +1 2150 . A G 100 PASS . GT 0/1 +1 2200 . A G 100 PASS . GT 0/1 +1 2250 . A G 100 PASS . GT 0/1 +1 2300 . A G 100 PASS . GT 0/1 +1 2350 . A G 100 PASS . GT 0/1 +1 2400 . A G 100 PASS . GT 0/1 +1 2450 . A G 100 PASS . GT 0/1 +1 2500 . A G 100 PASS . GT 0/1 +1 2550 . A G 100 PASS . GT 0/1 +1 2600 . A G 100 PASS . GT 0/1 +1 2650 . A G 100 PASS . GT 0/1 +1 2700 . A G 100 PASS . GT 0/1 +1 2750 . A G 100 PASS . GT 0/1 +1 2800 . A G 100 PASS . GT 0/1 +1 2850 . A G 100 PASS . GT 0/1 +1 2900 . A G 100 PASS . GT 0/1 +1 2950 . A G 100 PASS . GT 0/1 +1 3000 . A G 100 PASS . GT 0/1 +1 3050 . A G 100 PASS . GT 0/1 +1 3100 . A G 100 PASS . GT 0/1 +1 3150 . A G 100 PASS . GT 0/1 +1 3200 . A G 100 PASS . GT 0/1 +1 3250 . A G 100 PASS . GT 0/1 +1 3300 . A G 100 PASS . GT 0/1 +1 3350 . A G 100 PASS . GT 0/1 +1 3400 . A G 100 PASS . GT 0/1 +1 3450 . A G 100 PASS . GT 0/1 +1 3500 . A G 100 PASS . GT 0/1 +1 3550 . A G 100 PASS . GT 0/1 +1 3600 . A G 100 PASS . GT 0/1 +1 3650 . A G 100 PASS . GT 0/1 +1 3700 . A G 100 PASS . GT 0/1 +1 3750 . A G 100 PASS . GT 0/1 +1 3800 . A G 100 PASS . GT 0/1 +1 3850 . A G 100 PASS . GT 0/1 +1 3900 . A G 100 PASS . GT 0/1 +1 3950 . A G 100 PASS . GT 0/1 +1 4000 . A G 100 PASS . GT 0/1 +1 4050 . A G 100 PASS . GT 0/1 +1 4100 . A G 100 PASS . GT 0/1 +1 4150 . A G 100 PASS . GT 0/1 +1 4200 . A G 100 PASS . GT 0/1 +1 4250 . A G 100 PASS . GT 0/1 +1 4300 . A G 100 PASS . GT 0/1 +1 4350 . A G 100 PASS . GT 0/1 +1 4400 . A G 100 PASS . GT 0/1 +1 4450 . A G 100 PASS . GT 0/1 +1 4500 . A G 100 PASS . GT 0/1 +1 4550 . A G 100 PASS . GT 0/1 +1 4600 . A G 100 PASS . GT 0/1 +1 4650 . A G 100 PASS . GT 0/1 +1 4700 . A G 100 PASS . GT 0/1 +1 4750 . A G 100 PASS . GT 0/1 +1 4800 . A G 100 PASS . GT 0/1 +1 4850 . A G 100 PASS . GT 0/1 +1 4900 . A G 100 PASS . GT 0/1 +1 4950 . A G 100 PASS . GT 0/1 +1 5000 . A G 100 PASS . GT 0/1 +1 5050 . A G 100 PASS . GT 0/1 +1 5100 . A G 100 PASS . GT 0/1 +1 5150 . A G 100 PASS . GT 0/1 +1 5200 . A G 100 PASS . GT 0/1 +1 5250 . A G 100 PASS . GT 0/1 +1 5300 . A G 100 PASS . GT 0/1 +1 5350 . A G 100 PASS . GT 0/1 +1 5400 . A G 100 PASS . GT 0/1 +1 5450 . A G 100 PASS . GT 0/1 +1 5500 . A G 100 PASS . GT 0/1 +1 5550 . A G 100 PASS . GT 0/1 +1 5600 . A G 100 PASS . GT 0/1 +1 5650 . A G 100 PASS . GT 0/1 +1 5700 . A G 100 PASS . GT 0/1 +1 5750 . A G 100 PASS . GT 0/1 +1 5800 . A G 100 PASS . GT 0/1 +1 5850 . A G 100 PASS . GT 0/1 +1 5900 . A G 100 PASS . GT 0/1 +1 5950 . A G 100 PASS . GT 0/1 +1 6000 . A G 100 PASS . GT 0/1 +1 6050 . A G 100 PASS . GT 0/1 +1 6100 . A G 100 PASS . GT 0/1 +1 6150 . A G 100 PASS . GT 0/1 +1 6200 . A G 100 PASS . GT 0/1 +1 6250 . A G 100 PASS . GT 0/1 +1 6300 . A G 100 PASS . GT 0/1 +1 6350 . A G 100 PASS . GT 0/1 +1 6400 . A G 100 PASS . GT 0/1 +1 6450 . A G 100 PASS . GT 0/1 +1 6500 . A G 100 PASS . GT 0/1 +1 6550 . A G 100 PASS . GT 0/1 +1 6600 . A G 100 PASS . GT 0/1 +1 6650 . A G 100 PASS . GT 0/1 +1 6700 . A G 100 PASS . GT 0/1 +1 6750 . A G 100 PASS . GT 0/1 +1 6800 . A G 100 PASS . GT 0/1 +1 6850 . A G 100 PASS . GT 0/1 +1 6900 . A G 100 PASS . GT 0/1 +1 6950 . A G 100 PASS . GT 0/1 +1 7000 . A G 100 PASS . GT 0/1 +1 7050 . A G 100 PASS . GT 0/1 +1 7100 . A G 100 PASS . GT 0/1 +1 7150 . A G 100 PASS . GT 0/1 +1 7200 . A G 100 PASS . GT 0/1 +1 7250 . A G 100 PASS . GT 0/1 +1 7300 . A G 100 PASS . GT 0/1 +1 7350 . A G 100 PASS . GT 0/1 +1 7400 . A G 100 PASS . GT 0/1 +1 7450 . A G 100 PASS . GT 0/1 +1 7500 . A G 100 PASS . GT 0/1 +1 7550 . A G 100 PASS . GT 0/1 +1 7600 . A G 100 PASS . GT 0/1 +1 7650 . A G 100 PASS . GT 0/1 +1 7700 . A G 100 PASS . GT 0/1 +1 7750 . A G 100 PASS . GT 0/1 +1 7800 . A G 100 PASS . GT 0/1 +1 7850 . A G 100 PASS . GT 0/1 +1 7900 . A G 100 PASS . GT 0/1 +1 7950 . A G 100 PASS . GT 0/1 +1 8000 . A G 100 PASS . GT 0/1 +1 8050 . A G 100 PASS . GT 0/1 +1 8100 . A G 100 PASS . GT 0/1 +1 8150 . A G 100 PASS . GT 0/1 +1 8200 . A G 100 PASS . GT 0/1 +1 8250 . A G 100 PASS . GT 0/1 +1 8300 . A G 100 PASS . GT 0/1 +1 8350 . A G 100 PASS . GT 0/1 +1 8400 . A G 100 PASS . GT 0/1 +1 8450 . A G 100 PASS . GT 0/1 +1 8500 . A G 100 PASS . GT 0/1 +1 8550 . A G 100 PASS . GT 0/1 +1 8600 . A G 100 PASS . GT 0/1 +1 8650 . A G 100 PASS . GT 0/1 +1 8700 . A G 100 PASS . GT 0/1 +1 8750 . A G 100 PASS . GT 0/1 +1 8800 . A G 100 PASS . GT 0/1 +1 8850 . A G 100 PASS . GT 0/1 +1 8900 . A G 100 PASS . GT 0/1 +1 8950 . A G 100 PASS . GT 0/1 +1 9000 . A G 100 PASS . GT 0/1 +1 9050 . A G 100 PASS . GT 0/1 +1 9100 . A G 100 PASS . GT 0/1 +1 9150 . A G 100 PASS . GT 0/1 +1 9200 . A G 100 PASS . GT 0/1 +1 9250 . A G 100 PASS . GT 0/1 +1 9300 . A G 100 PASS . GT 0/1 +1 9350 . A G 100 PASS . GT 0/1 +1 9400 . A G 100 PASS . GT 0/1 +1 9450 . A G 100 PASS . GT 0/1 +1 9500 . A G 100 PASS . GT 0/1 +1 9550 . A G 100 PASS . GT 0/1 +1 9600 . A G 100 PASS . GT 0/1 +1 9650 . A G 100 PASS . GT 0/1 +1 9700 . A G 100 PASS . GT 0/1 +1 9750 . A G 100 PASS . GT 0/1 +1 9800 . A G 100 PASS . GT 0/1 +1 9850 . A G 100 PASS . GT 0/1 +1 9900 . A G 100 PASS . GT 0/1 +1 9950 . A G 100 PASS . GT 0/1 +1 10000 . A G 100 PASS . GT 0/1 +1 10050 . A G 100 PASS . GT 0/1 +2 100 . A G 100 PASS . GT 0/1 +2 150 . A G 100 PASS . GT 0/1 +2 200 . A G 100 PASS . GT 0/1 +2 250 . A G 100 PASS . GT 0/1 +2 300 . A G 100 PASS . GT 0/1 +2 350 . A G 100 PASS . GT 0/1 +2 400 . A G 100 PASS . GT 0/1 +2 450 . A G 100 PASS . GT 0/1 +2 500 . A G 100 PASS . GT 0/1 +2 550 . A G 100 PASS . GT 0/1 +2 600 . A G 100 PASS . GT 0/1 +2 650 . A G 100 PASS . GT 0/1 +2 700 . A G 100 PASS . GT 0/1 +2 750 . A G 100 PASS . GT 0/1 +2 800 . A G 100 PASS . GT 0/1 +2 850 . A G 100 PASS . GT 0/1 +2 900 . A G 100 PASS . GT 0/1 +2 950 . A G 100 PASS . GT 0/1 +2 1000 . A G 100 PASS . GT 0/1 +2 1050 . A G 100 PASS . GT 0/1 +2 1100 . A G 100 PASS . GT 0/1 +2 1150 . A G 100 PASS . GT 0/1 +2 1200 . A G 100 PASS . GT 0/1 +2 1250 . A G 100 PASS . GT 0/1 +2 1300 . A G 100 PASS . GT 0/1 +2 1350 . A G 100 PASS . GT 0/1 +2 1400 . A G 100 PASS . GT 0/1 +2 1450 . A G 100 PASS . GT 0/1 +2 1500 . A G 100 PASS . GT 0/1 +2 1550 . A G 100 PASS . GT 0/1 +2 1600 . A G 100 PASS . GT 0/1 +2 1650 . A G 100 PASS . GT 0/1 +2 1700 . A G 100 PASS . GT 0/1 +2 1750 . A G 100 PASS . GT 0/1 +2 1800 . A G 100 PASS . GT 0/1 +2 1850 . A G 100 PASS . GT 0/1 +2 1900 . A G 100 PASS . GT 0/1 +2 1950 . A G 100 PASS . GT 0/1 +2 2000 . A G 100 PASS . GT 0/1 +2 2050 . A G 100 PASS . GT 0/1 +2 2100 . A G 100 PASS . GT 0/1 +2 2150 . A G 100 PASS . GT 0/1 +2 2200 . A G 100 PASS . GT 0/1 +2 2250 . A G 100 PASS . GT 0/1 +2 2300 . A G 100 PASS . GT 0/1 +2 2350 . A G 100 PASS . GT 0/1 +2 2400 . A G 100 PASS . GT 0/1 +2 2450 . A G 100 PASS . GT 0/1 +2 2500 . A G 100 PASS . GT 0/1 +2 2550 . A G 100 PASS . GT 0/1 +2 2600 . A G 100 PASS . GT 0/1 +2 2650 . A G 100 PASS . GT 0/1 +2 2700 . A G 100 PASS . GT 0/1 +2 2750 . A G 100 PASS . GT 0/1 +2 2800 . A G 100 PASS . GT 0/1 +2 2850 . A G 100 PASS . GT 0/1 +2 2900 . A G 100 PASS . GT 0/1 +2 2950 . A G 100 PASS . GT 0/1 +2 3000 . A G 100 PASS . GT 0/1 +2 3050 . A G 100 PASS . GT 0/1 +2 3100 . A G 100 PASS . GT 0/1 +2 3150 . A G 100 PASS . GT 0/1 +2 3200 . A G 100 PASS . GT 0/1 +2 3250 . A G 100 PASS . GT 0/1 +2 3300 . A G 100 PASS . GT 0/1 +2 3350 . A G 100 PASS . GT 0/1 +2 3400 . A G 100 PASS . GT 0/1 +2 3450 . A G 100 PASS . GT 0/1 +2 3500 . A G 100 PASS . GT 0/1 +2 3550 . A G 100 PASS . GT 0/1 +2 3600 . A G 100 PASS . GT 0/1 +2 3650 . A G 100 PASS . GT 0/1 +2 3700 . A G 100 PASS . GT 0/1 +2 3750 . A G 100 PASS . GT 0/1 +2 3800 . A G 100 PASS . GT 0/1 +2 3850 . A G 100 PASS . GT 0/1 +2 3900 . A G 100 PASS . GT 0/1 +2 3950 . A G 100 PASS . GT 0/1 +2 4000 . A G 100 PASS . GT 0/1 +2 4050 . A G 100 PASS . GT 0/1 +2 4100 . A G 100 PASS . GT 0/1 +2 4150 . A G 100 PASS . GT 0/1 +2 4200 . A G 100 PASS . GT 0/1 +2 4250 . A G 100 PASS . GT 0/1 +2 4300 . A G 100 PASS . GT 0/1 +2 4350 . A G 100 PASS . GT 0/1 +2 4400 . A G 100 PASS . GT 0/1 +2 4450 . A G 100 PASS . GT 0/1 +2 4500 . A G 100 PASS . GT 0/1 +2 4550 . A G 100 PASS . GT 0/1 +2 4600 . A G 100 PASS . GT 0/1 +2 4650 . A G 100 PASS . GT 0/1 +2 4700 . A G 100 PASS . GT 0/1 +2 4750 . A G 100 PASS . GT 0/1 +2 4800 . A G 100 PASS . GT 0/1 +2 4850 . A G 100 PASS . GT 0/1 +2 4900 . A G 100 PASS . GT 0/1 +2 4950 . A G 100 PASS . GT 0/1 +2 5000 . A G 100 PASS . GT 0/1 +2 5050 . A G 100 PASS . GT 0/1 +2 5100 . A G 100 PASS . GT 0/1 +2 5150 . A G 100 PASS . GT 0/1 +2 5200 . A G 100 PASS . GT 0/1 +2 5250 . A G 100 PASS . GT 0/1 +2 5300 . A G 100 PASS . GT 0/1 +2 5350 . A G 100 PASS . GT 0/1 +2 5400 . A G 100 PASS . GT 0/1 +2 5450 . A G 100 PASS . GT 0/1 +2 5500 . A G 100 PASS . GT 0/1 +2 5550 . A G 100 PASS . GT 0/1 +2 5600 . A G 100 PASS . GT 0/1 +2 5650 . A G 100 PASS . GT 0/1 +2 5700 . A G 100 PASS . GT 0/1 +2 5750 . A G 100 PASS . GT 0/1 +2 5800 . A G 100 PASS . GT 0/1 +2 5850 . A G 100 PASS . GT 0/1 +2 5900 . A G 100 PASS . GT 0/1 +2 5950 . A G 100 PASS . GT 0/1 +2 6000 . A G 100 PASS . GT 0/1 +2 6050 . A G 100 PASS . GT 0/1 +2 6100 . A G 100 PASS . GT 0/1 +2 6150 . A G 100 PASS . GT 0/1 +2 6200 . A G 100 PASS . GT 0/1 +2 6250 . A G 100 PASS . GT 0/1 +2 6300 . A G 100 PASS . GT 0/1 +2 6350 . A G 100 PASS . GT 0/1 +2 6400 . A G 100 PASS . GT 0/1 +2 6450 . A G 100 PASS . GT 0/1 +2 6500 . A G 100 PASS . GT 0/1 +2 6550 . A G 100 PASS . GT 0/1 +2 6600 . A G 100 PASS . GT 0/1 +2 6650 . A G 100 PASS . GT 0/1 +2 6700 . A G 100 PASS . GT 0/1 +2 6750 . A G 100 PASS . GT 0/1 +2 6800 . A G 100 PASS . GT 0/1 +2 6850 . A G 100 PASS . GT 0/1 +2 6900 . A G 100 PASS . GT 0/1 +2 6950 . A G 100 PASS . GT 0/1 +2 7000 . A G 100 PASS . GT 0/1 +2 7050 . A G 100 PASS . GT 0/1 +2 7100 . A G 100 PASS . GT 0/1 +2 7150 . A G 100 PASS . GT 0/1 +2 7200 . A G 100 PASS . GT 0/1 +2 7250 . A G 100 PASS . GT 0/1 +2 7300 . A G 100 PASS . GT 0/1 +2 7350 . A G 100 PASS . GT 0/1 +2 7400 . A G 100 PASS . GT 0/1 +2 7450 . A G 100 PASS . GT 0/1 +2 7500 . A G 100 PASS . GT 0/1 +2 7550 . A G 100 PASS . GT 0/1 +2 7600 . A G 100 PASS . GT 0/1 +2 7650 . A G 100 PASS . GT 0/1 +2 7700 . A G 100 PASS . GT 0/1 +2 7750 . A G 100 PASS . GT 0/1 +2 7800 . A G 100 PASS . GT 0/1 +2 7850 . A G 100 PASS . GT 0/1 +2 7900 . A G 100 PASS . GT 0/1 +2 7950 . A G 100 PASS . GT 0/1 +2 8000 . A G 100 PASS . GT 0/1 +2 8050 . A G 100 PASS . GT 0/1 +2 8100 . A G 100 PASS . GT 0/1 +2 8150 . A G 100 PASS . GT 0/1 +2 8200 . A G 100 PASS . GT 0/1 +2 8250 . A G 100 PASS . GT 0/1 +2 8300 . A G 100 PASS . GT 0/1 +2 8350 . A G 100 PASS . GT 0/1 +2 8400 . A G 100 PASS . GT 0/1 +2 8450 . A G 100 PASS . GT 0/1 +2 8500 . A G 100 PASS . GT 0/1 +2 8550 . A G 100 PASS . GT 0/1 +2 8600 . A G 100 PASS . GT 0/1 +2 8650 . A G 100 PASS . GT 0/1 +2 8700 . A G 100 PASS . GT 0/1 +2 8750 . A G 100 PASS . GT 0/1 +2 8800 . A G 100 PASS . GT 0/1 +2 8850 . A G 100 PASS . GT 0/1 +2 8900 . A G 100 PASS . GT 0/1 +2 8950 . A G 100 PASS . GT 0/1 +2 9000 . A G 100 PASS . GT 0/1 +2 9050 . A G 100 PASS . GT 0/1 +2 9100 . A G 100 PASS . GT 0/1 +2 9150 . A G 100 PASS . GT 0/1 +2 9200 . A G 100 PASS . GT 0/1 +2 9250 . A G 100 PASS . GT 0/1 +2 9300 . A G 100 PASS . GT 0/1 +2 9350 . A G 100 PASS . GT 0/1 +2 9400 . A G 100 PASS . GT 0/1 +2 9450 . A G 100 PASS . GT 0/1 +2 9500 . A G 100 PASS . GT 0/1 +2 9550 . A G 100 PASS . GT 0/1 +2 9600 . A G 100 PASS . GT 0/1 +2 9650 . A G 100 PASS . GT 0/1 +2 9700 . A G 100 PASS . GT 0/1 +2 9750 . A G 100 PASS . GT 0/1 +2 9800 . A G 100 PASS . GT 0/1 +2 9850 . A G 100 PASS . GT 0/1 +2 9900 . A G 100 PASS . GT 0/1 +2 9950 . A G 100 PASS . GT 0/1 +2 10000 . A G 100 PASS . GT 0/1 +2 10050 . A G 100 PASS . GT 0/1 +3 100 . A G 100 PASS . GT 0/1 +3 150 . A G 100 PASS . GT 0/1 +3 200 . A G 100 PASS . GT 0/1 +3 250 . A G 100 PASS . GT 0/1 +3 300 . A G 100 PASS . GT 0/1 +3 350 . A G 100 PASS . GT 0/1 +3 400 . A G 100 PASS . GT 0/1 +3 450 . A G 100 PASS . GT 0/1 +3 500 . A G 100 PASS . GT 0/1 +3 550 . A G 100 PASS . GT 0/1 +3 600 . A G 100 PASS . GT 0/1 +3 650 . A G 100 PASS . GT 0/1 +3 700 . A G 100 PASS . GT 0/1 +3 750 . A G 100 PASS . GT 0/1 +3 800 . A G 100 PASS . GT 0/1 +3 850 . A G 100 PASS . GT 0/1 +3 900 . A G 100 PASS . GT 0/1 +3 950 . A G 100 PASS . GT 0/1 +3 1000 . A G 100 PASS . GT 0/1 +3 1050 . A G 100 PASS . GT 0/1 +3 1100 . A G 100 PASS . GT 0/1 +3 1150 . A G 100 PASS . GT 0/1 +3 1200 . A G 100 PASS . GT 0/1 +3 1250 . A G 100 PASS . GT 0/1 +3 1300 . A G 100 PASS . GT 0/1 +3 1350 . A G 100 PASS . GT 0/1 +3 1400 . A G 100 PASS . GT 0/1 +3 1450 . A G 100 PASS . GT 0/1 +3 1500 . A G 100 PASS . GT 0/1 +3 1550 . A G 100 PASS . GT 0/1 +3 1600 . A G 100 PASS . GT 0/1 +3 1650 . A G 100 PASS . GT 0/1 +3 1700 . A G 100 PASS . GT 0/1 +3 1750 . A G 100 PASS . GT 0/1 +3 1800 . A G 100 PASS . GT 0/1 +3 1850 . A G 100 PASS . GT 0/1 +3 1900 . A G 100 PASS . GT 0/1 +3 1950 . A G 100 PASS . GT 0/1 +3 2000 . A G 100 PASS . GT 0/1 +3 2050 . A G 100 PASS . GT 0/1 +3 2100 . A G 100 PASS . GT 0/1 +3 2150 . A G 100 PASS . GT 0/1 +3 2200 . A G 100 PASS . GT 0/1 +3 2250 . A G 100 PASS . GT 0/1 +3 2300 . A G 100 PASS . GT 0/1 +3 2350 . A G 100 PASS . GT 0/1 +3 2400 . A G 100 PASS . GT 0/1 +3 2450 . A G 100 PASS . GT 0/1 +3 2500 . A G 100 PASS . GT 0/1 +3 2550 . A G 100 PASS . GT 0/1 +3 2600 . A G 100 PASS . GT 0/1 +3 2650 . A G 100 PASS . GT 0/1 +3 2700 . A G 100 PASS . GT 0/1 +3 2750 . A G 100 PASS . GT 0/1 +3 2800 . A G 100 PASS . GT 0/1 +3 2850 . A G 100 PASS . GT 0/1 +3 2900 . A G 100 PASS . GT 0/1 +3 2950 . A G 100 PASS . GT 0/1 +3 3000 . A G 100 PASS . GT 0/1 +3 3050 . A G 100 PASS . GT 0/1 +3 3100 . A G 100 PASS . GT 0/1 +3 3150 . A G 100 PASS . GT 0/1 +3 3200 . A G 100 PASS . GT 0/1 +3 3250 . A G 100 PASS . GT 0/1 +3 3300 . A G 100 PASS . GT 0/1 +3 3350 . A G 100 PASS . GT 0/1 +3 3400 . A G 100 PASS . GT 0/1 +3 3450 . A G 100 PASS . GT 0/1 +3 3500 . A G 100 PASS . GT 0/1 +3 3550 . A G 100 PASS . GT 0/1 +3 3600 . A G 100 PASS . GT 0/1 +3 3650 . A G 100 PASS . GT 0/1 +3 3700 . A G 100 PASS . GT 0/1 +3 3750 . A G 100 PASS . GT 0/1 +3 3800 . A G 100 PASS . GT 0/1 +3 3850 . A G 100 PASS . GT 0/1 +3 3900 . A G 100 PASS . GT 0/1 +3 3950 . A G 100 PASS . GT 0/1 +3 4000 . A G 100 PASS . GT 0/1 +3 4050 . A G 100 PASS . GT 0/1 +3 4100 . A G 100 PASS . GT 0/1 +3 4150 . A G 100 PASS . GT 0/1 +3 4200 . A G 100 PASS . GT 0/1 +3 4250 . A G 100 PASS . GT 0/1 +3 4300 . A G 100 PASS . GT 0/1 +3 4350 . A G 100 PASS . GT 0/1 +3 4400 . A G 100 PASS . GT 0/1 +3 4450 . A G 100 PASS . GT 0/1 +3 4500 . A G 100 PASS . GT 0/1 +3 4550 . A G 100 PASS . GT 0/1 +3 4600 . A G 100 PASS . GT 0/1 +3 4650 . A G 100 PASS . GT 0/1 +3 4700 . A G 100 PASS . GT 0/1 +3 4750 . A G 100 PASS . GT 0/1 +3 4800 . A G 100 PASS . GT 0/1 +3 4850 . A G 100 PASS . GT 0/1 +3 4900 . A G 100 PASS . GT 0/1 +3 4950 . A G 100 PASS . GT 0/1 +3 5000 . A G 100 PASS . GT 0/1 +3 5050 . A G 100 PASS . GT 0/1 +3 5100 . A G 100 PASS . GT 0/1 +3 5150 . A G 100 PASS . GT 0/1 +3 5200 . A G 100 PASS . GT 0/1 +3 5250 . A G 100 PASS . GT 0/1 +3 5300 . A G 100 PASS . GT 0/1 +3 5350 . A G 100 PASS . GT 0/1 +3 5400 . A G 100 PASS . GT 0/1 +3 5450 . A G 100 PASS . GT 0/1 +3 5500 . A G 100 PASS . GT 0/1 +3 5550 . A G 100 PASS . GT 0/1 +3 5600 . A G 100 PASS . GT 0/1 +3 5650 . A G 100 PASS . GT 0/1 +3 5700 . A G 100 PASS . GT 0/1 +3 5750 . A G 100 PASS . GT 0/1 +3 5800 . A G 100 PASS . GT 0/1 +3 5850 . A G 100 PASS . GT 0/1 +3 5900 . A G 100 PASS . GT 0/1 +3 5950 . A G 100 PASS . GT 0/1 +3 6000 . A G 100 PASS . GT 0/1 +3 6050 . A G 100 PASS . GT 0/1 +3 6100 . A G 100 PASS . GT 0/1 +3 6150 . A G 100 PASS . GT 0/1 +3 6200 . A G 100 PASS . GT 0/1 +3 6250 . A G 100 PASS . GT 0/1 +3 6300 . A G 100 PASS . GT 0/1 +3 6350 . A G 100 PASS . GT 0/1 +3 6400 . A G 100 PASS . GT 0/1 +3 6450 . A G 100 PASS . GT 0/1 +3 6500 . A G 100 PASS . GT 0/1 +3 6550 . A G 100 PASS . GT 0/1 +3 6600 . A G 100 PASS . GT 0/1 +3 6650 . A G 100 PASS . GT 0/1 +3 6700 . A G 100 PASS . GT 0/1 +3 6750 . A G 100 PASS . GT 0/1 +3 6800 . A G 100 PASS . GT 0/1 +3 6850 . A G 100 PASS . GT 0/1 +3 6900 . A G 100 PASS . GT 0/1 +3 6950 . A G 100 PASS . GT 0/1 +3 7000 . A G 100 PASS . GT 0/1 +3 7050 . A G 100 PASS . GT 0/1 +3 7100 . A G 100 PASS . GT 0/1 +3 7150 . A G 100 PASS . GT 0/1 +3 7200 . A G 100 PASS . GT 0/1 +3 7250 . A G 100 PASS . GT 0/1 +3 7300 . A G 100 PASS . GT 0/1 +3 7350 . A G 100 PASS . GT 0/1 +3 7400 . A G 100 PASS . GT 0/1 +3 7450 . A G 100 PASS . GT 0/1 +3 7500 . A G 100 PASS . GT 0/1 +3 7550 . A G 100 PASS . GT 0/1 +3 7600 . A G 100 PASS . GT 0/1 +3 7650 . A G 100 PASS . GT 0/1 +3 7700 . A G 100 PASS . GT 0/1 +3 7750 . A G 100 PASS . GT 0/1 +3 7800 . A G 100 PASS . GT 0/1 +3 7850 . A G 100 PASS . GT 0/1 +3 7900 . A G 100 PASS . GT 0/1 +3 7950 . A G 100 PASS . GT 0/1 +3 8000 . A G 100 PASS . GT 0/1 +3 8050 . A G 100 PASS . GT 0/1 +3 8100 . A G 100 PASS . GT 0/1 +3 8150 . A G 100 PASS . GT 0/1 +3 8200 . A G 100 PASS . GT 0/1 +3 8250 . A G 100 PASS . GT 0/1 +3 8300 . A G 100 PASS . GT 0/1 +3 8350 . A G 100 PASS . GT 0/1 +3 8400 . A G 100 PASS . GT 0/1 +3 8450 . A G 100 PASS . GT 0/1 +3 8500 . A G 100 PASS . GT 0/1 +3 8550 . A G 100 PASS . GT 0/1 +3 8600 . A G 100 PASS . GT 0/1 +3 8650 . A G 100 PASS . GT 0/1 +3 8700 . A G 100 PASS . GT 0/1 +3 8750 . A G 100 PASS . GT 0/1 +3 8800 . A G 100 PASS . GT 0/1 +3 8850 . A G 100 PASS . GT 0/1 +3 8900 . A G 100 PASS . GT 0/1 +3 8950 . A G 100 PASS . GT 0/1 +3 9000 . A G 100 PASS . GT 0/1 +3 9050 . A G 100 PASS . GT 0/1 +3 9100 . A G 100 PASS . GT 0/1 +3 9150 . A G 100 PASS . GT 0/1 +3 9200 . A G 100 PASS . GT 0/1 +3 9250 . A G 100 PASS . GT 0/1 +3 9300 . A G 100 PASS . GT 0/1 +3 9350 . A G 100 PASS . GT 0/1 +3 9400 . A G 100 PASS . GT 0/1 +3 9450 . A G 100 PASS . GT 0/1 +3 9500 . A G 100 PASS . GT 0/1 +3 9550 . A G 100 PASS . GT 0/1 +3 9600 . A G 100 PASS . GT 0/1 +3 9650 . A G 100 PASS . GT 0/1 +3 9700 . A G 100 PASS . GT 0/1 +3 9750 . A G 100 PASS . GT 0/1 +3 9800 . A G 100 PASS . GT 0/1 +3 9850 . A G 100 PASS . GT 0/1 +3 9900 . A G 100 PASS . GT 0/1 +3 9950 . A G 100 PASS . GT 0/1 +3 10000 . A G 100 PASS . GT 0/1 +3 10050 . A G 100 PASS . GT 0/1 diff --git a/test/test.pl b/test/test.pl index f67c53f30..f16cd95ec 100755 --- a/test/test.pl +++ b/test/test.pl @@ -426,6 +426,12 @@ run_test(\&test_vcf_view,$opts,in=>'idx.4',out=>'idx.4.out',args=>q[-H -R {PATH}/idx.4.bed]); run_test(\&test_vcf_view,$opts,in=>'view-t',out=>'view-t.1.out',args=>'-Ht 2',reg=>''); run_test(\&test_vcf_view,$opts,in=>'view-t',out=>'view-t.2.out',args=>'-Ht 3',reg=>''); +# Regression for samtools/bcftools#2557. The fixture has 300 single-base +# BED entries (> htslib SNIFF_LINES=256) at dense ~100bp spacing, so the +# htslib sniffer accepts it and the opt routes -R FILE through the +# streaming-targets path. All three modes (fastpath, --no-regions-fastpath, +# -T) must produce the same expected output. +run_test(\&test_vcf_view_regions_fastpath,$opts,in=>'regions-fastpath',bed=>'regions-fastpath',out=>'regions-fastpath.out'); run_test(\&test_vcf_view,$opts,in=>'overlap',out=>'overlap.0.out',args=>q[-H -r chr1:100-200 --regions-overlap 0]); run_test(\&test_vcf_view,$opts,in=>'overlap',out=>'overlap.1.out',args=>q[-H -r chr1:100-200 --regions-overlap 1]); run_test(\&test_vcf_view,$opts,in=>'overlap',out=>'overlap.2.out',args=>q[-H -r chr1:100-200 --regions-overlap 2]); @@ -1701,6 +1707,25 @@ sub test_vcf_view test_cmd($opts,%args,cmd=>"$$opts{bin}/bcftools view -Ob $args{args} $$opts{tmp}/$args{in}.vcf.gz $args{reg} | $$opts{bin}/bcftools view | grep -v ^##bcftools_", exp_fix=>1); } } +sub test_vcf_view_regions_fastpath +{ + # Regression test for samtools/bcftools#2557. bcftools view -R FILE + # opts into BCF_SR_AUTO_TARGETS_FROM_REGIONS in htslib when no -T is + # given, which routes a dense single-base BED through the streaming- + # targets path (300x+ faster than per-region tabix seeks at panel + # sizes). All three modes must produce the same output: + # - fastpath (default, opt enabled, sniffer accepts the 300-entry BED) + # - slow path (--no-regions-fastpath; suppresses the opt) + # - -T FILE (control: existing streaming-targets path) + my ($opts,%args) = @_; + bgzip_tabix_vcf($opts, $args{in}); + bgzip_tabix($opts, file=>$args{bed}, suffix=>'bed'); + my $vcf = "$$opts{tmp}/$args{in}.vcf.gz"; + my $bed = "$$opts{tmp}/$args{bed}.bed.gz"; + test_cmd($opts,%args,cmd=>"$$opts{bin}/bcftools view --no-version -H -R $bed $vcf"); + test_cmd($opts,%args,cmd=>"$$opts{bin}/bcftools view --no-version -H -R $bed --no-regions-fastpath $vcf"); + test_cmd($opts,%args,cmd=>"$$opts{bin}/bcftools view --no-version -H -T $bed $vcf"); +} sub test_vcf_64bit { my ($opts,%args) = @_; diff --git a/vcfview.c b/vcfview.c index e830e96a1..6feb35385 100644 --- a/vcfview.c +++ b/vcfview.c @@ -67,6 +67,7 @@ typedef struct _args_t bcf_hdr_t *hdr, *hnull, *hsub; // original header, sites-only header, subset header char **argv, *format, *sample_names, *subset_fname, *targets_list, *regions_list; int regions_overlap, targets_overlap; + int regions_fastpath_disabled; // --no-regions-fastpath suppresses the htslib opt-in (#2557) int argc, clevel, n_threads, output_type, print_header, update_info, header_only, n_samples, *imap, calc_ac; int trim_alts, sites_only, known, novel, min_alleles, max_alleles, private_vars, uncalled, phased; int min_ac, min_ac_type, max_ac, max_ac_type, min_af_type, max_af_type, gt_type; @@ -521,6 +522,7 @@ static void usage(args_t *args) fprintf(stderr, " -r, --regions REGION Restrict to comma-separated list of regions\n"); fprintf(stderr, " -R, --regions-file FILE Restrict to regions listed in FILE\n"); fprintf(stderr, " --regions-overlap 0|1|2 Include if POS in the region (0), record overlaps (1), variant overlaps (2) [1]\n"); + fprintf(stderr, " --no-regions-fastpath Disable the dense-single-base BED auto-promotion (#2557); always index-jump\n"); fprintf(stderr, " -t, --targets [^]REGION Similar to -r but streams rather than index-jumps. Exclude regions with \"^\" prefix\n"); fprintf(stderr, " -T, --targets-file [^]FILE Similar to -R but streams rather than index-jumps. Exclude regions with \"^\" prefix\n"); fprintf(stderr, " --targets-overlap 0|1|2 Include if POS in the region (0), record overlaps (1), variant overlaps (2) [0]\n"); @@ -611,6 +613,7 @@ int main_vcfview(int argc, char *argv[]) {"regions",required_argument,NULL,'r'}, {"regions-file",required_argument,NULL,'R'}, {"regions-overlap",required_argument,NULL,3}, + {"no-regions-fastpath",no_argument,NULL,11}, {"min-ac",required_argument,NULL,'c'}, {"max-ac",required_argument,NULL,'C'}, {"min-af",required_argument,NULL,'q'}, @@ -755,6 +758,7 @@ int main_vcfview(int argc, char *argv[]) case 10 : if ( apply_verbosity(optarg) < 0 ) error("Could not parse argument: --verbosity %s\n", optarg); break; + case 11 : args->regions_fastpath_disabled = 1; break; case 'W': if (!(args->write_index = write_index_parse(optarg))) @@ -784,6 +788,15 @@ int main_vcfview(int argc, char *argv[]) if ( args->regions_list ) { bcf_sr_set_opt(args->files,BCF_SR_REGIONS_OVERLAP,args->regions_overlap); + // #2557: opt into the htslib dense-single-base auto-promotion when + // the regions are a file AND no -T is set (BCF_SR_AUTO_TARGETS_FROM_REGIONS + // populates readers->targets, which conflicts with a subsequent + // bcf_sr_set_targets() call). The htslib sniffer decides per-file + // whether the file actually qualifies for the streaming-targets path; + // sparse / small / wide BEDs fall back to the seek-per-region default. + // --no-regions-fastpath suppresses the opt unconditionally. + if ( regions_is_file && !args->targets_list && !args->regions_fastpath_disabled ) + bcf_sr_set_opt(args->files, BCF_SR_AUTO_TARGETS_FROM_REGIONS); if ( bcf_sr_set_regions(args->files, args->regions_list, regions_is_file)<0 ) error("Failed to read the regions: %s\n", args->regions_list); }