MaCh3  2.5.1
Reference Guide
parameters.h
Go to the documentation of this file.
1 #pragma once
2 
5 
6 // pybind includes
7 #include <pybind11/pybind11.h>
8 #include <pybind11/stl.h>
9 #include <pybind11/numpy.h>
10 // MaCh3 includes
13 
14 namespace py = pybind11;
15 
18 public:
19  /* Inherit the constructors */
21 
22  /* Trampoline (need one for each virtual function) */
23  double GetLikelihood() override {
24  PYBIND11_OVERRIDE_NAME(
25  double, /* Return type */
26  ParameterHandlerBase, /* Parent class */
27  "get_likelihood", /* Name in python*/
28  GetLikelihood /* Name of function in C++ (must match Python name) */
29  );
30  }
31 
32  void ProposeStep() override {
33  PYBIND11_OVERRIDE_NAME(
34  void, /* Return type */
35  ParameterHandlerBase, /* Parent class */
36  "propose_step", /* Name in python*/
37  ProposeStep /* Name of function in C++ (must match Python name) */
38  );
39  }
40 };
41 
42 
43 void initParametersModule(py::module &m_parameters){
44 
45  // Bind the systematic type enum that lets us set different types of systematics
46  py::enum_<SystType>(m_parameters, "SystematicType")
47  .value("Normalisation", SystType::kNorm)
48  .value("Spline", SystType::kSpline)
49  .value("Functional", SystType::kFunc)
50  .value("N_Systematic_Types", SystType::kSystTypes);
51 
52  py::class_<ParameterHandlerBase, PyParameterHandlerBase /* <--- trampoline*/>(m_parameters, "ParameterHandlerBase")
53  .def(
54  py::init<std::string &, std::string, M3::float_t, int, int>(),
55  "Construct a parameters object from a set of yaml files that define the systematic parameters \n\
56  :param name: the name of this ParameterHandler object. \n\
57  :param file: The name of the yaml file to initialise from. \n\
58  :param threshold: threshold PCA threshold from 0 to 1. Default is -1 and means no PCA. \n\
59  :param first_PCA_par: FirstPCAdpar First PCA parameter that will be decomposed. \n\
60  :param last_PCA_par: LastPCAdpar First PCA parameter that will be decomposed.",
61  py::arg("name"),
62  py::arg("file"),
63  py::arg("threshold") = -1.0,
64  py::arg("firs_PCA_par") = -999,
65  py::arg("last_PCA_par") = -999)
66 
67  .def(
68  "calculate_likelihood",
70  "Calculate penalty term based on inverted covariance matrix.")
71 
72  .def(
73  "get_internal_par_name",
74  [](ParameterHandlerBase &self, int index)
75  {
76  // do this to disambiguate between the std::string and const char* version of this fn
77  std::string ret;
78  ret = self.GetParName(index);
79  return ret;
80  },
81  "Get the internally used name of this parameter. \n\
82  :param index: The global index of the parameter",
83  py::arg("index"))
84 
85  .def(
86  "get_fancy_par_name",
87  [](ParameterHandlerBase &self, int index)
88  {
89  // do this to disambiguate between the std::string and const char* version of this fn
90  std::string ret;
91  ret = self.GetParFancyName(index);
92  return ret;
93  },
94  "Get the name of this parameter. \n\
95  :param index: The global index of the parameter",
96  py::arg("index"))
97 
98  .def(
99  "get_n_pars",
101  "Get the number of parameters that this ParameterHandler object knows about.")
102 
103  .def(
104  "propose_step",
106  "Propose a step based on the covariances. Also feel free to overwrite if you want something more funky.")
107 
108  .def(
109  "get_proposal_array",
110  [](ParameterHandlerBase &self)
111  {
112  // Get the number of parameters
113  size_t n_pars = self.GetNParameters();
114 
115  // Get pointer to the data
116  const M3::float_t* data_ptr = self.GetParPropVec().data();
117 
118  // Create a numpy array that copies the data
119  // This ensures the numpy array owns its data and won't have lifetime issues
120  py::array_t<M3::float_t> result(n_pars);
121  auto buf = result.request();
122  M3::float_t* result_ptr = static_cast<M3::float_t*>(buf.ptr);
123 
124  // Copy the data
125  std::memcpy(result_ptr, data_ptr, n_pars * sizeof(M3::float_t));
126 
127  return result;
128  },
129  "Get the parameter proposal values as a numpy array. \n\
130  This returns a copy of the current proposal values. \n\
131  :return: A numpy array containing the proposal values for all parameters.")
132 
133  .def("set_parameters", [](ParameterHandlerBase &self, py::object pars_obj = py::none())
134  {
135  if (pars_obj.is_none()) {
136  self.SetParameters();
137  } else {
138  // This handles both numpy arrays and Python lists
139  std::vector<double> pars_vec = pars_obj.cast<std::vector<double>>();
140  self.SetParameters(pars_vec);
141  } }, py::arg("pars") = py::none(),
142  R"pbdoc(
143  Set parameter values using array.
144 
145  Parameters
146  ----------
147  pars : numpy.ndarray or list of float, optional
148  Array holding new values for every parameter.
149  Must have same size as the number of parameters in the covariance class.
150  If not provided, parameters are set to their pre-fit values.
151 
152  Examples
153  --------
154  >>> import numpy as np
155  >>> handler.set_parameters(np.array([1.0, 2.0, 3.0]))
156  >>> handler.set_parameters([1.0, 2.0, 3.0])
157  >>> handler.set_parameters()
158  )pbdoc")
159 
160 
161  .def("get_par_init", &ParameterHandlerBase::GetParInit, py::arg("index"),
162  "Get initial value of parameter at index i\n\
163  :param index: index of the parameter")
164 
165  .def("get_lower_bound", &ParameterHandlerBase::GetLowerBound, py::arg("index"),
166  "Get the lower bound of parameter at index i. \n\
167  :param index: index of the parameter")
168 
169  .def("get_upper_bound", &ParameterHandlerBase::GetUpperBound, py::arg("index"),
170  "Get the upper bound of parameter at index i. \n\
171  :param index: index of the parameter")
172 
173  .def("get_flat_prior", &ParameterHandlerBase::GetFlatPrior, py::arg("index"),
174  "Is the parameter at index i flat?. \n\
175  :param index: index of the parameter")
176 
177  .def("get_par_error", &ParameterHandlerBase::GetDiagonalError, py::arg("index"),
178  "The prior error on parameter at index i \n\
179  :param index: index of the parameter")
180 
181  .def("get_par_fixed", static_cast<bool (ParameterHandlerBase::*)(const int) const>(&ParameterHandlerBase::IsParameterFixed), py::arg("index"),
182  "Is the parameter at index i fixed \n\
183  :param index: index of the parameter")
184 
185  .def("get_prior_cov", [](ParameterHandlerBase &self)
186  {
187  auto mat = self.GetCovMatrix();
188  if (!mat){
189  throw std::runtime_error("TMatrixDSym pointer is null");
190  }
191  int n = mat->GetNrows();
192  const double *data = mat->GetMatrixArray();
193  py::array_t<float> result({n, n});
194  // Shove matrix into the array
195  std::transform(data, data + n * n,
196  result.mutable_data(),
197  [](double v)
198  { return static_cast<float>(v); });
199 
200  return result; },
201  "Get the prior covariance")
202 
203  ; // End of ParameterHandlerBase binding
204 
205  py::class_<ParameterHandlerGeneric, ParameterHandlerBase /* <--- trampoline*/>(m_parameters, "ParameterHandlerGeneric")
206  .def(
207  py::init<const std::vector<std::string>&, const char *, M3::float_t, int, int>(),
208  "Construct a systematic ParameterHandler object from a set of yaml files that define the systematic parameters \n\
209  :param yaml_files: The name of the yaml file to initialise from. \n\
210  :param name: the name of this ParameterHandler object. \n\
211  :param threshold: threshold PCA threshold from 0 to 1. Default is -1 and means no PCA. \n\
212  :param first_PCA_par: FirstPCAdpar First PCA parameter that will be decomposed. \n\
213  :param last_PCA_par: LastPCAdpar First PCA parameter that will be decomposed.",
214  py::arg("yaml_files"),
215  py::arg("name") = "xsec_cov",
216  py::arg("threshold") = -1.0,
217  py::arg("firs_PCA_par") = -999,
218  py::arg("last_PCA_par") = -999
219  )
220 
221  .def(
222  "get_par_type",
224  "Get what type of systematic this parameters is (see :py:class:`pyMaCh3.m_parameters.SystematicType` for possible types). \n\
225  :param index: The global index of the parameter",
226  py::arg("index")
227  )
228 
229  .def(
230  "get_par_spline_type",
232  "Get what type of spline this parameter is set to use (assuming that it is a spline type parameter). \n\
233  :param index: The index of the spline parameter",
234  py::arg("index")
235  )
236 
237  .def(
238  "get_par_spline_name",
240  "Get the name of the spline associated with a spline parameter. This is generally what it is called in input spline files and can in principle be different to the parameters name. \n\
241  :param index: The index of the spline parameter",
242  py::arg("index")
243  )
244 
245  ; // End of ParameterHandlerGeneric binding
246 }
@ kNorm
For normalisation parameters.
@ kSpline
For splined parameters (1D)
@ kSystTypes
This only enumerates.
@ kFunc
For functional parameters.
Base class responsible for handling of systematic error parameters. Capable of using PCA or using ada...
virtual void ProposeStep()
Generate a new proposed state.
double GetUpperBound(const int i) const
Get upper parameter bound in which it is physically valid.
int GetNParameters() const
Get number of params which will be different depending if using Eigen decomposition or not.
bool IsParameterFixed(const int i) const
Is parameter fixed or not.
double GetLowerBound(const int i) const
Get lower parameter bound in which it is physically valid.
double CalcLikelihood() const _noexcept_
Calc penalty term based on inverted covariance matrix.
bool GetFlatPrior(const int i) const
Get if param has flat prior or not.
double GetParInit(const int i) const
Get prior parameter value.
double GetDiagonalError(const int i) const
Get diagonal error for ith parameter.
ParameterHandlerBase()=default
Class responsible for handling of systematic error parameters with different types defined in the con...
SystType GetParamType(const int i) const
Returns enum describing our param type.
std::string GetParSplineName(const int i) const
Get the name of the spline associated with the spline at index i.
SplineInterpolation GetParSplineInterpolation(const int i) const
Get interpolation type for a given parameter.
EW: As ParameterHandlerBase is an abstract base class we have to do some gymnastics to get it to get ...
Definition: parameters.h:17
double GetLikelihood() override
Return CalcLikelihood if some params were thrown out of boundary return LARGE_LOGL
Definition: parameters.h:23
void ProposeStep() override
Generate a new proposed state.
Definition: parameters.h:32
double float_t
Definition: Core.h:37
void initParametersModule(py::module &m_parameters)
Definition: parameters.h:43