diff --git a/Makefile b/Makefile index 7dfadf4..4c745b5 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,9 @@ default: ext ext: ## [DEFAULT] build c extension in place python setup.py build_ext --inplace +debug: ## Build extension with debug prints and assertions + python setup.py build_ext --inplace -UNDEBUG -DCR_VERBOSE + clean: ## Remove the build folder and the shared library rm -rf build/ creader.cpython* diff --git a/src/cluster_reader.c b/src/cluster_reader.c index b71034d..f36e87a 100644 --- a/src/cluster_reader.c +++ b/src/cluster_reader.c @@ -1,7 +1,9 @@ #include "cluster_reader.h" int read_clusters(FILE* fp, int64_t n_clusters, Cluster* buf, int *n_left){ +#ifdef CR_VERBOSE printf("Item size: %lu n_clusters: %lld, n_left: %d\n", sizeof(Cluster), n_clusters,*n_left); +#endif int iframe=0, nph=*n_left; size_t n_read=0, nph_read=0, nn=*n_left, nr=0; //n_left=n_clusters; @@ -39,7 +41,9 @@ int read_clusters(FILE* fp, int64_t n_clusters, Cluster* buf, int *n_left){ } } // size_t n_read = fread(buf, sizeof(Cluster), n_clusters, fp); +#ifdef CR_VERBOSE printf("Read: %zu items %zu left %d\n", nph_read, n_read,*n_left); +#endif return nph_read; } diff --git a/src/creader_module.c b/src/creader_module.c index ef382d5..f271d0e 100644 --- a/src/creader_module.c +++ b/src/creader_module.c @@ -1,22 +1,23 @@ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #define PY_SSIZE_T_CLEAN + +#include "cluster_reader.h" +#include "data_types.h" + #include #include -#include "data_types.h" -#include "cluster_reader.h" - +#include // Create a custom numpy data type that should reflect -// our cluster data type. +// our cluster data type. // TODO! Update with the actual cluster data type static PyArray_Descr *cluster_dt() { PyObject *dtype_dict; PyArray_Descr *dtype; - dtype_dict = Py_BuildValue( - "[(s, s),(s, s),(s, s, (i))]", - "x", "u2", "y", "u2","data","i4",9 ); + dtype_dict = Py_BuildValue("[(s, s),(s, s),(s, s, (i))]", "x", "u2", "y", + "u2", "data", "i4", 9); PyArray_DescrConverter(dtype_dict, &dtype); Py_DECREF(dtype_dict); @@ -26,38 +27,36 @@ static PyArray_Descr *cluster_dt() { static PyArray_Descr *cluster_analysis_dt() { PyObject *dtype_dict; PyArray_Descr *dtype; - dtype_dict = Py_BuildValue( - "[(s, s),(s, s),(s, s)]", "tot3", "i4","tot2","i4", - "corner", "u4"); + dtype_dict = Py_BuildValue("[(s, s),(s, s),(s, s)]", "tot3", "i4", "tot2", + "i4", "corner", "u4"); PyArray_DescrConverter(dtype_dict, &dtype); Py_DECREF(dtype_dict); return dtype; } - +// clang-format off // Structure holding our cluster reader class typedef struct { - PyObject_HEAD FILE *fp; - int n_left; - int n_read; + PyObject_HEAD + FILE *fp; + int n_left; } ClusterFileReader; +// clang-format on - -// Constructor: sets the fp to NULL then tries to open the file +// Constructor: sets the fp to NULL then tries to open the file // raises python exception if something goes wrong // returned object should mean file is open and ready to read static int ClusterFileReader_init(ClusterFileReader *self, PyObject *args, - PyObject * Py_UNUSED(kwds)) { - self->fp = NULL; + PyObject *Py_UNUSED(kwds)) { - // Parse file name + // Parse file name const char *fname = NULL; if (!PyArg_ParseTuple(args, "s", &fname)) return -1; self->fp = fopen(fname, "rb"); - self->n_left=0; + self->n_left = 0; // Raise python exception using information from errno if (self->fp == NULL) { @@ -65,28 +64,25 @@ static int ClusterFileReader_init(ClusterFileReader *self, PyObject *args, return -1; } - //Success + // Success return 0; } // Custom destructor to make sure we close the file -static void -ClusterFileReader_dealloc(ClusterFileReader *self) -{ - if(self->fp){ +static void ClusterFileReader_dealloc(ClusterFileReader *self) { + if (self->fp) { +#ifdef CR_VERBOSE printf("Closing file\n"); +#endif fclose(self->fp); self->fp = NULL; - } - Py_TYPE(self)->tp_free((PyObject *) self); + } + Py_TYPE(self)->tp_free((PyObject *)self); } - -// read method -static PyObject * -ClusterFileReader_read(ClusterFileReader *self, PyObject *args, - PyObject * Py_UNUSED(kwds)) -{ +// read method +static PyObject *ClusterFileReader_read(ClusterFileReader *self, PyObject *args, + PyObject *Py_UNUSED(kwds)) { const int ndim = 1; Py_ssize_t size = 0; @@ -95,33 +91,33 @@ ClusterFileReader_read(ClusterFileReader *self, PyObject *args, npy_intp dims[] = {size}; - //Create an uninitialized numpy array + // Create an uninitialized numpy array PyArray_Descr *dtype = cluster_dt(); - // PyObject *PyArray_SimpleNewFromDescr(int nd, npy_int const *dims, PyArray_Descr *descr) + // PyObject *PyArray_SimpleNewFromDescr(int nd, npy_int const *dims, + // PyArray_Descr *descr) PyObject *clusters = PyArray_SimpleNewFromDescr(ndim, dims, dtype); - PyArray_FILLWBYTE((PyArrayObject *)clusters, 0); //zero initialization can be removed later - - - //Get a pointer to the array memory - void* buf = PyArray_DATA((PyArrayObject *)clusters); + PyArray_FILLWBYTE((PyArrayObject *)clusters, + 0); // zero initialization can be removed later + + // Get a pointer to the array memory + void *buf = PyArray_DATA((PyArrayObject *)clusters); // Call the standalone C code to read clusters from file - // Here goes the looping, removing frame numbers etc. - self->n_read = read_clusters(self->fp, size, buf, &self->n_left); + // Here goes the looping, removing frame numbers etc. + int n_read = read_clusters(self->fp, size, buf, &self->n_left); + if (n_read != size) { + // resize the array to match the number of read photons + // this will reallocate memory - if(self->n_read != size){ - //resize the array to match the number of read photons - //this will reallocate memory - - //create a new_shape struct on the stack + // create a new_shape struct on the stack PyArray_Dims new_shape; - //reuse dims for the shape - dims[0] = self->n_read; + // reuse dims for the shape + dims[0] = n_read; new_shape.ptr = dims; new_shape.len = 1; - + // resize the array to match the number of clusters read PyArray_Resize((PyArrayObject *)clusters, &new_shape, 1, NPY_ANYORDER); } @@ -129,24 +125,16 @@ ClusterFileReader_read(ClusterFileReader *self, PyObject *args, return clusters; } +// read method +static PyObject *ClusterFileReader_clusterize(ClusterFileReader *self, + PyObject *args, + PyObject *Py_UNUSED(kwds)) { - - - -// read method -static PyObject * -ClusterFileReader_clusterize(ClusterFileReader *self, PyObject *args, - PyObject * Py_UNUSED(kwds)) -{ - - - - - //Create an uninitialized numpy array + // Create an uninitialized numpy array PyArray_Descr *dtypeIn = cluster_dt(); PyArray_Descr *dtypeOut = cluster_analysis_dt(); - PyObject *c_obj; + PyObject *c_obj; if (!PyArg_ParseTuple(args, "O", &c_obj)) return NULL; @@ -154,74 +142,63 @@ ClusterFileReader_clusterize(ClusterFileReader *self, PyObject *args, // use the underlying buffer, otherwise it will create a copy, for example // if data type is different or we pass in a list. The // NPY_ARRAY_C_CONTIGUOUS flag ensures that we have contiguous memory. - PyObject *c_array =PyArray_FromArray((PyArrayObject *)c_obj, dtypeIn, NPY_ARRAY_C_CONTIGUOUS); + PyObject *c_array = PyArray_FromArray((PyArrayObject *)c_obj, dtypeIn, + NPY_ARRAY_C_CONTIGUOUS); // If parsing of a or b fails we throw an exception in Python - if (c_array == NULL ) { - PyErr_SetString( - PyExc_TypeError, - "Could not convert one of the arguments to a numpy array."); - return NULL; + if (c_array == NULL) { + PyErr_SetString( + PyExc_TypeError, + "Could not convert one of the arguments to a numpy array."); + return NULL; } - - + const int ndim = PyArray_NDIM((PyArrayObject *)c_array); npy_intp *dims = PyArray_SHAPE((PyArrayObject *)c_array); - Py_ssize_t size=dims[0]; - //printf("%d size %d %d\n",ndim,size,sizeof(ClusterAnalysis)); - //dims[0]=size; - - //Cluster *clusters = reinterpret_cast( PyArray_DATA(reinterpret_cast(c_array))); + Py_ssize_t size = dims[0]; + // printf("%d size %d %d\n",ndim,size,sizeof(ClusterAnalysis)); + // dims[0]=size; + + // Cluster *clusters = reinterpret_cast( + // PyArray_DATA(reinterpret_cast(c_array))); Cluster *clusters = (Cluster *)(PyArray_DATA((PyArrayObject *)(c_array))); - - - - - // PyObject *PyArray_SimpleNewFromDescr(int nd, npy_int const *dims, PyArray_Descr *descr) + // PyObject *PyArray_SimpleNewFromDescr(int nd, npy_int const *dims, + // PyArray_Descr *descr) PyObject *clustersA = PyArray_SimpleNewFromDescr(ndim, dims, dtypeOut); - //PyArray_FILLWBYTE((PyArrayObject *)clustersA, 0); //zero initialization can be removed later - npy_intp *strides=PyArray_STRIDES(((PyArrayObject *)(clustersA))); + // PyArray_FILLWBYTE((PyArrayObject *)clustersA, 0); //zero initialization + // can be removed later + npy_intp *strides = PyArray_STRIDES(((PyArrayObject *)(clustersA))); // printf("strides %d %d\n", strides[0],sizeof(ClusterAnalysis)); - - //Get a pointer to the array memory - ClusterAnalysis* buf = PyArray_DATA((PyArrayObject *)clustersA); + + // Get a pointer to the array memory + ClusterAnalysis *buf = PyArray_DATA((PyArrayObject *)clustersA); // Call the standalone C code to read clusters from file - // Here goes the looping, removing frame numbers etc. - int nc = analyze_clusters(size,clusters,buf); - //printf("%d %d\n",nc,size); - - if(nc != size){ - - PyErr_SetString( - PyExc_TypeError, - "Parsed wrong size array!"); - + // Here goes the looping, removing frame numbers etc. + int nc = analyze_clusters(size, clusters, buf); + // printf("%d %d\n",nc,size); + + if (nc != size) { + + PyErr_SetString(PyExc_TypeError, "Parsed wrong size array!"); } return clustersA; } - - - - // List all methods in our ClusterFileReader class static PyMethodDef ClusterFileReader_methods[] = { - {"read", (PyCFunction) ClusterFileReader_read, METH_VARARGS, - "Read clusters" - }, - {"clusterize", (PyCFunction) ClusterFileReader_clusterize, METH_VARARGS, - "Analyze clusters" - }, - {NULL, NULL, 0, NULL} /* Sentinel */ + {"read", (PyCFunction)ClusterFileReader_read, METH_VARARGS, + "Read clusters"}, + {"clusterize", (PyCFunction)ClusterFileReader_clusterize, METH_VARARGS, + "Analyze clusters"}, + {NULL, NULL, 0, NULL} /* Sentinel */ }; - // Class defenition static PyTypeObject ClusterFileReaderType = { PyVarObject_HEAD_INIT(NULL, 0).tp_name = "creader.ClusterFileReader", @@ -230,7 +207,7 @@ static PyTypeObject ClusterFileReaderType = { .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_new = PyType_GenericNew, - .tp_dealloc = (destructor) ClusterFileReader_dealloc, + .tp_dealloc = (destructor)ClusterFileReader_dealloc, .tp_init = (initproc)ClusterFileReader_init, .tp_methods = ClusterFileReader_methods, }; @@ -238,21 +215,20 @@ static PyTypeObject ClusterFileReaderType = { //------------------------------------------- Module stuff from here // Docstring -static char module_docstring[] = - "C functions to read cluster files"; +static char module_docstring[] = "C functions to read cluster files"; static struct PyModuleDef creader_def = { - PyModuleDef_HEAD_INIT, "creader", - module_docstring, - -1, + PyModuleDef_HEAD_INIT, + "creader", + module_docstring, + -1, ClusterFileReader_methods, - NULL, //m_slots - NULL, //m_traverse - NULL, //m_clear - NULL //m_free + NULL, // m_slots + NULL, // m_traverse + NULL, // m_clear + NULL // m_free }; - PyMODINIT_FUNC PyInit_creader(void) { PyObject *m; if (PyType_Ready(&ClusterFileReaderType) < 0) @@ -272,4 +248,3 @@ PyMODINIT_FUNC PyInit_creader(void) { } return m; } -