Reputation: 621
See the code here: https://github.com/rootpy/root_numpy/blob/master/root_numpy/src/tree.pyx#L228
cdef cppclass VectorConverter[T](VectorConverterBase):
int elesize
int nptypecode
Vector2Array[T] v2a
__init__():
cdef TypeName[T] ast = TypeName[T]()
info = TYPES[ast.name]
this.elesize = info[1].itemsize
this.nptypecode = info[2]
int write(Column* col, void* buffer):
cdef vector[T]* tmp = <vector[T]*> col.GetValuePointer()
cdef unsigned long numele = tmp.size()
# check cython auto generate code
# if it really does &((*tmp)[0])
cdef T* fa = this.v2a.convert(tmp)
return create_numpyarray(buffer, fa, this.nptypecode, numele, this.elesize)
Basically - this code is mean to convert a vector <object>
(usually float or int) into an array [in particular, a NumPy array]. I have a hard time understanding it, but I digress.
I need to potentially extend it so that there's something that can implement vector<vector <object>>
as well. I think it should be, pretty much, a copy of the code I highlighted in said link.
Where do I start?
Upvotes: 1
Views: 1251
Reputation: 621
I've solved this, and since I'm not DenverCoder9, here's how I did it, if it helps someone in the future even, obsoletely
cdef cppclass VectorVectorConverter[T](VectorConverterBase):
int elesize
int nptypecode
Vector2Array[T] v2a
__init__():
cdef TypeName[T] ast = TypeName[T]()
info = TYPES[ast.name]
this.elesize = info[1].itemsize
this.nptypecode = info[2]
int write(Column* col, void* buffer):
cdef vector[vector[T]]* tmp = <vector[vector[T]]*> col.GetValuePointer()
#this will hold number of subvectors
cdef unsigned long numele
cdef T* fa
#these are defined solely for the outer array wrapper
cdef int objsize = np.dtype('O').itemsize
cdef int objtypecode = np.NPY_OBJECT
# it seems *tmp is exposed via tmp[0]
# we want to create an outer array container that dataptr points to, containing pointers
# from create_numpyarray()
numele = tmp[0].size()
#define an (numele)-dimensional outer array to hold our subvectors fa
cdef np.npy_intp dims[1]
dims[0] = numele
cdef np.ndarray outer = np.PyArray_EMPTY(1, dims, objtypecode, 0)
cdef PyObject* outerobj = <PyObject*> outer # borrow ref
# increase one since we are putting in buffer directly
Py_INCREF(outer)
# now write PyObject* to buffer
memcpy(buffer, &outerobj, sizeof(PyObject*))
# build a dataptr pointing to outer, so we can shift and write each of the subvectors
cdef char* dataptr = <char*> outer.data
# loop through all subvectors
for i in xrange(numele):
fa = this.v2a.convert(&tmp[0][i])
# for some reason, shift isn't working, so we're directly shifting it ourselves
#dataptr = shift(&dataptr, objsize)
create_numpyarray(&dataptr[i*objsize], fa, this.nptypecode, tmp[0][i].size(), this.elesize)
return sizeof(outerobj)
Upvotes: 4