LDMX Software
Event.h
Go to the documentation of this file.
1
8#ifndef FRAMEWORK_EVENT_H_
9#define FRAMEWORK_EVENT_H_
10
11// ROOT
12#include "TTree.h"
13
14// LDMX
15#include "Framework/Bus.h"
17#include "Framework/Exception/Exception.h"
19
20// STL
21#include <regex.h>
22
23#include <algorithm>
24#include <iostream>
25#include <map>
26#include <set>
27#include <sstream>
28#include <string>
29#include <typeinfo>
30
31namespace framework {
32
42class Event {
43 public:
48 Event(const std::string &passName);
49
53 ~Event();
54
60
66
71 int getEventNumber() const { return eventHeader_.getEventNumber(); }
72
77 double getEventWeight() const { return eventHeader_.getWeight(); }
78
84 void Print() const;
85
102 std::vector<ProductTag> searchProducts(const std::string &namematch,
103 const std::string &passmatch,
104 const std::string &typematch,
105 bool full_string_match = false) const;
106
135 bool exists(const std::string &name, const std::string &passName = "",
136 bool unique = true) const;
137
146 void addDrop(const std::string &exp);
147
173 template <typename T>
174 void add(const std::string &collectionName, T &obj) {
175 if (collectionName.find('_') != std::string::npos) {
176 EXCEPTION_RAISE("IllegalName",
177 "The product name '" + collectionName +
178 "' is illegal as it contains an underscore.");
179 }
180
181 // determine the branch name
182 std::string branchName;
183 if (collectionName == ldmx::EventHeader::BRANCH)
184 branchName = collectionName;
185 else
186 branchName = makeBranchName(collectionName);
187
188 if (branchesFilled_.find(branchName) != branchesFilled_.end()) {
189 EXCEPTION_RAISE("ProductExists",
190 "A product named '" + collectionName +
191 "' already exists in the event (has been loaded by a "
192 "previous producer in this process).");
193 }
194 branchesFilled_.insert(branchName);
195 // MEMORY add is leaking memory when given a vector (possible upon
196 // destruction of Event?) MEMORY add is 'conditional jump or move depends on
197 // uninitialised values' for all types of objects
198 // TTree::BranchImpRef or TTree::BronchExec
199 if (not bus_.isOnBoard(branchName)) {
200 // create a new branch for this collection
201
202 // have type T board bus under name 'branchName'
203 bus_.board<T>(branchName);
204
205 // type name (want to use branch element if possible)
206 std::string tname = typeid(obj).name();
207
208 if (outputTree_ and not shouldDrop(branchName)) {
209 // we are writing this branch to an output file, so let's
210 // attach this passenger to the output tree
211 TBranch *outBranch = bus_.attach(outputTree_, branchName, true);
212 // get type name from branch if possible,
213 // otherwise use compiler level type name (above)
214 std::string class_name{outBranch->GetClassName()};
215 if (not class_name.empty()) tname = class_name;
216 } // output tree exists or not
217
218 // check for cache entry to remove
219 auto it_known{knownLookups_.find(collectionName)};
220 if (it_known != knownLookups_.end()) knownLookups_.erase(it_known);
221
222 // add us to list of products
223 products_.emplace_back(collectionName, passName_, tname);
224 }
225
226 // copy input contents into bus passenger
227 try {
228 bus_.update(branchName, obj);
229 } catch (const std::bad_cast &) {
230 EXCEPTION_RAISE("TypeMismatch",
231 "Attempting to add an object whose type '" +
232 std::string(typeid(obj).name()) +
233 "' doesn't match the type stored in the collection.");
234 }
235
236 return;
237 }
238
277 template <typename T>
278 const T &getObject(const std::string &collectionName,
279 const std::string &passName = "") const {
280 // get branch name
281 std::string branchName;
282 if (collectionName == ldmx::EventHeader::BRANCH) {
283 branchName = collectionName;
284 } else if (passName.empty()) {
285 // if no passName, then find branchName by looking over known products
286 if (knownLookups_.find(collectionName) == knownLookups_.end()) {
287 // this collectionName hasn't been found before
288 // this collection name is the whole name and not a partial name
289 // so we search products with a full-string match required
290 auto matches = searchProducts(collectionName, "", "", true);
291 if (matches.empty()) {
292 // no matches found
293 EXCEPTION_RAISE("ProductNotFound",
294 "No product found for name '" + collectionName + "'");
295 } else if (matches.size() > 1) {
296 // more than one branch found
297 std::stringstream names;
298 for (auto strs : matches) {
299 names << "\n" << strs;
300 }
301 EXCEPTION_RAISE("ProductAmbiguous",
302 "Multiple products found for name '" +
303 collectionName +
304 "' without specified pass name :" + names.str());
305 } else {
306 // exactly one branch found -> cache for later
307 knownLookups_[collectionName] =
308 makeBranchName(collectionName, matches.at(0).passname());
309 } // different options for number of possible branch matches
310 } // collection not in known lookups
311 branchName = knownLookups_.at(collectionName);
312 } else {
313 branchName = makeBranchName(collectionName, passName);
314 }
315
316 // now we have determined the unique branch name to look for
317 // so we can start looking on the bus and the input tree
318 // (if it exists) for it
319 bool already_on_board{bus_.isOnBoard(branchName)};
320 if (not already_on_board and inputTree_) {
321 // branch is not on the bus but there is an input tree
322 // -> let's look for a new branch to load
323
324 // default construct a new passenger
325 bus_.board<T>(branchName);
326
327 // attempt to attach the new passenger to the input tree
328 TBranch *branch = bus_.attach(inputTree_, branchName, false);
329 if (branch == 0) {
330 // inputTree doesn't have that branch
331 EXCEPTION_RAISE("ProductNotFound", "No product found for branch '" +
332 branchName + "' on input tree.");
333 }
334 // ooh, new branch!
335 branch->SetStatus(1); // overrides any 'ignore' rules
346 long long int ientry{inputTree_->GetReadEntry()};
347 if (ientry < 0) {
348 // reached getObject without initializing inputTree's read entry
349 EXCEPTION_RAISE("InTreeInit",
350 "The input tree was un-initialized with read entry " +
351 std::to_string(ientry) +
352 " when attempting to get '" + branchName + "'.");
353 }
354 branch->GetEntry(ientry);
355 } else if (not already_on_board) {
356 // not found in loaded branches and there is no inputTree,
357 // so no hope of finding an unloaded object
358 EXCEPTION_RAISE("ProductNotFound", "No product found for name '" +
359 collectionName + "' and pass '" +
360 passName_ + "'");
361 }
362
363 // we've made sure the passenger is on the bus
364 // and the branch we are reading from (if we are reading)
365 // has been updated
366 // let's return the object that the passenger is carrying
367 try {
368 const T &obj = bus_.get<T>(branchName);
369 return obj;
370 } catch (const std::bad_cast &) {
371 EXCEPTION_RAISE("BadType",
372 "Trying to get product from '" + branchName +
373 "' but asking for wrong type: " + typeid(T).name());
374 }
375 } // getObject
376
387 template <typename ContentType>
388 const std::vector<ContentType> &getCollection(
389 const std::string &collectionName,
390 const std::string &passName = "") const {
391 return getObject<std::vector<ContentType> >(collectionName, passName);
392 }
393
405 template <typename KeyType, typename ValType>
406 const std::map<KeyType, ValType> &getMap(
407 const std::string &collectionName,
408 const std::string &passName = "") const {
409 return getObject<std::map<KeyType, ValType> >(collectionName, passName);
410 }
411
416 void setInputTree(TTree *tree);
417
422 void setOutputTree(TTree *tree);
423
428 TTree *createTree();
429
433 const std::vector<ProductTag> &getProducts() const { return products_; }
434
445 bool nextEvent();
446
450 void beforeFill();
451
455 void Clear();
456
460 void onEndOfEvent();
461
468 void onEndOfFile();
469
474 std::string getPassName() { return passName_; }
475
477 int getElectronCount() const { return electronCount_; }
478
484 void setElectronCount(const int &electronCount) {
485 electronCount_ = electronCount;
486 }
487
488 private:
495 bool shouldDrop(const std::string &collName) const;
496
502 std::string makeBranchName(const std::string &collectionName,
503 const std::string &passName) const {
504 return collectionName + "_" + passName;
505 }
506
511 std::string makeBranchName(const std::string &collectionName) const {
512 return makeBranchName(collectionName, passName_);
513 }
514
515 private:
520
524 std::string passName_;
525
529 TTree *outputTree_{nullptr};
530
534 TTree *inputTree_{nullptr};
535
538
548
557 std::set<std::string> branchesFilled_;
558
562 std::vector<regex_t> regexDropCollections_;
563
567 mutable std::map<std::string, std::string> knownLookups_;
568
572 std::vector<ProductTag> products_;
573};
574} // namespace framework
575
576#endif /* FRAMEWORK_EVENT_H_ */
Class that provides header information about an event such as event number and timestamp.
Class defining the identity of a data product in the event.
A map of bus passengers.
Definition Bus.h:29
const BaggageType & get(const std::string &name)
Get the baggage carried by the passenger with the passed name.
Definition Bus.h:43
void update(const std::string &name, const BaggageType &obj)
Update the object a passenger is carrying.
Definition Bus.h:83
bool isOnBoard(const std::string &name)
Check if a passenger is on the bus.
Definition Bus.h:117
TBranch * attach(TTree *tree, const std::string &name, bool can_create)
Attach the input tree to the object a passenger is carrying.
Definition Bus.h:107
void board(const std::string &name)
Board a new passenger onto the bus.
Definition Bus.h:65
Implements an event buffer system for storing event data.
Definition Event.h:42
std::string makeBranchName(const std::string &collectionName) const
Make a branch name from a collection and the default(current) pass name.
Definition Event.h:511
const std::vector< ContentType > & getCollection(const std::string &collectionName, const std::string &passName="") const
Get a collection (std::vector) of objects from the event bus.
Definition Event.h:388
void Print() const
Print event bus.
Definition Event.cxx:15
std::vector< ProductTag > products_
List of all the event products.
Definition Event.h:572
int getEventNumber() const
Get the event number.
Definition Event.h:71
std::vector< ProductTag > searchProducts(const std::string &namematch, const std::string &passmatch, const std::string &typematch, bool full_string_match=false) const
Get a list of products which match the given POSIX-Extended, case-insenstive regular-expressions.
Definition Event.cxx:66
std::vector< regex_t > regexDropCollections_
Regex of collection names to not store in event.
Definition Event.h:562
std::map< std::string, std::string > knownLookups_
Efficiency cache for empty pass name lookups.
Definition Event.h:567
~Event()
Class destructor.
Definition Event.cxx:9
void onEndOfFile()
Perform end of file action.
Definition Event.cxx:172
std::string makeBranchName(const std::string &collectionName, const std::string &passName) const
Make a branch name from a collection and pass name.
Definition Event.h:502
TTree * createTree()
Create the output data tree.
Definition Event.cxx:102
void setElectronCount(const int &electronCount)
Set the beam electron count.
Definition Event.h:484
std::string passName_
The default pass name.
Definition Event.h:524
TTree * inputTree_
The input tree for reading existing data.
Definition Event.h:534
void setOutputTree(TTree *tree)
Set the output data tree.
Definition Event.cxx:108
double getEventWeight() const
Get the event weight.
Definition Event.h:77
void beforeFill()
Action to be executed before the tree is filled.
Definition Event.cxx:156
void onEndOfEvent()
Perform end of event action (doesn't do anything right now).
Definition Event.cxx:170
void Clear()
Clear this object's data (including passengers).
Definition Event.cxx:165
const std::vector< ProductTag > & getProducts() const
Get a list of the data products in the event.
Definition Event.h:433
TTree * outputTree_
The output tree for writing a new file.
Definition Event.h:529
ldmx::EventHeader eventHeader_
The event header object.
Definition Event.h:519
framework::Bus bus_
The Bus.
Definition Event.h:547
Event(const std::string &passName)
Class constructor.
Definition Event.cxx:7
bool nextEvent()
Go to the next event by retrieving the event header.
Definition Event.cxx:151
ldmx::EventHeader & getEventHeader()
Get the event header.
Definition Event.h:59
const std::map< KeyType, ValType > & getMap(const std::string &collectionName, const std::string &passName="") const
Get a map (std::map) of objects from the event bus.
Definition Event.h:406
const ldmx::EventHeader * getEventHeaderPtr()
Get the event header as a pointer.
Definition Event.h:65
std::set< std::string > branchesFilled_
Names of branches filled during this event.
Definition Event.h:557
void setInputTree(TTree *tree)
Set the input data tree.
Definition Event.cxx:110
std::string getPassName()
Get the current/default pass name.
Definition Event.h:474
int electronCount_
The total number of electrons in the event.
Definition Event.h:537
const T & getObject(const std::string &collectionName, const std::string &passName="") const
Get an general object from the event bus.
Definition Event.h:278
void add(const std::string &collectionName, T &obj)
Adds an object to the event bus.
Definition Event.h:174
bool shouldDrop(const std::string &collName) const
Check if collection should be dropped.
Definition Event.cxx:181
bool exists(const std::string &name, const std::string &passName="", bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:92
void addDrop(const std::string &exp)
Add a drop rule to the list of regex expressions to drop.
Definition Event.cxx:21
int getElectronCount() const
Definition Event.h:477
Provides header information an event such as event number and timestamp.
Definition EventHeader.h:44
double getWeight() const
Get the event weight (default of 1.0).
Definition EventHeader.h:98
int getEventNumber() const
Return the event number.
Definition EventHeader.h:78
static const std::string BRANCH
Name of EventHeader branch.
Definition EventHeader.h:49
All classes in the ldmx-sw project use this namespace.
Definition PerfDict.cxx:45