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
76
82
87 double getEventWeight() const { return event_header_.getWeight(); }
88
94 void print() const;
95
112 std::vector<ProductTag> searchProducts(const std::string &namematch,
113 const std::string &passmatch,
114 const std::string &typematch,
115 bool full_string_match = false) const;
116
145 bool exists(const std::string &name, const std::string &passName,
146 bool unique = true) const;
147
156 void addDrop(const std::string &exp);
157
167 void addIgnore(const std::string &exp);
168
194 template <typename T>
195 void add(const std::string &collectionName, T &obj) {
196 if (collectionName.find('_') != std::string::npos) {
197 EXCEPTION_RAISE("IllegalName",
198 "The product name '" + collectionName +
199 "' is illegal as it contains an underscore.");
200 }
201
202 // determine the branch name
203 std::string branch_name;
204 if (collectionName == ldmx::EventHeader::BRANCH)
205 branch_name = collectionName;
206 else
207 branch_name = makeBranchName(collectionName);
208
209 if (branches_filled_.find(branch_name) != branches_filled_.end()) {
210 EXCEPTION_RAISE("ProductExists",
211 "A product named '" + collectionName +
212 "' already exists in the event (has been loaded by a "
213 "previous producer in this process).");
214 }
215 branches_filled_.insert(branch_name);
216 // MEMORY add is leaking memory when given a vector (possible upon
217 // destruction of Event?) MEMORY add is 'conditional jump or move depends on
218 // uninitialised values' for all types of objects
219 // TTree::BranchImpRef or TTree::BronchExec
220 if (not bus_.isOnBoard(branch_name)) {
221 // create a new branch for this collection
222
223 // have type T board bus under name 'branchName'
224 bus_.board<T>(branch_name);
225
226 // type name (want to use branch element if possible)
227 std::string tname = typeid(obj).name();
228
229 if (output_tree_ and not shouldDrop(branch_name)) {
230 // we are writing this branch to an output file, so let's
231 // attach this passenger to the output tree
232 TBranch *out_branch = bus_.attach(output_tree_, branch_name, true);
233 // get type name from branch if possible,
234 // otherwise use compiler level type name (above)
235 std::string class_name{out_branch->GetClassName()};
236 if (not class_name.empty()) tname = class_name;
237 } // output tree exists or not
238
239 // check for cache entry to remove
240 auto it_known{known_lookups_.find(collectionName)};
241 if (it_known != known_lookups_.end()) known_lookups_.erase(it_known);
242
243 // add us to list of products
244 products_.emplace_back(collectionName, pass_name_, tname);
245 }
246
247 // copy input contents into bus passenger
248 try {
249 bus_.update(branch_name, obj);
250 } catch (const std::bad_cast &) {
251 EXCEPTION_RAISE("TypeMismatch",
252 "Attempting to add an object whose type '" +
253 std::string(typeid(obj).name()) +
254 "' doesn't match the type stored in the collection.");
255 }
256
257 return;
258 }
259
298 template <typename T>
299 const T &getObject(const std::string &collectionName,
300 const std::string &passName) const {
301 // get branch name
302 std::string branch_name;
303 if (collectionName == ldmx::EventHeader::BRANCH) {
304 branch_name = collectionName;
305 } else if (passName.empty()) {
306 // if no passName, then find branchName by looking over known products
307 if (known_lookups_.find(collectionName) == known_lookups_.end()) {
308 // this collectionName hasn't been found before
309 // this collection name is the whole name and not a partial name
310 // so we search products with a full-string match required
311 auto matches = searchProducts(collectionName, "", "", true);
312 if (matches.empty()) {
313 // no matches found
314 EXCEPTION_RAISE("ProductNotFound",
315 "No product found for name '" + collectionName + "'");
316 } else if (matches.size() > 1) {
317 // more than one branch found
318 std::stringstream names;
319 for (auto strs : matches) {
320 names << "\n" << strs;
321 }
322 EXCEPTION_RAISE("ProductAmbiguous",
323 "Multiple products found for name '" +
324 collectionName +
325 "' without specified pass name :" + names.str());
326 } else {
327 // exactly one branch found -> cache for later
328 known_lookups_[collectionName] =
329 makeBranchName(collectionName, matches.at(0).passname());
330 } // different options for number of possible branch matches
331 } // collection not in known lookups
332 branch_name = known_lookups_.at(collectionName);
333 } else {
334 branch_name = makeBranchName(collectionName, passName);
335 }
336
337 // now we have determined the unique branch name to look for
338 // so we can start looking on the bus and the input tree
339 // (if it exists) for it
340 bool already_on_board{bus_.isOnBoard(branch_name)};
341 if (not already_on_board and input_tree_) {
342 // branch is not on the bus but there is an input tree
343 // -> let's look for a new branch to load
344
345 // default construct a new passenger
346 bus_.board<T>(branch_name);
347
348 // attempt to attach the new passenger to the input tree
349 TBranch *branch = bus_.attach(input_tree_, branch_name, false);
350 if (branch == 0) {
351 // inputTree doesn't have that branch
352 EXCEPTION_RAISE(
353 "ProductNotFound",
354 "No product found for branch '" + branch_name + "' on input tree.");
355 }
356 // ooh, new branch!
357 branch->SetStatus(1); // overrides any 'ignore' rules
368 long long int ientry{input_tree_->GetReadEntry()};
369 if (ientry < 0) {
370 // reached getObject without initializing inputTree's read entry
371 EXCEPTION_RAISE("InTreeInit",
372 "The input tree was un-initialized with read entry " +
373 std::to_string(ientry) +
374 " when attempting to get '" + branch_name + "'.");
375 }
376 branch->GetEntry(ientry);
377 } else if (not already_on_board) {
378 // not found in loaded branches and there is no inputTree,
379 // so no hope of finding an unloaded object
380 EXCEPTION_RAISE("ProductNotFound", "No product found for name '" +
381 collectionName + "' and pass '" +
382 pass_name_ + "'");
383 }
384
385 // we've made sure the passenger is on the bus
386 // and the branch we are reading from (if we are reading)
387 // has been updated
388 // let's return the object that the passenger is carrying
389 try {
390 const T &obj = bus_.get<T>(branch_name);
391 return obj;
392 } catch (const std::bad_cast &) {
393 EXCEPTION_RAISE("BadType",
394 "Trying to get product from '" + branch_name +
395 "' but asking for wrong type: " + typeid(T).name());
396 }
397 } // getObject
398
410 template <typename ContentType>
411 const std::vector<ContentType> &getCollection(
412 const std::string &collectionName, const std::string &passName) const {
413 return getObject<std::vector<ContentType> >(collectionName, passName);
414 }
415
427 template <typename KeyType, typename ValType>
428 const std::map<KeyType, ValType> &getMap(const std::string &collectionName,
429 const std::string &passName) const {
430 return getObject<std::map<KeyType, ValType> >(collectionName, passName);
431 }
436 void setInputTree(TTree *tree);
437
442 void setOutputTree(TTree *tree);
443
448 TTree *createTree();
449
453 const std::vector<ProductTag> &getProducts() const { return products_; }
454
465 bool nextEvent();
466
470 void beforeFill();
471
475 void clear();
476
480 void onEndOfEvent();
481
488 void onEndOfFile();
489
494 std::string getPassName() { return pass_name_; }
495
497 int getElectronCount() const { return electron_count_; }
498
504 void setElectronCount(const int &electronCount) {
505 electron_count_ = electronCount;
506 }
507
508 private:
515 bool shouldDrop(const std::string &collName) const;
516
526 bool shouldIgnore(const std::string &branchName) const;
527
533 std::string makeBranchName(const std::string &collectionName,
534 const std::string &passName) const {
535 return collectionName + "_" + passName;
536 }
537
542 std::string makeBranchName(const std::string &collectionName) const {
543 return makeBranchName(collectionName, pass_name_);
544 }
545
546 private:
551
555 std::string pass_name_;
556
560 TTree *output_tree_{nullptr};
561
565 TTree *input_tree_{nullptr};
566
569
579
588 std::set<std::string> branches_filled_;
589
593 std::vector<regex_t> regex_drop_collections_;
594
598 std::vector<regex_t> regex_ignore_collections_;
599
603 mutable std::map<std::string, std::string> known_lookups_;
604
608 std::vector<ProductTag> products_;
609};
610} // namespace framework
611
612#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
const ldmx::EventHeader & getEventHeader() const
Get the event header.
Definition Event.h:65
std::string makeBranchName(const std::string &collectionName) const
Make a branch name from a collection and the default(current) pass name.
Definition Event.h:542
void addIgnore(const std::string &exp)
Add an ignore rule to the list of regex expressions to ignore on input.
Definition Event.cxx:34
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:105
TTree * input_tree_
The input tree for reading existing data.
Definition Event.h:565
std::vector< ProductTag > products_
List of all the event products.
Definition Event.h:608
int getEventNumber() const
Get the event number.
Definition Event.h:81
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:79
int electron_count_
The total number of electrons in the event.
Definition Event.h:568
std::vector< regex_t > regex_ignore_collections_
Regex of branch names to not even read from the input tree.
Definition Event.h:598
void clear()
Clear this object's data (including passengers).
Definition Event.cxx:179
~Event()
Class destructor.
Definition Event.cxx:9
void onEndOfFile()
Perform end of file action.
Definition Event.cxx:186
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:533
TTree * createTree()
Create the output data tree.
Definition Event.cxx:115
ldmx::EventHeader event_header_
The event header object.
Definition Event.h:550
void setElectronCount(const int &electronCount)
Set the beam electron count.
Definition Event.h:504
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:428
bool shouldIgnore(const std::string &branchName) const
Check if a branch from the input tree should be ignored.
Definition Event.cxx:202
void setOutputTree(TTree *tree)
Set the output data tree.
Definition Event.cxx:121
std::string pass_name_
The default pass name.
Definition Event.h:555
double getEventWeight() const
Get the event weight.
Definition Event.h:87
void beforeFill()
Action to be executed before the tree is filled.
Definition Event.cxx:170
void onEndOfEvent()
Perform end of event action (doesn't do anything right now).
Definition Event.cxx:184
const std::vector< ProductTag > & getProducts() const
Get a list of the data products in the event.
Definition Event.h:453
framework::Bus bus_
The Bus.
Definition Event.h:578
Event(const std::string &passName)
Class constructor.
Definition Event.cxx:7
const T & getObject(const std::string &collectionName, const std::string &passName) const
Get an general object from the event bus.
Definition Event.h:299
std::set< std::string > branches_filled_
Names of branches filled during this event.
Definition Event.h:588
bool nextEvent()
Go to the next event by retrieving the event header.
Definition Event.cxx:165
ldmx::EventHeader & getEventHeader()
Get the event header.
Definition Event.h:59
const ldmx::EventHeader * getEventHeaderPtr()
Get the event header as a pointer.
Definition Event.h:75
std::vector< regex_t > regex_drop_collections_
Regex of collection names to not store in event.
Definition Event.h:593
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:411
void setInputTree(TTree *tree)
Set the input data tree.
Definition Event.cxx:123
void print() const
Print event bus.
Definition Event.cxx:18
std::string getPassName()
Get the current/default pass name.
Definition Event.h:494
void add(const std::string &collectionName, T &obj)
Adds an object to the event bus.
Definition Event.h:195
bool shouldDrop(const std::string &collName) const
Check if collection should be dropped.
Definition Event.cxx:195
TTree * output_tree_
The output tree for writing a new file.
Definition Event.h:560
std::map< std::string, std::string > known_lookups_
Efficiency cache for empty pass name lookups.
Definition Event.h:603
void addDrop(const std::string &exp)
Add a drop rule to the list of regex expressions to drop.
Definition Event.cxx:24
int getElectronCount() const
Definition Event.h:497
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.