bindings.cc
Go to the documentation of this file.
1 /*
2  * MoMEMta: a modular implementation of the Matrix Element Method
3  * Copyright (C) 2016 Universite catholique de Louvain (UCL), Belgium
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <momemta/Configuration.h>
20 #include <momemta/ConfigurationReader.h>
21 #include <momemta/MoMEMta.h>
22 #include <momemta/Logging.h>
23 
24 #include <boost/python.hpp>
25 
26 #ifdef ROOT_HAS_PYROOT
27 #include <TPython.h>
28 #endif
29 
36 namespace bp = boost::python;
37 using namespace momemta;
38 
39 void set_log_level(logging::level::level_enum lvl) {
40  logging::set_level(lvl);
41 }
42 
43 void MoMEMta_setEvent_MET(MoMEMta& m, bp::list particles_, bp::list met_) {
44  std::vector<Particle> particles;
45  for (ssize_t i = 0; i < bp::len(particles_); i++) {
46  particles.push_back(bp::extract<Particle>(particles_[i]));
47  }
48 
49  LorentzVector met;
50  bp::extract<LorentzVector> lorentzVectorExtractor(met_);
51  if (lorentzVectorExtractor.check())
52  met = lorentzVectorExtractor();
53 
54  m.setEvent(particles, met);
55 }
56 
57 void MoMEMta_setEvent(MoMEMta& m, bp::list particles_) {
58  MoMEMta_setEvent_MET(m, particles_, bp::list());
59 }
60 
61 bp::list MoMEMta_evaluateIntegrand(MoMEMta& m, bp::list psPoint_) {
62  std::vector<double> psPoint;
63  for (ssize_t i = 0; i < bp::len(psPoint_); i++) {
64  psPoint.push_back(bp::extract<double>(psPoint_[i]));
65  }
66 
67  auto integrands = m.evaluateIntegrand(psPoint);
68 
69  bp::list result;
70  for (const auto& integrand: integrands) {
71  result.append(integrand);
72  }
73 
74  return result;
75 }
76 
77 bp::list MoMEMta_computeWeights_MET(MoMEMta& m, bp::list particles_, bp::list met_) {
78  std::vector<Particle> particles;
79  for (ssize_t i = 0; i < bp::len(particles_); i++) {
80  particles.push_back(bp::extract<Particle>(particles_[i]));
81  }
82 
83  LorentzVector met;
84  bp::extract<LorentzVector> lorentzVectorExtractor(met_);
85  if (lorentzVectorExtractor.check())
86  met = lorentzVectorExtractor();
87 
88  auto weights = m.computeWeights(particles, met);
89 
90  bp::list result;
91  for (const auto& weight: weights) {
92  bp::tuple pair = bp::make_tuple(weight.first, weight.second);
93  result.append(pair);
94  }
95 
96  return result;
97 }
98 
99 bp::list MoMEMta_computeWeights(MoMEMta& m, bp::list particles) {
100  return MoMEMta_computeWeights_MET(m, particles, bp::list());
101 }
102 
103 template<typename T>
104 const T& ParameterSet_get(ParameterSet& p, const std::string& name) {
105  return p.get<T>(name);
106 }
107 
108 template<typename T>
109 void ParameterSet_set(ParameterSet& p, const std::string& name, const T& value) {
110  return p.set<T>(name, value);
111 }
112 
114  static PyObject* convert(LorentzVector const& s) {
115  bp::list result;
116  result.append(s.X());
117  result.append(s.Y());
118  result.append(s.Z());
119  result.append(s.T());
120 
121  return boost::python::incref(result.ptr());
122  }
123 };
124 
127  bp::converter::registry::push_back(
128  &convertible,
129  &construct,
130  boost::python::type_id<LorentzVector>());
131  }
132 
133  static void* convertible(PyObject* obj_ptr) {
134  if (! PyList_Check(obj_ptr))
135  return nullptr;
136 
137  if (PyList_Size(obj_ptr) != 4)
138  return nullptr;
139 
140  return obj_ptr;
141  }
142 
143  static void construct(
144  PyObject* obj_ptr,
145  bp::converter::rvalue_from_python_stage1_data* data) {
146  //if (value == 0) boost::python::throw_error_already_set();
147 
148  void* storage = (
149  (bp::converter::rvalue_from_python_storage<LorentzVector>*)
150  data)->storage.bytes;
151  new (storage) LorentzVector(
152  bp::extract<double>(PyList_GET_ITEM(obj_ptr, 0)),
153  bp::extract<double>(PyList_GET_ITEM(obj_ptr, 1)),
154  bp::extract<double>(PyList_GET_ITEM(obj_ptr, 2)),
155  bp::extract<double>(PyList_GET_ITEM(obj_ptr, 3))
156  );
157  data->convertible = storage;
158  }
159 };
160 
161 #ifdef ROOT_HAS_PYROOT
162 template <typename T>
163 struct convert_py_root_to_cpp_root {
164  convert_py_root_to_cpp_root() {
165  bp::converter::registry::push_back(&convertible, &construct,
166  bp::type_id<T>());
167  }
168  static void* convertible(PyObject* obj_ptr) {
169  return TPython::ObjectProxy_Check(obj_ptr) ? obj_ptr : nullptr;
170  }
171 
172  static void construct(PyObject* obj_ptr,
173  bp::converter::rvalue_from_python_stage1_data* data) {
174  T* TObj = static_cast<T*>(TPython::ObjectProxy_AsVoidPtr(obj_ptr));
175  data->convertible = TObj;
176  }
177 };
178 #endif
179 
180 // Overloads for MoMEMta::computeWeights
181 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MoMEMta_computeWeights_overloads, MoMEMta::computeWeights, 1, 2)
182 
183 // Overloads for MoMEMta::setEvent
184 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MoMEMta_setEvent_overloads, MoMEMta::setEvent, 1, 2)
185 
186 BOOST_PYTHON_MODULE(momemta) {
187 
188  using namespace boost::python;
189 
190  to_python_converter<LorentzVector, LorentzVector_to_python>();
192 
193 #ifdef ROOT_HAS_PYROOT
194  convert_py_root_to_cpp_root<LorentzVector>();
195 #endif
196 
197  enum_<logging::level::level_enum>("log_level")
198  .value("trace", logging::level::trace)
199  .value("debug", logging::level::debug)
200  .value("info", logging::level::info)
201  .value("warning", logging::level::warning)
202  .value("error", logging::level::error)
203  .value("fatal", logging::level::fatal)
204  .value("off", logging::level::off);
205 
206  def("set_log_level", set_log_level);
207 
208  class_<ParameterSet>("ParameterSet", no_init)
209  .def("exists", &ParameterSet::exists)
210  .def("getDouble", ParameterSet_get<double>, return_value_policy<copy_const_reference>())
211  .def("getInt", ParameterSet_get<int>, return_value_policy<copy_const_reference>())
212  .def("getString", ParameterSet_get<std::string>, return_value_policy<copy_const_reference>())
213  .def("getInputTag", ParameterSet_get<InputTag>, return_value_policy<copy_const_reference>())
214  .def("getParameterSet", ParameterSet_get<ParameterSet>, return_value_policy<copy_const_reference>())
215  .def("setDouble", ParameterSet_set<double>)
216  .def("setInt", ParameterSet_set<int>)
217  .def("setString", ParameterSet_set<std::string>)
218  .def("setInputTag", ParameterSet_set<InputTag>);
219 
220  class_<Configuration>("Configuration", no_init)
221  .def("getGlobalParameters", &Configuration::getGlobalParameters,
222  return_internal_reference<>())
223  .def("getCubaConfiguration", &Configuration::getCubaConfiguration,
224  return_internal_reference<>());
225 
226  class_<ConfigurationReader>("ConfigurationReader", init<std::string>())
227  .def("freeze", &ConfigurationReader::freeze)
228  .def("getGlobalParameters", &ConfigurationReader::getGlobalParameters,
229  return_value_policy<reference_existing_object>())
230  .def("getCubaConfiguration", &ConfigurationReader::getCubaConfiguration,
231  return_value_policy<reference_existing_object>());
232 
233  enum_<MoMEMta::IntegrationStatus>("IntegrationStatus")
234  .value("ABORTED", MoMEMta::IntegrationStatus::ABORTED)
235  .value("ACCURACY_NOT_REACHED", MoMEMta::IntegrationStatus::ACCURACY_NOT_REACHED)
236  .value("DIM_OUT_OF_RANGE", MoMEMta::IntegrationStatus::DIM_OUT_OF_RANGE)
237  .value("FAILED", MoMEMta::IntegrationStatus::FAILED)
238  .value("NONE", MoMEMta::IntegrationStatus::NONE)
239  .value("SUCCESS", MoMEMta::IntegrationStatus::SUCCESS);
240 
241  class_<Particle>("Particle", init<std::string>())
242  .def(init<std::string, LorentzVector>())
243  .def(init<std::string, LorentzVector, int64_t>())
244  .def_readonly("name", &Particle::name)
245  .add_property("p4", make_getter(&Particle::p4, return_value_policy<return_by_value>()), &Particle::p4)
246  .def_readwrite("type", &Particle::type);
247 
248  class_<MoMEMta>("MoMEMta", init<Configuration>())
249  .def("getIntegrationStatus", &MoMEMta::getIntegrationStatus)
250  //.def("getPool", &MoMEMta::getPool, return_value_policy<copy_const_reference>())
251  .def("computeWeights", MoMEMta_computeWeights)
252  .def("computeWeights", MoMEMta_computeWeights_MET)
253  .def("computeWeights", &MoMEMta::computeWeights, MoMEMta_computeWeights_overloads())
254  .def("setEvent", MoMEMta_setEvent)
255  .def("setEvent", MoMEMta_setEvent_MET)
256  .def("setEvent", &MoMEMta::setEvent, MoMEMta_setEvent_overloads())
257  .def("evaluateIntegrand", MoMEMta_evaluateIntegrand);
258 }
Configuration freeze() const
Freeze the configuration.
const ParameterSet & getGlobalParameters() const
A MoMEMta instance.
Definition: MoMEMta.h:44
IntegrationStatus getIntegrationStatus() const
Return the status of the integration.
Definition: MoMEMta.cc:485
std::vector< double > evaluateIntegrand(const std::vector< double > &psPoints)
Evaluate the integrand on a single phase-space point.
Definition: MoMEMta.cc:414
std::enable_if< std::is_same< T, bool >::value||std::is_same< T, InputTag >::value >::type set(const std::string &name, const T &value)
Change the value of a given parameter. If the parameter does not exist, it&#39;s first created...
Definition: ParameterSet.h:160
Definition: Graph.h:21
No integration was performed.
const ParameterSet & getCubaConfiguration() const
A class encapsulating a lua table.
Definition: ParameterSet.h:82
Integration was successful.
void setEvent(const std::vector< momemta::Particle > &particles, const LorentzVector &met=LorentzVector())
Set the event particles&#39; momenta.
Definition: MoMEMta.cc:159
Integration was stopped before desired accuracy was reached.
std::vector< std::pair< double, double > > computeWeights(const std::vector< momemta::Particle > &particles, const LorentzVector &met=LorentzVector())
Compute the weights in the current configuration.
Definition: MoMEMta.cc:192