LDMX Software
framework::EventFile Class Reference

This class manages all ROOT file input/output operations. More...

#include <EventFile.h>

Public Member Functions

 EventFile (const framework::config::Parameters &params, const std::string &filename, EventFile *parent, bool isOutputFile, bool isSingleOutput, bool isLoopable)
 Constructor to make a general file.
 
 EventFile (const framework::config::Parameters &param, const std::string &fileName, bool isLoopable)
 Constructor to make a pileup overlay file.
 
 EventFile (const framework::config::Parameters &param, const std::string &fileName, EventFile *parent, bool isSingleOutput=false)
 Class constructor for cloning data from a "parent" file.
 
 EventFile (const framework::config::Parameters &params, const std::string &fileName)
 Class constructor to make a file to read in an event root file.
 
 ~EventFile ()
 Destructor.
 
bool isCorrupted () const
 Check if the file we have is corrupted.
 
void addDrop (const std::string &rule)
 Add a rule for dropping collections from the output.
 
void setupEvent (Event *evt)
 Set an Event object containing the event data to work with this file.
 
void updateParent (EventFile *parent)
 Change pointer to different parent file.
 
EventgetEvent ()
 Get the Event object containing the event data.
 
bool nextEvent (bool storeCurrentEvent=true)
 Prepare the next event.
 
int skipToEvent (int offset)
 Skip events using an offset.
 
void writeRunHeader (ldmx::RunHeader &runHeader)
 Write the run header into the run map.
 
void writeRunTree ()
 Write the map of run headers to the file as a TTree of RunHeader.
 
ldmx::RunHeadergetRunHeaderPtr (int runNumber)
 Update the RunHeader for a given run, if it exists in the input file.
 
ldmx::RunHeadergetRunHeader (int runNumber)
 Get the RunHeader for a given run, if it exists in the input file.
 
const std::string & getFileName ()
 

Private Member Functions

void importRunHeaders ()
 Fill the internal map of run numbers to RunHeader objects from the input file.
 

Private Attributes

Long64_t entries_ {-1}
 The number of entries in the tree.
 
Long64_t ientry_ {-1}
 The current entry in the tree.
 
std::string file_name_
 The file name.
 
bool is_output_file_
 True if file is an output file being written to disk.
 
bool is_single_output_
 True if there is only one output file.
 
bool is_loopable_ {false}
 True if this is an input file with pileup overlay events *‍/.
 
TFile * file_ {nullptr}
 The backing TFile for this EventFile.
 
TTree * tree_ {nullptr}
 The tree with event data.
 
EventFileparent_ {nullptr}
 A parent file containing event data.
 
Eventevent_ {nullptr}
 The object containing the actual event data (trees and branches).
 
std::vector< std::pair< std::string, bool > > pre_clone_rules_
 Pre-clone rules.
 
std::vector< std::string > reactivate_rules_
 Vector of drop rules that have been parsed and need to be used to reactivate these branches on the input tree.
 
std::map< int, std::pair< bool, ldmx::RunHeader * > > run_map_
 Map of run numbers to RunHeader objects.
 

Detailed Description

This class manages all ROOT file input/output operations.

Definition at line 27 of file EventFile.h.

Constructor & Destructor Documentation

◆ EventFile() [1/4]

framework::EventFile::EventFile ( const framework::config::Parameters & params,
const std::string & filename,
EventFile * parent,
bool isOutputFile,
bool isSingleOutput,
bool isLoopable )

Constructor to make a general file.

This is not used directly, but it is called in the more specialised constructors. This method is mainly focused on reducing code copying.

Parameters
[in]paramsThe parameters used to configure this EventFile.
[in]filenamethe name of the file to read/write
[in]parenta pointer to the parent file to copy
[in]isOutputFiletrue if this file is written out
[in]isSingleOutputtrue if only one output file is being written to
[in]isLoopabletrue for an input file where events can be reused

Definition at line 15 of file EventFile.cxx.

19 : file_name_(filename),
20 is_output_file_(is_output_file),
21 is_single_output_(is_single_output),
22 is_loopable_(is_loopable),
23 parent_(parent) {
24 if (is_output_file_) {
25 // we are writting out so open the file and make sure it is writable
26 file_ = new TFile(file_name_.c_str(), "RECREATE");
27 if (!file_->IsOpen() or !file_->IsWritable()) {
28 EXCEPTION_RAISE("FileError",
29 "Output file '" + file_name_ + "' is not writable.");
30 }
31
32 // set compression settings
33 // Check out the TFile constructor for explanation of how this integer is
34 // built Short Reference: setting = 100*algorithem + level algorithm = 0
35 // ==> use global default
36 file_->SetCompressionSettings(params.get<int>("compression_setting", 9));
37
38 if (parent_) {
39 // output file when there are input files
40 // might be drop/keep rules, so we should have these rules to make sure
41 // it works
42
43 // turn everything on
44 // hypothetically could turn everything off? Doesn't work for some
45 // reason?
46 pre_clone_rules_.emplace_back("*", true);
47
48 // except EventHeader (copies over to output)
49 pre_clone_rules_.emplace_back("EventHeader*", true);
50
51 // reactivate all branches so default behavior is drop
52 reactivate_rules_.push_back("*");
53 }
54 } else {
55 // open file with only reading enabled
56 file_ = new TFile(file_name_.c_str());
57 // double check that file is open
58 if (!file_->IsOpen()) {
59 EXCEPTION_RAISE("FileError", "Input file '" + file_name_ +
60 "' is not readable or does not exist.");
61 }
62
63 bool skip_corrupted = params.get<bool>("skip_corrupted_input_files", false);
64
65 // make sure file is not a zombie file
66 // (i.e. process ended without closing or the file was corrupted some other
67 // way)
68 if (file_->IsZombie()) {
69 if (not skip_corrupted) {
70 EXCEPTION_RAISE("FileError", "Input file '" + file_name_ +
71 "' is corrupted. Framework will not "
72 "attempt to recover this file.");
73 }
74 return;
75 }
76
77 // Get the tree name from the configuration
78 auto tree_name{params.get<std::string>("tree_name")};
79 tree_ = static_cast<TTree *>(file_->Get(tree_name.c_str()));
80 if (!tree_) {
81 if (not skip_corrupted) {
82 EXCEPTION_RAISE("FileError", "File '" + file_name_ +
83 "' does not have a TTree named '" +
84 tree_name + "' in it.");
85 }
86 return;
87 }
88 entries_ = tree_->GetEntriesFast();
89 }
90
92}
TFile * file_
The backing TFile for this EventFile.
Definition EventFile.h:300
Long64_t entries_
The number of entries in the tree.
Definition EventFile.h:282
std::vector< std::pair< std::string, bool > > pre_clone_rules_
Pre-clone rules.
Definition EventFile.h:317
bool is_loopable_
True if this is an input file with pileup overlay events *‍/.
Definition EventFile.h:297
void importRunHeaders()
Fill the internal map of run numbers to RunHeader objects from the input file.
std::string file_name_
The file name.
Definition EventFile.h:288
bool is_single_output_
True if there is only one output file.
Definition EventFile.h:294
EventFile * parent_
A parent file containing event data.
Definition EventFile.h:306
std::vector< std::string > reactivate_rules_
Vector of drop rules that have been parsed and need to be used to reactivate these branches on the in...
Definition EventFile.h:326
bool is_output_file_
True if file is an output file being written to disk.
Definition EventFile.h:291
TTree * tree_
The tree with event data.
Definition EventFile.h:303
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78

References entries_, file_, file_name_, framework::config::Parameters::get(), importRunHeaders(), is_output_file_, parent_, pre_clone_rules_, reactivate_rules_, and tree_.

◆ EventFile() [2/4]

framework::EventFile::EventFile ( const framework::config::Parameters & param,
const std::string & fileName,
bool isLoopable )

Constructor to make a pileup overlay file.

This is an additional input file from which collections are pulled to be overlaid with simulated hit collections.

Parameters
[in]paramsThe parameters used to configure this EventFile.
fileNameThe file name.
isLoopabletrue if we want to reset the event counter and keep processing from the start when we hit the end of the event tree in this input file (set in the call in the producer)

Definition at line 94 of file EventFile.cxx.

96 : EventFile(params, filename, nullptr, false, false, is_loopable) {}
EventFile(const framework::config::Parameters &params, const std::string &filename, EventFile *parent, bool isOutputFile, bool isSingleOutput, bool isLoopable)
Constructor to make a general file.
Definition EventFile.cxx:15

◆ EventFile() [3/4]

framework::EventFile::EventFile ( const framework::config::Parameters & param,
const std::string & fileName,
EventFile * parent,
bool isSingleOutput = false )

Class constructor for cloning data from a "parent" file.

This is used for output files when there is an input file. (OR for files with a parent EventFile to clone)

Parameters
[in]paramsThe parameters used to configure this EventFile.
[in]fileNameThe file name.
[in]parentParent file for cloning data tree.
[in]isSingleOutputboolean check if only one output file is being written to

Definition at line 102 of file EventFile.cxx.

105 : EventFile(params, filename, parent, true, is_single_output, false) {}

◆ EventFile() [4/4]

framework::EventFile::EventFile ( const framework::config::Parameters & params,
const std::string & fileName )

Class constructor to make a file to read in an event root file.

This constructor just wraps the constructor above and sets the parent to null and the parameters isOutputFile/isSingleOutput to false.

This is used for all input files.

Parameters
[in]paramsThe parameters used to configure this EventFile.
[in]fileNameThe file name.

Definition at line 98 of file EventFile.cxx.

100 : EventFile(params, filename, nullptr, false, false, false) {}

◆ ~EventFile()

framework::EventFile::~EventFile ( )

Destructor.

Make sure to close the file when we destruct

Definition at line 107 of file EventFile.cxx.

107 {
108 // Before an output file, the Event tree needs to be written.
109 if (is_output_file_) {
110 // make sure we are in output file before writing
111 file_->cd();
112 tree_->Write();
113 }
114
115 // Close the file
116 file_->Close();
117}

References file_, is_output_file_, and tree_.

Member Function Documentation

◆ addDrop()

void framework::EventFile::addDrop ( const std::string & rule)

Add a rule for dropping collections from the output.

This needs to be called after setupEvent. This method uses the event to help drop collections.

The rules should be of the following form: <drop,keep, or ignore> exp where exp is an expression that matches the collectionName. ignore ==> any branch with name matching exp is not even read in from the input file (if it exists) keep ==> any branch with name matching exp is read in from the input (if exists) and written to output (if exists) drop ==> any branch with name matching exp is read in from the input (if exists) and NOT written to output

The default behavior for all branches is keep.

ROOT uses the internal TRegexp to match branch names to the passed expression and set the status of the branch (whether it will be read or not). This internal object has different rules than real regular expressions, so it is best to keep it safe and only use asterisks or full names. Additionally, the rules you pass are analyzed in succession, so you can go from something more general to something more specific.

For example to drop all EcalSimHits.* drop EcalSimHits.*

or drop scoring plane collections drop .*ScoringPlane.*

or drop scoring plane collections but keep EcalScoringPlane collection drop .*ScoringPlane.* keep EcalScoringPlane.*

Note
The Event::getImpl overrides any ignore rules for the input file in order to avoid any seg faults. The items accessed will still be dropped.
Parameters
ruleThe rule for dropping collections.

Definition at line 124 of file EventFile.cxx.

124 {
125 int offset;
126 bool is_keep = false, is_drop = false, is_ignore = false;
127 // keywords must appear at the start of the rule string
128 if (rule.find("keep") == 0) {
129 offset = 4;
130 is_keep = true;
131 } else if (rule.find("drop") == 0) {
132 offset = 4;
133 is_drop = true;
134 } else if (rule.find("ignore") == 0) {
135 offset = 6;
136 is_ignore = true;
137 }
138
139 // none of (keep,drop,ignore) was provided => not valid rule
140 if (int(is_keep) + int(is_drop) + int(is_ignore) != 1) return;
141
142 std::string srule = rule.substr(offset);
143 size_t i;
144 for (i = srule.find_first_of(" \t\n\r"); i != std::string::npos;
145 i = srule.find_first_of(" \t\n\r"))
146 srule.erase(i, 1);
147
148 // name of branch is not given
149 if (srule.length() == 0) return;
150
151 // add wild card at end for matching purposes
152 if (srule.back() != '*') srule += ".*"; // add wildcard to back
153
154 // Guard: EventHeader must never be dropped or ignored
155 if (is_drop or is_ignore) {
156 regex_t guard_reg;
157 if (regcomp(&guard_reg, srule.c_str(),
158 REG_EXTENDED | REG_ICASE | REG_NOSUB) == 0) {
159 bool matches_event_header =
160 (regexec(&guard_reg, ldmx::EventHeader::BRANCH.c_str(), 0, 0, 0) ==
161 0);
162 regfree(&guard_reg);
163 if (matches_event_header) {
164 EXCEPTION_RAISE("BadRule",
165 "Drop/ignore rule '" + rule +
166 "' would affect EventHeader which is required by "
167 "the framework and cannot be removed.");
168 }
169 }
170 }
171
172 if (is_keep) {
173 // turn both the input and output tree's on
174 // root needs . removed otherwise it gets cranky
175 srule.erase(std::remove(srule.begin(), srule.end(), '.'), srule.end());
176 pre_clone_rules_.emplace_back(srule, true);
177 // this branch will then be copied over into output tree and be active
178 } else if (is_ignore) {
179 // don't even read it from the input file
180 // pass regex (with dots) to event bus so setInputTree skips these branches
181 event_->addIgnore(srule); // requires event_ to be set
182 // root needs . removed otherwise it gets cranky
183 srule.erase(std::remove(srule.begin(), srule.end(), '.'), srule.end());
184 // warn if this rule drops all collections
185 if (srule == "*")
186 ldmx_log(fatal) << "Ignore rule '" << rule
187 << "' will hide all input collections from processors.";
188 pre_clone_rules_.emplace_back(srule, false);
189 // these branches won't be copied over into output tree
190 } else if (is_drop) {
191 // drop means allowing it on reading but not writing
192 // pass these regex to event bus so Event::add knows
193 event_->addDrop(srule); // requires event_ to be set
194
195 // root needs . removed otherwise it gets cranky
196 srule.erase(std::remove(srule.begin(), srule.end(), '.'), srule.end());
197 // warn if this rule drops all collections
198 if (srule == "*")
199 ldmx_log(fatal) << "Drop rule '" << rule
200 << "' will drop all collections from the output file.";
201 pre_clone_rules_.emplace_back(srule, false);
202 // these branches won't be copied over into output tree
203 // reactivate input branch after clone
204 reactivate_rules_.push_back(srule);
205 }
206}
Event * event_
The object containing the actual event data (trees and branches).
Definition EventFile.h:309
void addIgnore(const std::string &exp)
Add an ignore rule to the list of regex expressions to ignore on input.
Definition Event.cxx:34
void addDrop(const std::string &exp)
Add a drop rule to the list of regex expressions to drop.
Definition Event.cxx:24
static const std::string BRANCH
Name of EventHeader branch.
Definition EventHeader.h:49

References framework::Event::addDrop(), framework::Event::addIgnore(), ldmx::EventHeader::BRANCH, event_, pre_clone_rules_, and reactivate_rules_.

Referenced by framework::Process::run().

◆ getEvent()

Event * framework::EventFile::getEvent ( )
inline

Get the Event object containing the event data.

Returns
The Event object containing event data.

Definition at line 182 of file EventFile.h.

182{ return event_; };

References event_.

◆ getFileName()

const std::string & framework::EventFile::getFileName ( )
inline
Returns
the name of the ROOT file being managed.

Definition at line 259 of file EventFile.h.

259{ return file_name_; }

References file_name_.

Referenced by framework::Process::run().

◆ getRunHeader()

ldmx::RunHeader & framework::EventFile::getRunHeader ( int runNumber)

Get the RunHeader for a given run, if it exists in the input file.

Parameters
runNumberThe run number.
Returns
The RunHeader from the input file.
Exceptions
Exceptionif there is no RunHeader in the map with the given run number.

Definition at line 419 of file EventFile.cxx.

419 {
420 ldmx::RunHeader *rh{this->getRunHeaderPtr(run_number)};
421 if (rh != nullptr) {
422 return *rh;
423 }
424 EXCEPTION_RAISE("RunHeader", "Unable to find header for run " +
425 std::to_string(run_number));
426}
ldmx::RunHeader * getRunHeaderPtr(int runNumber)
Update the RunHeader for a given run, if it exists in the input file.
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:57

References getRunHeaderPtr().

◆ getRunHeaderPtr()

ldmx::RunHeader * framework::EventFile::getRunHeaderPtr ( int runNumber)

Update the RunHeader for a given run, if it exists in the input file.

Parameters
[in]runNumberThe run number.
Returns
pointer to the header corresponding to the run number
Note
the returned pointer will be nullptr if the run was not found

Definition at line 412 of file EventFile.cxx.

412 {
413 if (run_map_.find(run_number) != run_map_.end()) {
414 return run_map_.at(run_number).second;
415 }
416 return nullptr;
417}
std::map< int, std::pair< bool, ldmx::RunHeader * > > run_map_
Map of run numbers to RunHeader objects.
Definition EventFile.h:338

References run_map_.

Referenced by getRunHeader(), and framework::Process::run().

◆ importRunHeaders()

void framework::EventFile::importRunHeaders ( )
private

Fill the internal map of run numbers to RunHeader objects from the input file.

If this file is an output file and parent_ and parent_->file_ are valid pointers, then the run headers are imported from parent_->file_.

Otherwise, we try to import run headers from file_.

Does not check if any run headers are getting overwritten!

Any RunHeaders read in from this function are owned by this instance of EventFile and are deleted in close().

Note
This function does nothing if parent_->file_ and file_ are nullptrs.

Definition at line 428 of file EventFile.cxx.

428 {
429 // choose which file to import from
430 auto the_import_file{file_}; // if this is an input file
432 the_import_file = parent_->file_; // output file with input parent
433 else if (is_output_file_)
434 return; // output file, no input parent to read from
435
436 if (the_import_file) {
437 // the file exist
438 TTreeReader old_run_tree("LDMX_Run", the_import_file);
439 TTreeReaderValue<ldmx::RunHeader> old_run_header(old_run_tree, "RunHeader");
440 // TODO check that setup went correctly
441 while (old_run_tree.Next()) {
442 auto *old_run_header_ptr = old_run_header.Get();
443 if (old_run_header_ptr != nullptr) {
444 // copy input run tree into run map
445 // We should consider moving to a shared_ptr instead of 'new'
446 run_map_[old_run_header_ptr->getRunNumber()] =
447 std::make_pair(true, new ldmx::RunHeader(*old_run_header_ptr));
448 }
449 }
450 }
451
452 return;
453}

References file_, is_output_file_, parent_, and run_map_.

Referenced by EventFile(), and updateParent().

◆ isCorrupted()

bool framework::EventFile::isCorrupted ( ) const

Check if the file we have is corrupted.

The check on if the file is corrupted is only helpful for input files, but we attempt to have a resonable definition for output files as well.

Input Files

There are two ways a file can be corrupted and these may not be mutually exclusive.

  1. The LDMX_Events tree does not exist within it.
  2. The IsZombie flag of the TFile is set

Output Files

For output files, we just check the IsZombie flag of the TFile. Again, since we are actively writing to this file, a corruption check is not very stable.

Definition at line 119 of file EventFile.cxx.

119 {
120 if (is_output_file_) return file_->IsZombie();
121 return (!tree_ or file_->IsZombie() or file_->GetNkeys() == 0);
122}

References file_, is_output_file_, and tree_.

Referenced by framework::Process::run().

◆ nextEvent()

bool framework::EventFile::nextEvent ( bool storeCurrentEvent = true)

Prepare the next event.

We do the necessary set-up if ientry_ < 0. This means if we are an output file with a parent file, we clone our parent tree to our tree so we have the same branches.

After the first entry (when ientry_ >= 0), we "close up" the last event, filling our tree if we storeCurrentEvent is true and telling the event bus to clear.

Going to the next event depends on the configuration of the event file. THere are three cases.

  1. We have a parent file - Just follow the parent's lead by calling the parent's nextEvent.
  2. We are an output file (and we don't have a parent file). Just increment the number of entries and the entry index_.
  3. We are an input file. Now we need to load the next entry of the our tree into the event bus objects. If we are configured to be "loopable", then we will reset ientry_ to -1 when we reach the last event. Otherwise, we will return false as a stopping condition.
Parameters
[in]storeCurrentEventShould we save the current event to the output (if we are an output file)?
Returns
If event was prepared/read successfully.

Definition at line 208 of file EventFile.cxx.

208 {
209 if (ientry_ < 0) {
210 // first entry of this file
211 if (parent_) {
212 // we have a parent file
213 if (!parent_->tree_) {
214 // this should _never_ happen
215 EXCEPTION_RAISE("EventFile", "No event tree in the file");
216 }
217 // Only clone parent tree if either
218 // 1) There is no tree setup yet (first input file)
219 // 2) This is not single output (new input file --> new output file)
220 if (!tree_ or !is_single_output_) {
221 // clones parent_->tree_ to our tree_ keeping drop/keep rules in mind
222 // clone tree (only copies over branches that are active on input tree)
223
224 file_->cd(); // go into output file
225
226 for (auto const &rule_pair : pre_clone_rules_)
227 parent_->tree_->SetBranchStatus(rule_pair.first.c_str(),
228 rule_pair.second);
229
230 tree_ = parent_->tree_->CloneTree(0);
231
232 // reactivate any drop branches (drop) on input tree
233 for (auto const &rule : reactivate_rules_)
234 parent_->tree_->SetBranchStatus(rule.c_str(), 1);
235 }
238 } // we have a parent file
239 } else {
240 // later than first entry of file
241 if (is_output_file_) {
243 if (storeCurrentEvent) // we should store before moving on
244 tree_->Fill(); // fill the clones...
245 } // we are an output file
246
247 // the event bus may not be defined
248 // for this file if we are input file and
249 // there is an output file during this run
250 if (event_) {
251 event_->clear();
253 } // event bus defined
254 } // first or not first entry in this file
255
256 if (parent_) {
257 // we have a parent, follow their lead
258 if (!parent_->nextEvent()) {
259 return false;
260 }
262 entries_++;
263 } else if (is_output_file_) {
264 // we don't have a parent and we
265 // are an output file
266 // Just increment the number of entries
267 // and the index_ of the current entry
268 ientry_++;
269 entries_++;
270 } else {
271 // we don't have a parent and
272 // we aren't an output file
273 // try to load another entry from our tree
274 if (ientry_ + 1 >= entries_) {
275 if (is_loopable_) {
276 // reset the event counter: reuse events from start of pileup tree
277 ientry_ = -1;
278 } else
279 return false;
280 }
281 ientry_++;
282 tree_->GetEntry(ientry_);
283 }
284
285 // if we have an event_
286 // make sure it is iterated as well
287 return event_ ? event_->nextEvent() : true;
288}
bool nextEvent(bool storeCurrentEvent=true)
Prepare the next event.
Long64_t ientry_
The current entry in the tree.
Definition EventFile.h:285
void clear()
Clear this object's data (including passengers).
Definition Event.cxx:179
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
bool nextEvent()
Go to the next event by retrieving the event header.
Definition Event.cxx:165
void setInputTree(TTree *tree)
Set the input data tree.
Definition Event.cxx:123

References framework::Event::beforeFill(), framework::Event::clear(), entries_, event_, file_, ientry_, is_loopable_, is_output_file_, is_single_output_, framework::Event::nextEvent(), nextEvent(), framework::Event::onEndOfEvent(), parent_, pre_clone_rules_, reactivate_rules_, framework::Event::setInputTree(), framework::Event::setOutputTree(), and tree_.

Referenced by nextEvent(), and framework::Process::run().

◆ setupEvent()

void framework::EventFile::setupEvent ( Event * evt)

Set an Event object containing the event data to work with this file.

Parameters
evtThe Event object with event data.

Definition at line 290 of file EventFile.cxx.

290 {
291 event_ = evt;
292 if (is_output_file_) {
293 // we are an output file
294 if (!tree_ && !parent_) {
295 // we don't have a tree and we don't have a parent
296 // ==> *Production Mode* create a new tree
298 ientry_ = 0;
299 entries_ = 0;
300 }
301
302 if (parent_) {
303 // we have a parent file so give
304 // the parent's tree to the event bus
305 // as the input tree
307 }
308
309 // give our tree to the event as the output tree
311 } else {
312 // we are an input file
313 // so give our tree to the event as input tree
315 } // output or input file
316}
TTree * createTree()
Create the output data tree.
Definition Event.cxx:115

References framework::Event::createTree(), entries_, event_, ientry_, is_output_file_, parent_, framework::Event::setInputTree(), framework::Event::setOutputTree(), and tree_.

Referenced by framework::Process::run().

◆ skipToEvent()

int framework::EventFile::skipToEvent ( int offset)

Skip events using an offset.

Used in pileup overlay.

Returns
New event number if read successfully, else -1.

Definition at line 318 of file EventFile.cxx.

318 {
319 // make sure the event number exists
320 ientry_ = offset % entries_ - 1;
321 return ientry_;
322}

References entries_, and ientry_.

◆ updateParent()

void framework::EventFile::updateParent ( EventFile * parent)

Change pointer to different parent file.

We assume that the parent file is an EventFile configured to be an input file. This allows us to assume that the tree_ member variable of parent is valid.

Parameters
parentpointer to new parent file

Definition at line 324 of file EventFile.cxx.

324 {
325 parent_ = parent;
326
327 // we can assume parent_->tree_ is valid
328 // because (for input files) the tree_ is imported
329 // from the file and then checked if its valid in the
330 // EventFile constructor
331
332 // Enter output file
333 file_->cd();
334
335 // need to turn on/off the same branches as in the initial setup...
336 for (auto const &rule_pair : pre_clone_rules_)
337 parent_->tree_->SetBranchStatus(rule_pair.first.c_str(), rule_pair.second);
338
339 // Copy over addresses from the new parent
340 parent_->tree_->CopyAddresses(tree_);
341
342 // and reactivate any dropping rules
343 for (auto const &rule : reactivate_rules_)
344 parent_->tree_->SetBranchStatus(rule.c_str(), 1);
345
346 // Reset the entry index_ with the new parent index_
348
349 // import run headers from new input file
351
352 return;
353}

References file_, ientry_, importRunHeaders(), parent_, pre_clone_rules_, reactivate_rules_, and tree_.

Referenced by framework::Process::run().

◆ writeRunHeader()

void framework::EventFile::writeRunHeader ( ldmx::RunHeader & runHeader)

Write the run header into the run map.

Any RunHeader passed here is not owned or cleaned up by this EventFile instance.

Parameters
runHeaderThe run header to write into the map
Exceptions
Exceptionif run number is already in run map

Definition at line 399 of file EventFile.cxx.

399 {
400 int run_number = run_header.getRunNumber();
401
402 if (run_map_.find(run_number) != run_map_.end()) {
403 EXCEPTION_RAISE("RunMap", "Run map already contains a run with number '" +
404 std::to_string(run_number) + "'.");
405 }
406
407 run_map_[run_number] = std::make_pair(false, &run_header);
408
409 return;
410}

References ldmx::RunHeader::getRunNumber(), and run_map_.

Referenced by framework::Process::run().

◆ writeRunTree()

void framework::EventFile::writeRunTree ( )

Write the map of run headers to the file as a TTree of RunHeader.

Deletes any RunHeaders that this instance of EventFile owns.

Exceptions
Exceptionif call this function on a non-output file.

ROOT requires us to be in the correct directory when we create the output TTree for us to have it written into the correct location.

In order to allow downstream processors to getHistoDirectory() and enter that directory for this histograms we need to enter the output event file again here so that our run tree ends up in the correct location.

Definition at line 355 of file EventFile.cxx.

355 {
356 if (not is_output_file_) {
357 EXCEPTION_RAISE("MisCall",
358 "Cannot write the run tree on an input event file.");
359 }
360
361 // store the run map into the output tree
362 // Check for the existence of the run tree in the file.
363 // If it already exists, throw an exception.
364 // TODO: Tree name shouldn't be hardcoded. Is this check really necessary?
365 auto run_tree{static_cast<TTree *>(file_->Get("LDMX_Run"))};
366 if (run_tree) {
367 EXCEPTION_RAISE("RunTree",
368 "RunTree 'LDMX_Run' already exists in output file '" +
369 file_name_ + "'.");
370 }
371
382 file_->cd();
383 run_tree = new TTree("LDMX_Run", "LDMX run header");
384
385 // create the branch on this tree
386 ldmx::RunHeader *the_handle = nullptr;
387 run_tree->Branch("RunHeader", "ldmx::RunHeader", &the_handle, 32000, 3);
388
389 // copy over the run headers into the tree
390 for (auto &[num, header_pair] : run_map_) {
391 the_handle = header_pair.second;
392 run_tree->Fill();
393 if (header_pair.first) delete header_pair.second;
394 }
395
396 run_tree->Write();
397}

References file_, file_name_, is_output_file_, and run_map_.

Referenced by framework::Process::run().

Member Data Documentation

◆ entries_

Long64_t framework::EventFile::entries_ {-1}
private

The number of entries in the tree.

Definition at line 282 of file EventFile.h.

282{-1};

Referenced by EventFile(), nextEvent(), setupEvent(), and skipToEvent().

◆ event_

Event* framework::EventFile::event_ {nullptr}
private

The object containing the actual event data (trees and branches).

Definition at line 309 of file EventFile.h.

309{nullptr};

Referenced by addDrop(), getEvent(), nextEvent(), and setupEvent().

◆ file_

TFile* framework::EventFile::file_ {nullptr}
private

The backing TFile for this EventFile.

Definition at line 300 of file EventFile.h.

300{nullptr};

Referenced by EventFile(), importRunHeaders(), isCorrupted(), nextEvent(), updateParent(), writeRunTree(), and ~EventFile().

◆ file_name_

std::string framework::EventFile::file_name_
private

The file name.

Definition at line 288 of file EventFile.h.

Referenced by EventFile(), getFileName(), and writeRunTree().

◆ ientry_

Long64_t framework::EventFile::ientry_ {-1}
private

The current entry in the tree.

Definition at line 285 of file EventFile.h.

285{-1};

Referenced by nextEvent(), setupEvent(), skipToEvent(), and updateParent().

◆ is_loopable_

bool framework::EventFile::is_loopable_ {false}
private

True if this is an input file with pileup overlay events *‍/.

Definition at line 297 of file EventFile.h.

297{false};

Referenced by nextEvent().

◆ is_output_file_

bool framework::EventFile::is_output_file_
private

True if file is an output file being written to disk.

Definition at line 291 of file EventFile.h.

Referenced by EventFile(), importRunHeaders(), isCorrupted(), nextEvent(), setupEvent(), writeRunTree(), and ~EventFile().

◆ is_single_output_

bool framework::EventFile::is_single_output_
private

True if there is only one output file.

Definition at line 294 of file EventFile.h.

Referenced by nextEvent().

◆ parent_

EventFile* framework::EventFile::parent_ {nullptr}
private

A parent file containing event data.

Definition at line 306 of file EventFile.h.

306{nullptr};

Referenced by EventFile(), importRunHeaders(), nextEvent(), setupEvent(), and updateParent().

◆ pre_clone_rules_

std::vector<std::pair<std::string, bool> > framework::EventFile::pre_clone_rules_
private

Pre-clone rules.

The series of rules to call before cloning/copying the parent tree.

Definition at line 317 of file EventFile.h.

Referenced by addDrop(), EventFile(), nextEvent(), and updateParent().

◆ reactivate_rules_

std::vector<std::string> framework::EventFile::reactivate_rules_
private

Vector of drop rules that have been parsed and need to be used to reactivate these branches on the input tree.

The branches were initial deactivated so they don't get cloned to output tree.

Definition at line 326 of file EventFile.h.

Referenced by addDrop(), EventFile(), nextEvent(), and updateParent().

◆ run_map_

std::map<int, std::pair<bool, ldmx::RunHeader *> > framework::EventFile::run_map_
private

Map of run numbers to RunHeader objects.

The value object is a pair that should remain internal.

  1. True if EventFile owns the RunHeader (and needs to clean it up)
    • This happens when RunHeaders are imported from an input file
  2. False if EventFile does not own the RunHeader
    • This happens when the RunHeader is created by Process::run during production

Definition at line 338 of file EventFile.h.

Referenced by getRunHeaderPtr(), importRunHeaders(), writeRunHeader(), and writeRunTree().

◆ tree_

TTree* framework::EventFile::tree_ {nullptr}
private

The tree with event data.

Definition at line 303 of file EventFile.h.

303{nullptr};

Referenced by EventFile(), isCorrupted(), nextEvent(), setupEvent(), updateParent(), and ~EventFile().


The documentation for this class was generated from the following files: