nyx_space/od/msr/trackingdata/
python.rs1use super::{Measurement, MeasurementType, TrackingDataArc};
20use crate::io::{ExportCfg, InputOutputError};
21use hifitime::{Duration, Epoch};
22use pyo3::prelude::*;
23use pyo3::types::PyType;
24use std::collections::HashMap;
25use std::ops::Bound::{Excluded, Included, Unbounded};
26
27#[pymethods]
28impl TrackingDataArc {
29 #[new]
30 fn py_new(measurements: Vec<Measurement>) -> Self {
31 let mut trk_data = Self {
32 measurements,
33 source: None,
34 moduli: None,
35 force_reject: false,
36 };
37
38 trk_data.sort();
39
40 trk_data
41 }
42
43 #[classmethod]
49 #[pyo3(name = "from_ccsds_tdm")]
50 fn py_from_ccsds_tdm_file(
51 _cls: Bound<'_, PyType>,
52 path: &str,
53 aliases: Option<HashMap<String, String>>,
54 ) -> Result<Self, InputOutputError> {
55 TrackingDataArc::from_tdm(path, aliases)
56 }
57
58 #[classmethod]
63 #[pyo3(name = "from_parquet")]
64 fn py_from_parquet(_cls: Bound<'_, PyType>, path: &str) -> Result<Self, InputOutputError> {
65 Self::from_parquet(path)
66 }
67
68 #[pyo3(name = "write_ccsds_tdm")]
75 fn py_write_ccsds_tdm(
76 &self,
77 spacecraft_name: String,
78 aliases: Option<HashMap<String, String>>,
79 path: &str,
80 ) -> Result<String, InputOutputError> {
81 Ok(self
82 .clone()
83 .to_tdm_file(spacecraft_name, aliases, path, ExportCfg::default())?
84 .to_str()
85 .unwrap_or("woah_bug_building_path")
86 .to_string())
87 }
88
89 #[pyo3(name = "unique_aliases")]
91 fn py_unique_aliases(&self) -> Vec<String> {
92 self.unique_aliases().iter().cloned().collect()
93 }
94 #[pyo3(name = "unique_types")]
96 fn py_unique_types(&self) -> Vec<MeasurementType> {
97 self.unique_types().iter().cloned().collect()
98 }
99
100 fn merge(&mut self, other: Self) {
101 *self = self.clone() + other;
102 }
103
104 fn __str__(&self) -> String {
105 format!("{self}")
106 }
107
108 fn __repr__(&self) -> String {
109 format!("{self} @ {self:p}")
110 }
111
112 fn __add__(&self, other: Self) -> Self {
113 self.clone() + other
114 }
115
116 #[getter]
117 fn get_force_reject(&self) -> bool {
118 self.force_reject
119 }
120
121 #[setter]
122 fn set_force_reject(&mut self, reject: bool) {
123 self.force_reject = reject;
124 }
125
126 #[pyo3(name = "filter_by_epoch")]
132 fn py_filter_by_epoch(&self, start: Option<Epoch>, end: Option<Epoch>) -> Self {
133 let start_bound = start.map(Included).unwrap_or(Unbounded);
134 let end_bound = end.map(Excluded).unwrap_or(Unbounded);
135 self.clone().filter_by_epoch((start_bound, end_bound))
136 }
137
138 #[pyo3(name = "filter_by_offset")]
144 fn py_filter_by_offset(&self, start: Option<Duration>, end: Option<Duration>) -> Self {
145 let start_bound = match start {
146 Some(s) => Included(s),
147 None => Unbounded,
148 };
149 let end_bound = match end {
150 Some(e) => Excluded(e),
151 None => Unbounded,
152 };
153 self.clone().filter_by_offset((start_bound, end_bound))
154 }
155
156 #[pyo3(name = "filter_by_tracker")]
161 fn py_filter_by_tracker(&self, tracker: String) -> Self {
162 self.clone().filter_by_tracker(tracker)
163 }
164
165 #[pyo3(name = "filter_by_measurement_type")]
170 fn py_filter_by_measurement_type(&self, msr_type: MeasurementType) -> Self {
171 self.clone().filter_by_measurement_type(msr_type)
172 }
173
174 #[pyo3(name = "exclude_tracker")]
179 fn py_exclude_tracker(&self, tracker: String) -> Self {
180 self.clone().exclude_tracker(tracker)
181 }
182
183 #[pyo3(name = "exclude_by_epoch")]
189 fn py_exclude_by_epoch(&self, start: Option<Epoch>, end: Option<Epoch>) -> Self {
190 let start_bound = match start {
191 Some(s) => Included(s),
192 None => Unbounded,
193 };
194 let end_bound = match end {
195 Some(e) => Excluded(e),
196 None => Unbounded,
197 };
198 self.clone().exclude_by_epoch((start_bound, end_bound))
199 }
200
201 #[pyo3(name = "exclude_measurement_type")]
206 fn py_exclude_measurement_type(&self, msr_type: MeasurementType) -> Self {
207 self.clone().exclude_measurement_type(msr_type)
208 }
209
210 #[pyo3(name = "resid_vs_ref_check")]
212 fn py_resid_vs_ref_check(&self) -> Self {
213 self.clone().resid_vs_ref_check()
214 }
215
216 #[pyo3(signature = (path, cfg=None))]
222 #[pyo3(name = "to_parquet")]
223 fn py_to_parquet(
224 &self,
225 path: String,
226 cfg: Option<ExportCfg>,
227 ) -> Result<String, InputOutputError> {
228 self.to_parquet(path, cfg.unwrap_or_default())
229 .map(|pathbuf| pathbuf.to_string_lossy().into_owned())
230 }
231}