sp3/processing/
decimation.rs1use qc_traits::{Decimate, DecimationFilter, DecimationFilterType};
2
3use crate::prelude::{Epoch, Header, SP3};
4
5impl Decimate for Header {
6 fn decimate(&self, f: &DecimationFilter) -> Self {
7 let mut s = self.clone();
8 s.decimate_mut(f);
9 s
10 }
11 fn decimate_mut(&mut self, f: &DecimationFilter) {
12 match f.filter {
13 DecimationFilterType::Duration(interval) => {
14 self.sampling_period = std::cmp::max(self.sampling_period, interval);
15 },
16 DecimationFilterType::Modulo(modulo) => {
17 self.sampling_period = self.sampling_period * modulo as f64;
18 },
19 }
20 }
21}
22
23impl Decimate for SP3 {
24 fn decimate(&self, f: &DecimationFilter) -> Self {
25 let mut s = self.clone();
26 s.decimate_mut(&f);
27 s
28 }
29 fn decimate_mut(&mut self, f: &DecimationFilter) {
30 if f.item.is_some() {
31 todo!("targetted decimation not supported yet");
32 }
33 self.header.decimate_mut(f);
34
35 match f.filter {
36 DecimationFilterType::Modulo(modulo) => {
37 let mut i = 0;
38 self.data.retain(|_, _| {
39 let retained = (i % modulo) == 0;
40 i += 1;
41 retained
42 });
43 },
44 DecimationFilterType::Duration(interval) => {
45 let mut last_retained = Option::<Epoch>::None;
46 self.data.retain(|k, _| {
47 if let Some(last) = last_retained {
48 let dt = k.epoch - last;
49 if dt >= interval {
50 last_retained = Some(k.epoch);
51 true
52 } else {
53 false
54 }
55 } else {
56 last_retained = Some(k.epoch);
57 true
58 }
59 });
60 },
61 }
62 }
63}