This repository has been archived on 2025-04-15. You can view files and clone it, but cannot push or open issues or pull requests.
python_cluster_reader/src/creader_module.c
2023-10-27 11:34:50 +02:00

210 lines
6.5 KiB
C

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <numpy/arrayobject.h>
#include "ClusterReader.h"
#include "RawFileReader.h"
#include "arr_desc.h"
#include "cluster_reader.h"
#include "data_types.h"
/* static PyObject *clusterize(PyObject *Py_UNUSED(self), PyObject *args) {
// // Create an uninitialized numpy array
// PyArray_Descr *dtypeIn = cluster_dt();
// PyArray_Descr *dtypeOut = cluster_analysis_dt();
PyObject *cl_obj;
Py_ssize_t csize = 0;
if (!PyArg_ParseTuple(args, "nO", &csize,&cl_obj))
return NULL;
// Create a numpy array from the passed object, 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.
// function steals a reference to the data type so no need to deallocate
/\* PyObject *cl_array = PyArray_FromArray( *\/
/\* (PyArrayObject *)cl_obj, cluster_dt(), NPY_ARRAY_C_CONTIGUOUS); *\/
/\* if (cl_array == NULL) { *\/
/\* PyErr_SetString(PyExc_TypeError, *\/
/\* "Could not convert first argument to numpy array.");
*\/
/\* return NULL; *\/
/\* } *\/
const int ndim = PyArray_NDIM((PyArrayObject *)cl_array);
npy_intp *dims = PyArray_SHAPE((PyArrayObject *)cl_array);
Py_ssize_t size = dims[0];
Cluster *clusters = (Cluster *)(PyArray_DATA((PyArrayObject *)(cl_array)));
PyObject *cl_analysis =
PyArray_SimpleNewFromDescr(ndim, dims, cluster_analysis_dt());
PyArray_FILLWBYTE((PyArrayObject *)cl_analysis, 0); // zero initialization
// // Get a pointer to the array memory
ClusterAnalysis *buf = PyArray_DATA((PyArrayObject *)cl_analysis);
int nc = analyze_clusters(size, clusters, buf,csize);
if (nc != size) {
PyErr_SetString(PyExc_TypeError, "Parsed wrong size array!");
}
Py_DECREF(cl_array);
return cl_analysis;
}
*/
// clusterize method
// static PyObject *ClusterFileReader_clusterize(ClusterFileReader *self,
// PyObject *args) {
static PyObject *clusterize(PyObject *Py_UNUSED(self), PyObject *args) {
const int ndim = 1;
Py_ssize_t size = 0;
PyObject *data_obj;
if (!PyArg_ParseTuple(args, "nO", &size, &data_obj)) {
PyErr_SetString(PyExc_TypeError, "Could not parse args.");
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 *data_array =
PyArray_FROM_OTF(data_obj, NPY_INT32, NPY_ARRAY_C_CONTIGUOUS);
int nx = 0, ny = 0;
int32_t *data = NULL;
// If parsing of a or b fails we throw an exception in Python
if (data_array) {
int ndim_data = PyArray_NDIM((PyArrayObject *)(data_array));
npy_intp *data_shape = PyArray_SHAPE((PyArrayObject *)(data_array));
// For the C++ function call we need pointers (or another C++ type/data
// structure)
data = (int32_t *)(PyArray_DATA((PyArrayObject *)(data_array)));
/* for (int i=0; i< ndim_noise; i++) { */
/* printf("Dimension %d size %d pointer \n",i,noise_shape[i],
* noise_map); */
/* } */
if (ndim_data == 2) {
nx = data_shape[0];
ny = data_shape[1];
if (ny != 9) {
PyErr_SetString(PyExc_TypeError, "Wrong data type.");
// printf("Data found size %d %d %d\n",nx,ny,ndim);
}
} else {
PyErr_SetString(PyExc_TypeError, "Wrong data type.");
}
}
// Create an uninitialized numpy array
// npy_intp dims[] = {nx};
// printf("%d %d\n",ndim,nx);
npy_intp dims[] = {nx};
PyObject *ca =
PyArray_SimpleNewFromDescr(ndim, dims, cluster_analysis_dt());
// printf("1\n");
// Fill with zeros
PyArray_FILLWBYTE((PyArrayObject *)ca, 0);
// printf("2\n");
// Get a pointer to the array memory
void *buf = PyArray_DATA((PyArrayObject *)ca);
// Call the standalone C code to read clusters from file
// Here goes the looping, removing frame numbers etc.
// printf("3\n");
int nc = analyze_clusters(nx, data, buf, size);
// printf("aa %d %d\n",n_read, nx);
/* if (nc != nx) { */
/* // resize the array to match the number of read photons */
/* // this will reallocate memory */
/* // create a new_shape struct on the stack */
/* PyArray_Dims new_shape; */
/* // reuse dims for the shape */
/* //dims[0] = n_read; */
/* new_shape.ptr = n_read; */
/* new_shape.len = 1; */
/* // resize the array to match the number of clusters read */
/* PyArray_Resize((PyArrayObject *)ca, &new_shape, 1, NPY_ANYORDER); */
/* } */
if (nc != nx) {
printf("%d %d\n", nx, nc);
PyErr_SetString(PyExc_TypeError, "Parsed wrong size array!");
}
Py_DECREF(data_array);
return ca;
}
static PyObject *get_cluster_dt(PyObject *Py_UNUSED(self), PyObject *args) {
if (!PyArg_ParseTuple(args, ""))
return NULL;
return (PyObject *)cluster_dt();
}
static PyObject *get_frame_header_dt(PyObject *Py_UNUSED(self),
PyObject *args) {
if (!PyArg_ParseTuple(args, ""))
return NULL;
return (PyObject *)frame_header_dt();
}
// Module docstring, shown as a part of help(creader)
static char module_docstring[] = "C functions to read cluster files";
// Module methods
static PyMethodDef creader_methods[] = {
{"clusterize", clusterize, METH_VARARGS, "Do some stuff"},
{"cluster_dt", get_cluster_dt, METH_VARARGS, "Do some stuff"},
{"frame_header_dt", get_frame_header_dt, METH_VARARGS, "Do some stuff"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
// Module defenition
static struct PyModuleDef creader_def = {
PyModuleDef_HEAD_INIT,
"_creader",
module_docstring,
-1,
creader_methods, // m_methods
NULL, // m_slots
NULL, // m_traverse
NULL, // m_clear
NULL // m_free
};
// Initialize module and add classes
PyMODINIT_FUNC PyInit__creader(void) {
PyObject *m = PyModule_Create(&creader_def);
if (m == NULL)
return NULL;
import_array();
m = init_ClusterFileReader(m);
m = init_RawFileReader(m);
return m;
}