/* -*- C -*- */ static PyObject* histogram_histogram2d_alloc(PyObject *self, PyObject *args) { gsl_histogram2d* histogram; long int m; long int n; if((histogram = PyGSL_HIST2D_GET(self)) == NULL) return NULL; /* get size */ if (0==PyArg_ParseTuple(args,"ll",&m,&n)) return NULL; if (n<=0) { gsl_error ("histogram length n must be a positive integer", filename, __LINE__, GSL_EDOM ); return NULL; } if (m<=0) { gsl_error ("histogram length m must be a positive integer", filename, __LINE__, GSL_EDOM ); return NULL; } /* free existing histogram */ gsl_histogram2d_free(histogram); PyGSL_HIST2D_CAST(self) = NULL; histogram=gsl_histogram2d_alloc(m,n); /* if this fails, the pointer should be NULL, although this object is useless now */ if (histogram==NULL){ GSL_ERROR_NULL("Could not allocate 2d Histogram", GSL_ENOMEM); return NULL; } PyGSL_HIST2D_CAST(self) = histogram; Py_INCREF(Py_None); return Py_None; } static PyObject* histogram_histogram2d_set_ranges_uniform(PyObject *self, PyObject *args) { gsl_histogram2d * histogram; double xmin; double xmax; double ymin; double ymax; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } if (0==PyArg_ParseTuple(args,"dddd",&xmin,&xmax,&ymin,&ymax)) { return NULL; } if (PyGSL_ERROR_FLAG(gsl_histogram2d_set_ranges_uniform(histogram,xmin,xmax,ymin,ymax)) != GSL_SUCCESS) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject* histogram_histogram2d_increment(PyObject *self, PyObject *args) { gsl_histogram2d * histogram; int result; double x; double y; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } if (0==PyArg_ParseTuple(args,"dd",&x,&y)) { return NULL; } result=gsl_histogram2d_increment(histogram,x,y); if(PyGSL_HIST_EDOM_WARN(result) != GSL_SUCCESS) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject* histogram_histogram2d_accumulate(PyObject *self, PyObject *args) { gsl_histogram2d * histogram; int result; double x; double y; double weight; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } if (0==PyArg_ParseTuple(args,"ddd",&x,&y,&weight)) { return NULL; } result=gsl_histogram2d_accumulate(histogram,x,y,weight); if(PyGSL_HIST_EDOM_WARN(result) != GSL_SUCCESS) return NULL; Py_INCREF(Py_None); return Py_None; } #define PyGSL_TYPE_FROM_HIST2D(funcname, conversion) \ static PyObject* histogram_histogram2d_ ## funcname (PyObject *self) \ { \ void* histogram; \ if((histogram = (void *)PyGSL_HIST2D_GET(self)) == NULL) \ return NULL; \ return conversion(gsl_histogram2d_ ## funcname(histogram)); \ } #define PyGSL_FLOAT_FROM_HIST2D(funcname) PyGSL_TYPE_FROM_HIST2D(funcname, PyFloat_FromDouble) #define PyGSL_LONG_FROM_HIST2D(funcname) PyGSL_TYPE_FROM_HIST2D(funcname, PyLong_FromLong) #define PyGSL_ULONG_FROM_HIST2D(funcname) PyGSL_TYPE_FROM_HIST2D(funcname, PyLong_FromUnsignedLong) PyGSL_FLOAT_FROM_HIST2D(xmax) PyGSL_FLOAT_FROM_HIST2D(ymax) PyGSL_FLOAT_FROM_HIST2D(xmin) PyGSL_FLOAT_FROM_HIST2D(ymin) PyGSL_LONG_FROM_HIST2D(nx) PyGSL_LONG_FROM_HIST2D(ny) PyGSL_FLOAT_FROM_HIST2D(max_val) PyGSL_FLOAT_FROM_HIST2D(min_val) PyGSL_FLOAT_FROM_HIST2D(xmean) PyGSL_FLOAT_FROM_HIST2D(xsigma) PyGSL_FLOAT_FROM_HIST2D(ymean) PyGSL_FLOAT_FROM_HIST2D(ysigma) PyGSL_FLOAT_FROM_HIST2D(sum) PyGSL_FLOAT_FROM_HIST2D(cov) static PyObject* histogram_histogram2d_max_bin(PyObject *self) { gsl_histogram2d * histogram; size_t i; size_t j; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } gsl_histogram2d_max_bin(histogram, &i, &j); return Py_BuildValue("(ll)", (long)i, (long)j); } static PyObject* histogram_histogram2d_min_bin(PyObject *self) { gsl_histogram2d * histogram; size_t i; size_t j; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } gsl_histogram2d_max_bin(histogram, &i, &j); return Py_BuildValue("(ll)", (long)i, (long)j); } static PyObject* histogram_histogram2d_get(PyObject *self, PyObject *args) { gsl_histogram2d* histogram; long int i; long int j; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } /* get index */ if (0==PyArg_ParseTuple(args,"ll",&i,&j)) return NULL; if (i<0 || i>=histogram->nx) { gsl_error ("index i lies outside valid range of 0 .. nx - 1", filename, __LINE__, GSL_EDOM); return NULL; } if (j<0 || j>=histogram->ny) { gsl_error ("index j lies outside valid range of 0 .. ny - 1", filename, __LINE__, GSL_EDOM); return NULL; } return PyFloat_FromDouble(gsl_histogram2d_get(histogram,i,j)); } static PyObject* histogram_histogram2d_get_xrange(PyObject *self, PyObject *args) { gsl_histogram2d* histogram; long int i; double lower; double upper; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } /* get index */ if (0==PyArg_ParseTuple(args,"l",&i)) return NULL; if (i<0 || i>=histogram->nx) { gsl_error ("index i lies outside valid range of 0 .. nx - 1", filename, __LINE__, GSL_EDOM); return NULL; } if (GSL_SUCCESS!=gsl_histogram2d_get_xrange(histogram,i,&lower,&upper)) return NULL; return Py_BuildValue("(dd)",lower,upper); } static PyObject* histogram_histogram2d_get_yrange(PyObject *self, PyObject *args) { gsl_histogram2d* histogram; long int j; double lower; double upper; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } /* get index */ if (0==PyArg_ParseTuple(args,"l",&j)) return NULL; if (j<0 || j>=histogram->ny) { gsl_error ("index j lies outside valid range of 0 .. ny - 1", filename, __LINE__, GSL_EDOM); return NULL; } if (PyGSL_ERROR_FLAG(gsl_histogram2d_get_yrange(histogram,j,&lower,&upper)) != GSL_SUCCESS) return NULL; return Py_BuildValue("(dd)",lower,upper); } static PyObject* histogram_histogram2d_find(PyObject *self, PyObject *args) { gsl_histogram2d* histogram; double xvalue; size_t xindex; double yvalue; size_t yindex; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } /* get index */ if (0==PyArg_ParseTuple(args,"dd",&xvalue,&yvalue)) return NULL; if (GSL_SUCCESS!=gsl_histogram2d_find(histogram, xvalue, yvalue, &xindex, &yindex)) return NULL; return Py_BuildValue("(ll)", xindex, yindex); } static PyObject* histogram_histogram2d_set_ranges(PyObject *self, PyObject *ranges) { gsl_histogram2d * histogram; PyObject* x_o; PyObject* y_o; PyArrayObject *xranges=NULL, *yranges=NULL; int gsl_result; FUNC_MESS_BEGIN(); if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } /* get two arguments */ if (0==PySequence_Check(ranges) || 2!=PySequence_Size(ranges)) { PyErr_SetString(PyExc_TypeError, "histogram2d.set_ranges needs two sequences"); goto fail; } x_o=PySequence_GetItem(ranges,0); y_o=PySequence_GetItem(ranges,1); if(x_o == NULL || y_o == NULL) goto fail; xranges = PyGSL_PyArray_prepare_gsl_vector_view(x_o, PyArray_DOUBLE, PyGSL_INPUT_ARRAY| PyGSL_CONTIGUOUS, -1, 1, NULL); yranges = PyGSL_PyArray_prepare_gsl_vector_view(y_o, PyArray_DOUBLE, PyGSL_INPUT_ARRAY| PyGSL_CONTIGUOUS, -1, 1, NULL); if(xranges == NULL) goto fail; if(yranges == NULL) goto fail; /* set ranges to gsl_histogram structure */ gsl_result=gsl_histogram2d_set_ranges(histogram, (double*)xranges->data,(size_t)xranges->dimensions[0], (double*)yranges->data,(size_t)yranges->dimensions[0]); Py_DECREF(xranges); Py_DECREF(yranges); xranges = NULL; yranges = NULL; if (GSL_SUCCESS!=PyGSL_ERROR_FLAG(gsl_result)) return NULL; Py_INCREF(Py_None); FUNC_MESS_END(); return Py_None; fail: PyGSL_add_traceback(module, __FILE__, __FUNCTION__, __LINE__); Py_XDECREF(xranges); Py_XDECREF(yranges); return NULL; } static PyObject* histogram_histogram2d_plot_data(PyObject *self, PyObject *args) { gsl_histogram2d *histogram; PyArrayObject *x_a = NULL, *y_a = NULL, *h_a = NULL; int nx, ny, i, j, dim[2], testsize, index; if((histogram = PyGSL_HIST2D_GET(self)) == NULL) goto fail; nx = gsl_histogram2d_nx(histogram); ny = gsl_histogram2d_ny(histogram); dim[0] = nx; dim[1] = 2; x_a = PyGSL_New_Array(2, dim, PyArray_DOUBLE); dim[0] = ny; dim[1] = 2; y_a = PyGSL_New_Array(2, dim, PyArray_DOUBLE); dim[1] = nx; h_a = PyGSL_New_Array(2, dim, PyArray_DOUBLE); if(x_a == NULL || y_a == NULL || h_a == NULL) goto fail; for(i = 0; i < nx; ++i){ gsl_histogram2d_get_xrange(histogram, i, ((double *) x_a->data) + 2*i, ((double *) x_a->data) + 2*i+1); } for(j = 0; j < ny; ++j){ gsl_histogram2d_get_xrange(histogram, j, ((double *) y_a->data) + 2*j, ((double *) y_a->data) + 2*j+1); } testsize = nx * ny; for(j = 0; j < ny; ++j){ for(i = 0; i < nx; ++i){ index = ny*j+i; if(index >= testsize){ gsl_error("h_a not big enough ?!?", __FILE__, __LINE__ - 1, GSL_ESANITY); goto fail; } ((double *) h_a->data)[index] = gsl_histogram2d_get(histogram, i, j); } } return Py_BuildValue("(OO)", x_a, y_a, h_a); fail: Py_XDECREF(x_a); Py_XDECREF(y_a); Py_XDECREF(h_a); PyGSL_add_traceback(module, __FILE__, __FUNCTION__, __LINE__); return NULL; } #define HIST2D_OP(op_name) \ static PyObject * \ histogram_histogram2d_ ## op_name (PyObject *self, PyObject * arg) \ { \ return histogram_histogram2d_op(self, arg, (hist_op) gsl_histogram2d_ ## op_name); \ } HIST2D_OP(add) HIST2D_OP(sub) HIST2D_OP(mul) HIST2D_OP(div) HIST2D_OP(memcpy) #define HIST2D_FILE(op_name) \ static PyObject * \ histogram_histogram2d_ ## op_name (PyObject *self, PyObject * arg) \ { \ return histogram_histogram2d_file(self, arg, (hist_file) gsl_histogram2d_ ## op_name); \ } HIST2D_FILE(fread) HIST2D_FILE(fwrite) HIST2D_FILE(fscanf) /* method index */ #if 0 static PyMethodDef histogram_histogram2d_methods[] = { {"alloc",(PyCFunction)histogram_histogram2d_alloc,METH_VARARGS,"allocate necessary space"}, {"set_ranges_uniform", (PyCFunction)histogram_histogram2d_set_ranges_uniform, METH_VARARGS,"set the ranges to uniform distance"}, {"reset",(PyCFunction)histogram_histogram2d_reset,METH_NOARGS,"sets all bin values to 0"}, {"increment",(PyCFunction)histogram_histogram2d_increment,METH_VARARGS,"increments corresponding bin"}, {"accumulate",(PyCFunction)histogram_histogram2d_accumulate,METH_VARARGS,"adds the weight to corresponding bin"}, {"xmax",(PyCFunction)histogram_histogram2d_xmax,METH_NOARGS,"returns upper x range"}, {"xmin",(PyCFunction)histogram_histogram2d_xmin,METH_NOARGS,"returns lower x range"}, {"ymax",(PyCFunction)histogram_histogram2d_ymax,METH_NOARGS,"returns upper y range"}, {"ymin",(PyCFunction)histogram_histogram2d_ymin,METH_NOARGS,"returns lower y range"}, {"nx",(PyCFunction)histogram_histogram2d_nx,METH_NOARGS,"returns number of x bins"}, {"ny",(PyCFunction)histogram_histogram2d_ny,METH_NOARGS,"returns number of y bins"}, {"get",(PyCFunction)histogram_histogram2d_get,METH_VARARGS,"gets value of indexed bin"}, {"get_xrange",(PyCFunction)histogram_histogram2d_get_xrange,METH_VARARGS,"gets upper and lower x range of indexed bin"}, {"get_yrange",(PyCFunction)histogram_histogram2d_get_yrange,METH_VARARGS,"gets upper and lower y range of indexed bin"}, {"find",(PyCFunction)histogram_histogram2d_find,METH_VARARGS,"finds index pair of corresponding value pair"}, {"max_val",(PyCFunction)histogram_histogram2d_max_val,METH_NOARGS,"returns maximal bin value"}, {"max_bin",(PyCFunction)histogram_histogram2d_max_bin,METH_NOARGS,"returns bin index with maximal value"}, {"min_val",(PyCFunction)histogram_histogram2d_min_val,METH_NOARGS,"returns minimal bin value"}, {"min_bin",(PyCFunction)histogram_histogram2d_min_bin,METH_NOARGS,"returns bin index with minimal value"}, {"sum",(PyCFunction)histogram_histogram2d_sum,METH_NOARGS,"returns sum of bin values"}, {"xmean",(PyCFunction)histogram_histogram2d_xmean,METH_NOARGS,"returns x mean of histogram"}, {"xsigma",(PyCFunction)histogram_histogram2d_xsigma,METH_NOARGS,"returns x std deviation of histogram"}, {"ymean",(PyCFunction)histogram_histogram2d_ymean,METH_NOARGS,"returns y mean of histogram"}, {"ysigma",(PyCFunction)histogram_histogram2d_ysigma,METH_NOARGS,"returns y std deviation of histogram"}, {"cov",(PyCFunction)histogram_histogram2d_cov,METH_NOARGS,"returns covariance of histogram"}, {"set_ranges", (PyCFunction)histogram_histogram2d_set_ranges, METH_VARARGS,"set the ranges according to given sequences"}, {"shift",(PyCFunction)histogram_histogram2d_shift,METH_O,"shifts the contents of the bins by the given offset"}, {"scale",(PyCFunction)histogram_histogram2d_scale,METH_O,"multiplies the contents of the bins by the given scale"}, {"equal_bins_p",(PyCFunction)histogram_histogram2d_equal_bins_p,METH_O,"true if the all of the individual bin ranges are identical"}, {"add",(PyCFunction)histogram_histogram2d_add,METH_O,"adds the contents of the bins"}, {"sub",(PyCFunction)histogram_histogram2d_sub,METH_O,"substracts the contents of the bins"}, {"mul",(PyCFunction)histogram_histogram2d_mul,METH_O,"multiplicates the contents of the bins"}, {"div",(PyCFunction)histogram_histogram2d_div,METH_O,"divides the contents of the bins"}, {"clone",(PyCFunction)histogram_histogram2d_clone,METH_NOARGS,"returns a new copy of this histogram"}, {"copy",(PyCFunction)histogram_histogram2d_memcpy,METH_O,"copies the given histogram to myself"}, {"read",(PyCFunction)histogram_histogram2d_fread,METH_O,"reads histogram binary data from file"}, {"write",(PyCFunction)histogram_histogram2d_fwrite,METH_O,"writes histogram binary data to file"}, {"scanf",(PyCFunction)histogram_histogram2d_fscanf,METH_O,"reads histogram data from file using scanf"}, {"printf",(PyCFunction)histogram_histogram2d_printf,METH_VARARGS,"writes histogram data to file using printf"}, {NULL, NULL, 0, NULL} /* sentinel */ }; #endif /* methods for map protocol */ static int histogram_histogram2d_mp_length(PyObject *self) { gsl_histogram2d* histogram; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return -1; } return histogram->nx*histogram->ny; } static PyObject* histogram_histogram2d_mp_subscript(PyObject *self, PyObject *key) { gsl_histogram2d* histogram; long int i; /* indices for histogram access */ long int j; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return NULL; } if (0==PyArg_ParseTuple(key,"ll",&i,&j)) { return NULL; } if (i<0 || i>=histogram->nx) { gsl_error ("index i lies outside valid range of 0 .. nx - 1", filename, __LINE__, GSL_EDOM); return NULL; } if (j<0 || j>=histogram->ny) { gsl_error ("index j lies outside valid range of 0 .. ny - 1", filename, __LINE__, GSL_EDOM); return NULL; } return PyFloat_FromDouble(gsl_histogram2d_get(histogram,i,j)); } static int histogram_histogram2d_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { gsl_histogram2d* histogram; long int i; /* indices for histogram access */ long int j; double v; if ((histogram = PyGSL_HIST2D_GET(self))==NULL) { return -1; } if (0==PyArg_ParseTuple(key,"ll",&i,&j)) { return -1; } if (i<0 || i>=histogram->nx) { gsl_error ("index i lies outside valid range of 0 .. nx - 1", filename, __LINE__, GSL_EDOM); return -1; } if (j<0 || j>=histogram->ny) { gsl_error ("index j lies outside valid range of 0 .. ny - 1", filename, __LINE__, GSL_EDOM ); return -1; } /* get value */ if (value == NULL) v=0; else { PyObject* my_value=PyNumber_Float(value); if (my_value==NULL) return -1; v=PyFloat_AsDouble(value); Py_DECREF(my_value); } histogram->bin[i*histogram->ny+j]=v; return 0; } /* typedef struct { inquiry mp_length; binaryfunc mp_subscript; objobjargproc mp_ass_subscript; } PyMappingMethods; */ static PyMappingMethods histogram_histogram2d_as_mapping = { (inquiry)histogram_histogram2d_mp_length, /* inquiry mp_length */ (binaryfunc)histogram_histogram2d_mp_subscript, /* binaryfunc mp_subscript */ (objobjargproc)histogram_histogram2d_mp_ass_subscript/* objobjargproc mp_ass_subscript */ }; static int histogram_histogram2d_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject* orig_histogram; long int n; long int m; static char *kwlist1[] = {"histogram",NULL}; static char *kwlist2[] = {"nx","ny",NULL}; /* initialise histogram pointer */ PyGSL_HIST2D_CAST(self) = NULL; /* test two call alternatives: */ if (PyArg_ParseTupleAndKeywords(args, kwds,"O!",kwlist1,&histogram_histogram2dType,&orig_histogram)) { gsl_histogram2d *histogram=NULL, *histogram2; if ((histogram2 = PyGSL_HIST2D_GET(orig_histogram))==NULL) { return -1; } histogram=gsl_histogram2d_clone(histogram2); if (histogram==NULL) return -1; PyGSL_HIST2D_CAST(self) = histogram; return 0; } else { /* reset exception */ PyErr_Clear(); } if (PyArg_ParseTupleAndKeywords(args, kwds,"ll",kwlist2,&m,&n)) { gsl_histogram2d* histogram; if (n<=0 || m<=0) { gsl_error ("histogram length n and m must be positive", filename, __LINE__, GSL_EDOM ); return -1; } histogram=gsl_histogram2d_alloc(m,n); if (histogram==NULL) return -1; gsl_histogram2d_reset(histogram); PyGSL_HIST2D_CAST(self) =histogram; return 0; } else { /* set own error message */ PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "histogram2d.init requires pygsl.histogram.histogram2d object or two long int arguments"); return -1; } }