changeset 28:1175e814954e

Pruning & tidying
author Chris Cannam
date Wed, 26 Nov 2014 10:54:48 +0000
parents fb6519598734
children 7e7f2f7d9542
files PyTypeConversions.cpp PyTypeConversions.h vampyhost.cpp
diffstat 3 files changed, 199 insertions(+), 404 deletions(-) [+]
line wrap: on
line diff
--- a/PyTypeConversions.cpp	Wed Nov 26 10:01:04 2014 +0000
+++ b/PyTypeConversions.cpp	Wed Nov 26 10:54:48 2014 +0000
@@ -1,38 +1,38 @@
 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
 
 /*
-    VampyHost
+  VampyHost
 
-    Use Vamp audio analysis plugins in Python
+  Use Vamp audio analysis plugins in Python
 
-    Gyorgy Fazekas and Chris Cannam
-    Centre for Digital Music, Queen Mary, University of London
-    Copyright 2008-2014 Queen Mary, University of London
+  Gyorgy Fazekas and Chris Cannam
+  Centre for Digital Music, Queen Mary, University of London
+  Copyright 2008-2014 Queen Mary, University of London
   
-    Permission is hereby granted, free of charge, to any person
-    obtaining a copy of this software and associated documentation
-    files (the "Software"), to deal in the Software without
-    restriction, including without limitation the rights to use, copy,
-    modify, merge, publish, distribute, sublicense, and/or sell copies
-    of the Software, and to permit persons to whom the Software is
-    furnished to do so, subject to the following conditions:
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation
+  files (the "Software"), to deal in the Software without
+  restriction, including without limitation the rights to use, copy,
+  modify, merge, publish, distribute, sublicense, and/or sell copies
+  of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
 
-    The above copyright notice and this permission notice shall be
-    included in all copies or substantial portions of the Software.
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
 
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
-    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+  ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-    Except as contained in this notice, the names of the Centre for
-    Digital Music; Queen Mary, University of London; and the authors
-    shall not be used in advertising or otherwise to promote the sale,
-    use or other dealings in this Software without prior written
-    authorization.
+  Except as contained in this notice, the names of the Centre for
+  Digital Music; Queen Mary, University of London; and the authors
+  shall not be used in advertising or otherwise to promote the sale,
+  use or other dealings in this Software without prior written
+  authorization.
 */
 
 #include <Python.h>
@@ -41,23 +41,15 @@
 
 #include <math.h>
 #include <float.h>
-#include <limits.h>
-#ifndef SIZE_T_MAX
-#define SIZE_T_MAX ((size_t) -1)
-#endif
 
-using std::string;
-using std::vector;
-using std::cerr;
-using std::endl;
+using namespace std;
 
 /*  Note: NO FUNCTION IN THIS CLASS SHOULD ALTER REFERENCE COUNTS
-	(EXCEPT FOR TEMPORARY PYTHON OBJECTS)! */
+    (EXCEPT FOR TEMPORARY PYTHON OBJECTS)! */
 
 PyTypeConversions::PyTypeConversions() : 
-	m_strict(false),
-	m_error(false),
-	error(m_error) // const public reference for easy access
+    m_error(false),
+    error(m_error) // const public reference for easy access
 {
 }
 
@@ -65,323 +57,158 @@
 {
 }
 
-
 /// floating point numbers (TODO: check numpy.float128)
 float 
 PyTypeConversions::PyValue_To_Float(PyObject* pyValue) const
 {
-	// convert float
-	if (pyValue && PyFloat_Check(pyValue)) 
-		//TODO: check for limits here (same on most systems)
-		return (float) PyFloat_AS_DOUBLE(pyValue);
+    // convert float
+    if (pyValue && PyFloat_Check(pyValue)) 
+        //TODO: check for limits here (same on most systems)
+        return (float) PyFloat_AS_DOUBLE(pyValue);
 	
-	if (pyValue == NULL)
-	{
-		setValueError("Error while converting object " + PyValue_Get_TypeName(pyValue) + " to float. ",m_strict);
-		return 0.0;		
-	}
+    if (pyValue == NULL)
+    {
+        setValueError("Error while converting object " + PyValue_Get_TypeName(pyValue) + " to float. ");
+        return 0.0;		
+    }
 		
-	// in strict mode we will not try harder
-	if (m_strict) {
-		setValueError("Strict conversion error: object" + PyValue_Get_TypeName(pyValue) +" is not float.",m_strict);
-		return 0.0;
-	}
-
-	// convert other objects supporting the number protocol
-	if (PyNumber_Check(pyValue))
-	{
-		PyObject* pyFloat = PyNumber_Float(pyValue); // new ref
-		if (!pyFloat)
-		{
-			if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
-			setValueError("Error while converting " + PyValue_Get_TypeName(pyValue) + " object to float.",m_strict);
-			return 0.0;
-		}
-		float rValue = (float) PyFloat_AS_DOUBLE(pyFloat);
-		Py_DECREF(pyFloat);
-		return rValue;
-	}
-/*	
-	// convert other objects supporting the number protocol
-	if (PyNumber_Check(pyValue)) 
-	{	
-		// PEP353: Py_ssize_t is size_t but signed !
-		// This will work up to numpy.float64
-		Py_ssize_t rValue = PyNumber_AsSsize_t(pyValue,NULL);
-		if (PyErr_Occurred()) 
-		{
-			PyErr_Print(); PyErr_Clear();
-			setValueError("Error while converting integer object.",m_strict);
-			return 0.0;
-		}
-		if (rValue > (Py_ssize_t)FLT_MAX || rValue < (Py_ssize_t)FLT_MIN)
-		{
-			setValueError("Overflow error. Object can not be converted to float.",m_strict);
-			return 0.0;
-		}
-		return (float) rValue;
-	}
-*/	
-    // convert string
-	if (PyString_Check(pyValue))
-	{
-		PyObject* pyFloat = PyFloat_FromString(pyValue,NULL);
-		if (!pyFloat) 
-		{
-			if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
-			setValueError("String value can not be converted to float.",m_strict);
-			return 0.0;
-		}
-		float rValue = (float) PyFloat_AS_DOUBLE(pyFloat);
-		if (PyErr_Occurred()) 
-		{
-			PyErr_Print(); PyErr_Clear(); 
-			Py_CLEAR(pyFloat);
-			setValueError("Error while converting float object.",m_strict);
-			return 0.0;
-		}
-		Py_DECREF(pyFloat);
-		return rValue;
-	}
-	
-	// convert the first element of any iterable sequence (for convenience and backwards compatibility)
-	if (PySequence_Check(pyValue) && PySequence_Size(pyValue) > 0) 
-	{
-		PyObject* item = PySequence_GetItem(pyValue,0);
-		if (item)
-		{
-			float rValue = this->PyValue_To_Float(item);
-			if (!m_error) {
-				Py_DECREF(item);
-				return rValue;
-			} else {
-				Py_CLEAR(item);
-				std::string msg = "Could not convert sequence element to float. ";
-				setValueError(msg,m_strict);
-				return 0.0;
-			}
-		}
-	}
-
-    // give up
-	if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
-	std::string msg = "Conversion from " + PyValue_Get_TypeName(pyValue) + " to float is not possible.";
-	setValueError(msg,m_strict);
-#ifdef _DEBUG
-	cerr << "PyTypeConversions::PyValue_To_Float failed. " << msg << endl;
-#endif	
-	return 0.0;
+    setValueError("Conversion error: object" + PyValue_Get_TypeName(pyValue) +" is not float.");
+    return 0.0;
 }
 
-
-/*			 			Sequence Types to C++ Types	    		  	*/
-
-//convert PyFeature.value (typically a list or numpy array) to C++ vector of floats
-std::vector<float> 
+vector<float> 
 PyTypeConversions::PyValue_To_FloatVector (PyObject *pyValue) const 
 {
-	// there are four types of values we may receive from a numpy process:
-	// * a python scalar, 
-	// * an array scalar, (e.g. numpy.float32)
-	// * an array with nd = 0  (0D array)
-	// * an array with nd > 0
+    /// numpy array
+    if (PyArray_CheckExact(pyValue)) 
+        return PyArray_To_FloatVector(pyValue);
 
-	/// check for scalars
-	if (PyArray_CheckScalar(pyValue) || PyFloat_Check(pyValue)) {
+    /// python list of floats (backward compatible)
+    if (PyList_Check(pyValue)) {
+        return PyList_To_FloatVector(pyValue);
+    }
 
-		std::vector<float> Output;
-
-		// we rely on the behaviour the scalars are either floats
-		// or support the number protocol
-		// TODO: a potential optimisation is to handle them directly
-		Output.push_back(PyValue_To_Float(pyValue));
-		return Output;
-	}
-
-	/// numpy array
-	if (PyArray_CheckExact(pyValue)) 
-		return PyArray_To_FloatVector(pyValue);
-
-	/// python list of floats (backward compatible)
-	if (PyList_Check(pyValue)) {
-		return PyList_To_FloatVector(pyValue);
-	}
-
-	std::vector<float> Output;
-	
-	/// finally assume a single value supporting the number protocol 
-	/// this allows to write e.g. Feature.values = 5 instead of [5.00]
-	Output.push_back(PyValue_To_Float(pyValue));
-	if (m_error) {
-		std::string msg = "Value is not list or array of floats nor can be casted as float. ";
-		setValueError(msg,m_strict);
+    string msg = "Value is not list or array of floats";
+    setValueError(msg);
 #ifdef _DEBUG
-	cerr << "PyTypeConversions::PyValue_To_FloatVector failed. " << msg << endl;
+    cerr << "PyTypeConversions::PyValue_To_FloatVector failed. " << msg << endl;
 #endif
-	}
-	return Output;
+    return vector<float>();
 }
 
-//convert a list of python floats
-std::vector<float> 
+vector<float> 
 PyTypeConversions::PyList_To_FloatVector (PyObject *inputList) const 
 {
-	std::vector<float> Output;
+    vector<float> v;
 	
-#ifdef _DEBUG
-	// This is a low level function normally called from 
-	// PyValue_To_FloatVector(). Checking for list is not required.
-	if (!PyList_Check(inputList)) {
-		std::string msg = "Value is not list.";
-		setValueError(msg,true);
-		cerr << "PyTypeConversions::PyList_To_FloatVector failed. " << msg << endl;
-		return Output; 
-	} 
-#endif
+    if (!PyList_Check(inputList)) {
+        setValueError("Value is not a list");
+        return v;
+    } 
 
-	float ListElement;
-	PyObject *pyFloat = NULL;
-	PyObject **pyObjectArray = PySequence_Fast_ITEMS(inputList);
+    PyObject **pyObjectArray = PySequence_Fast_ITEMS(inputList);
+    int n = PyList_GET_SIZE(inputList);
 
-	for (Py_ssize_t i = 0; i < PyList_GET_SIZE(inputList); ++i) {
-
-		// pyFloat = PyList_GET_ITEM(inputList,i);
-		pyFloat = pyObjectArray[i];
-
-#ifdef _DEBUG
-		if (!pyFloat) {
-			if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
-			cerr << "PyTypeConversions::PyList_To_FloatVector: Could not obtain list element: " 
-			<< i << " PyList_GetItem returned NULL! Skipping value." << endl;
-			continue;
-		}
-#endif		
-
-		// ListElement = (float) PyFloat_AS_DOUBLE(pyFloat);
-		ListElement = PyValue_To_Float(pyFloat);
-		
-
-#ifdef _DEBUG_VALUES
-		cerr << "value: " << ListElement << endl;
-#endif
-		Output.push_back(ListElement);
-	}
-	return Output;
+    for (int i = 0; i < n; ++i) {
+        v.push_back(PyValue_To_Float(pyObjectArray[i]));
+    }
+    
+    return v;
 }
 
-// if numpy is not installed this will not be called, 
-// therefor we do not check again
-std::vector<float> 
+vector<float> 
 PyTypeConversions::PyArray_To_FloatVector (PyObject *pyValue) const 
 {
-	std::vector<float> Output;
+    vector<float> v;
 	
+    if (!PyArray_Check(pyValue)) {
+        setValueError("Value is not an array");
+        return v;
+    } 
+
+    PyArrayObject* pyArray = (PyArrayObject*) pyValue;
+    PyArray_Descr* descr = PyArray_DESCR(pyArray);
+	
+    if (PyArray_DATA(pyArray) == 0 || descr == 0) {
+        string msg = "NumPy array with NULL data or descriptor pointer encountered.";
+        setValueError(msg);
+        return v;
+    }
+
+    if (PyArray_NDIM(pyArray) != 1) {
+        string msg = "NumPy array must be a one dimensional vector.";
+        setValueError(msg);
+        return v;
+    }
+
+    /// check strides (useful if array is not continuous)
+    size_t strides =  *((size_t*) PyArray_STRIDES(pyArray));
+    
+    /// convert the array
+    switch (descr->type_num) {
+        
+    case NPY_FLOAT : // dtype='float32'
+        return PyArray_Convert<float,float>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
+    case NPY_DOUBLE : // dtype='float64'
+        return PyArray_Convert<float,double>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
+    case NPY_INT : // dtype='int'
+        return PyArray_Convert<float,int>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
+    case NPY_LONG : // dtype='long'
+        return PyArray_Convert<float,long>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
+    default :
+        string msg = "Unsupported value type in NumPy array object.";
+        setValueError(msg);
 #ifdef _DEBUG
-	// This is a low level function, normally called from 
-	// PyValue_To_FloatVector(). Checking the array here is not required.
-	if (!PyArray_Check(pyValue)) {
-		std::string msg = "Object has no array conversions.";
-		setValueError(msg,true);
-		cerr << "PyTypeConversions::PyArray_To_FloatVector failed. " << msg << endl;
-		return Output; 
-	} 
-#endif
-
-	PyArrayObject* pyArray = (PyArrayObject*) pyValue;
-	PyArray_Descr* descr = PyArray_DESCR(pyArray);
-	
-	/// check raw data and descriptor pointers
-	if (PyArray_DATA(pyArray) == 0 || descr == 0) {
-		std::string msg = "NumPy array with NULL data or descriptor pointer encountered.";
-		setValueError(msg,m_strict);
-#ifdef _DEBUG
-		cerr << "PyTypeConversions::PyArray_To_FloatVector failed. Error: " << msg << endl;
-#endif		
-		return Output;
-	}
-
-	/// check dimensions
-	if (PyArray_NDIM(pyArray) != 1) {
-		std::string msg = "NumPy array must be a one dimensional vector.";
-		setValueError(msg,m_strict);
-#ifdef _DEBUG
-		cerr << "PyTypeConversions::PyArray_To_FloatVector failed. Error: " << msg << " Dims: " << (int) PyArray_NDIM(pyArray) << endl;
-#endif	
-		return Output;
-	}
-
-#ifdef _DEBUG_VALUES
-	cerr << "PyTypeConversions::PyArray_To_FloatVector: Numpy array verified." << endl;
-#endif
-	
-	/// check strides (useful if array is not continuous)
-	size_t strides =  *((size_t*) PyArray_STRIDES(pyArray));
-    
-	/// convert the array
-	switch (descr->type_num)
-	{
-		case NPY_FLOAT : // dtype='float32'
-			return PyArray_Convert<float,float>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
-		case NPY_DOUBLE : // dtype='float64'
-			return PyArray_Convert<float,double>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
-		case NPY_INT : // dtype='int'
-			return PyArray_Convert<float,int>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
-		case NPY_LONG : // dtype='long'
-			return PyArray_Convert<float,long>(PyArray_DATA(pyArray),PyArray_DIMS(pyArray)[0],strides);
-		default :
-			std::string msg = "Unsupported value type in NumPy array object.";
-			setValueError(msg,m_strict);
-#ifdef _DEBUG
-			cerr << "PyTypeConversions::PyArray_To_FloatVector failed. Error: " << msg << endl;
+        cerr << "PyTypeConversions::PyArray_To_FloatVector failed. Error: " << msg << endl;
 #endif			
-			return Output;
-	}
+        return v;
+    }
 }
 
 PyObject *
-PyTypeConversions::FloatVector_To_PyArray(const vector<float> &v) const
+PyTypeConversions::PyArray_From_FloatVector(const vector<float> &v) const
 {
-	npy_intp ndims[1];
-	ndims[0] = (int)v.size();
-	PyObject *arr = PyArray_SimpleNew(1, ndims, dtype_float32);
-	float *data = (float *)PyArray_DATA((PyArrayObject *)arr);
-	for (int i = 0; i < ndims[0]; ++i) {
-		data[i] = v[i];
-	}
-	return arr;
+    npy_intp ndims[1];
+    ndims[0] = (int)v.size();
+    PyObject *arr = PyArray_SimpleNew(1, ndims, NPY_FLOAT);
+    float *data = (float *)PyArray_DATA((PyArrayObject *)arr);
+    for (int i = 0; i < ndims[0]; ++i) {
+        data[i] = v[i];
+    }
+    return arr;
 }
 
 PyObject *
-PyTypeConversions::PyValue_From_StringVector(const std::vector<std::string> &v) const
+PyTypeConversions::PyValue_From_StringVector(const vector<string> &v) const
 {
-	PyObject *pyList = PyList_New(v.size());
-	for (size_t i = 0; i < v.size(); ++i) {
-		PyObject *pyStr = PyString_FromString(v[i].c_str());
-		PyList_SET_ITEM(pyList, i, pyStr);
-	}
-	return pyList;
+    PyObject *pyList = PyList_New(v.size());
+    for (size_t i = 0; i < v.size(); ++i) {
+        PyObject *pyStr = PyString_FromString(v[i].c_str());
+        PyList_SET_ITEM(pyList, i, pyStr);
+    }
+    return pyList;
 }
 
 
-/*			   			  	Error handling		   			  		*/
+/* Error handling */
 
 void
-PyTypeConversions::setValueError (std::string message, bool strict) const
+PyTypeConversions::setValueError (string message) const
 {
-	m_error = true;
-	m_errorQueue.push(ValueError(message,strict));
+    m_error = true;
+    m_errorQueue.push(ValueError(message));
 }
 
 /// return a reference to the last error or creates a new one.
 ValueError&
 PyTypeConversions::lastError() const 
 {
-	m_error = false;
-	if (!m_errorQueue.empty()) return m_errorQueue.back();
-	else {
-		m_errorQueue.push(ValueError("Type conversion error.",m_strict));
-		return m_errorQueue.back();
-	}
+    m_error = false;
+    if (!m_errorQueue.empty()) return m_errorQueue.back();
+    else {
+        m_errorQueue.push(ValueError("Type conversion error."));
+        return m_errorQueue.back();
+    }
 }
 
 /// helper function to iterate over the error message queue:
@@ -389,50 +216,49 @@
 ValueError 
 PyTypeConversions::getError() const
 {
-	if (!m_errorQueue.empty()) {
-		ValueError e = m_errorQueue.front();
-		m_errorQueue.pop();
-		if (m_errorQueue.empty()) m_error = false;
-		return e;
-	}
-	else {
-		m_error = false;
-		return ValueError();
-	}
+    if (!m_errorQueue.empty()) {
+        ValueError e = m_errorQueue.front();
+        m_errorQueue.pop();
+        if (m_errorQueue.empty()) m_error = false;
+        return e;
+    }
+    else {
+        m_error = false;
+        return ValueError();
+    }
 }
 
-/*			   			  	Utilities						  		*/
+/* Utilities */
 
 /// get the type name of an object
-std::string
+string
 PyTypeConversions::PyValue_Get_TypeName(PyObject* pyValue) const
 {
-	PyObject *pyType = PyObject_Type(pyValue);
-	if (!pyType) 
-	{
-		cerr << "Warning: Object type name could not be found." << endl;
-		if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
-		return std::string ("< unknown type >");
-	}
-	PyObject *pyString = PyObject_Str(pyType);
-	if (!pyString)
-	{
-		cerr << "Warning: Object type name could not be found." << endl;
-		if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
-		Py_CLEAR(pyType);
-		return std::string ("< unknown type >");
-	}
-	char *cstr = PyString_AS_STRING(pyString);
-	if (!cstr)
-	{
-		cerr << "Warning: Object type name could not be found." << endl;
-		if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
-		Py_DECREF(pyType);
-		Py_CLEAR(pyString);
-		return std::string("< unknown type >");
-	}
-	Py_DECREF(pyType);
-	Py_DECREF(pyString);
-	return std::string(cstr);
-	
+    PyObject *pyType = PyObject_Type(pyValue);
+    if (!pyType) 
+    {
+        cerr << "Warning: Object type name could not be found." << endl;
+        if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
+        return string ("< unknown type >");
+    }
+    PyObject *pyString = PyObject_Str(pyType);
+    if (!pyString)
+    {
+        cerr << "Warning: Object type name could not be found." << endl;
+        if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
+        Py_CLEAR(pyType);
+        return string ("< unknown type >");
+    }
+    char *cstr = PyString_AS_STRING(pyString);
+    if (!cstr)
+    {
+        cerr << "Warning: Object type name could not be found." << endl;
+        if (PyErr_Occurred()) {PyErr_Print(); PyErr_Clear();}
+        Py_DECREF(pyType);
+        Py_CLEAR(pyString);
+        return string("< unknown type >");
+    }
+    Py_DECREF(pyType);
+    Py_DECREF(pyString);
+    return string(cstr);
 }
--- a/PyTypeConversions.h	Wed Nov 26 10:01:04 2014 +0000
+++ b/PyTypeConversions.h	Wed Nov 26 10:54:48 2014 +0000
@@ -56,26 +56,15 @@
 #include <string>
 #include <sstream>
 #include <iostream>
-
-#ifdef HAVE_NUMPY
-enum eArrayDataType {
-    dtype_float32 = (int) NPY_FLOAT,
-    dtype_complex64 = (int) NPY_CFLOAT 
-};
-#endif 
-
-/* C++ mapping of PyNone Type */
-struct NoneType {};
 	
 // Data
 class ValueError
 {
 public:
     ValueError() {}
-    ValueError(std::string m, bool s) : message(m),strict(s) {}
+    ValueError(std::string m) : message(m) {}
     std::string location;
     std::string message;
-    bool strict;
     std::string str() const { 
         return (location.empty()) ? message : message + "\nLocation: " + location;}
     template<typename V> ValueError &operator<< (const V& v)
@@ -93,79 +82,57 @@
     PyTypeConversions();
     ~PyTypeConversions();
 
-	ValueError getError() const;
-    std::string PyValue_Get_TypeName(PyObject*) const;
-    float 	PyValue_To_Float(PyObject*) const;
+    ValueError getError() const;
 
-    // Sequence types
-    std::vector<std::string> PyValue_To_StringVector (PyObject*) const;
     std::vector<float> PyValue_To_FloatVector (PyObject*) const;
+    std::vector<float> PyArray_To_FloatVector (PyObject *) const;
     std::vector<float> PyList_To_FloatVector (PyObject*) const;
 
     PyObject *PyValue_From_StringVector(const std::vector<std::string> &) const;
-	
-    // Numpy types
-    std::vector<float> PyArray_To_FloatVector (PyObject *pyValue) const;
-    PyObject *FloatVector_To_PyArray(const std::vector<float> &) const; // Copying the data
+    PyObject *PyArray_From_FloatVector(const std::vector<float> &) const;
+
+private:
+    std::string PyValue_Get_TypeName(PyObject*) const;
+    float PyValue_To_Float(PyObject*) const;
 
     /// Convert DTYPE type 1D NumpyArray to std::vector<RET>
     template<typename RET, typename DTYPE>
-    std::vector<RET> PyArray_Convert(void* raw_data_ptr, long length, size_t strides) const
-    {
-        std::vector<RET> rValue;
+    std::vector<RET> PyArray_Convert(void* raw_data_ptr,
+                                     int length,
+                                     size_t strides) const {
+        
+        std::vector<RET> v(length);
 		
         /// check if the array is continuous, if not use strides info
-        if (sizeof(DTYPE)!=strides) {
+        if (sizeof(DTYPE) != strides) {
 #ifdef _DEBUG_VALUES
             cerr << "Warning: discontinuous numpy array. Strides: " << strides << " bytes. sizeof(dtype): " << sizeof(DTYPE) << endl;
 #endif
             char* data = (char*) raw_data_ptr;
-            for (long i = 0; i<length; ++i){
-                rValue.push_back((RET)(*((DTYPE*)data)));
-#ifdef _DEBUG_VALUES
-                cerr << "value: " << (RET)(*((DTYPE*)data)) << endl;
-#endif				
-                data+=strides;
+            for (int i = 0; i < length; ++i){
+                v[i] = (RET)(*((DTYPE*)data));
+                data += strides;
             }
-            return rValue;
+            return v;
         }
 
         DTYPE* data = (DTYPE*) raw_data_ptr;
-        for (long i = 0; i<length; ++i){
-#ifdef _DEBUG_VALUES
-            cerr << "value: " << (RET)data[i] << endl;
-#endif
-            rValue.push_back((RET)data[i]);
+        for (int i = 0; i < length; ++i){
+            v[i] = (RET)data[i];
         }
-        return rValue;
-    }
 
-    /// this is a special case. numpy.float64 has an array conversions but no array descriptor
-    std::vector<float> PyArray0D_Convert(PyArrayInterface *ai) const
-    {
-        std::vector<float> rValue;
-        if ((ai->typekind) == *"f") 
-            rValue.push_back((float)*(double*)(ai->data));
-        else { 
-            setValueError("Unsupported NumPy data type.",m_strict); 
-            return rValue;
-        }
-#ifdef _DEBUG_VALUES
-        cerr << "value: " << rValue[0] << endl;
-#endif
-        return rValue;
+        return v;
     }
 
 private:
-    bool m_strict;
     mutable bool m_error;
     mutable std::queue<ValueError> m_errorQueue;
 	
-    void setValueError(std::string,bool) const;
+    void setValueError(std::string) const;
     ValueError& lastError() const;
+    
 public:
     const bool& error;
-
 };
 
 #endif
--- a/vampyhost.cpp	Wed Nov 26 10:01:04 2014 +0000
+++ b/vampyhost.cpp	Wed Nov 26 10:54:48 2014 +0000
@@ -108,6 +108,8 @@
 
 PyDoc_STRVAR(xx_foo_doc, "Some description"); //!!!
 
+//!!! todo: conv errors
+
 PyPluginObject *
 getPluginObject(PyObject *pyPluginHandle)
 {
@@ -503,7 +505,7 @@
 
                 if (!f.values.empty()) {
                     PyDict_SetItemString
-                        (pyF, "values", conv.FloatVector_To_PyArray(f.values));
+                        (pyF, "values", conv.PyArray_From_FloatVector(f.values));
                 }
 
                 PyList_SET_ITEM(pyFl, fli, pyF);