Skip to content

Instantly share code, notes, and snippets.

@jepio
Last active April 14, 2018 22:20
Show Gist options
  • Save jepio/4802f87164f20e266503 to your computer and use it in GitHub Desktop.
Save jepio/4802f87164f20e266503 to your computer and use it in GitHub Desktop.
Copy TGraph data to numpy array and back.
"""
Example of interfacing numpy to pyroot. Additionally, the great package
root_numpy implements interfaces between various pyroot objects and numpy
through a cython extension module.
"""
import numpy as np
import ROOT
data = ROOT.TGraph("filename")
# Create buffers
x_buff = data.GetX()
y_buff = data.GetY()
N = data.GetN()
x_buff.SetSize(N)
y_buff.SetSize(N)
# Create arrays from buffers, copy to prevent data loss
x_arr = np.array(x_buff,copy=True)
y_arr = np.array(y_buff,copy=True)
# Create TGraph from arrays
new_data = ROOT.TGraph(N, x_arr, y_arr)
@jepio
Copy link
Author

jepio commented Aug 13, 2014

This requires the memory to be contiguous (column-major order), so np.loadtxt for more than one column will not work (because data will be stored in row-major order). I also have trouble with using a different data type than float64 (double).

@mjkramer
Copy link

This solution segfaults for me on ROOT 6.05 and Numpy 1.14. Instead the following does the trick:

x_buff, N = mygraph.GetX(), mygraph.GetN()
x_buff.SetSize(N*8)
x_arr = np.array(np.frombuffer(x_buff, dtype=np.double))

There seems to be some inconsistency in the meaning of the buffer's "size". It apparently refers to the number of elements (i.e. doubles) for the purpose of, e.g., list(x_buff), but np.frombuffer interprets the "size" as the number of bytes. Go figure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment