doris_rs/record/
measurement.rs1#[cfg(doc)]
2use crate::prelude::{TimeScale, DORIS};
3
4use crate::prelude::{ClockOffset, GroundStation, Matcher, Observable, Observation};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use itertools::Itertools;
10use std::collections::BTreeMap;
11
12#[derive(Clone, Debug, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15pub struct ObservationKey {
16 pub station: GroundStation,
18
19 pub observable: Observable,
21}
22
23#[derive(Clone, Debug, Default, PartialEq)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub struct Measurements {
27 pub satellite_clock_offset: Option<ClockOffset>,
29
30 pub observations: BTreeMap<ObservationKey, Observation>,
32}
33
34impl Measurements {
35 pub fn add_observation(
37 &mut self,
38 station: GroundStation,
39 observable: Observable,
40 observation: Observation,
41 ) {
42 self.observations.insert(
43 ObservationKey {
44 station,
45 observable,
46 },
47 observation,
48 );
49 }
50
51 pub fn with_observation(
53 &self,
54 station: GroundStation,
55 observable: Observable,
56 observation: Observation,
57 ) -> Self {
58 let mut s = self.clone();
59 s.observations.insert(
60 ObservationKey {
61 station,
62 observable,
63 },
64 observation,
65 );
66 s
67 }
68
69 pub fn observables(&self) -> Box<dyn Iterator<Item = Observable> + '_> {
71 Box::new(self.observations.keys().map(|k| k.observable).unique())
72 }
73
74 pub fn station_observables<'a>(
76 &'a self,
77 matcher: &'a Matcher<'a>,
78 ) -> Box<dyn Iterator<Item = Observable> + '_> {
79 Box::new(
80 self.observations
81 .keys()
82 .filter_map(|k| {
83 if k.station.matches(matcher) {
84 Some(k.observable)
85 } else {
86 None
87 }
88 })
89 .unique(),
90 )
91 }
92
93 pub fn with_satellite_clock_offset(&self, clock_offset: ClockOffset) -> Self {
95 let mut s = self.clone();
96 s.satellite_clock_offset = Some(clock_offset);
97 s
98 }
99}