LDMX Software
Event.cxx
1#include "Framework/Event.h"
2
3#include <iostream>
4
5#include "TBranchElement.h"
6
7namespace framework {
8
9Event::Event(const std::string& thePassName) : pass_name_(thePassName) {}
10
12 for (regex_t& reg : regex_drop_collections_) {
13 regfree(&reg);
14 }
15 for (regex_t& reg : regex_ignore_collections_) {
16 regfree(&reg);
17 }
18}
19
20void Event::print() const {
21 for (const ProductTag& tag : getProducts()) {
22 std::cout << tag << std::endl;
23 }
24}
25
26void Event::addDrop(const std::string& exp) {
27 regex_t reg;
28 if (!regcomp(&reg, exp.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
29 regex_drop_collections_.push_back(reg);
30 } else {
31 EXCEPTION_RAISE("InvalidRegex", "The passed drop rule regex '" + exp +
32 "' is not a valid regex.");
33 }
34}
35
36void Event::addIgnore(const std::string& exp) {
37 regex_t reg;
38 if (!regcomp(&reg, exp.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
39 regex_ignore_collections_.push_back(reg);
40 } else {
41 EXCEPTION_RAISE("InvalidRegex", "The passed ignore rule regex '" + exp +
42 "' is not a valid regex.");
43 }
44}
45
62static regex_t constructRegex(const std::string& pattern,
63 bool full_string_match) {
64 std::string pattern_regex{pattern};
65 if (pattern_regex.empty())
66 pattern_regex = ".*";
67 else if (full_string_match)
68 pattern_regex = "^" + pattern_regex + "$";
69
70 regex_t reg;
71 if (regcomp(&reg, pattern_regex.c_str(),
72 REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
73 // use input value in exception since we expect our code above evolving
74 // the regex to be accurate
75 EXCEPTION_RAISE("InvalidRegex", "The passed regex '" + pattern +
76 "' is not a valid regular expression.");
77 }
78 return reg;
79}
80
81std::vector<ProductTag> Event::searchProducts(const std::string& namematch,
82 const std::string& passmatch,
83 const std::string& typematch,
84 bool full_string_match) const {
85 std::vector<ProductTag> retval;
86 regex_t reg_name{constructRegex(namematch, full_string_match)},
87 reg_pass{constructRegex(passmatch, full_string_match)},
88 reg_type{constructRegex(typematch, full_string_match)};
89
90 // all passed expressions are valid regular expressions
91 const std::vector<ProductTag>& products = getProducts();
92 for (std::vector<ProductTag>::const_iterator i = products.begin();
93 i != products.end(); i++) {
94 if (!regexec(&reg_name, i->name().c_str(), 0, 0, 0) &&
95 !regexec(&reg_pass, i->passname().c_str(), 0, 0, 0) &&
96 !regexec(&reg_type, i->type().c_str(), 0, 0, 0))
97 retval.push_back(*i);
98 }
99
100 regfree(&reg_type);
101 regfree(&reg_pass);
102 regfree(&reg_name);
103
104 return retval;
105}
106
107bool Event::exists(const std::string& name, const std::string& passName,
108 bool unique) const {
109 static const bool require_full_string_match = true;
110 auto matches = searchProducts(name, passName, "", require_full_string_match);
111 if (unique)
112 return (matches.size() == 1);
113 else
114 return (matches.size() > 0);
115}
116
118 output_tree_ = new TTree("LDMX_Events", "LDMX Events");
119
120 return output_tree_;
121}
122
123void Event::setOutputTree(TTree* tree) { output_tree_ = tree; }
124
125void Event::setInputTree(TTree* tree) {
126 input_tree_ = tree;
127
128 // in some cases, setInputTree is called more than once,
129 // so reset branch listing before starting
130 products_.clear();
131 known_lookups_.clear(); // reset caching of empty pass requests
133
134 // put in EventHeader (only one without pass name)
135 products_.emplace_back(ldmx::EventHeader::BRANCH, "", "ldmx::EventHeader");
136
137 // find the names of all the existing branches
138 TObjArray* branches = input_tree_->GetListOfBranches();
139 if (!branches) {
140 EXCEPTION_RAISE(
141 "BadInputFile",
142 "Input tree doesn't have a list of branches but still made it to this "
143 "point. This is bad and has never been seen before!");
144 return;
145 }
146 for (int i = 0; i < branches->GetEntriesFast(); i++) {
147 std::string brname;
148 if (branches->At(i)) {
149 brname = branches->At(i)->GetName();
150 }
151 if (brname != ldmx::EventHeader::BRANCH) {
152 if (shouldIgnore(brname)) continue;
153 size_t j = brname.find("_");
154 auto br = dynamic_cast<TBranchElement*>(branches->At(i));
155 // can't determine type if branch isn't
156 // the higher-level TBranchElement type
157 // Only occurs if the type on the bus is one of:
158 // bool, short, int, long, float, double (BSILFD)
159 products_.emplace_back(
160 brname.substr(0, j), // collection name is before '_'
161 brname.substr(j + 1), // pass name is after
162 br ? br->GetClassName() : "BSILFD");
163 }
164 }
165}
166
171
174 branches_filled_.end()) {
175 // Event Header not copied from input and hasn't been added yet, need to put
176 // it in
178 }
179}
180
182 branches_filled_.clear(); // forget names of branches we filled
183 bus_.clear(); // clear the event objects individually but leave them on bus
184}
185
187
189 if (output_tree_)
190 output_tree_->ResetBranchAddresses(); // reset addresses for output branch
191 if (input_tree_)
192 input_tree_ = nullptr; // detach old input_tree (owned by EventFile)
193 known_lookups_.clear(); // reset caching of empty pass requests
194 bus_.everybodyOff(); // delete buffer objects
195}
196
197bool Event::shouldDrop(const std::string& branch_name) const {
198 for (const regex_t& exp : regex_drop_collections_) {
199 if (!regexec(&exp, branch_name.c_str(), 0, 0, 0)) return true;
200 }
201 return false;
202}
203
204bool Event::shouldIgnore(const std::string& branch_name) const {
205 for (const regex_t& exp : regex_ignore_collections_) {
206 if (!regexec(&exp, branch_name.c_str(), 0, 0, 0)) return true;
207 }
208 return false;
209}
210
211} // namespace framework
Class implementing an event buffer system for storing event data.
void clear()
Reset the objects carried by the passengers.
Definition Bus.h:126
void everybodyOff()
Kicks all of the passengers off the bus and therefore destroys any objects they are carrying.
Definition Bus.h:140
void addIgnore(const std::string &exp)
Add an ignore rule to the list of regex expressions to ignore on input.
Definition Event.cxx:36
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:107
TTree * input_tree_
The input tree for reading existing data.
Definition Event.h:563
std::vector< ProductTag > products_
List of all the event products.
Definition Event.h:606
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:81
std::vector< regex_t > regex_ignore_collections_
Regex of branch names to not even read from the input tree.
Definition Event.h:596
void clear()
Clear this object's data (including passengers).
Definition Event.cxx:181
~Event()
Class destructor.
Definition Event.cxx:11
void onEndOfFile()
Perform end of file action.
Definition Event.cxx:188
TTree * createTree()
Create the output data tree.
Definition Event.cxx:117
ldmx::EventHeader event_header_
The event header object.
Definition Event.h:548
bool shouldIgnore(const std::string &branchName) const
Check if a branch from the input tree should be ignored.
Definition Event.cxx:204
void setOutputTree(TTree *tree)
Set the output data tree.
Definition Event.cxx:123
void beforeFill()
Action to be executed before the tree is filled.
Definition Event.cxx:172
void onEndOfEvent()
Perform end of event action (doesn't do anything right now).
Definition Event.cxx:186
const std::vector< ProductTag > & getProducts() const
Get a list of the data products in the event.
Definition Event.h:451
framework::Bus bus_
The Bus.
Definition Event.h:576
Event(const std::string &passName)
Class constructor.
Definition Event.cxx:9
const T & getObject(const std::string &collectionName, const std::string &passName) const
Get an general object from the event bus.
Definition Event.h:297
std::set< std::string > branches_filled_
Names of branches filled during this event.
Definition Event.h:586
bool nextEvent()
Go to the next event by retrieving the event header.
Definition Event.cxx:167
std::vector< regex_t > regex_drop_collections_
Regex of collection names to not store in event.
Definition Event.h:591
void setInputTree(TTree *tree)
Set the input data tree.
Definition Event.cxx:125
void print() const
Print event bus.
Definition Event.cxx:20
void add(const std::string &collectionName, T &obj)
Adds an object to the event bus.
Definition Event.h:193
bool shouldDrop(const std::string &collName) const
Check if collection should be dropped.
Definition Event.cxx:197
TTree * output_tree_
The output tree for writing a new file.
Definition Event.h:558
std::map< std::string, std::string > known_lookups_
Efficiency cache for empty pass name lookups.
Definition Event.h:601
void addDrop(const std::string &exp)
Add a drop rule to the list of regex expressions to drop.
Definition Event.cxx:26
Defines the identity of a product and can be used for searches.
Definition ProductTag.h:23
static const std::string BRANCH
Name of EventHeader branch.
Definition EventHeader.h:49
All classes in the ldmx-sw project use this namespace.
static regex_t constructRegex(const std::string &pattern, bool full_string_match)
Construct an actual regex from the pass pattern (and full-string flag)
Definition Event.cxx:62