|
16 | 16 | #include "ROOT/RDF/RSampleInfo.hxx" |
17 | 17 | #include "ROOT/RDF/Utils.hxx" |
18 | 18 | #include "ROOT/RLogger.hxx" |
| 19 | +#include "ROOT/RTTreeDS.hxx" |
19 | 20 | #include "RtypesCore.h" |
20 | 21 | #include "TBranch.h" |
21 | 22 | #include "TBranchElement.h" |
| 23 | +#include <TChain.h> |
| 24 | +#include "TChainElement.h" |
22 | 25 | #include "TClass.h" |
23 | 26 | #include "TClassEdit.h" |
24 | 27 | #include "TClassRef.h" |
25 | 28 | #include "TError.h" // Info |
| 29 | +#include "TFile.h" |
26 | 30 | #include "TInterpreter.h" |
27 | 31 | #include "TLeaf.h" |
28 | 32 | #include "TROOT.h" // IsImplicitMTEnabled, GetThreadPoolSize |
@@ -632,9 +636,69 @@ ROOT::RDF::Experimental::RDatasetSpec RetrieveSpecFromJson(const std::string &js |
632 | 636 | return spec; |
633 | 637 | }; |
634 | 638 |
|
635 | | -} // end NS RDF |
636 | | -} // end NS Internal |
637 | | -} // end NS ROOT |
| 639 | +std::vector<std::pair<ULong64_t, ULong64_t>> GetClusterRanges(ROOT::Detail::RDF::RLoopManager &lm) |
| 640 | +{ |
| 641 | + std::vector<std::pair<ULong64_t, ULong64_t>> ranges{}; |
| 642 | + |
| 643 | + auto *ds = lm.GetDataSource(); |
| 644 | + if (!ds) { |
| 645 | + throw std::runtime_error("Cannot retrieve cluster ranges, no data source available"); |
| 646 | + } |
| 647 | + |
| 648 | + auto *ttreeds = dynamic_cast<RTTreeDS *>(ds); |
| 649 | + if (!ttreeds) { |
| 650 | + throw std::runtime_error("Cannot retrieve cluster ranges, data source is not a TTree"); |
| 651 | + } |
| 652 | + |
| 653 | + TTree *tree = ttreeds->GetTree(); |
| 654 | + if (!tree) { |
| 655 | + return ranges; |
| 656 | + } |
| 657 | + |
| 658 | + // Collect cluster boundaries from a single tree applying a global offset |
| 659 | + auto collectClusters = [&ranges](TTree *t, Long64_t offset) -> Long64_t { |
| 660 | + const Long64_t nEntries = t->GetEntries(); |
| 661 | + auto it = t->GetClusterIterator(0); |
| 662 | + Long64_t start = 0; |
| 663 | + while ((start = it()) < nEntries) |
| 664 | + ranges.emplace_back(offset + start, offset + it.GetNextEntry()); |
| 665 | + return nEntries; |
| 666 | + }; |
| 667 | + |
| 668 | + if (auto *chain = dynamic_cast<TChain *>(tree)) { |
| 669 | + // If TChain, open each file and iterate over its clusters |
| 670 | + TObjArray *files = chain->GetListOfFiles(); |
| 671 | + if (!files) { |
| 672 | + return ranges; |
| 673 | + } |
| 674 | + |
| 675 | + Long64_t offset = 0; |
| 676 | + for (int i = 0; i < files->GetEntries(); ++i) { |
| 677 | + auto *el = static_cast<TChainElement *>(files->At(i)); |
| 678 | + if (!el) { |
| 679 | + continue; |
| 680 | + } |
| 681 | + std::unique_ptr<TFile> f{TFile::Open(el->GetTitle(), "READ")}; |
| 682 | + if (!f || f->IsZombie()) { |
| 683 | + continue; |
| 684 | + } |
| 685 | + auto *t = f->Get<TTree>(el->GetName()); |
| 686 | + if (!t) { |
| 687 | + continue; |
| 688 | + } |
| 689 | + offset += collectClusters(t, offset); |
| 690 | + } |
| 691 | + } else { |
| 692 | + // If single TTree, iterate over its clusters |
| 693 | + collectClusters(tree, 0); |
| 694 | + } |
| 695 | + |
| 696 | + return ranges; |
| 697 | +} |
| 698 | + |
| 699 | +} // namespace RDF |
| 700 | +} // namespace Internal |
| 701 | +} // namespace ROOT |
638 | 702 |
|
639 | 703 | std::string |
640 | 704 | ROOT::Internal::RDF::GetTypeNameWithOpts(const ROOT::RDF::RDataSource &df, std::string_view colName, bool vector2RVec) |
|
0 commit comments