1

I have trouble loading y-values from a TProfile object from my .root file.

It seems using file.pandas() loads only the x-values, the counts and variances but not the specific y-values.

I have tried file.values also, which returns counts, but not y-values

2 Answers2

0

Objects read from ROOT files have a Pythonic interpretation only if "methods" have been included in uproot-methods. TProfile has not been handled in this way—the only reason anything works for you is because TProfile is a subclass of TH1, and TH1 has a .pandas() method. Since TH1 is for one-dimensional histograms, it doesn't include code that would handle a second dimension.

uproot-methods is user contributed. If you want TProfile methods, you can add one here and submit a pull request:

https://github.com/scikit-hep/uproot-methods/tree/master/uproot_methods/classes

If you add a TProfile module containing a Methods class here, uproot will automatically load it and apply it to the TProfile objects it loads from ROOT files.

For any class, even those we haven't heard of, uproot loads all of the private member data into a Python object. You'll find all of your TProfile data in attributes that start with _f, such as _fSumw2 and _fBinEntries. The methods just use these "internal" attributes to present a more user-friendly picture of the data, such as Pandas.

Here's an example of getting data from an uninterpreted TProfile:

>>> import numpy
>>> import uproot
>>> 
>>> file = uproot.open("http://scikit-hep.org/uproot/examples/hepdata-example.root")
>>> hprof = file["hprof"]
>>> 
>>> numpy.sqrt(numpy.array(hprof._fSumw2) / numpy.array(hprof._fBinEntries))

will print

-c:1: RuntimeWarning: invalid value encountered in true_divide
array([18.00160401, 17.08522023, 16.98982401, 15.18948269, 13.73788834,
       13.37976188, 13.55597897, 12.66036748, 12.68400763, 11.86598111,
       11.69668773, 11.64276616, 10.08540753, 10.15367219,  9.76541727,
        8.84047502,  8.73065944,  8.24346727,  7.46907584,  7.6620407 ,
        7.09749961,  6.62763951,  6.42199904,  5.98234406,  5.78193984,
        5.14476043,  5.15432392,  4.715674  ,  4.50246509,  4.36212988,
        3.86741244,  3.80635409,  3.60625837,  3.29332404,  3.04594764,
        2.98292569,  2.74283755,  2.50385849,  2.50978034,  2.30446027,
        2.29145554,  2.18459822,  1.99270465,  1.92651016,  1.86253428,
        1.79821825,  1.807856  ,  1.80803939,  1.75249321,  1.81588997,
        1.8226282 ,  1.74867267,  1.79842962,  1.75790778,  1.70895758,
        1.859834  ,  1.82793384,  1.96163584,  1.81903189,  2.0223054 ,
        2.14521968,  2.24565426,  2.24184203,  2.48460961,  2.63208939,
        2.69851588,  2.98989799,  3.1141892 ,  3.25304525,  3.46517157,
        3.53320406,  3.98586013,  4.25062225,  4.57520817,  4.75338005,
        5.18494724,  5.387066  ,  5.6277353 ,  5.8802666 ,  6.34427442,
        6.51966721,  7.24680462,  7.33759813,  7.63198011,  8.34535604,
        9.30064575,  8.82698396,  9.4099613 ,  9.60905376, 10.31570735,
       11.17540473, 11.13947421, 12.78232904, 12.1993165 , 12.39763587,
       16.68535354, 13.30451531, 14.67711301, 14.96741772,         nan,
       18.32199478, 17.84275258])

which are the y-values for this TProfile. The errors on those values are left as an exercise for the reader.

Jim Pivarski
  • 5,568
  • 2
  • 35
  • 47
0

The TProfile y-values (h) and default errors (err) can be reconstructed using the private member data according to

import numpy
import uproot 

file = uproot.open("somefile_w_TProfile.root")
hprof = file['hprof_title']

cont = numpy.array(hprof.values)
sumw = numpy.array(hprof._fBinEntries)[1:-1]
err2 = numpy.array(hprof._fSumw2)[1:-1]

h = cont/sumw
s = numpy.sqrt(err2/sumw - h**2)
err = s/numpy.sqrt(sumw)

N.B. The C++ TProfile member .fArray is called .values in the uproot TProfile object.

gsbowers
  • 1
  • 1