33 std::unordered_set<TTree *> &analysedTrees,
const std::string friendName =
"")
35 if (!analysedTrees.insert(&t).second) {
41 for (
auto branchObj : *branches) {
43 if (bNamesReg.insert(
name).second) {
44 bNames.emplace_back(
name);
45 }
else if (!friendName.empty()) {
48 const auto longName = friendName +
"." +
name;
49 if (bNamesReg.insert(longName).second)
50 bNames.emplace_back(longName);
60 for (
auto friendTreeObj : *friendTrees) {
62 auto friendTree = friendElement->
GetTree();
63 const std::string frName(friendElement->GetName());
76 std::unordered_set<std::string> bNamesSet;
77 std::vector<std::string> bNames;
78 std::unordered_set<TTree *> analysedTrees;
91 std::vector<std::string> filenames;
94 if (
auto chain =
dynamic_cast<const TChain *
>(&tree)) {
95 const auto *chainFiles = chain->GetListOfFiles();
97 throw std::runtime_error(
"Could not retrieve a list of files from the input TChain.");
101 const auto nfiles = chainFiles->GetEntries();
103 throw std::runtime_error(
"The list of files associated with the input TChain is empty.");
105 filenames.reserve(nfiles);
106 for (
const auto *
f : *chainFiles)
107 filenames.emplace_back(
f->GetTitle());
109 const TFile *
f = tree.GetCurrentFile();
111 throw std::runtime_error(
"The input TTree is not linked to any file, "
112 "in-memory-only trees are not supported.");
115 filenames.emplace_back(
f->GetName());
172 const auto *friends = tree.GetListOfFriends();
173 if (!friends || friends->GetEntries() == 0)
176 std::vector<std::pair<std::string, std::string>> friendNames;
177 std::vector<std::vector<std::string>> friendFileNames;
178 std::vector<std::vector<std::string>> friendChainSubNames;
179 std::vector<std::vector<Long64_t>> nEntriesPerTreePerFriend;
180 std::vector<std::unique_ptr<TVirtualIndex>> treeIndexes;
183 auto nFriends = friends->GetEntries();
184 friendNames.reserve(nFriends);
185 friendFileNames.reserve(nFriends);
186 friendChainSubNames.reserve(nFriends);
187 nEntriesPerTreePerFriend.reserve(nFriends);
189 for (
auto fr : *friends) {
195 friendFileNames.emplace_back();
196 auto &fileNames = friendFileNames.back();
200 friendChainSubNames.emplace_back();
201 auto &chainSubNames = friendChainSubNames.back();
204 nEntriesPerTreePerFriend.emplace_back();
205 auto &nEntriesInThisFriend = nEntriesPerTreePerFriend.back();
208 const auto *alias_c = tree.GetFriendAlias(frTree);
209 const std::string alias = alias_c !=
nullptr ? alias_c :
"";
211 auto *treeIndex = frTree->GetTreeIndex();
212 treeIndexes.emplace_back(
static_cast<TVirtualIndex *
>(treeIndex ? treeIndex->Clone() :
nullptr));
215 if (
auto frChain =
dynamic_cast<const TChain *
>(frTree)) {
226 const auto *chainFiles = frChain->GetListOfFiles();
227 if (!chainFiles || chainFiles->GetEntries() == 0) {
228 throw std::runtime_error(
"A TChain in the list of friends does not contain any file. "
229 "Friends with no associated files are not supported.");
233 auto nFiles = chainFiles->GetEntries();
234 fileNames.reserve(nFiles);
235 chainSubNames.reserve(nFiles);
236 nEntriesInThisFriend.reserve(nFiles);
239 friendNames.emplace_back(std::make_pair(frChain->GetName(), alias));
243 for (
const auto *
f : *chainFiles) {
245 auto thisTreeName =
f->GetName();
246 auto thisFileName =
f->GetTitle();
248 chainSubNames.emplace_back(thisTreeName);
249 fileNames.emplace_back(thisFileName);
251 if (retrieveEntries) {
252 std::unique_ptr<TFile> thisFile{
TFile::Open(thisFileName,
"READ_WITHOUT_GLOBALREGISTRATION")};
253 if (!thisFile || thisFile->IsZombie())
254 throw std::runtime_error(std::string(
"GetFriendInfo: Could not open file \"") + thisFileName +
"\"");
255 TTree *thisTree = thisFile->Get<
TTree>(thisTreeName);
257 throw std::runtime_error(std::string(
"GetFriendInfo: Could not retrieve TTree \"") + thisTreeName +
258 "\" from file \"" + thisFileName +
"\"");
259 nEntriesInThisFriend.emplace_back(thisTree->
GetEntries());
265 nEntriesInThisFriend.emplace_back(maxEntries);
271 friendNames.emplace_back(std::make_pair(realName, alias));
274 const auto *
f = frTree->GetCurrentFile();
276 throw std::runtime_error(
"A TTree in the list of friends is not linked to any file. "
277 "Friends with no associated files are not supported.");
278 fileNames.emplace_back(
f->GetName());
281 nEntriesInThisFriend.emplace_back(frTree->GetEntries());
286 std::move(friendChainSubNames), std::move(nEntriesPerTreePerFriend),
287 std::move(treeIndexes));
307 if (
auto chain =
dynamic_cast<const TChain *
>(&tree)) {
308 const auto *chainFiles = chain->GetListOfFiles();
309 if (!chainFiles || chainFiles->GetEntries() == 0) {
310 throw std::runtime_error(
"The input TChain does not contain any file.");
312 std::vector<std::string> treeNames;
313 for (
const auto *
f : *chainFiles)
314 treeNames.emplace_back(
f->GetName());
320 if (
const auto *treeDir = tree.GetDirectory()) {
325 if (
dynamic_cast<const TFile *
>(treeDir)) {
326 return {tree.GetName()};
328 std::string fullPath = treeDir->GetPath();
329 fullPath = fullPath.substr(fullPath.rfind(
":/") + 1);
331 fullPath += tree.GetName();
336 return {tree.GetName()};
352 TObjArray *subBranches = branch->GetListOfBranches();
354 TObjArray *leaves = branch->GetListOfLeaves();
376 std::vector<std::unique_ptr<TChain>> friends;
378 friends.reserve(nFriends);
380 for (std::size_t i = 0u; i < nFriends; ++i) {
381 const auto &thisFriendName = finfo.
fFriendNames[i].first;
388 if (thisFriendChainSubNames.empty()) {
390 frChain->Add(thisFriendFileNames[0].c_str(), thisFriendEntries[0]);
394 for (std::size_t j = 0u; j < thisFriendFileNames.size(); ++j) {
395 frChain->Add((thisFriendFileNames[j] +
"?#" + thisFriendChainSubNames[j]).c_str(), thisFriendEntries[j]);
407 frChain->BuildIndex(treeIndex->GetMajorName(), treeIndex->GetMinorName());
410 friends.emplace_back(std::move(frChain));
434 std::string basename;
435 std::string remainder;
439 const char *wildcardSpecials =
"[]*?";
441 const auto wildcardPos = glob.find_first_of(wildcardSpecials);
443 auto slashLPos = glob.rfind(
'/', wildcardPos);
445 const auto slashRPos = glob.find(
'/', wildcardPos);
447 if (slashLPos != std::string::npos) {
449 dirname = glob.substr(0, slashLPos);
459 if (slashRPos != std::string::npos) {
460 basename = glob.substr(slashLPos + 1, slashRPos - (slashLPos + 1));
461 remainder = glob.substr(slashRPos + 1);
463 basename = glob.substr(slashLPos + 1);
472 TRegexp re(basename.c_str(),
true);
476 if (!strcmp(dirEntry,
".") || !strcmp(dirEntry,
".."))
478 entryName = dirEntry;
479 if ((basename != dirEntry) && entryName.
Index(re) ==
kNPOS)
485 if (!remainder.empty() && isDirectory) {
486 RecursiveGlob(out, dirname +
'/' + dirEntry +
'/' + remainder);
487 }
else if (remainder.empty() && !isDirectory) {
490 out.Add(
new TObjString((dirname +
'/' + dirEntry).c_str()));
496 throw std::runtime_error(
"ExpandGlob: could not open directory '" + dirname +
"'.");
520 std::vector<std::string> ret;
521 ret.reserve(
l.GetEntries());
522 for (
const auto *tobjstr : ROOT::RangeStaticCast<const TObjString *>(
l)) {
523 ret.push_back(tobjstr->GetName());
540 std::unique_ptr<TFile> inFile{
TFile::Open(path.data(),
"READ_WITHOUT_GLOBALREGISTRATION")};
541 if (!inFile || inFile->IsZombie())
542 throw std::invalid_argument(
"GetClustersAndEntries: could not open file \"" + std::string(path) +
"\".");
543 std::unique_ptr<TTree> tree{inFile->Get<
TTree>(treename.data())};
545 throw std::invalid_argument(
"GetClustersAndEntries: could not find tree \"" + std::string(treename) +
546 "\" in file \"" + std::string(path) +
"\".");
548 auto nEntries{tree->GetEntriesFast()};
550 auto clusterIt{tree->GetClusterIterator(0)};
551 auto clusterBegin{clusterIt()};
552 std::vector boundaries{clusterBegin};
553 while (clusterBegin < nEntries) {
554 clusterBegin = clusterIt();
555 boundaries.push_back(clusterBegin);
558 return std::make_pair(std::move(boundaries), std::move(nEntries));
569 if (
auto friends = tree.GetListOfFriends(); friends && friends->GetEntries() > 0) {
571 auto *frTree = fr->GetTree();
572 if (frTree->GetTreeIndex())
573 return {
true, frTree->GetName()};
static void GetTopLevelBranchNamesImpl(TTree &t, std::unordered_set< std::string > &bNamesReg, std::vector< std::string > &bNames, std::unordered_set< TTree * > &analysedTrees, const std::string friendName="")
R__EXTERN TSystem * gSystem
A chain is a collection of files containing TTree objects.
@ kWithoutGlobalRegistration
const char * GetName() const override
Return name of this collection.
TDirectory::TContext keeps track and restore the current directory.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
A TFriendElement TF describes a TTree object TF in a file.
virtual TTree * GetTree()
Return pointer to friend TTree.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Collectable string class.
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
@ kMustCleanup
if object destructor must call RecursiveRemove()
Regular expression class.
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
A TSystemFile describes an operating system file.
virtual Bool_t IsDirectory(const char *dir=nullptr) const
Check if object is a directory.
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
virtual void FreeDirectory(void *dirp)
Free a directory.
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
virtual const char * UnixPathName(const char *unixpathname)
Convert from a local pathname to a Unix pathname.
virtual const char * WorkingDirectory()
Return working directory.
A TTree represents a columnar dataset.
virtual Long64_t GetEntries() const
virtual TObjArray * GetListOfBranches()
virtual TList * GetListOfFriends() const
static constexpr Long64_t kMaxEntries
Abstract interface for Tree Index.
Different standalone functions to work with trees and tuples, not reqiuired to be a member of any cla...
std::vector< std::string > GetTreeFullPaths(const TTree &tree)
std::vector< std::string > GetTopLevelBranchNames(TTree &t)
Get all the top-level branches names, including the ones of the friend trees.
std::unique_ptr< TChain > MakeChainForMT(const std::string &name="", const std::string &title="")
Create a TChain object with options that avoid common causes of thread contention.
std::pair< bool, std::string > TreeUsesIndexedFriends(const TTree &tree)
Check whether the input tree is using any TTreeIndex.
std::vector< std::unique_ptr< TChain > > MakeFriends(const ROOT::TreeUtils::RFriendInfo &finfo)
Create friends from the main TTree.
void RecursiveGlob(TList &out, const std::string &glob)
Recursively expand the glob to take care of potential wildcard specials for subdirectories in the glo...
ROOT::TreeUtils::RFriendInfo GetFriendInfo(const TTree &tree, bool retrieveEntries=false)
std::vector< std::string > ExpandGlob(const std::string &glob)
Expands input glob into a collection of full paths to files.
std::pair< std::vector< Long64_t >, Long64_t > GetClustersAndEntries(std::string_view treename, std::string_view path)
Returns the cluster boundaries and number of entries of the input tree.
void ClearMustCleanupBits(TObjArray &arr)
Reset the kMustCleanup bit of a TObjArray of TBranch objects (e.g.
std::vector< std::string > GetFileNamesFromTree(const TTree &tree)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Information about friend trees of a certain TTree or TChain object.
std::vector< std::pair< std::string, std::string > > fFriendNames
Pairs of names and aliases of each friend tree/chain.
std::vector< std::vector< std::string > > fFriendChainSubNames
Names of the subtrees of a friend TChain.
std::vector< std::unique_ptr< TVirtualIndex > > fTreeIndexInfos
Information on the friend's TTreeIndexes.
std::vector< std::vector< std::string > > fFriendFileNames
Names of the files where each friend is stored.
std::vector< std::vector< Long64_t > > fNEntriesPerTreePerFriend
Number of entries contained in each tree of each friend.