From 81257f317f978888d91bc63273f23e995f2388b9 Mon Sep 17 00:00:00 2001 From: Madhava Jay Date: Tue, 26 May 2026 14:06:22 +1000 Subject: [PATCH 1/2] adding bcf support --- rust/Cargo.lock | 13 + rust/Cargo.toml | 1 + rust/bioscript-cli/src/cli_bootstrap.rs | 5 +- rust/bioscript-cli/src/cli_commands.rs | 90 +++ rust/bioscript-cli/src/report_options.rs | 7 +- rust/bioscript-formats/Cargo.toml | 2 +- .../assets/liftover/hg19ToHg38.over.chain.gz | Bin 0 -> 227698 bytes rust/bioscript-formats/src/genotype.rs | 135 +++- .../src/genotype/backends.rs | 34 +- rust/bioscript-formats/src/genotype/bcf.rs | 674 ++++++++++++++++++ rust/bioscript-formats/src/genotype/io.rs | 4 + rust/bioscript-formats/src/genotype/query.rs | 16 +- rust/bioscript-formats/src/genotype/types.rs | 26 + rust/bioscript-formats/src/genotype/vcf.rs | 4 +- rust/bioscript-formats/src/inspect.rs | 62 ++ .../src/inspect/heuristics.rs | 7 +- rust/bioscript-formats/src/inspect/io.rs | 2 + rust/bioscript-formats/src/inspect/render.rs | 1 + rust/bioscript-formats/src/lib.rs | 5 + rust/bioscript-formats/src/liftover.rs | 535 ++++++++++++++ rust/bioscript-formats/tests/file_formats.rs | 2 + .../tests/file_formats/bcf.rs | 375 ++++++++++ rust/bioscript-reporting/src/report_json.rs | 1 + rust/bioscript-wasm/src/inspect_api.rs | 1 + 24 files changed, 1987 insertions(+), 15 deletions(-) create mode 100644 rust/bioscript-formats/assets/liftover/hg19ToHg38.over.chain.gz create mode 100644 rust/bioscript-formats/src/genotype/bcf.rs create mode 100644 rust/bioscript-formats/src/liftover.rs create mode 100644 rust/bioscript-formats/tests/file_formats/bcf.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 7e35e9b..8b5cbaf 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1158,6 +1158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34e7ed524a472dbd0dc69cc7b63408f37552e48460028af44a3024f2eb77f036" dependencies = [ "noodles-bam", + "noodles-bcf", "noodles-bgzf", "noodles-core", "noodles-cram", @@ -1181,6 +1182,18 @@ dependencies = [ "noodles-sam", ] +[[package]] +name = "noodles-bcf" +version = "0.86.0" +dependencies = [ + "indexmap", + "memchr", + "noodles-bgzf", + "noodles-core", + "noodles-csi", + "noodles-vcf", +] + [[package]] name = "noodles-bgzf" version = "0.47.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 79214a0..67ca3a6 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -22,6 +22,7 @@ codegen-units = 1 [patch.crates-io] lexical-util = { path = "vendor/lexical-util" } noodles-bam = { path = "../noodles/noodles-bam" } +noodles-bcf = { path = "../noodles/noodles-bcf" } noodles-bgzf = { path = "../noodles/noodles-bgzf" } noodles-core = { path = "../noodles/noodles-core" } noodles-cram = { path = "../noodles/noodles-cram" } diff --git a/rust/bioscript-cli/src/cli_bootstrap.rs b/rust/bioscript-cli/src/cli_bootstrap.rs index f27e560..80dd0ac 100644 --- a/rust/bioscript-cli/src/cli_bootstrap.rs +++ b/rust/bioscript-cli/src/cli_bootstrap.rs @@ -11,7 +11,7 @@ use std::{ use bioscript_formats::{ GenotypeLoadOptions, GenotypeSourceFormat, GenotypeStore, InferredSex, InspectOptions, PrepareRequest, SexDetectionConfidence, SexInference, inspect_file, prepare_indexes, - shell_flags, + shell_flags, convert_23andme_grch37_to_grch38, }; use bioscript_runtime::{BioscriptRuntime, RuntimeConfig, StageTiming}; use bioscript_schema::{ @@ -57,7 +57,7 @@ fn run_cli() -> Result<(), String> { Ok(()) } -const USAGE: &str = "usage: bioscript [--root ] [--input-file ] [--output-file ] [--observations-file ] [--asset id=path] [--participant-id ] [--trace-report ] [--timing-report ] [--filter key=value] [--input-format auto|text|zip|vcf|cram] [--input-index ] [--reference-file ] [--reference-index ] [--auto-index] [--cache-dir ] [--max-duration-ms N] [--max-memory-bytes N] [--max-allocations N] [--max-recursion-depth N]\n bioscript report --input-file [--input-file ...] --output-dir [--html] [--open] [--root ] [--input-format auto|text|zip|vcf|cram] [--input-index ] [--reference-file ] [--reference-index ] [--allow-md5-mismatch] [--detect-sex] [--sample-sex male|female|unknown] [--analysis-max-duration-ms N]\n bioscript review --cases --output-dir [--html] [--root ] [--filter key=value]\n bioscript import-package [--root ] [--output-dir ]\n bioscript validate-variants [--report ]\n bioscript validate-panels [--report ]\n bioscript validate-assays [--report ]\n bioscript prepare [--root ] [--input-file ] [--reference-file ] [--input-format auto|text|zip|vcf|cram] [--cache-dir ]\n bioscript inspect [--input-index ] [--reference-file ] [--reference-index ] [--detect-sex]"; +const USAGE: &str = "usage: bioscript [--root ] [--input-file ] [--output-file ] [--observations-file ] [--asset id=path] [--participant-id ] [--trace-report ] [--timing-report ] [--filter key=value] [--input-format auto|text|zip|vcf|bcf|cram] [--input-index ] [--reference-file ] [--reference-index ] [--auto-index] [--cache-dir ] [--max-duration-ms N] [--max-memory-bytes N] [--max-allocations N] [--max-recursion-depth N]\n bioscript report --input-file [--input-file ...] --output-dir [--html] [--open] [--root ] [--input-format auto|text|zip|vcf|bcf|cram] [--input-index ] [--reference-file ] [--reference-index ] [--allow-md5-mismatch] [--detect-sex] [--sample-sex male|female|unknown] [--analysis-max-duration-ms N]\n bioscript review --cases --output-dir [--html] [--root ] [--filter key=value]\n bioscript import-package [--root ] [--output-dir ]\n bioscript validate-variants [--report ]\n bioscript validate-panels [--report ]\n bioscript validate-assays [--report ]\n bioscript prepare [--root ] [--input-file ] [--reference-file ] [--input-format auto|text|zip|vcf|bcf|cram] [--cache-dir ]\n bioscript inspect [--input-index ] [--reference-file ] [--reference-index ] [--detect-sex]\n bioscript liftover-23andme [--unmapped ]"; struct CliOptions { script_path: Option, @@ -90,6 +90,7 @@ fn dispatch_subcommand(args: &[String]) -> Result { "validate-assays" => run_validate_assays(rest).map(|()| true), "prepare" => run_prepare(rest).map(|()| true), "inspect" => run_inspect(rest).map(|()| true), + "liftover-23andme" => run_liftover_23andme(rest).map(|()| true), _ => Ok(false), } } diff --git a/rust/bioscript-cli/src/cli_commands.rs b/rust/bioscript-cli/src/cli_commands.rs index 68898ca..e12ea8e 100644 --- a/rust/bioscript-cli/src/cli_commands.rs +++ b/rust/bioscript-cli/src/cli_commands.rs @@ -112,6 +112,53 @@ fn run_inspect(args: Vec) -> Result<(), String> { Ok(()) } +fn run_liftover_23andme(args: Vec) -> Result<(), String> { + let mut input: Option = None; + let mut output: Option = None; + let mut unmapped: Option = None; + + let mut iter = args.into_iter(); + while let Some(arg) = iter.next() { + match arg.as_str() { + "--unmapped" => { + unmapped = Some(PathBuf::from( + iter.next().ok_or("--unmapped requires a path")?, + )); + } + other if input.is_none() => input = Some(PathBuf::from(other)), + other if output.is_none() => output = Some(PathBuf::from(other)), + other => return Err(format!("unexpected argument: {other}")), + } + } + + let Some(input) = input else { + return Err( + "usage: bioscript liftover-23andme [--unmapped ]" + .to_owned(), + ); + }; + let Some(output) = output else { + return Err( + "usage: bioscript liftover-23andme [--unmapped ]" + .to_owned(), + ); + }; + let unmapped = unmapped.unwrap_or_else(|| output.with_extension("unmapped.tsv")); + + let stats = convert_23andme_grch37_to_grch38(&input, &output, &unmapped) + .map_err(|err| err.to_string())?; + println!("total_markers={}", stats.total_markers); + println!("mapped={}", stats.mapped); + println!("unmapped={}", stats.unmapped); + println!( + "reverse_strand_genotypes={}", + stats.reverse_strand_genotypes + ); + println!("output={}", output.display()); + println!("unmapped_report={}", unmapped.display()); + Ok(()) +} + fn run_validate_variants(args: Vec) -> Result<(), String> { let mut path: Option = None; let mut report_path: Option = None; @@ -321,6 +368,20 @@ alleles: assert!(run_inspect(vec!["sample.cram".to_owned(), "--input-index".to_owned()]) .unwrap_err() .contains("--input-index requires")); + + assert!(run_liftover_23andme(Vec::new()) + .unwrap_err() + .contains("usage")); + assert!(run_liftover_23andme(vec!["input.txt".to_owned()]) + .unwrap_err() + .contains("usage")); + assert!(run_liftover_23andme(vec![ + "input.txt".to_owned(), + "output.txt".to_owned(), + "--unmapped".to_owned(), + ]) + .unwrap_err() + .contains("--unmapped requires")); } #[test] @@ -365,6 +426,35 @@ alleles: fs::remove_dir_all(dir).unwrap(); } + #[test] + fn liftover_23andme_command_uses_bundled_chain() { + let dir = temp_dir("liftover"); + let input = dir.join("genome.txt"); + let output = dir.join("genome.grch38.txt"); + let unmapped = dir.join("unmapped.tsv"); + fs::write( + &input, + "# We are using reference human assembly build 37\n\ +rs1800437\t19\t46181392\tCG\n", + ) + .unwrap(); + + run_liftover_23andme(vec![ + input.display().to_string(), + output.display().to_string(), + "--unmapped".to_owned(), + unmapped.display().to_string(), + ]) + .unwrap(); + + let lifted = fs::read_to_string(&output).unwrap(); + assert!(lifted.contains("# Coordinates lifted")); + assert!(lifted.contains("rs1800437\t19\t45678134\tCG")); + assert!(fs::read_to_string(&unmapped).unwrap().contains("reason")); + + fs::remove_dir_all(dir).unwrap(); + } + #[test] fn validate_panels_and_assays_cover_report_and_error_paths() { let dir = temp_dir("panels-assays"); diff --git a/rust/bioscript-cli/src/report_options.rs b/rust/bioscript-cli/src/report_options.rs index a3248bf..0147363 100644 --- a/rust/bioscript-cli/src/report_options.rs +++ b/rust/bioscript-cli/src/report_options.rs @@ -312,7 +312,11 @@ fn loader_with_inspection( let mut loader = base.clone(); if loader.format.is_none() { loader.format = if inspection.container == bioscript_formats::FileContainer::Zip { - Some(GenotypeSourceFormat::Zip) + if inspection.detected_kind == bioscript_formats::DetectedKind::Bcf { + Some(GenotypeSourceFormat::Bcf) + } else { + Some(GenotypeSourceFormat::Zip) + } } else { match inspection.detected_kind { bioscript_formats::DetectedKind::AlignmentBam => { @@ -322,6 +326,7 @@ fn loader_with_inspection( Some(GenotypeSourceFormat::Cram) } bioscript_formats::DetectedKind::Vcf => Some(GenotypeSourceFormat::Vcf), + bioscript_formats::DetectedKind::Bcf => Some(GenotypeSourceFormat::Bcf), bioscript_formats::DetectedKind::GenotypeText => Some(GenotypeSourceFormat::Text), _ => None, } diff --git a/rust/bioscript-formats/Cargo.toml b/rust/bioscript-formats/Cargo.toml index 52db7fc..e48ea2a 100644 --- a/rust/bioscript-formats/Cargo.toml +++ b/rust/bioscript-formats/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["rlib"] [dependencies] bioscript-core = { path = "../bioscript-core" } flate2 = "1.1.9" -noodles = { version = "0.110.0", features = ["bam", "bgzf", "core", "cram", "csi", "fasta", "sam", "tabix", "vcf"] } +noodles = { version = "0.110.0", features = ["bam", "bcf", "bgzf", "core", "cram", "csi", "fasta", "sam", "tabix", "vcf"] } zip = { version = "2.2.0", default-features = false, features = ["deflate"] } [lints.clippy] diff --git a/rust/bioscript-formats/assets/liftover/hg19ToHg38.over.chain.gz b/rust/bioscript-formats/assets/liftover/hg19ToHg38.over.chain.gz new file mode 100644 index 0000000000000000000000000000000000000000..6da318c1a46bdd697567edd5fa3f4245bc9a4cf6 GIT binary patch literal 227698 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ʵfi_?@digZ1z6CnRkNSh4qU` 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

i=gBy(iF+k40qXFc4 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%0Dl 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 literal 0 HcmV?d00001 diff --git a/rust/bioscript-formats/src/genotype.rs b/rust/bioscript-formats/src/genotype.rs index ca8617b..8324772 100644 --- a/rust/bioscript-formats/src/genotype.rs +++ b/rust/bioscript-formats/src/genotype.rs @@ -12,6 +12,7 @@ use bioscript_core::{RuntimeError, VariantObservation}; mod alignment_bytes; mod backends; mod bam_backend; +mod bcf; mod cache; mod common; mod cram_backend; @@ -39,8 +40,8 @@ use io::{ select_zip_entry, }; use types::{ - AlignmentBytesBackend, BamBackend, CramBackend, DelimitedBackend, QueryBackend, RsidMapBackend, - VcfBackend, + AlignmentBytesBackend, BamBackend, BcfBackend, BcfSource, CramBackend, DelimitedBackend, + QueryBackend, RsidMapBackend, VcfBackend, }; pub use types::{ BackendCapabilities, GenotypeLoadOptions, GenotypeSourceFormat, GenotypeStore, QueryKind, @@ -123,6 +124,17 @@ impl GenotypeStore { )), GenotypeSourceFormat::Zip => Self::from_zip_file(path, options), GenotypeSourceFormat::Vcf => Ok(Self::from_vcf_file(path, options)), + GenotypeSourceFormat::Bcf => { + if path + .to_string_lossy() + .to_ascii_lowercase() + .ends_with(".zip") + { + Self::from_zip_file(path, options) + } else { + Ok(Self::from_bcf_file(path, options)) + } + } GenotypeSourceFormat::Cram => Self::from_cram_file(path, options), GenotypeSourceFormat::Bam => Ok(Self::from_bam_file(path, options)), } @@ -137,6 +149,13 @@ impl GenotypeStore { if lower.ends_with(".zip") || bytes_look_like_zip(bytes) { return Self::from_zip_bytes(name, bytes); } + if lower.ends_with(".bcf") { + return Ok(Self::from_bcf_bytes( + name, + bytes, + &GenotypeLoadOptions::default(), + )); + } let reader = BufReader::new(Cursor::new(bytes)); if lower.ends_with(".vcf") || bytes_look_like_vcf(bytes) { return Self::from_vcf_reader(reader, name); @@ -148,6 +167,33 @@ impl GenotypeStore { let mut archive = ZipArchive::new(Cursor::new(bytes)).map_err(|err| { RuntimeError::Io(format!("failed to read genotype zip {name}: {err}")) })?; + let bcf_entries = collect_bcf_zip_entries_from_archive(&mut archive, name)?; + if !bcf_entries.is_empty() { + let mut entries = Vec::with_capacity(bcf_entries.len()); + for entry_name in bcf_entries { + let mut entry = archive.by_name(&entry_name).map_err(|err| { + RuntimeError::Io(format!( + "failed to open genotype entry {entry_name} in {name}: {err}" + )) + })?; + let mut data = Vec::new(); + std::io::Read::read_to_end(&mut entry, &mut data).map_err(|err| { + RuntimeError::Io(format!( + "failed to read genotype entry {entry_name} in {name}: {err}" + )) + })?; + entries.push((entry_name, data)); + } + return Ok(Self { + backend: QueryBackend::Bcf(BcfBackend { + source: BcfSource::ZipBytes { + name: name.to_owned(), + entries, + }, + options: GenotypeLoadOptions::default(), + }), + }); + } let mut selected = None; for idx in 0..archive.len() { let entry = archive.by_index(idx).map_err(|err| { @@ -159,6 +205,7 @@ impl GenotypeStore { let entry_name = entry.name().to_owned(); let lower = entry_name.to_ascii_lowercase(); if lower.ends_with(".vcf") + || lower.ends_with(".bcf") || lower.ends_with(".txt") || lower.ends_with(".tsv") || lower.ends_with(".csv") @@ -187,6 +234,20 @@ impl GenotypeStore { if selected.to_ascii_lowercase().ends_with(".vcf") { return Self::from_vcf_reader(reader, &label); } + if selected.to_ascii_lowercase().ends_with(".bcf") { + let mut entry = reader.into_inner(); + let mut data = Vec::new(); + std::io::Read::read_to_end(&mut entry, &mut data).map_err(|err| { + RuntimeError::Io(format!( + "failed to read genotype entry {selected} in {name}: {err}" + )) + })?; + return Ok(Self::from_bcf_bytes( + &label, + &data, + &GenotypeLoadOptions::default(), + )); + } Self::from_delimited_reader(GenotypeSourceFormat::Zip, reader, &label) } @@ -199,7 +260,40 @@ impl GenotypeStore { } } + fn from_bcf_file(path: &Path, options: &GenotypeLoadOptions) -> Self { + Self { + backend: QueryBackend::Bcf(BcfBackend { + source: BcfSource::File(path.to_path_buf()), + options: options.clone(), + }), + } + } + + fn from_bcf_bytes(name: &str, bytes: &[u8], options: &GenotypeLoadOptions) -> Self { + Self { + backend: QueryBackend::Bcf(BcfBackend { + source: BcfSource::Bytes { + name: name.to_owned(), + data: bytes.to_vec(), + }, + options: options.clone(), + }), + } + } + fn from_zip_file(path: &Path, options: &GenotypeLoadOptions) -> Result { + let bcf_entries = collect_bcf_zip_entries(path)?; + if !bcf_entries.is_empty() { + return Ok(Self { + backend: QueryBackend::Bcf(BcfBackend { + source: BcfSource::ZipFile { + path: path.to_path_buf(), + entries: bcf_entries, + }, + options: options.clone(), + }), + }); + } let selected = select_zip_entry(path)?; let lower = selected.to_ascii_lowercase(); if lower.ends_with(".vcf") || lower.ends_with(".vcf.gz") { @@ -308,6 +402,43 @@ impl GenotypeStore { } } +fn collect_bcf_zip_entries(path: &Path) -> Result, RuntimeError> { + let file = File::open(path).map_err(|err| { + RuntimeError::Io(format!( + "failed to open genotype zip {}: {err}", + path.display() + )) + })?; + let mut archive = ZipArchive::new(file).map_err(|err| { + RuntimeError::Io(format!( + "failed to read genotype zip {}: {err}", + path.display() + )) + })?; + collect_bcf_zip_entries_from_archive(&mut archive, &path.display().to_string()) +} + +fn collect_bcf_zip_entries_from_archive( + archive: &mut ZipArchive, + label: &str, +) -> Result, RuntimeError> { + let mut entries = Vec::new(); + for idx in 0..archive.len() { + let entry = archive.by_index(idx).map_err(|err| { + RuntimeError::Io(format!("failed to inspect genotype zip {label}: {err}")) + })?; + if entry.is_dir() { + continue; + } + let name = entry.name().to_owned(); + if name.to_ascii_lowercase().ends_with(".bcf") { + entries.push(name); + } + } + entries.sort(); + Ok(entries) +} + fn bytes_look_like_zip(bytes: &[u8]) -> bool { bytes.starts_with(b"PK\x03\x04") || bytes.starts_with(b"PK\x05\x06") diff --git a/rust/bioscript-formats/src/genotype/backends.rs b/rust/bioscript-formats/src/genotype/backends.rs index 584c18a..58b8168 100644 --- a/rust/bioscript-formats/src/genotype/backends.rs +++ b/rust/bioscript-formats/src/genotype/backends.rs @@ -1,8 +1,9 @@ use bioscript_core::{Assembly, GenomicLocus, RuntimeError, VariantObservation, VariantSpec}; use super::{ + bcf::scan_bcf_variants, describe_query, lookup_indexed_vcf_variants, scan_delimited_variants, scan_vcf_variants, - types::{DelimitedBackend, GenotypeSourceFormat, RsidMapBackend, VcfBackend}, + types::{BcfBackend, DelimitedBackend, GenotypeSourceFormat, RsidMapBackend, VcfBackend}, }; impl RsidMapBackend { @@ -11,6 +12,7 @@ impl RsidMapBackend { GenotypeSourceFormat::Text => "text", GenotypeSourceFormat::Zip => "zip", GenotypeSourceFormat::Vcf => "vcf", + GenotypeSourceFormat::Bcf => "bcf", GenotypeSourceFormat::Cram => "cram", GenotypeSourceFormat::Bam => "bam", } @@ -104,6 +106,7 @@ impl DelimitedBackend { GenotypeSourceFormat::Text => "text", GenotypeSourceFormat::Zip => "zip", GenotypeSourceFormat::Vcf => "vcf", + GenotypeSourceFormat::Bcf => "bcf", GenotypeSourceFormat::Cram => "cram", GenotypeSourceFormat::Bam => "bam", } @@ -164,3 +167,32 @@ impl VcfBackend { scan_vcf_variants(self, variants) } } + +impl BcfBackend { + pub(super) fn backend_name(&self) -> &'static str { + "bcf" + } + + pub(super) fn get(&self, rsid: &str) -> Result, RuntimeError> { + let results = self.lookup_variants(&[VariantSpec { + rsids: vec![rsid.to_owned()], + ..VariantSpec::default() + }])?; + Ok(results.into_iter().next().and_then(|obs| obs.genotype)) + } + + pub(super) fn lookup_variant( + &self, + variant: &VariantSpec, + ) -> Result { + let mut results = self.lookup_variants(std::slice::from_ref(variant))?; + Ok(results.pop().unwrap_or_default()) + } + + pub(super) fn lookup_variants( + &self, + variants: &[VariantSpec], + ) -> Result, RuntimeError> { + scan_bcf_variants(self, variants) + } +} diff --git a/rust/bioscript-formats/src/genotype/bcf.rs b/rust/bioscript-formats/src/genotype/bcf.rs new file mode 100644 index 0000000..80d5933 --- /dev/null +++ b/rust/bioscript-formats/src/genotype/bcf.rs @@ -0,0 +1,674 @@ +use std::{ + collections::{HashMap, HashSet}, + fs::File, + io::{Cursor, Read}, +}; + +use bioscript_core::{Assembly, RuntimeError, VariantKind, VariantObservation, VariantSpec}; +use noodles::bcf; +use noodles::vcf::{ + self, + variant::record::{ + AlternateBases as _, Ids as _, ReferenceBases as _, + samples::Sample as _, + samples::series::{Value as SampleValue, value::Array}, + }, +}; +use zip::ZipArchive; + +use super::{ + common::variant_sort_key, + types::{BcfBackend, BcfSource}, + vcf::{ + ParsedVcfRow, choose_variant_locus_for_assembly, imputed_reference_observation, + normalize_chromosome_name, vcf_row_genotype_for_variant, vcf_row_matches_variant, + }, +}; + +pub(crate) fn scan_bcf_variants( + backend: &BcfBackend, + variants: &[VariantSpec], +) -> Result, RuntimeError> { + let assembly = backend.options.assembly.or(Some(Assembly::Grch38)); + let mut indexed: Vec<(usize, &VariantSpec)> = variants.iter().enumerate().collect(); + indexed.sort_by_cached_key(|(_, variant)| variant_sort_key(variant)); + + let targets = BcfTargets::new(variants, assembly); + let mut results = vec![VariantObservation::default(); variants.len()]; + let mut unresolved = variants.len(); + + for shard in backend.shards()? { + if unresolved == 0 { + break; + } + if !targets.should_scan_shard(&shard.name) { + continue; + } + scan_bcf_shard( + backend, + &shard, + &targets, + &mut results, + &mut unresolved, + assembly, + )?; + } + + for (idx, variant) in indexed { + if results[idx].genotype.is_none() { + let label = backend.label(); + results[idx] = if backend.options.impute_vcf_missing_as_reference { + choose_variant_locus_for_assembly(variant, assembly) + .and_then(|locus| { + imputed_reference_observation( + backend.backend_name(), + &label, + variant, + &locus, + assembly, + backend.options.inferred_sex, + "no matching rsid or locus found in BCF", + ) + }) + .unwrap_or_else(|| missing_observation(backend, assembly)) + } else { + missing_observation(backend, assembly) + }; + } + } + + Ok(results) +} + +struct BcfTargets<'a> { + variants: &'a [VariantSpec], + assembly: Option, + rsid_targets: HashMap>, + coord_targets: HashMap<(String, i64), Vec>, + chroms: HashSet, +} + +impl<'a> BcfTargets<'a> { + fn new(variants: &'a [VariantSpec], assembly: Option) -> Self { + let mut rsid_targets: HashMap> = HashMap::new(); + let mut coord_targets: HashMap<(String, i64), Vec> = HashMap::new(); + let mut chroms = HashSet::new(); + for (idx, variant) in variants.iter().enumerate() { + for rsid in &variant.rsids { + rsid_targets.entry(rsid.clone()).or_default().push(idx); + } + if let Some(locus) = choose_variant_locus_for_assembly(variant, assembly) { + let chrom = normalize_chromosome_name(&locus.chrom); + chroms.insert(chrom.clone()); + coord_targets + .entry((chrom.clone(), locus.start)) + .or_default() + .push(idx); + if matches!( + variant.kind, + Some(VariantKind::Deletion | VariantKind::Insertion | VariantKind::Indel) + ) { + coord_targets + .entry((chrom, locus.start.saturating_sub(1))) + .or_default() + .push(idx); + } + } + } + Self { + variants, + assembly, + rsid_targets, + coord_targets, + chroms, + } + } + + fn should_scan_shard(&self, name: &str) -> bool { + if self.chroms.is_empty() { + return true; + } + let Some(chrom) = chrom_from_bcf_shard_name(name) else { + return true; + }; + self.chroms.contains(&chrom) + } +} + +struct BcfShard { + name: String, + data: BcfShardData, +} + +enum BcfShardData { + File(std::path::PathBuf), + Bytes(Vec), + ZipEntry { + zip_path: std::path::PathBuf, + entry_name: String, + }, +} + +impl BcfBackend { + fn label(&self) -> String { + match &self.source { + BcfSource::File(path) => path.display().to_string(), + BcfSource::ZipFile { path, .. } => path.display().to_string(), + BcfSource::Bytes { name, .. } | BcfSource::ZipBytes { name, .. } => name.clone(), + } + } + + fn shards(&self) -> Result, RuntimeError> { + match &self.source { + BcfSource::File(path) => Ok(vec![BcfShard { + name: path.display().to_string(), + data: BcfShardData::File(path.clone()), + }]), + BcfSource::Bytes { name, data } => Ok(vec![BcfShard { + name: name.clone(), + data: BcfShardData::Bytes(data.clone()), + }]), + BcfSource::ZipFile { path, entries } => Ok(entries + .iter() + .map(|entry_name| BcfShard { + name: entry_name.clone(), + data: BcfShardData::ZipEntry { + zip_path: path.clone(), + entry_name: entry_name.clone(), + }, + }) + .collect()), + BcfSource::ZipBytes { entries, .. } => Ok(entries + .iter() + .map(|(name, data)| BcfShard { + name: name.clone(), + data: BcfShardData::Bytes(data.clone()), + }) + .collect()), + } + } +} + +fn scan_bcf_shard( + backend: &BcfBackend, + shard: &BcfShard, + targets: &BcfTargets<'_>, + results: &mut [VariantObservation], + unresolved: &mut usize, + assembly: Option, +) -> Result<(), RuntimeError> { + match &shard.data { + BcfShardData::File(path) => { + let file = File::open(path).map_err(|err| { + RuntimeError::Io(format!("failed to open BCF file {}: {err}", path.display())) + })?; + scan_bcf_reader( + backend, + shard, + bcf::io::Reader::new(file), + targets, + results, + unresolved, + assembly, + ) + } + BcfShardData::Bytes(data) => scan_bcf_reader( + backend, + shard, + bcf::io::Reader::new(Cursor::new(data)), + targets, + results, + unresolved, + assembly, + ), + BcfShardData::ZipEntry { + zip_path, + entry_name, + } => { + let file = File::open(zip_path).map_err(|err| { + RuntimeError::Io(format!( + "failed to open genotype zip {}: {err}", + zip_path.display() + )) + })?; + let mut archive = ZipArchive::new(file).map_err(|err| { + RuntimeError::Io(format!( + "failed to read genotype zip {}: {err}", + zip_path.display() + )) + })?; + let mut entry = archive.by_name(entry_name).map_err(|err| { + RuntimeError::Io(format!( + "failed to open genotype entry {entry_name} in {}: {err}", + zip_path.display() + )) + })?; + let mut data = Vec::new(); + entry.read_to_end(&mut data).map_err(|err| { + RuntimeError::Io(format!( + "failed to read genotype entry {entry_name} in {}: {err}", + zip_path.display() + )) + })?; + scan_bcf_reader( + backend, + shard, + bcf::io::Reader::new(Cursor::new(data)), + targets, + results, + unresolved, + assembly, + ) + } + } +} + +fn scan_bcf_reader( + backend: &BcfBackend, + shard: &BcfShard, + mut reader: bcf::io::Reader, + targets: &BcfTargets<'_>, + results: &mut [VariantObservation], + unresolved: &mut usize, + assembly: Option, +) -> Result<(), RuntimeError> { + let header = read_bcf_header_lenient(&mut reader, &shard.name)?; + let string_maps = header.string_maps().clone(); + + for record_result in reader.records() { + if *unresolved == 0 { + break; + } + let record = record_result.map_err(|err| { + RuntimeError::Io(format!("failed to read BCF record {}: {err}", shard.name)) + })?; + let row = bcf_record_to_vcf_row(&header, &string_maps, &record, &shard.name)?; + resolve_bcf_row(backend, &row, targets, results, unresolved, assembly); + } + Ok(()) +} + +fn read_bcf_header_lenient( + reader: &mut bcf::io::Reader, + label: &str, +) -> Result { + let mut header_reader = reader.header_reader(); + header_reader + .read_magic_number() + .map_err(|err| RuntimeError::Io(format!("failed to read BCF magic {label}: {err}")))?; + header_reader + .read_format_version() + .map_err(|err| RuntimeError::Io(format!("failed to read BCF version {label}: {err}")))?; + let mut raw_reader = header_reader + .raw_vcf_header_reader() + .map_err(|err| RuntimeError::Io(format!("failed to open BCF VCF header {label}: {err}")))?; + let mut raw = String::new(); + raw_reader + .read_to_string(&mut raw) + .map_err(|err| RuntimeError::Io(format!("failed to read BCF VCF header {label}: {err}")))?; + raw_reader.discard_to_end().map_err(|err| { + RuntimeError::Io(format!( + "failed to discard BCF VCF header padding {label}: {err}" + )) + })?; + + let sanitized = sanitize_bcf_vcf_header(&raw); + sanitized + .parse::() + .map_err(|err| RuntimeError::Io(format!("failed to parse BCF VCF header {label}: {err}"))) +} + +fn sanitize_bcf_vcf_header(raw: &str) -> String { + let is_23andme_imputed = raw.contains("##DISCLAIMER=") && raw.contains("23andMe"); + let mut inserted_23andme_contigs = false; + raw.lines() + .filter_map(|line| { + if is_23andme_imputed && line.starts_with("##contig=<") { + if inserted_23andme_contigs { + return None; + } + inserted_23andme_contigs = true; + return Some( + (1..=22) + .map(|chrom| format!("##contig=")) + .chain(std::iter::once("##contig=".to_owned())) + .collect::>() + .join("\n"), + ); + } + if line.starts_with("##FORMAT=<") + && line.contains("ID=HDS") + && !line.contains("Description=") + { + Some( + "##FORMAT=" + .to_owned(), + ) + } else { + Some(line.to_owned()) + } + }) + .collect::>() + .join("\n") +} + +fn bcf_record_to_vcf_row( + header: &vcf::Header, + string_maps: &vcf::header::StringMaps, + record: &bcf::Record, + label: &str, +) -> Result { + let chrom = record + .reference_sequence_name(string_maps) + .map(str::to_owned) + .or_else(|_| { + chrom_from_bcf_shard_name(label) + .map(|chrom| { + if chrom == "mt" { + "chrM".to_owned() + } else { + format!("chr{chrom}") + } + }) + .ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "missing reference sequence name in contig string map", + ) + }) + }) + .map_err(|err| { + RuntimeError::Io(format!("{label}: failed to read BCF chromosome: {err}")) + })?; + let position = record + .variant_start() + .transpose() + .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF position: {err}")))? + .ok_or_else(|| RuntimeError::Io(format!("{label}: BCF record missing position")))? + .get() as i64; + let ids_buf = record.ids(); + let ids: Vec<&str> = ids_buf.iter().collect(); + let rsid = ids + .iter() + .find(|id| !id.is_empty() && **id != ".") + .map(|id| (*id).to_owned()); + let reference = String::from_utf8( + record + .reference_bases() + .iter() + .collect::, _>>() + .map_err(|err| { + RuntimeError::Io(format!( + "{label}: failed to read BCF reference bases: {err}" + )) + })?, + ) + .map_err(|err| RuntimeError::Io(format!("{label}: invalid BCF reference bases: {err}")))?; + let alternates = record + .alternate_bases() + .iter() + .map(|result| result.map(str::to_owned)) + .collect::, _>>() + .map_err(|err| { + RuntimeError::Io(format!( + "{label}: failed to read BCF alternate bases: {err}" + )) + })?; + let hds = extract_hds(header, record, label)?; + let genotype = genotype_from_hds(&reference, alternates.first().map(String::as_str), &hds) + .unwrap_or_else(|| "--".to_owned()); + let raw_line = format!( + "{} {} {} {} {} FORMAT=HDS HDS={}", + chrom, + position, + rsid.as_deref().unwrap_or("."), + reference, + alternates.join(","), + hds.iter() + .map(|value| format_hds_value(*value)) + .collect::>() + .join(",") + ); + + Ok(ParsedVcfRow { + rsid, + chrom, + position, + reference, + alternates, + genotype, + raw_line, + }) +} + +fn extract_hds( + header: &vcf::Header, + record: &bcf::Record, + label: &str, +) -> Result, RuntimeError> { + let samples = record + .samples() + .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF samples: {err}")))?; + if let Some(values) = parse_first_bcf_float_series(samples.as_ref()) { + return Ok(values); + } + let Some(sample) = samples.get_index(0) else { + return Ok(Vec::new()); + }; + let Some(value) = sample + .get(header, "HDS") + .transpose() + .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF HDS: {err}")))? + .flatten() + else { + return Ok(Vec::new()); + }; + match value { + SampleValue::Array(Array::Float(values)) => values + .iter() + .filter_map(|result| { + result + .map_err(|err| { + RuntimeError::Io(format!("{label}: failed to read HDS value: {err}")) + }) + .transpose() + }) + .collect(), + SampleValue::Float(value) => Ok(vec![value]), + _ => Ok(Vec::new()), + } +} + +fn parse_first_bcf_float_series(src: &[u8]) -> Option> { + let mut offset = 0usize; + skip_bcf_typed_value(src, &mut offset)?; + let descriptor = *src.get(offset)?; + offset += 1; + let (len, ty) = bcf_descriptor_len_ty(src, descriptor, &mut offset)?; + if ty != 5 { + return None; + } + let mut values = Vec::with_capacity(len); + for _ in 0..len { + let bytes: [u8; 4] = src.get(offset..offset + 4)?.try_into().ok()?; + offset += 4; + let value = f32::from_le_bytes(bytes); + if !value.is_nan() { + values.push(value); + } + } + Some(values) +} + +fn skip_bcf_typed_value(src: &[u8], offset: &mut usize) -> Option<()> { + let descriptor = *src.get(*offset)?; + *offset += 1; + let (len, ty) = bcf_descriptor_len_ty(src, descriptor, offset)?; + let width = match ty { + 1 | 7 => 1, + 2 => 2, + 3 | 5 => 4, + _ => return None, + }; + *offset = offset.checked_add(len.checked_mul(width)?)?; + (*offset <= src.len()).then_some(()) +} + +fn bcf_descriptor_len_ty(src: &[u8], descriptor: u8, offset: &mut usize) -> Option<(usize, u8)> { + let ty = descriptor & 0x0f; + let mut len = usize::from(descriptor >> 4); + if len == 15 { + let len_descriptor = *src.get(*offset)?; + *offset += 1; + let (len_len, len_ty) = bcf_descriptor_len_ty(src, len_descriptor, offset)?; + if len_len != 1 { + return None; + } + len = match len_ty { + 1 => usize::from(*src.get(*offset)?), + 2 => { + let bytes: [u8; 2] = src.get(*offset..*offset + 2)?.try_into().ok()?; + usize::try_from(i16::from_le_bytes(bytes)).ok()? + } + 3 => { + let bytes: [u8; 4] = src.get(*offset..*offset + 4)?.try_into().ok()?; + usize::try_from(i32::from_le_bytes(bytes)).ok()? + } + _ => return None, + }; + *offset += match len_ty { + 1 => 1, + 2 => 2, + 3 => 4, + _ => return None, + }; + } + Some((len, ty)) +} + +fn genotype_from_hds(reference: &str, alternate: Option<&str>, hds: &[f32]) -> Option { + let alternate = alternate?; + if reference.is_empty() || alternate.is_empty() || hds.is_empty() { + return None; + } + let mut alleles = Vec::with_capacity(hds.len().max(2)); + for dosage in hds { + if *dosage >= 0.5 { + alleles.push(alternate.to_owned()); + } else { + alleles.push(reference.to_owned()); + } + } + if alleles.len() == 1 { + alleles.push(reference.to_owned()); + } + if alleles.iter().any(|allele| allele.len() > 1) { + return Some(alleles.join("/")); + } + Some(super::normalize_genotype(&alleles.join("/"))) +} + +fn resolve_bcf_row( + backend: &BcfBackend, + row: &ParsedVcfRow, + targets: &BcfTargets<'_>, + results: &mut [VariantObservation], + unresolved: &mut usize, + assembly: Option, +) { + if let Some(rsid) = row.rsid.as_ref() + && let Some(target_indexes) = targets.rsid_targets.get(rsid) + { + for &target_idx in target_indexes { + if results[target_idx].genotype.is_none() { + results[target_idx] = observation_from_row( + backend, + row, + target_idx, + targets, + assembly, + Some(format!("resolved by rsid {rsid}")), + ); + *unresolved = (*unresolved).saturating_sub(1); + } + } + } + + if *unresolved == 0 { + return; + } + + let key = (normalize_chromosome_name(&row.chrom), row.position); + if let Some(target_indexes) = targets.coord_targets.get(&key) { + for &target_idx in target_indexes { + if results[target_idx].genotype.is_none() + && vcf_row_matches_variant(row, &targets.variants[target_idx], targets.assembly) + { + results[target_idx] = observation_from_row( + backend, + row, + target_idx, + targets, + assembly, + Some(format!("resolved by locus {}:{}", row.chrom, row.position)), + ); + *unresolved = (*unresolved).saturating_sub(1); + } + } + } +} + +fn observation_from_row( + backend: &BcfBackend, + row: &ParsedVcfRow, + target_idx: usize, + targets: &BcfTargets<'_>, + assembly: Option, + resolved: Option, +) -> VariantObservation { + let resolved = resolved.unwrap_or_else(|| "resolved by BCF record".to_owned()); + VariantObservation { + backend: backend.backend_name().to_owned(), + matched_rsid: row.rsid.clone(), + assembly, + genotype: Some(vcf_row_genotype_for_variant( + row, + &targets.variants[target_idx], + )), + evidence: vec![resolved, format!("source record: {}", row.raw_line)], + ..VariantObservation::default() + } +} + +fn missing_observation(backend: &BcfBackend, assembly: Option) -> VariantObservation { + VariantObservation { + backend: backend.backend_name().to_owned(), + assembly, + evidence: vec!["no matching rsid or locus found in BCF".to_owned()], + ..VariantObservation::default() + } +} + +fn chrom_from_bcf_shard_name(name: &str) -> Option { + let file = name.rsplit('/').next().unwrap_or(name); + let lower = file.to_ascii_lowercase(); + let chrom = lower.strip_suffix(".bcf").unwrap_or(&lower); + let chrom = chrom + .strip_prefix("chr") + .unwrap_or(chrom) + .split('.') + .next() + .unwrap_or(chrom); + (!chrom.is_empty()).then(|| chrom.to_owned()) +} + +fn format_hds_value(value: f32) -> String { + if (value.fract()).abs() < f32::EPSILON { + format!("{value:.0}") + } else { + format!("{value:.3}") + .trim_end_matches('0') + .trim_end_matches('.') + .to_owned() + } +} diff --git a/rust/bioscript-formats/src/genotype/io.rs b/rust/bioscript-formats/src/genotype/io.rs index 8d69e55..8b35553 100644 --- a/rust/bioscript-formats/src/genotype/io.rs +++ b/rust/bioscript-formats/src/genotype/io.rs @@ -58,6 +58,7 @@ pub(crate) fn select_zip_entry(path: &Path) -> Result { || lower.ends_with(".tsv") || lower.ends_with(".vcf") || lower.ends_with(".vcf.gz") + || lower.ends_with(".bcf") { return Ok(name); } @@ -117,6 +118,9 @@ pub(crate) fn detect_source_format( if lower.ends_with(".vcf") || lower.ends_with(".vcf.gz") { return Ok(GenotypeSourceFormat::Vcf); } + if lower.ends_with(".bcf") { + return Ok(GenotypeSourceFormat::Bcf); + } let lines = read_plain_lines(path)?; if looks_like_vcf_lines(&lines) { diff --git a/rust/bioscript-formats/src/genotype/query.rs b/rust/bioscript-formats/src/genotype/query.rs index 0a375e1..745b879 100644 --- a/rust/bioscript-formats/src/genotype/query.rs +++ b/rust/bioscript-formats/src/genotype/query.rs @@ -13,10 +13,12 @@ impl GenotypeStore { rsid_lookup: true, locus_lookup: false, }, - QueryBackend::Delimited(_) | QueryBackend::Vcf(_) => BackendCapabilities { - rsid_lookup: true, - locus_lookup: true, - }, + QueryBackend::Delimited(_) | QueryBackend::Vcf(_) | QueryBackend::Bcf(_) => { + BackendCapabilities { + rsid_lookup: true, + locus_lookup: true, + } + } QueryBackend::Cram(_) | QueryBackend::Bam(_) | QueryBackend::AlignmentBytes(_) => { BackendCapabilities { rsid_lookup: false, @@ -48,6 +50,7 @@ impl GenotypeStore { QueryBackend::RsidMap(map) => map.backend_name(), QueryBackend::Delimited(backend) => backend.backend_name(), QueryBackend::Vcf(backend) => backend.backend_name(), + QueryBackend::Bcf(backend) => backend.backend_name(), QueryBackend::Cram(backend) => backend.backend_name(), QueryBackend::Bam(backend) => backend.backend_name(), QueryBackend::AlignmentBytes(backend) => backend.backend_name(), @@ -60,6 +63,7 @@ impl GenotypeStore { QueryBackend::RsidMap(map) => Ok(map.values.get(rsid).cloned()), QueryBackend::Delimited(backend) => backend.get(rsid), QueryBackend::Vcf(backend) => backend.get(rsid), + QueryBackend::Bcf(backend) => backend.get(rsid), QueryBackend::Cram(backend) => backend .lookup_variant(&VariantSpec { rsids: vec![rsid.to_owned()], @@ -111,6 +115,7 @@ impl GenotypeStore { QueryBackend::RsidMap(map) => map.lookup_variant(variant), QueryBackend::Delimited(backend) => backend.lookup_variant(variant), QueryBackend::Vcf(backend) => backend.lookup_variant(variant), + QueryBackend::Bcf(backend) => backend.lookup_variant(variant), QueryBackend::Cram(backend) => backend.lookup_variant(variant), QueryBackend::Bam(backend) => backend.lookup_variant(variant), QueryBackend::AlignmentBytes(backend) => backend.lookup_variant(variant), @@ -177,6 +182,9 @@ impl GenotypeStore { if let QueryBackend::Vcf(backend) = &self.backend { return backend.lookup_variants(variants); } + if let QueryBackend::Bcf(backend) = &self.backend { + return backend.lookup_variants(variants); + } if let QueryBackend::Cram(backend) = &self.backend { return backend.lookup_variants(variants); } diff --git a/rust/bioscript-formats/src/genotype/types.rs b/rust/bioscript-formats/src/genotype/types.rs index 65a7f7d..288116c 100644 --- a/rust/bioscript-formats/src/genotype/types.rs +++ b/rust/bioscript-formats/src/genotype/types.rs @@ -14,6 +14,7 @@ pub(crate) enum QueryBackend { RsidMap(RsidMapBackend), Delimited(DelimitedBackend), Vcf(VcfBackend), + Bcf(BcfBackend), Cram(CramBackend), Bam(BamBackend), /// In-memory CRAM/BAM: alignment + index (+ reference for CRAM) held as @@ -63,6 +64,29 @@ pub(crate) struct VcfBackend { pub(crate) options: GenotypeLoadOptions, } +#[derive(Debug, Clone)] +pub(crate) struct BcfBackend { + pub(crate) source: BcfSource, + pub(crate) options: GenotypeLoadOptions, +} + +#[derive(Debug, Clone)] +pub(crate) enum BcfSource { + File(PathBuf), + ZipFile { + path: PathBuf, + entries: Vec, + }, + Bytes { + name: String, + data: Vec, + }, + ZipBytes { + name: String, + entries: Vec<(String, Vec)>, + }, +} + #[derive(Debug, Clone)] pub(crate) struct CramBackend { pub(crate) path: PathBuf, @@ -107,6 +131,7 @@ pub enum GenotypeSourceFormat { Text, Zip, Vcf, + Bcf, Cram, Bam, } @@ -119,6 +144,7 @@ impl FromStr for GenotypeSourceFormat { "txt" | "text" | "genotype" => Ok(Self::Text), "zip" => Ok(Self::Zip), "vcf" => Ok(Self::Vcf), + "bcf" => Ok(Self::Bcf), "cram" => Ok(Self::Cram), "bam" => Ok(Self::Bam), other => Err(format!("unsupported input format: {other}")), diff --git a/rust/bioscript-formats/src/genotype/vcf.rs b/rust/bioscript-formats/src/genotype/vcf.rs index 18ad60e..f672ad9 100644 --- a/rust/bioscript-formats/src/genotype/vcf.rs +++ b/rust/bioscript-formats/src/genotype/vcf.rs @@ -21,7 +21,9 @@ mod matching; mod reader; pub use matching::{choose_variant_locus_for_assembly, imputed_reference_observation}; -pub(crate) use matching::{normalize_chromosome_name, vcf_row_matches_variant}; +pub(crate) use matching::{ + normalize_chromosome_name, vcf_row_genotype_for_variant, vcf_row_matches_variant, +}; pub use reader::{observe_vcf_snp_with_reader, observe_vcf_variant_with_reader}; #[derive(Debug, Clone)] diff --git a/rust/bioscript-formats/src/inspect.rs b/rust/bioscript-formats/src/inspect.rs index 9cc7520..27f052b 100644 --- a/rust/bioscript-formats/src/inspect.rs +++ b/rust/bioscript-formats/src/inspect.rs @@ -57,6 +57,7 @@ pub enum FileContainer { pub enum DetectedKind { GenotypeText, Vcf, + Bcf, AlignmentCram, AlignmentBam, ReferenceFasta, @@ -126,6 +127,19 @@ pub fn inspect_bytes( if lower.ends_with(".zip") { let selected_entry = select_zip_entry_from_bytes(bytes)?; + if selected_entry.to_ascii_lowercase().ends_with(".bcf") { + let mut inspection = inspect_from_bcf( + path, + FileContainer::Zip, + Some(selected_entry), + options, + started.elapsed().as_millis(), + ); + inspection + .evidence + .push("selected BCF zip entry".to_owned()); + return Ok(inspection); + } let sample_lines = read_zip_sample_lines_from_bytes(bytes, &selected_entry)?; let mut inspection = inspect_from_textual_sample( path, @@ -151,6 +165,9 @@ pub fn inspect_bytes( } else if lower.ends_with(".bam") { evidence.push("extension .bam".to_owned()); DetectedKind::AlignmentBam + } else if lower.ends_with(".bcf") { + evidence.push("extension .bcf".to_owned()); + DetectedKind::Bcf } else if is_reference_path(path) { evidence.push("reference fasta extension".to_owned()); DetectedKind::ReferenceFasta @@ -177,6 +194,7 @@ pub fn inspect_bytes( DetectedKind::AlignmentCram | DetectedKind::AlignmentBam | DetectedKind::ReferenceFasta => { Vec::new() } + DetectedKind::Bcf => Vec::new(), _ => read_plain_sample_lines_from_bytes(&lower, bytes)?, }; let inspection_context = inspect_context_name(&lower, options); @@ -239,6 +257,19 @@ pub fn inspect_file(path: &Path, options: &InspectOptions) -> Result Result Result { Vec::new() } + DetectedKind::Bcf => Vec::new(), _ => read_plain_sample_lines(path)?, }; let inspection_context = inspect_context_name(&lower, options); @@ -401,6 +436,33 @@ fn inspect_from_textual_sample( } } +fn inspect_from_bcf( + path: &Path, + container: FileContainer, + selected_entry: Option, + options: &InspectOptions, + duration_ms: u128, +) -> FileInspection { + let (has_index, index_path) = detect_index(path, DetectedKind::Bcf, options); + FileInspection { + path: path.to_path_buf(), + container, + detected_kind: DetectedKind::Bcf, + confidence: DetectionConfidence::Authoritative, + source: None, + assembly: Some(Assembly::Grch38), + phased: None, + selected_entry, + has_index, + index_path, + reference_matches: None, + inferred_sex: None, + evidence: vec!["BCF input".to_owned()], + warnings: Vec::new(), + duration_ms, + } +} + fn inspect_context_name(lower_name: &str, options: &InspectOptions) -> String { let mut context = lower_name.to_owned(); for path in [ diff --git a/rust/bioscript-formats/src/inspect/heuristics.rs b/rust/bioscript-formats/src/inspect/heuristics.rs index 1c03a2b..0cac9ca 100644 --- a/rust/bioscript-formats/src/inspect/heuristics.rs +++ b/rust/bioscript-formats/src/inspect/heuristics.rs @@ -422,9 +422,10 @@ pub(crate) fn classify_confidence( DetectedKind::Vcf if looks_like_vcf_lines(sample_lines) => { DetectionConfidence::Authoritative } - DetectedKind::AlignmentCram | DetectedKind::AlignmentBam | DetectedKind::ReferenceFasta => { - DetectionConfidence::Authoritative - } + DetectedKind::Bcf + | DetectedKind::AlignmentCram + | DetectedKind::AlignmentBam + | DetectedKind::ReferenceFasta => DetectionConfidence::Authoritative, DetectedKind::GenotypeText if source.is_some() => DetectionConfidence::StrongHeuristic, DetectedKind::GenotypeText => DetectionConfidence::WeakHeuristic, DetectedKind::Unknown => DetectionConfidence::Unknown, diff --git a/rust/bioscript-formats/src/inspect/io.rs b/rust/bioscript-formats/src/inspect/io.rs index a6f06a2..efca6c0 100644 --- a/rust/bioscript-formats/src/inspect/io.rs +++ b/rust/bioscript-formats/src/inspect/io.rs @@ -63,6 +63,7 @@ pub(crate) fn select_zip_entry_from_bytes(bytes: &[u8]) -> Result Result { let lower = name.to_ascii_lowercase(); if lower.ends_with(".vcf") || lower.ends_with(".vcf.gz") + || lower.ends_with(".bcf") || lower.ends_with(".txt") || lower.ends_with(".tsv") || lower.ends_with(".csv") diff --git a/rust/bioscript-formats/src/inspect/render.rs b/rust/bioscript-formats/src/inspect/render.rs index 13180f6..89240f0 100644 --- a/rust/bioscript-formats/src/inspect/render.rs +++ b/rust/bioscript-formats/src/inspect/render.rs @@ -89,6 +89,7 @@ pub(crate) fn render_kind(value: DetectedKind) -> &'static str { match value { DetectedKind::GenotypeText => "genotype_text", DetectedKind::Vcf => "vcf", + DetectedKind::Bcf => "bcf", DetectedKind::AlignmentCram => "alignment_cram", DetectedKind::AlignmentBam => "alignment_bam", DetectedKind::ReferenceFasta => "reference_fasta", diff --git a/rust/bioscript-formats/src/lib.rs b/rust/bioscript-formats/src/lib.rs index e8ae348..cfda399 100644 --- a/rust/bioscript-formats/src/lib.rs +++ b/rust/bioscript-formats/src/lib.rs @@ -11,6 +11,7 @@ pub mod alignment; mod genotype; mod inspect; +mod liftover; mod prepare; pub use genotype::{ @@ -24,4 +25,8 @@ pub use inspect::{ SexDetectionConfidence, SexInference, SourceMetadata, infer_sex_from_alignment_reader, infer_sex_from_named_reader, infer_sex_from_text_lines, inspect_bytes, inspect_file, }; +pub use liftover::{ + ChainIndex, LiftOverOptions, LiftedLocus, LiftoverStats, convert_23andme_grch37_to_grch38, + grch37_to_grch38_chain, +}; pub use prepare::{PrepareRequest, PreparedPaths, prepare_indexes, shell_flags}; diff --git a/rust/bioscript-formats/src/liftover.rs b/rust/bioscript-formats/src/liftover.rs new file mode 100644 index 0000000..ed094ae --- /dev/null +++ b/rust/bioscript-formats/src/liftover.rs @@ -0,0 +1,535 @@ +use std::{ + cmp::Ordering, + collections::HashMap, + fs::File, + io::{self, BufRead, BufReader, Cursor, Write}, + path::Path, +}; + +use bioscript_core::{Assembly, RuntimeError}; +use flate2::read::GzDecoder; + +const HG19_TO_HG38_CHAIN_GZ: &[u8] = include_bytes!("../assets/liftover/hg19ToHg38.over.chain.gz"); + +const PRIMARY_CHROMS: [&str; 25] = [ + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", + "18", "19", "20", "21", "22", "X", "Y", "MT", +]; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct LiftOverOptions { + pub primary_only: bool, +} + +impl Default for LiftOverOptions { + fn default() -> Self { + Self { primary_only: true } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct LiftedLocus { + pub chrom: String, + pub pos: i64, + pub strand: char, + pub score: i64, +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct LiftoverStats { + pub total_markers: u64, + pub mapped: u64, + pub unmapped: u64, + pub reverse_strand_genotypes: u64, +} + +#[derive(Debug, Clone)] +pub struct ChainIndex { + from: Assembly, + to: Assembly, + blocks_by_chrom: HashMap, +} + +#[derive(Debug, Clone)] +struct ChromBlocks { + starts: Vec, + blocks: Vec, +} + +#[derive(Debug, Clone)] +struct ChainBlock { + source_start: i64, + source_end: i64, + target_start: i64, + target_name: String, + target_size: i64, + target_strand: char, + score: i64, + index: usize, +} + +#[derive(Debug, Clone)] +struct ChainHeader { + score: i64, + source_name: String, + source_pos: i64, + target_name: String, + target_size: i64, + target_strand: char, + target_pos: i64, + index: usize, +} + +impl ChainIndex { + pub fn from_reader( + from: Assembly, + to: Assembly, + reader: R, + options: LiftOverOptions, + ) -> Result { + if (from, to) != (Assembly::Grch37, Assembly::Grch38) { + return Err(RuntimeError::Unsupported( + "liftover currently supports only GRCh37 to GRCh38".to_owned(), + )); + } + + let mut blocks_by_chrom: HashMap> = HashMap::new(); + let mut current: Option = None; + let mut chain_index = 0usize; + + for raw in reader.lines() { + let raw = + raw.map_err(|err| RuntimeError::Io(format!("failed to read chain: {err}")))?; + let line = raw.trim(); + if line.is_empty() { + current = None; + continue; + } + + let parts: Vec<&str> = line.split_whitespace().collect(); + if parts.first() == Some(&"chain") { + current = parse_chain_header(&parts, chain_index, options.primary_only)?; + if current.is_some() { + chain_index += 1; + } + continue; + } + + let Some(header) = current.as_mut() else { + continue; + }; + let size = parse_i64(parts[0], "chain block size")?; + let source_start = header.source_pos; + let target_start = header.target_pos; + let source_end = source_start + size; + + blocks_by_chrom + .entry(header.source_name.clone()) + .or_default() + .push(ChainBlock { + source_start, + source_end, + target_start, + target_name: header.target_name.clone(), + target_size: header.target_size, + target_strand: header.target_strand, + score: header.score, + index: header.index, + }); + + if parts.len() == 3 { + header.source_pos = source_end + parse_i64(parts[1], "chain dt")?; + header.target_pos = target_start + size + parse_i64(parts[2], "chain dq")?; + } else { + current = None; + } + } + + let blocks_by_chrom = blocks_by_chrom + .into_iter() + .map(|(chrom, mut blocks)| { + blocks.sort_by(|a, b| { + a.source_start + .cmp(&b.source_start) + .then_with(|| b.score.cmp(&a.score)) + .then_with(|| a.index.cmp(&b.index)) + }); + let starts = blocks.iter().map(|block| block.source_start).collect(); + (chrom, ChromBlocks { starts, blocks }) + }) + .collect(); + + Ok(Self { + from, + to, + blocks_by_chrom, + }) + } + + pub fn lookup( + &self, + from: Assembly, + to: Assembly, + chrom: &str, + pos1: i64, + ) -> Option { + if from != self.from || to != self.to || pos1 <= 0 { + return None; + } + + let source_chrom = chain_chrom(chrom); + let chrom_blocks = self + .blocks_by_chrom + .get(&source_chrom) + .or_else(|| self.blocks_by_chrom.get(chrom))?; + let pos0 = pos1 - 1; + let mut i = chrom_blocks.starts.partition_point(|start| *start <= pos0); + if i == 0 { + return None; + } + i -= 1; + + let mut best: Option<&ChainBlock> = None; + loop { + let block = &chrom_blocks.blocks[i]; + if block.source_start <= pos0 && pos0 < block.source_end { + if best.is_none_or(|candidate| compare_blocks(block, candidate).is_gt()) { + best = Some(block); + } + } + + if let Some(candidate) = best + && chrom_blocks.starts[i] < candidate.source_start - 1_000_000 + { + break; + } + if best.is_none() && pos0 - chrom_blocks.starts[i] > 10_000_000 { + break; + } + if i == 0 { + break; + } + i -= 1; + } + + let best = best?; + let offset = pos0 - best.source_start; + let target_pos0 = if best.target_strand == '+' { + best.target_start + offset + } else { + best.target_size - (best.target_start + offset) - 1 + }; + + Some(LiftedLocus { + chrom: canon_chrom(&best.target_name), + pos: target_pos0 + 1, + strand: best.target_strand, + score: best.score, + }) + } +} + +pub fn grch37_to_grch38_chain() -> Result { + let reader = BufReader::new(GzDecoder::new(Cursor::new(HG19_TO_HG38_CHAIN_GZ))); + ChainIndex::from_reader( + Assembly::Grch37, + Assembly::Grch38, + reader, + LiftOverOptions::default(), + ) +} + +pub fn convert_23andme_grch37_to_grch38( + input_path: &Path, + output_path: &Path, + unmapped_path: &Path, +) -> Result { + let chain = grch37_to_grch38_chain()?; + convert_23andme_with_chain(input_path, output_path, unmapped_path, &chain) +} + +pub fn convert_23andme_with_chain( + input_path: &Path, + output_path: &Path, + unmapped_path: &Path, + chain: &ChainIndex, +) -> Result { + let input = File::open(input_path).map_err(|err| { + RuntimeError::Io(format!("failed to open {}: {err}", input_path.display())) + })?; + let mut output = File::create(output_path).map_err(|err| { + RuntimeError::Io(format!("failed to create {}: {err}", output_path.display())) + })?; + let mut unmapped = File::create(unmapped_path).map_err(|err| { + RuntimeError::Io(format!( + "failed to create unmapped report {}: {err}", + unmapped_path.display() + )) + })?; + + convert_23andme_reader_with_chain(BufReader::new(input), &mut output, &mut unmapped, chain) +} + +pub fn convert_23andme_reader_with_chain( + reader: R, + output: &mut W, + unmapped: &mut U, + chain: &ChainIndex, +) -> Result { + let mut stats = LiftoverStats::default(); + let mut added_note = false; + writeln!(unmapped, "rsid\tchromosome\tposition\tgenotype\treason") + .map_err(write_error("unmapped report"))?; + + for raw in reader.lines() { + let raw = + raw.map_err(|err| RuntimeError::Io(format!("failed to read 23andMe txt: {err}")))?; + let line = raw.trim_end_matches(['\n', '\r']); + if line.starts_with('#') { + if !added_note && line.contains("reference human assembly build 37") { + writeln!( + output, + "# Coordinates lifted from reference human assembly build 37 to build 38 / GRCh38." + ) + .map_err(write_error("lifted 23andMe output"))?; + writeln!( + output, + "# Genotype bases were reverse-complemented for markers mapping through reverse-strand chains." + ) + .map_err(write_error("lifted 23andMe output"))?; + added_note = true; + } + writeln!( + output, + "{}", + line.replace("build 37", "build 38 / GRCh38") + .replace("Annotation Release 104", "GRCh38") + ) + .map_err(write_error("lifted 23andMe output"))?; + continue; + } + + if line.is_empty() { + writeln!(output).map_err(write_error("lifted 23andMe output"))?; + continue; + } + + stats.total_markers += 1; + let mut fields: Vec = line.split('\t').map(ToOwned::to_owned).collect(); + if fields.len() < 4 { + stats.unmapped += 1; + writeln!(unmapped, "{line}\tmalformed").map_err(write_error("unmapped report"))?; + continue; + } + + let pos = match fields[2].parse::() { + Ok(pos) => pos, + Err(_) => { + stats.unmapped += 1; + writeln!( + unmapped, + "{}\t{}\t{}\t{}\tnon_integer_position", + fields[0], fields[1], fields[2], fields[3] + ) + .map_err(write_error("unmapped report"))?; + continue; + } + }; + + let Some(lifted) = chain.lookup(Assembly::Grch37, Assembly::Grch38, &fields[1], pos) else { + stats.unmapped += 1; + writeln!( + unmapped, + "{}\t{}\t{}\t{}\tno_primary_mapping", + fields[0], fields[1], fields[2], fields[3] + ) + .map_err(write_error("unmapped report"))?; + continue; + }; + + if lifted.strand == '-' { + fields[3] = revcomp_genotype(&fields[3]); + stats.reverse_strand_genotypes += 1; + } + fields[1] = lifted.chrom; + fields[2] = lifted.pos.to_string(); + writeln!(output, "{}", fields.join("\t")).map_err(write_error("lifted 23andMe output"))?; + stats.mapped += 1; + } + + Ok(stats) +} + +fn parse_chain_header( + parts: &[&str], + index: usize, + primary_only: bool, +) -> Result, RuntimeError> { + if parts.len() < 13 { + return Err(RuntimeError::Io("malformed chain header".to_owned())); + } + let source_name = parts[2].to_owned(); + let source_strand = parts[4]; + let source_pos = parse_i64(parts[5], "chain tStart")?; + let target_name = parts[7].to_owned(); + let target_size = parse_i64(parts[8], "chain qSize")?; + let target_strand = parts[9].chars().next().unwrap_or('+'); + let target_pos = parse_i64(parts[10], "chain qStart")?; + + if source_strand != "+" { + return Ok(None); + } + if primary_only + && (!is_primary_chrom(&canon_chrom(&source_name)) + || !is_primary_chrom(&canon_chrom(&target_name))) + { + return Ok(None); + } + + Ok(Some(ChainHeader { + score: parse_i64(parts[1], "chain score")?, + source_name, + source_pos, + target_name, + target_size, + target_strand, + target_pos, + index, + })) +} + +fn compare_blocks(a: &ChainBlock, b: &ChainBlock) -> Ordering { + a.score.cmp(&b.score).then_with(|| b.index.cmp(&a.index)) +} + +fn parse_i64(value: &str, label: &str) -> Result { + value + .parse::() + .map_err(|err| RuntimeError::Io(format!("failed to parse {label} '{value}': {err}"))) +} + +fn canon_chrom(name: &str) -> String { + let stripped = name.strip_prefix("chr").unwrap_or(name); + if stripped == "M" { + "MT".to_owned() + } else { + stripped.to_owned() + } +} + +fn chain_chrom(name: &str) -> String { + let canon = canon_chrom(name); + if canon == "MT" { + "chrM".to_owned() + } else { + format!("chr{canon}") + } +} + +fn is_primary_chrom(chrom: &str) -> bool { + PRIMARY_CHROMS.contains(&chrom) +} + +fn revcomp_genotype(genotype: &str) -> String { + genotype + .chars() + .map(|ch| match ch { + 'A' => 'T', + 'C' => 'G', + 'G' => 'C', + 'T' => 'A', + 'a' => 't', + 'c' => 'g', + 'g' => 'c', + 't' => 'a', + other => other, + }) + .collect() +} + +fn write_error(label: &'static str) -> impl FnOnce(io::Error) -> RuntimeError { + move |err| RuntimeError::Io(format!("failed to write {label}: {err}")) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn tiny_chain() -> ChainIndex { + let chain = "\ +chain 100 chr1 1000 + 9 30 chr1 1000 + 99 120 1\n\ +10 5 5\n\ +10\n\ +\n\ +chain 90 chr2 1000 + 49 60 chr2 1000 - 100 111 2\n\ +10\n\ +"; + ChainIndex::from_reader( + Assembly::Grch37, + Assembly::Grch38, + BufReader::new(chain.as_bytes()), + LiftOverOptions::default(), + ) + .unwrap() + } + + #[test] + fn bundled_chain_maps_known_23andme_marker() { + let chain = grch37_to_grch38_chain().unwrap(); + let lifted = chain + .lookup(Assembly::Grch37, Assembly::Grch38, "19", 46_181_392) + .unwrap(); + assert_eq!(lifted.chrom, "19"); + assert_eq!(lifted.pos, 45_678_134); + assert_eq!(lifted.strand, '+'); + } + + #[test] + fn chain_lookup_handles_forward_and_reverse_blocks() { + let chain = tiny_chain(); + let forward = chain + .lookup(Assembly::Grch37, Assembly::Grch38, "1", 11) + .unwrap(); + assert_eq!(forward.chrom, "1"); + assert_eq!(forward.pos, 101); + assert_eq!(forward.strand, '+'); + + let reverse = chain + .lookup(Assembly::Grch37, Assembly::Grch38, "2", 50) + .unwrap(); + assert_eq!(reverse.chrom, "2"); + assert_eq!(reverse.pos, 900); + assert_eq!(reverse.strand, '-'); + } + + #[test] + fn convert_23andme_lifts_positions_and_reverse_complements() { + let chain = tiny_chain(); + let input = b"# We are using reference human assembly build 37\n\ +rsForward\t1\t11\tAG\n\ +rsReverse\t2\t50\tAC\n\ +rsMissing\t3\t10\tTT\n"; + let mut out = Vec::new(); + let mut unmapped = Vec::new(); + let stats = convert_23andme_reader_with_chain( + BufReader::new(&input[..]), + &mut out, + &mut unmapped, + &chain, + ) + .unwrap(); + + assert_eq!(stats.total_markers, 3); + assert_eq!(stats.mapped, 2); + assert_eq!(stats.unmapped, 1); + assert_eq!(stats.reverse_strand_genotypes, 1); + + let out = String::from_utf8(out).unwrap(); + assert!(out.contains("# Coordinates lifted")); + assert!(out.contains("rsForward\t1\t101\tAG")); + assert!(out.contains("rsReverse\t2\t900\tTG")); + + let unmapped = String::from_utf8(unmapped).unwrap(); + assert!(unmapped.contains("rsMissing\t3\t10\tTT\tno_primary_mapping")); + } +} diff --git a/rust/bioscript-formats/tests/file_formats.rs b/rust/bioscript-formats/tests/file_formats.rs index a561b34..4c51a16 100644 --- a/rust/bioscript-formats/tests/file_formats.rs +++ b/rust/bioscript-formats/tests/file_formats.rs @@ -76,6 +76,8 @@ fn zip_bytes(entry_name: &str, contents: &[u8]) -> Vec { mod alignment_tests; #[path = "file_formats/basic.rs"] mod basic; +#[path = "file_formats/bcf.rs"] +mod bcf; #[path = "file_formats/cram.rs"] mod cram; #[path = "file_formats/delimited.rs"] diff --git a/rust/bioscript-formats/tests/file_formats/bcf.rs b/rust/bioscript-formats/tests/file_formats/bcf.rs new file mode 100644 index 0000000..285f926 --- /dev/null +++ b/rust/bioscript-formats/tests/file_formats/bcf.rs @@ -0,0 +1,375 @@ +use super::*; + +use bioscript_core::GenomicLocus; +use bioscript_formats::{ + DetectedKind, FileContainer, InspectOptions, convert_23andme_grch37_to_grch38, inspect_file, +}; +use noodles::core::Position; +use noodles::vcf::{ + self, + header::record::value::{ + Map, + map::{ + Contig, Filter, Format, + format::{Number, Type}, + }, + }, + variant::{ + io::Write as _, + record_buf::{ + Samples, + samples::{Keys, sample::Value}, + }, + }, +}; +use std::io::{BufRead, BufReader}; + +fn locus(chrom: &str, start: i64, end: i64) -> GenomicLocus { + GenomicLocus { + chrom: chrom.to_owned(), + start, + end, + } +} + +fn bcf_bytes(records: &[(&str, i64, &str, &str, &str, &[f32])]) -> Vec { + let header = vcf::Header::builder() + .add_filter("PASS", Map::::pass()) + .add_contig("chr6", Map::::new()) + .add_contig("chr19", Map::::new()) + .add_format( + "HDS", + Map::::new(Number::Unknown, Type::Float, "haploid alternate dosage"), + ) + .add_sample_name("1") + .build(); + + let mut data = Vec::new(); + let mut writer = noodles::bcf::io::Writer::new(&mut data); + writer.write_header(&header).unwrap(); + + let keys: Keys = ["HDS".to_owned()].into_iter().collect(); + for (chrom, pos, id, reference, alternate, hds) in records { + let samples = Samples::new( + keys.clone(), + vec![vec![Some(Value::from( + hds.iter().copied().map(Some).collect::>(), + ))]], + ); + let mut builder = vcf::variant::RecordBuf::builder() + .set_reference_sequence_name(*chrom) + .set_variant_start(Position::try_from(usize::try_from(*pos).unwrap()).unwrap()) + .set_reference_bases(*reference) + .set_alternate_bases(vec![(*alternate).to_owned()].into()) + .set_samples(samples); + if *id != "." { + builder = builder.set_ids([(*id).to_owned()].into_iter().collect()); + } + let record = builder.build(); + writer.write_variant_record(&header, &record).unwrap(); + } + writer.try_finish().unwrap(); + drop(writer); + data +} + +#[test] +fn individual_bcf_hds_records_are_readable_by_locus() { + let dir = temp_dir("bcf-hds"); + let path = dir.join("chr6.bcf"); + fs::write( + &path, + bcf_bytes(&[ + ("chr6", 39_011_352, ".", "A", "G", &[0.0, 0.0]), + ("chr6", 39_048_860, ".", "C", "T", &[1.0, 1.0]), + ("chr6", 39_051_898, ".", "G", "T", &[0.0, 1.0]), + ]), + ) + .unwrap(); + + let store = GenotypeStore::from_file(&path).unwrap(); + assert_eq!(store.backend_name(), "bcf"); + + let observations = store + .lookup_variants(&[ + VariantSpec { + grch38: Some(locus("6", 39_011_352, 39_011_352)), + reference: Some("A".to_owned()), + alternate: Some("G".to_owned()), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }, + VariantSpec { + grch38: Some(locus("6", 39_048_860, 39_048_860)), + reference: Some("C".to_owned()), + alternate: Some("T".to_owned()), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }, + VariantSpec { + grch38: Some(locus("6", 39_051_898, 39_051_898)), + reference: Some("G".to_owned()), + alternate: Some("T".to_owned()), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }, + ]) + .unwrap(); + + assert_eq!(observations[0].genotype.as_deref(), Some("AA")); + assert_eq!(observations[1].genotype.as_deref(), Some("TT")); + assert_eq!(observations[2].genotype.as_deref(), Some("GT")); + assert_eq!(observations[0].assembly, Some(Assembly::Grch38)); + assert!( + observations[2].evidence[1].contains("HDS=0,1"), + "{:?}", + observations[2].evidence + ); +} + +#[test] +fn zip_of_bcf_shards_is_treated_as_one_logical_store() { + let dir = temp_dir("bcf-zip"); + let zip_path = dir.join("imputed_genotype_data_r6_sample.zip"); + let chr6 = bcf_bytes(&[("chr6", 39_051_898, ".", "G", "T", &[0.0, 1.0])]); + let chr19 = bcf_bytes(&[("chr19", 45_678_134, ".", "G", "C", &[1.0, 0.0])]); + + let file = fs::File::create(&zip_path).unwrap(); + let mut writer = zip::ZipWriter::new(file); + writer + .start_file("fbbdf42da6/chr6.bcf", SimpleFileOptions::default()) + .unwrap(); + writer.write_all(&chr6).unwrap(); + writer + .start_file("fbbdf42da6/chr19.bcf", SimpleFileOptions::default()) + .unwrap(); + writer.write_all(&chr19).unwrap(); + writer.finish().unwrap(); + + let store = GenotypeStore::from_file(&zip_path).unwrap(); + assert_eq!(store.backend_name(), "bcf"); + + let observations = store + .lookup_variants(&[ + VariantSpec { + grch38: Some(locus("19", 45_678_134, 45_678_134)), + reference: Some("G".to_owned()), + alternate: Some("C".to_owned()), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }, + VariantSpec { + grch38: Some(locus("6", 39_051_898, 39_051_898)), + reference: Some("G".to_owned()), + alternate: Some("T".to_owned()), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }, + ]) + .unwrap(); + + assert_eq!(observations[0].genotype.as_deref(), Some("CG")); + assert_eq!(observations[1].genotype.as_deref(), Some("GT")); + + let inspection = inspect_file(&zip_path, &InspectOptions::default()).unwrap(); + assert_eq!(inspection.container, FileContainer::Zip); + assert_eq!(inspection.detected_kind, DetectedKind::Bcf); + assert_eq!(inspection.assembly, Some(Assembly::Grch38)); +} + +#[test] +fn bcf_left_anchored_indel_matches_23andme_style_catalog_variant() { + let dir = temp_dir("bcf-indel"); + let path = dir.join("chr19.bcf"); + fs::write( + &path, + bcf_bytes(&[ + ("chr19", 45_679_773, ".", "A", "AT", &[1.0, 0.0]), + ("chr19", 45_679_773, ".", "A", "ATT", &[0.0, 0.0]), + ]), + ) + .unwrap(); + + let store = GenotypeStore::from_file(&path).unwrap(); + let observation = store + .lookup_variant(&VariantSpec { + rsids: vec!["rs71338792".to_owned()], + grch38: Some(locus("19", 45_679_774, 45_679_786)), + reference: Some("TTTTTTTTTTTTT".to_owned()), + alternate: Some("TTTTTTTTTTTTTT".to_owned()), + kind: Some(VariantKind::Indel), + ..VariantSpec::default() + }) + .unwrap(); + + assert_eq!(observation.genotype.as_deref(), Some("DI")); + assert!( + observation.evidence[0].contains("resolved by locus chr19:45679773"), + "{:?}", + observation.evidence + ); +} + +#[test] +fn local_23andme_lifted_text_matches_real_bcf_zip_for_known_variant_when_enabled() { + if std::env::var_os("BIOSCRIPT_RUN_LOCAL_23ANDME_BCF").is_none() { + eprintln!("skipping local 23andMe BCF concordance; set BIOSCRIPT_RUN_LOCAL_23ANDME_BCF=1"); + return; + } + + let workspace = repo_root().parent().expect("workspace root").to_path_buf(); + let raw_txt = workspace.join("genome_Madhava_Jay_v4_Full_20250613052552.txt"); + let bcf_zip = workspace + .join("exvitae") + .join("imputed_genotype_data_r6_Madhava_Jay.zip"); + if !raw_txt.exists() || !bcf_zip.exists() { + eprintln!( + "skipping local 23andMe BCF concordance; missing {} or {}", + raw_txt.display(), + bcf_zip.display() + ); + return; + } + + let dir = temp_dir("real-23andme-bcf"); + let lifted = dir.join("genome.grch38.txt"); + let unmapped = dir.join("unmapped.tsv"); + convert_23andme_grch37_to_grch38(&raw_txt, &lifted, &unmapped).unwrap(); + + let lifted_store = GenotypeStore::from_file(&lifted).unwrap(); + let bcf_store = GenotypeStore::from_file(&bcf_zip).unwrap(); + let variant = VariantSpec { + rsids: vec!["rs1800437".to_owned()], + grch38: Some(locus("19", 45_678_134, 45_678_134)), + reference: Some("G".to_owned()), + alternate: Some("C".to_owned()), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }; + + let lifted_observation = lifted_store.lookup_variant(&variant).unwrap(); + let bcf_observation = bcf_store.lookup_variant(&variant).unwrap(); + assert_eq!(lifted_observation.genotype.as_deref(), Some("CG")); + assert_eq!(bcf_observation.genotype.as_deref(), Some("CG")); + assert_eq!(lifted_observation.genotype, bcf_observation.genotype); +} + +#[test] +fn local_23andme_lifted_text_broadly_matches_real_bcf_zip_when_enabled() { + if std::env::var_os("BIOSCRIPT_RUN_LOCAL_23ANDME_BCF").is_none() { + eprintln!( + "skipping local 23andMe BCF broad concordance; set BIOSCRIPT_RUN_LOCAL_23ANDME_BCF=1" + ); + return; + } + + let workspace = repo_root().parent().expect("workspace root").to_path_buf(); + let raw_txt = workspace.join("genome_Madhava_Jay_v4_Full_20250613052552.txt"); + let bcf_zip = workspace + .join("exvitae") + .join("imputed_genotype_data_r6_Madhava_Jay.zip"); + if !raw_txt.exists() || !bcf_zip.exists() { + eprintln!( + "skipping local 23andMe BCF broad concordance; missing {} or {}", + raw_txt.display(), + bcf_zip.display() + ); + return; + } + + let dir = temp_dir("real-23andme-bcf-broad"); + let lifted = dir.join("genome.grch38.txt"); + let unmapped = dir.join("unmapped.tsv"); + convert_23andme_grch37_to_grch38(&raw_txt, &lifted, &unmapped).unwrap(); + + let mut txt_genotypes = Vec::new(); + let mut variants = Vec::new(); + let file = fs::File::open(&lifted).unwrap(); + for line in BufReader::new(file).lines() { + let line = line.unwrap(); + if line.is_empty() || line.starts_with('#') { + continue; + } + let fields: Vec<&str> = line.split('\t').collect(); + if fields.len() < 4 { + continue; + } + let chrom = fields[1]; + if matches!(chrom, "Y" | "MT" | "M") { + continue; + } + let genotype = fields[3].trim().to_ascii_uppercase(); + if genotype.is_empty() + || genotype == "--" + || !genotype + .chars() + .all(|base| matches!(base, 'A' | 'C' | 'G' | 'T')) + { + continue; + } + let Ok(pos) = fields[2].parse::() else { + continue; + }; + txt_genotypes.push(normalized_acgt_genotype(&genotype)); + variants.push(VariantSpec { + rsids: vec![fields[0].to_owned()], + grch38: Some(locus(chrom, pos, pos)), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }); + } + + let bcf_store = GenotypeStore::from_file(&bcf_zip).unwrap(); + let observations = bcf_store.lookup_variants(&variants).unwrap(); + + let mut queried = 0usize; + let mut found = 0usize; + let mut matched = 0usize; + let mut mismatched = 0usize; + let mut examples = Vec::new(); + for (idx, observation) in observations.iter().enumerate() { + queried += 1; + let Some(bcf_genotype) = observation.genotype.as_deref() else { + continue; + }; + found += 1; + if normalized_acgt_genotype(bcf_genotype) == txt_genotypes[idx] { + matched += 1; + } else { + mismatched += 1; + if examples.len() < 8 { + let locus = variants[idx].grch38.as_ref().unwrap(); + examples.push(format!( + "{} {}:{} txt={} bcf={}", + variants[idx].rsids[0], + locus.chrom, + locus.start, + txt_genotypes[idx], + bcf_genotype + )); + } + } + } + + eprintln!( + "local 23andMe BCF broad concordance: queried={queried} found={found} matched={matched} mismatched={mismatched} missing={}", + queried - found + ); + if !examples.is_empty() { + eprintln!("mismatch examples: {}", examples.join("; ")); + } + assert!(queried > 500_000, "expected broad 23andMe SNP comparison"); + assert!( + found > 500_000, + "expected most lifted SNPs to be present in BCF" + ); +} + +fn normalized_acgt_genotype(genotype: &str) -> String { + let mut chars: Vec = genotype + .chars() + .filter(|base| matches!(base, 'A' | 'C' | 'G' | 'T')) + .collect(); + chars.sort_unstable(); + chars.into_iter().collect() +} diff --git a/rust/bioscript-reporting/src/report_json.rs b/rust/bioscript-reporting/src/report_json.rs index 1652809..3a88e34 100644 --- a/rust/bioscript-reporting/src/report_json.rs +++ b/rust/bioscript-reporting/src/report_json.rs @@ -141,6 +141,7 @@ fn detected_kind_name(value: bioscript_formats::DetectedKind) -> &'static str { match value { bioscript_formats::DetectedKind::GenotypeText => "genotype_text", bioscript_formats::DetectedKind::Vcf => "vcf", + bioscript_formats::DetectedKind::Bcf => "bcf", bioscript_formats::DetectedKind::AlignmentCram => "alignment_cram", bioscript_formats::DetectedKind::AlignmentBam => "alignment_bam", bioscript_formats::DetectedKind::ReferenceFasta => "reference_fasta", diff --git a/rust/bioscript-wasm/src/inspect_api.rs b/rust/bioscript-wasm/src/inspect_api.rs index 429e102..dcc4016 100644 --- a/rust/bioscript-wasm/src/inspect_api.rs +++ b/rust/bioscript-wasm/src/inspect_api.rs @@ -138,6 +138,7 @@ fn render_kind(k: DetectedKind) -> &'static str { match k { DetectedKind::GenotypeText => "genotype_text", DetectedKind::Vcf => "vcf", + DetectedKind::Bcf => "bcf", DetectedKind::AlignmentCram => "alignment_cram", DetectedKind::AlignmentBam => "alignment_bam", DetectedKind::ReferenceFasta => "reference_fasta", From cd55c95fd36af60f422395aef4ca08b04335a540 Mon Sep 17 00:00:00 2001 From: Madhava Jay Date: Tue, 26 May 2026 14:16:11 +1000 Subject: [PATCH 2/2] linting --- rust/bioscript-formats/src/genotype/bcf.rs | 306 +---------------- .../src/genotype/bcf/records.rs | 309 ++++++++++++++++++ rust/bioscript-formats/src/liftover.rs | 30 +- .../tests/file_formats/bcf.rs | 204 +++++++----- 4 files changed, 456 insertions(+), 393 deletions(-) create mode 100644 rust/bioscript-formats/src/genotype/bcf/records.rs diff --git a/rust/bioscript-formats/src/genotype/bcf.rs b/rust/bioscript-formats/src/genotype/bcf.rs index 80d5933..3b644ae 100644 --- a/rust/bioscript-formats/src/genotype/bcf.rs +++ b/rust/bioscript-formats/src/genotype/bcf.rs @@ -6,16 +6,12 @@ use std::{ use bioscript_core::{Assembly, RuntimeError, VariantKind, VariantObservation, VariantSpec}; use noodles::bcf; -use noodles::vcf::{ - self, - variant::record::{ - AlternateBases as _, Ids as _, ReferenceBases as _, - samples::Sample as _, - samples::series::{Value as SampleValue, value::Array}, - }, -}; use zip::ZipArchive; +mod records; + +use records::{bcf_record_to_vcf_row, read_bcf_header_lenient}; + use super::{ common::variant_sort_key, types::{BcfBackend, BcfSource}, @@ -152,8 +148,7 @@ enum BcfShardData { impl BcfBackend { fn label(&self) -> String { match &self.source { - BcfSource::File(path) => path.display().to_string(), - BcfSource::ZipFile { path, .. } => path.display().to_string(), + BcfSource::File(path) | BcfSource::ZipFile { path, .. } => path.display().to_string(), BcfSource::Bytes { name, .. } | BcfSource::ZipBytes { name, .. } => name.clone(), } } @@ -288,286 +283,6 @@ fn scan_bcf_reader( Ok(()) } -fn read_bcf_header_lenient( - reader: &mut bcf::io::Reader, - label: &str, -) -> Result { - let mut header_reader = reader.header_reader(); - header_reader - .read_magic_number() - .map_err(|err| RuntimeError::Io(format!("failed to read BCF magic {label}: {err}")))?; - header_reader - .read_format_version() - .map_err(|err| RuntimeError::Io(format!("failed to read BCF version {label}: {err}")))?; - let mut raw_reader = header_reader - .raw_vcf_header_reader() - .map_err(|err| RuntimeError::Io(format!("failed to open BCF VCF header {label}: {err}")))?; - let mut raw = String::new(); - raw_reader - .read_to_string(&mut raw) - .map_err(|err| RuntimeError::Io(format!("failed to read BCF VCF header {label}: {err}")))?; - raw_reader.discard_to_end().map_err(|err| { - RuntimeError::Io(format!( - "failed to discard BCF VCF header padding {label}: {err}" - )) - })?; - - let sanitized = sanitize_bcf_vcf_header(&raw); - sanitized - .parse::() - .map_err(|err| RuntimeError::Io(format!("failed to parse BCF VCF header {label}: {err}"))) -} - -fn sanitize_bcf_vcf_header(raw: &str) -> String { - let is_23andme_imputed = raw.contains("##DISCLAIMER=") && raw.contains("23andMe"); - let mut inserted_23andme_contigs = false; - raw.lines() - .filter_map(|line| { - if is_23andme_imputed && line.starts_with("##contig=<") { - if inserted_23andme_contigs { - return None; - } - inserted_23andme_contigs = true; - return Some( - (1..=22) - .map(|chrom| format!("##contig=")) - .chain(std::iter::once("##contig=".to_owned())) - .collect::>() - .join("\n"), - ); - } - if line.starts_with("##FORMAT=<") - && line.contains("ID=HDS") - && !line.contains("Description=") - { - Some( - "##FORMAT=" - .to_owned(), - ) - } else { - Some(line.to_owned()) - } - }) - .collect::>() - .join("\n") -} - -fn bcf_record_to_vcf_row( - header: &vcf::Header, - string_maps: &vcf::header::StringMaps, - record: &bcf::Record, - label: &str, -) -> Result { - let chrom = record - .reference_sequence_name(string_maps) - .map(str::to_owned) - .or_else(|_| { - chrom_from_bcf_shard_name(label) - .map(|chrom| { - if chrom == "mt" { - "chrM".to_owned() - } else { - format!("chr{chrom}") - } - }) - .ok_or_else(|| { - std::io::Error::new( - std::io::ErrorKind::InvalidData, - "missing reference sequence name in contig string map", - ) - }) - }) - .map_err(|err| { - RuntimeError::Io(format!("{label}: failed to read BCF chromosome: {err}")) - })?; - let position = record - .variant_start() - .transpose() - .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF position: {err}")))? - .ok_or_else(|| RuntimeError::Io(format!("{label}: BCF record missing position")))? - .get() as i64; - let ids_buf = record.ids(); - let ids: Vec<&str> = ids_buf.iter().collect(); - let rsid = ids - .iter() - .find(|id| !id.is_empty() && **id != ".") - .map(|id| (*id).to_owned()); - let reference = String::from_utf8( - record - .reference_bases() - .iter() - .collect::, _>>() - .map_err(|err| { - RuntimeError::Io(format!( - "{label}: failed to read BCF reference bases: {err}" - )) - })?, - ) - .map_err(|err| RuntimeError::Io(format!("{label}: invalid BCF reference bases: {err}")))?; - let alternates = record - .alternate_bases() - .iter() - .map(|result| result.map(str::to_owned)) - .collect::, _>>() - .map_err(|err| { - RuntimeError::Io(format!( - "{label}: failed to read BCF alternate bases: {err}" - )) - })?; - let hds = extract_hds(header, record, label)?; - let genotype = genotype_from_hds(&reference, alternates.first().map(String::as_str), &hds) - .unwrap_or_else(|| "--".to_owned()); - let raw_line = format!( - "{} {} {} {} {} FORMAT=HDS HDS={}", - chrom, - position, - rsid.as_deref().unwrap_or("."), - reference, - alternates.join(","), - hds.iter() - .map(|value| format_hds_value(*value)) - .collect::>() - .join(",") - ); - - Ok(ParsedVcfRow { - rsid, - chrom, - position, - reference, - alternates, - genotype, - raw_line, - }) -} - -fn extract_hds( - header: &vcf::Header, - record: &bcf::Record, - label: &str, -) -> Result, RuntimeError> { - let samples = record - .samples() - .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF samples: {err}")))?; - if let Some(values) = parse_first_bcf_float_series(samples.as_ref()) { - return Ok(values); - } - let Some(sample) = samples.get_index(0) else { - return Ok(Vec::new()); - }; - let Some(value) = sample - .get(header, "HDS") - .transpose() - .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF HDS: {err}")))? - .flatten() - else { - return Ok(Vec::new()); - }; - match value { - SampleValue::Array(Array::Float(values)) => values - .iter() - .filter_map(|result| { - result - .map_err(|err| { - RuntimeError::Io(format!("{label}: failed to read HDS value: {err}")) - }) - .transpose() - }) - .collect(), - SampleValue::Float(value) => Ok(vec![value]), - _ => Ok(Vec::new()), - } -} - -fn parse_first_bcf_float_series(src: &[u8]) -> Option> { - let mut offset = 0usize; - skip_bcf_typed_value(src, &mut offset)?; - let descriptor = *src.get(offset)?; - offset += 1; - let (len, ty) = bcf_descriptor_len_ty(src, descriptor, &mut offset)?; - if ty != 5 { - return None; - } - let mut values = Vec::with_capacity(len); - for _ in 0..len { - let bytes: [u8; 4] = src.get(offset..offset + 4)?.try_into().ok()?; - offset += 4; - let value = f32::from_le_bytes(bytes); - if !value.is_nan() { - values.push(value); - } - } - Some(values) -} - -fn skip_bcf_typed_value(src: &[u8], offset: &mut usize) -> Option<()> { - let descriptor = *src.get(*offset)?; - *offset += 1; - let (len, ty) = bcf_descriptor_len_ty(src, descriptor, offset)?; - let width = match ty { - 1 | 7 => 1, - 2 => 2, - 3 | 5 => 4, - _ => return None, - }; - *offset = offset.checked_add(len.checked_mul(width)?)?; - (*offset <= src.len()).then_some(()) -} - -fn bcf_descriptor_len_ty(src: &[u8], descriptor: u8, offset: &mut usize) -> Option<(usize, u8)> { - let ty = descriptor & 0x0f; - let mut len = usize::from(descriptor >> 4); - if len == 15 { - let len_descriptor = *src.get(*offset)?; - *offset += 1; - let (len_len, len_ty) = bcf_descriptor_len_ty(src, len_descriptor, offset)?; - if len_len != 1 { - return None; - } - len = match len_ty { - 1 => usize::from(*src.get(*offset)?), - 2 => { - let bytes: [u8; 2] = src.get(*offset..*offset + 2)?.try_into().ok()?; - usize::try_from(i16::from_le_bytes(bytes)).ok()? - } - 3 => { - let bytes: [u8; 4] = src.get(*offset..*offset + 4)?.try_into().ok()?; - usize::try_from(i32::from_le_bytes(bytes)).ok()? - } - _ => return None, - }; - *offset += match len_ty { - 1 => 1, - 2 => 2, - 3 => 4, - _ => return None, - }; - } - Some((len, ty)) -} - -fn genotype_from_hds(reference: &str, alternate: Option<&str>, hds: &[f32]) -> Option { - let alternate = alternate?; - if reference.is_empty() || alternate.is_empty() || hds.is_empty() { - return None; - } - let mut alleles = Vec::with_capacity(hds.len().max(2)); - for dosage in hds { - if *dosage >= 0.5 { - alleles.push(alternate.to_owned()); - } else { - alleles.push(reference.to_owned()); - } - } - if alleles.len() == 1 { - alleles.push(reference.to_owned()); - } - if alleles.iter().any(|allele| allele.len() > 1) { - return Some(alleles.join("/")); - } - Some(super::normalize_genotype(&alleles.join("/"))) -} - fn resolve_bcf_row( backend: &BcfBackend, row: &ParsedVcfRow, @@ -661,14 +376,3 @@ fn chrom_from_bcf_shard_name(name: &str) -> Option { .unwrap_or(chrom); (!chrom.is_empty()).then(|| chrom.to_owned()) } - -fn format_hds_value(value: f32) -> String { - if (value.fract()).abs() < f32::EPSILON { - format!("{value:.0}") - } else { - format!("{value:.3}") - .trim_end_matches('0') - .trim_end_matches('.') - .to_owned() - } -} diff --git a/rust/bioscript-formats/src/genotype/bcf/records.rs b/rust/bioscript-formats/src/genotype/bcf/records.rs new file mode 100644 index 0000000..351cb52 --- /dev/null +++ b/rust/bioscript-formats/src/genotype/bcf/records.rs @@ -0,0 +1,309 @@ +use std::io::Read; + +use bioscript_core::RuntimeError; +use noodles::{ + bcf, vcf, + vcf::variant::record::{ + AlternateBases as _, Ids as _, ReferenceBases as _, + samples::Sample as _, + samples::series::{Value as SampleValue, value::Array}, + }, +}; + +use super::{super::vcf::ParsedVcfRow, chrom_from_bcf_shard_name}; + +pub(super) fn read_bcf_header_lenient( + reader: &mut bcf::io::Reader, + label: &str, +) -> Result { + let mut header_reader = reader.header_reader(); + header_reader + .read_magic_number() + .map_err(|err| RuntimeError::Io(format!("failed to read BCF magic {label}: {err}")))?; + header_reader + .read_format_version() + .map_err(|err| RuntimeError::Io(format!("failed to read BCF version {label}: {err}")))?; + let mut raw_reader = header_reader + .raw_vcf_header_reader() + .map_err(|err| RuntimeError::Io(format!("failed to open BCF VCF header {label}: {err}")))?; + let mut raw = String::new(); + raw_reader + .read_to_string(&mut raw) + .map_err(|err| RuntimeError::Io(format!("failed to read BCF VCF header {label}: {err}")))?; + raw_reader.discard_to_end().map_err(|err| { + RuntimeError::Io(format!( + "failed to discard BCF VCF header padding {label}: {err}" + )) + })?; + + let sanitized = sanitize_bcf_vcf_header(&raw); + sanitized + .parse::() + .map_err(|err| RuntimeError::Io(format!("failed to parse BCF VCF header {label}: {err}"))) +} + +pub(super) fn bcf_record_to_vcf_row( + header: &vcf::Header, + string_maps: &vcf::header::StringMaps, + record: &bcf::Record, + label: &str, +) -> Result { + let chrom = record + .reference_sequence_name(string_maps) + .map(str::to_owned) + .or_else(|_| { + chrom_from_bcf_shard_name(label) + .map(|chrom| { + if chrom == "mt" { + "chrM".to_owned() + } else { + format!("chr{chrom}") + } + }) + .ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "missing reference sequence name in contig string map", + ) + }) + }) + .map_err(|err| { + RuntimeError::Io(format!("{label}: failed to read BCF chromosome: {err}")) + })?; + let position = i64::try_from( + record + .variant_start() + .transpose() + .map_err(|err| { + RuntimeError::Io(format!("{label}: failed to read BCF position: {err}")) + })? + .ok_or_else(|| RuntimeError::Io(format!("{label}: BCF record missing position")))? + .get(), + ) + .map_err(|_| RuntimeError::Io(format!("{label}: BCF position exceeds i64 range")))?; + let ids_buf = record.ids(); + let ids: Vec<&str> = ids_buf.iter().collect(); + let rsid = ids + .iter() + .find(|id| !id.is_empty() && **id != ".") + .map(|id| (*id).to_owned()); + let reference = String::from_utf8( + record + .reference_bases() + .iter() + .collect::, _>>() + .map_err(|err| { + RuntimeError::Io(format!( + "{label}: failed to read BCF reference bases: {err}" + )) + })?, + ) + .map_err(|err| RuntimeError::Io(format!("{label}: invalid BCF reference bases: {err}")))?; + let alternates = record + .alternate_bases() + .iter() + .map(|result| result.map(str::to_owned)) + .collect::, _>>() + .map_err(|err| { + RuntimeError::Io(format!( + "{label}: failed to read BCF alternate bases: {err}" + )) + })?; + let hds = extract_hds(header, record, label)?; + let genotype = genotype_from_hds(&reference, alternates.first().map(String::as_str), &hds) + .unwrap_or_else(|| "--".to_owned()); + let raw_line = format!( + "{} {} {} {} {} FORMAT=HDS HDS={}", + chrom, + position, + rsid.as_deref().unwrap_or("."), + reference, + alternates.join(","), + hds.iter() + .map(|value| format_hds_value(*value)) + .collect::>() + .join(",") + ); + + Ok(ParsedVcfRow { + rsid, + chrom, + position, + reference, + alternates, + genotype, + raw_line, + }) +} + +fn sanitize_bcf_vcf_header(raw: &str) -> String { + let is_23andme_imputed = raw.contains("##DISCLAIMER=") && raw.contains("23andMe"); + let mut inserted_23andme_contigs = false; + raw.lines() + .filter_map(|line| { + if is_23andme_imputed && line.starts_with("##contig=<") { + if inserted_23andme_contigs { + return None; + } + inserted_23andme_contigs = true; + return Some( + (1..=22) + .map(|chrom| format!("##contig=")) + .chain(std::iter::once("##contig=".to_owned())) + .collect::>() + .join("\n"), + ); + } + if line.starts_with("##FORMAT=<") + && line.contains("ID=HDS") + && !line.contains("Description=") + { + Some( + "##FORMAT=" + .to_owned(), + ) + } else { + Some(line.to_owned()) + } + }) + .collect::>() + .join("\n") +} + +fn extract_hds( + header: &vcf::Header, + record: &bcf::Record, + label: &str, +) -> Result, RuntimeError> { + let samples = record + .samples() + .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF samples: {err}")))?; + if let Some(values) = parse_first_bcf_float_series(samples.as_ref()) { + return Ok(values); + } + let Some(sample) = samples.get_index(0) else { + return Ok(Vec::new()); + }; + let Some(value) = sample + .get(header, "HDS") + .transpose() + .map_err(|err| RuntimeError::Io(format!("{label}: failed to read BCF HDS: {err}")))? + .flatten() + else { + return Ok(Vec::new()); + }; + match value { + SampleValue::Array(Array::Float(values)) => values + .iter() + .filter_map(|result| { + result + .map_err(|err| { + RuntimeError::Io(format!("{label}: failed to read HDS value: {err}")) + }) + .transpose() + }) + .collect(), + SampleValue::Float(value) => Ok(vec![value]), + _ => Ok(Vec::new()), + } +} + +fn parse_first_bcf_float_series(src: &[u8]) -> Option> { + let mut offset = 0usize; + skip_bcf_typed_value(src, &mut offset)?; + let descriptor = *src.get(offset)?; + offset += 1; + let (len, ty) = bcf_descriptor_len_ty(src, descriptor, &mut offset)?; + if ty != 5 { + return None; + } + let mut values = Vec::with_capacity(len); + for _ in 0..len { + let bytes: [u8; 4] = src.get(offset..offset + 4)?.try_into().ok()?; + offset += 4; + let value = f32::from_le_bytes(bytes); + if !value.is_nan() { + values.push(value); + } + } + Some(values) +} + +fn skip_bcf_typed_value(src: &[u8], offset: &mut usize) -> Option<()> { + let descriptor = *src.get(*offset)?; + *offset += 1; + let (len, ty) = bcf_descriptor_len_ty(src, descriptor, offset)?; + let width = match ty { + 1 | 7 => 1, + 2 => 2, + 3 | 5 => 4, + _ => return None, + }; + *offset = offset.checked_add(len.checked_mul(width)?)?; + (*offset <= src.len()).then_some(()) +} + +fn bcf_descriptor_len_ty(src: &[u8], descriptor: u8, offset: &mut usize) -> Option<(usize, u8)> { + let ty = descriptor & 0x0f; + let mut len = usize::from(descriptor >> 4); + if len == 15 { + let len_descriptor = *src.get(*offset)?; + *offset += 1; + let (len_len, len_ty) = bcf_descriptor_len_ty(src, len_descriptor, offset)?; + if len_len != 1 { + return None; + } + len = match len_ty { + 1 => usize::from(*src.get(*offset)?), + 2 => { + let bytes: [u8; 2] = src.get(*offset..*offset + 2)?.try_into().ok()?; + usize::try_from(i16::from_le_bytes(bytes)).ok()? + } + 3 => { + let bytes: [u8; 4] = src.get(*offset..*offset + 4)?.try_into().ok()?; + usize::try_from(i32::from_le_bytes(bytes)).ok()? + } + _ => return None, + }; + *offset += match len_ty { + 1 => 1, + 2 => 2, + 3 => 4, + _ => return None, + }; + } + Some((len, ty)) +} + +fn genotype_from_hds(reference: &str, alternate: Option<&str>, hds: &[f32]) -> Option { + let alternate = alternate?; + if reference.is_empty() || alternate.is_empty() || hds.is_empty() { + return None; + } + let mut alleles = Vec::with_capacity(hds.len().max(2)); + for dosage in hds { + if *dosage >= 0.5 { + alleles.push(alternate.to_owned()); + } else { + alleles.push(reference.to_owned()); + } + } + if alleles.len() == 1 { + alleles.push(reference.to_owned()); + } + if alleles.iter().any(|allele| allele.len() > 1) { + return Some(alleles.join("/")); + } + Some(super::super::normalize_genotype(&alleles.join("/"))) +} + +fn format_hds_value(value: f32) -> String { + if (value.fract()).abs() < f32::EPSILON { + format!("{value:.0}") + } else { + format!("{value:.3}") + .trim_end_matches('0') + .trim_end_matches('.') + .to_owned() + } +} diff --git a/rust/bioscript-formats/src/liftover.rs b/rust/bioscript-formats/src/liftover.rs index ed094ae..e4b9116 100644 --- a/rust/bioscript-formats/src/liftover.rs +++ b/rust/bioscript-formats/src/liftover.rs @@ -192,10 +192,11 @@ impl ChainIndex { let mut best: Option<&ChainBlock> = None; loop { let block = &chrom_blocks.blocks[i]; - if block.source_start <= pos0 && pos0 < block.source_end { - if best.is_none_or(|candidate| compare_blocks(block, candidate).is_gt()) { - best = Some(block); - } + if block.source_start <= pos0 + && pos0 < block.source_end + && best.is_none_or(|candidate| compare_blocks(block, candidate).is_gt()) + { + best = Some(block); } if let Some(candidate) = best @@ -322,18 +323,15 @@ pub fn convert_23andme_reader_with_chain( continue; } - let pos = match fields[2].parse::() { - Ok(pos) => pos, - Err(_) => { - stats.unmapped += 1; - writeln!( - unmapped, - "{}\t{}\t{}\t{}\tnon_integer_position", - fields[0], fields[1], fields[2], fields[3] - ) - .map_err(write_error("unmapped report"))?; - continue; - } + let Ok(pos) = fields[2].parse::() else { + stats.unmapped += 1; + writeln!( + unmapped, + "{}\t{}\t{}\t{}\tnon_integer_position", + fields[0], fields[1], fields[2], fields[3] + ) + .map_err(write_error("unmapped report"))?; + continue; }; let Some(lifted) = chain.lookup(Assembly::Grch37, Assembly::Grch38, &fields[1], pos) else { diff --git a/rust/bioscript-formats/tests/file_formats/bcf.rs b/rust/bioscript-formats/tests/file_formats/bcf.rs index 285f926..038d4c5 100644 --- a/rust/bioscript-formats/tests/file_formats/bcf.rs +++ b/rust/bioscript-formats/tests/file_formats/bcf.rs @@ -22,7 +22,25 @@ use noodles::vcf::{ }, }, }; -use std::io::{BufRead, BufReader}; +use std::{ + io::{BufRead, BufReader}, + path::Path, +}; + +type BcfRecord<'a> = (&'a str, i64, &'a str, &'a str, &'a str, &'a [f32]); + +struct LiftedVariants { + txt_genotypes: Vec, + variants: Vec, +} + +struct Concordance { + queried: usize, + found: usize, + matched: usize, + mismatched: usize, + examples: Vec, +} fn locus(chrom: &str, start: i64, end: i64) -> GenomicLocus { GenomicLocus { @@ -32,7 +50,7 @@ fn locus(chrom: &str, start: i64, end: i64) -> GenomicLocus { } } -fn bcf_bytes(records: &[(&str, i64, &str, &str, &str, &[f32])]) -> Vec { +fn bcf_bytes(records: &[BcfRecord<'_>]) -> Vec { let header = vcf::Header::builder() .add_filter("PASS", Map::::pass()) .add_contig("chr6", Map::::new()) @@ -73,6 +91,87 @@ fn bcf_bytes(records: &[(&str, i64, &str, &str, &str, &[f32])]) -> Vec { data } +fn lifted_text_variants(lifted: &Path) -> LiftedVariants { + let mut txt_genotypes = Vec::new(); + let mut variants = Vec::new(); + let file = fs::File::open(lifted).unwrap(); + for line in BufReader::new(file).lines() { + let line = line.unwrap(); + if line.is_empty() || line.starts_with('#') { + continue; + } + let fields: Vec<&str> = line.split('\t').collect(); + if fields.len() < 4 { + continue; + } + let chrom = fields[1]; + if matches!(chrom, "Y" | "MT" | "M") { + continue; + } + let genotype = fields[3].trim().to_ascii_uppercase(); + if !is_acgt_genotype(&genotype) { + continue; + } + let Ok(pos) = fields[2].parse::() else { + continue; + }; + txt_genotypes.push(normalized_acgt_genotype(&genotype)); + variants.push(VariantSpec { + rsids: vec![fields[0].to_owned()], + grch38: Some(locus(chrom, pos, pos)), + kind: Some(VariantKind::Snp), + ..VariantSpec::default() + }); + } + + LiftedVariants { + txt_genotypes, + variants, + } +} + +fn bcf_concordance( + bcf_zip: &Path, + variants: &[VariantSpec], + txt_genotypes: &[String], +) -> Concordance { + let bcf_store = GenotypeStore::from_file(bcf_zip).unwrap(); + let observations = bcf_store.lookup_variants(variants).unwrap(); + let mut concordance = Concordance { + queried: 0, + found: 0, + matched: 0, + mismatched: 0, + examples: Vec::new(), + }; + + for (idx, observation) in observations.iter().enumerate() { + concordance.queried += 1; + let Some(bcf_genotype) = observation.genotype.as_deref() else { + continue; + }; + concordance.found += 1; + if normalized_acgt_genotype(bcf_genotype) == txt_genotypes[idx] { + concordance.matched += 1; + } else { + concordance.mismatched += 1; + if concordance.examples.len() < 8 { + let locus = variants[idx].grch38.as_ref().unwrap(); + concordance.examples.push(format!( + "{} {}:{} txt={} bcf={}", + variants[idx].rsids[0], + locus.chrom, + locus.start, + txt_genotypes[idx], + bcf_genotype + )); + } + } + } + + concordance +} + #[test] fn individual_bcf_hds_records_are_readable_by_locus() { let dir = temp_dir("bcf-hds"); @@ -282,89 +381,42 @@ fn local_23andme_lifted_text_broadly_matches_real_bcf_zip_when_enabled() { let unmapped = dir.join("unmapped.tsv"); convert_23andme_grch37_to_grch38(&raw_txt, &lifted, &unmapped).unwrap(); - let mut txt_genotypes = Vec::new(); - let mut variants = Vec::new(); - let file = fs::File::open(&lifted).unwrap(); - for line in BufReader::new(file).lines() { - let line = line.unwrap(); - if line.is_empty() || line.starts_with('#') { - continue; - } - let fields: Vec<&str> = line.split('\t').collect(); - if fields.len() < 4 { - continue; - } - let chrom = fields[1]; - if matches!(chrom, "Y" | "MT" | "M") { - continue; - } - let genotype = fields[3].trim().to_ascii_uppercase(); - if genotype.is_empty() - || genotype == "--" - || !genotype - .chars() - .all(|base| matches!(base, 'A' | 'C' | 'G' | 'T')) - { - continue; - } - let Ok(pos) = fields[2].parse::() else { - continue; - }; - txt_genotypes.push(normalized_acgt_genotype(&genotype)); - variants.push(VariantSpec { - rsids: vec![fields[0].to_owned()], - grch38: Some(locus(chrom, pos, pos)), - kind: Some(VariantKind::Snp), - ..VariantSpec::default() - }); - } - - let bcf_store = GenotypeStore::from_file(&bcf_zip).unwrap(); - let observations = bcf_store.lookup_variants(&variants).unwrap(); - - let mut queried = 0usize; - let mut found = 0usize; - let mut matched = 0usize; - let mut mismatched = 0usize; - let mut examples = Vec::new(); - for (idx, observation) in observations.iter().enumerate() { - queried += 1; - let Some(bcf_genotype) = observation.genotype.as_deref() else { - continue; - }; - found += 1; - if normalized_acgt_genotype(bcf_genotype) == txt_genotypes[idx] { - matched += 1; - } else { - mismatched += 1; - if examples.len() < 8 { - let locus = variants[idx].grch38.as_ref().unwrap(); - examples.push(format!( - "{} {}:{} txt={} bcf={}", - variants[idx].rsids[0], - locus.chrom, - locus.start, - txt_genotypes[idx], - bcf_genotype - )); - } - } - } + let lifted_variants = lifted_text_variants(&lifted); + let concordance = bcf_concordance( + &bcf_zip, + &lifted_variants.variants, + &lifted_variants.txt_genotypes, + ); eprintln!( - "local 23andMe BCF broad concordance: queried={queried} found={found} matched={matched} mismatched={mismatched} missing={}", - queried - found + "local 23andMe BCF broad concordance: queried={queried} found={found} matched={matched} mismatched={mismatched} missing={missing}", + queried = concordance.queried, + found = concordance.found, + matched = concordance.matched, + mismatched = concordance.mismatched, + missing = concordance.queried - concordance.found ); - if !examples.is_empty() { - eprintln!("mismatch examples: {}", examples.join("; ")); + if !concordance.examples.is_empty() { + eprintln!("mismatch examples: {}", concordance.examples.join("; ")); } - assert!(queried > 500_000, "expected broad 23andMe SNP comparison"); assert!( - found > 500_000, + concordance.queried > 500_000, + "expected broad 23andMe SNP comparison" + ); + assert!( + concordance.found > 500_000, "expected most lifted SNPs to be present in BCF" ); } +fn is_acgt_genotype(genotype: &str) -> bool { + !genotype.is_empty() + && genotype != "--" + && genotype + .chars() + .all(|base| matches!(base, 'A' | 'C' | 'G' | 'T')) +} + fn normalized_acgt_genotype(genotype: &str) -> String { let mut chars: Vec = genotype .chars()