Reading ROOT file with Branches

I have a root file with a tree, branches and leaves, like this:
image

When I try to read it like using UnROOT like this:

using UnROOT
f = ROOTFile("out_files/pienu00000-00.root")

tree = LazyTree(f,"sim")

I get a bounds error:

ERROR: BoundsError: attempt to access 7-element Vector{Any} at index [-1]
Stacktrace:
  [1] getindex(A::Vector{Any}, i1::Int64)
    @ Base ./essentials.jl:13
  [2] streamerfor(f::ROOTFile, branch::UnROOT.TBranchElement_10)
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/root.jl:160
  [3] UnROOT.JaggType(f::ROOTFile, branch::UnROOT.TBranchElement_10, leaf::UnROOT.TLeafElement)
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/utils.jl:64
  [4] auto_T_JaggT(f::ROOTFile, branch::UnROOT.TBranchElement_10; customstructs::Dict{String, Type})
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/root.jl:365
  [5] auto_T_JaggT
    @ ~/.julia/packages/UnROOT/PnXmk/src/root.jl:360 [inlined]
  [6] LazyBranch(f::ROOTFile, b::UnROOT.TBranchElement_10)
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:117
  [7] LazyBranch(f::ROOTFile, s::String)
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:134
  [8] LazyTree(f::ROOTFile, tree::UnROOT.TTree, treepath::String, branches::Vector{String}; sink::Type{LazyTree})
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:450
  [9] LazyTree
    @ ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:432 [inlined]
 [10] LazyTree(f::ROOTFile, s::String, branches::Vector{String}; kwargs::@Kwargs{})
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:393
 [11] LazyTree(f::ROOTFile, s::String, branches::Vector{String})
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:390
 [12] LazyTree(f::ROOTFile, s::String; kwargs::@Kwargs{})
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:461
 [13] LazyTree(f::ROOTFile, s::String)
    @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:460
 [14] top-level scope
    @ /popos/home/caspar/Documents-old/code/semesterprojekt-pioneer/analysis/analyze.jl:4

However reading root files that do not have branches works just fine.

This is how the file looks like within unroot:

julia> f
ROOTFile with 2 entries and 27 streamers.
out_files/pienu00000-00.root
โ”œโ”€ sim (TTree)
โ”‚  โ”œโ”€ "info"
โ”‚  โ”œโ”€ "init"
โ”‚  โ”œโ”€ "track"
โ”‚  โ”œโ”€ "decay"
โ”‚  โ”œโ”€ "ghost"
โ”‚  โ”œโ”€ "ghostface"
โ”‚  โ””โ”€ "upstream"
โ””โ”€ PIMCRunHeader (PIMCRunHeader)

In C I can read it by branch.leaf:

    events = (TTree*)fp->Get("sim");
    unsigned int nEvents = events -> GetEntriesFast();
    int pions = events -> GetEntries("ghost.pdgid==211");

So I also tried using
tree = LazyTree(f,"sim", "ghost.pdgid")

But I get another error:

ERROR: MethodError: no method matching LazyBranch(::ROOTFile, ::Missing)

Closest candidates are:
  LazyBranch(::ROOTFile, ::Union{UnROOT.TBranch, UnROOT.TBranchElement})
   @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:116
  LazyBranch(::ROOTFile, ::AbstractString)
   @ UnROOT ~/.julia/packages/UnROOT/PnXmk/src/iteration.jl:134

While it works fine when having a flat root file:

f = ROOTFile("data/data.root")
tree = LazyTree(f,"events","NJet")

Method where the error occurs

The error occurs here:

streamerfor(f::ROOTFile, branch::TBranch) = missing
function streamerfor(f::ROOTFile, branch::TBranchElement)
    fID = branch.fID
    # According to ChatGPt: When fID is equal to -1, it means that the
    # TBranch object has not been registered yet in the TTree's list of
    # branches. This can happen, for example, when a TBranch object has been
    # created, but has not been added to a TTree with the TTree::Branch()
    # method.
    #
    # TODO: For now, we force it to be 0 in this case, until someone complains.
    if fID == -1
        fID = 0
    end
    next_streamer = streamerfor(f, branch.fClassName)
    if ismissing(next_streamer)
        return missing
    else
        return next_streamer.streamer.fElements.elements[fID + 1]  # one-based indexing in Julia
    end
end

Which is located at ~/.julia/dev/UnROOT/src/root.jl

That part of the ROOT specification is a bit unclear as you can see from my comments :wink: Iโ€™ll follow up in the git issue you created Reading a file with Branches and Leafs ยท Issue #323 ยท JuliaHEP/UnROOT.jl ยท GitHub

1 Like

For the sake of completeness, there was a bug in UnROOT.jl which is now fixed (in v0.10.26) and the other issue was that the full path to the branch is a little bit different (that probably needs a better documentation, itโ€™s not the first time that people are confused).

Long story short, here is the happy end, with some fancy regex to read multiple sub-branches and return a lazy table-like instance:

julia> using UnROOT

julia> f = ROOTFile("test/samples/issue323.root")
ROOTFile with 2 entries and 27 streamers.
test/samples/issue323.root
โ”œโ”€ sim (TTree)
โ”‚  โ”œโ”€ "info"
โ”‚  โ”œโ”€ "init"
โ”‚  โ”œโ”€ "track"
โ”‚  โ”œโ”€ "decay"
โ”‚  โ”œโ”€ "ghost"
โ”‚  โ”œโ”€ "ghostface"
โ”‚  โ””โ”€ "upstream"
โ””โ”€ PIMCRunHeader (PIMCRunHeader)


julia> t = LazyTree(f, "sim", [r"ghost/ghost\.(.*)" => s"\1"])
 Row โ”‚ ypos             ghostID          time             stepID           fUniqueID        xmom             pd โ‹ฏ
     โ”‚ SubArray{Float3  SubArray{Int32,  SubArray{Float3  SubArray{Int32,  SubArray{UInt32  SubArray{Float3  Su โ‹ฏ
โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
 1   โ”‚ [982.0, 6.83]    [110000, 11000   [3230.0, 36.4]   [0, 0]           [0, 0]           [-25.6, -29.5]   [- โ‹ฏ
 2   โ”‚ [2590.0]         [110000]         [29.7]           [0]              [0]              [21.9]           [1 โ‹ฏ
 3   โ”‚ [258.0, -2230.   [110000, 11000   [774.0, 48.0]    [0, 0]           [0, 0]           [-44.3, 22.1]    [- โ‹ฏ
 4   โ”‚ [-1850.0]        [110000]         [60.6]           [0]              [0]              [14.1]           [1 โ‹ฏ
 5   โ”‚ []               []               []               []               []               []               [] โ‹ฏ
 6   โ”‚ [512.0]          [110000]         [587.0]          [0]              [0]              [-11.5]          [- โ‹ฏ
 7   โ”‚ [-11.0]          [110000]         [40.8]           [0]              [0]              [-2.61]          [2 โ‹ฏ
 8   โ”‚ [2890.0]         [110000]         [28.7]           [0]              [0]              [-8.56]          [1 โ‹ฏ
 9   โ”‚ []               []               []               []               []               []               [] โ‹ฏ
 10  โ”‚ [28.1]           [110000]         [41.0]           [0]              [0]              [-0.453]         [2 โ‹ฏ
 11  โ”‚ [2660.0]         [110000]         [799.0]          [0]              [0]              [-4.84]          [- โ‹ฏ
 12  โ”‚ [12.0]           [110000]         [41.0]           [0]              [0]              [2.28]           [2 โ‹ฏ
 13  โ”‚ [33.0]           [110000]         [41.8]           [0]              [0]              [-4.04]          [2 โ‹ฏ
 14  โ”‚ [-0.84]          [110000]         [40.5]           [0]              [0]              [-5.09]          [2 โ‹ฏ
 15  โ”‚ [664.0]          [110000]         [311.0]          [0]              [0]              [-3.08]          [1 โ‹ฏ
 16  โ”‚ []               []               []               []               []               []               [] โ‹ฏ
 17  โ”‚ [-1220.0]        [110000]         [640.0]          [0]              [0]              [7.4]            [1 โ‹ฏ
 18  โ”‚ [-2290.0, -269   [110000, 11000   [1410.0, 1410.   [0, 0, 0]        [0, 0, 0]        [0.0214, 0.01,   [2 โ‹ฏ
 19  โ”‚ [906.0]          [110000]         [8140.0]         [0]              [0]              [41.8]           [- โ‹ฏ
 20  โ”‚ [3430.0]         [110000]         [4960.0]         [0]              [0]              [-13.3]          [- โ‹ฏ
 21  โ”‚ []               []               []               []               []               []               [] โ‹ฏ
 22  โ”‚ [5.71]           [110000]         [41.0]           [0]              [0]              [6.6]            [2 โ‹ฏ
 23  โ”‚ []               []               []               []               []               []               [] โ‹ฏ
 24  โ”‚ [1330.0]         [110000]         [1250.0]         [0]              [0]              [-24.4]          [1 โ‹ฏ
 25  โ”‚ [-1050.0]        [110000]         [23.5]           [0]              [0]              [10.1]           [1 โ‹ฏ
 26  โ”‚ [-280.0, -2400   [110000, 11000   [1150.0, 39.1]   [0, 0]           [0, 0]           [0.412, -13.6]   [2 โ‹ฏ
 27  โ”‚ []               []               []               []               []               []               [] โ‹ฏ
 28  โ”‚ [-12.8]          [110000]         [1150.0]         [0]              [0]              [10.7]           [- โ‹ฏ
 29  โ”‚ [2770.0, 2080.   [110000, 11000   [1610.0, 20.5]   [0, 0]           [0, 0]           [20.8, -15.4]    [- โ‹ฏ
 30  โ”‚ [262.0, -866.0   [110000, 11000   [36.3, 35.7]     [0, 0]           [0, 0]           [-17.5, 5.21]    [1 โ‹ฏ
 31  โ”‚ []               []               []               []               []               []               [] โ‹ฏ
  โ‹ฎ  โ”‚        โ‹ฎ                โ‹ฎ                โ‹ฎ                โ‹ฎ                โ‹ฎ                โ‹ฎ            โ‹ฑ
                                                                                  7 columns and 1169 rows omitted


julia> t.time[23:42]
20-element Vector{Vector{Float32}}:
 []
 [1248.5364]
 [23.53635]
 [1154.8237, 39.09293]
 []
 [1154.2357]
 [1608.5714, 20.453718]
 [36.331398, 35.730732]
 []
 [2756.7627]
 [4619.069, 41.54856]
 [618.69916, 51.805447]
 []
 [2412.702]
 [2667.897, 2671.2146]
 [41.457493, 86.87225]
 [2779.9707]
 [2550.0178]
 [3598.2415, 30.367851]
 [2836.5977, 38.199326]

julia>
1 Like

Thank you so much! :smiley:

1 Like