1
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus
3
* MAUS is free software: you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation, either version 3 of the License, or
6
* (at your option) any later version.
8
* MAUS is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with MAUS. If not, see <http://www.gnu.org/licenses/>.
17
#ifndef _SRC_COMMON_CPP_API_PYWRAPINPUTBASE_INL_
18
#define _SRC_COMMON_CPP_API_PYWRAPINPUTBASE_INL_
22
// These ifdefs are required to avoid cpp compiler warning
23
#ifdef _POSIX_C_SOURCE
24
#undef _POSIX_C_SOURCE
32
#include "structmember.h"
34
#include "src/common_cpp/API/PyWrapInputBaseEmitter.hh"
37
template <class INPUTCLASS>
38
PyObject* PyWrapInputBase<INPUTCLASS>::birth(PyObject* self,
41
PyWrappedInput* py_input = reinterpret_cast<PyWrappedInput*>(self);
42
if (!py_input->input) {
43
PyErr_SetString(PyExc_ValueError, "self was not initialised properly");
47
static char *kwlist[] = {const_cast<char*>("datacards"), NULL};
50
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, &cards)) {
53
std::string config(cards);
55
py_input->input->birth(config);
56
} catch (std::exception& exc) {
57
PyErr_SetString(PyExc_ValueError, (&exc)->what());
60
PyErr_SetString(PyExc_SystemError, "Caught an unknown error during birth");
67
template <class INPUTCLASS>
68
PyObject* PyWrapInputBase<INPUTCLASS>::death(PyObject* self,
71
PyWrappedInput* py_input = reinterpret_cast<PyWrappedInput*>(self);
72
if (!py_input->input) {
73
PyErr_SetString(PyExc_ValueError, "self was not initialised properly");
77
py_input->input->death();
78
} catch (std::exception& exc) {
79
PyErr_SetString(PyExc_ValueError, (&exc)->what());
82
PyErr_SetString(PyExc_SystemError, "Caught an unknown error during birth");
89
template <class INPUTCLASS>
90
PyObject* PyWrapInputBase<INPUTCLASS>::emitter(PyObject* self,
93
typedef PyWrapInputBaseEmitter<INPUTCLASS> Emitter;
94
typedef typename Emitter::PyWrappedInputEmitter PyEmitter;
95
PyTypeObject& type = Emitter::_class_type;
96
PyEmitter* emitter = reinterpret_cast<PyEmitter*>(type.tp_alloc(&type, 0));
97
PyWrappedInput* self_input = reinterpret_cast<PyWrappedInput*>(self);
98
emitter->input = self_input->input;
99
return reinterpret_cast<PyObject*>(emitter);
102
template <class INPUTCLASS>
103
PyObject* PyWrapInputBase<INPUTCLASS>::_new(PyTypeObject* type, PyObject *args, PyObject *kwds) {
104
PyWrappedInput* self = reinterpret_cast<PyWrappedInput*>(type->tp_alloc(type, 0));
106
return reinterpret_cast<PyObject*>(self);
109
template <class INPUTCLASS>
110
std::string PyWrapInputBase<INPUTCLASS>::_birth_docstring =
111
std::string("Initialise the inputter based on datacards\n\n")+
112
std::string(" - datacards: string representation of the control variables\n");
114
template <class INPUTCLASS>
115
std::string PyWrapInputBase<INPUTCLASS>::_emitter_docstring =
116
std::string("Emit some data\n\n");
118
template <class INPUTCLASS>
119
std::string PyWrapInputBase<INPUTCLASS>::_death_docstring =
120
std::string("Deinitialise the inputter ready for the next run\n");
122
template <class INPUTCLASS>
123
std::string PyWrapInputBase<INPUTCLASS>::_class_docstring =
124
std::string("Class for generating MAUS data.\n\n")+
125
std::string(" def __init__(self)\n")+
126
std::string(" Initialise the class\n");
129
template <class INPUTCLASS>
130
int PyWrapInputBase<INPUTCLASS>::_init(PyWrappedInput* self, PyObject *args, PyObject *kwds) {
131
if (self->input == NULL)
132
self->input = new INPUTCLASS();
136
template <class INPUTCLASS>
137
void PyWrapInputBase<INPUTCLASS>::_dealloc(PyWrappedInput* self) {
138
if (self->input != NULL)
142
template <class INPUTCLASS>
143
PyMemberDef PyWrapInputBase<INPUTCLASS>::_members[] = {
144
{NULL} /* Sentinel */
147
// static PyMemberDef _members[] = {
152
template <class INPUTCLASS>
153
PyMethodDef PyWrapInputBase<INPUTCLASS>::_methods[] = {
154
{"birth", (PyCFunction)birth,
155
METH_VARARGS|METH_KEYWORDS, _birth_docstring.c_str()},
156
{"death", (PyCFunction)death,
157
METH_VARARGS|METH_KEYWORDS, _death_docstring.c_str()},
158
{"emitter", (PyCFunction)emitter,
159
METH_VARARGS|METH_KEYWORDS, _emitter_docstring.c_str()},
163
template <class INPUTCLASS>
164
PyMethodDef PyWrapInputBase<INPUTCLASS>::_module_methods[] = {
165
{NULL} /* Sentinel */
168
template <class INPUTCLASS>
169
std::string PyWrapInputBase<INPUTCLASS>::_class_name = "";
170
template <class INPUTCLASS>
171
std::string PyWrapInputBase<INPUTCLASS>::_module_name = "";
172
template <class INPUTCLASS>
173
std::string PyWrapInputBase<INPUTCLASS>::_path_name = "";
176
template <class INPUTCLASS>
177
PyTypeObject PyWrapInputBase<INPUTCLASS>::_class_type = {
178
PyObject_HEAD_INIT(NULL)
180
_path_name.c_str(), /*tp_name*/
181
sizeof(PyWrappedInput), /*tp_basicsize*/
183
(destructor)_dealloc, /*tp_dealloc*/
190
0, /*tp_as_sequence*/
198
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
199
_class_docstring.c_str(), /* tp_doc */
202
0, /* tp_richcompare */
203
0, /* tp_weaklistoffset */
206
PyWrapInputBase<INPUTCLASS>::_methods, /* tp_methods */
207
PyWrapInputBase<INPUTCLASS>::_members, /* tp_members */
211
0, /* tp_descr_get */
212
0, /* tp_descr_set */
213
0, /* tp_dictoffset */
214
(initproc)_init, /* tp_init */
219
template <class INPUTCLASS>
220
void PyWrapInputBase<INPUTCLASS>::PyWrapInputBaseModInit(
221
std::string class_name,
222
std::string class_docstring,
223
std::string birth_docstring,
224
std::string death_docstring,
225
std::string emitter_docstring) {
226
if (class_docstring != "")
227
_class_docstring = class_docstring;
228
if (birth_docstring != "")
229
_birth_docstring = birth_docstring;
230
if (death_docstring != "")
231
_death_docstring = death_docstring;
232
if (emitter_docstring != "")
233
_emitter_docstring = emitter_docstring;
234
_methods[0].ml_doc = _birth_docstring.c_str();
235
_methods[1].ml_doc = _emitter_docstring.c_str();
236
_methods[2].ml_doc = _death_docstring.c_str();
238
_class_type.tp_doc = _class_docstring.c_str();
239
// Static so allocates c_str() memory for lifetime of the program
240
_class_name = class_name;
241
_module_name = "_"+_class_name;
242
_path_name = "_"+_class_name+"."+_class_name;
243
_class_type.tp_name = _path_name.c_str();
246
if (PyType_Ready(&_class_type) < 0)
249
module = Py_InitModule3(_module_name.c_str(), _module_methods,
250
"Please import the class directly from the MAUS module.");
254
PyTypeObject* obj_class_type = &_class_type;
255
Py_INCREF(obj_class_type);
256
PyModule_AddObject(module,
258
reinterpret_cast<PyObject*>(obj_class_type));
260
// Now the iterator object
261
typedef PyWrapInputBaseEmitter<INPUTCLASS> Emitter;
262
Emitter::_path_name = _module_name+"."+Emitter::_class_name;
263
Emitter::_class_type.tp_name = Emitter::_path_name.c_str();
264
Emitter::_class_type.tp_new = PyType_GenericNew;
265
if (PyType_Ready(&Emitter::_class_type) < 0)
267
PyTypeObject* emitter_class_type = &Emitter::_class_type;
268
Py_INCREF(emitter_class_type);
269
PyModule_AddObject(module,
270
Emitter::_class_name.c_str(),
271
reinterpret_cast<PyObject*>(emitter_class_type));