use clap::Parser;
use minimap2::*;
use needletail::{FastxReader, parse_fastx_file};
use rayon::prelude::*;
use std::path::PathBuf;
use std::{error::Error, path::Path};
#[derive(Parser, Debug)]
#[command(
name = "minimap2-channels-example",
about = "An example of how to use the minimap2 crate with multithreading"
)]
struct Cli {
pub target: PathBuf,
pub query: PathBuf,
pub threads: usize,
}
fn main() {
let args = Cli::parse();
map(args.target, args.query, args.threads).expect("Unable to map");
}
fn map(
target_file: impl AsRef<Path>,
query_file: impl AsRef<Path>,
threads: usize,
) -> Result<(), Box<dyn Error>> {
rayon::ThreadPoolBuilder::new()
.num_threads(threads)
.build_global()
.expect("Unable to set number of threads");
println!("Creating index");
let aligner = Aligner::builder()
.map_ont()
.with_cigar()
.with_index_threads(threads) .with_index(target_file, None)
.expect("Unable to build index");
println!("Index created");
let mut reader = parse_fastx_file(query_file)?;
let mut queries: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
while let Some(record) = reader.next() {
let record = record.expect("Error reading record");
queries.push((record.id().to_vec(), record.seq().to_vec()));
}
let results: Vec<Vec<Mapping>> = queries
.par_iter()
.map(|(id, seq)| {
aligner
.map(&seq, false, false, None, None, Some(&id))
.expect("Error mapping")
})
.collect();
let total_alignments: usize = results.iter().map(|x| x.len()).sum();
println!("Iteration complete, total alignments {}", total_alignments);
Ok(())
}