ROOT buffers and Numpy

[quote=“jfcaron”]This question has been posed many times, and I found several solutions to the problem of converting ROOT buffers (like returned from a TGraph.GetY()) into a usable Numpy array. Could an expert chime in regarding the differences between the following three ways of proceeding? Are they completely equivalent, or is there some subtle difference?

In the code examples tgraph is a TGraph filled with Double_t values, so that tgraph.GetY() returns a “<read-write buffer ptr 0x… >” object.

y_buff = tgraph.GetY() N = tgraph.GetN() y_arr = numpy.frombuffer(y_buff,count=N)

y_buff = tgraph.GetY() N = tgraph.GetN() y_arr = numpy.ndarray(N,'d',y_buff)

y_buff = tgraph.GetY() N = tgraph.GetN() y_buff.SetSize(N) yarr = numpy.array(y_buff,copy=True)

I tried using the first two for my purposes, but I found inconsistent behavior (worked some of the time, mostly with hand-typed example rather than in scripts), only the third way works consistently for me.

Edit: relevant old posts:

[url=http://sqlfury.com]Problem reading from buffer with numpy
https://root-forum.cern.ch/t/convert-of-root-double-t-buffer-to-list-numpy/14451/1[/quote]

The format of these values is Left channel MSB, LSB, Right channel MSB, LSB, … and so on. So, to convert this into a numpy array, here’s my function:

def bufToNumpy( inBuf ):
bufLength = len(inBuf)
outBuf = np.zeros(bufLength/2)
for i in range(bufLength/2):
outBuf[i] = struct.unpack('h', inBuf[2*i] + inBuf[2*i+1])[0]
return outBuf