doris_rs/record/
formatting.rs

1use crate::{
2    epoch::format as format_epoch,
3    error::FormattingError,
4    prelude::{Epoch, EpochFlag, GroundStation, Header, Key, Record},
5};
6
7use std::io::{BufWriter, Write};
8
9impl Record {
10    /// Format this DORIS [Record] according to the standard specifications,
11    /// into [W]ritable interface.
12    pub fn format<W: Write>(
13        &self,
14        writer: &mut BufWriter<W>,
15        header: &Header,
16    ) -> Result<(), FormattingError> {
17        let num_observables = header.observables.len();
18
19        // browse in chronological order
20        for (epoch, flag) in self.epochs_iter() {
21            write!(writer, "> {}00  {}", format_epoch(epoch), flag)?;
22
23            // determine number of station at this epoch
24            let mut num_stations = 0;
25            let mut prev_code = 0;
26
27            for station in header.ground_stations.iter() {
28                let key = Key {
29                    epoch,
30                    flag,
31                    station: station.clone(),
32                };
33
34                if self.measurements.get(&key).is_some() {
35                    num_stations += 1;
36                }
37
38                prev_code = station.code;
39            }
40
41            write!(writer, "{:3}", num_stations)?;
42
43            match flag {
44                EpochFlag::OK | EpochFlag::PowerFailure => {
45                    // browse by station ID#
46                    for station in header.ground_stations.iter() {
47                        let key = Key {
48                            epoch,
49                            flag,
50                            station: station.clone(),
51                        };
52
53                        if let Some(measurements) = self.measurements.get(&key) {
54                            // conclude with clock offset (if any)
55                            if let Some(clock_offset) = measurements.satellite_clock_offset {
56                                write!(
57                                    writer,
58                                    "{:13.3} {}\n",
59                                    clock_offset.offset.to_seconds(),
60                                    clock_offset.extrapolated as u8
61                                )?;
62                            } else {
63                                write!(writer, "\n")?;
64                            }
65
66                            // browse by observables specs
67                            for (nth_observable, hd_observable) in
68                                header.observables.iter().enumerate()
69                            {
70                                if nth_observable == 0 {
71                                    write!(writer, "D{:02}", station.code)?;
72                                }
73
74                                if let Some(observation) = measurements
75                                    .observations
76                                    .iter()
77                                    .filter_map(|(observable, observation)| {
78                                        if observable == hd_observable {
79                                            Some(observation)
80                                        } else {
81                                            None
82                                        }
83                                    })
84                                    .reduce(|k, _| k)
85                                {
86                                    write!(writer, "{:14.3}  ", observation.value)?;
87
88                                    if nth_observable == num_observables - 1 {
89                                        write!(writer, "\n")?;
90                                    } else {
91                                        if (nth_observable % 5) == 4 {
92                                            write!(writer, "\n   ")?;
93                                        }
94                                    }
95                                }
96                            }
97                        }
98                    }
99                },
100                todo => {
101                    // TODO not supported yet
102                },
103            }
104        }
105
106        Ok(())
107    }
108}