/* -*- C -*- */ static PyObject* histogram_histogram_alloc(PyObject *self, PyObject *args) { gsl_histogram* histogram; long int n; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; /* get size */ if (0==PyArg_ParseTuple(args,"l",&n)) return NULL; if (n<=0) { gsl_error ("histogram length n must be positive integer", filename, __LINE__, GSL_EDOM ); return NULL; } /* free existing histogram */ if(histogram) gsl_histogram_free(histogram); histogram=gsl_histogram_alloc(n); /* if this fails, the pointer should be NULL, although this object is useless now */ PyGSL_HIST_CAST(self) = histogram; if (histogram==NULL){ PyErr_NoMemory(); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject* histogram_histogram_set_ranges_uniform(PyObject *self, PyObject *args) { gsl_histogram * histogram; double xmin; double xmax; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; if (0==PyArg_ParseTuple(args,"dd",&xmin,&xmax)) { return NULL; } DEBUG_MESS(4, "xmin = %f, xmax = %f", xmin, xmax); if (PyGSL_ERROR_FLAG(gsl_histogram_set_ranges_uniform(histogram,xmin,xmax)) != GSL_SUCCESS) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject* histogram_histogram_increment(PyObject *self, PyObject *args) { gsl_histogram * histogram; PyObject *x_o; PyArrayObject *a=NULL; int result, i; double x; FUNC_MESS_BEGIN(); if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; if (0==PyArg_ParseTuple(args,"O",&x_o)) { return NULL; } if((a = PyGSL_vector_or_double(x_o, PyGSL_CONTIGUOUS | PyGSL_INPUT_ARRAY, -1, 1, NULL)) == NULL) goto fail; for(i = 0; i dimensions[0]; ++i){ x = *((double *) (a->data + a->strides[0] * i)); DEBUG_MESS(3, "x[%d] = %e", i, x); result=gsl_histogram_increment(histogram, x); if(PyGSL_HIST_EDOM_WARN(result) != GSL_SUCCESS) goto fail; } Py_DECREF(a); Py_INCREF(Py_None); FUNC_MESS_END(); return Py_None; fail: Py_XDECREF(a); return NULL; } static PyObject* histogram_histogram_accumulate(PyObject *self, PyObject *args) { gsl_histogram * histogram; PyObject *x_o, *w_o; PyArrayObject *x_a=NULL,*w_a=NULL; int result, dimension, i; double x,w; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; if (0==PyArg_ParseTuple(args,"OO",&x_o,&w_o)) { return NULL; } if((x_a= PyGSL_vector_or_double(x_o, PyGSL_CONTIGUOUS | PyGSL_INPUT_ARRAY, -1, 1, NULL)) == NULL) goto fail; dimension = x_a->dimensions[0]; if((w_a= PyGSL_vector_or_double(w_o, PyGSL_CONTIGUOUS | PyGSL_INPUT_ARRAY, -1, dimension, NULL)) == NULL) goto fail; for(i = 0; i data + x_a->strides[0] * i)); w = *((double *) (w_a->data + w_a->strides[0] * i)); result=gsl_histogram_accumulate(histogram,x,w); if(PyGSL_HIST_EDOM_WARN(result) != GSL_SUCCESS) goto fail; } Py_DECREF(x_a); Py_DECREF(w_a); Py_INCREF(Py_None); return Py_None; fail: Py_XDECREF(x_a); Py_XDECREF(w_a); return NULL; } #define PyGSL_TYPE_FROM_HIST(funcname, conversion) \ static PyObject* histogram_histogram_ ## funcname (PyObject *self) \ { \ void* histogram; \ if((histogram = (void *)PyGSL_HIST_GET(self)) == NULL) \ return NULL; \ return conversion(gsl_histogram_ ## funcname(histogram)); \ } #define PyGSL_FLOAT_FROM_HIST(funcname) PyGSL_TYPE_FROM_HIST(funcname, PyFloat_FromDouble) #define PyGSL_LONG_FROM_HIST(funcname) PyGSL_TYPE_FROM_HIST(funcname, PyLong_FromLong) #define PyGSL_ULONG_FROM_HIST(funcname) PyGSL_TYPE_FROM_HIST(funcname, PyLong_FromUnsignedLong) PyGSL_FLOAT_FROM_HIST(max) PyGSL_FLOAT_FROM_HIST(min) PyGSL_LONG_FROM_HIST(bins) PyGSL_FLOAT_FROM_HIST(max_val) PyGSL_FLOAT_FROM_HIST(min_val) PyGSL_ULONG_FROM_HIST(max_bin) PyGSL_ULONG_FROM_HIST(min_bin) PyGSL_FLOAT_FROM_HIST(mean) PyGSL_FLOAT_FROM_HIST(sigma) PyGSL_FLOAT_FROM_HIST(sum) static PyObject* histogram_histogram_get(PyObject *self, PyObject *args) { gsl_histogram* histogram; long int n; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; /* get index */ if (0==PyArg_ParseTuple(args,"l",&n)) return NULL; if (n<0 || n>=histogram->n) { GSL_ERROR_NULL("index lies outside valid range of 0 .. n - 1", GSL_EDOM); return NULL; } return PyFloat_FromDouble(gsl_histogram_get(histogram,n)); } static PyObject* histogram_histogram_get_range(PyObject *self, PyObject *args) { gsl_histogram* histogram; long int n; double lower; double upper; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; /* get index */ if (0==PyArg_ParseTuple(args,"l",&n)) return NULL; if (n<0 || n>=histogram->n) { gsl_error ("index lies outside valid range of 0 .. n - 1", filename, __LINE__, GSL_EDOM ); return NULL; } if (PyGSL_ERROR_FLAG(gsl_histogram_get_range(histogram,n,&lower,&upper)) != GSL_SUCCESS) return NULL; return Py_BuildValue("(dd)",lower,upper); } static PyObject* histogram_histogram_find(PyObject *self, PyObject *args) { gsl_histogram* histogram; double value; size_t index; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; /* get index */ if (0==PyArg_ParseTuple(args,"d",&value)) return NULL; if (PyGSL_ERROR_FLAG(gsl_histogram_find(histogram, value, &index)) != GSL_SUCCESS) return NULL; return PyLong_FromUnsignedLong(index); } static PyObject* histogram_histogram_set_ranges(PyObject *self, PyObject *ranges) { PyObject *tmp; PyArrayObject *a_ranges=NULL; gsl_histogram * histogram; int gsl_result; FUNC_MESS_BEGIN(); /* get gsl_histogram struct */ if((histogram = PyGSL_HIST_GET(self)) == NULL) goto fail; if(0==PyArg_ParseTuple(ranges, "O", &tmp)) return NULL; a_ranges = PyGSL_PyArray_prepare_gsl_vector_view(tmp, PyArray_DOUBLE, PyGSL_INPUT_ARRAY| PyGSL_CONTIGUOUS, -1, 1, NULL); if(a_ranges == NULL) goto fail; /* set ranges to gsl_histogram structure */ gsl_result=gsl_histogram_set_ranges(histogram, (double *)a_ranges->data, a_ranges->dimensions[0]); Py_DECREF(a_ranges); a_ranges = NULL; if (PyGSL_ERROR_FLAG(gsl_result) != GSL_SUCCESS) goto fail; Py_INCREF(Py_None); FUNC_MESS_END(); return Py_None; fail: Py_XDECREF(a_ranges); PyGSL_add_traceback(module, __FILE__, __FUNCTION__, __LINE__); return NULL; } static PyObject* histogram_histogram_plot_data(PyObject *self, PyObject *args) { gsl_histogram *histogram; PyArrayObject *x_a = NULL, *y_a = NULL; int n, i, dim[2]; double *data; FUNC_MESS_BEGIN(); if((histogram = PyGSL_HIST_GET(self)) == NULL) goto fail; n = gsl_histogram_bins(histogram); DEBUG_MESS(3, "n = %d", n); assert(n>0); dim[0] = n; dim[1] = 2; x_a = PyGSL_New_Array(2, dim, PyArray_DOUBLE); DEBUG_MESS(3, "x_a = %p", (void *) x_a); y_a = PyGSL_New_Array(1, &n, PyArray_DOUBLE); DEBUG_MESS(3, "y_a = %p", (void *) y_a); if(x_a == NULL || y_a == NULL) goto fail; data = (double *) x_a->data; for(i = 0; i < n; ++i){ gsl_histogram_get_range(histogram, i, &data[2*i], &data[2*i+1]); ((double *) (y_a->data))[i] = gsl_histogram_get(histogram, i); } FUNC_MESS_END(); return Py_BuildValue("(OO)", x_a, y_a); fail: Py_XDECREF(x_a); Py_XDECREF(y_a); PyGSL_add_traceback(module, __FILE__, __FUNCTION__, __LINE__); return NULL; } #define HIST_OP(op_name) \ static PyObject * \ histogram_histogram_ ## op_name (PyObject *self, PyObject * arg) \ { \ return histogram_histogram_op(self, arg, (hist_op) gsl_histogram_ ## op_name); \ } HIST_OP(add) HIST_OP(sub) HIST_OP(mul) HIST_OP(div) HIST_OP(memcpy) #define HIST_FILE(op_name) \ static PyObject * \ histogram_histogram_ ## op_name (PyObject *self, PyObject * arg) \ { \ return histogram_histogram_file(self, arg, (hist_file) gsl_histogram_ ## op_name); \ } HIST_FILE(fread) HIST_FILE(fwrite) HIST_FILE(fscanf) /* method table */ #if 0 static PyMethodDef histogram_histogram_methods[] = { {"alloc",(PyCFunction)histogram_histogram_alloc,METH_VARARGS,"allocate necessary space"}, {"set_ranges_uniform", (PyCFunction)histogram_histogram_set_ranges_uniform, METH_VARARGS,"set the ranges to uniform distance"}, {"reset",(PyCFunction)histogram_histogram_reset,METH_NOARGS,"sets all bin values to 0"}, {"increment",(PyCFunction)histogram_histogram_increment,METH_VARARGS,"increments corresponding bin"}, {"accumulate",(PyCFunction)histogram_histogram_accumulate,METH_VARARGS,"adds the weight to corresponding bin"}, {"max",(PyCFunction)histogram_histogram_max,METH_NOARGS,"returns upper range"}, {"min",(PyCFunction)histogram_histogram_min,METH_NOARGS,"returns lower range"}, {"bins",(PyCFunction)histogram_histogram_bins,METH_NOARGS,"returns number of bins"}, {"get",(PyCFunction)histogram_histogram_get,METH_VARARGS,"gets value of indexed bin"}, {"get_range",(PyCFunction)histogram_histogram_get_range,METH_VARARGS,"gets upper and lower range of indexed bin"}, {"find",(PyCFunction)histogram_histogram_find,METH_VARARGS,"finds index of corresponding bin"}, {"max_val",(PyCFunction)histogram_histogram_max_val,METH_NOARGS,"returns maximal bin value"}, {"max_bin",(PyCFunction)histogram_histogram_max_bin,METH_NOARGS,"returns bin index with maximal value"}, {"min_val",(PyCFunction)histogram_histogram_min_val,METH_NOARGS,"returns minimal bin value"}, {"min_bin",(PyCFunction)histogram_histogram_min_bin,METH_NOARGS,"returns bin index with minimal value"}, {"mean",(PyCFunction)histogram_histogram_mean,METH_NOARGS,"returns mean of histogram"}, {"sigma",(PyCFunction)histogram_histogram_sigma,METH_NOARGS,"returns std deviation of histogram"}, {"sum",(PyCFunction)histogram_histogram_sum,METH_NOARGS,"returns sum of bin values"}, {"set_ranges",(PyCFunction)histogram_histogram_set_ranges,METH_O,"sets range according given sequence"}, {"shift",(PyCFunction)histogram_histogram_shift,METH_O,"shifts the contents of the bins by the given offset"}, {"scale",(PyCFunction)histogram_histogram_scale,METH_O,"multiplies the contents of the bins by the given scale"}, {"equal_bins_p",(PyCFunction)histogram_histogram_equal_bins_p,METH_O,"true if the all of the individual bin ranges are identical"}, {"add",(PyCFunction)histogram_histogram_add,METH_O,"adds the contents of the bins"}, {"sub",(PyCFunction)histogram_histogram_sub,METH_O,"substracts the contents of the bins"}, {"mul",(PyCFunction)histogram_histogram_mul,METH_O,"multiplicates the contents of the bins"}, {"div",(PyCFunction)histogram_histogram_div,METH_O,"divides the contents of the bins"}, {"clone",(PyCFunction)histogram_histogram_clone,METH_NOARGS,"returns a new copy of this histogram"}, {"copy",(PyCFunction)histogram_histogram_memcpy,METH_O,"copies the given histogram to myself"}, {"read",(PyCFunction)histogram_histogram_fread,METH_O,"reads histogram binary data from file"}, {"write",(PyCFunction)histogram_histogram_fwrite,METH_O,"writes histogram binary data to file"}, {"scanf",(PyCFunction)histogram_histogram_fscanf,METH_O,"reads histogram data from file using scanf"}, {"printf",(PyCFunction)histogram_histogram_printf,METH_VARARGS,"writes histogram data to file using printf"}, {NULL, NULL, 0, NULL} /* sentinel */ }; #endif /* methods for map protocol */ static int histogram_histogram_mp_length(PyObject *self) { gsl_histogram* histogram; if((histogram = PyGSL_HIST_GET(self)) == NULL) return -1; return gsl_histogram_bins(histogram); } static PyObject* histogram_histogram_mp_subscript(PyObject *self, PyObject *key) { gsl_histogram* histogram; long int k; PyObject* my_key; if((histogram = PyGSL_HIST_GET(self)) == NULL) return NULL; /* get key */ my_key=PyNumber_Long(key); if (my_key==NULL) return NULL; k=PyInt_AsLong(my_key); if (k<0 || k>=histogram->n) { gsl_error ("index lies outside valid range of 0 .. n - 1", filename, __LINE__, GSL_EDOM ); return NULL; } Py_DECREF(my_key); return PyFloat_FromDouble(gsl_histogram_get(histogram,k)); } static int histogram_histogram_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { gsl_histogram* histogram; PyObject* my_key; PyObject* my_value; double v; size_t k; /* get histogram struct */ if((histogram = PyGSL_HIST_GET(self)) == NULL) return -1; /* get key */ my_key=PyNumber_Long(key); if (my_key==NULL) return -1; k=PyInt_AsLong(my_key); if (k<0 || k>=histogram->n) { gsl_error ("index lies outside valid range of 0 .. n - 1", filename, __LINE__, GSL_EDOM); return -1; } Py_DECREF(my_key); /* get value */ if (value == NULL) v=0; else { my_value=PyNumber_Float(value); if (my_value==NULL) return -1; v=PyFloat_AsDouble(value); Py_DECREF(my_value); } histogram->bin[k]=v; return 0; } /* typedef struct { inquiry mp_length; binaryfunc mp_subscript; objobjargproc mp_ass_subscript; } PyMappingMethods; */ static PyMappingMethods histogram_histogram_as_mapping = { (inquiry)histogram_histogram_mp_length, /* inquiry mp_length */ (binaryfunc)histogram_histogram_mp_subscript, /* binaryfunc mp_subscript */ (objobjargproc)histogram_histogram_mp_ass_subscript/* objobjargproc mp_ass_subscript */ }; /* initialisation and finalisation functions */ static int histogram_histogram_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject* orig_histogram; long int n; static char *kwlist1[] = {"histogram",NULL}; static char *kwlist2[] = {"bins",NULL}; /* initialise histogram pointer */ PyGSL_HIST_CAST(self) = NULL; /* test two call alternatives: */ if (PyArg_ParseTupleAndKeywords(args, kwds,"O!",kwlist1,&histogram_histogramType,&orig_histogram)) { gsl_histogram* histogram, *histogram2; if((histogram2=PyGSL_HIST_GET(orig_histogram)) == NULL) return -1; histogram=gsl_histogram_clone(histogram2); if (histogram==NULL) return -1; PyGSL_HIST_CAST(self)=histogram; return 0; } else { /* reset exception */ PyErr_Clear(); } if (PyArg_ParseTupleAndKeywords(args, kwds,"l",kwlist2,&n)) { gsl_histogram* histogram; if (n<=0) { gsl_error ("histogram length n must be positive", filename, __LINE__, GSL_EDOM); return -1; } histogram=gsl_histogram_alloc(n); if (histogram==NULL) return -1; gsl_histogram_reset(histogram); PyGSL_HIST_CAST(self)=histogram; return 0; } else { /* set own error message */ PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "histogram.init requires pygsl.histogram.histogram object or long int argument"); return -1; } }