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 (tree_ && is_output_file_) {
110 // make sure we are in output file before writing
111 file_->cd();
112 tree_->Write();
113 file_->Close();
114 }
115}

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 122 of file EventFile.cxx.

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

417 {
418 ldmx::RunHeader* rh{this->getRunHeaderPtr(run_number)};
419 if (rh != nullptr) {
420 return *rh;
421 }
422 EXCEPTION_RAISE("RunHeader", "Unable to find header for run " +
423 std::to_string(run_number));
424}
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 410 of file EventFile.cxx.

410 {
411 if (run_map_.find(run_number) != run_map_.end()) {
412 return run_map_.at(run_number).second;
413 }
414 return nullptr;
415}
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 426 of file EventFile.cxx.

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

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 117 of file EventFile.cxx.

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

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 206 of file EventFile.cxx.

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

288 {
289 event_ = evt;
290 if (is_output_file_) {
291 // we are an output file
292 if (!tree_ && !parent_) {
293 // we don't have a tree and we don't have a parent
294 // ==> *Production Mode* create a new tree
296 ientry_ = 0;
297 entries_ = 0;
298 }
299
300 if (parent_) {
301 // we have a parent file so give
302 // the parent's tree to the event bus
303 // as the input tree
305 }
306
307 // give our tree to the event as the output tree
309 } else {
310 // we are an input file
311 // so give our tree to the event as input tree
313 } // output or input file
314}
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 316 of file EventFile.cxx.

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

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 322 of file EventFile.cxx.

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

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 397 of file EventFile.cxx.

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

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 353 of file EventFile.cxx.

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

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: