I'm a beginning root user, and want to make TTrees for my next analysis
project. The project is a fairly simple one, so it's as good a time as
any to step away from ntuples. But after succeeding in making a TTree
with branches holding only simple variables, I am now stumped at how to
do the next more complex thing. I need to store events which have
*lists* of various (sparse) detector hits.
It is not obvious to me what the best way to do this is. For each event
I need to make at least two lists (collections) of items that have a few
variables such as what cell was hit, and how much energy. I have looked
at the example at http://root.cern.ch/root/html/examples/Event.C.html
but this approach seems unnecessarily complex for my needs. The first
thing I tried to do was make a class with a simple variable array in it,
and add the class to my tree. The member data was a pointer to the
array, and the number of elements. rootcint complained that it needed
help with the class since it used pointers, and I could see how there's
no way it would know (for example) what variable held the array length.
Next I tried making a class that defined hit properties, and added a
TObjArray (to hold instances of the class) to a branch. This compiled
after some effort, but gave me a segmentation fault upon execution. The
stack trace shows the fault occurring when the branch is defined.
...
TObjArray *ccaa = new TObjArray(50); // initial capacity of 50
...
tree->Branch("CCABitArray", "TObjArray", ccaa); // crashes here
...
I'm not sure what to do here. The objects I'm storing in the array are
proper subclasses of TObject, but that doesn't matter because I get the
same crash whether or not the TObjArray is empty when defining the branch.
I now see that I can add variable-length arrays to a tree, and maybe
that's the way to go. But I'm still curious what I did wrong with the
method above. The other alternative is to put the TObjArray into
another class, as in the tutorial example. But I don't see how this
will help the problem I ran into, and it doesn't really simplify the
project.
Any advice?
- Topher Cawlfield
p.s.
I was honestly very disappointed with TTrees and how they handle data
like this. Common tasks should be easy, and events contaning
variable-length lists of things are the norm for any analysis in
particle physics. The analysis package that I'm most familliar with is
an ancient, home-brew Fortran beast that at least had the advantage of
making certain common tasks easy. Its "ntuple"-equivalent had a
two-level structure with "global" quantities and "combination"
quantities. Typically global quantities were reserved for events, and
combination quantities for decay candidates. Or, globals could be a
fit, and combinations might loop over fit parameters. Another
successful use was to have globals refer to decay candidates and
combination quantities run over each track in the candidate.
I'm describing all this to make two observations. First, this built-in
two-level structure was fantastically useful. Second, it was also very
limiting and forced one to make clever, arbitrary decisions for any
analysis. So naturally, when thinking about how I would reinvent an
analysis package if given the opportunity, I decided that a tree-like
structure would be best. The trunk of the tree would contain quantities
corresponding to the "global" quantities of the old program, perhaps
describing general event properties such as the number of tracks, total
energy, etc. Then any number of branches could be added and implicitly
looped over. One branch could hold decay candidates, and a sub-branch
might hold track-by-track information.
So, when I began to see the term TTree in the root guide, I got *very*
excited and rejoiced that someone else was thinking the same way, and
finally got it "right!" I gradually learned that my initial assumptions
were all wrong, and that TTrees are just a structure used to minimize
computing time and don't really make an analysis any easier. And now
I'm learning that even a simple two-level event structure is a major
headache to implement, and will require special code just to histogram
simple variables (Draw won't work on elements of a variable-length list,
will it?). What a let-down!
So I'm now trying to think constructively. Maybe what's needed is a way
to have multiple trees, and be able to link "instances" (one "instance"
per call to Fill()) of one tree to instances of another in a one-to-many
fasion. The nested loops that would normally be required would then be
handled automatically through recursion, or not be needed at all. Well,
this is still a vague idea, but I thought I'd throw it out and see if
anyone else has been thinking along these lines or likes the idea.
Imagine building TTrees where you have a general event information
tree, a track list tree, track combination tree, and decay candidate
tree, all interlinked.
This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:10 MET