1use std::fmt::Write;
2use std::path::Path;
3
4use rsomics_common::{Result, RsomicsError};
5
6pub fn align(reference: &Path, query: &Path, preset: &str) -> Result<String> {
7 let mm_preset = match preset {
8 "sr" => minimap2::Preset::Sr,
9 "map-hifi" => minimap2::Preset::MapHifi,
10 "map-pb" => minimap2::Preset::MapPb,
11 _ => minimap2::Preset::MapOnt,
12 };
13
14 let aligner = minimap2::Aligner::builder()
15 .preset(mm_preset)
16 .with_index(reference.to_str().unwrap_or(""), None)
17 .map_err(|e| RsomicsError::InvalidInput(format!("building index: {e}")))?;
18
19 let seqs = std::fs::read_to_string(query)
20 .map_err(|e| RsomicsError::InvalidInput(format!("{}: {e}", query.display())))?;
21
22 let mut output = String::new();
23 for record in seqs.split('>').skip(1) {
24 let mut lines = record.lines();
25 let name = lines.next().unwrap_or("unknown");
26 let seq: String = lines.collect();
27
28 let mappings = aligner
29 .map(
30 seq.as_bytes(),
31 false,
32 false,
33 None,
34 None,
35 Some(name.as_bytes()),
36 )
37 .map_err(|e| RsomicsError::InvalidInput(format!("mapping: {e}")))?;
38
39 for m in mappings {
40 writeln!(output, "{m:?}").ok();
41 }
42 }
43
44 Ok(output)
45}