/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*/
#ifndef _SRC_COMMON_CPP_API_PYWRAPREDUCEBASE_INL_
#define _SRC_COMMON_CPP_API_PYWRAPREDUCEBASE_INL_
#include
#include "Python.h"
#include "structmember.h" // python PyMemberDef
#include "src/common_cpp/Utils/JsonWrapper.hh"
#include "src/common_cpp/DataStructure/Data.hh"
#include "src/common_cpp/Utils/CppErrorHandler.hh"
namespace MAUS {
template
PyObject* PyWrapReduceBase::birth(PyObject* self,
PyObject *args,
PyObject *kwds) {
PyWrappedReduce* py_reduce = reinterpret_cast(self);
if (!py_reduce->reduce) {
PyErr_SetString(PyExc_ValueError, "self was not initialised properly");
return NULL;
}
static char *kwlist[] = {const_cast("datacards"), NULL};
char* cards;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, &cards)) {
return NULL;
}
std::string config(cards);
try {
py_reduce->reduce->birth(config);
} catch (std::exception& exc) {
PyErr_SetString(PyExc_ValueError, (&exc)->what());
return NULL;
} catch (...) {
PyErr_SetString(PyExc_SystemError, "Caught an unknown error during birth");
return NULL;
}
Py_RETURN_NONE;
}
template
PyObject* PyWrapReduceBase::death(PyObject* self,
PyObject *args,
PyObject *kwds) {
PyWrappedReduce* py_reduce = reinterpret_cast(self);
if (!py_reduce->reduce) {
PyErr_SetString(PyExc_ValueError, "self was not initialised properly");
return NULL;
}
try {
py_reduce->reduce->death();
} catch (std::exception& exc) {
PyErr_SetString(PyExc_ValueError, (&exc)->what());
return NULL;
} catch (...) {
PyErr_SetString(PyExc_SystemError, "Caught an unknown error during birth");
return NULL;
}
Py_RETURN_NONE;
}
template
PyObject* PyWrapReduceBase::process(PyObject* self,
PyObject *args,
PyObject *kwds) {
PyWrappedReduce* py_reduce = reinterpret_cast(self);
if (!py_reduce->reduce) {
PyErr_SetString(PyExc_ValueError, "self was not initialised properly");
return NULL;
}
static char *kwlist[] = {const_cast("data"), NULL};
PyObject* data_in;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|", kwlist, &data_in)) {
return NULL;
}
PyObject* data_out = py_reduce->reduce->process_pyobj(data_in);
// PyObject* data_tuple_out = Py_BuildValue("(O)", &data_out);
return data_out;
}
template
PyObject* PyWrapReduceBase::_new(PyTypeObject* type,
PyObject *args,
PyObject *kwds) {
PyWrappedReduce* self = reinterpret_cast(
type->tp_alloc(type, 0));
self->reduce = NULL;
return reinterpret_cast(self);
}
template
std::string PyWrapReduceBase::_birth_docstring =
std::string("Initialise the reducer based on datacards\n\n")+
std::string(" - datacards: string representation of the control variables\n");
template
std::string PyWrapReduceBase::_process_docstring =
std::string("Process the data\n\n")+
std::string(" - data: a MAUS::Data event, either in json, string or MAUS\n")+
std::string(" native representation.\n")+
std::string("Returns a MAUS object, typically of MAUS::ImageData type.\n");
template
std::string PyWrapReduceBase::_death_docstring =
std::string("Deinitialise the reducer ready for the next run\n");
template
std::string PyWrapReduceBase::_class_docstring =
std::string("Class for processing the MAUS data.\n\n")+
std::string(" def __init__(self)\n")+
std::string(" Initialise the class\n");
template
int PyWrapReduceBase::_init(PyWrappedReduce* self,
PyObject *args,
PyObject *kwds) {
if (self->reduce == NULL)
self->reduce = new REDUCECLASS();
if (self->can_convert == NULL) {
self->can_convert = Py_True;
Py_INCREF(self->can_convert);
}
return 0;
}
template
void PyWrapReduceBase::_dealloc(PyWrappedReduce* self) {
if (self->reduce != NULL)
delete self->reduce;
Py_DECREF(self->can_convert);
}
template
PyMemberDef PyWrapReduceBase::_members[] = {
{const_cast("can_convert"),
T_OBJECT_EX, offsetof(PyWrappedReduce, can_convert), 0,
const_cast(
"Returns true if the module can do conversions, else false (or non-existent)"
)},
{NULL} /* Sentinel */
};
template
PyMethodDef PyWrapReduceBase::_methods[] = {
{"birth", (PyCFunction)birth,
METH_VARARGS|METH_KEYWORDS, _birth_docstring.c_str()},
{"death", (PyCFunction)death,
METH_VARARGS|METH_KEYWORDS, _death_docstring.c_str()},
{"process", (PyCFunction)process,
METH_VARARGS|METH_KEYWORDS, _process_docstring.c_str()},
{NULL} // Sentinel
};
template
PyMethodDef PyWrapReduceBase::_module_methods[] = {
{NULL} /* Sentinel */
};
template
std::string PyWrapReduceBase::_class_name = "";
template
std::string PyWrapReduceBase::_module_name = "";
template
std::string PyWrapReduceBase::_path_name = "";
template
PyTypeObject PyWrapReduceBase::_class_type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
_path_name.c_str(), /*tp_name*/
sizeof(PyWrappedReduce), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
_class_docstring.c_str(), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
PyWrapReduceBase::_methods, /* tp_methods */
PyWrapReduceBase::_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)_init, /* tp_init */
0, /* tp_alloc */
_new, /* tp_new */
};
template
void PyWrapReduceBase::PyWrapReduceBaseModInit(
std::string class_name,
std::string class_docstring,
std::string birth_docstring,
std::string death_docstring,
std::string process_docstring) {
if (class_docstring != "")
_class_docstring = class_docstring;
if (birth_docstring != "")
_birth_docstring = birth_docstring;
if (death_docstring != "")
_death_docstring = death_docstring;
if (process_docstring != "")
_process_docstring = process_docstring;
_methods[0].ml_doc = _birth_docstring.c_str();
_methods[1].ml_doc = _process_docstring.c_str();
_methods[2].ml_doc = _death_docstring.c_str();
_class_type.tp_doc = _class_docstring.c_str();
// Static so allocates c_str() memory for lifetime of the program
_class_name = class_name;
_module_name = "_"+_class_name;
_path_name = "_"+_class_name+"."+_class_name;
_class_type.tp_name = _path_name.c_str();
PyObject* module;
if (PyType_Ready(&_class_type) < 0)
return;
module = Py_InitModule3(_module_name.c_str(), _module_methods,
"Please import the class directly from the MAUS module.");
if (module == NULL)
return;
PyTypeObject* obj_class_type = &_class_type;
Py_INCREF(obj_class_type);
PyModule_AddObject(module,
_class_name.c_str(),
reinterpret_cast(obj_class_type));
}
} // ~MAUS
#endif