Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bwa = ">=0.7.17"
skani = ">=0.2.2"
fastani = ">=1.3"
extern = "*"
x-mapper = "*"

# x86_64-specific dependencies
[target.linux-64.dependencies]
Expand Down
37 changes: 35 additions & 2 deletions src/bam_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub enum MappingProgram {
MINIMAP2_HIFI,
MINIMAP2_NO_PRESET,
STROBEALIGN,
X_MAPPER,
}

pub struct BamFileNamedReader {
Expand Down Expand Up @@ -415,7 +416,10 @@ pub fn generate_named_bam_readers_from_reads(

// Required because of https://github.com/wwood/CoverM/issues/58
let minimap2_log_file_index = match mapping_program {
MappingProgram::BWA_MEM | MappingProgram::BWA_MEM2 | MappingProgram::STROBEALIGN => None,
MappingProgram::BWA_MEM
| MappingProgram::BWA_MEM2
| MappingProgram::STROBEALIGN
| MappingProgram::X_MAPPER => None,
// Required because of https://github.com/lh3/minimap2/issues/527
MappingProgram::MINIMAP2_SR
| MappingProgram::MINIMAP2_ONT
Expand Down Expand Up @@ -864,6 +868,32 @@ pub fn build_mapping_command(
read2_path: Option<&str>,
mapping_options: Option<&str>,
) -> String {
if matches!(mapping_program, MappingProgram::X_MAPPER) {
let read_params = match read_format {
ReadFormat::Coupled => format!(
"--paired-queries '{}' '{}'",
read1_path,
read2_path.unwrap()
),
ReadFormat::Single => format!("--queries '{}'", read1_path),
ReadFormat::Interleaved => {
panic!("Interleaved reads are not supported by X-Mapper")
}
};
let mapping_options = mapping_options
.filter(|opts| !opts.is_empty())
.map(|opts| format!(" {opts}"))
.unwrap_or_default();
return format!(
"x-mapper{} --num-threads {} --reference '{}' {} --out-sam - | samtools calmd -S - '{}'",
mapping_options,
threads,
reference.index_path(),
read_params,
reference.index_path()
);
}

let read_params1 = match mapping_program {
// minimap2 auto-detects interleaved based on read names
MappingProgram::MINIMAP2_SR
Expand All @@ -879,6 +909,7 @@ pub fn build_mapping_command(
ReadFormat::Interleaved => "--interleaved",
ReadFormat::Coupled | ReadFormat::Single => "",
},
MappingProgram::X_MAPPER => unreachable!(),
};

let read_params2 = match read_format {
Expand All @@ -893,6 +924,7 @@ pub fn build_mapping_command(
MappingProgram::BWA_MEM => "bwa mem".to_string(),
MappingProgram::BWA_MEM2 => "bwa-mem2 mem".to_string(),
MappingProgram::STROBEALIGN => "strobealign".to_string(),
MappingProgram::X_MAPPER => unreachable!(),
_ => {
let split_prefix = tempfile::Builder::new()
.prefix("coverm-minimap2-split-index")
Expand All @@ -912,7 +944,8 @@ pub fn build_mapping_command(
match mapping_program {
MappingProgram::BWA_MEM
| MappingProgram::BWA_MEM2
| MappingProgram::STROBEALIGN => unreachable!(),
| MappingProgram::STROBEALIGN
| MappingProgram::X_MAPPER => unreachable!(),
MappingProgram::MINIMAP2_SR => "-x sr",
MappingProgram::MINIMAP2_ONT => "-x map-ont",
MappingProgram::MINIMAP2_HIFI => "-x map-hifi",
Expand Down
10 changes: 10 additions & 0 deletions src/bin/coverm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,12 @@ fn setup_mapping_index(
))
}
}
MappingProgram::X_MAPPER => {
info!("Not pre-generating x-mapper index");
Box::new(coverm::mapping_index_maintenance::VanillaIndexStruct::new(
reference_wise_params.reference,
))
}
}
}

Expand Down Expand Up @@ -879,6 +885,7 @@ fn parse_mapping_program(m: &clap::ArgMatches) -> MappingProgram {
Some("minimap2-hifi") => MappingProgram::MINIMAP2_HIFI,
Some("minimap2-no-preset") => MappingProgram::MINIMAP2_NO_PRESET,
Some("strobealign") => MappingProgram::STROBEALIGN,
Some("x-mapper") => MappingProgram::X_MAPPER,
None => DEFAULT_MAPPING_SOFTWARE_ENUM,
_ => panic!(
"Unexpected definition for --mapper: {:?}",
Expand All @@ -902,6 +909,9 @@ fn parse_mapping_program(m: &clap::ArgMatches) -> MappingProgram {
MappingProgram::STROBEALIGN => {
external_command_checker::check_for_strobealign();
}
MappingProgram::X_MAPPER => {
external_command_checker::check_for_x_mapper();
}
}
mapping_program
}
Expand Down
42 changes: 37 additions & 5 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const MAPPING_SOFTWARE_LIST: &[&str] = &[
"minimap2-hifi",
"minimap2-no-preset",
"strobealign",
"x-mapper",
];
const DEFAULT_MAPPING_SOFTWARE: &str = "strobealign";

Expand Down Expand Up @@ -86,11 +87,15 @@ fn add_mapping_options(manual: Manual) -> Manual {
&format!("minimap2 with '{}' option", &monospace_roff("-x map-hifi"))
],
&[
&monospace_roff("minimap2-no-preset"),
&format!("minimap2 with no '{}' option", &monospace_roff("-x"))
],
])
)))
&monospace_roff("minimap2-no-preset"),
&format!("minimap2 with no '{}' option", &monospace_roff("-x"))
],
&[
&monospace_roff("x-mapper"),
"x-mapper using default parameters"
],
])
)))
.option(Opt::new("PARAMS").long("--minimap2-params").help(&format!(
"Extra parameters to provide to minimap2, \
both indexing command (if used) and for \
Expand All @@ -113,6 +118,12 @@ fn add_mapping_options(manual: Manual) -> Manual {
"Extra parameters to provide to strobealign. Note \
that usage of this parameter has security \
implications if untrusted input is specified. \
[default: none]",
))
.option(Opt::new("PARAMS").long("--x-mapper-params").help(
"Extra parameters to provide to x-mapper. Note \
that usage of this parameter has security \
implications if untrusted input is specified. \
[default: none]",
))
.flag(Flag::new().long("--strobealign-use-index").help(
Expand Down Expand Up @@ -1233,6 +1244,13 @@ Ben J. Woodcroft <benjwoodcroft near gmail.com>
.allow_hyphen_values(true)
.requires("reference"),
)
.arg(
Arg::new("x-mapper-params")
.long("x-mapper-params")
.long("x-mapper-parameters")
.allow_hyphen_values(true)
.requires("reference"),
)
.arg(
Arg::new("strobealign-use-index")
.long("strobealign-use-index")
Expand Down Expand Up @@ -1768,6 +1786,13 @@ Ben J. Woodcroft <benjwoodcroft near gmail.com>
.allow_hyphen_values(true)
.requires("reference"),
)
.arg(
Arg::new("x-mapper-params")
.long("x-mapper-params")
.long("x-mapper-parameters")
.allow_hyphen_values(true)
.requires("reference"),
)
.arg(
Arg::new("strobealign-use-index")
.long("strobealign-use-index")
Expand Down Expand Up @@ -2146,6 +2171,13 @@ Ben J. Woodcroft <benjwoodcroft near gmail.com>
.allow_hyphen_values(true)
.requires("reference"),
)
.arg(
Arg::new("x-mapper-params")
.long("x-mapper-params")
.long("x-mapper-parameters")
.allow_hyphen_values(true)
.requires("reference"),
)
.arg(
Arg::new("strobealign-use-index")
.long("strobealign-use-index")
Expand Down
5 changes: 5 additions & 0 deletions src/external_command_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ pub fn check_for_strobealign() {
default_version_check("strobealign", "0.11.0", false, None)
.expect("Failed to find sufficient version of strobealign");
}

pub fn check_for_x_mapper() {
check_for_external_command_presence_with_which("x-mapper")
.expect("Failed to find installed x-mapper");
}
10 changes: 8 additions & 2 deletions src/mapping_index_maintenance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl TemporaryIndexStruct {
| MappingProgram::MINIMAP2_HIFI
| MappingProgram::MINIMAP2_NO_PRESET => std::process::Command::new("minimap2"),
MappingProgram::STROBEALIGN => std::process::Command::new("strobealign"),
MappingProgram::X_MAPPER => unreachable!(),
};
match &mapping_program {
MappingProgram::BWA_MEM | MappingProgram::BWA_MEM2 => {
Expand Down Expand Up @@ -96,7 +97,8 @@ impl TemporaryIndexStruct {
MappingProgram::MINIMAP2_NO_PRESET
| MappingProgram::BWA_MEM
| MappingProgram::BWA_MEM2
| MappingProgram::STROBEALIGN => {}
| MappingProgram::STROBEALIGN
| MappingProgram::X_MAPPER => {}
};
if let Some(t) = num_threads {
cmd.arg("-t").arg(format!("{t}"));
Expand All @@ -106,6 +108,9 @@ impl TemporaryIndexStruct {
MappingProgram::STROBEALIGN => {
warn!("STROBEALIGN pre-indexing is not supported currently, so skipping index generation.");
}
MappingProgram::X_MAPPER => {
warn!("X_MAPPER pre-indexing is not supported currently, so skipping index generation.");
}
};
if let Some(params) = index_creation_options {
for s in params.split_whitespace() {
Expand Down Expand Up @@ -201,7 +206,8 @@ pub fn check_reference_existence(reference_path: &str, mapping_program: &Mapping
| MappingProgram::MINIMAP2_HIFI
| MappingProgram::MINIMAP2_PB
| MappingProgram::MINIMAP2_NO_PRESET
| MappingProgram::STROBEALIGN => {}
| MappingProgram::STROBEALIGN
| MappingProgram::X_MAPPER => {}
};

if !ref_path.exists() {
Expand Down
9 changes: 9 additions & 0 deletions src/mapping_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ impl<'a> MappingParameters<'a> {
process::exit(1);
}
}
MappingProgram::X_MAPPER => {
if !interleaved.is_empty() {
error!(
"Interleaved read input specified to be mapped with x-mapper which is not supported."
);
process::exit(1);
}
}
_ => {}
}

Expand All @@ -122,6 +130,7 @@ impl<'a> MappingParameters<'a> {
| MappingProgram::MINIMAP2_PB
| MappingProgram::MINIMAP2_NO_PRESET => "minimap2-params",
MappingProgram::STROBEALIGN => "strobealign-params",
MappingProgram::X_MAPPER => "x-mapper-params",
};
let mapping_options = match m.contains_id(mapping_parameters_arg) {
true => {
Expand Down
Loading