1use clap::Parser;
2use minimap2::*;
3use needletail::{FastxReader, parse_fastx_file};
4use rayon::prelude::*;
5
6use std::path::PathBuf;
7use std::{error::Error, path::Path};
8
9#[derive(Parser, Debug)]
10#[command(
11 name = "minimap2-channels-example",
12 about = "An example of how to use the minimap2 crate with multithreading"
13)]
14struct Cli {
15 pub target: PathBuf,
17
18 pub query: PathBuf,
20
21 pub threads: usize,
23}
24
25fn main() {
26 let args = Cli::parse();
28
29 map(args.target, args.query, args.threads).expect("Unable to map");
30}
31
32fn map(
33 target_file: impl AsRef<Path>,
34 query_file: impl AsRef<Path>,
35 threads: usize,
36) -> Result<(), Box<dyn Error>> {
37 rayon::ThreadPoolBuilder::new()
39 .num_threads(threads)
40 .build_global()
41 .expect("Unable to set number of threads");
42
43 println!("Creating index");
44
45 let aligner = Aligner::builder()
48 .map_ont()
49 .with_cigar()
50 .with_index_threads(threads) .with_index(target_file, None)
52 .expect("Unable to build index");
53
54 println!("Index created");
55
56 let mut reader = parse_fastx_file(query_file)?;
58
59 let mut queries: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
60 while let Some(record) = reader.next() {
61 let record = record.expect("Error reading record");
62 queries.push((record.id().to_vec(), record.seq().to_vec()));
63 }
64
65 let results: Vec<Vec<Mapping>> = queries
67 .par_iter()
68 .map(|(id, seq)| {
69 aligner
70 .map(&seq, false, false, None, None, Some(&id))
71 .expect("Error mapping")
72 })
73 .collect();
74
75 let total_alignments: usize = results.iter().map(|x| x.len()).sum();
77 println!("Iteration complete, total alignments {}", total_alignments);
78
79 Ok(())
80}