/* 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_PYWRAPOUTPUTBASE_INL_
#define _SRC_COMMON_CPP_API_PYWRAPOUTPUTBASE_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* PyWrapOutputBase::birth(PyObject* self,
PyObject *args,
PyObject *kwds) {
PyWrappedOutput* py_output = reinterpret_cast(self);
if (!py_output->output) {
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_output->output->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* PyWrapOutputBase::death(PyObject* self,
PyObject *args,
PyObject *kwds) {
PyWrappedOutput* py_output = reinterpret_cast(self);
if (!py_output->output) {
PyErr_SetString(PyExc_ValueError, "self was not initialised properly");
return NULL;
}
try {
py_output->output->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* PyWrapOutputBase::save(PyObject* self,
PyObject *args,
PyObject *kwds) {
PyWrappedOutput* py_output = reinterpret_cast(self);
if (!py_output->output) {
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;
}
// data_out should be Py_NONE or NULL (error)
PyObject* data_out = py_output->output->save_pyobj(data_in);
return data_out;
}
template
PyObject* PyWrapOutputBase::_new(PyTypeObject* type, PyObject *args, PyObject *kwds) {
PyWrappedOutput* self = reinterpret_cast(type->tp_alloc(type, 0));
self->output = NULL;
return reinterpret_cast(self);
}
template
std::string PyWrapOutputBase::_birth_docstring =
std::string("Initialise the outputter based on datacards\n\n")+
std::string(" - datacards: string representation of the control variables\n");
template
std::string PyWrapOutputBase::_save_docstring =
std::string("Save the data\n\n")+
std::string(" - data: a parsable event, either in json, string or MAUS\n")+
std::string(" native representation. Can be a MAUS.Data, MAUS.JobHeader,\n")+
std::string(" MAUS.RunHeader, MAUS.RunFooter or MAUS.JobFooter object\n");
template
std::string PyWrapOutputBase::_death_docstring =
std::string("Deinitialise the outputter ready for the next run\n");
template
std::string PyWrapOutputBase::_class_docstring =
std::string("Class for saving the MAUS data.\n\n")+
std::string(" def __init__(self)\n")+
std::string(" Initialise the class\n");
template
int PyWrapOutputBase::_init(PyWrappedOutput* self, PyObject *args, PyObject *kwds) {
if (self->output == NULL)
self->output = new OUTPUTCLASS();
if (self->can_convert == NULL) {
self->can_convert = Py_True;
Py_INCREF(self->can_convert);
}
return 0;
}
template
void PyWrapOutputBase::_dealloc(PyWrappedOutput* self) {
if (self->output != NULL)
delete self->output;
Py_DECREF(self->can_convert);
}
template
PyMemberDef PyWrapOutputBase::_members[] = {
{const_cast("can_convert"),
T_OBJECT_EX, offsetof(PyWrappedOutput, can_convert), 0,
const_cast(
"Returns true if the module can do conversions, else false (or non-existent)"
)},
{NULL} /* Sentinel */
};
template
PyMethodDef PyWrapOutputBase::_methods[] = {
{"birth", (PyCFunction)birth,
METH_VARARGS|METH_KEYWORDS, _birth_docstring.c_str()},
{"death", (PyCFunction)death,
METH_VARARGS|METH_KEYWORDS, _death_docstring.c_str()},
{"save", (PyCFunction)save,
METH_VARARGS|METH_KEYWORDS, _save_docstring.c_str()},
{NULL} // Sentinel
};
template
PyMethodDef PyWrapOutputBase::_module_methods[] = {
{NULL} /* Sentinel */
};
template
std::string PyWrapOutputBase::_class_name = "";
template
std::string PyWrapOutputBase::_module_name = "";
template
std::string PyWrapOutputBase::_path_name = "";
template
PyTypeObject PyWrapOutputBase::_class_type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
_path_name.c_str(), /*tp_name*/
sizeof(PyWrappedOutput), /*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 */
PyWrapOutputBase::_methods, /* tp_methods */
PyWrapOutputBase::_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 PyWrapOutputBase::PyWrapOutputBaseModInit(
std::string class_name,
std::string class_docstring,
std::string birth_docstring,
std::string death_docstring,
std::string save_docstring) {
if (class_docstring != "")
_class_docstring = class_docstring;
if (birth_docstring != "")
_birth_docstring = birth_docstring;
if (death_docstring != "")
_death_docstring = death_docstring;
if (save_docstring != "")
_save_docstring = save_docstring;
_methods[0].ml_doc = _birth_docstring.c_str();
_methods[1].ml_doc = _save_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