diff --git a/src/Makefile.test b/src/Makefile.test new file mode 100644 index 0000000..a263aba --- /dev/null +++ b/src/Makefile.test @@ -0,0 +1,2 @@ +test: main.cpp cluster_reader.cpp cluster_reader.h + g++ -o test main.cpp cluster_reader.cpp -std=c++11 diff --git a/src/cluster_reader.cpp b/src/cluster_reader.cpp new file mode 100644 index 0000000..a65e46d --- /dev/null +++ b/src/cluster_reader.cpp @@ -0,0 +1,66 @@ + +#include "cluster_reader.h" +#include +#include "single_photon_hit.h" +#include + +FILE *f; +int ph_left; +void cpp_open_cluster_file(char *fname, int &ok){ + f=fopen(fname,"r"); + if (f) + ok=1; + else + ok=0; +} + +void cpp_close_cluster_file(int &ok){ + if (f){ + fclose(f); + f=NULL; + ok=1; + } else + ok=0; + +} + + + +void cpp_read_clusters(int &iiph, std::vector &v, int &ok, int maxframes) { + iiph=0; + int iframe, iff, nph; + //std::vector v={}; + struct cluster *clust; + single_photon_hit cl; + ph_left=0; + + iff=0; + ok=0; + if (f) { + ok=1; + while (fread((void*)&iframe, 1, sizeof(int), f)) { + if (fread((void*)&nph, 1, sizeof(int), f)) { + ph_lft=nph; + if (nph>0) { + for (int iph=0; iphx=cl.x; + clust->y=cl.y; + for (int ix=0; ix<3; ix++) + for (int iy=0; iy<3; iy++) + clust->data[iy*3+ix]=cl.data[iy*3+ix]; + v.push_back(*clust); + iiph++; + } + } + } + } + iff++; + if (maxframes>0 && iff>maxframes) + break; + } + } + //return v; +} diff --git a/src/cluster_reader.h b/src/cluster_reader.h new file mode 100644 index 0000000..49a96b3 --- /dev/null +++ b/src/cluster_reader.h @@ -0,0 +1,21 @@ +#ifndef CLUSTER_READER_H +#define CLUSTER_READER_H +#include +#include +#include + +struct cluster { + int16_t x; + int16_t y; + //data[iy * 3 + ix ] + int32_t data[9]; +} ; + +void cpp_read_clusters(int &iiph, std::vector &v, int &ok, int maxframes=-1); + + +void cpp_open_cluster_file(char *fname, int &ok); + +void cpp_close_cluster_file(int &ok); + +#endif diff --git a/src/cluster_reader_module.cpp b/src/cluster_reader_module.cpp new file mode 100644 index 0000000..39c8578 --- /dev/null +++ b/src/cluster_reader_module.cpp @@ -0,0 +1,154 @@ +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include "function.h" //this is the function that we want to call +#include +#include +#include +using namespace std; + + +// Docstring +static char module_docstring[] = "Cluster reader"; + + +PyDoc_STRVAR(read_clusters_doc, "Read clusters from open file.\n\n" + "Parameters\n" + "----------\n" + "f: file name\n" + + "Returns\n" + "----------\n" + "nothing\n\n"); + + + + +PyDoc_STRVAR(open_cluster_file_doc, "Read cluster file.\n\n" + "Parameters\n" + "----------\n" + "maxframes: maximum number of frames to be read\n" + + "Returns\n" + "----------\n" + "v: numpy_array\n" + " clusters\n\n"); + + +PyDoc_STRVAR(close_cluster_file_doc, "Read cluster file.\n\n" + "Parameters\n" + "----------\n" + "none\n" + "Returns\n" + "----------\n" + "nothing\n\n"); + + +// Declare functions that should go into the module +static PyObject *read_clusters(PyObject *self, PyObject *args); + +// This is the module itself +static PyMethodDef module_methods[] = {{"open_cluster_file", (PyCFunction)open_cluster_file, METH_VARARGS, open_cluster_file_doc},{"close_cluster_file", (PyCFunction)close_cluster_file, METH_VARARGS, close_cluster_file_doc},{"read_clusters", (PyCFunction)read_clusters, METH_VARARGS, read_clusters_doc}, + {NULL, NULL, 0, NULL}}; + +// Don't touch except the name +static struct PyModuleDef mymod_def = {PyModuleDef_HEAD_INIT, "cluster_reader_mod", + module_docstring, -1, module_methods}; + +// Don't touch +PyMODINIT_FUNC PyInit_cluster_reader_cpp(void) { + PyObject *m = PyModule_Create(&cluster_reader_module_def); + if (m == NULL) + return NULL; + + import_array(); + return m; +} + +static int open_cluster_file(PyObject *self, PyObject *args) { + +// cout << "Hello there" << endl; // General Kenobi + // Python offers a lot of flexibility so the first thing we need to do + // is to parse the arguments and make sure we are called with correct + // parameters + char *fname; + if (!PyArg_ParseTuple(args, "s", fname)) + return NULL; + + // Now call add wih pointers and size + int ok; + cpp_open_cluster_file(fname,ok); + + return ok; +} + +static int close_cluster_file(PyObject *self, PyObject *args) { + +// cout << "Hello there" << endl; // General Kenobi + // Python offers a lot of flexibility so the first thing we need to do + // is to parse the arguments and make sure we are called with correct + // parameters + + // Now call add wih pointers and size + int ok; + cpp_close_cluster_file(ok); + + return ok; +} + + +static PyObject *read_clusters(PyObject *self, PyObject *args) { + +// cout << "Hello there" << endl; // General Kenobi + // Python offers a lot of flexibility so the first thing we need to do + // is to parse the arguments and make sure we are called with correct + // parameters + PyObject *fname_obj; + PyObject *maxframes_obj; + if (!PyArg_ParseTuple(args, "OO", &_obj, &b_obj)) + return NULL; + + // Create two numpy arrays from the passed objects, if possible numpy will + // 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 *a_array = + PyArray_FROM_OTF(a_obj, NPY_UINT16, NPY_ARRAY_C_CONTIGUOUS); + PyObject *d_array = + PyArray_FROM_OTF(b_obj, NPY_UINT64, NPY_ARRAY_C_CONTIGUOUS); + + // If parsing of a or b fails we throw an exception in Python + if (a_array == NULL || d_array == NULL) { + PyErr_SetString( + PyExc_TypeError, + "Could not convert one of the arguments to a numpy array."); + return NULL; + } + + //npy_intp dims[2] = { 400, 400 }; + + // Create array for return values + PyObject *cluster_array = PyArray_SimpleNew(1, dims, NPY_UINT16); + + // For the C++ function call we need pointers (or another C++ type/data + // structure) + uint16_t *a = reinterpret_cast( + PyArray_DATA(reinterpret_cast(a_array))); + uint64_t*b = reinterpret_cast( + PyArray_DATA(reinterpret_cast(d_array))); + uint16_t *result_analog = reinterpret_cast( + PyArray_DATA(reinterpret_cast(result_analog_array))); + uint8_t *result_digital = reinterpret_cast( + PyArray_DATA(reinterpret_cast(result_digital_array))); + + // Now call add wih pointers and size + cpp_decode(a, b, result_analog, result_digital); + + // Clean up + Py_DECREF(a_array); + Py_DECREF(d_array); + + PyObject *result_tuple = PyTuple_New(2); + PyTuple_SetItem(result_tuple, 0, result_analog_array); + PyTuple_SetItem(result_tuple, 1, result_digital_array); +// return result_analog_array; + return result_tuple; +}