1use pyo3::prelude::*;
2
3use neopdf::metadata::{InterpolatorType, MetaData, SetType};
4
5#[pyclass(eq, eq_int, name = "SetType")]
7#[derive(Clone, PartialEq, Eq)]
8pub enum PySetType {
9 SpaceLike,
11 TimeLike,
13}
14
15impl From<&SetType> for PySetType {
16 fn from(set_type: &SetType) -> Self {
17 match set_type {
18 SetType::SpaceLike => Self::SpaceLike,
19 SetType::TimeLike => Self::TimeLike,
20 }
21 }
22}
23
24impl From<&PySetType> for SetType {
25 fn from(set_type: &PySetType) -> Self {
26 match set_type {
27 PySetType::SpaceLike => Self::SpaceLike,
28 PySetType::TimeLike => Self::TimeLike,
29 }
30 }
31}
32
33#[pyclass(eq, eq_int, name = "InterpolatorType")]
35#[derive(Clone, PartialEq, Eq)]
36pub enum PyInterpolatorType {
37 Bilinear,
39 LogBilinear,
41 LogBicubic,
43 LogTricubic,
45 NDLinear,
47 LogChebyshev,
49 LogFourCubic,
51 LogFiveCubic,
53}
54
55impl From<&InterpolatorType> for PyInterpolatorType {
56 fn from(basis: &InterpolatorType) -> Self {
57 match basis {
58 InterpolatorType::Bilinear => Self::Bilinear,
59 InterpolatorType::LogBilinear => Self::LogBilinear,
60 InterpolatorType::LogBicubic => Self::LogBicubic,
61 InterpolatorType::LogTricubic => Self::LogTricubic,
62 InterpolatorType::InterpNDLinear => Self::NDLinear,
63 InterpolatorType::LogChebyshev => Self::LogChebyshev,
64 InterpolatorType::LogFourCubic => Self::LogFourCubic,
65 InterpolatorType::LogFiveCubic => Self::LogFiveCubic,
66 }
67 }
68}
69
70impl From<&PyInterpolatorType> for InterpolatorType {
71 fn from(basis: &PyInterpolatorType) -> Self {
72 match basis {
73 PyInterpolatorType::Bilinear => Self::Bilinear,
74 PyInterpolatorType::LogBilinear => Self::LogBilinear,
75 PyInterpolatorType::LogBicubic => Self::LogBicubic,
76 PyInterpolatorType::LogTricubic => Self::LogTricubic,
77 PyInterpolatorType::NDLinear => Self::InterpNDLinear,
78 PyInterpolatorType::LogChebyshev => Self::LogChebyshev,
79 PyInterpolatorType::LogFourCubic => Self::LogFourCubic,
80 PyInterpolatorType::LogFiveCubic => Self::LogFiveCubic,
81 }
82 }
83}
84
85#[pyclass(name = "PhysicsParameters")]
87#[derive(Debug, Clone)]
88pub struct PyPhysicsParameters {
89 pub(crate) flavor_scheme: String,
90 pub(crate) order_qcd: u32,
91 pub(crate) alphas_order_qcd: u32,
92 pub(crate) m_w: f64,
93 pub(crate) m_z: f64,
94 pub(crate) m_up: f64,
95 pub(crate) m_down: f64,
96 pub(crate) m_strange: f64,
97 pub(crate) m_charm: f64,
98 pub(crate) m_bottom: f64,
99 pub(crate) m_top: f64,
100 pub(crate) alphas_type: String,
101 pub(crate) number_flavors: u32,
102}
103
104#[pymethods]
105impl PyPhysicsParameters {
106 #[new]
108 #[must_use]
109 #[allow(clippy::too_many_arguments)]
110 #[pyo3(signature = (
111 flavor_scheme = "None".to_string(),
112 order_qcd = 0,
113 alphas_order_qcd = 0,
114 m_w = 0.0,
115 m_z = 0.0,
116 m_up = 0.0,
117 m_down = 0.0,
118 m_strange = 0.0,
119 m_charm = 0.0,
120 m_bottom = 0.0,
121 m_top = 0.0,
122 alphas_type = "None".to_string(),
123 number_flavors = 0,
124 ))]
125 pub const fn new(
126 flavor_scheme: String,
127 order_qcd: u32,
128 alphas_order_qcd: u32,
129 m_w: f64,
130 m_z: f64,
131 m_up: f64,
132 m_down: f64,
133 m_strange: f64,
134 m_charm: f64,
135 m_bottom: f64,
136 m_top: f64,
137 alphas_type: String,
138 number_flavors: u32,
139 ) -> Self {
140 Self {
141 flavor_scheme,
142 order_qcd,
143 alphas_order_qcd,
144 m_w,
145 m_z,
146 m_up,
147 m_down,
148 m_strange,
149 m_charm,
150 m_bottom,
151 m_top,
152 alphas_type,
153 number_flavors,
154 }
155 }
156
157 pub fn to_dict(&self, py: Python) -> PyResult<Py<PyAny>> {
163 let dict = pyo3::types::PyDict::new(py);
164 dict.set_item("flavor_scheme", &self.flavor_scheme)?;
165 dict.set_item("order_qcd", self.order_qcd)?;
166 dict.set_item("alphas_order_qcd", self.alphas_order_qcd)?;
167 dict.set_item("m_w", self.m_w)?;
168 dict.set_item("m_z", self.m_z)?;
169 dict.set_item("m_up", self.m_up)?;
170 dict.set_item("m_down", self.m_down)?;
171 dict.set_item("m_strange", self.m_strange)?;
172 dict.set_item("m_charm", self.m_charm)?;
173 dict.set_item("m_bottom", self.m_bottom)?;
174 dict.set_item("m_top", self.m_top)?;
175
176 Ok(dict.into())
177 }
178}
179
180impl Default for PyPhysicsParameters {
181 fn default() -> Self {
182 Self {
183 flavor_scheme: String::new(),
184 order_qcd: 0,
185 alphas_order_qcd: 0,
186 m_w: 0.0,
187 m_z: 0.0,
188 m_up: 0.0,
189 m_down: 0.0,
190 m_strange: 0.0,
191 m_charm: 0.0,
192 m_bottom: 0.0,
193 m_top: 0.0,
194 alphas_type: String::new(),
195 number_flavors: 0,
196 }
197 }
198}
199
200#[pyclass(name = "MetaData")]
202#[derive(Debug, Clone)]
203#[repr(transparent)]
204pub struct PyMetaData {
205 pub(crate) meta: MetaData,
206}
207
208#[pymethods]
209impl PyMetaData {
210 #[new]
212 #[must_use]
213 #[allow(clippy::too_many_arguments)]
214 #[allow(clippy::needless_pass_by_value)]
215 #[pyo3(signature = (
216 set_desc,
217 set_index,
218 num_members,
219 x_min,
220 x_max,
221 q_min,
222 q_max,
223 xsi_min,
224 xsi_max,
225 delta_min,
226 delta_max,
227 flavors,
228 format,
229 alphas_q_values = vec![],
230 alphas_vals = vec![],
231 polarised = false,
232 set_type = PySetType::SpaceLike,
233 interpolator_type = PyInterpolatorType::LogBicubic,
234 error_type = "replicas".to_string(),
235 hadron_pid = 2212,
236 phys_params = PyPhysicsParameters::default(),
237 ))]
238 pub fn new(
239 set_desc: String,
240 set_index: u32,
241 num_members: u32,
242 x_min: f64,
243 x_max: f64,
244 q_min: f64,
245 q_max: f64,
246 xsi_min: f64,
247 xsi_max: f64,
248 delta_min: f64,
249 delta_max: f64,
250 flavors: Vec<i32>,
251 format: String,
252 alphas_q_values: Vec<f64>,
253 alphas_vals: Vec<f64>,
254 polarised: bool,
255 set_type: PySetType,
256 interpolator_type: PyInterpolatorType,
257 error_type: String,
258 hadron_pid: i32,
259 phys_params: PyPhysicsParameters,
260 ) -> Self {
261 Self {
262 meta: MetaData {
263 set_desc,
264 set_index,
265 num_members,
266 x_min,
267 x_max,
268 q_min,
269 q_max,
270 flavors,
271 format,
272 alphas_q_values,
273 alphas_vals,
274 polarised,
275 set_type: SetType::from(&set_type),
276 interpolator_type: InterpolatorType::from(&interpolator_type),
277 error_type,
278 hadron_pid,
279 git_version: String::new(), code_version: String::new(), flavor_scheme: phys_params.flavor_scheme,
282 order_qcd: phys_params.order_qcd,
283 alphas_order_qcd: phys_params.alphas_order_qcd,
284 m_w: phys_params.m_w,
285 m_z: phys_params.m_z,
286 m_up: phys_params.m_up,
287 m_down: phys_params.m_down,
288 m_strange: phys_params.m_strange,
289 m_charm: phys_params.m_charm,
290 m_bottom: phys_params.m_bottom,
291 m_top: phys_params.m_top,
292 alphas_type: phys_params.alphas_type,
293 number_flavors: phys_params.number_flavors,
294 xi_min: xsi_min,
296 xi_max: xsi_max,
297 delta_min,
298 delta_max,
299 },
300 }
301 }
302
303 pub fn to_dict(&self, py: Python) -> PyResult<Py<PyAny>> {
309 let dict = pyo3::types::PyDict::new(py);
310
311 let set_type = match &self.meta.set_type {
312 SetType::SpaceLike => "PDF",
313 SetType::TimeLike => "FragFn",
314 };
315
316 let interpolator_type = match &self.meta.interpolator_type {
317 InterpolatorType::Bilinear => "Bilinear",
318 InterpolatorType::LogBilinear => "LogBilinear",
319 InterpolatorType::LogBicubic => "LogBicubic",
320 InterpolatorType::LogTricubic => "LogTricubic",
321 InterpolatorType::InterpNDLinear => "NDLinear",
322 InterpolatorType::LogChebyshev => "LogChebyshev",
323 InterpolatorType::LogFourCubic => "LogFourCubic",
324 InterpolatorType::LogFiveCubic => "LogFiveCubic",
325 };
326
327 dict.set_item("set_desc", &self.meta.set_desc)?;
328 dict.set_item("set_index", self.meta.set_index)?;
329 dict.set_item("num_members", self.meta.num_members)?;
330 dict.set_item("x_min", self.meta.x_min)?;
331 dict.set_item("x_max", self.meta.x_max)?;
332 dict.set_item("q_min", self.meta.q_min)?;
333 dict.set_item("q_max", self.meta.q_max)?;
334 dict.set_item("flavors", &self.meta.flavors)?;
335 dict.set_item("format", &self.meta.format)?;
336 dict.set_item("alphas_q_values", &self.meta.alphas_q_values)?;
337 dict.set_item("alphas_vals", &self.meta.alphas_vals)?;
338 dict.set_item("polarised", self.meta.polarised)?;
339 dict.set_item("set_type", set_type)?;
340 dict.set_item("interpolator_type", interpolator_type)?;
341 dict.set_item("error_type", &self.meta.error_type)?;
342 dict.set_item("hadron_pid", self.meta.hadron_pid)?;
343 dict.set_item("git_version", &self.meta.git_version)?;
344 dict.set_item("code_version", &self.meta.code_version)?;
345 dict.set_item("flavor_scheme", &self.meta.flavor_scheme)?;
346 dict.set_item("order_qcd", self.meta.order_qcd)?;
347 dict.set_item("alphas_order_qcd", self.meta.alphas_order_qcd)?;
348 dict.set_item("m_w", self.meta.m_w)?;
349 dict.set_item("m_z", self.meta.m_z)?;
350 dict.set_item("m_up", self.meta.m_up)?;
351 dict.set_item("m_down", self.meta.m_down)?;
352 dict.set_item("m_strange", self.meta.m_strange)?;
353 dict.set_item("m_charm", self.meta.m_charm)?;
354 dict.set_item("m_bottom", self.meta.m_bottom)?;
355 dict.set_item("m_top", self.meta.m_top)?;
356
357 Ok(dict.into())
358 }
359
360 #[must_use]
362 pub const fn set_desc(&self) -> &String {
363 &self.meta.set_desc
364 }
365
366 #[must_use]
368 pub const fn set_index(&self) -> u32 {
369 self.meta.set_index
370 }
371
372 #[must_use]
374 pub const fn number_sets(&self) -> u32 {
375 self.meta.num_members
376 }
377
378 #[must_use]
380 pub const fn x_min(&self) -> f64 {
381 self.meta.x_min
382 }
383
384 #[must_use]
386 pub const fn x_max(&self) -> f64 {
387 self.meta.x_max
388 }
389
390 #[must_use]
392 pub const fn q_min(&self) -> f64 {
393 self.meta.q_min
394 }
395
396 #[must_use]
398 pub const fn q_max(&self) -> f64 {
399 self.meta.q_max
400 }
401
402 #[must_use]
404 pub const fn xi_min(&self) -> f64 {
405 self.meta.xi_min
406 }
407
408 #[must_use]
410 pub const fn xi_max(&self) -> f64 {
411 self.meta.xi_max
412 }
413
414 #[must_use]
416 pub const fn delta_min(&self) -> f64 {
417 self.meta.delta_min
418 }
419
420 #[must_use]
422 pub const fn delta_max(&self) -> f64 {
423 self.meta.delta_max
424 }
425
426 #[must_use]
428 pub const fn pids(&self) -> &Vec<i32> {
429 &self.meta.flavors
430 }
431
432 #[must_use]
434 pub const fn format(&self) -> &String {
435 &self.meta.format
436 }
437
438 #[must_use]
440 pub const fn alphas_q(&self) -> &Vec<f64> {
441 &self.meta.alphas_q_values
442 }
443
444 #[must_use]
446 pub const fn alphas_values(&self) -> &Vec<f64> {
447 &self.meta.alphas_vals
448 }
449
450 #[must_use]
452 pub const fn is_polarised(&self) -> bool {
453 self.meta.polarised
454 }
455
456 #[must_use]
458 pub fn set_type(&self) -> PySetType {
459 PySetType::from(&self.meta.set_type)
460 }
461
462 #[must_use]
464 pub fn interpolator_type(&self) -> PyInterpolatorType {
465 PyInterpolatorType::from(&self.meta.interpolator_type)
466 }
467
468 #[must_use]
470 pub const fn error_type(&self) -> &String {
471 &self.meta.error_type
472 }
473
474 #[must_use]
476 pub const fn hadron_pid(&self) -> i32 {
477 self.meta.hadron_pid
478 }
479}
480
481pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
498 let m = PyModule::new(parent_module.py(), "metadata")?;
499 m.setattr(pyo3::intern!(m.py(), "__doc__"), "Interface for PDF.")?;
500 pyo3::py_run!(
501 parent_module.py(),
502 m,
503 "import sys; sys.modules['neopdf.metadata'] = m"
504 );
505 m.add_class::<PySetType>()?;
506 m.add_class::<PyInterpolatorType>()?;
507 m.add_class::<PyPhysicsParameters>()?;
508 m.add_class::<PyMetaData>()?;
509 parent_module.add_submodule(&m)
510}