BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
BaseUtils::Python Namespace Reference

Functions

PyObjectcreateNumpyArray (const std::vector< double > &data)
 
PyObjectimport_bornagain (const std::vector< std::string > &paths={})
 Imports BornAgain from given location. If path is empty, tries to rely on PYTHONPATH. More...
 
std::string pythonRuntimeInfo ()
 Returns multi-line string representing PATH, PYTHONPATH, sys.path and other info. More...
 
std::string pythonStackTrace ()
 Returns string representing python stack trace. More...
 
std::string toString (char *c)
 Converts char to string. In the case of nullptr will return an empty string. More...
 
std::string toString (PyObject *obj)
 Converts PyObject into string, if possible, or throws exception. More...
 
std::string toString (wchar_t *c)
 
std::vector< std::string > toVectorString (PyObject *obj)
 Converts PyObject into vector of strings, if possible, or throws exception. More...
 

Function Documentation

◆ createNumpyArray()

PyObject * BaseUtils::Python::createNumpyArray ( const std::vector< double > &  data)

Definition at line 178 of file PyUtils.cpp.

179 {
180  const size_t ndim(1);
181  npy_int ndim_numpy = ndim;
182  auto* ndimsizes_numpy = new npy_intp[ndim];
183  ndimsizes_numpy[0] = data.size();
184 
185  // creating standalone numpy array
186  PyObject* pyarray = PyArray_SimpleNew(ndim_numpy, ndimsizes_numpy, NPY_DOUBLE);
187  delete[] ndimsizes_numpy;
188  if (pyarray == nullptr)
189  throw std::runtime_error("ExportDatafield() -> Panic in PyArray_SimpleNew");
190 
191  // getting pointer to data buffer of numpy array
192  double* array_buffer = (double*)PyArray_DATA((PyArrayObject*)pyarray);
193 
194  for (size_t index = 0; index < data.size(); ++index)
195  *array_buffer++ = data[index];
196 
197  return pyarray;
198 }
_object PyObject
Definition: PyObject.h:25

◆ import_bornagain()

PyObject * BaseUtils::Python::import_bornagain ( const std::vector< std::string > &  paths = {})

Imports BornAgain from given location. If path is empty, tries to rely on PYTHONPATH.

Definition at line 71 of file PyUtils.cpp.

72 {
73  if (Py_IsInitialized())
74  return nullptr;
75 
76  Py_InitializeEx(0); // like Py_Initialize, but skip registration of signal handlers
77 
78  if (!paths.empty()) {
79  PyObject* sysPath = PySys_GetObject((char*)"path");
80  for (const std::string& path : paths)
81  PyList_Append(sysPath, PyString_FromString(path.c_str()));
82  }
83 
84  // Stores signal handler before numpy's mess it up.
85  // This is to make ctrl-c working from terminal.
86 #ifndef _WIN32
87  PyOS_sighandler_t sighandler;
88  sighandler = PyOS_getsig(SIGINT);
89 #endif
90 
91  PyObject* pmod = PyImport_ImportModule("bornagain");
92  if (!pmod) {
93  PyErr_Print();
94  throw std::runtime_error("Can't load bornagain");
95  }
96 
97  // restores single handler to make ctr-c alive.
98 #ifndef _WIN32
99  PyOS_setsig(SIGINT, sighandler);
100 #endif
101 
102  return pmod;
103 }

Referenced by Py::Import::createFromPython(), and Py::Import::listOfFunctions().

◆ pythonRuntimeInfo()

std::string BaseUtils::Python::pythonRuntimeInfo ( )

Returns multi-line string representing PATH, PYTHONPATH, sys.path and other info.

Definition at line 105 of file PyUtils.cpp.

106 {
107  Py_InitializeEx(0);
108 
109  std::stringstream result;
110 
111  // Runtime environment
112  result << std::string(60, '=') << "\n";
113  result << "PATH: " << BaseUtils::System::getenv("PATH") << "\n";
114  result << "PYTHONPATH: " << BaseUtils::System::getenv("PYTHONPATH") << "\n";
115  result << "PYTHONHOME: " << BaseUtils::System::getenv("PYTHONHOME") << "\n";
116 
117  // Embedded Python details
118  result << "Py_GetProgramName(): " << BaseUtils::Python::toString(Py_GetProgramName()) << "\n";
119  result << "Py_GetProgramFullPath(): " << BaseUtils::Python::toString(Py_GetProgramFullPath())
120  << "\n";
121  result << "Py_GetPath(): " << BaseUtils::Python::toString(Py_GetPath()) << "\n";
122  result << "Py_GetPythonHome(): " << BaseUtils::Python::toString(Py_GetPythonHome()) << "\n";
123 
124  // Runtime Python's sys.path
125  PyObject* sysPath = PySys_GetObject((char*)"path");
126  auto content = BaseUtils::Python::toVectorString(sysPath);
127  result << "sys.path: ";
128  for (auto s : content)
129  result << s << ",";
130  result << "\n";
131 
132  return result.str();
133 }
std::vector< std::string > toVectorString(PyObject *obj)
Converts PyObject into vector of strings, if possible, or throws exception.
Definition: PyUtils.cpp:35
std::string toString(PyObject *obj)
Converts PyObject into string, if possible, or throws exception.
Definition: PyUtils.cpp:24
std::string getenv(const std::string &name)
Returns environment variable.
Definition: SysUtils.cpp:32

References BaseUtils::System::getenv(), toString(), and toVectorString().

Referenced by pythonStackTrace().

Here is the call graph for this function:

◆ pythonStackTrace()

std::string BaseUtils::Python::pythonStackTrace ( )

Returns string representing python stack trace.

Definition at line 138 of file PyUtils.cpp.

139 {
140  std::stringstream result;
141 
142  if (PyErr_Occurred()) {
143  PyObject *ptype, *pvalue, *ptraceback, *pystr;
144 
145  PyErr_Fetch(&ptype, &pvalue, &ptraceback);
146  pystr = PyObject_Str(pvalue);
147  if (char* str = PyString_AsString(pystr))
148  result << std::string(str) << "\n";
149 
150  PyObject* module_name = PyString_FromString("traceback");
151  PyObject* pyth_module = PyImport_Import(module_name);
152  Py_DecRef(module_name);
153 
154  if (pyth_module) {
155  result << "\n";
156  PyObject* pyth_func = PyObject_GetAttrString(pyth_module, "format_exception");
157  if (pyth_func && PyCallable_Check(pyth_func)) {
158  PyObject* pyth_val =
159  PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL);
160  if (pyth_val) {
161  pystr = PyObject_Str(pyth_val);
162  if (char* str = PyString_AsString(pystr))
163  result << std::string(str);
164  Py_DecRef(pyth_val);
165  }
166  }
167  result << "\n";
168  }
169  }
170 
171  result << "\n";
172  result << pythonRuntimeInfo();
173  result << "\n";
174 
175  return result.str();
176 }
std::string pythonRuntimeInfo()
Returns multi-line string representing PATH, PYTHONPATH, sys.path and other info.
Definition: PyUtils.cpp:105

References pythonRuntimeInfo().

Here is the call graph for this function:

◆ toString() [1/3]

std::string BaseUtils::Python::toString ( char *  c)

Converts char to string. In the case of nullptr will return an empty string.

Definition at line 56 of file PyUtils.cpp.

57 {
58  if (c)
59  return c;
60  return "";
61 }

◆ toString() [2/3]

std::string BaseUtils::Python::toString ( PyObject obj)

Converts PyObject into string, if possible, or throws exception.

Definition at line 24 of file PyUtils.cpp.

25 {
26  std::string result;
27  PyObject* pyStr = PyUnicode_AsEncodedString(obj, "utf-8", "replace");
28  if (pyStr != nullptr) {
29  result = std::string(PyBytes_AsString(pyStr));
30  Py_DecRef(pyStr);
31  }
32  return result;
33 }

Referenced by Py::Import::listOfFunctions(), pythonRuntimeInfo(), and toVectorString().

◆ toString() [3/3]

std::string BaseUtils::Python::toString ( wchar_t *  c)

Definition at line 63 of file PyUtils.cpp.

64 {
65  if (!c)
66  return "";
67  std::wstring wstr(c);
68  return std::string(wstr.begin(), wstr.end());
69 }

◆ toVectorString()

std::vector< std::string > BaseUtils::Python::toVectorString ( PyObject obj)

Converts PyObject into vector of strings, if possible, or throws exception.

Definition at line 35 of file PyUtils.cpp.

36 {
37  std::vector<std::string> result;
38 
39  if (PyTuple_Check(obj)) {
40  for (Py_ssize_t i = 0; i < PyTuple_Size(obj); i++) {
41  PyObject* value = PyTuple_GetItem(obj, i);
42  result.push_back(toString(value));
43  }
44  } else if (PyList_Check(obj)) {
45  for (Py_ssize_t i = 0; i < PyList_Size(obj); i++) {
46  PyObject* value = PyList_GetItem(obj, i);
47  result.push_back(toString(value));
48  }
49  } else
50  throw std::runtime_error(
51  "BaseUtils::Python::toVectorString() -> Error. Unexpected object.");
52 
53  return result;
54 }

References toString().

Referenced by pythonRuntimeInfo().

Here is the call graph for this function: