OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
PythonExpr.h
Go to the documentation of this file.
1 //
2 // Struct PythonExpression
3 // Execute a python script using all given arguments (except for the first
4 // being the script name) and return the value of the "result" variable in
5 // the python script.
6 // Expression arguments can be accessed in the Python script using the vector
7 // variable "arguments", like i.e. in file "test.py":
8 // \verbatim
9 // result = 2.0 * arguments[0]
10 // \endverbatim
11 // to double the value passed as second argument to the Python expression.
12 // For example the expression
13 // \verbatim
14 // EXPR="python("test.py", 15.0)";
15 // \endverbatim
16 // evaluates to a value of 30.0 (test.py contains the line shown above).
17 //
18 // Copyright (c) 2010 - 2013, Yves Ineichen, ETH Zürich
19 // All rights reserved
20 //
21 // Implemented as part of the PhD thesis
22 // "Toward massively parallel multi-objective optimization with application to
23 // particle accelerators" (https://doi.org/10.3929/ethz-a-009792359)
24 //
25 // This file is part of OPAL.
26 //
27 // OPAL is free software: you can redistribute it and/or modify
28 // it under the terms of the GNU General Public License as published by
29 // the Free Software Foundation, either version 3 of the License, or
30 // (at your option) any later version.
31 //
32 // You should have received a copy of the GNU General Public License
33 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
34 //
35 #ifndef __PYTHON_EXPR_H__
36 #define __PYTHON_EXPR_H__
37 
38 #include "boost/tuple/tuple.hpp"
39 #include "boost/variant/get.hpp"
40 #include "boost/variant/variant.hpp"
41 
42 #include <boost/python.hpp>
43 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
44 
45 #include "Util/Types.h"
46 #include "Util/OptPilotException.h"
47 #include "Expression/Expression.h"
49 
50 using namespace boost::python;
51 
53 
55  std::string script = boost::get<std::string>(args[0]);
56  std::vector<double> pargs;
57  for(size_t i = 1; i < args.size(); i++) {
58  pargs.push_back(boost::get<double>(args[i]));
59  }
60 
61  try {
62  Py_Initialize();
63  object main_module = import("__main__");
64  object main_namespace = main_module.attr("__dict__");
65 
66  boost::python::class_<std::vector<double> >("PyVec")
67  .def(boost::python::vector_indexing_suite<std::vector<double> >());
68  main_namespace["arguments"] = pargs;
69 
70  object ignored = exec_file(script.c_str(), main_namespace);
71  double res = extract<double>(main_namespace["result"]);
72 
73  Py_Finalize();
74  return boost::make_tuple(res, true);
75 
76  } catch (error_already_set) {
77  PyErr_Print();
78  return boost::make_tuple(0.0, false);
79  }
80  }
81 };
82 
83 
84 #endif
boost::tuple< double, bool > Result_t
Definition: Expression.h:66
std::vector< argument_t > arguments_t
Definition: function.hpp:19
Expressions::Result_t operator()(client::function::arguments_t args)
Definition: PythonExpr.h:54