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}