1use numpy::{PyArray1, PyArrayMethods};
2use pyo3::prelude::*;
3
4#[pyclass(name = "Uncertainty")]
6#[derive(Clone, Debug)]
7pub struct PyUncertainty {
8 #[pyo3(get)]
10 pub central: f64,
11 #[pyo3(get)]
13 pub errminus: f64,
14 #[pyo3(get)]
16 pub errplus: f64,
17}
18
19#[pymethods]
20impl PyUncertainty {
21 fn __repr__(&self) -> String {
22 format!(
23 "Uncertainty(central={}, errminus={}, errplus={})",
24 self.central, self.errminus, self.errplus
25 )
26 }
27
28 #[must_use]
30 pub fn errsymm(&self) -> f64 {
31 (self.errminus + self.errplus) / 2.0
32 }
33}
34
35#[pyfunction]
64#[pyo3(name = "uncertainty")]
65#[pyo3(signature = (values, error_type, error_conf_level=None, cl=68.268_949_213_708_58, alternative=false))]
66pub fn py_uncertainty<'py>(
67 _py: Python<'py>,
68 values: &Bound<'py, PyArray1<f64>>,
69 error_type: &str,
70 error_conf_level: Option<f64>,
71 cl: f64,
72 alternative: bool,
73) -> PyResult<PyUncertainty> {
74 let slice = unsafe { values.as_slice()? };
75 let unc = neopdf::uncertainty::uncertainty(
76 slice,
77 error_type,
78 error_conf_level.unwrap_or(neopdf::uncertainty::CL_1_SIGMA),
79 cl,
80 alternative,
81 )
82 .map_err(pyo3::exceptions::PyValueError::new_err)?;
83
84 Ok(PyUncertainty {
85 central: unc.central,
86 errminus: unc.errminus,
87 errplus: unc.errplus,
88 })
89}
90
91pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
97 let m = PyModule::new(parent_module.py(), "uncertainty")?;
98 m.setattr(
99 pyo3::intern!(m.py(), "__doc__"),
100 "PDF set uncertainty utilities.",
101 )?;
102 pyo3::py_run!(
103 parent_module.py(),
104 m,
105 "import sys; sys.modules['neopdf.uncertainty'] = m"
106 );
107 m.add("CL_1_SIGMA", neopdf::uncertainty::CL_1_SIGMA)?;
108 m.add("CL_2_SIGMA", neopdf::uncertainty::CL_2_SIGMA)?;
109 m.add("CL_3_SIGMA", neopdf::uncertainty::CL_3_SIGMA)?;
110 m.add("CL_90", neopdf::uncertainty::CL_90)?;
111 m.add("CL_95", neopdf::uncertainty::CL_95)?;
112 m.add_class::<PyUncertainty>()?;
113 m.add_function(wrap_pyfunction!(py_uncertainty, &m)?)?;
114 parent_module.add_submodule(&m)
115}