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 (std::shared_ptr< ldmx::RunHeader > runHeader)
 Write the run header into the run map.
 
void writeRunTree (bool completed=false)
 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 ()
 
std::vector< int > getIncompleteRuns () const
 The runs in this file whose writer did not close cleanly.
 

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::shared_ptr< ldmx::RunHeader > > run_map_
 Map of run numbers to RunHeader objects (owned via shared_ptr)
 
TTree * run_tree_ {nullptr}
 The run tree, owned by file_ once written.
 
bool run_headers_have_completeness_ {false}
 True when the run headers we read were written with a completion flag.
 

Detailed Description

This class manages all ROOT file input/output operations.

Definition at line 28 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 30 of file EventFile.cxx.

34 : file_name_(filename),
35 is_output_file_(is_output_file),
36 is_single_output_(is_single_output),
37 is_loopable_(is_loopable),
38 parent_(parent) {
39 if (is_output_file_) {
40 // we are writting out so open the file and make sure it is writable
41 file_ = new TFile(file_name_.c_str(), "RECREATE");
42 if (!file_->IsOpen() or !file_->IsWritable()) {
43 EXCEPTION_RAISE("FileError",
44 "Output file '" + file_name_ + "' is not writable.");
45 }
46
47 // set compression settings
48 // Check out the TFile constructor for explanation of how this integer is
49 // built Short Reference: setting = 100*algorithem + level algorithm = 0
50 // ==> use global default
51 file_->SetCompressionSettings(params.get<int>("compression_setting", 9));
52
53 if (parent_) {
54 // output file when there are input files
55 // might be drop/keep rules, so we should have these rules to make sure
56 // it works
57
58 // turn everything on
59 // hypothetically could turn everything off? Doesn't work for some
60 // reason?
61 pre_clone_rules_.emplace_back("*", true);
62
63 // except EventHeader (copies over to output)
64 pre_clone_rules_.emplace_back("EventHeader*", true);
65
66 // reactivate all branches so default behavior is drop
67 reactivate_rules_.push_back("*");
68 }
69 } else {
70 // open file with only reading enabled
71 file_ = new TFile(file_name_.c_str());
72 // double check that file is open
73 if (!file_->IsOpen()) {
74 EXCEPTION_RAISE("FileError", "Input file '" + file_name_ +
75 "' is not readable or does not exist.");
76 }
77
78 bool skip_corrupted = params.get<bool>("skip_corrupted_input_files", false);
79
80 // make sure file is not a zombie file
81 // (i.e. process ended without closing or the file was corrupted some other
82 // way)
83 if (file_->IsZombie()) {
84 if (not skip_corrupted) {
85 EXCEPTION_RAISE("FileError", "Input file '" + file_name_ +
86 "' is corrupted. Framework will not "
87 "attempt to recover this file.");
88 }
89 return;
90 }
91
92 // Get the tree name from the configuration
93 auto tree_name{params.get<std::string>("tree_name")};
94 tree_ = static_cast<TTree*>(file_->Get(tree_name.c_str()));
95 if (!tree_) {
96 if (not skip_corrupted) {
97 EXCEPTION_RAISE("FileError", "File '" + file_name_ +
98 "' does not have a TTree named '" +
99 tree_name + "' in it.");
100 }
101 return;
102 }
103 entries_ = tree_->GetEntriesFast();
104 }
105
107}
TFile * file_
The backing TFile for this EventFile.
Definition EventFile.h:315
Long64_t entries_
The number of entries in the tree.
Definition EventFile.h:297
std::vector< std::pair< std::string, bool > > pre_clone_rules_
Pre-clone rules.
Definition EventFile.h:332
bool is_loopable_
True if this is an input file with pileup overlay events *‍/.
Definition EventFile.h:312
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:303
bool is_single_output_
True if there is only one output file.
Definition EventFile.h:309
EventFile * parent_
A parent file containing event data.
Definition EventFile.h:321
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:341
bool is_output_file_
True if file is an output file being written to disk.
Definition EventFile.h:306
TTree * tree_
The tree with event data.
Definition EventFile.h:318
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 109 of file EventFile.cxx.

111 : 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:30

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

120 : 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 113 of file EventFile.cxx.

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

◆ ~EventFile()

framework::EventFile::~EventFile ( )

Destructor.

Make sure to close the file when we destruct

Definition at line 122 of file EventFile.cxx.

122 {
123 // Before an output file, the Event tree needs to be written.
124 if (tree_ && is_output_file_) {
125 // make sure we are in output file before writing
126 file_->cd();
127 tree_->Write();
128 file_->Close();
129 }
130}

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

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

183{ return event_; };

References event_.

◆ getFileName()

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

Definition at line 261 of file EventFile.h.

261{ return file_name_; }

References file_name_.

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

◆ getIncompleteRuns()

std::vector< int > framework::EventFile::getIncompleteRuns ( ) const

The runs in this file whose writer did not close cleanly.

Events are missing from the end of any such run, so processing it silently would produce a biased sample.

A file written before ldmx::RunHeader::VERSION_WITH_COMPLETED carries no completion flag. We cannot say anything about those runs, so they are left out rather than reported as incomplete.

Returns
run numbers of the incomplete runs, empty if the file is whole

Definition at line 441 of file EventFile.cxx.

441 {
442 std::vector<int> incomplete;
443 // without the flag on disk we have nothing to judge by
444 if (not run_headers_have_completeness_) return incomplete;
445 for (const auto& [num, run_header] : run_map_) {
446 if (not run_header->isCompleted()) incomplete.push_back(num);
447 }
448 return incomplete;
449}
std::map< int, std::shared_ptr< ldmx::RunHeader > > run_map_
Map of run numbers to RunHeader objects (owned via shared_ptr)
Definition EventFile.h:344
bool run_headers_have_completeness_
True when the run headers we read were written with a completion flag.
Definition EventFile.h:350

References run_headers_have_completeness_, and run_map_.

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

432 {
433 ldmx::RunHeader* rh{this->getRunHeaderPtr(run_number)};
434 if (rh != nullptr) {
435 return *rh;
436 }
437 EXCEPTION_RAISE("RunHeader", "Unable to find header for run " +
438 std::to_string(run_number));
439}
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:67

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

425 {
426 if (run_map_.find(run_number) != run_map_.end()) {
427 return run_map_.at(run_number).get();
428 }
429 return nullptr;
430}

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!

RunHeaders read in from this function are stored as shared_ptr.

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

Definition at line 451 of file EventFile.cxx.

451 {
452 // choose which file to import from
453 auto the_import_file{file_}; // if this is an input file
455 the_import_file = parent_->file_; // output file with input parent
456 else if (is_output_file_)
457 return; // output file, no input parent to read from
458
459 if (the_import_file) {
460 // the file exist
461 TTreeReader old_run_tree("LDMX_Run", the_import_file);
462 TTreeReaderValue<ldmx::RunHeader> old_run_header(old_run_tree, "RunHeader");
463 // older headers stream into a default false, which means nothing
465 onDiskRunHeaderVersion(old_run_tree.GetTree()) >=
467 // TODO check that setup went correctly
468 while (old_run_tree.Next()) {
469 auto* old_run_header_ptr = old_run_header.Get();
470 if (old_run_header_ptr != nullptr) {
471 int run_number = old_run_header_ptr->getRunNumber();
472 run_map_[run_number] =
473 std::make_shared<ldmx::RunHeader>(*old_run_header_ptr);
474 }
475 }
476 }
477
478 return;
479}
static constexpr int VERSION_WITH_COMPLETED
The first class version that writes completed_.
Definition RunHeader.h:75

References file_, is_output_file_, parent_, run_headers_have_completeness_, run_map_, and ldmx::RunHeader::VERSION_WITH_COMPLETED.

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

132 {
133 if (is_output_file_) return file_->IsZombie();
134 return (!tree_ or file_->IsZombie() or file_->GetNkeys() == 0);
135}

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

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

303 {
304 event_ = evt;
305 if (is_output_file_) {
306 // we are an output file
307 if (!tree_ && !parent_) {
308 // we don't have a tree and we don't have a parent
309 // ==> *Production Mode* create a new tree
311 ientry_ = 0;
312 entries_ = 0;
313 }
314
315 if (parent_) {
316 // we have a parent file so give
317 // the parent's tree to the event bus
318 // as the input tree
320 }
321
322 // give our tree to the event as the output tree
324 } else {
325 // we are an input file
326 // so give our tree to the event as input tree
328 } // output or input file
329}
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 331 of file EventFile.cxx.

331 {
332 // make sure the event number exists
333 ientry_ = offset % entries_ - 1;
334 return ientry_;
335}

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

337 {
338 parent_ = parent;
339
340 // we can assume parent_->tree_ is valid
341 // because (for input files) the tree_ is imported
342 // from the file and then checked if its valid in the
343 // EventFile constructor
344
345 // Enter output file
346 file_->cd();
347
348 // need to turn on/off the same branches as in the initial setup...
349 for (auto const& rule_pair : pre_clone_rules_)
350 parent_->tree_->SetBranchStatus(rule_pair.first.c_str(), rule_pair.second);
351
352 // Copy over addresses from the new parent
353 parent_->tree_->CopyAddresses(tree_);
354
355 // and reactivate any dropping rules
356 for (auto const& rule : reactivate_rules_)
357 parent_->tree_->SetBranchStatus(rule.c_str(), 1);
358
359 // Reset the entry index_ with the new parent index_
361
362 // import run headers from new input file
364
365 return;
366}

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

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

◆ writeRunHeader()

void framework::EventFile::writeRunHeader ( std::shared_ptr< ldmx::RunHeader > runHeader)

Write the run header into the run map.

Parameters
runHeadershared pointer to the run header to store
Exceptions
Exceptionif run number is already in run map

Definition at line 414 of file EventFile.cxx.

414 {
415 int run_number = run_header->getRunNumber();
416
417 if (run_map_.find(run_number) != run_map_.end()) {
418 EXCEPTION_RAISE("RunMap", "Run map already contains a run with number '" +
419 std::to_string(run_number) + "'.");
420 }
421
422 run_map_[run_number] = run_header;
423}

References run_map_.

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

◆ writeRunTree()

void framework::EventFile::writeRunTree ( bool completed = false)

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

Safe to call more than once; any run tree already in the file is overwritten. Process calls it once the producers have filled the headers and again on close, so a killed job still leaves a usable file.

Parameters
[in]completedtrue when closing cleanly. Only the final call should pass true.
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 368 of file EventFile.cxx.

368 {
369 if (not is_output_file_) {
370 EXCEPTION_RAISE("MisCall",
371 "Cannot write the run tree on an input event file.");
372 }
373
374 // TODO: Tree name shouldn't be hardcoded.
375
376 // stamp completion onto the headers before they go out
377 for (auto& [num, run_header] : run_map_) run_header->setCompleted(completed);
378
389 file_->cd();
390
391 // rebuild so the branch address stays valid across calls
392 delete run_tree_;
393 run_tree_ = nullptr;
394 file_->Delete("LDMX_Run;*"); // drop any earlier cycle
395 run_tree_ = new TTree("LDMX_Run", "LDMX run header");
396
397 // create the branch on this tree
398 ldmx::RunHeader* the_handle = nullptr;
399 run_tree_->Branch("RunHeader", "ldmx::RunHeader", &the_handle, 32000, 3);
400 // ROOT allocates a RunHeader when given a null pointer and leaves
401 // ownership with the caller, so take it to avoid leaking it
402 std::unique_ptr<ldmx::RunHeader> root_allocated(the_handle);
403
404 // copy over the run headers into the tree
405 for (auto& [num, run_header] : run_map_) {
406 the_handle = run_header.get();
407 run_tree_->Fill();
408 }
409
410 run_tree_->Write("", TObject::kOverwrite);
411 file_->Flush(); // get the key on disk before any kill
412}
TTree * run_tree_
The run tree, owned by file_ once written.
Definition EventFile.h:347

References file_, is_output_file_, run_map_, and run_tree_.

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

Member Data Documentation

◆ entries_

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

The number of entries in the tree.

Definition at line 297 of file EventFile.h.

297{-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 324 of file EventFile.h.

324{nullptr};

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

◆ file_

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

The backing TFile for this EventFile.

Definition at line 315 of file EventFile.h.

315{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 303 of file EventFile.h.

Referenced by EventFile(), and getFileName().

◆ ientry_

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

The current entry in the tree.

Definition at line 300 of file EventFile.h.

300{-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 312 of file EventFile.h.

312{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 306 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 309 of file EventFile.h.

Referenced by nextEvent().

◆ parent_

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

A parent file containing event data.

Definition at line 321 of file EventFile.h.

321{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 332 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 341 of file EventFile.h.

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

◆ run_headers_have_completeness_

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

True when the run headers we read were written with a completion flag.

Definition at line 350 of file EventFile.h.

350{false};

Referenced by getIncompleteRuns(), and importRunHeaders().

◆ run_map_

std::map<int, std::shared_ptr<ldmx::RunHeader> > framework::EventFile::run_map_
private

Map of run numbers to RunHeader objects (owned via shared_ptr)

Definition at line 344 of file EventFile.h.

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

◆ run_tree_

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

The run tree, owned by file_ once written.

Definition at line 347 of file EventFile.h.

347{nullptr};

Referenced by writeRunTree().

◆ tree_

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

The tree with event data.

Definition at line 318 of file EventFile.h.

318{nullptr};

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


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