BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
PyImport Namespace Reference

Functions

std::unique_ptr< MultiLayercreateFromPython (const std::string &script, const std::string &functionName, const std::string &path="")
 Creates a multi layer by running python code in embedded interpreter. More...
 
std::vector< std::string > listOfFunctions (const std::string &script, const std::string &path="")
 Returns list of functions defined in the script. More...
 

Function Documentation

◆ createFromPython()

std::unique_ptr< MultiLayer > PyImport::createFromPython ( const std::string &  script,
const std::string &  functionName,
const std::string &  path = "" 
)

Creates a multi layer by running python code in embedded interpreter.

Parameters
scriptPython script
functionNameA function name in this script which produces a MultiLayer
pathA path to import BornAgain library. If empty, relies on PYTHONPATH

Definition at line 34 of file PyImport.cpp.

37 {
39 
40  PyObject* pCompiledFn = Py_CompileString(script.c_str(), "", Py_file_input);
41  if (!pCompiledFn)
42  throw std::runtime_error(error_description("Can't compile snippet"));
43 
44  // create a module
45  PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn);
46  if (!pModule) {
47  Py_DecRef(pCompiledFn);
48  throw std::runtime_error(error_description("Can't exec module"));
49  }
50 
51  // locate the "get_simulation" function (it's an attribute of the module)
52  PyObject* pAddFn = PyObject_GetAttrString(pModule, functionName.c_str());
53  if (!pAddFn)
54  throw std::runtime_error("Can't locate compiled function");
55 
56  PyObject* instance = PyObject_CallFunctionObjArgs(pAddFn, NULL);
57  if (!instance) {
58  Py_DecRef(pAddFn);
59  Py_DecRef(pModule);
60  Py_DecRef(pCompiledFn);
61  throw std::runtime_error(error_description("Can't call function"));
62  }
63 
64  // clean up
65  Py_DecRef(pAddFn);
66  Py_DecRef(pModule);
67  Py_DecRef(pCompiledFn);
68 
69  void* argp1 = 0;
70  swig_type_info* pTypeInfo = SWIG_TypeQuery("MultiLayer *");
71 
72  const int res = SWIG_ConvertPtr(instance, &argp1, pTypeInfo, 0);
73  if (!SWIG_IsOK(res)) {
74  Py_DecRef(instance);
75  throw std::runtime_error("SWIG failed to extract a MultiLayer.");
76  }
77 
78  MultiLayer* multilayer = reinterpret_cast<MultiLayer*>(argp1);
79  std::unique_ptr<MultiLayer> result(multilayer->clone());
80 
81  Py_DecRef(instance);
82 
83  return result;
84 }
_object PyObject
Definition: PyObject.h:25
Our sample model: a stack of layers one below the other.
Definition: MultiLayer.h:41
MultiLayer * clone() const final
Returns a clone of this ISampleNode object.
Definition: MultiLayer.cpp:36
void import_bornagain(const std::string &path="")
Imports BornAgain from given location. If path is empty, tries to rely on PYTHONPATH.
Definition: PyUtils.cpp:71

References MultiLayer::clone(), and PyUtils::import_bornagain().

Referenced by PyImportAssistant::createMultiLayer().

Here is the call graph for this function:

◆ listOfFunctions()

std::vector< std::string > PyImport::listOfFunctions ( const std::string &  script,
const std::string &  path = "" 
)

Returns list of functions defined in the script.

Parameters
scriptPython script
pathA path to import BornAgain library. If empty, relies on PYTHONPATH

Definition at line 86 of file PyImport.cpp.

88 {
90 
91  PyObject* pCompiledFn = Py_CompileString(script.c_str(), "", Py_file_input);
92  if (!pCompiledFn)
93  throw std::runtime_error(error_description("Can't compile snippet"));
94 
95  // create a module
96  PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn);
97  if (!pModule) {
98  Py_DecRef(pCompiledFn);
99  throw std::runtime_error(error_description("Can't exec module"));
100  }
101 
102  PyObject* dict = PyModule_GetDict(pModule);
103  if (!dict)
104  throw std::runtime_error("Can't get dictionary from module");
105 
106  std::vector<std::string> result;
107  PyObject *key, *value;
108  Py_ssize_t pos = 0;
109  while (PyDict_Next(dict, &pos, &key, &value)) {
110  if (PyCallable_Check(value)) {
111  std::string func_name = PyUtils::toString(key);
112  if (func_name.find("__") == std::string::npos)
113  result.push_back(func_name);
114  }
115  }
116 
117  Py_DecRef(dict);
118  Py_DecRef(pModule);
119  Py_DecRef(pCompiledFn);
120 
121  return result;
122 }
std::string toString(PyObject *obj)
Converts PyObject into string, if possible, or throws exception.
Definition: PyUtils.cpp:24

References PyUtils::import_bornagain(), and PyUtils::toString().

Referenced by PyImportAssistant::getPySampleFunctionName().

Here is the call graph for this function: