#include #include #include #include /* python headers */ #include /* numarray headers */ #include #include /********************************************************/ /******************* graceTMPL.data type ***************/ /********************************************************/ typedef struct { PyObject_HEAD GraceTMPL::Data *data; } graceTMPL_dataObject; static void graceTMPL_dataDealloc(graceTMPL_dataObject *); static PyObject *graceTMPL_dataGetattr(graceTMPL_dataObject *, char *); static int graceTMPL_dataSetattr(graceTMPL_dataObject *, char *, PyObject *); static PyTypeObject graceTMPL_dataType = { PyObject_HEAD_INIT(NULL) 0, "data", sizeof(graceTMPL_dataObject), 0, (destructor)graceTMPL_dataDealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)graceTMPL_dataGetattr, /*tp_getattr*/ (setattrfunc)graceTMPL_dataSetattr, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ }; // PyTypeObject graceTMPL_dataType #define graceTMPLdata_Check(op) ((op)->ob_type == graceTMPL_dataType) /******************* attribute member functions *******************/ static char doc_data_setEnv[] = "setEnv(string, string): Set an environment definition."; static PyObject* graceTMPL_data_setEnv(graceTMPL_dataObject *self, PyObject *args) { char *name; char *value; if (!PyArg_ParseTuple(args, "ss:graceTMPL.data.setEnv(name, value)", &name, &value)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.data.setEnv(string, string) expected as arguments."); return NULL; } self->data->setenv(std::string(name), std::string(value)); return Py_None; } // graceTMPL_data_setEnv(PyObject *, PyObject *) static PyMethodDef graceTMPL_dataMethods[] = { {"setEnv", (PyCFunction)graceTMPL_data_setEnv, METH_VARARGS, doc_data_setEnv}, {NULL, NULL} /* sentinel */ }; // PyMethodDef graceTMPL_dataMethods[] /******************* type member functions *******************/ static void graceTMPL_dataDealloc(graceTMPL_dataObject *self) { delete self->data; PyObject_Del(self); } // graceTMPL_dataDealloc(graceTMPL_dataObject *) static PyObject *graceTMPL_dataGetattr(graceTMPL_dataObject *self, char *name) { return Py_FindMethod(graceTMPL_dataMethods, (PyObject *)self, name); } // graceTMPL_dataGetattr(graceTMPL_dataObject *, char *) static int graceTMPL_dataSetattr(graceTMPL_dataObject *self, char *name, PyObject *op) { PyErr_SetString(PyExc_AttributeError, "Attribute does not exist or cannot be set"); return -1; } // graceTMPL_dataSetattr(graceTMPL_dataObject *, char *, PyObject *) /********************************************************/ /******************* graceTMPL.graph type ***************/ /********************************************************/ typedef struct { PyObject_HEAD std::multiset *dataSet; GraceTMPL::Graph *graph; } graceTMPL_graphObject; static void graceTMPL_graphDealloc(graceTMPL_graphObject *); static PyObject *graceTMPL_graphGetattr(graceTMPL_graphObject *, char *); static int graceTMPL_graphSetattr(graceTMPL_graphObject *, char *, PyObject *); static PyTypeObject graceTMPL_graphType = { PyObject_HEAD_INIT(NULL) 0, "graph", sizeof(graceTMPL_graphObject), 0, (destructor)graceTMPL_graphDealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)graceTMPL_graphGetattr, /*tp_getattr*/ (setattrfunc)graceTMPL_graphSetattr, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ }; // PyTypeObject graceTMPL_graphType #define graceTMPLgraph_Check(op) ((op)->ob_type == graceTMPL_graphType) /******************* attribute member functions *******************/ static char doc_graph_setEnv[] = "setEnv(string, string): Set an environment definition."; static PyObject* graceTMPL_graph_setEnv(graceTMPL_graphObject *self, PyObject *args) { char *name; char *value; if (!PyArg_ParseTuple(args, "ss:graceTMPL.graph.setEnv(name, value)", &name, &value)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.graph.setEnv(string, string) expected as arguments."); return NULL; } self->graph->setenv(std::string(name), std::string(value)); return Py_None; } // graceTMPL_graph_setEnv(PyObject *, PyObject *) static char doc_graph_addData[] = "addData(numarray.array): Add a dataset to this graph."; static PyObject* graceTMPL_graph_addData(graceTMPL_graphObject *self, PyObject *args) { char *name; PyObject *oDataArray = Py_None; PyArrayObject *dataArray = 0; GraceTMPL::Data *newData = 0; graceTMPL_dataObject *dataObject = 0; int cols, rows; if (!PyArg_ParseTuple(args, "sO:graceTMPL.graph.addData(name, dataArray)", &name, &oDataArray)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.graph.addData(string, numarray.array) expected as arguments."); return NULL; } dataArray = NA_InputArray(oDataArray, tFloat64, C_ARRAY); if (dataArray->nd != 2 || dataArray->descr->type_num != PyArray_DOUBLE){ PyErr_SetString(PyExc_ValueError, "data array has to have exactly two axes and has to be of type float"); return NULL; } if(dataArray->dimensions[0] < 2){ PyErr_SetString(PyExc_ValueError, "data array has to have at least dimension 2 in first axis"); return NULL; } XXX_PyArray_INCREF(dataArray); cols = dataArray->dimensions[0]; rows = dataArray->dimensions[1]; if(cols > 4) cols = 4; double **data = new double *[cols]; for(int c = 0; c < cols; ++c){ data[c] = new double[rows]; for(int r = 0; r < rows; ++r) data[c][r] = *(double *)(dataArray->data + c * dataArray->strides[0] + r * dataArray->strides[1]); } XXX_PyArray_XDECREF(dataArray); switch(cols){ case 2: newData = new GraceTMPL::Data(std::string(name), rows, data[0], data[1]); break; case 3: newData = new GraceTMPL::Data(std::string(name), rows, data[0], data[1], data[2]); break; default: newData = new GraceTMPL::Data(std::string(name), rows, data[0], data[1], data[2], data[3]); } // switch(cols) for(int c = 0; c < cols; ++c) delete[] data[c]; delete[] data; dataObject = PyObject_New(graceTMPL_dataObject, &graceTMPL_dataType); dataObject->data = newData; Py_INCREF(dataObject); self->dataSet->insert(dataObject); self->graph->addData(newData); return (PyObject*)dataObject; } // graceTMPL_graph_addData(PyObject *, PyObject *) static PyMethodDef graceTMPL_graphMethods[] = { {"setEnv", (PyCFunction)graceTMPL_graph_setEnv, METH_VARARGS, doc_graph_setEnv}, {"addData", (PyCFunction)graceTMPL_graph_addData, METH_VARARGS, doc_graph_addData}, {NULL, NULL} /* sentinel */ }; // PyMethodDef graceTMPL_graphMethods[] /******************* type member functions *******************/ static void graceTMPL_graphDealloc(graceTMPL_graphObject *self) { std::multiset::iterator data; for(data = self->dataSet->begin(); data != self->dataSet->end(); ++data) Py_DECREF(*data); delete self->graph; delete self->dataSet; PyObject_Del(self); } // graceTMPL_graphDealloc(graceTMPL_graphObject *) static PyObject *graceTMPL_graphGetattr(graceTMPL_graphObject *self, char *name) { if(strcmp(name, "xoffset") == 0){ return PyFloat_FromDouble(self->graph->xoffset()); } if(strcmp(name, "yoffset") == 0){ return PyFloat_FromDouble(self->graph->yoffset()); } if(strcmp(name, "scaling") == 0){ return PyFloat_FromDouble(self->graph->scale()); } return Py_FindMethod(graceTMPL_graphMethods, (PyObject *)self, name); } // graceTMPL_graphGetattr(graceTMPL_graphObject *, char *) static int graceTMPL_graphSetattr(graceTMPL_graphObject *self, char *name, PyObject *op) { if(strcmp(name, "xoffset") == 0){ if (!PyFloat_Check(op)) return -1; self->graph->setXOffset(PyFloat_AsDouble(op)); return 0; } if(strcmp(name, "yoffset") == 0){ if (!PyFloat_Check(op)) return -1; self->graph->setYOffset(PyFloat_AsDouble(op)); return 0; } if(strcmp(name, "scaling") == 0){ if (!PyFloat_Check(op)) return -1; self->graph->setScaling(PyFloat_AsDouble(op)); return 0; } PyErr_SetString(PyExc_AttributeError, "Attribute does not exist or cannot be set"); return -1; } // graceTMPL_graphSetattr(graceTMPL_graphObject *, char *, PyObject *) /********************************************************/ /******************* graceTMPL.save type ****************/ /********************************************************/ typedef struct { PyObject_HEAD std::multiset *graphSet; GraceTMPL::Save *save; } graceTMPL_saveObject; static void graceTMPL_saveDealloc(graceTMPL_saveObject *); static PyObject *graceTMPL_saveGetattr(graceTMPL_saveObject *, char *); static int graceTMPL_saveSetattr(graceTMPL_saveObject *, char *, PyObject *); static PyTypeObject graceTMPL_saveType = { PyObject_HEAD_INIT(NULL) 0, "save", sizeof(graceTMPL_saveObject), 0, (destructor)graceTMPL_saveDealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)graceTMPL_saveGetattr, /*tp_getattr*/ (setattrfunc)graceTMPL_saveSetattr, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ }; // PyTypeObject graceTMPL_saveType #define graceTMPLsave_Check(op) ((op)->ob_type == graceTMPL_saveType) /******************* attribute member functions *******************/ static char doc_save_loadTemplate[] = "loadTemplate(string, bool): Load a xmgrace file as template."; static PyObject* graceTMPL_save_loadTemplate(graceTMPL_saveObject *self, PyObject *args) { char *name; int useS0 = 0; if (!PyArg_ParseTuple(args, "s|i:graceTMPL.save.loadTemplate(name, useS0=0)", &name, &useS0)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.save.loadTemplate(string, int) expected as arguments."); return NULL; } self->save->loadTemplate(name, useS0); return Py_None; } // graceTMPL_save_LoadTemplate(PyObject *, PyObject *) static char doc_save_setEnv[] = "setEnv(string, string): Set an environment definition."; static PyObject* graceTMPL_save_setEnv(graceTMPL_saveObject *self, PyObject *args) { char *name; char *value; if (!PyArg_ParseTuple(args, "ss:graceTMPL.save.setEnv(name, value)", &name, &value)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.save.setEnv(string, string) expected as arguments."); return NULL; } self->save->setenv(std::string(name), std::string(value)); return Py_None; } // graceTMPL_save_setEnv(PyObject *, PyObject *) static char doc_save_addGraph[] = "addGraph(int=0): Create and store a new Graph within this object."; static PyObject* graceTMPL_save_addGraph(graceTMPL_saveObject *self, PyObject *args) { graceTMPL_graphObject *graphObject; std::multiset *dataSet; int logplot = 0; if(!PyArg_ParseTuple(args, "|i:save.addGraph(logplot=0)", &logplot)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.save.addGraph(int=0) expected as arguments."); return NULL; } graphObject = PyObject_New(graceTMPL_graphObject, &graceTMPL_graphType); Py_INCREF(graphObject); self->graphSet->insert(graphObject); dataSet = new std::multiset; graphObject->graph = self->save->newGraph(logplot); graphObject->dataSet = dataSet; return (PyObject*)graphObject; } // graceTMPL_save_addGraph(PyObject *, PyObject *) static char doc_save_save[] = "save.save(): Save all graphs to a file."; static PyObject *graceTMPL_save_save(graceTMPL_saveObject* self, PyObject *name){ char *filename; if(!PyArg_ParseTuple(name, "s:save.save(filename)", &filename)){ PyErr_SetString(PyExc_TypeError, "graceTMPL.save.save(string) expected as argument."); return NULL; } self->save->setOutputName(filename); self->save->save(); return Py_None; } static char doc_save_info[] = "save.info(): Quey information about datasets the template requests."; static PyObject *graceTMPL_save_info(graceTMPL_saveObject* self, PyObject *args){ if(!PyArg_ParseTuple(args, ":save.info()")){ PyErr_SetString(PyExc_TypeError, "graceTMPL.save.save(): no argument expected."); return NULL; } GraceTMPL::String2Vec templateInfo = self->save->templateDataRequestInfo(); PyObject *infoList; PyObject *subList; infoList = PyList_New(0); GraceTMPL::String2Vec::iterator subVec; GraceTMPL::StringVec::iterator entry; for(subVec = templateInfo.begin(); subVec != templateInfo.end(); ++subVec){ subList = PyList_New(0); for(entry = subVec->begin(); entry != subVec->end(); ++entry) PyList_Append(subList, PyString_FromStringAndSize(entry->c_str(), entry->size())); PyList_Append(infoList, subList); } return (PyObject*)infoList; } static PyMethodDef graceTMPL_saveMethods[] = { {"save", (PyCFunction)graceTMPL_save_save, METH_VARARGS, doc_save_save}, {"loadTemplate", (PyCFunction)graceTMPL_save_loadTemplate, METH_VARARGS, doc_save_loadTemplate}, {"setEnv", (PyCFunction)graceTMPL_save_setEnv, METH_VARARGS, doc_save_setEnv}, {"addGraph", (PyCFunction)graceTMPL_save_addGraph, METH_VARARGS, doc_save_addGraph}, {"info", (PyCFunction)graceTMPL_save_info, METH_VARARGS, doc_save_info}, {NULL, NULL} }; // PyMethodDef graceTMPL_saveMethods[] /******************* type member functions *******************/ static void graceTMPL_saveDealloc(graceTMPL_saveObject *self) { std::multiset::iterator graph; for(graph = self->graphSet->begin(); graph != self->graphSet->end(); ++graph) Py_DECREF(*graph); delete self->save; delete self->graphSet; PyObject_Del(self); } // graceTMPL_saveDealloc(graceTMPL_saveObject *) static PyObject *graceTMPL_saveGetattr(graceTMPL_saveObject *self, char *name) { return Py_FindMethod(graceTMPL_saveMethods, (PyObject *)self, name); } // graceTMPL_saveGetattr(graceTMPL_saveObject *, char *) static int graceTMPL_saveSetattr(graceTMPL_saveObject *self, char *name, PyObject *op) { if(strcmp(name, "outputName") == 0){ if (!PyString_Check(op)) return -1; self->save->setOutputName(PyString_AsString(op)); return 0; } PyErr_SetString(PyExc_AttributeError, "Attribute does not exist or cannot be set"); return -1; } // graceTMPL_saveSetattr(graceTMPL_saveObject *, char *, PyObject *) /********************************************************/ /******************* module functions *******************/ /********************************************************/ static char doc_save[] = "save() will return a new save object."; static PyObject* graceTMPL_save(PyObject* self, PyObject* args) { graceTMPL_saveObject* saveObject; GraceTMPL::Save *save; std::multiset *graphSet; if (!PyArg_ParseTuple(args,":save")){ PyErr_SetString(PyExc_TypeError, "graceTMPL.save() no arguments expected."); return NULL; } save = new GraceTMPL::Save; graphSet = new std::multiset; saveObject = PyObject_New(graceTMPL_saveObject, &graceTMPL_saveType); saveObject->save = save; saveObject->graphSet = graphSet; return (PyObject*)saveObject; } // graceTMPL_save(PyObject *, PyObject *) static PyMethodDef graceTMPL_Methods[] = { {"save", graceTMPL_save, METH_VARARGS | METH_KEYWORDS, doc_save}, {NULL, NULL} }; // PyMethodDef graceTMPL_Methods[] #ifdef __cplusplus extern "C" { #endif DL_EXPORT(void) initgraceTMPL(void) { graceTMPL_dataType.ob_type = &PyType_Type; graceTMPL_graphType.ob_type = &PyType_Type; graceTMPL_saveType.ob_type = &PyType_Type; Py_InitModule("graceTMPL", graceTMPL_Methods); import_libnumarray(); } // initgraceTMPL(void) #ifdef __cplusplus } #endif