changeset 716:26a19beb7e3d

the low level bindings now include a direct data insertion method (with a numpy array). Should compile, but new functionality not really tested. Exercise caution.
author map01bf
date Wed, 23 Jun 2010 10:12:24 +0000
parents 84336d871962
children 159becb0701e
files bindings/python/pyadbmodule.c
diffstat 1 files changed, 122 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/bindings/python/pyadbmodule.c	Mon Jun 21 15:00:55 2010 +0000
+++ b/bindings/python/pyadbmodule.c	Wed Jun 23 10:12:24 2010 +0000
@@ -4,7 +4,8 @@
 // see pyadb.py for the public classes
 // 
 // Created by Benjamin Fields on 2009-09-04.
-// Copyright (c) 2009 Goldsmith University of London. 
+// Big update for direct data insertion 2010-June (Benjamin Fields)
+// Copyleft 2009, 2010 Goldsmith University of London. 
 // Distributed and licensed under GPL2. See ../../license.txt for details.
 // 	
 #include <fcntl.h>
@@ -124,6 +125,119 @@
 	return PyBool_FromLong(ok-1);
 	
 }
+
+/* insert feature data from a numpy array */
+/* array given should have ndarray.shape = (numDims, numVectors)*/
+/* array datatype needs to be doubles (float may work...)*/
+/* if power is given, must be 1d array of length numVectors*/
+/* if times is given, must be 1d array of length 2*numVectors like this:*/
+
+/* api call: */
+// typedef struct adb_datum {
+//   uint32_t nvectors;
+//   uint32_t dim;
+//   const char *key;
+//   double *data;
+//   double *power;
+//   double *times;
+// } adb_datum_t;
+// int audiodb_insert_datum(adb_t *, const adb_datum_t *);
+PyObject * _pyadb_insertFromArray(PyObject *self, PyObject *args, PyObject *keywds)
+{
+	adb_t *current_db;
+	adb_status_t *status;
+	adb_datum_t *ins;
+	int ok;
+	npy_intp dims[1];
+	unsigned int nDims = 0;
+	unsigned int nVect = 0;
+	PyObject *incoming = 0;
+	PyObject *features = 0;
+	PyObject *power = NULL;
+	const char *key = NULL;
+	PyObject *times = NULL;
+	PyArray_Descr *descr;
+	static char *kwlist[]  = { "db", "features", "nDim", "nVect", "power", "key", "times" , NULL};
+	
+	ok =  PyArg_ParseTupleAndKeywords(args, keywds, "OOII|OsO", kwlist, &incoming, &features, nDims, nVect, &power, &key, &times);
+	if (!ok){return NULL;}
+	//check our arrays
+	if (!PyArray_Check(features)){
+		PyErr_SetString(PyExc_TypeError, "features must be a numpy array (of floats or doubles)");
+		return NULL;
+	}
+	if (!PyArray_ISFLOAT(features)){
+		PyErr_SetString(PyExc_TypeError, "features numpy array must contain floats or doubles");
+		return NULL;
+	}
+	if ((PyArray_NDIM(features) != 1) || (PyArray_DIMS(features)[0] != (nDims * nVect))){
+		PyErr_SetString(PyExc_TypeError, "features numpy array must be flattened before call.");
+		return NULL;
+	}
+	descr = PyArray_DescrFromType(NPY_DOUBLE);
+	
+	if (power){
+		if (!PyArray_Check(power)){
+			PyErr_SetString(PyExc_TypeError, "power, if given, must be a numpy array (of floats or doubles)");
+			return NULL;
+		}
+		if (!PyArray_ISFLOAT(power)){
+			PyErr_SetString(PyExc_TypeError, "power numpy array, if given, must contain floats or doubles");
+			return NULL;
+		}
+		// power = (PyArrayObject *)PyCObject_AsVoidPtr(incomingPow);
+		if (PyArray_NDIM(features) != 1 || PyArray_DIMS(power)[0] == nVect){
+			PyErr_SetString(PyExc_ValueError, "power, if given must be a 1d numpy array with shape =  (numVectors,)");
+			return NULL;
+		}
+	}
+	if (times){
+		if (!PyArray_Check(times)){
+			PyErr_SetString(PyExc_TypeError, "times, if given, must be a numpy array (of floats or doubles)");
+			return NULL;
+		}
+		if (!PyArray_ISFLOAT(times)){
+			PyErr_SetString(PyExc_TypeError, "times numpy array, if given, must contain floats or doubles");
+			return NULL;
+		}
+		// times = (PyArrayObject *)PyCObject_AsVoidPtr(incomingTime);
+		if (PyArray_NDIM(times) != 1 || PyArray_DIMS(times)[0] == (nVect*2)){
+			PyErr_SetString(PyExc_ValueError, "times, if given must be a 1d numpy array with shape =  (numVectors,)");
+			return NULL;
+		}
+	}
+	current_db = (adb_t *)PyCObject_AsVoidPtr(incoming);
+	status = (adb_status_t *)malloc(sizeof(adb_status_t));
+	//verify that the data to be inserted is the correct size for the database.
+	
+	ins = (adb_datum_t *)malloc(sizeof(adb_datum_t));
+	if (!PyArray_AsCArray(&features, ins->data, dims,  1, descr)){
+		PyErr_SetString(PyExc_RuntimeError, "Trouble expressing the feature np array as a C array.");
+		return NULL;
+	}
+	
+	if (power != NULL){
+		if (!PyArray_AsCArray(&power, ins->power, dims,  1, descr)){
+			PyErr_SetString(PyExc_RuntimeError, "Trouble expressing the power np array as a C array.");
+			return NULL;
+		}
+	}
+	
+	if (power != NULL){
+		if (!PyArray_AsCArray(&times, ins->times, dims,  1, descr)){
+			PyErr_SetString(PyExc_RuntimeError, "Trouble expressing the times np array as a C array.");
+			return NULL;
+		}
+	}
+	ins->key = key;
+	ins->nvectors = (uint32_t)nVect;
+	ins->dim = (uint32_t)nDims;
+	//printf("features::%s\npower::%s\nkey::%s\ntimes::%s\n", ins->features, ins->power, ins->key, ins->times);
+	ok = audiodb_insert_datum(current_db, ins);//(current_db, ins);
+	return PyBool_FromLong(ok-1);
+	
+}
+
 /* insert feature data stored in a file */
 /* this is a bit gross, */
 /* should be replaced eventually by a numpy based feature.*/
@@ -447,6 +561,13 @@
 	  "_pyadb_l2norm(adb_t *)->int return code (0 for sucess)"},
 	{ "_pyadb_power", _pyadb_power, METH_VARARGS,
 	  "_pyadb_power(adb_t *)->int return code (0 for sucess)"},
+	{"_pyadb_insertFromArray", (PyCFunction)_pyadb_insertFromArray, METH_VARARGS | METH_KEYWORDS,
+	"insert feature data from a numpy array\n\
+	array given should have ndarray.shape = (numDims*numVectors,)\n\
+	array datatype needs to be doubles (float may work...)\n\
+	if power is given, must be 1d array of length numVectors\n\
+	if times is given, must be 1d array of length 2*numVectors like this:\n\
+	int audiodb_insert_datum(adb_t *, const adb_datum_t *);"},
 	{ "_pyadb_insertFromFile", (PyCFunction)_pyadb_insertFromFile, METH_VARARGS | METH_KEYWORDS,
 	  "_pyadb_insertFromFile(adb_t *, features=featureFile, [power=powerfile | key=keystring | times=timingFile])->\
 	int return code (0 for sucess)"},