LDMX Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
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 fileName_
 The file name.
 
bool isOutputFile_
 True if file is an output file being written to disk.
 
bool isSingleOutput_
 True if there is only one output file.
 
bool isLoopable_ {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 > > preCloneRules_
 Pre-clone rules.
 
std::vector< std::string > reactivateRules_
 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 * > > runMap_
 Map of run numbers to RunHeader objects.
 

Detailed Description

This class manages all ROOT file input/output operations.

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

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

References entries_, file_, fileName_, framework::config::Parameters::getParameter(), importRunHeaders(), isOutputFile_, parent_, preCloneRules_, reactivateRules_, 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 93 of file EventFile.cxx.

95 : EventFile(params, filename, nullptr, false, false, isLoopable) {}
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:13

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

104 : EventFile(params, filename, parent, true, isSingleOutput, 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 97 of file EventFile.cxx.

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

◆ ~EventFile()

framework::EventFile::~EventFile ( )

Destructor.

Make sure to close the file when we destruct

Definition at line 106 of file EventFile.cxx.

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

References file_, isOutputFile_, 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 123 of file EventFile.cxx.

123 {
124 int offset;
125 bool isKeep = false, isDrop = false, isIgnore = false;
126 size_t i = rule.find("keep");
127 if (i != std::string::npos) {
128 offset = i + 4;
129 isKeep = true;
130 }
131 i = rule.find("drop");
132 if (i != std::string::npos) {
133 offset = i + 4;
134 isDrop = true;
135 }
136 i = rule.find("ignore");
137 if (i != std::string::npos) {
138 offset = i + 6;
139 isIgnore = true;
140 }
141
142 // more than one of (keep,drop,ignore) was provided => not valid rule
143 if (int(isKeep) + int(isDrop) + int(isIgnore) != 1) return;
144
145 std::string srule = rule.substr(offset);
146 for (i = srule.find_first_of(" \t\n\r"); i != std::string::npos;
147 i = srule.find_first_of(" \t\n\r"))
148 srule.erase(i, 1);
149
150 // name of branch is not given
151 if (srule.length() == 0) return;
152
153 // add wild card at end for matching purposes
154 if (srule.back() != '*') srule += ".*"; // add wildcard to back
155
156 if (isKeep) {
157 // turn both the input and output tree's on
158 // root needs . removed otherwise it gets cranky
159 srule.erase(std::remove(srule.begin(), srule.end(), '.'), srule.end());
160 preCloneRules_.emplace_back(srule, true);
161 // this branch will then be copied over into output tree and be active
162 } else if (isIgnore) {
163 // don't even read it from the input file
164 // root needs . removed otherwise it gets cranky
165 srule.erase(std::remove(srule.begin(), srule.end(), '.'), srule.end());
166 preCloneRules_.emplace_back(srule, false);
167 // these branches won't be copied over into output tree
168 } else if (isDrop) {
169 // drop means allowing it on reading but not writing
170 // pass these regex to event bus so Event::add knows
171 event_->addDrop(srule); // requires event_ to be set
172
173 // root needs . removed otherwise it gets cranky
174 srule.erase(std::remove(srule.begin(), srule.end(), '.'), srule.end());
175 preCloneRules_.emplace_back(srule, false);
176 // these branches won't be copied over into output tree
177 // reactivate input branch after clone
178 reactivateRules_.push_back(srule);
179 }
180}
Event * event_
The object containing the actual event data (trees and branches).
Definition EventFile.h:308
void addDrop(const std::string &exp)
Add a drop rule to the list of regex expressions to drop.
Definition Event.cxx:21

References framework::Event::addDrop(), event_, preCloneRules_, and reactivateRules_.

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 181 of file EventFile.h.

181{ return event_; };

References event_.

◆ getFileName()

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

Definition at line 258 of file EventFile.h.

258{ return fileName_; }

References fileName_.

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

393 {
394 ldmx::RunHeader *rh{this->getRunHeaderPtr(runNumber)};
395 if (rh != nullptr) {
396 return *rh;
397 }
398 EXCEPTION_RAISE("RunHeader",
399 "Unable to find header for run " + std::to_string(runNumber));
400}
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:54

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

386 {
387 if (runMap_.find(runNumber) != runMap_.end()) {
388 return runMap_.at(runNumber).second;
389 }
390 return nullptr;
391}
std::map< int, std::pair< bool, ldmx::RunHeader * > > runMap_
Map of run numbers to RunHeader objects.
Definition EventFile.h:337

References runMap_.

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

402 {
403 // choose which file to import from
404 auto theImportFile{file_}; // if this is an input file
405 if (isOutputFile_ and parent_ and parent_->file_)
406 theImportFile = parent_->file_; // output file with input parent
407 else if (isOutputFile_)
408 return; // output file, no input parent to read from
409
410 if (theImportFile) {
411 // the file exist
412 TTreeReader oldRunTree("LDMX_Run", theImportFile);
413 TTreeReaderValue<ldmx::RunHeader> oldRunHeader(oldRunTree, "RunHeader");
414 // TODO check that setup went correctly
415 while (oldRunTree.Next()) {
416 auto *oldRunHeaderPtr = oldRunHeader.Get();
417 if (oldRunHeaderPtr != nullptr) {
418 // copy input run tree into run map
419 // We should consider moving to a shared_ptr instead of 'new'
420 runMap_[oldRunHeaderPtr->getRunNumber()] =
421 std::make_pair(true, new ldmx::RunHeader(*oldRunHeader));
422 }
423 }
424 }
425
426 return;
427}

References file_, isOutputFile_, parent_, and runMap_.

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

118 {
119 if (isOutputFile_) return file_->IsZombie();
120 return (!tree_ or file_->IsZombie());
121}

References file_, isOutputFile_, 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 182 of file EventFile.cxx.

182 {
183 if (ientry_ < 0) {
184 // first entry of this file
185 if (parent_) {
186 // we have a parent file
187 if (!parent_->tree_) {
188 // this should _never_ happen
189 EXCEPTION_RAISE("EventFile", "No event tree in the file");
190 }
191 // Only clone parent tree if either
192 // 1) There is no tree setup yet (first input file)
193 // 2) This is not single output (new input file --> new output file)
194 if (!tree_ or !isSingleOutput_) {
195 // clones parent_->tree_ to our tree_ keeping drop/keep rules in mind
196 // clone tree (only copies over branches that are active on input tree)
197
198 file_->cd(); // go into output file
199
200 for (auto const &rulePair : preCloneRules_)
201 parent_->tree_->SetBranchStatus(rulePair.first.c_str(),
202 rulePair.second);
203
204 tree_ = parent_->tree_->CloneTree(0);
205
206 // reactivate any drop branches (drop) on input tree
207 for (auto const &rule : reactivateRules_)
208 parent_->tree_->SetBranchStatus(rule.c_str(), 1);
209 }
212 } // we have a parent file
213 } else {
214 // later than first entry of file
215 if (isOutputFile_) {
217 if (storeCurrentEvent) // we should store before moving on
218 tree_->Fill(); // fill the clones...
219 } // we are an output file
220
221 // the event bus may not be defined
222 // for this file if we are input file and
223 // there is an output file during this run
224 if (event_) {
225 event_->Clear();
227 } // event bus defined
228 } // first or not first entry in this file
229
230 if (parent_) {
231 // we have a parent, follow their lead
232 if (!parent_->nextEvent()) {
233 return false;
234 }
236 entries_++;
237 } else if (isOutputFile_) {
238 // we don't have a parent and we
239 // are an output file
240 // Just increment the number of entries
241 // and the index of the current entry
242 ientry_++;
243 entries_++;
244 } else {
245 // we don't have a parent and
246 // we aren't an output file
247 // try to load another entry from our tree
248 if (ientry_ + 1 >= entries_) {
249 if (isLoopable_) {
250 // reset the event counter: reuse events from start of pileup tree
251 ientry_ = -1;
252 } else
253 return false;
254 }
255 ientry_++;
256 tree_->GetEntry(ientry_);
257 }
258
259 // if we have an event_
260 // make sure it is iterated as well
261 return event_ ? event_->nextEvent() : true;
262}
bool nextEvent(bool storeCurrentEvent=true)
Prepare the next event.
Long64_t ientry_
The current entry in the tree.
Definition EventFile.h:284
void setOutputTree(TTree *tree)
Set the output data tree.
Definition Event.cxx:108
void beforeFill()
Action to be executed before the tree is filled.
Definition Event.cxx:156
void onEndOfEvent()
Perform end of event action (doesn't do anything right now).
Definition Event.cxx:170
void Clear()
Clear this object's data (including passengers).
Definition Event.cxx:165
bool nextEvent()
Go to the next event by retrieving the event header.
Definition Event.cxx:151
void setInputTree(TTree *tree)
Set the input data tree.
Definition Event.cxx:110

References framework::Event::beforeFill(), framework::Event::Clear(), entries_, event_, file_, ientry_, isLoopable_, isOutputFile_, isSingleOutput_, framework::Event::nextEvent(), nextEvent(), framework::Event::onEndOfEvent(), parent_, preCloneRules_, reactivateRules_, 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 264 of file EventFile.cxx.

264 {
265 event_ = evt;
266 if (isOutputFile_) {
267 // we are an output file
268 if (!tree_ && !parent_) {
269 // we don't have a tree and we don't have a parent
270 // ==> *Production Mode* create a new tree
272 ientry_ = 0;
273 entries_ = 0;
274 }
275
276 if (parent_) {
277 // we have a parent file so give
278 // the parent's tree to the event bus
279 // as the input tree
281 }
282
283 // give our tree to the event as the output tree
285 } else {
286 // we are an input file
287 // so give our tree to the event as input tree
289 } // output or input file
290}
TTree * createTree()
Create the output data tree.
Definition Event.cxx:102

References framework::Event::createTree(), entries_, event_, ientry_, isOutputFile_, 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 292 of file EventFile.cxx.

292 {
293 // make sure the event number exists
294 ientry_ = offset % entries_ - 1;
295 return ientry_;
296}

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

298 {
299 parent_ = parent;
300
301 // we can assume parent_->tree_ is valid
302 // because (for input files) the tree_ is imported
303 // from the file and then checked if its valid in the
304 // EventFile constructor
305
306 // Enter output file
307 file_->cd();
308
309 // need to turn on/off the same branches as in the initial setup...
310 for (auto const &rulePair : preCloneRules_)
311 parent_->tree_->SetBranchStatus(rulePair.first.c_str(), rulePair.second);
312
313 // Copy over addresses from the new parent
314 parent_->tree_->CopyAddresses(tree_);
315
316 // and reactivate any dropping rules
317 for (auto const &rule : reactivateRules_)
318 parent_->tree_->SetBranchStatus(rule.c_str(), 1);
319
320 // Reset the entry index with the new parent index
322
323 // import run headers from new input file
325
326 return;
327}

References file_, ientry_, importRunHeaders(), parent_, preCloneRules_, reactivateRules_, 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 373 of file EventFile.cxx.

373 {
374 int runNumber = runHeader.getRunNumber();
375
376 if (runMap_.find(runNumber) != runMap_.end()) {
377 EXCEPTION_RAISE("RunMap", "Run map already contains a run with number '" +
378 std::to_string(runNumber) + "'.");
379 }
380
381 runMap_[runNumber] = std::make_pair(false, &runHeader);
382
383 return;
384}
int getRunNumber() const
Definition RunHeader.h:74

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

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

329 {
330 if (not isOutputFile_) {
331 EXCEPTION_RAISE("MisCall",
332 "Cannot write the run tree on an input event file.");
333 }
334
335 // store the run map into the output tree
336 // Check for the existence of the run tree in the file.
337 // If it already exists, throw an exception.
338 // TODO: Tree name shouldn't be hardcoded. Is this check really necessary?
339 auto runTree{static_cast<TTree *>(file_->Get("LDMX_Run"))};
340 if (runTree) {
341 EXCEPTION_RAISE("RunTree",
342 "RunTree 'LDMX_Run' already exists in output file '" +
343 fileName_ + "'.");
344 }
345
356 file_->cd();
357 runTree = new TTree("LDMX_Run", "LDMX run header");
358
359 // create the branch on this tree
360 ldmx::RunHeader *theHandle = nullptr;
361 runTree->Branch("RunHeader", "ldmx::RunHeader", &theHandle, 32000, 3);
362
363 // copy over the run headers into the tree
364 for (auto &[num, header_pair] : runMap_) {
365 theHandle = header_pair.second;
366 runTree->Fill();
367 if (header_pair.first) delete header_pair.second;
368 }
369
370 runTree->Write();
371}

References file_, fileName_, isOutputFile_, and runMap_.

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 281 of file EventFile.h.

281{-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 308 of file EventFile.h.

308{nullptr};

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

◆ file_

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

The backing TFile for this EventFile.

Definition at line 299 of file EventFile.h.

299{nullptr};

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

◆ fileName_

std::string framework::EventFile::fileName_
private

The file name.

Definition at line 287 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 284 of file EventFile.h.

284{-1};

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

◆ isLoopable_

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

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

Definition at line 296 of file EventFile.h.

296{false};

Referenced by nextEvent().

◆ isOutputFile_

bool framework::EventFile::isOutputFile_
private

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

Definition at line 290 of file EventFile.h.

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

◆ isSingleOutput_

bool framework::EventFile::isSingleOutput_
private

True if there is only one output file.

Definition at line 293 of file EventFile.h.

Referenced by nextEvent().

◆ parent_

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

A parent file containing event data.

Definition at line 305 of file EventFile.h.

305{nullptr};

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

◆ preCloneRules_

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

Pre-clone rules.

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

Definition at line 316 of file EventFile.h.

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

◆ reactivateRules_

std::vector<std::string> framework::EventFile::reactivateRules_
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 325 of file EventFile.h.

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

◆ runMap_

std::map<int, std::pair<bool, ldmx::RunHeader *> > framework::EventFile::runMap_
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 337 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 302 of file EventFile.h.

302{nullptr};

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


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