/* * author: Achim Gaedke * created: January 2001 * file: pygsl/src/histogrammodule.c * $Id: histogrammodule.c,v 1.1 2005/05/19 12:04:44 schnizer Exp $ * * * May 2005 * Pierre Schnizer * maintainance: replaced direct python error calls with pygsl calls * added CAST and GET macros to reduce code duplication * * Now the warnings are all handled by a separate function. */ #include #include #include #include #include #include enum hist_error{ NOHIST = 0, NOHIST2D, ARGNOHIST, ARGNOHIST2D, HISTP_NULL }; static const char * filename = __FILE__; static PyObject * module = NULL; #include "histogram_doc.ic" static int PyGSL_hist_error_helper(const char * function, int line, int myerrno, enum hist_error errtype) { char *tmp; switch (errtype){ case NOHIST: tmp = "Object was not a histogramm"; break; case NOHIST2D: tmp = "Object was not a 2D histogramm"; break; case ARGNOHIST: tmp = "Argument was not a histogramm"; break; case ARGNOHIST2D: tmp = "Argument was not a 2D histogramm"; break; case HISTP_NULL: tmp = "Pointer to GSL histogramm(2d) object was NULL!"; break; default: tmp = "Unknown case in function hist_error_helper"; myerrno = GSL_ESANITY; break; } PyGSL_add_traceback(module, filename, function, line); gsl_error(tmp, filename, line, myerrno); return myerrno; } /* * Check if the recieved object is of approbriate type and that the histogram is defined. * Invokes PyGSL_hist_error_helper if it fails. * returns GSL_SUCCESS on success * * ob ... the object to check * type ... the Python type object * errcode ... the errorcode used to describe the failure type for * PyGSL_hist_error_helper */ #define _PyGSL_HIST_CHECK_INT(ob, type, errcode) \ ((ob->ob_type == &(type)) ? GSL_SUCCESS : \ PyGSL_hist_error_helper(__FUNCTION__, __LINE__, (errcode), GSL_ESANITY)) /* * returns the gsl histogram from the object */ #define _PyGSL_HIST_CAST(ob, type) (( ((type *)(ob)) ->h )) /* * Check if it the gsl_histogram is not NULL. Will give a descriptive error * message if it fails. */ #define _PyGSL_HIST_CAST_SAVE(ob, type) \ (\ (_PyGSL_HIST_CAST((ob), type) == NULL ) \ ? \ (PyGSL_hist_error_helper(__FUNCTION__, __LINE__, GSL_EFAULT, HISTP_NULL), NULL) \ : \ ( _PyGSL_HIST_CAST((ob), type) ) \ ) /* * Try to get the gsl_histogram from the python object. * Checks for errors ... */ #define _PyGSL_HIST_GET_INT(ob, type, cast, errcode) \ ( \ ( _PyGSL_HIST_CHECK_INT((ob), type, (errcode)) == GSL_SUCCESS ) \ ? \ _PyGSL_HIST_CAST_SAVE((ob), cast) \ : \ NULL \ ) #define _PyGSL_HIST_GET(ob, type, errcode) _PyGSL_HIST_GET_INT(ob, type ## Type, type ## Object, errcode) #define _PyGSL_HIST_CHECK(ob, errcode) _PyGSL_HIST_CHECK_INT((ob), (histogram_histogramType), (errcode)) #define _PyGSL_HIST2D_CHECK(ob, errcode) _PyGSL_HIST_CHECK_INT((ob), (histogram_histogram2dType), (errcode)) #define PyGSL_HIST_CHECK(ob) _PyGSL_HIST_CHECK((ob), (NOHIST)) #define PyGSL_HIST2D_CHECK(ob) _PyGSL_HIST2D_CHECK((ob), (NOHIST2D)) #define PyGSL_HIST_ARG_CHECK(ob) _PyGSL_HIST_CHECK((ob), (ARGNOHIST)) #define PyGSL_HIST2D_ARG_CHECK(ob) _PyGSL_HIST2D_CHECK((ob), (ARGNOHIST2D)) #define PyGSL_HIST_CAST(ob) _PyGSL_HIST_CAST((ob), histogram_histogramObject) #define PyGSL_HIST2D_CAST(ob) _PyGSL_HIST_CAST((ob), histogram_histogram2dObject) #define PyGSL_HIST_GET(ob) _PyGSL_HIST_GET((ob), histogram_histogram, (NOHIST)) #define PyGSL_HIST2D_GET(ob) _PyGSL_HIST_GET((ob), histogram_histogram2d, (NOHIST2D)) #define _PyGSL_HIST_GET_ARG(ob) _PyGSL_HIST_GET((ob), histogram_histogram, (ARGNOHIST)) #define _PyGSL_HIST2D_GET_ARG(ob) _PyGSL_HIST_GET((ob), histogram_histogram2d, (ARGNOHIST2D)) #define PyGSL_HIST_GET_ARG(ob) ( ((ob) == NULL) ? NULL : _PyGSL_HIST_GET_ARG((ob)) ) #define PyGSL_HIST2D_GET_ARG(ob) ( ((ob) == NULL) ? NULL : _PyGSL_HIST2D_GET_ARG((ob)) ) /* * Helper function for dealing with warning and errors ... */ static int PyGSL_warn_err(int rcode, int errcode, const char * errdes, const char * file, int line) { int warn_result; if (errcode==rcode) { warn_result = PyGSL_warning(errdes, file, line, errcode); if (warn_result==-1) /* exception is raised by PyErr_Warn */ return GSL_EFAILED; } else if (PyGSL_ERROR_FLAG(rcode) != GSL_SUCCESS) return rcode; return GSL_SUCCESS; } #define PyGSL_WARN_ERR(ob, errcode, errdes) \ (\ ((ob) == (GSL_SUCCESS)) \ ? \ GSL_SUCCESS \ : \ ((ob) == (errcode)) \ ? PyGSL_warn_err(ob, errcode, errdes, filename, __LINE__) \ : PyGSL_error_flag((ob)) \ ) static const char edom_message[] = "value out of histogram range"; #define PyGSL_HIST_EDOM_WARN(ob) PyGSL_WARN_ERR((ob), GSL_EDOM, edom_message) typedef int (*hist_op)(void *, const void *); typedef int (*hist_file)(FILE *, void *); static PyObject * histogram_histogram_op(PyObject *self, PyObject * arg, hist_op fptr); static PyObject * histogram_histogram2d_op(PyObject *self, PyObject * arg, hist_op fptr); static PyObject * histogram_histogram_file(PyObject *self, PyObject * arg, hist_file fptr); static PyObject * histogram_histogram2d_file(PyObject *self, PyObject * arg, hist_file fptr); /* * * histogram type * for 1d histogram data * */ /* my typedef */ staticforward PyTypeObject histogram_histogramType; staticforward PyMethodDef histogram_histogram_methods[]; typedef struct { PyObject_HEAD gsl_histogram* h; } histogram_histogramObject; #define _CONCAT2(class, suffix) class ## _ ## suffix #include "histogram.ic" #define HISTTYPE gsl_histogram #define PyGSLHISTTYPE histogram_histogramType #define PyGSL_HIST_TYPE_GET(ob) PyGSL_HIST_GET((ob)) #define PyGSL_HIST_TYPE_CAST(ob) PyGSL_HIST_CAST((ob)) #define PyGSL_HIST_TYPE_ARG_GET(ob) PyGSL_HIST_GET_ARG((ob)) #define GSLNAME(suffix) _CONCAT2(gsl_histogram, suffix) #define FUNCNAME(suffix) _CONCAT2(histogram_histogram, suffix) #ifdef HISTOGRAM2D #undef HISTOGRAM2D #endif #include "histogram_common.ic" #undef HISTTYPE #undef PyGSLHISTTYPE #undef PyGSL_HIST_TYPE_GET #undef PyGSL_HIST_TYPE_CAST #undef PyGSL_HIST_TYPE_ARG_GET #undef FUNCNAME #undef GSLNAME static PyTypeObject histogram_histogramType = { PyObject_HEAD_INIT(NULL) 0, "pygsl.histogram.histogram", sizeof(histogram_histogramObject), 0, (destructor)histogram_histogram_dealloc, /* tp_dealloc */ 0, /* tp_print */ histogram_histogram_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ &histogram_histogram_as_mapping, /* 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, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)histogram_histogram_init, /* tp_init */ NULL, /* tp_alloc */ NULL, /* tp_new */ NULL /* tp_free */ }; /* * * here begins the section for the 2d histogram * */ /* my typedef */ staticforward PyTypeObject histogram_histogram2dType; staticforward PyMethodDef histogram_histogram2d_methods[]; typedef struct { PyObject_HEAD gsl_histogram2d* h; } histogram_histogram2dObject; static PyObject * histogram_histogram2d_reset(PyObject *); #include "histogram2d.ic" #define HISTOGRAM2D 1 #define HISTTYPE gsl_histogram2d #define PyGSLHISTTYPE histogram_histogram2dType #define PyGSL_HIST_TYPE_GET(ob) PyGSL_HIST2D_GET((ob)) #define PyGSL_HIST_TYPE_ARG_GET(ob) PyGSL_HIST2D_GET_ARG((ob)) #define PyGSL_HIST_TYPE_CAST(ob) PyGSL_HIST2D_CAST((ob)) #define GSLNAME(suffix) _CONCAT2(gsl_histogram2d, suffix) #define FUNCNAME(suffix) _CONCAT2(histogram_histogram2d, suffix) #include "histogram_common.ic" static PyTypeObject histogram_histogram2dType = { PyObject_HEAD_INIT(NULL) 0, "pygsl.histogram.histogram2d", sizeof(histogram_histogram2dObject), 0, (destructor)histogram_histogram2d_dealloc, /* tp_dealloc */ 0, /* tp_print */ histogram_histogram2d_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ &histogram_histogram2d_as_mapping, /* 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, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)histogram_histogram2d_init, /* tp_init */ NULL, /* tp_alloc */ NULL, /* tp_new */ NULL /* tp_free */ }; /* * * module specific stuff * */ static PyMethodDef histogramMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; void inithistogram(void) { PyObject* m; m=Py_InitModule("histogram", histogramMethods); import_array(); init_pygsl(); /* init histogram type */ histogram_histogramType.ob_type = &PyType_Type; histogram_histogramType.tp_alloc = PyType_GenericAlloc; histogram_histogramType.tp_new = PyType_GenericNew; histogram_histogramType.tp_free = _PyObject_Del; /* install histogram type */ /* important! must increment histogram type reference counter */ Py_INCREF((PyObject*)&histogram_histogramType); PyModule_AddObject(m,"histogram", (PyObject*)&histogram_histogramType); /* init histogram type */ histogram_histogram2dType.ob_type = &PyType_Type; histogram_histogram2dType.tp_alloc = PyType_GenericAlloc; histogram_histogram2dType.tp_new = PyType_GenericNew; histogram_histogram2dType.tp_free = _PyObject_Del; /* install histogram type */ /* important! must increment histogram type reference counter */ Py_INCREF((PyObject*)&histogram_histogram2dType); PyModule_AddObject(m,"histogram2d", (PyObject*)&histogram_histogram2dType); }