which version of ROOT are you using? For older versions, there was a reliance on the datamember ‘typecode’ (as per the python array module) to find the type of the array elements if it could not be inferred from the buffer interface. This has since been improved.
There may be workarounds possible for older versions, but then I’d need to know the one your using …
just checked … 5.18 works for me (for my previous posting I used CVS HEAD). If it doesn’t work for you, can you post a script that I can run for testing?
Cheers,
Wim
[code]>>> import numpy
a = numpy.ndarray( [5.] )
for i in range(len(a)):
… a[i] = i
…
from ROOT import TGraph
b = TGraph( 4, a, a )
b
<ROOT.TGraph object (“Graph”) at 0x88dcb38>
b.Draw() TCanvas::MakeDefCanvas: created default TCanvas with name c1
[/code]
I tried your snippet of code, and it seems to work, but my code still has the same behaviour ! I even printed the version of ROOT to be sure. The data I have is quite big, so I saved the result in two files (I don’t yet know how to “pickle” two objects in the same file). They are attached.
Then I did
import numpy
import pickle
f = file(‘startTime.txt’)
st = pickle.load(f)
f.close()
f = file(‘numTemplates.txt’)
numt = pickle.load(f)
from ROOT import TGraph
gr = TGraph(374,st,numt)
I think I’ve found what is going on. Trying to see what was the difference between the two files I gave above, I noticed there was a string
(S’i4’
in one of them, while it was
(S’f8’
in the other. So I guess that one of the arrays was an array of ints and the other an array of floats. Which is obviously a problem for ROOT to handle.
Maybe the error message is misleading and could be changed ?
yes, that is the problem (check type(numt[0]). You can do something like numt.astype(‘float’) to get an array with the correct type.
I’ve changed to error message to:could not convert argument 3 ('numpy.ndarray' object has no attribute 'typecode' and given element size (4) does not match needed (8))
(the match would be on double*, double*, so required element size is 8 (i.e. sizeof(double), given is 4 (that is, sizeof(int) ). Note that with a bad type, b/c of the trial of element size (which is calculated from buflenth/nelem), you could end up with a bad match for e.g. float* and int* when sizeof(float) == sizeof(int).
I have a problem similar to the one posted above. The difference is that I have a numpy array containing float32 data which is read from an external library (which i would prefer not to change). When i try the above code snippet, everything works fine, but the numpy array a is containing float64 data. If i change the snippet to force the numpy array to contain float32 data:
In[8]: import numpy
In[9]: a = numpy.ndarray( [5.],dtype=numpy.float32)
In [10]: for i in range(len(a)):
a[i]=i
…:
In [12]: b = TGraph( 4, a, a )
In [13]: b.Draw(“AL”)
I don’t get any error message, but the absolute scale on the plot is messed up. My guess is that, the resolution of the overloaded TGraph constructor doesn’t work properly, and the data is read using Double_t pointers, or something alike.
Does anyone know a way around this?
edit: as a workaround I’m now using: a = numpy.asarray(a,dtype=numpy.float64) to copy the array to float64.