Wrap TProfile (was TProfile list conversion - infinite loop) #56

Closed
kreczko opened this Issue Nov 8, 2012 · 13 comments

Projects

None yet

4 participants

@kreczko
Contributor
kreczko commented Nov 8, 2012

Hi,

Today a college of mine encountered an interesting problem. He tried to convert a TProfile to a rootpy hist to a python list. The error shows itself in an infinite amount of the following lines:

"Error in TArrayD::operator[]: index 102 out of bounds (size: 102, this: 0x2bb9dd8)"

with increasing index.

Example code (taken from ROOT TProfile):

from rootpy.utils import asrootpy
from ROOT import TProfile
from ROOT import gRandom
import ROOT

hprof = TProfile("hprof","Profile of pz versus px",100,-4,4,0,20)

px, py, pz = 0,0,0

px = ROOT.Double(0)
py = ROOT.Double(0)
pz = ROOT.Double(0)
for i in range (25000):
gRandom.Rannor(px,py)
pz = px_px + py_py
hprof.Fill(px, pz, 1)

h_rootpy = asrootpy(hprof)
print list(h_rootpy)

This code, if output is redirected into a file, produces error messages worth a hundred MB every few seconds. In general the prompt becomes non-responsive.

@ndawe
Member
ndawe commented Nov 8, 2012

TProfile is not wrapped in rootpy yet so asrootpy does nothing and simply returns the original TProfile. What you are seeing is simply PyROOT trying to go beyond the end of the internal profile array. We can fix this in a properly wrapped TProfile in rootpy.

@cdeil
Member
cdeil commented Nov 8, 2012

Ahh, I'm typing too slow, anyways here's some details why trying to create a list for a ROOT.TProfile fails:

In [11]: h_rootpy = asrootpy(hprof)

In [12]: h_rootpy
Out[12]: <ROOT.TProfile object ("hprof") at 0x7fd254316600>

In [13]: h_rootpy[1]
Out[13]: 0.0

In [14]: h_rootpy[100000]
Error in <TArrayD::operator[]>: index 100000 out of bounds (size: 102, this: 0x7fd2543169b8)
Out[14]: 0.0

In [15]: len(h_rootpy)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-c34c1c2fcdc3> in <module>()
----> 1 len(h_rootpy)

TypeError: object of type 'TProfile' has no len()
@ndawe
Member
ndawe commented Nov 8, 2012

Exactly. Thanks @cdeil

@kreczko
Contributor
kreczko commented Nov 8, 2012

Thank you for the explanation. Can this be converted into a feature request?
I guess there are many classes which don't have a wrapper at the moment and obviously doesn't make sense to support them all. Do you have a list of planned wrappers?
Maybe this is something I could contribute.

@ndawe
Member
ndawe commented Nov 8, 2012

No list of planned wrappers at the moment. Essentially all useful non-redundant ROOT classes could be subclassed in rootpy. TProfile, TProfile2D and TProfile3D should be subclassed in rootpy.plotting.hist. You're welcome to submit a pull request!

@ndawe
Member
ndawe commented Nov 8, 2012

In rootpy they should be named Profile, Profile2D, and Profile3D and could probably be subclasses of _Hist, _Hist2D and _Hist3D. Will require some careful thought here...

@kreczko
Contributor
kreczko commented Nov 8, 2012

OK, I will have some time next Tuesday (maybe on the weekend) and will try to get my head around your wrappers.

@cdeil
Member
cdeil commented Nov 8, 2012

It would be nice to find some way to have a list of wrapped ROOT classes in the asrootpy docstring and maybe even issue a warning if called on some ROOT object that isn't wrapped?
I'm not sure is this is possible without maintaining this list by hand (which wouldn't be too bad either).

@ndawe
Member
ndawe commented Nov 8, 2012

@cdeil good point. I'm working on a PR right now that reimplements the registry system. All wrapped classes are listed in the main __init__ as strings. I'll post a "work in progress" PR now.

@pwaller
Member
pwaller commented Feb 21, 2013

@ndawe status?

@ndawe
Member
ndawe commented Feb 21, 2013

Profile, Profile2D, and Profile3D are now included with #190 😄

@ndawe
Member
ndawe commented Feb 22, 2013

@kreczko once #190 is merged your code will work as follows:

from rootpy import asrootpy
from rootpy.plotting import Profile
from ROOT import gRandom, Double

#hprof = Profile(100,-4,4,0,20, name='hprof', title='Profile of pz versus px')
hprof = Profile(100,-4,4,0,20)

px = Double(0)
py = Double(0)
pz = Double(0)
for i in range (25000):
    gRandom.Rannor(px,py)
    pz = px*px + py*py
    hprof.Fill(px, pz, 1)

print list(hprof)
@ndawe
Member
ndawe commented Feb 22, 2013

@pwaller we can close this issue once #190 is merged.

@pwaller pwaller closed this Feb 22, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment