I have a root file with a tree, branches and leaves, like this:
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