From c279445ec07bc2b14893bd6f878260d4b7a65bda Mon Sep 17 00:00:00 2001 From: Stefan Wunsch <stefan.wunsch@cern.ch> Date: Tue, 28 Jan 2020 16:22:22 +0100 Subject: [PATCH] [ROOT-10508] Fix TTreeProcessorMT for unnamed chain as friend * Retrieves correctly the name of the trees building the chain if the chain itself does not has a name. This happens if the default constructor for TChain is used and the name of the tree is retrieved via the string given to `TChain::AddFile("file.root/treeName")`. * This does not fix the issue entirely since the FriendInfo needs a refactoring. The FriendInfo assumes that in a chain each tree has the same name, which could not hold true. --- tree/treeplayer/src/TTreeProcessorMT.cxx | 39 +++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/tree/treeplayer/src/TTreeProcessorMT.cxx b/tree/treeplayer/src/TTreeProcessorMT.cxx index 0823eadf448..edb1a607be0 100644 --- a/tree/treeplayer/src/TTreeProcessorMT.cxx +++ b/tree/treeplayer/src/TTreeProcessorMT.cxx @@ -328,26 +328,37 @@ Internal::FriendInfo TTreeProcessorMT::GetFriendInfo(TTree &tree) for (auto fr : *friends) { const auto frTree = static_cast<TFriendElement *>(fr)->GetTree(); + const bool isChain = frTree->IsA() == TChain::Class(); - // Check if friend tree has an alias - const auto realName = frTree->GetName(); - const auto alias = tree.GetFriendAlias(frTree); - if (alias) { - friendNames.emplace_back(std::make_pair(realName, std::string(alias))); - } else { - friendNames.emplace_back(std::make_pair(realName, "")); - } - - // Store the file names of the friend tree friendFileNames.emplace_back(); auto &fileNames = friendFileNames.back(); - const bool isChain = tree.IsA() == TChain::Class(); + + // Check if friend tree/chain has an alias + const auto alias_c = tree.GetFriendAlias(frTree); + const std::string alias = alias_c != nullptr ? alias_c : ""; + if (isChain) { - const auto frChain = static_cast<TChain *>(frTree); - for (auto f : *(frChain->GetListOfFiles())) { + // Note that each TChainElement returned by chain.GetListOfFiles has a name + // equal to the tree name of this TChain and a title equal to the filename. + // Accessing the information like this ensures that we get the correct + // filenames and treenames if the treename is given as part of the filename + // via chain.AddFile(file.root/myTree) and as well if the tree name is given + // in the constructor via TChain(myTree) and a file is added later by chain.AddFile(file.root). + + // Get name of the trees building the chain + const auto chainFiles = static_cast<TChain*>(frTree)->GetListOfFiles(); + const auto realName = chainFiles->First()->GetName(); + friendNames.emplace_back(std::make_pair(realName, alias)); + // Get filenames stored in the title member + for (auto f : *chainFiles) { fileNames.emplace_back(f->GetTitle()); } } else { + // Get name of the tree + const auto realName = frTree->GetName(); + friendNames.emplace_back(std::make_pair(realName, alias)); + + // Get filename const auto f = frTree->GetCurrentFile(); if (!f) throw std::runtime_error("Friend trees with no associated file are not supported."); @@ -549,4 +560,4 @@ unsigned int TTreeProcessorMT::GetMaxTasksPerFilePerWorker() void TTreeProcessorMT::SetMaxTasksPerFilePerWorker(unsigned int maxTasksPerFile) { fgMaxTasksPerFilePerWorker = maxTasksPerFile; -} \ No newline at end of file +} -- GitLab