1use std::fmt::Debug;
2use std::hash::Hash;
3use std::path::Path;
4use std::{fs::File, io::{BufReader, BufWriter}};
5
6use boomphf::hashmap::BoomHashMap2;
7use serde::{de::DeserializeOwned, Deserialize, Serialize};
8
9use crate::graph::DebruijnGraph;
10use crate::reads::{ReadData, ReadDatas};
11use crate::summarizer::{Summarizers, SummaryConfig, SummaryData, Translator};
12use crate::Kmer;
13use crate::{reads::ReadsPaired, Exts};
14
15#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
17pub struct SerReads<DI> {
18 reads: ReadsPaired<DI>,
19 read_datas: ReadDatas,
20 translator: Translator
21}
22
23impl<DI> SerReads<DI> {
24 pub fn new(reads: ReadsPaired<DI>, translator: Translator) -> SerReads<DI>
26 where DI: ReadData
27 {
28 SerReads {
29 reads,
30 read_datas: DI::read_datas(),
31 translator
32 }
33 }
34
35 pub fn serialize<P: AsRef<Path>>(&self, path: P)
37 where DI: Serialize
38 {
39 let file = File::create(path).expect("error creating file for serialized reads");
40 let writer = BufWriter::new(file);
41 bincode::serialize_into(writer, &self).expect("error serializing reads");
42 }
43
44 pub fn deserialize_from<P: AsRef<Path> + Debug>(path: P) -> SerReads<DI>
46 where DI: DeserializeOwned
47 {
48 let file = File::open(&path).expect("error opening file with serialized reads");
49 let reader = BufReader::new(file);
50
51 match bincode::deserialize_from(reader) {
52 Ok(ser_reads) => ser_reads,
53 Err(err) => panic!("Error deserializing cached reads: {}\n Make sure the file was cached with a compatible version and parameters. \nFile: {:?}", err, path)
54 }
55 }
56
57 pub fn reads(&self) -> &ReadsPaired<DI> {
59 &self.reads
60 }
61
62 pub fn translator(&self) -> &Translator {
64 &self.translator
65 }
66
67 pub fn parameters(&self) -> ReadDatas {
69 self.read_datas
70 }
71
72 pub fn dissolve(self) -> (ReadsPaired<DI>, Translator) {
74 (self.reads, self.translator)
75 }
76}
77
78
79#[derive(Debug, Serialize, Deserialize, Clone)]
81pub struct SerKmers<K: Hash, SD> {
82 kmers: BoomHashMap2<K, Exts, SD>,
83 k: usize,
84 summarizer: Summarizers,
85 translator: Translator,
86 config: SummaryConfig
87}
88
89impl<K: Kmer, SD> SerKmers<K, SD> {
90 pub fn new<DI>(kmers: BoomHashMap2<K, Exts, SD>, translator: Translator, config: SummaryConfig) -> SerKmers<K, SD>
92 where SD: SummaryData<DI>
93 {
94 SerKmers {
95 kmers,
96 summarizer: SD::summarizer(),
97 k: K::k(),
98 translator,
99 config
100 }
101 }
102
103 pub fn serialize<P: AsRef<Path>>(&self, path: P)
105 where
106 K: Serialize,
107 SD: Serialize
108 {
109 let file = File::create(path).expect("error creating file for serialized k-mers");
110 let writer = BufWriter::new(file);
111 bincode::serialize_into(writer, &self).expect("error serializing k-mers");
112 }
113
114 pub fn deserialize_from<P: AsRef<Path> + Debug, DI>(path: P) -> SerKmers<K, SD>
116 where
117 K: DeserializeOwned,
118 SD: DeserializeOwned + SummaryData<DI>
119 {
120 let file = File::open(&path).expect("error opening file with serialized k-mers");
121 let reader = BufReader::new(file);
122
123 let ser_kmers: SerKmers<K, SD> = match bincode::deserialize_from(reader) {
124 Ok(ser_kmers) => ser_kmers,
125 Err(err) => panic!("Error deserializing cached k-mers: {}\n Make sure the file was cached with a compatible version and parameters. \nFile: {:?}", err, path)
126 };
127
128 assert_eq!(ser_kmers.parameters().0, K::k(), "deserialized k-kmers do not match expected k");
129 assert_eq!(ser_kmers.parameters().1, SD::summarizer(), "deserialized k-mers do not match expected summarizer");
130
131 ser_kmers
132 }
133
134 pub fn kmers(&self) -> &BoomHashMap2<K, Exts, SD> {
136 &self.kmers
137 }
138
139 pub fn translator(&self) -> &Translator {
141 &self.translator
142 }
143
144 pub fn config(&self) -> &SummaryConfig {
146 &self.config
147 }
148
149 pub fn parameters(&self) -> (usize, Summarizers) {
151 (self.k, self.summarizer)
152 }
153
154 pub fn dissolve(self) -> (BoomHashMap2<K, Exts, SD>, Translator, SummaryConfig) {
156 (self.kmers, self.translator, self.config)
157 }
158}
159
160#[derive(Debug, Serialize, Deserialize)]
162pub struct SerGraph<K: Hash, SD> {
163 graph: DebruijnGraph<K, SD>,
164 summarizer: Summarizers,
165 k: usize,
166 translator: Translator,
167 config: SummaryConfig
168}
169
170impl<K: Kmer, SD> SerGraph<K, SD> {
171 pub fn new<DI>(graph: DebruijnGraph<K, SD>, translator: Translator, config: SummaryConfig) -> SerGraph<K, SD>
173 where SD: SummaryData<DI>
174 {
175 SerGraph {
176 graph,
177 summarizer: SD::summarizer(),
178 k: K::k(),
179 translator,
180 config
181 }
182 }
183
184 pub fn serialize<P: AsRef<Path>>(&self, path: P)
186 where
187 K: Serialize,
188 SD: Serialize
189 {
190 let file = File::create(path).expect("error creating file for a serialized graph");
191 let writer = BufWriter::new(file);
192 bincode::serialize_into(writer, &self).expect("error serializing graph");
193 }
194
195 pub fn deserialize_from<P: AsRef<Path> + Debug, DI>(path: P) -> SerGraph<K, SD>
197 where
198 K: DeserializeOwned,
199 SD: DeserializeOwned + SummaryData<DI>
200 {
201 let file = File::open(&path).expect("error opening file with a serialized graph");
202 let reader = BufReader::new(file);
203
204 let ser_graph: SerGraph<K, SD> = match bincode::deserialize_from(reader) {
205 Ok(ser_graph) => ser_graph,
206 Err(err) => panic!("Error deserializing cached graph: {}\n Make sure the file was cached with a compatible version and parameters. \n File: {:?}", err, path)
207 };
208
209 assert_eq!(ser_graph.parameters().0, K::k(), "deserialized k-kmers do not match expected k");
210 assert_eq!(ser_graph.parameters().1, SD::summarizer(), "deserialized k-mers do not match expected summarizer");
211
212 ser_graph
213 }
214
215 pub fn graph(&self) -> &DebruijnGraph<K, SD> {
217 &self.graph
218 }
219
220 pub fn translator(&self) -> &Translator {
222 &self.translator
223 }
224 pub fn config(&self) -> &SummaryConfig {
226 &self.config
227 }
228
229 pub fn parameters(&self) -> (usize, Summarizers) {
231 (self.k, self.summarizer)
232 }
233
234 pub fn dissolve(self) -> (DebruijnGraph<K, SD>, Translator, SummaryConfig) {
236 (self.graph, self.translator, self.config)
237 }
238}
239
240#[cfg(test)]
241mod test {
242 use std::fs::remove_file;
243
244 use crate::{kmer::Kmer16, reads::ReadDatas, serde::{SerGraph, SerKmers}, summarizer::{IDSumData, IDTag, Summarizers}, test::build_test_graph};
245
246 use super::SerReads;
247
248 #[test]
249 fn test_ser_reads() {
250 let (ser_reads, _, _) = build_test_graph::<Kmer16, IDSumData, _>();
251
252 let cloned_ser_reads = ser_reads.clone();
253
254 let all = ser_reads.dissolve();
255 assert_eq!(cloned_ser_reads.reads(), &all.0);
256 assert_eq!(cloned_ser_reads.translator(), &all.1);
257 assert_eq!(cloned_ser_reads.parameters(), ReadDatas::IDTag);
258
259 let ser_reads = SerReads::new(all.0, all.1);
260 let ser_path = "test_data/new_ser_reads";
261 ser_reads.serialize(ser_path);
262
263 let new_ser_reads: SerReads<IDTag> = SerReads::deserialize_from(ser_path);
264 assert_eq!(ser_reads, new_ser_reads);
265 remove_file(ser_path).unwrap();
266 }
267
268 #[test]
269 fn test_ser_kmers() {
270 let (_, ser_kmers, _) = build_test_graph::<Kmer16, IDSumData, _>();
271
272 let cloned_ser_kmers = ser_kmers.clone();
273
274 let all = ser_kmers.dissolve();
275 assert_eq!(cloned_ser_kmers.kmers().len(), all.0.len());
276 assert_eq!(cloned_ser_kmers.translator(), &all.1);
277 assert_eq!(cloned_ser_kmers.config(), &all.2);
278 assert_eq!(cloned_ser_kmers.parameters(), (16, Summarizers::IDSumData));
279
280 let ser_kmers = SerKmers::new(all.0, all.1, all.2);
281 let ser_path = "test_data/new_ser_kmers";
282 ser_kmers.serialize(ser_path);
283
284 let new_ser_kmers: SerKmers<Kmer16, IDSumData> = SerKmers::deserialize_from(ser_path);
285 assert_eq!(ser_kmers.kmers().len(), new_ser_kmers.kmers().len());
286 assert_eq!(ser_kmers.translator(), new_ser_kmers.translator());
287 assert_eq!(ser_kmers.config(), new_ser_kmers.config());
288
289 remove_file(ser_path).unwrap();
290 }
291
292 #[test]
293 fn test_ser_graph() {
294 let (_, _, ser_graph) = build_test_graph::<Kmer16, IDSumData, _>();
295
296 let all = ser_graph.dissolve();
297
298 let ser_graph = SerGraph::new(all.0, all.1, all.2);
299 let ser_path = "test_data/new_ser_graph";
300 ser_graph.serialize(ser_path);
301
302 let new_ser_kmers: SerGraph<Kmer16, IDSumData> = SerGraph::deserialize_from(ser_path);
303 assert_eq!(ser_graph.graph().len(), new_ser_kmers.graph().len());
304 assert_eq!(ser_graph.translator(), new_ser_kmers.translator());
305 assert_eq!(ser_graph.config(), new_ser_kmers.config());
306 assert_eq!(ser_graph.parameters(), (16, Summarizers::IDSumData));
307
308 remove_file(ser_path).unwrap();
309 }
310}
311