DataGetterHelper.h
Go to the documentation of this file.
1 #ifndef gallery_DataGetterHelper_h
2 #define gallery_DataGetterHelper_h
3 // vim: set sw=2 expandtab :
4 
5 // Allows one to lookup a product given module label, instance name,
6 // type and optionally the process name. It contains various data
7 // structures to efficiently perform that lookup. Using
8 // BranchMapReader it can also find a product using the ProductID
9 // stored in Ptrs.
10 
11 // By default TTreeCache is used and it is the design intent that the
12 // configuration defaults are reasonably good and the user needs to do
13 // nothing. in what follows there are some details of how it works and
14 // some alternatives, but most people can stop reading this comment
15 // here and not waste their time ... The default cache sizes of ROOT
16 // (currently 30 MB)is used. This code decides which branches to put
17 // into the cache as follows. It includes all branches where the
18 // type/label/instance was requested and the process both exists in
19 // some product registry in an input file already open and the branch
20 // exists in the currently open input file. It initializes the cache
21 // when the specified number of events has been processed
22 // (eventsToLearnUsedBranches argument of the Event constructor which
23 // defaults to 7). And also everytime a new file is opened after that
24 // point. The user has some alternatives. By using the second argument
25 // of the Event contructor, one could turn off TTreeCache usage by
26 // this code and run without a TTreeCache. Alternately, one could turn
27 // it off and get the TTree* at each file open and manually configure
28 // the TTreeCache however one would like. Note EventAuxiliary is
29 // special in that it is always cached. Also note that in the
30 // implementation TChain is not used so if one were to manually
31 // configure one would have to do that everytime a new TFile was
32 // opened which could be detected by looking for a change in the file
33 // entry number using the Event interface.
34 
39 #include "canvas/Utilities/fwd.h"
40 
41 #include "canvas_root_io/Utilities/DictionaryChecker.h"
42 
43 #include "gallery/BranchData.h"
47 
48 #include <map>
49 #include <memory>
50 #include <set>
51 #include <string>
52 #include <typeinfo>
53 #include <utility>
54 #include <vector>
55 
56 namespace art {
57  class EDProduct;
58  class EDProductGetter;
59  class BranchDescription;
60 }
61 
62 class TClass;
63 class TFile;
64 class TTree;
65 
66 namespace gallery {
67 
68  class EventHistoryGetter;
69  class EventNavigator;
70  using ProductWithID = std::pair<art::EDProduct const*, art::ProductID>;
71 
73  public:
74  explicit DataGetterHelper(
75  EventNavigator const* eventNavigator,
76  std::shared_ptr<EventHistoryGetter> historyGetter);
77 
78  DataGetterHelper(DataGetterHelper const&) = delete;
80  DataGetterHelper& operator=(DataGetterHelper const&) = delete;
81  DataGetterHelper& operator=(DataGetterHelper&&) = delete;
82 
83  ProductWithID getByLabel(std::type_info const& typeInfoOfWrapper,
84  art::InputTag const& inputTag) const;
85 
86  std::vector<art::InputTag> getInputTags(
87  std::type_info const& typeInfoOfWrapper) const;
88 
89  std::vector<ProductWithID> getManyByType(
90  std::type_info const& typeInfoOfWrapper) const;
91 
92  art::BranchDescription const& getProductDescription(art::ProductID) const;
93 
94  void updateFile(TFile* iFile, TTree* iTree, bool initializeTheCache);
95 
96  void initializeTTreeCache();
97 
98  void updateEvent();
99 
100  private: // MEMBER FUNCTIONS
101  void initializeForProcessHistory() const;
102 
103  void addProcess(std::string const& processName) const;
104 
105  void addBranchData(std::string branchName,
106  unsigned int processIndex,
108  bool initializeTheCache = false) const;
109 
110  TClass* getTClass(InfoForTypeLabelInstance const& info,
111  std::string const& processName) const;
112 
113  InfoForTypeLabelInstance& getInfoForTypeLabelInstance(
114  art::TypeID const& type,
115  std::string const& label,
116  std::string const& instance) const;
117 
118  void addTypeLabelInstance(art::TypeID const& type,
119  std::string const& label,
120  std::string const& instance) const;
121 
122  void insertIntoInfoMap(art::TypeID const& type,
123  std::string const& label,
124  std::string const& instance,
125  unsigned int infoIndex) const;
126 
127  art::EDProduct const* readProduct(art::ProductID const productID,
128  art::TypeID const& type) const;
129 
130  art::ProductID getMaybeValidProductID(
131  std::vector<IndexProductIDPair> const& processIndexToProductID,
132  unsigned int processIndex) const;
133 
134  void updateBranchDataIndexOrderedByHistory(
135  InfoForTypeLabelInstance const& info) const;
136 
137  std::vector<art::BranchDescription const*> getProductDescriptions(
138  art::TypeID const& typeIDOfWrapper) const;
139 
140  BranchData const* getBranchData(InfoForTypeLabelInstance const& info,
141  unsigned int processIndex) const;
142 
143  BranchData const* getBranchData(art::BranchDescription const&) const;
144 
145  art::EDProductGetter const* getEDProductGetter_(
146  art::ProductID const&) const override;
147 
148  private: // MEMBER DATA
150 
151  TTree* tree_{nullptr};
152 
153  std::shared_ptr<EventHistoryGetter> historyGetter_;
154 
155  mutable bool initializedForProcessHistory_{false};
156 
157  mutable art::ProcessHistoryID previousProcessHistoryID_{};
158 
159  mutable std::vector<std::string> previousProcessHistoryNames_{};
160 
161  // Includes all processNames seen in ProcessHistories. They are
162  // pushed onto the back of the vector when first seen and then
163  // never modified or moved.
164  mutable std::vector<std::string> processNames_{};
165 
166  // The key to this map is the process name. The value is the index
167  // into the vector processNames_
168  mutable std::map<std::string, unsigned int> processNameToProcessIndex_{};
169 
170  // These are ordered by the current ProcessHistory
171  mutable std::vector<unsigned int> orderedProcessIndexes_{};
172 
173  // Note we just add to this, the order is never changed so an
174  // index into this can be cached. Entries are only added if and
175  // when data is requested via a getValidHandle function call or
176  // another similar function call. We should be able to combine
177  // the infoVector_ and infoMap_ into one object.
178  mutable std::vector<InfoForTypeLabelInstance> infoVector_{};
179 
180  // Use this to find the desired entry in the infoVector_ using a
181  // key with type, label, and instance.
182  mutable std::map<TypeLabelInstanceKey, unsigned int> infoMap_{};
183 
184  // The BranchData object contains the object that ROOT fills when
185  // reading the data. It also contains related items. Note we just
186  // add to this map. The TBranch* in BranchData will be set to
187  // nullptr if the TBranch does not exist in the current
188  // file. There are entries here when the data product is not
189  // "present" because the producer declared it but never put
190  // it. You have to read the data and check the isPresent bit to
191  // determine that. There will be one entry in a
192  // processIndexToProductID_ that points at each element in this
193  // vector. These are only created when needed, which can happen at
194  // three distinct points:
195  // 1. when a new InfoForTypeLabelInstance is constructed
196  // 2. when a new process is encountered in a process history
197  // 3. when a new input file is opened with new entries in its
198  // product registry.
199  mutable std::map<art::ProductID, std::unique_ptr<BranchData>>
200  branchDataMap_{};
201 
202  BranchData invalidBranchData_{};
203 
204  // Use this for get functions that use the ProductID. These are
205  // mostly used when dereferencing a Ptr.
206 
207  mutable std::set<art::ProductID> branchDataMissingSet_{};
208 
209  // Keeps track of information related to metadata.
210  BranchMapReader branchMapReader_{};
211 
212  mutable art::root::DictionaryChecker dictChecker_{};
213  };
214 
215 } // namespace gallery
216 
217 #endif /* gallery_DataGetterHelper_h */
218 
219 // Local Variables:
220 // mode: c++
221 // End:
std::string string
Definition: nybbler.cc:12
const std::string instance
EventNavigator const * eventNavigator_
std::pair< art::EDProduct const *, art::ProductID > ProductWithID
std::shared_ptr< EventHistoryGetter > historyGetter_