Logo ROOT   6.16/01
Reference Guide
TTreeProcessorMT.hxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Authors: Enric Tejedor, Enrico Guiraud CERN 05/06/2018
3
4/*************************************************************************
5 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifndef ROOT_TTreeProcessorMT
13#define ROOT_TTreeProcessorMT
14
15#include "TKey.h"
16#include "TTree.h"
17#include "TFile.h"
18#include "TChain.h"
19#include "TTreeReader.h"
20#include "TError.h"
21#include "TEntryList.h"
22#include "TFriendElement.h"
23#include "ROOT/RMakeUnique.hxx"
25
26#include <string.h>
27#include <functional>
28#include <vector>
29
30
31/** \class TTreeView
32 \brief A helper class that encapsulates a file and a tree.
33
34A helper class that encapsulates a TFile and a TTree, along with their names.
35It is used together with TTProcessor and ROOT::TThreadedObject, so that
36in the TTProcessor::Process method each thread can work on its own
37<TFile,TTree> pair.
38
39This class can also be used with a collection of file names or a TChain, in case
40the tree is stored in more than one file. A view will always contain only the
41current (active) tree and file objects.
42
43A copy constructor is defined for TTreeView to work with ROOT::TThreadedObject.
44The latter makes a copy of a model object every time a new thread accesses
45the threaded object.
46*/
47
48namespace ROOT {
49 namespace Internal {
50
51 /// A cluster of entries
52 struct EntryCluster {
55 };
56
57 /// Names, aliases, and file names of a TTree's or TChain's friends
58 using NameAlias = std::pair<std::string, std::string>;
59 struct FriendInfo {
60 /// Pairs of names and aliases of friend trees/chains
61 std::vector<Internal::NameAlias> fFriendNames;
62 /// Names of the files where each friend is stored. fFriendFileNames[i] is the list of files for friend with
63 /// name fFriendNames[i]
64 std::vector<std::vector<std::string>> fFriendFileNames;
65 };
66
67 class TTreeView {
68 private:
69 using TreeReaderEntryListPair = std::pair<std::unique_ptr<TTreeReader>, std::unique_ptr<TEntryList>>;
70
71 // NOTE: fFriends must come before fChain to be deleted after it, see ROOT-9281 for more details
72 std::vector<std::unique_ptr<TChain>> fFriends; ///< Friends of the tree/chain
73 std::unique_ptr<TChain> fChain; ///< Chain on which to operate
74
75 ////////////////////////////////////////////////////////////////////////////////
76 /// Construct fChain, also adding friends if needed and injecting knowledge of offsets if available.
77 void MakeChain(const std::string &treeName, const std::vector<std::string> &fileNames,
78 const FriendInfo &friendInfo, const std::vector<Long64_t> &nEntries,
79 const std::vector<std::vector<Long64_t>> &friendEntries)
80 {
81 const std::vector<NameAlias> &friendNames = friendInfo.fFriendNames;
82 const std::vector<std::vector<std::string>> &friendFileNames = friendInfo.fFriendFileNames;
83
84 fChain.reset(new TChain(treeName.c_str()));
85 const auto nFiles = fileNames.size();
86 for (auto i = 0u; i < nFiles; ++i) {
87 fChain->Add(fileNames[i].c_str(), nEntries[i]);
88 }
90
91 fFriends.clear();
92 const auto nFriends = friendNames.size();
93 for (auto i = 0u; i < nFriends; ++i) {
94 const auto &friendName = friendNames[i];
95 const auto &name = friendName.first;
96 const auto &alias = friendName.second;
97
98 // Build a friend chain
99 auto frChain = std::make_unique<TChain>(name.c_str());
100 const auto nFileNames = friendFileNames[i].size();
101 for (auto j = 0u; j < nFileNames; ++j)
102 frChain->Add(friendFileNames[i][j].c_str(), friendEntries[i][j]);
103
104 // Make it friends with the main chain
105 fChain->AddFriend(frChain.get(), alias.c_str());
106 fFriends.emplace_back(std::move(frChain));
107 }
108 }
109
111 {
112 // TEntryList and SetEntriesRange do not work together (the former has precedence).
113 // We need to construct a TEntryList that contains only those entry numbers in our desired range.
114 auto localList = std::make_unique<TEntryList>();
115 Long64_t entry = globalList.GetEntry(0);
116 do {
117 if (entry >= end)
118 break;
119 else if (entry >= start)
120 localList->Enter(entry);
121 } while ((entry = globalList.Next()) >= 0);
122
123 auto reader = std::make_unique<TTreeReader>(fChain.get(), localList.get());
124 return std::make_pair(std::move(reader), std::move(localList));
125 }
126
127 std::unique_ptr<TTreeReader> MakeReader(Long64_t start, Long64_t end)
128 {
129 auto reader = std::make_unique<TTreeReader>(fChain.get());
130 reader->SetEntriesRange(start, end);
131 return reader;
132 }
133
134 public:
136
137 // no-op, we don't want to copy the local TChains
139
140 //////////////////////////////////////////////////////////////////////////
141 /// Get a TTreeReader for the current tree of this view.
142 TreeReaderEntryListPair GetTreeReader(Long64_t start, Long64_t end, const std::string &treeName,
143 const std::vector<std::string> &fileNames, const FriendInfo &friendInfo,
144 TEntryList entryList, const std::vector<Long64_t> &nEntries,
145 const std::vector<std::vector<Long64_t>> &friendEntries)
146 {
147 const bool usingLocalEntries = friendInfo.fFriendNames.empty() && entryList.GetN() == 0;
148 if (fChain == nullptr || (usingLocalEntries && fileNames[0] != fChain->GetListOfFiles()->At(0)->GetTitle()))
149 MakeChain(treeName, fileNames, friendInfo, nEntries, friendEntries);
150
151 std::unique_ptr<TTreeReader> reader;
152 std::unique_ptr<TEntryList> localList;
153 if (entryList.GetN() > 0) {
154 std::tie(reader, localList) = MakeReaderWithEntryList(entryList, start, end);
155 } else {
156 reader = MakeReader(start, end);
157 }
158
159 // we need to return the entry list too, as it needs to be in scope as long as the reader is
160 return std::make_pair(std::move(reader), std::move(localList));
161 }
162 };
163 } // End of namespace Internal
164
166 private:
167 const std::vector<std::string> fFileNames; ///< Names of the files
168 const std::string fTreeName; ///< Name of the tree
169 /// User-defined selection of entry numbers to be processed, empty if none was provided
172
174
176 std::string FindTreeName();
177 static unsigned int fgMaxTasksPerFilePerWorker;
178 public:
179 TTreeProcessorMT(std::string_view filename, std::string_view treename = "");
180 TTreeProcessorMT(const std::vector<std::string_view> &filenames, std::string_view treename = "");
181 TTreeProcessorMT(TTree &tree, const TEntryList &entries);
183
184 void Process(std::function<void(TTreeReader &)> func);
185 static void SetMaxTasksPerFilePerWorker(unsigned int m);
186 static unsigned int GetMaxTasksPerFilePerWorker();
187 };
188
189} // End of namespace ROOT
190
191#endif // defined TTreeProcessorMT
long long Long64_t
Definition: RtypesCore.h:69
std::pair< std::unique_ptr< TTreeReader >, std::unique_ptr< TEntryList > > TreeReaderEntryListPair
TTreeView(const TTreeView &)
std::unique_ptr< TChain > fChain
Chain on which to operate.
std::vector< std::unique_ptr< TChain > > fFriends
Friends of the tree/chain.
void MakeChain(const std::string &treeName, const std::vector< std::string > &fileNames, const FriendInfo &friendInfo, const std::vector< Long64_t > &nEntries, const std::vector< std::vector< Long64_t > > &friendEntries)
Construct fChain, also adding friends if needed and injecting knowledge of offsets if available.
TreeReaderEntryListPair MakeReaderWithEntryList(TEntryList &globalList, Long64_t start, Long64_t end)
TreeReaderEntryListPair GetTreeReader(Long64_t start, Long64_t end, const std::string &treeName, const std::vector< std::string > &fileNames, const FriendInfo &friendInfo, TEntryList entryList, const std::vector< Long64_t > &nEntries, const std::vector< std::vector< Long64_t > > &friendEntries)
Get a TTreeReader for the current tree of this view.
std::unique_ptr< TTreeReader > MakeReader(Long64_t start, Long64_t end)
A wrapper to make object instances thread private, lazily.
A class to process the entries of a TTree in parallel.
static unsigned int GetMaxTasksPerFilePerWorker()
Sets the maximum number of tasks created per file, per worker.
const std::string fTreeName
Name of the tree.
const std::vector< std::string > fFileNames
Names of the files.
static void SetMaxTasksPerFilePerWorker(unsigned int m)
Sets the maximum number of tasks created per file, per worker.
Internal::FriendInfo GetFriendInfo(TTree &tree)
Get and store the names, aliases and file names of the friends of the tree.
static unsigned int fgMaxTasksPerFilePerWorker
TTreeProcessorMT(std::string_view filename, std::string_view treename="")
Constructor based on a file name.
const TEntryList fEntryList
User-defined selection of entry numbers to be processed, empty if none was provided.
void Process(std::function< void(TTreeReader &)> func)
Process the entries of a TTree in parallel.
ROOT::TThreadedObject< ROOT::Internal::TTreeView > treeView
! Thread-local TreeViews
const Internal::FriendInfo fFriendInfo
std::string FindTreeName()
Retrieve the name of the first TTree in the first input file, else throw.
A chain is a collection of files containing TTree objects.
Definition: TChain.h:33
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:26
virtual Long64_t Next()
Return the next non-zero entry index (next after fLastIndexQueried) this function is faster than GetE...
Definition: TEntryList.cxx:886
virtual Long64_t GetEntry(Int_t index)
Return the number of the entry #index of this TEntryList in the TTree or TChain See also Next().
Definition: TEntryList.cxx:653
virtual Long64_t GetN() const
Definition: TEntryList.h:75
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
A simple, robust and fast interface to read values from ROOT colmnar datasets such as TTree,...
Definition: TTreeReader.h:44
A TTree object has a header with a name and a title.
Definition: TTree.h:71
std::pair< std::string, std::string > NameAlias
Names, aliases, and file names of a TTree's or TChain's friends.
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:151
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
basic_string_view< char > string_view
Definition: RStringView.hxx:35
Definition: tree.py:1
std::vector< std::vector< std::string > > fFriendFileNames
Names of the files where each friend is stored.
std::vector< Internal::NameAlias > fFriendNames
Pairs of names and aliases of friend trees/chains.
auto * m
Definition: textangle.C:8