nyx_space/od/ground_station/
python.rs1use super::super::msr::MeasurementType;
2use super::super::noise::StochasticNoise;
3use super::GroundStation;
4use anise::astro::Location;
5use hifitime::Duration;
6use indexmap::{IndexMap, IndexSet};
7use pyo3::prelude::*;
8use std::collections::HashMap;
9
10#[cfg(feature = "python")]
11#[pymethods]
12impl GroundStation {
13 #[new]
14 #[pyo3(signature = (name, location, stochastic_noises, integration_time=None, light_time_correction=false, timestamp_noise_s=None))]
15 fn py_new(
16 name: String,
17 location: Location,
18 stochastic_noises: HashMap<MeasurementType, StochasticNoise>,
19 integration_time: Option<Duration>,
20 light_time_correction: Option<bool>,
21 timestamp_noise_s: Option<StochasticNoise>,
22 ) -> Self {
23 Self {
24 name,
25 location,
26 measurement_types: IndexSet::from_iter(
27 stochastic_noises
28 .keys()
29 .copied()
30 .collect::<Vec<MeasurementType>>(),
31 ),
32 integration_time,
33 light_time_correction: light_time_correction.unwrap_or(false),
34 timestamp_noise_s,
35 stochastic_noises: Some(stochastic_noises.into_iter().collect()),
36 }
37 }
38
39 #[classmethod]
40 #[pyo3(name = "from_yaml")]
41 fn py_from_yaml(_cls: &Bound<'_, pyo3::types::PyType>, yaml_str: &str) -> PyResult<Self> {
42 serde_yml::from_str(yaml_str)
43 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
44 }
45
46 #[pyo3(name = "to_yaml")]
47 fn py_to_yaml(&self) -> PyResult<String> {
48 serde_yml::to_string(self)
49 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
50 }
51
52 #[classmethod]
53 #[pyo3(name = "load_many_yaml")]
54 fn py_load_many_yaml(_cls: &Bound<'_, pyo3::types::PyType>, path: &str) -> PyResult<Vec<Self>> {
55 use crate::io::ConfigRepr;
56 Self::load_many(path).map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
57 }
58
59 #[classmethod]
60 #[pyo3(name = "loads_many_yaml")]
61 fn py_loads_many_yaml(
62 _cls: &Bound<'_, pyo3::types::PyType>,
63 yaml_str: &str,
64 ) -> PyResult<Vec<Self>> {
65 use crate::io::ConfigRepr;
66 Self::loads_many(yaml_str)
67 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
68 }
69
70 #[classmethod]
71 #[pyo3(name = "dump_many_yaml")]
72 fn py_dump_many_yaml(
73 _cls: &Bound<'_, pyo3::types::PyType>,
74 stations: Vec<Self>,
75 path: &str,
76 ) -> PyResult<()> {
77 let s = serde_yml::to_string(&stations)
78 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
79 std::fs::write(path, s).map_err(|e| pyo3::exceptions::PyIOError::new_err(e.to_string()))
80 }
81
82 #[classmethod]
83 #[pyo3(name = "dumps_many_yaml")]
84 fn py_dumps_many_yaml(
85 _cls: &Bound<'_, pyo3::types::PyType>,
86 stations: Vec<Self>,
87 ) -> PyResult<String> {
88 serde_yml::to_string(&stations)
89 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
90 }
91
92 #[getter]
93 pub fn get_name(&self) -> String {
94 self.name.clone()
95 }
96
97 #[setter]
98 pub fn set_name(&mut self, name: String) {
99 self.name = name;
100 }
101
102 #[getter]
103 pub fn get_location(&self) -> Location {
104 self.location.clone()
105 }
106
107 #[setter]
108 pub fn set_location(&mut self, location: Location) {
109 self.location = location;
110 }
111
112 #[getter]
113 pub fn get_integration_time(&self) -> Option<Duration> {
114 self.integration_time
115 }
116
117 #[setter]
118 pub fn set_integration_time(&mut self, integration_time: Option<Duration>) {
119 self.integration_time = integration_time;
120 }
121
122 #[getter]
123 pub fn get_light_time_correction(&self) -> bool {
124 self.light_time_correction
125 }
126
127 #[setter]
128 pub fn set_light_time_correction(&mut self, light_time_correction: bool) {
129 self.light_time_correction = light_time_correction;
130 }
131
132 #[getter]
133 pub fn get_timestamp_noise_s(&self) -> Option<StochasticNoise> {
134 self.timestamp_noise_s
135 }
136
137 #[setter]
138 pub fn set_timestamp_noise_s(&mut self, noise: Option<StochasticNoise>) {
139 self.timestamp_noise_s = noise;
140 }
141
142 #[getter]
143 pub fn get_measurement_types(&self) -> Vec<MeasurementType> {
144 self.measurement_types.iter().cloned().collect()
145 }
146
147 #[setter]
148 pub fn set_measurement_types(&mut self, types: Vec<MeasurementType>) {
149 self.measurement_types = types.into_iter().collect();
150 }
151
152 pub fn add_measurement_type(&mut self, msr_type: MeasurementType, noise: StochasticNoise) {
153 self.measurement_types.insert(msr_type);
154 self.stochastic_noises
155 .get_or_insert_with(IndexMap::new)
156 .insert(msr_type, noise);
157 }
158
159 pub fn remove_measurement_type(&mut self, msr_type: &MeasurementType) -> bool {
160 self.measurement_types.shift_remove(msr_type)
163 }
164
165 pub fn clear_measurement_types(&mut self) {
166 self.measurement_types.clear();
167 }
168
169 #[getter]
170 pub fn get_stochastic_noises(&self) -> Option<Vec<(MeasurementType, StochasticNoise)>> {
171 self.stochastic_noises
172 .as_ref()
173 .map(|map| map.iter().map(|(k, v)| (*k, *v)).collect())
174 }
175
176 pub fn get_stochastic_noise(&self, m_type: &MeasurementType) -> Option<StochasticNoise> {
177 self.stochastic_noises
178 .as_ref()
179 .and_then(|map| map.get(m_type).cloned())
180 }
181
182 pub fn set_stochastic_noise(&mut self, m_type: MeasurementType, noise: StochasticNoise) {
183 self.stochastic_noises
184 .get_or_insert_with(indexmap::IndexMap::new)
185 .insert(m_type, noise);
186 }
187
188 pub fn remove_stochastic_noise(&mut self, m_type: &MeasurementType) -> Option<StochasticNoise> {
189 self.stochastic_noises
190 .as_mut()
191 .and_then(|map| map.shift_remove(m_type))
192 }
193
194 pub fn clear_stochastic_noises(&mut self) {
195 self.stochastic_noises = None;
196 }
197
198 fn __str__(&self) -> String {
199 format!("{self}")
200 }
201
202 fn __repr__(&self) -> String {
203 format!("{self:?} @ {self:p}")
204 }
205
206 fn __eq__(&self, other: &Self) -> bool {
207 self == other
208 }
209}