Skip to content

Reading a file with Branches and Leafs #323

@TheFibonacciEffect

Description

@TheFibonacciEffect

I originally posted this on the julia discourse https://discourse.julialang.org/t/reading-root-file-with-branches/112014. However I believe this might actually be a bug in the package so I am posting my issue here as well.

Here is a link to the file I would like to read:
https://polybox.ethz.ch/index.php/s/1aNZCiDSO1f2Eig

Original Post on julia Discourse

This is what I had originaly posted on the julia discourse

I have a root file with a tree, branches and leaves:
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, from my understanding I have a branch with branch.fID < -1

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions