diff --git a/docs/coverm-contig.html b/docs/coverm-contig.html index 9fcac82..f3fca67 100644 --- a/docs/coverm-contig.html +++ b/docs/coverm-contig.html @@ -197,6 +197,10 @@

MAPPING ALGORITHM OPTIONS

minimap2 with '-x map-hifi' option +minimap2-lr-hq +minimap2 with '-x lr:hq' option + + minimap2-no-preset minimap2 with no '-x' option diff --git a/docs/coverm-genome.html b/docs/coverm-genome.html index e8b7362..54bd6c1 100644 --- a/docs/coverm-genome.html +++ b/docs/coverm-genome.html @@ -378,6 +378,10 @@

MAPPING ALGORITHM OPTIONS

minimap2 with '-x map-hifi' option +minimap2-lr-hq +minimap2 with '-x lr:hq' option + + minimap2-no-preset minimap2 with no '-x' option diff --git a/docs/coverm-make.html b/docs/coverm-make.html index 82360f2..c5ac44a 100644 --- a/docs/coverm-make.html +++ b/docs/coverm-make.html @@ -178,6 +178,10 @@

MAPPING ALGORITHM OPTIONS

minimap2 with '-x map-hifi' option +minimap2-lr-hq +minimap2 with '-x lr:hq' option + + minimap2-no-preset minimap2 with no '-x' option diff --git a/src/bam_generator.rs b/src/bam_generator.rs index e428af9..5c1b953 100644 --- a/src/bam_generator.rs +++ b/src/bam_generator.rs @@ -51,6 +51,7 @@ pub enum MappingProgram { MINIMAP2_ONT, MINIMAP2_PB, MINIMAP2_HIFI, + MINIMAP2_LR_HQ, MINIMAP2_NO_PRESET, STROBEALIGN, } @@ -421,6 +422,7 @@ pub fn generate_named_bam_readers_from_reads( | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_PB | MappingProgram::MINIMAP2_HIFI + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => Some(0), }; @@ -870,6 +872,7 @@ pub fn build_mapping_command( | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_HIFI | MappingProgram::MINIMAP2_PB + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => "", MappingProgram::BWA_MEM | MappingProgram::BWA_MEM2 => match read_format { ReadFormat::Interleaved => "-p", @@ -917,6 +920,7 @@ pub fn build_mapping_command( MappingProgram::MINIMAP2_ONT => "-x map-ont", MappingProgram::MINIMAP2_HIFI => "-x map-hifi", MappingProgram::MINIMAP2_PB => "-x map-pb", + MappingProgram::MINIMAP2_LR_HQ => "-x lr:hq", MappingProgram::MINIMAP2_NO_PRESET => "", } ) diff --git a/src/bin/coverm.rs b/src/bin/coverm.rs index 76fe0ca..1fa08e8 100644 --- a/src/bin/coverm.rs +++ b/src/bin/coverm.rs @@ -774,6 +774,7 @@ fn setup_mapping_index( | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_HIFI | MappingProgram::MINIMAP2_PB + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => { if m.get_flag("minimap2-reference-is-index") || reference_wise_params.len() == 1 { info!("Not pre-generating minimap2 index"); @@ -877,6 +878,7 @@ fn parse_mapping_program(m: &clap::ArgMatches) -> MappingProgram { Some("minimap2-ont") => MappingProgram::MINIMAP2_ONT, Some("minimap2-pb") => MappingProgram::MINIMAP2_PB, Some("minimap2-hifi") => MappingProgram::MINIMAP2_HIFI, + Some("minimap2-lr-hq") => MappingProgram::MINIMAP2_LR_HQ, Some("minimap2-no-preset") => MappingProgram::MINIMAP2_NO_PRESET, Some("strobealign") => MappingProgram::STROBEALIGN, None => DEFAULT_MAPPING_SOFTWARE_ENUM, @@ -896,6 +898,7 @@ fn parse_mapping_program(m: &clap::ArgMatches) -> MappingProgram { | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_HIFI | MappingProgram::MINIMAP2_PB + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => { external_command_checker::check_for_minimap2(); } diff --git a/src/cli.rs b/src/cli.rs index a3839e2..bba577d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -18,6 +18,7 @@ const MAPPING_SOFTWARE_LIST: &[&str] = &[ "minimap2-ont", "minimap2-pb", "minimap2-hifi", + "minimap2-lr-hq", "minimap2-no-preset", "strobealign", ]; @@ -85,6 +86,10 @@ fn add_mapping_options(manual: Manual) -> Manual { &monospace_roff("minimap2-hifi"), &format!("minimap2 with '{}' option", &monospace_roff("-x map-hifi")) ], + &[ + &monospace_roff("minimap2-lr-hq"), + &format!("minimap2 with '{}' option", &monospace_roff("-x lr:hq")) + ], &[ &monospace_roff("minimap2-no-preset"), &format!("minimap2 with no '{}' option", &monospace_roff("-x")) diff --git a/src/coverage_printer.rs b/src/coverage_printer.rs index 80b084e..b766a19 100644 --- a/src/coverage_printer.rs +++ b/src/coverage_printer.rs @@ -197,9 +197,8 @@ pub fn print_sparse_cached_coverage_taker( } coverage_totals[*i] = Some(total_coverage); - if reads_mapped_per_sample.is_some() { - let reads_mapped = - &reads_mapped_per_sample.as_ref().unwrap()[current_stoit_index]; + if let Some(reads_mapped_per_sample) = reads_mapped_per_sample.as_ref() { + let reads_mapped = &reads_mapped_per_sample[current_stoit_index]; let fraction_mapped = reads_mapped.num_mapped_reads as f32 / reads_mapped.num_reads as f32; coverage_multipliers[*i] = Some(fraction_mapped); diff --git a/src/mapping_index_maintenance.rs b/src/mapping_index_maintenance.rs index 6b590f9..64f6c3f 100644 --- a/src/mapping_index_maintenance.rs +++ b/src/mapping_index_maintenance.rs @@ -65,6 +65,7 @@ impl TemporaryIndexStruct { | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_PB | MappingProgram::MINIMAP2_HIFI + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => std::process::Command::new("minimap2"), MappingProgram::STROBEALIGN => std::process::Command::new("strobealign"), }; @@ -79,6 +80,7 @@ impl TemporaryIndexStruct { | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_HIFI | MappingProgram::MINIMAP2_PB + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => { match &mapping_program { MappingProgram::MINIMAP2_SR => { @@ -93,6 +95,9 @@ impl TemporaryIndexStruct { MappingProgram::MINIMAP2_PB => { cmd.arg("-x").arg("map-pb"); } + MappingProgram::MINIMAP2_LR_HQ => { + cmd.arg("-x").arg("lr:hq"); + } MappingProgram::MINIMAP2_NO_PRESET | MappingProgram::BWA_MEM | MappingProgram::BWA_MEM2 @@ -180,7 +185,7 @@ fn check_for_bwa_index_existence(reference_path: &str, mapping_program: &Mapping if num_existing == 0 { false } else if num_existing == num_extensions { - return true; + true } else { error!("BWA index appears to be incomplete, cannot continue."); process::exit(1); @@ -200,6 +205,7 @@ pub fn check_reference_existence(reference_path: &str, mapping_program: &Mapping | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_HIFI | MappingProgram::MINIMAP2_PB + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET | MappingProgram::STROBEALIGN => {} }; diff --git a/src/mapping_parameters.rs b/src/mapping_parameters.rs index 596d744..c762152 100644 --- a/src/mapping_parameters.rs +++ b/src/mapping_parameters.rs @@ -99,11 +99,13 @@ impl<'a> MappingParameters<'a> { match mapping_program { MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_PB - | MappingProgram::MINIMAP2_HIFI => { + | MappingProgram::MINIMAP2_HIFI + | MappingProgram::MINIMAP2_LR_HQ => { if !read1.is_empty() || !interleaved.is_empty() { error!( "Paired-end read input specified to be mapped \ - with minimap2-ont, minimap2-pb, or minimap2-hifi which is presumably \ + with minimap2-ont, minimap2-pb, minimap2-hifi, or minimap2-lr-hq \ + which is presumably \ incorrect. Mapping paired reads can be run via \ minimap2-no-params if -ont or -pb mapping \ is desired." @@ -120,6 +122,7 @@ impl<'a> MappingParameters<'a> { | MappingProgram::MINIMAP2_ONT | MappingProgram::MINIMAP2_HIFI | MappingProgram::MINIMAP2_PB + | MappingProgram::MINIMAP2_LR_HQ | MappingProgram::MINIMAP2_NO_PRESET => "minimap2-params", MappingProgram::STROBEALIGN => "strobealign-params", }; @@ -239,27 +242,27 @@ impl<'a> Iterator for SingleReferenceMappingParameters<'a> { } else if self.iter_interleaved_index < self.interleaved.len() { let i = self.iter_interleaved_index; self.iter_interleaved_index += 1; - return Some(OneSampleMappingParameters { + Some(OneSampleMappingParameters { reference: self.reference, read_format: ReadFormat::Interleaved, read1: self.interleaved[i], read2: None, threads: self.threads, mapping_options: self.mapping_options, - }); + }) } else if self.iter_unpaired_index < self.unpaired.len() { let i = self.iter_unpaired_index; self.iter_unpaired_index += 1; - return Some(OneSampleMappingParameters { + Some(OneSampleMappingParameters { reference: self.reference, read_format: ReadFormat::Single, read1: self.unpaired[i], read2: None, threads: self.threads, mapping_options: self.mapping_options, - }); + }) } else { - return None; + None } } } diff --git a/tests/test_cmdline.rs b/tests/test_cmdline.rs index 50752ab..b89f95c 100644 --- a/tests/test_cmdline.rs +++ b/tests/test_cmdline.rs @@ -1875,6 +1875,57 @@ genome6 26.697144 .unwrap(); } + #[test] + fn test_lr_hq_single_sample_two_zero_means() { + Assert::main_binary() + .with_args(&[ + "contig", + "-m", + "mean", + "-p", + "minimap2-lr-hq", + "--single", + "tests/data/2seqs.fasta", + "-r", + "tests/data/7seqs.fna", + ]) + .succeeds() + .stdout() + .satisfies( + |observed| { + let mut lines = observed.lines(); + let header = lines.next().unwrap_or(""); + assert!( + header.starts_with("Contig\t"), + "Unexpected header: {header}", + header = header + ); + + let mut total = 0; + let mut zero_means = 0; + for line in lines { + let fields: Vec<&str> = line.split('\t').collect(); + assert_eq!( + fields.len(), + 2, + "Expected contig and mean columns in '{line}'" + ); + let mean: f64 = fields[1].parse().unwrap(); + if mean == 0.0 { + zero_means += 1; + } + total += 1; + } + + assert_eq!(total, 7, "Expected 7 contig rows"); + assert_eq!(zero_means, 2, "Expected 2 zero-mean contigs"); + true + }, + "unexpected output", + ) + .unwrap(); + } + #[test] fn test_ont_two_samples() { // Also tests that -t is being set when minimap2 indexing