-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathlib.rs
151 lines (134 loc) · 4.16 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//!
//! # A*PA library
//!
//! This crate is the entrypoint of the A*PA library.
//! It can be used in a few ways. From simple to generic:
//! - `astarpa(a,b)`
//! - `astarpa_gcsh(a,b,r,k,Prune)`
//! - `make_aligner(dt: bool, h: HeuristicParams).align(a,b)`
//! - `AstarPa{ dt: bool, h: Heuristic, v: VisualizerT}.align(a,b)`
//! The last 2 methods create an aligner object that can be reused.
//!
#![feature(
test,
duration_constants,
step_trait,
int_roundings,
iter_intersperse,
slice_as_chunks,
let_chains,
is_sorted,
exclusive_range_pattern,
associated_type_defaults,
// If you get compile errors here, make sure to be on at least rust 1.72.
// Before, this was called `drain_filter`.
extract_if
)]
mod alignment_graph;
mod astar;
mod astar_dt;
mod bucket_queue;
mod config;
#[cfg(test)]
mod tests;
pub mod stats;
mod prelude {
pub use pa_types::*;
pub use rustc_hash::FxHashMap as HashMap;
pub use crate::config::*;
}
use pa_heuristic::seeds::MatchCost;
use pa_heuristic::{Heuristic, HeuristicMapper, Prune};
use pa_heuristic::{MatchConfig, Pruning, GCSH};
use pa_types::{Aligner, Cigar, Cost, Seq, I};
use pa_vis::{NoVis, VisualizerT};
use stats::AstarStats;
// ------------ Root alignment interface follows from here ------------
pub use astar::{astar, astar_with_vis};
pub use astar_dt::astar_dt;
pub use pa_heuristic::HeuristicParams;
/// Align using default settings:
/// - Gap-cost chaining seed heuristic (GCSH)
/// - with diagonal transition (DT)
/// - inexact matches (r=2)
/// - seed length k=15
/// - prune by start only.
pub fn astarpa(a: Seq, b: Seq) -> (Cost, Cigar) {
astarpa_gcsh(a, b, 2, 15, Prune::Start)
}
/// Align using GCSH with DT, with custom parameters.
/// - r=1 instead of r=2 can be used when the error rate is low.
/// - pruning by start *and* end (`Prune::Both`) can help for higher error rates where there are not many spurious matches.
pub fn astarpa_gcsh(a: Seq, b: Seq, r: MatchCost, k: I, pruning: Prune) -> (Cost, Cigar) {
astar_dt::astar_dt(
a,
b,
&GCSH::new(MatchConfig::new(k, r), Pruning::new(pruning)),
&NoVis,
)
.0
}
/// Build an `AstarStatsAligner` instance from
pub fn make_aligner(dt: bool, h: &HeuristicParams) -> Box<dyn AstarStatsAligner> {
make_aligner_with_visualizer(dt, h, NoVis)
}
/// Build a type-erased aligner object from parameters.
pub fn make_aligner_with_visualizer<V: VisualizerT + 'static>(
dt: bool,
h: &HeuristicParams,
v: V,
) -> Box<dyn AstarStatsAligner> {
struct Mapper<V: VisualizerT> {
dt: bool,
v: V,
}
impl<V: VisualizerT + 'static> HeuristicMapper for Mapper<V> {
type R = Box<dyn AstarStatsAligner>;
fn call<H: Heuristic + 'static>(self, h: H) -> Box<dyn AstarStatsAligner> {
Box::new(AstarPa {
dt: self.dt,
h,
v: self.v,
})
}
}
h.map(Mapper { dt, v })
}
/// Align using a reusable object containing all parameters.
#[derive(Debug)]
pub struct AstarPa<V: VisualizerT, H: Heuristic> {
pub dt: bool,
pub h: H,
pub v: V,
}
impl<H: Heuristic> AstarPa<NoVis, H> {
pub fn new(dt: bool, h: H) -> Self {
AstarPa { dt, h, v: NoVis }
}
}
impl<V: VisualizerT, H: Heuristic> AstarPa<V, H> {
pub fn align(&self, a: Seq, b: Seq) -> ((Cost, Cigar), AstarStats) {
if self.dt {
astar_dt(a, b, &self.h, &self.v)
} else {
astar(a, b, &self.h, &self.v)
}
}
}
/// Helper trait to erase the type of the heuristic that additionally returns alignment statistics.
pub trait AstarStatsAligner: Aligner {
fn align(&self, a: Seq, b: Seq) -> ((Cost, Cigar), AstarStats);
}
// Implement aligner traits.
impl<V: VisualizerT, H: Heuristic> AstarStatsAligner for AstarPa<V, H> {
fn align(&self, a: Seq, b: Seq) -> ((Cost, Cigar), AstarStats) {
self.align(a, b)
}
}
/// A simple aligner interface.
impl<V: VisualizerT, H: Heuristic> Aligner for AstarPa<V, H> {
fn align(&mut self, a: Seq, b: Seq) -> (Cost, Option<Cigar>) {
let ((cost, cigar), _stats) = AstarPa::align(self, a, b);
(cost, Some(cigar))
}
}