Skip to content

Draft: Add an iterator over TTree

TTree is a bit antiquated and iterating over it requires plain old for loops. Implement an iterator so we can use range-based for loops.

This MR is highly experimental and is certainly not intended for merging before the hackaton. I'm not even sure it fits in Darwin.

Demo of what is currently possible:

auto tIn = GetInput(...);
auto weights = GetBranchReadOnly(...);

for (auto entry : tIn) {
    // Use branches as usual
    cout << weights->at(0) << endl;
}

// Find an event with negative weight
auto it = ranges::find_if(DT::TreeRange(tIn), [&] (auto) { return weights->at(0) < 0; });
*it; // Load the event (likely a no-op because `find_if` would already have loaded it)
// ... inspect it ...

// Largest weight?
auto getWeight = [&] (auto) { return weights->at(0); };
auto maxWeight = ranges::max(DT::TreeRange(tIn) | views::transform(getWeight));

It would of course be nice to return actual branch values from the loop, but this is left for future work. It would need some more thinking and a weird construct but might not be out of reach.

Looper functionality is not implemented by design. It can be recovered with something similar to this (or that). In general, it would be a nice for Looper to work with a range (=essentially begin/end iterators).

Note that this would break badly if ROOT ever introduced a similar interface. I would hide begin() and end() in a namespace that would be used, similar to std::placeholders. But since ROOT hasn't done so in 15 years of range-based for...

Edited by Louis Moureaux

Merge request reports