LDMX Software
Event.cxx
1#include "Framework/Event.h"
2
3#include "TBranchElement.h"
4
5namespace framework {
6
7Event::Event(const std::string& thePassName) : pass_name_(thePassName) {}
8
10 for (regex_t& reg : regex_drop_collections_) {
11 regfree(&reg);
12 }
13 for (regex_t& reg : regex_ignore_collections_) {
14 regfree(&reg);
15 }
16}
17
18void Event::print() const {
19 for (const ProductTag& tag : getProducts()) {
20 std::cout << tag << std::endl;
21 }
22}
23
24void Event::addDrop(const std::string& exp) {
25 regex_t reg;
26 if (!regcomp(&reg, exp.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
27 regex_drop_collections_.push_back(reg);
28 } else {
29 EXCEPTION_RAISE("InvalidRegex", "The passed drop rule regex '" + exp +
30 "' is not a valid regex.");
31 }
32}
33
34void Event::addIgnore(const std::string& exp) {
35 regex_t reg;
36 if (!regcomp(&reg, exp.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
37 regex_ignore_collections_.push_back(reg);
38 } else {
39 EXCEPTION_RAISE("InvalidRegex", "The passed ignore rule regex '" + exp +
40 "' is not a valid regex.");
41 }
42}
43
60static regex_t constructRegex(const std::string& pattern,
61 bool full_string_match) {
62 std::string pattern_regex{pattern};
63 if (pattern_regex.empty())
64 pattern_regex = ".*";
65 else if (full_string_match)
66 pattern_regex = "^" + pattern_regex + "$";
67
68 regex_t reg;
69 if (regcomp(&reg, pattern_regex.c_str(),
70 REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
71 // use input value in exception since we expect our code above evolving
72 // the regex to be accurate
73 EXCEPTION_RAISE("InvalidRegex", "The passed regex '" + pattern +
74 "' is not a valid regular expression.");
75 }
76 return reg;
77}
78
79std::vector<ProductTag> Event::searchProducts(const std::string& namematch,
80 const std::string& passmatch,
81 const std::string& typematch,
82 bool full_string_match) const {
83 std::vector<ProductTag> retval;
84 regex_t reg_name{constructRegex(namematch, full_string_match)},
85 reg_pass{constructRegex(passmatch, full_string_match)},
86 reg_type{constructRegex(typematch, full_string_match)};
87
88 // all passed expressions are valid regular expressions
89 const std::vector<ProductTag>& products = getProducts();
90 for (std::vector<ProductTag>::const_iterator i = products.begin();
91 i != products.end(); i++) {
92 if (!regexec(&reg_name, i->name().c_str(), 0, 0, 0) &&
93 !regexec(&reg_pass, i->passname().c_str(), 0, 0, 0) &&
94 !regexec(&reg_type, i->type().c_str(), 0, 0, 0))
95 retval.push_back(*i);
96 }
97
98 regfree(&reg_type);
99 regfree(&reg_pass);
100 regfree(&reg_name);
101
102 return retval;
103}
104
105bool Event::exists(const std::string& name, const std::string& passName,
106 bool unique) const {
107 static const bool require_full_string_match = true;
108 auto matches = searchProducts(name, passName, "", require_full_string_match);
109 if (unique)
110 return (matches.size() == 1);
111 else
112 return (matches.size() > 0);
113}
114
116 output_tree_ = new TTree("LDMX_Events", "LDMX Events");
117
118 return output_tree_;
119}
120
121void Event::setOutputTree(TTree* tree) { output_tree_ = tree; }
122
123void Event::setInputTree(TTree* tree) {
124 input_tree_ = tree;
125
126 // in some cases, setInputTree is called more than once,
127 // so reset branch listing before starting
128 products_.clear();
129 known_lookups_.clear(); // reset caching of empty pass requests
131
132 // put in EventHeader (only one without pass name)
133 products_.emplace_back(ldmx::EventHeader::BRANCH, "", "ldmx::EventHeader");
134
135 // find the names of all the existing branches
136 TObjArray* branches = input_tree_->GetListOfBranches();
137 if (!branches) {
138 EXCEPTION_RAISE(
139 "BadInputFile",
140 "Input tree doesn't have a list of branches but still made it to this "
141 "point. This is bad and has never been seen before!");
142 return;
143 }
144 for (int i = 0; i < branches->GetEntriesFast(); i++) {
145 std::string brname;
146 if (branches->At(i)) {
147 brname = branches->At(i)->GetName();
148 }
149 if (brname != ldmx::EventHeader::BRANCH) {
150 if (shouldIgnore(brname)) continue;
151 size_t j = brname.find("_");
152 auto br = dynamic_cast<TBranchElement*>(branches->At(i));
153 // can't determine type if branch isn't
154 // the higher-level TBranchElement type
155 // Only occurs if the type on the bus is one of:
156 // bool, short, int, long, float, double (BSILFD)
157 products_.emplace_back(
158 brname.substr(0, j), // collection name is before '_'
159 brname.substr(j + 1), // pass name is after
160 br ? br->GetClassName() : "BSILFD");
161 }
162 }
163}
164
169
172 branches_filled_.end()) {
173 // Event Header not copied from input and hasn't been added yet, need to put
174 // it in
176 }
177}
178
180 branches_filled_.clear(); // forget names of branches we filled
181 bus_.clear(); // clear the event objects individually but leave them on bus
182}
183
185
187 if (output_tree_)
188 output_tree_->ResetBranchAddresses(); // reset addresses for output branch
189 if (input_tree_)
190 input_tree_ = nullptr; // detach old input_tree (owned by EventFile)
191 known_lookups_.clear(); // reset caching of empty pass requests
192 bus_.everybodyOff(); // delete buffer objects
193}
194
195bool Event::shouldDrop(const std::string& branch_name) const {
196 for (const regex_t& exp : regex_drop_collections_) {
197 if (!regexec(&exp, branch_name.c_str(), 0, 0, 0)) return true;
198 }
199 return false;
200}
201
202bool Event::shouldIgnore(const std::string& branch_name) const {
203 for (const regex_t& exp : regex_ignore_collections_) {
204 if (!regexec(&exp, branch_name.c_str(), 0, 0, 0)) return true;
205 }
206 return false;
207}
208
209} // 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: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
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
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
TTree * createTree()
Create the output data tree.
Definition Event.cxx:115
ldmx::EventHeader event_header_
The event header object.
Definition Event.h:550
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
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
std::vector< regex_t > regex_drop_collections_
Regex of collection names to not store in event.
Definition Event.h:593
void setInputTree(TTree *tree)
Set the input data tree.
Definition Event.cxx:123
void print() const
Print event bus.
Definition Event.cxx:18
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
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:60