LDMX Software
Process.cxx
Go to the documentation of this file.
1
6#include "Framework/Process.h"
7
8#include <dlfcn.h>
9
10#include <iostream>
11#include <set>
12
13#include "Framework/Event.h"
14#include "Framework/EventFile.h"
16#include "Framework/Exception/Exception.h"
17#include "Framework/Logger.h"
18#include "Framework/NtupleManager.h"
19#include "Framework/RunHeader.h"
20#include "TFile.h"
21#include "TROOT.h"
22
23// Preemption flag that can be set by signal handlers
24// NOLINTNEXTLINE(readability-identifier-naming)
25volatile std::sig_atomic_t preemption_received_ = 0;
26
27namespace framework {
28
30 : conditions_{*this} {
31 config_ = configuration;
32
33 pass_name_ = configuration.get<std::string>("pass_name", "");
34 histo_filename_ = configuration.get<std::string>("histogram_file", "");
35
36 max_tries_ = configuration.get<int>("max_tries_per_event", 1);
37 event_limit_ = configuration.get<int>("max_events", -1);
38 min_events_ = configuration.get<int>("min_events", -1);
39 total_events_ = configuration.get<int>("total_events", -1);
40 log_frequency_ = configuration.get<int>("log_frequency", -1);
41 compression_setting_ = configuration.get<int>("compression_setting", 9);
43 configuration.get<bool>("skip_corrupted_input_files", false);
44
45 input_files_ = configuration.get<std::vector<std::string>>("input_files", {});
47 configuration.get<std::vector<std::string>>("output_files", {});
48 drop_keep_rules_ = configuration.get<std::vector<std::string>>("keep", {});
49
50 event_header_ = 0;
51
52 // set up the logging for this run
53 logging::open(configuration.get<framework::config::Parameters>("logger", {}));
54
55 auto run{configuration.get<int>("run", -1)};
56 if (run > 0) run_for_generation_ = run;
57
58 auto libs{configuration.get<std::vector<std::string>>("libraries", {})};
59 std::set<std::string> libraries_loaded;
60 for (const auto &lib : libs) {
61 if (libraries_loaded.find(lib) != libraries_loaded.end()) {
62 continue;
63 }
64
65 void *handle = dlopen(lib.c_str(), RTLD_NOW);
66 if (handle == nullptr) {
67 EXCEPTION_RAISE("LibraryLoadFailure",
68 "Error loading library '" + lib + "':" + dlerror());
69 }
70
71 libraries_loaded.insert(lib);
72 }
73
75 configuration.get<bool>("skim_default_is_keep", true));
76 auto skim_rules{
77 configuration.get<std::vector<std::string>>("skim_rules", {})};
78 for (size_t i = 0; i < skim_rules.size(); i += 2) {
79 storage_controller_.addRule(skim_rules[i], skim_rules[i + 1]);
80 }
81
82 auto sequence{configuration.get<std::vector<framework::config::Parameters>>(
83 "sequence", {})};
84 if (sequence.empty() && configuration.get<bool>("testing_mode", false)) {
85 EXCEPTION_RAISE(
86 "NoSeq",
87 "No sequence has been defined. What should I be doing?\nUse "
88 "p.sequence to tell me what processors to run.");
89 }
90 for (auto proc : sequence) {
91 auto class_name{proc.get<std::string>("class_name")};
92 auto instance_name{proc.get<std::string>("instance_name")};
93 auto ep{
94 EventProcessor::Factory::get().make(class_name, instance_name, *this)};
95 if (not ep) {
96 EXCEPTION_RAISE("UnableToCreate",
97 "The EventProcessor Factory was unable to create " +
98 instance_name + " of type " + class_name +
99 ". Did you inherit from framework::Producer or "
100 "framework::Analyzer? "
101 "Did you DECLARE_PRODUCER or DECLARE_ANALYZER in the "
102 "implementation (.cxx) file? "
103 "Did you use the class's full name (including "
104 "namespaces) in the Python configuration class? "
105 "Does the Python configuration class reference the "
106 "correct library it is a part of?");
107 }
108 auto histograms{
109 proc.get<std::vector<framework::config::Parameters>>("histograms", {})};
110 if (!histograms.empty()) {
111 ep.value()->getHistoDirectory();
112 ep.value()->createHistograms(histograms);
113 }
114 ep.value()->configure(proc);
115 sequence_.push_back(ep.value());
116 }
117
118 auto conditions_object_providers{
119 configuration.get<std::vector<framework::config::Parameters>>(
120 "conditions_object_providers", {})};
121 for (auto cop : conditions_object_providers) {
122 auto class_name{cop.get<std::string>("class_name")};
123 auto object_name{cop.get<std::string>("object_name")};
124 auto tag_name{cop.get<std::string>("tag_name")};
125 conditions_.createConditionsObjectProvider(class_name, object_name,
126 tag_name, cop);
127 }
128
129 bool log_performance = configuration.get<bool>("log_performance", false);
130 if (log_performance) {
131 std::vector<std::string> names{sequence_.size()};
132 for (std::size_t i{0}; i < sequence_.size(); i++) {
133 names[i] = sequence_[i]->getName();
134 }
136 new performance::Tracker(makeHistoDirectory("performance"), names);
137 }
138}
139
141 // need to delete the performance object so that it is
142 // written before we close the histogram file below
143 if (performance_) delete performance_;
144 for (EventProcessor *ep : sequence_) {
145 delete ep;
146 }
147 if (histo_t_file_) {
148 histo_t_file_->Write();
149 delete histo_t_file_;
150 histo_t_file_ = 0;
151 }
152}
153
156
157 // Counter to keep track of the number of events that have been
158 // procesed
159 auto n_events_processed{0};
160
161 // make sure the ntuple manager is in a blank state
163
164 // event bus for this process
165 Event the_event(pass_name_);
166 // the EventHeader object is created with the event bus as
167 // one of its members, we obtain a pointer for the header
168 // here so we can share it with the conditions system
169 event_header_ = the_event.getEventHeaderPtr();
171
172 // Start by notifying everyone that modules processing is beginning
173 std::size_t i_proc{0};
174 if (performance_)
175 performance_->start(performance::Callback::onProcessStart, 0);
177 for (auto proc : sequence_) {
178 i_proc++;
179 if (performance_)
180 performance_->start(performance::Callback::onProcessStart, i_proc);
181 proc->onProcessStart();
182 if (performance_)
183 performance_->stop(performance::Callback::onProcessStart, i_proc);
184 }
185 if (performance_)
186 performance_->stop(performance::Callback::onProcessStart, 0);
187
188 // If we have no input files, but do have an event number, run for
189 // that number of events and generate an output file.
190 if (input_files_.empty() && event_limit_ > 0) {
191 if (output_files_.empty()) {
192 EXCEPTION_RAISE("InvalidConfig",
193 "No input files or output files were given.");
194 } else if (output_files_.size() > 1) {
195 ldmx_log(warn) << "Several output files given with no input files. "
196 << "Only the first output file '" << output_files_.at(0)
197 << "' will be used.";
198 }
199 std::string output_file_name = output_files_.at(0);
200
201 // Configure the event file to create an output file with no parent. This
202 // requires setting the parameters isOutputFile and isSingleOutput to true.
203 EventFile out_file(config_, output_file_name, nullptr, true, true, false);
204 onFileOpen(out_file);
205 out_file.setupEvent(&the_event);
206
207 for (auto rule : drop_keep_rules_) out_file.addDrop(rule);
208
210 run_header.setRunStart(std::time(nullptr)); // set run starting
211 run_header_ = &run_header; // give handle to run header to process
212 out_file.writeRunHeader(run_header); // add run header to file
213
214 newRun(run_header);
215
216 int total_tries = 0; // total number of tries for entire run
217 int num_tries = 0; // number of tries for the current event number
218 int event_limit = event_limit_;
219 if (total_events_ > 0) {
220 // Have a warning at the first event
221 if (num_tries == 0)
222 ldmx_log(warn) << "The total_events was set, so max_events and "
223 "max_tries_per_event will be ignored!";
224 event_limit = total_events_;
225 }
226 while (n_events_processed < event_limit) {
227 // Check for preemption before processing each event
228 if (preemption_received_) {
229 ldmx_log(fatal)
230 << "Preemption signal received, stopping event generation";
231 break;
232 }
233
234 total_tries++;
235 num_tries++;
236
237 ldmx::EventHeader &eh = the_event.getEventHeader();
239 eh.setEventNumber(n_events_processed + 1);
240 eh.setTimestamp(TTimeStamp());
241
242 // reset the storage controller state
245
246 bool completed = process(n_events_processed, num_tries, the_event);
247
248 out_file.nextEvent(storage_controller_.keepEvent(completed));
249
250 // reset try counter only on successfully completed events
251 if (completed) num_tries = 0;
252
253 // we use modulo here insetad of >= because we want to carry
254 // the number of tries across the number of events processed boundary
255 // total_events_ is set let's not exit until that's reached
256 if (completed or (total_events_ < 0 and num_tries % max_tries_ == 0)) {
257 n_events_processed++; // increment events made
258 NtupleManager::getInstance().fill(); // fill ntuples
259 }
260
262 }
263
264 onFileClose(out_file);
265
266 run_header.setRunEnd(std::time(nullptr));
267 run_header.setNumTries(total_tries);
268 out_file.writeRunTree();
269
270 // Give a warning that this filter has very low efficiency
271 if (n_events_processed < total_tries / 10000) { // integer division is okay
272 ldmx_log(warn)
273 << "Less than 1 event out of every 10k events tried was accepted!";
274 ldmx_log(warn)
275 << "This could be an issue with your filtering and biasing procedure "
276 "since this is incredibly inefficient.";
277 }
278
279 } else {
280 // there are input files
281
282 EventFile *out_file(0);
283
284 bool single_output = false;
285 if (output_files_.size() == 1) {
286 single_output = true;
287 } else if (!output_files_.empty() and
288 output_files_.size() != input_files_.size()) {
289 EXCEPTION_RAISE("Process",
290 "Unable to handle case of different number of input and "
291 "output files (other than zero/one ouput file).");
292 }
293
294 // next, loop through the files
295 int ifile = 0;
296 int was_run = -1;
297 for (auto infilename : input_files_) {
298 EventFile in_file(config_, infilename);
299 if (in_file.isCorrupted()) {
301 ldmx_log(warn) << "Input file '" << infilename
302 << "' was found to be corrupted. Skipping.";
303 continue;
304 } else {
305 EXCEPTION_RAISE(
306 "BadCode",
307 "We should never get here. "
308 "EventFile is corrupted but we aren't skipping corrupted inputs. "
309 "EventFile should be throwing its own exceptions in this case.");
310 }
311 }
312
313 ldmx_log(info) << "Opening file " << infilename;
314 onFileOpen(in_file);
315
316 // configure event file that will be iterated over
317 EventFile *master_file;
318 if (!output_files_.empty()) {
319 // setup new output file if either
320 // 1) we are not in single output mode
321 // 2) this is the first input file
322 if (!single_output or ifile == 0) {
323 // setup new output file
324 out_file = new EventFile(config_, output_files_[ifile], &in_file,
325 single_output);
326 ifile++;
327
328 // setup theEvent we will iterate over
329 if (out_file) {
330 out_file->setupEvent(&the_event);
331 master_file = out_file;
332 } else {
333 EXCEPTION_RAISE("Process", "Unable to construct output file for " +
334 output_files_[ifile]);
335 }
336
337 for (auto rule : drop_keep_rules_) out_file->addDrop(rule);
338
339 } else {
340 // all other input files
341 out_file->updateParent(&in_file);
342 master_file = out_file;
343
344 } // check if in singleOutput mode
345
346 } else {
347 // empty output file list, use inputFile as master file
348 in_file.setupEvent(&the_event);
349 master_file = &in_file;
350 }
351
352 // In case we'd like to skip up to the event of min_events_
353 while (n_events_processed < (min_events_ - 1) &&
354 master_file->nextEvent(false)) {
355 n_events_processed++;
356 }
357
358 bool event_completed = true;
359 while (!preemption_received_ &&
360 master_file->nextEvent(
361 storage_controller_.keepEvent(event_completed)) &&
362 ((event_limit_ < 0) || (n_events_processed < event_limit_))) {
363 // clean up for storage control calculation
366
367 // notify for new run if necessary
368 if (the_event.getEventHeader().getRun() != was_run) {
369 was_run = the_event.getEventHeader().getRun();
370 ldmx::RunHeader *rh{master_file->getRunHeaderPtr(was_run)};
371 if (rh != nullptr) {
372 run_header_ = rh;
373 ldmx_log(info) << "Got new run header from '"
374 << master_file->getFileName() << "'";
376 } else {
377 ldmx_log(warn) << "Run header for run " << was_run
378 << " was not found!";
379 }
380 }
381
382 event_completed = process(n_events_processed, 1, the_event);
383
384 if (event_completed) NtupleManager::getInstance().fill();
386
387 n_events_processed++;
388 } // loop through events
389
390 if (preemption_received_) {
391 ldmx_log(fatal) << "Preemption signal received, stopping event "
392 "processing and closing files";
393 }
394
395 bool leave_early{false};
396 if (event_limit_ > 0 && n_events_processed == event_limit_) {
397 ldmx_log(info) << "Reached event limit of " << event_limit_
398 << " events";
399 leave_early = true;
400 }
401
402 if (event_limit_ == 0 && n_events_processed > event_limit_) {
403 ldmx_log(warn) << "Processing interrupted";
404 leave_early = true;
405 }
406
407 ldmx_log(info) << "Closing file " << infilename;
408 onFileClose(in_file);
409
410 // Reset the event in case of multiple input files
411 the_event.onEndOfFile();
412
413 if (out_file and !single_output) {
414 out_file->writeRunTree();
415 delete out_file;
416 out_file = nullptr;
417 }
418
419 if (leave_early) {
420 break;
421 }
422 } // loop through input files
423
424 if (out_file) {
425 // close outFile
426 // outFile would survive to here in single output mode
427 out_file->writeRunTree();
428 delete out_file;
429 out_file = nullptr;
430 }
431
432 } // are there input files? if-else tree
433
434 // finally, notify everyone that we are stopping
435 if (performance_) performance_->start(performance::Callback::onProcessEnd, 0);
436 i_proc = 0;
437 for (auto proc : sequence_) {
438 i_proc++;
439 if (performance_)
440 performance_->start(performance::Callback::onProcessEnd, i_proc);
441 proc->onProcessEnd();
442 if (performance_)
443 performance_->stop(performance::Callback::onProcessEnd, i_proc);
444 }
445 if (performance_) performance_->stop(performance::Callback::onProcessEnd, 0);
446
447 // we're done so let's close up the logging
448 logging::close();
450}
451
455
456TDirectory *Process::makeHistoDirectory(const std::string &dirName) {
457 auto owner{openHistoFile()};
458 TDirectory *child = owner->mkdir((char *)dirName.c_str());
459 if (child) child->cd();
460 return child;
461}
462
464 TDirectory *owner{nullptr};
465
466 if (histo_filename_.empty()) {
467 // trying to write histograms/ntuples but no file defined
468 EXCEPTION_RAISE(
469 "NoHistFileName",
470 "You did not provide the necessary histogram file name to "
471 "put your histograms (or performance data) in.\n Provide this "
472 "name in the python configuration with 'p.histogramFile = "
473 "\"myHistFile.root\"' where p is the Process object.");
474 } else if (histo_t_file_ == nullptr) {
475 histo_t_file_ = new TFile(histo_filename_.c_str(), "RECREATE");
476 owner = histo_t_file_;
477 } else {
478 owner = histo_t_file_;
479 }
480 owner->cd();
481
482 return owner;
483}
484
486 // Producers are allowed to put parameters into
487 // the run header through 'beforeNewRun' method
488
489 // Put the version into the rh string param
490 header.setStringParameter("Pass = " + pass_name_ + ", version",
491 LDMXSW_VERSION);
492 if (performance_) performance_->start(performance::Callback::beforeNewRun, 0);
493 std::size_t i_proc{0};
494 for (auto proc : sequence_) {
495 i_proc++;
496 if (performance_)
497 performance_->start(performance::Callback::beforeNewRun, i_proc);
498 proc->beforeNewRun(header);
499 if (performance_)
500 performance_->stop(performance::Callback::beforeNewRun, i_proc);
501 }
502 if (performance_) performance_->stop(performance::Callback::beforeNewRun, 0);
503 // now run header has been modified by Producers,
504 // it is valid to read from for everyone else in 'onNewRun'
505 if (performance_) performance_->start(performance::Callback::onNewRun, 0);
506 conditions_.onNewRun(header);
507 i_proc = 0;
508 for (auto proc : sequence_) {
509 i_proc++;
510 if (performance_)
511 performance_->start(performance::Callback::onNewRun, i_proc);
512 proc->onNewRun(header);
513 if (performance_)
514 performance_->stop(performance::Callback::onNewRun, i_proc);
515 }
516 if (performance_) performance_->stop(performance::Callback::onNewRun, 0);
517 ldmx_log(info) << header;
518}
519
520bool Process::process(int n, int n_try, Event &event) const {
521 if ((log_frequency_ != -1) && ((n + 1) % log_frequency_ == 0) &&
522 (n_try < 2)) {
523 // only printout event counter if we've enabled log frequency, the event
524 // matches the frequency and we are on the first try
525 TTimeStamp t;
526 ldmx_log(info) << "Processing " << n + 1 << " Run "
527 << event.getEventHeader().getRun() << " Event "
528 << event.getEventHeader().getEventNumber() << " ("
529 << t.AsString("lc") << ")";
530 }
531
532 if (performance_) performance_->start(performance::Callback::process, 0);
533 std::size_t i_proc{0};
534 try {
535 for (auto proc : sequence_) {
536 i_proc++;
537 if (performance_)
538 performance_->start(performance::Callback::process, i_proc);
539 proc->process(event);
540 if (performance_)
541 performance_->stop(performance::Callback::process, i_proc);
542 }
543 } catch (AbortEventException &) {
544 if (performance_) {
545 performance_->stop(performance::Callback::process, i_proc);
546 performance_->stop(performance::Callback::process, 0);
547 performance_->endEvent(false);
548 }
549 return false;
550 }
551 if (performance_) {
552 performance_->stop(performance::Callback::process, 0);
553 performance_->endEvent(true);
554 }
555 return true;
556}
557
559 if (performance_) performance_->start(performance::Callback::onFileOpen, 0);
560 std::size_t i_proc{0};
561 for (auto proc : sequence_) {
562 i_proc++;
563 if (performance_)
564 performance_->start(performance::Callback::onFileOpen, i_proc);
565 proc->onFileOpen(file);
566 if (performance_)
567 performance_->stop(performance::Callback::onFileOpen, i_proc);
568 }
569 if (performance_) performance_->stop(performance::Callback::onFileOpen, 0);
570}
571
573 if (performance_) performance_->start(performance::Callback::onFileClose, 0);
574 std::size_t i_proc{0};
575 for (auto proc : sequence_) {
576 i_proc++;
577 if (performance_)
578 performance_->start(performance::Callback::onFileClose, i_proc);
579 proc->onFileClose(file);
580 if (performance_)
581 performance_->stop(performance::Callback::onFileClose, i_proc);
582 }
583 if (performance_) performance_->stop(performance::Callback::onFileClose, 0);
584}
585
586} // namespace framework
Base classes for all user event processing components to extend.
Class implementing an event buffer system for storing event data.
Class which represents the process under execution.
Specific exception used to abort an event.
void onProcessStart()
Calls onProcessStart for all ConditionsObjectProviders.
void onNewRun(ldmx::RunHeader &)
Calls onNewRun for all ConditionsObjectProviders.
void createConditionsObjectProvider(const std::string &classname, const std::string &instancename, const std::string &tagname, const framework::config::Parameters &params)
Create a ConditionsObjectProvider given the information.
This class manages all ROOT file input/output operations.
Definition EventFile.h:26
void updateParent(EventFile *parent)
Change pointer to different parent file.
const std::string & getFileName()
Definition EventFile.h:258
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 writeRunTree()
Write the map of run headers to the file as a TTree of RunHeader.
bool nextEvent(bool storeCurrentEvent=true)
Prepare the next event.
ldmx::RunHeader * getRunHeaderPtr(int runNumber)
Update the RunHeader for a given run, if it exists in the input file.
void writeRunHeader(ldmx::RunHeader &runHeader)
Write the run header into the run map.
bool isCorrupted() const
Check if the file we have is corrupted.
Base class for all event processing components.
Implements an event buffer system for storing event data.
Definition Event.h:42
int getEventNumber() const
Get the event number.
Definition Event.h:81
void onEndOfFile()
Perform end of file action.
Definition Event.cxx:172
ldmx::EventHeader & getEventHeader()
Get the event header.
Definition Event.h:59
const ldmx::EventHeader * getEventHeaderPtr()
Get the event header as a pointer.
Definition Event.h:75
void clear()
Reset all of the variables to their limits.
static NtupleManager & getInstance()
void reset()
Reset NtupleManager to blank state.
int log_frequency_
The frequency with which event info is printed.
Definition Process.h:169
std::vector< EventProcessor * > sequence_
Ordered list of EventProcessors to execute.
Definition Process.h:183
bool skip_corrupted_input_files_
allow the Process to skip input files that are corrupted
Definition Process.h:177
std::string histo_filename_
Filename for histograms and other user products.
Definition Process.h:211
int max_tries_
Maximum number of attempts to make before giving up on an event.
Definition Process.h:172
int run_for_generation_
Run number to use if generating events.
Definition Process.h:208
int compression_setting_
Compression setting to pass to output files.
Definition Process.h:202
void run()
Run the process.
Definition Process.cxx:154
int event_limit_
Limit on events to process.
Definition Process.h:158
std::string pass_name_
Processing pass name.
Definition Process.h:155
void newRun(ldmx::RunHeader &header)
Run through the processors and let them know that we are starting a new run.
Definition Process.cxx:485
TFile * histo_t_file_
TFile for histograms and other user products.
Definition Process.h:220
TDirectory * openHistoFile()
Open a ROOT TFile to write histograms and TTrees.
Definition Process.cxx:463
int total_events_
Number of events we'd like to produce independetly of the number of tries it would take.
Definition Process.h:166
~Process()
Class Destructor.
Definition Process.cxx:140
void onFileClose(EventFile &file) const
File is begin closed.
Definition Process.cxx:572
std::vector< std::string > drop_keep_rules_
Set of drop/keep rules.
Definition Process.h:205
ldmx::RunHeader * run_header_
Pointer to the current RunHeader, used for Conditions information.
Definition Process.h:217
TDirectory * makeHistoDirectory(const std::string &dirName)
Construct a TDirectory* for the given module.
Definition Process.cxx:456
performance::Tracker * performance_
class with calls backs to track performance measurements of software
Definition Process.h:223
int min_events_
When reading a file in, what's the first event to read.
Definition Process.h:161
StorageControl storage_controller_
Storage controller.
Definition Process.h:180
std::vector< std::string > output_files_
List of output file names.
Definition Process.h:193
std::vector< std::string > input_files_
List of input files to process.
Definition Process.h:190
const ldmx::EventHeader * event_header_
Pointer to the current EventHeader, used for Conditions information.
Definition Process.h:214
bool process(int n, int n_tries, Event &event) const
Process the input event through the sequence of processors.
Definition Process.cxx:520
void onFileOpen(EventFile &file) const
File is being opened.
Definition Process.cxx:558
Conditions conditions_
Set of ConditionsProviders.
Definition Process.h:186
Process(const framework::config::Parameters &configuration)
Class constructor.
Definition Process.cxx:29
int getRunNumber() const
Get the current run number or the run number to be used when initiating new events from the job.
Definition Process.cxx:452
framework::config::Parameters config_
The parameters used to configure this class.
Definition Process.h:152
void setDefaultKeep(bool keep)
Set the default state.
bool keepEvent(bool event_completed) const
Determine if the current event should be kept, based on the defined rules.
void addRule(const std::string &processor_pat, const std::string &purpose_pat)
Add a listening rule.
void resetEventState()
Reset the event-by-event state.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
static void set(int n)
set the event number in the current Formatter
Definition Logger.cxx:158
Class to interface between framework::Process and various measurements that can eventually be written...
Definition Tracker.h:20
void start(Callback cb, std::size_t i_proc)
start the timer for a specific callback and specific processor
Definition Tracker.cxx:90
void absoluteStop()
literally last line of Process::run (if run compeletes without error)
Definition Tracker.cxx:88
void endEvent(bool completed)
inform us that we finished an event (and whether it was completed or not)
Definition Tracker.cxx:98
void stop(Callback cb, std::size_t i_proc)
stop the timer for a specific callback and specific processor
Definition Tracker.cxx:94
void absoluteStart()
literally first line of Process::run
Definition Tracker.cxx:86
Provides header information an event such as event number and timestamp.
Definition EventHeader.h:44
int getRun() const
Return the run number.
Definition EventHeader.h:84
void setEventNumber(int eventNumber)
Set the event number.
void setRun(int run)
Set the run number.
void setTimestamp(const TTimeStamp &timestamp)
Set the timestamp.
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:57
void setRunEnd(const int runEnd)
Set the end time of the run in seconds since epoch.
Definition RunHeader.h:129
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:222
void setRunStart(const int runStart)
Set the run start time in seconds since epoch.
Definition RunHeader.h:115
void setNumTries(const int numTries)
Set the total number of tries that were done during the production of this run.
Definition RunHeader.h:149
All classes in the ldmx-sw project use this namespace.