SourceXtractorPlusPlus  0.10
Please provide a description of the project.
PythonInterpreter.cpp
Go to the documentation of this file.
1 
17 /*
18  * @file PythonInterpreter.cpp
19  * @author Nikolaos Apostolakos <nikoapos@gmail.com>
20  */
21 
22 #include <signal.h>
23 #include <utility>
24 #include <boost/python/dict.hpp>
25 #include <boost/python/exec.hpp>
26 #include <boost/python/extract.hpp>
27 #include <boost/python/import.hpp>
28 #include <boost/python/object.hpp>
29 #include <Python.h>
30 
31 #include <SEUtils/Python.h>
34 
35 namespace py = boost::python;
36 
37 static Elements::Logging logger = Elements::Logging::getLogger("Python::Interpreter");
40 
41 namespace SourceXtractor {
42 
44  static PythonInterpreter singleton{};
45  return singleton;
46 }
47 
49  // Python sets its own signal handler for SIGINT (Ctrl+C), so it can throw a KeyboardInterrupt
50  // Here we are not interested on this behaviour, so we get whatever handler we've got (normally
51  // the default one) and restore it after initializing the interpreter
52  struct sigaction sigint_handler;
53  sigaction(SIGINT, nullptr, &sigint_handler);
54 
55  Py_Initialize();
56  PyEval_InitThreads();
57  PyEval_SaveThread();
58 
59  sigaction(SIGINT, &sigint_handler, nullptr);
60 }
61 
63  GILStateEnsure ensure;
64 
65  py::object main_module = py::import("__main__");
66  py::object main_namespace = main_module.attr("__dict__");
67  try {
68  py::exec(code.c_str(), main_namespace);
69  }
70  catch (const py::error_already_set &e) {
72  }
73 }
74 
76  GILStateEnsure ensure;
77 
78  try {
79  // Setup argv
80  // Python expects to have the ownership!
81 #if PY_MAJOR_VERSION == 2
82  using py_argv_char_t = char;
83 # define py_argv_assign(d, s, l) d = strndup(s, l)
84 #else
85  using py_argv_char_t = wchar_t;
86 # define py_argv_assign(d, s, l) d = Py_DecodeLocale(s, &l)
87 #endif
88 
89  py_argv_char_t **py_argv = static_cast<py_argv_char_t**>(PyMem_MALLOC((argv.size() + 1) * sizeof(py_argv_char_t*)));
90  size_t wlen = filename.size();
91  py_argv_assign(py_argv[0], filename.c_str(), wlen);
92  for (size_t i = 0; i < argv.size(); ++i) {
93  wlen = argv[i].size();
94  py_argv_assign(py_argv[i + 1], argv[i].c_str(), wlen);
95  }
96  PySys_SetArgv(argv.size() + 1, py_argv);
97 
98  // Import ourselves so the conversions are registered
99  py::import("_SourceXtractorPy");
100 
101  // Setup stdout and stderr
102  PySys_SetObject("stdout", py::object(boost::ref(m_out_wrapper)).ptr());
103  PySys_SetObject("stderr", py::object(boost::ref(m_err_wrapper)).ptr());
104 
105  // Run the file
106  py::object main_module = py::import("__main__");
107  py::setattr(main_module, "__file__", py::object(filename));
108  py::object main_namespace = main_module.attr("__dict__");
109  py::exec_file(filename.c_str(), main_namespace);
110  }
111  catch (const py::error_already_set &e) {
113  }
114 }
115 
117  GILStateEnsure ensure;
118 
119  try {
120  py::object meas_images_module = py::import("sourcextractor.config.measurement_images");
121  py::dict images = py::extract<py::dict>(meas_images_module.attr("measurement_images"));
122  py::list ids = images.keys();
124  for (int i = 0; i < py::len(ids); ++i) {
125  int id = py::extract<int>(ids[i]);
126  PyMeasurementImage im = py::extract<PyMeasurementImage>(images[ids[i]]);
127  result.emplace(std::make_pair(id, im));
128  }
129  return result;
130  }
131  catch (const py::error_already_set &e) {
133  }
134 }
135 
137  GILStateEnsure ensure;
138 
139  try {
140  py::object apertures_module = py::import("sourcextractor.config.aperture");
141  py::dict apertures = py::extract<py::dict>(apertures_module.attr("apertures_for_image"));
142  py::list ids = apertures.keys();
144  for (int i = 0; i < py::len(ids); ++i) {
145  int id = py::extract<int>(ids[i]);
146  PyAperture ap = py::extract<PyAperture>(apertures[ids[i]]);
147  result.emplace(std::make_pair(id, ap));
148  }
149  return result;
150  }
151  catch (const py::error_already_set &e) {
153  }
154 }
155 
157  GILStateEnsure ensure;
158 
159  try {
160  py::object output_module = py::import("sourcextractor.config.output");
161  py::list output = py::extract<py::list>(output_module.attr("model_fitting_parameter_columns"));
163  for (int i = 0; i < py::len(output); ++i) {
164  py::tuple t = py::extract<py::tuple>(output[i]);
165  std::string name = py::extract<std::string>(t[0]);
166  auto extract_list = py::extract<py::list>(t[1]);
167 
168  std::vector<int> ids{};
169  if (extract_list.check()) {
170  py::list cs = extract_list;
171  for (int j = 0; j < py::len(cs); ++j) {
172  int c = py::extract<int>(cs[j].attr("id"));
173  ids.push_back(c);
174  }
175  } else {
176  int c = py::extract<int>(t[1]);
177  ids.push_back(c);
178  }
179  result.emplace_back(name, std::move(ids));
180  }
181  return result;
182  }
183  catch (const py::error_already_set &e) {
185  }
186 }
187 
189  GILStateEnsure ensure;
190 
191  try {
192  py::object output_module = py::import("sourcextractor.config.output");
193  py::list output = py::extract<py::list>(output_module.attr("aperture_columns"));
195  for (int i = 0; i < py::len(output); ++i) {
196  py::tuple t = py::extract<py::tuple>(output[i]);
197  std::string name = py::extract<std::string>(t[0]);
198  auto extract_list = py::extract<py::list>(t[1]);
199 
200  if (extract_list.check()) {
201  py::list cs = extract_list;
202  for (int j = 0; j < py::len(cs); ++j) {
203  int c = py::extract<int>(cs[j].attr("id"));
204  result[name].push_back(c);
205  }
206  } else {
207  int c = py::extract<int>(t[1]);
208  result[name].push_back(c);
209  }
210  }
211  return result;
212  }
213  catch (const py::error_already_set &e) {
215  }
216 }
217 
218 namespace {
219 
220 std::map<int, boost::python::object> getMapFromDict(const py::str &module_name, const py::str &dict_name) {
221  GILStateEnsure ensure;
222 
223  try {
224  py::object model_fitting_module = py::import(module_name);
225  py::dict parameters = py::extract<py::dict>(model_fitting_module.attr(dict_name));
226  py::list ids = parameters.keys();
228  for (int i = 0; i < py::len(ids); ++i) {
229  int id = py::extract<int>(ids[i]);
230  auto par = parameters[ids[i]];
231  result.emplace(std::make_pair(id, par));
232  }
233  return result;
234  }
235  catch (const py::error_already_set &e) {
237  }
238 }
239 
240 }
241 
243  return getMapFromDict("sourcextractor.config.model_fitting", "constant_parameter_dict");
244 }
245 
247  return getMapFromDict("sourcextractor.config.model_fitting", "free_parameter_dict");
248 }
249 
251  return getMapFromDict("sourcextractor.config.model_fitting", "dependent_parameter_dict");
252 }
253 
255  return getMapFromDict("sourcextractor.config.model_fitting", "prior_dict");
256 }
257 
259  return getMapFromDict("sourcextractor.config.model_fitting", "constant_model_dict");
260 }
261 
263  return getMapFromDict("sourcextractor.config.model_fitting", "point_source_model_dict");
264 }
265 
267  return getMapFromDict("sourcextractor.config.model_fitting", "sersic_model_dict");
268 }
269 
271  return getMapFromDict("sourcextractor.config.model_fitting", "exponential_model_dict");
272 }
273 
275  return getMapFromDict("sourcextractor.config.model_fitting", "de_vaucouleurs_model_dict");
276 }
277 
279  GILStateEnsure ensure;
280  try {
282  py::object model_fitting_module = py::import("sourcextractor.config.model_fitting");
283  py::dict frame_dict = py::extract<py::dict>(model_fitting_module.attr("frame_models_dict"));
284  py::list frame_ids = frame_dict.keys();
285  for (int i = 0; i < py::len(frame_ids); ++i) {
286  int frame_id = py::extract<int>(frame_ids[i]);
287  py::list model_ids = py::extract<py::list>(frame_dict[frame_ids[i]]);
288  for (int j = 0; j < py::len(model_ids); ++j) {
289  int model_id = py::extract<int>(model_ids[j]);
290  result[frame_id].push_back(model_id);
291  }
292  }
293  return result;
294  }
295  catch (const py::error_already_set &e) {
297  }
298 }
299 
301  GILStateEnsure ensure;
302 
303  py::object model_fitting_module = py::import("sourcextractor.config.model_fitting");
304  py::dict parameters = py::extract<py::dict>(model_fitting_module.attr("params_dict"));
305  py::list ids = parameters.keys();
307  for (int i = 0; i < py::len(ids); ++i) {
308  std::string id = py::extract<std::string>(ids[i]);
309  auto par = parameters[ids[i]];
310  result.emplace(std::make_pair(id, par));
311  }
312  return result;
313 }
314 
316  GILStateEnsure ensure;
317 
318  try {
319  py::object model_fitting_module = py::import("sourcextractor.config.measurement_images");
320  py::list groups = py::extract<py::list>(model_fitting_module.attr("MeasurementGroup").attr("_all_groups"));
322  for (int i = 0; i < py::len(groups); ++i) {
323  result.emplace_back(groups[i]);
324  }
325  return result;
326  }
327  catch (const py::error_already_set &e) {
329  }
330 }
331 
333  GILStateEnsure ensure;
334 
335  py::object model_fitting_module = py::import("sourcextractor.config.model_fitting");
336  auto python_function = model_fitting_module.attr("set_coordinate_system");
337  python_function(coordinate_system);
338 }
339 
340 }
std::map< int, boost::python::object > getConstantModels()
std::map< int, boost::python::object > getFreeParameters()
STL class.
static Elements::Logging logger
std::map< int, PyMeasurementImage > getMeasurementImages()
std::map< int, boost::python::object > getPointSourceModels()
std::vector< boost::python::object > getMeasurementGroups()
constexpr double e
void runCode(const std::string &code)
void setCoordinateSystem(std::shared_ptr< CoordinateSystem > coordinate_system)
std::map< std::string, std::vector< int > > getApertureOutputColumns()
Elements::Exception pyToElementsException(Elements::Logging &logger)
Definition: Python.cpp:30
STL class.
std::map< int, boost::python::object > getDeVaucouleursModels()
STL class.
std::map< int, boost::python::object > getSersicModels()
void runFile(const std::string &filename, const std::vector< std::string > &argv)
std::map< std::string, boost::python::object > getModelFittingParams()
std::map< int, boost::python::object > getPriors()
std::map< int, std::vector< int > > getFrameModelsMap()
string filename
Definition: conf.py:63
std::map< int, boost::python::object > getExponentialModels()
static Elements::Logging stdout_logger
std::map< int, boost::python::object > getConstantParameters()
T make_pair(T... args)
std::vector< std::pair< std::string, std::vector< int > > > getModelFittingOutputColumns()
#define py_argv_assign(d, s, l)
T move(T... args)
std::map< int, PyAperture > getApertures()
T size(T... args)
static Elements::Logging stderr_logger
T c_str(T... args)
T emplace(T... args)
std::map< int, boost::python::object > getDependentParameters()
static Logging getLogger(const std::string &name="")
static PythonInterpreter & getSingleton()
static Elements::Logging logger