creader_module added
This commit is contained in:
parent
2378055412
commit
0846799f28
180
src/creader_module.c
Normal file
180
src/creader_module.c
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <Python.h>
|
||||||
|
#include <numpy/arrayobject.h>
|
||||||
|
|
||||||
|
#include "data_types.h"
|
||||||
|
#include "cluster_reader.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(read_doc, "Read clusters from open file.\n\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"n: max number of clusters\n"
|
||||||
|
|
||||||
|
"Returns\n"
|
||||||
|
"----------\n"
|
||||||
|
"Array of clusters read\n\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create a custom numpy data type that should reflect
|
||||||
|
// 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 );
|
||||||
|
PyArray_DescrConverter(dtype_dict, &dtype);
|
||||||
|
Py_DECREF(dtype_dict);
|
||||||
|
return dtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Structure holding our cluster reader class
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD FILE *fp;
|
||||||
|
int n_left;
|
||||||
|
int n_read;
|
||||||
|
} ClusterFileReader;
|
||||||
|
|
||||||
|
|
||||||
|
// 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 *kwds) {
|
||||||
|
self->fp = NULL;
|
||||||
|
|
||||||
|
// Parse file name
|
||||||
|
const char *fname = NULL;
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &fname))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
self->fp = fopen(fname, "rb");
|
||||||
|
self->n_left=0;
|
||||||
|
|
||||||
|
// Raise python exception using information from errno
|
||||||
|
if (self->fp == NULL) {
|
||||||
|
PyErr_SetFromErrnoWithFilename(PyExc_OSError, fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close file on clearing the object
|
||||||
|
static int
|
||||||
|
ClusterFileReader_clear(ClusterFileReader *self)
|
||||||
|
{
|
||||||
|
if(self->fp){
|
||||||
|
printf("Closing file\n");
|
||||||
|
fclose(self->fp);
|
||||||
|
self->fp = NULL;
|
||||||
|
self->n_left=0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom destructor, not sure this is needed
|
||||||
|
// might be an easier way to access the fclose on clear
|
||||||
|
static void
|
||||||
|
ClusterFileReader_dealloc(ClusterFileReader *self)
|
||||||
|
{
|
||||||
|
PyObject_GC_UnTrack(self);
|
||||||
|
ClusterFileReader_clear(self);
|
||||||
|
Py_TYPE(self)->tp_free((PyObject *) self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// read method
|
||||||
|
static PyObject *
|
||||||
|
ClusterFileReader_read(ClusterFileReader *self, PyObject *args,
|
||||||
|
PyObject *kwds)
|
||||||
|
{
|
||||||
|
|
||||||
|
const int ndim = 1;
|
||||||
|
Py_ssize_t size = 0;
|
||||||
|
if (!PyArg_ParseTuple(args, "|n", &size))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
npy_intp dims[] = {size};
|
||||||
|
|
||||||
|
//Create an uninitialized numpy array
|
||||||
|
PyArray_Descr *dtype = cluster_dt();
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
//TODO! All kinds of error checking here!!! Resize array etc.
|
||||||
|
|
||||||
|
return clusters;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all methods in our ClusterFileReader class
|
||||||
|
static PyMethodDef ClusterFileReader_methods[] = {
|
||||||
|
{"read", (PyCFunction) ClusterFileReader_read, METH_VARARGS,
|
||||||
|
"Read clusters"
|
||||||
|
},
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Class defenition
|
||||||
|
static PyTypeObject ClusterFileReaderType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "creader.ClusterFileReader",
|
||||||
|
.tp_doc = PyDoc_STR("ClusterFileReader implemented in C"),
|
||||||
|
.tp_basicsize = sizeof(ClusterFileReader),
|
||||||
|
.tp_itemsize = 0,
|
||||||
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
|
||||||
|
.tp_new = PyType_GenericNew,
|
||||||
|
.tp_clear = (inquiry) ClusterFileReader_clear,
|
||||||
|
.tp_dealloc = (destructor) ClusterFileReader_dealloc,
|
||||||
|
.tp_init = (initproc)ClusterFileReader_init,
|
||||||
|
.tp_methods = ClusterFileReader_methods,
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------- Module stuff from here
|
||||||
|
|
||||||
|
// Docstring
|
||||||
|
static char module_docstring[] =
|
||||||
|
"C functions to read cluster files";
|
||||||
|
|
||||||
|
// This is the module itself
|
||||||
|
static PyMethodDef module_methods[] = {
|
||||||
|
{NULL, NULL, 0, NULL}};
|
||||||
|
|
||||||
|
static struct PyModuleDef creader_def = {PyModuleDef_HEAD_INIT, "creader",
|
||||||
|
module_docstring, -1, module_methods};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC PyInit_creader(void) {
|
||||||
|
PyObject *m;
|
||||||
|
if (PyType_Ready(&ClusterFileReaderType) < 0)
|
||||||
|
return NULL;
|
||||||
|
m = PyModule_Create(&creader_def);
|
||||||
|
if (m == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
import_array();
|
||||||
|
|
||||||
|
Py_INCREF(&ClusterFileReaderType);
|
||||||
|
if (PyModule_AddObject(m, "ClusterFileReader",
|
||||||
|
(PyObject *)&ClusterFileReaderType) < 0) {
|
||||||
|
Py_DECREF(&ClusterFileReaderType);
|
||||||
|
Py_DECREF(m);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user