rscm_core/python/
spatial.rs1use crate::spatial::{
2 FourBoxGrid, FourBoxRegion, HemisphericGrid, HemisphericRegion, ScalarGrid, ScalarRegion,
3 SpatialGrid,
4};
5use pyo3::prelude::*;
6use pyo3::{pymodule, Bound, PyResult};
7
8#[pyclass]
9#[pyo3(name = "ScalarRegion")]
10#[derive(Clone, Copy)]
11pub struct PyScalarRegion(pub ScalarRegion);
12
13#[pymethods]
14impl PyScalarRegion {
15 #[classattr]
16 const GLOBAL: usize = ScalarRegion::Global as usize;
17
18 fn __repr__(&self) -> String {
19 "ScalarRegion.GLOBAL".to_string()
20 }
21}
22
23#[pyclass]
24#[pyo3(name = "FourBoxRegion")]
25#[derive(Clone, Copy)]
26pub struct PyFourBoxRegion(pub FourBoxRegion);
27
28#[pymethods]
29impl PyFourBoxRegion {
30 #[classattr]
31 const NORTHERN_OCEAN: usize = FourBoxRegion::NorthernOcean as usize;
32
33 #[classattr]
34 const NORTHERN_LAND: usize = FourBoxRegion::NorthernLand as usize;
35
36 #[classattr]
37 const SOUTHERN_OCEAN: usize = FourBoxRegion::SouthernOcean as usize;
38
39 #[classattr]
40 const SOUTHERN_LAND: usize = FourBoxRegion::SouthernLand as usize;
41
42 fn __repr__(&self) -> String {
43 match self.0 {
44 FourBoxRegion::NorthernOcean => "FourBoxRegion.NORTHERN_OCEAN".to_string(),
45 FourBoxRegion::NorthernLand => "FourBoxRegion.NORTHERN_LAND".to_string(),
46 FourBoxRegion::SouthernOcean => "FourBoxRegion.SOUTHERN_OCEAN".to_string(),
47 FourBoxRegion::SouthernLand => "FourBoxRegion.SOUTHERN_LAND".to_string(),
48 }
49 }
50}
51
52#[pyclass]
53#[pyo3(name = "HemisphericRegion")]
54#[derive(Clone, Copy)]
55pub struct PyHemisphericRegion(pub HemisphericRegion);
56
57#[pymethods]
58impl PyHemisphericRegion {
59 #[classattr]
60 const NORTHERN: usize = HemisphericRegion::Northern as usize;
61
62 #[classattr]
63 const SOUTHERN: usize = HemisphericRegion::Southern as usize;
64
65 fn __repr__(&self) -> String {
66 match self.0 {
67 HemisphericRegion::Northern => "HemisphericRegion.NORTHERN".to_string(),
68 HemisphericRegion::Southern => "HemisphericRegion.SOUTHERN".to_string(),
69 }
70 }
71}
72
73#[pyclass]
74#[pyo3(name = "ScalarGrid")]
75#[derive(Clone)]
76pub struct PyScalarGrid(pub ScalarGrid);
77
78#[pymethods]
79impl PyScalarGrid {
80 #[new]
81 fn new() -> Self {
82 Self(ScalarGrid)
83 }
84
85 fn __repr__(&self) -> String {
86 format!("<ScalarGrid size={}>", self.0.size())
87 }
88
89 fn grid_name(&self) -> &'static str {
90 self.0.grid_name()
91 }
92
93 fn size(&self) -> usize {
94 self.0.size()
95 }
96
97 fn region_names(&self) -> Vec<String> {
98 self.0.region_names().to_vec()
99 }
100
101 fn aggregate_global(&self, values: Vec<f64>) -> f64 {
102 self.0.aggregate_global(&values)
103 }
104}
105
106#[pyclass]
107#[pyo3(name = "FourBoxGrid")]
108#[derive(Clone)]
109pub struct PyFourBoxGrid(pub FourBoxGrid);
110
111#[pymethods]
112impl PyFourBoxGrid {
113 #[new]
114 #[pyo3(signature = (weights=None))]
115 fn new(weights: Option<[f64; 4]>) -> Self {
116 match weights {
117 Some(w) => Self(FourBoxGrid::with_weights(w)),
118 None => Self(FourBoxGrid::magicc_standard()),
119 }
120 }
121
122 #[staticmethod]
123 fn magicc_standard() -> Self {
124 Self(FourBoxGrid::magicc_standard())
125 }
126
127 #[staticmethod]
128 fn with_weights(weights: [f64; 4]) -> Self {
129 Self(FourBoxGrid::with_weights(weights))
130 }
131
132 fn __repr__(&self) -> String {
133 format!("<FourBoxGrid size={}>", self.0.size())
134 }
135
136 fn grid_name(&self) -> &'static str {
137 self.0.grid_name()
138 }
139
140 fn size(&self) -> usize {
141 self.0.size()
142 }
143
144 fn region_names(&self) -> Vec<String> {
145 self.0.region_names().to_vec()
146 }
147
148 fn weights(&self) -> [f64; 4] {
149 *self.0.weights()
150 }
151
152 fn aggregate_global(&self, values: Vec<f64>) -> f64 {
153 self.0.aggregate_global(&values)
154 }
155}
156
157#[pyclass]
158#[pyo3(name = "HemisphericGrid")]
159#[derive(Clone)]
160pub struct PyHemisphericGrid(pub HemisphericGrid);
161
162#[pymethods]
163impl PyHemisphericGrid {
164 #[new]
165 #[pyo3(signature = (weights=None))]
166 fn new(weights: Option<[f64; 2]>) -> Self {
167 match weights {
168 Some(w) => Self(HemisphericGrid::with_weights(w)),
169 None => Self(HemisphericGrid::equal_weights()),
170 }
171 }
172
173 #[staticmethod]
174 fn equal_weights() -> Self {
175 Self(HemisphericGrid::equal_weights())
176 }
177
178 #[staticmethod]
179 fn with_weights(weights: [f64; 2]) -> Self {
180 Self(HemisphericGrid::with_weights(weights))
181 }
182
183 fn __repr__(&self) -> String {
184 format!("<HemisphericGrid size={}>", self.0.size())
185 }
186
187 fn grid_name(&self) -> &'static str {
188 self.0.grid_name()
189 }
190
191 fn size(&self) -> usize {
192 self.0.size()
193 }
194
195 fn region_names(&self) -> Vec<String> {
196 self.0.region_names().to_vec()
197 }
198
199 fn weights(&self) -> [f64; 2] {
200 *self.0.weights()
201 }
202
203 fn aggregate_global(&self, values: Vec<f64>) -> f64 {
204 self.0.aggregate_global(&values)
205 }
206}
207
208#[pymodule]
209pub fn spatial(m: &Bound<'_, PyModule>) -> PyResult<()> {
210 m.add_class::<PyScalarRegion>()?;
211 m.add_class::<PyScalarGrid>()?;
212 m.add_class::<PyFourBoxRegion>()?;
213 m.add_class::<PyFourBoxGrid>()?;
214 m.add_class::<PyHemisphericRegion>()?;
215 m.add_class::<PyHemisphericGrid>()?;
216 Ok(())
217}