Arrays from ROOT C and unsigned char

Hello,

In my PyROOT program I am reading a large array from a TTree into a numpy array to perform some operations on it. The reading of the array in pure compiled ROOT it at least 10 time faster then in PyROOT, so I decided to try to read the array in ROOT script called from PyROOT and use it afterwards with numpy.

  1. I understand that multidimensional C arrays are not well supported on PyROOT, so basically in the C script I need to flatten the array and return it flattened.

  2. My array is unsigned char. It seems that this type is not returned properly, while unsigned int is. Here is a code snippet:

#include "TFile.h"
#include "TTree.h"
#include <iostream>

unsigned int *test_speed()
{

unsigned int *a = new unsigned int[5];
a[0]=1;
a[1] = 5;
a[2] = 2;
a[3] = 4;

cout << (int)a[3] << endl;

return a;

}

and the calling python code:

import ROOT
import numpy as np

ROOT.gROOT.LoadMacro("test_speed.c+")

print "a"
u = ROOT.test_speed()
print u
b = np.frombuffer(u, np.uint32, 5)
print b

In the above example everything is OK, but when I change all the unsigned ints to unsigned chars, the return from the ROOT.test_speed() is None. Am I doing something wrong?

Hi,

We currently don’t have any maintainer of PyROOT; this is expected to get fixed at some point. We will debug this at some point ourselves. Until then maybe the PyROOT community can help?

Cheers, Axel.

I see. I was not aware of that.

Executor for “unsigned char*” non-existent:RuntimeWarning: creating executor for unknown type "unsigned char*"Still returns void*, not None. Can use that: address is same.

-Dom

I forgot to mention that my ROOT version is 5.34.32. Maybe that is why it is None…

Oui; for 5:return type not handled (using void): unsigned char*‘void’ executor return None.

Can still cast void* in C++; file toto.h:void *test_speed() { unsigned char *a = new unsigned char[5]; a[0]=1; a[1] = 5; a[2] = 2; a[3] = 4; return (void*)a; }
and use with fix-up:[code]import ROOT
ROOT.gROOT.LoadMacro(“toto.h+”)

a = ROOT.test_speed()
a.SetSize(5)

import numpy as np
b = np.frombuffer(a, np.ubyte)[/code]
-Dom

Ahh, OK. I understood that it returns void by itself, not that I have to cast it. Thanks!