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]
22 #[pyo3(signature = (name, location, stochastic_noises, integration_time=None, light_time_correction=false, timestamp_noise_s=None))]
23 fn py_new(
24 name: String,
25 location: Location,
26 stochastic_noises: HashMap<MeasurementType, StochasticNoise>,
27 integration_time: Option<Duration>,
28 light_time_correction: Option<bool>,
29 timestamp_noise_s: Option<StochasticNoise>,
30 ) -> Self {
31 Self {
32 name,
33 location,
34 measurement_types: IndexSet::from_iter(
35 stochastic_noises
36 .keys()
37 .copied()
38 .collect::<Vec<MeasurementType>>(),
39 ),
40 integration_time,
41 light_time_correction: light_time_correction.unwrap_or(false),
42 timestamp_noise_s,
43 stochastic_noises: Some(stochastic_noises.into_iter().collect()),
44 }
45 }
46
47 #[classmethod]
52 #[pyo3(name = "from_yaml")]
53 fn py_from_yaml(_cls: &Bound<'_, pyo3::types::PyType>, yaml_str: &str) -> PyResult<Self> {
54 serde_yml::from_str(yaml_str)
55 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
56 }
57
58 #[pyo3(name = "to_yaml")]
60 fn py_to_yaml(&self) -> PyResult<String> {
61 serde_yml::to_string(self)
62 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
63 }
64
65 #[classmethod]
70 #[pyo3(name = "load_many_yaml")]
71 fn py_load_many_yaml(_cls: &Bound<'_, pyo3::types::PyType>, path: &str) -> PyResult<Vec<Self>> {
72 use crate::io::ConfigRepr;
73 Self::load_many(path).map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
74 }
75
76 #[classmethod]
81 #[pyo3(name = "loads_many_yaml")]
82 fn py_loads_many_yaml(
83 _cls: &Bound<'_, pyo3::types::PyType>,
84 yaml_str: &str,
85 ) -> PyResult<Vec<Self>> {
86 use crate::io::ConfigRepr;
87 Self::loads_many(yaml_str)
88 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
89 }
90
91 #[classmethod]
97 #[pyo3(name = "dump_many_yaml")]
98 fn py_dump_many_yaml(
99 _cls: &Bound<'_, pyo3::types::PyType>,
100 stations: Vec<Self>,
101 path: &str,
102 ) -> PyResult<()> {
103 let s = serde_yml::to_string(&stations)
104 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
105 std::fs::write(path, s).map_err(|e| pyo3::exceptions::PyIOError::new_err(e.to_string()))
106 }
107
108 #[classmethod]
113 #[pyo3(name = "dumps_many_yaml")]
114 fn py_dumps_many_yaml(
115 _cls: &Bound<'_, pyo3::types::PyType>,
116 stations: Vec<Self>,
117 ) -> PyResult<String> {
118 serde_yml::to_string(&stations)
119 .map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
120 }
121
122 #[getter]
123 pub fn get_name(&self) -> String {
124 self.name.clone()
125 }
126
127 #[setter]
128 pub fn set_name(&mut self, name: String) {
129 self.name = name;
130 }
131
132 #[getter]
133 pub fn get_location(&self) -> Location {
134 self.location.clone()
135 }
136
137 #[setter]
138 pub fn set_location(&mut self, location: Location) {
139 self.location = location;
140 }
141
142 #[getter]
143 pub fn get_integration_time(&self) -> Option<Duration> {
144 self.integration_time
145 }
146
147 #[setter]
148 pub fn set_integration_time(&mut self, integration_time: Option<Duration>) {
149 self.integration_time = integration_time;
150 }
151
152 #[getter]
153 pub fn get_light_time_correction(&self) -> bool {
154 self.light_time_correction
155 }
156
157 #[setter]
158 pub fn set_light_time_correction(&mut self, light_time_correction: bool) {
159 self.light_time_correction = light_time_correction;
160 }
161
162 #[getter]
163 pub fn get_timestamp_noise_s(&self) -> Option<StochasticNoise> {
164 self.timestamp_noise_s
165 }
166
167 #[setter]
168 pub fn set_timestamp_noise_s(&mut self, noise: Option<StochasticNoise>) {
169 self.timestamp_noise_s = noise;
170 }
171
172 #[getter]
173 pub fn get_measurement_types(&self) -> Vec<MeasurementType> {
174 self.measurement_types.iter().cloned().collect()
175 }
176
177 #[setter]
178 pub fn set_measurement_types(&mut self, types: Vec<MeasurementType>) {
179 self.measurement_types = types.into_iter().collect();
180 }
181
182 pub fn add_measurement_type(&mut self, msr_type: MeasurementType, noise: StochasticNoise) {
188 self.measurement_types.insert(msr_type);
189 self.stochastic_noises
190 .get_or_insert_with(IndexMap::new)
191 .insert(msr_type, noise);
192 }
193
194 pub fn remove_measurement_type(&mut self, msr_type: &MeasurementType) -> bool {
199 self.measurement_types.shift_remove(msr_type)
202 }
203
204 pub fn clear_measurement_types(&mut self) {
208 self.measurement_types.clear();
209 }
210
211 #[getter]
212 pub fn get_stochastic_noises(&self) -> Option<Vec<(MeasurementType, StochasticNoise)>> {
213 self.stochastic_noises
214 .as_ref()
215 .map(|map| map.iter().map(|(k, v)| (*k, *v)).collect())
216 }
217
218 pub fn get_stochastic_noise(&self, m_type: &MeasurementType) -> Option<StochasticNoise> {
223 self.stochastic_noises
224 .as_ref()
225 .and_then(|map| map.get(m_type).cloned())
226 }
227
228 pub fn set_stochastic_noise(&mut self, m_type: MeasurementType, noise: StochasticNoise) {
234 self.stochastic_noises
235 .get_or_insert_with(indexmap::IndexMap::new)
236 .insert(m_type, noise);
237 }
238
239 pub fn remove_stochastic_noise(&mut self, m_type: &MeasurementType) -> Option<StochasticNoise> {
244 self.stochastic_noises
245 .as_mut()
246 .and_then(|map| map.shift_remove(m_type))
247 }
248
249 pub fn clear_stochastic_noises(&mut self) {
253 self.stochastic_noises = None;
254 }
255
256 fn __str__(&self) -> String {
257 format!("{self}")
258 }
259
260 fn __repr__(&self) -> String {
261 format!("{self:?} @ {self:p}")
262 }
263
264 fn __eq__(&self, other: &Self) -> bool {
265 self == other
266 }
267}