27 std::unordered_set<TTree *> &analysedTrees,
const std::string friendName =
"")
29 if (!analysedTrees.insert(&t).second) {
35 for (
auto branchObj : *branches) {
37 if (bNamesReg.insert(
name).second) {
38 bNames.emplace_back(
name);
39 }
else if (!friendName.empty()) {
42 const auto longName = friendName +
"." +
name;
43 if (bNamesReg.insert(longName).second)
44 bNames.emplace_back(longName);
54 for (
auto friendTreeObj : *friendTrees) {
56 auto friendTree = friendElement->
GetTree();
57 const std::string frName(friendElement->GetName());
70 std::unordered_set<std::string> bNamesSet;
71 std::vector<std::string> bNames;
72 std::unordered_set<TTree *> analysedTrees;
85 std::vector<std::string> filenames;
88 if (
auto chain =
dynamic_cast<const TChain *
>(&
tree)) {
89 const auto *chainFiles = chain->GetListOfFiles();
91 throw std::runtime_error(
"Could not retrieve a list of files from the input TChain.");
95 const auto nfiles = chainFiles->GetEntries();
97 throw std::runtime_error(
"The list of files associated with the input TChain is empty.");
99 filenames.reserve(nfiles);
100 for (
const auto *
f : *chainFiles)
101 filenames.emplace_back(
f->GetTitle());
105 throw std::runtime_error(
"The input TTree is not linked to any file, "
106 "in-memory-only trees are not supported.");
109 filenames.emplace_back(
f->GetName());
166 const auto *friends =
tree.GetListOfFriends();
167 if (!friends || friends->GetEntries() == 0)
170 std::vector<std::pair<std::string, std::string>> friendNames;
171 std::vector<std::vector<std::string>> friendFileNames;
172 std::vector<std::vector<std::string>> friendChainSubNames;
173 std::vector<std::vector<std::int64_t>> nEntriesPerTreePerFriend;
174 std::vector<std::unique_ptr<TVirtualIndex>> treeIndexes;
177 auto nFriends = friends->GetEntries();
178 friendNames.reserve(nFriends);
179 friendFileNames.reserve(nFriends);
180 friendChainSubNames.reserve(nFriends);
181 nEntriesPerTreePerFriend.reserve(nFriends);
183 for (
auto fr : *friends) {
189 friendFileNames.emplace_back();
190 auto &fileNames = friendFileNames.back();
194 friendChainSubNames.emplace_back();
195 auto &chainSubNames = friendChainSubNames.back();
198 nEntriesPerTreePerFriend.emplace_back();
199 auto &nEntriesInThisFriend = nEntriesPerTreePerFriend.back();
202 const auto *alias_c =
tree.GetFriendAlias(frTree);
203 const std::string alias = alias_c !=
nullptr ? alias_c :
"";
205 auto *treeIndex = frTree->GetTreeIndex();
206 treeIndexes.emplace_back(
static_cast<TVirtualIndex *
>(treeIndex ? treeIndex->Clone() :
nullptr));
209 if (
auto frChain =
dynamic_cast<const TChain *
>(frTree)) {
220 const auto *chainFiles = frChain->GetListOfFiles();
221 if (!chainFiles || chainFiles->GetEntries() == 0) {
222 throw std::runtime_error(
"A TChain in the list of friends does not contain any file. "
223 "Friends with no associated files are not supported.");
227 auto nFiles = chainFiles->GetEntries();
228 fileNames.reserve(nFiles);
229 chainSubNames.reserve(nFiles);
230 nEntriesInThisFriend.reserve(nFiles);
233 friendNames.emplace_back(std::make_pair(frChain->GetName(), alias));
237 for (
const auto *
f : *chainFiles) {
239 auto thisTreeName =
f->GetName();
240 auto thisFileName =
f->GetTitle();
242 chainSubNames.emplace_back(thisTreeName);
243 fileNames.emplace_back(thisFileName);
245 if (retrieveEntries) {
246 std::unique_ptr<TFile> thisFile{
TFile::Open(thisFileName,
"READ_WITHOUT_GLOBALREGISTRATION")};
247 if (!thisFile || thisFile->IsZombie())
248 throw std::runtime_error(std::string(
"GetFriendInfo: Could not open file \"") + thisFileName +
"\"");
249 TTree *thisTree = thisFile->Get<
TTree>(thisTreeName);
251 throw std::runtime_error(std::string(
"GetFriendInfo: Could not retrieve TTree \"") + thisTreeName +
252 "\" from file \"" + thisFileName +
"\"");
253 nEntriesInThisFriend.emplace_back(thisTree->
GetEntries());
259 nEntriesInThisFriend.emplace_back(maxEntries);
265 friendNames.emplace_back(std::make_pair(realName, alias));
268 const auto *
f = frTree->GetCurrentFile();
270 throw std::runtime_error(
"A TTree in the list of friends is not linked to any file. "
271 "Friends with no associated files are not supported.");
272 fileNames.emplace_back(
f->GetName());
275 nEntriesInThisFriend.emplace_back(frTree->GetEntries());
280 std::move(friendChainSubNames), std::move(nEntriesPerTreePerFriend),
281 std::move(treeIndexes));
301 if (
auto chain =
dynamic_cast<const TChain *
>(&
tree)) {
302 const auto *chainFiles = chain->GetListOfFiles();
303 if (!chainFiles || chainFiles->GetEntries() == 0) {
304 throw std::runtime_error(
"The input TChain does not contain any file.");
306 std::vector<std::string> treeNames;
307 for (
const auto *
f : *chainFiles)
308 treeNames.emplace_back(
f->GetName());
314 if (
const auto *treeDir =
tree.GetDirectory()) {
319 if (
dynamic_cast<const TFile *
>(treeDir)) {
320 return {
tree.GetName()};
322 std::string fullPath = treeDir->GetPath();
323 fullPath = fullPath.substr(fullPath.rfind(
":/") + 1);
325 fullPath +=
tree.GetName();
330 return {
tree.GetName()};
346 TObjArray *subBranches = branch->GetListOfBranches();
348 TObjArray *leaves = branch->GetListOfLeaves();
370 std::vector<std::unique_ptr<TChain>> friends;
372 friends.reserve(nFriends);
374 for (std::size_t i = 0u; i < nFriends; ++i) {
375 const auto &thisFriendName = finfo.
fFriendNames[i].first;
382 if (thisFriendChainSubNames.empty()) {
384 frChain->Add(thisFriendFileNames[0].c_str(), thisFriendEntries[0]);
388 for (std::size_t j = 0u; j < thisFriendFileNames.size(); ++j) {
389 frChain->Add((thisFriendFileNames[j] +
"?#" + thisFriendChainSubNames[j]).c_str(), thisFriendEntries[j]);
395 auto *copyOfIndex =
static_cast<TVirtualIndex *
>(treeIndex->Clone());
396 copyOfIndex->
SetTree(frChain.get());
397 frChain->SetTreeIndex(copyOfIndex);
400 friends.emplace_back(std::move(frChain));
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="")
A chain is a collection of files containing TTree objects.
@ kWithoutGlobalRegistration
const char * GetName() const override
Return name of this collection.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
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
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
@ kMustCleanup
if object destructor must call RecursiveRemove()
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.
virtual void SetTree(TTree *T)=0
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::vector< std::unique_ptr< TChain > > MakeFriends(const ROOT::TreeUtils::RFriendInfo &finfo)
Create friends from the main TTree.
ROOT::TreeUtils::RFriendInfo GetFriendInfo(const TTree &tree, bool retrieveEntries=false)
void ClearMustCleanupBits(TObjArray &arr)
Reset the kMustCleanup bit of a TObjArray of TBranch objects (e.g.
std::vector< std::string > GetFileNamesFromTree(const TTree &tree)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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::int64_t > > fNEntriesPerTreePerFriend
Number of entries contained in each tree of each friend.
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.