1#![warn(missing_docs)]
14
15use numpy::{IntoPyArray, PyArray1, PyArray2, PyReadonlyArray1, PyReadonlyArray2};
16use pyo3::prelude::{pymodule, PyModule, PyResult, Python};
17
18use field::{summator, summator_incompr};
19use krige::{calculator_field_krige, calculator_field_krige_and_variance};
20use variogram::{
21 variogram_directional, variogram_ma_structured, variogram_structured, variogram_unstructured,
22};
23
24pub mod field;
25pub mod krige;
26mod short_vec;
27pub mod variogram;
28
29#[pymodule]
30fn gstools_core(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
31 m.add("__version__", env!("CARGO_PKG_VERSION"))?;
32
33 #[pyfn(m)]
34 #[pyo3(name = "summate")]
35 fn summate_py<'py>(
36 py: Python<'py>,
37 cov_samples: PyReadonlyArray2<f64>,
38 z1: PyReadonlyArray1<f64>,
39 z2: PyReadonlyArray1<f64>,
40 pos: PyReadonlyArray2<f64>,
41 num_threads: Option<usize>,
42 ) -> &'py PyArray1<f64> {
43 let cov_samples = cov_samples.as_array();
44 let z1 = z1.as_array();
45 let z2 = z2.as_array();
46 let pos = pos.as_array();
47 summator(cov_samples, z1, z2, pos, num_threads).into_pyarray(py)
48 }
49
50 #[pyfn(m)]
51 #[pyo3(name = "summate_incompr")]
52 fn summate_incompr_py<'py>(
53 py: Python<'py>,
54 cov_samples: PyReadonlyArray2<f64>,
55 z1: PyReadonlyArray1<f64>,
56 z2: PyReadonlyArray1<f64>,
57 pos: PyReadonlyArray2<f64>,
58 num_threads: Option<usize>,
59 ) -> &'py PyArray2<f64> {
60 let cov_samples = cov_samples.as_array();
61 let z1 = z1.as_array();
62 let z2 = z2.as_array();
63 let pos = pos.as_array();
64 summator_incompr(cov_samples, z1, z2, pos, num_threads).into_pyarray(py)
65 }
66
67 #[pyfn(m)]
68 #[pyo3(name = "calc_field_krige_and_variance")]
69 fn calc_field_krige_and_variance_py<'py>(
70 py: Python<'py>,
71 krige_mat: PyReadonlyArray2<f64>,
72 krig_vecs: PyReadonlyArray2<f64>,
73 cond: PyReadonlyArray1<f64>,
74 num_threads: Option<usize>,
75 ) -> (&'py PyArray1<f64>, &'py PyArray1<f64>) {
76 let krige_mat = krige_mat.as_array();
77 let krig_vecs = krig_vecs.as_array();
78 let cond = cond.as_array();
79 let (field, error) =
80 calculator_field_krige_and_variance(krige_mat, krig_vecs, cond, num_threads);
81 let field = field.into_pyarray(py);
82 let error = error.into_pyarray(py);
83 (field, error)
84 }
85
86 #[pyfn(m)]
87 #[pyo3(name = "calc_field_krige")]
88 fn calc_field_krige_py<'py>(
89 py: Python<'py>,
90 krige_mat: PyReadonlyArray2<f64>,
91 krig_vecs: PyReadonlyArray2<f64>,
92 cond: PyReadonlyArray1<f64>,
93 num_threads: Option<usize>,
94 ) -> &'py PyArray1<f64> {
95 let krige_mat = krige_mat.as_array();
96 let krig_vecs = krig_vecs.as_array();
97 let cond = cond.as_array();
98 calculator_field_krige(krige_mat, krig_vecs, cond, num_threads).into_pyarray(py)
99 }
100
101 #[pyfn(m)]
102 #[pyo3(name = "variogram_structured")]
103 fn variogram_structured_py<'py>(
104 py: Python<'py>,
105 f: PyReadonlyArray2<f64>,
106 estimator_type: Option<char>,
107 num_threads: Option<usize>,
108 ) -> &'py PyArray1<f64> {
109 let f = f.as_array();
110 let estimator_type = estimator_type.unwrap_or('m');
111 variogram_structured(f, estimator_type, num_threads).into_pyarray(py)
112 }
113
114 #[pyfn(m)]
115 #[pyo3(name = "variogram_ma_structured")]
116 fn variogram_ma_structured_py<'py>(
117 py: Python<'py>,
118 f: PyReadonlyArray2<f64>,
119 mask: PyReadonlyArray2<bool>,
120 estimator_type: Option<char>,
121 num_threads: Option<usize>,
122 ) -> &'py PyArray1<f64> {
123 let f = f.as_array();
124 let mask = mask.as_array();
125 let estimator_type = estimator_type.unwrap_or('m');
126 variogram_ma_structured(f, mask, estimator_type, num_threads).into_pyarray(py)
127 }
128
129 #[pyfn(m)]
130 #[pyo3(name = "variogram_directional")]
131 #[allow(clippy::too_many_arguments)]
132 fn variogram_directional_py<'py>(
133 py: Python<'py>,
134 f: PyReadonlyArray2<f64>,
135 bin_edges: PyReadonlyArray1<f64>,
136 pos: PyReadonlyArray2<f64>,
137 direction: PyReadonlyArray2<f64>, angles_tol: Option<f64>,
139 bandwidth: Option<f64>,
140 separate_dirs: Option<bool>,
141 estimator_type: Option<char>,
142 num_threads: Option<usize>,
143 ) -> (&'py PyArray2<f64>, &'py PyArray2<u64>) {
144 let f = f.as_array();
145 let bin_edges = bin_edges.as_array();
146 let pos = pos.as_array();
147 let direction = direction.as_array();
148 let angles_tol = angles_tol.unwrap_or(std::f64::consts::PI / 8.0);
149 let bandwidth = bandwidth.unwrap_or(-1.0);
150 let separate_dirs = separate_dirs.unwrap_or(false);
151 let estimator_type = estimator_type.unwrap_or('m');
152 let (variogram, counts) = variogram_directional(
153 f,
154 bin_edges,
155 pos,
156 direction,
157 angles_tol,
158 bandwidth,
159 separate_dirs,
160 estimator_type,
161 num_threads,
162 );
163 let variogram = variogram.into_pyarray(py);
164 let counts = counts.into_pyarray(py);
165
166 (variogram, counts)
167 }
168
169 #[pyfn(m)]
170 #[pyo3(name = "variogram_unstructured")]
171 fn variogram_unstructured_py<'py>(
172 py: Python<'py>,
173 f: PyReadonlyArray2<f64>,
174 bin_edges: PyReadonlyArray1<f64>,
175 pos: PyReadonlyArray2<f64>,
176 estimator_type: Option<char>,
177 distance_type: Option<char>,
178 num_threads: Option<usize>,
179 ) -> (&'py PyArray1<f64>, &'py PyArray1<u64>) {
180 let f = f.as_array();
181 let bin_edges = bin_edges.as_array();
182 let pos = pos.as_array();
183 let estimator_type = estimator_type.unwrap_or('m');
184 let distance_type = distance_type.unwrap_or('e');
185 let (variogram, counts) = variogram_unstructured(
186 f,
187 bin_edges,
188 pos,
189 estimator_type,
190 distance_type,
191 num_threads,
192 );
193 let variogram = variogram.into_pyarray(py);
194 let counts = counts.into_pyarray(py);
195
196 (variogram, counts)
197 }
198
199 Ok(())
200}