lorikeet_genome/graphs/
multi_sample_edge.rs1use std::cmp::Reverse;
2use std::collections::BinaryHeap;
3use std::hash::{Hash, Hasher};
4
5use crate::graphs::base_edge::BaseEdge;
6
7#[derive(Debug, Clone)]
28pub struct MultiSampleEdge {
29 current_single_sample_multiplicity: usize,
30 single_sample_capacity: usize,
31 single_sample_multiplicities: BinaryHeap<Reverse<usize>>,
32 reference_path_indexes: Vec<usize>,
33 pub(crate) multiplicity: usize,
34 pub(crate) is_ref: bool,
35}
36
37impl Hash for MultiSampleEdge {
38 fn hash<H: Hasher>(&self, state: &mut H) {
39 self.reference_path_indexes.hash(state);
40 self.multiplicity.hash(state);
41 self.is_ref.hash(state);
42 self.single_sample_capacity.hash(state);
43 }
44}
45
46impl PartialEq for MultiSampleEdge {
47 fn eq(&self, other: &Self) -> bool {
48 self.reference_path_indexes == other.reference_path_indexes
49 && self.is_ref == other.is_ref
50 && self.multiplicity == other.multiplicity
51 && self.single_sample_capacity == other.single_sample_capacity
52 }
53}
54
55impl Eq for MultiSampleEdge {}
56
57impl MultiSampleEdge {
58 pub fn set(&mut self, is_ref: bool, multiplicity: usize, single_sample_capacity: usize) {
59 let mut single_sample_multiplicities = BinaryHeap::with_capacity(single_sample_capacity);
60 single_sample_multiplicities.push(Reverse(multiplicity));
61 self.multiplicity = multiplicity;
62 self.is_ref = is_ref;
63 self.single_sample_capacity = single_sample_capacity;
64 self.single_sample_multiplicities = single_sample_multiplicities;
65 self.current_single_sample_multiplicity = multiplicity;
66 self.reference_path_indexes = Vec::with_capacity(2);
67 }
68
69 pub fn flush_single_sample_multiplicity(&mut self) {
74 self.single_sample_multiplicities
75 .push(Reverse(self.current_single_sample_multiplicity));
76 if self.single_sample_multiplicities.len() == self.single_sample_capacity + 1 {
77 self.single_sample_multiplicities.pop();
79 } else if self.single_sample_multiplicities.len() > self.single_sample_capacity + 1 {
80 panic!(
81 "Somehow the per sample multiplicity list has grown too big: {:?}",
82 self.single_sample_multiplicities
83 );
84 }
85
86 self.current_single_sample_multiplicity = 0;
87 }
88
89 pub fn inc_multiplicity(&mut self, incr: usize) {
90 self.multiplicity += incr;
91 self.current_single_sample_multiplicity += incr;
92 }
93
94 pub fn get_pruning_multiplicity(&self) -> usize {
95 self.single_sample_multiplicities.peek().unwrap().0
96 }
97
98 pub fn add_reference_index(&mut self, i: usize) {
99 self.reference_path_indexes.push(i)
100 }
101
102 pub fn get_reference_path_indexes(&self) -> &Vec<usize> {
103 &self.reference_path_indexes
104 }
105
106 pub fn get_current_single_sample_multiplicity(&self) -> usize {
107 self.current_single_sample_multiplicity
108 }
109}
110
111impl BaseEdge for MultiSampleEdge {
112 fn new(is_ref: bool, multiplicity: usize, single_sample_capacity: usize) -> MultiSampleEdge {
120 let mut single_sample_multiplicities = BinaryHeap::with_capacity(single_sample_capacity);
121 single_sample_multiplicities.push(Reverse(multiplicity));
122
123 MultiSampleEdge {
124 multiplicity,
125 is_ref,
126 single_sample_multiplicities,
127 single_sample_capacity,
128 current_single_sample_multiplicity: multiplicity,
129 reference_path_indexes: Vec::with_capacity(2),
130 }
131 }
132
133 fn get_multiplicity(&self) -> usize {
138 self.multiplicity
139 }
140
141 fn get_dot_label(&self) -> String {
146 return format!(
147 "{}/{}",
148 self.multiplicity.to_string(),
149 self.get_pruning_multiplicity()
150 );
151 }
152
153 fn inc_multiplicity(&mut self, incr: usize) {
158 self.multiplicity += incr
159 }
160
161 fn get_pruning_multiplicity(&self) -> usize {
167 self.single_sample_multiplicities.peek().unwrap().0
168 }
169
170 fn set_multiplicity(&mut self, value: usize) {
175 self.multiplicity = value
176 }
177
178 fn is_ref(&self) -> bool {
183 return self.is_ref;
184 }
185
186 fn set_is_ref(&mut self, is_ref: bool) {
191 self.is_ref = is_ref
192 }
193
194 fn add(&mut self, edge: Self) {
204 self.multiplicity += edge.multiplicity;
205 self.is_ref = self.is_ref || edge.is_ref;
206 }
207
208 fn make_o_r_edge(edges: Vec<Self>, multiplicity: usize, single_sample_capacity: usize) -> Self {
217 assert!(!edges.is_empty(), "Edges cannot be empty");
218 let is_ref = edges.iter().any(|e| e.is_ref());
219
220 Self::new(is_ref, multiplicity, single_sample_capacity)
221 }
222
223 fn to_string(&self) -> String {
224 return format!(
225 "BaseEdge{{multiplicity={}, isRef={}}}",
226 self.multiplicity, self.is_ref
227 );
228 }
229}