diff --git a/src/ClusterReader.c b/src/ClusterReader.c index e0c864c..296dcc6 100644 --- a/src/ClusterReader.c +++ b/src/ClusterReader.c @@ -74,10 +74,12 @@ static void ClusterFileReader_dealloc(ClusterFileReader *self) { static PyObject *ClusterFileReader_read(ClusterFileReader *self, PyObject *args) { - const int ndim = 1; + Py_ssize_t size = 0; PyObject *noise_obj = NULL; - PyObject *noise_array = NULL; + + + //refcount of the python object is not increased when parsing with O if (!PyArg_ParseTuple(args, "|nO", &size, &noise_obj)) { PyErr_SetString(PyExc_TypeError, "Could not parse args."); return NULL; @@ -101,44 +103,43 @@ static PyObject *ClusterFileReader_read(ClusterFileReader *self, // If the user passed a noise map we fetch a pointer to that array as well int nx = 0, ny = 0; + PyObject *noise_array = NULL; double *noise_map = NULL; if (noise_obj) { - noise_array = - PyArray_FROM_OTF(noise_obj, NPY_DOUBLE, NPY_ARRAY_C_CONTIGUOUS); + //The user could have passes Py_None to indicate no noise map + //in that case we do nothing. + if (noise_obj == Py_None){ + printf("Got Py_None as noise map, doing nothing\n"); + }else{ + //Check that we really got a numpy array and not any kind of PyObject + if(!PyArray_CheckExact(noise_obj)){ + PyErr_SetString(PyExc_TypeError, "Noise map has to be a numpy array (or None)."); + //TODO! Cleanup? + return NULL; + } - int ndim_noise = PyArray_NDIM((PyArrayObject *)(noise_array)); - npy_intp *noise_shape = PyArray_SHAPE((PyArrayObject *)(noise_array)); + noise_array = + PyArray_FROM_OTF(noise_obj, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY | NPY_ARRAY_ENSUREARRAY); + + int ndim_noise = PyArray_NDIM((PyArrayObject *)(noise_array)); + npy_intp *noise_shape = PyArray_SHAPE((PyArrayObject *)(noise_array)); - // For the C++ function call we need pointers (or another C++ type/data - // structure) - - noise_map = (double *)(PyArray_DATA((PyArrayObject *)(noise_array))); - - /* for (int i=0; i< ndim_noise; i++) { */ - /* printf("Dimension %d size %d pointer \n",i,noise_shape[i], - * noise_map); */ - - /* } */ - - if (ndim_noise == 2) { - - nx = noise_shape[0]; - ny = noise_shape[1]; - - // printf("Noise map found size %d %d %d\n",nx,ny,noise_map); - - } else { - nx = 0; - if (ndim_noise == 1) + // For the C++ function call we need pointers (or another C++ type/data + // structure) + if (ndim_noise == 2) { nx = noise_shape[0]; - ny = 0; - noise_map = NULL; - // printf("NO Noise map found %d %d %d - //%d\n",ndim_noise,nx,ny,noise_map); + ny = noise_shape[1]; + noise_map = (double *)(PyArray_DATA((PyArrayObject *)(noise_array))); + } else { + PyErr_SetString(PyExc_TypeError, "Noise map has to be 2D."); + //TODO! Cleanup? + return NULL; + } } } // Create an uninitialized numpy array + const int ndim = 1; PyObject *clusters = PyArray_SimpleNewFromDescr(ndim, dims, cluster_dt()); // Fill with zeros @@ -172,6 +173,10 @@ static PyObject *ClusterFileReader_read(ClusterFileReader *self, PyArray_Resize((PyArrayObject *)clusters, &new_shape, 1, NPY_ANYORDER); } + + //refcount of noise_obj was not increased + //XDECREF also works if noise_array is NULL + Py_XDECREF(noise_array); return clusters; }