10#include <framework/core/Module.h>
12#include <framework/core/EventProcessor.h>
14#include <framework/core/PathIterator.h>
15#include <framework/datastore/DataStore.h>
16#include <framework/database/DBStore.h>
17#include <framework/database/Database.h>
18#include <framework/logging/Logger.h>
19#include <framework/core/Environment.h>
20#include <framework/core/DataFlowVisualization.h>
21#include <framework/core/RandomNumbers.h>
22#include <framework/core/MetadataService.h>
23#include <framework/gearbox/Unit.h>
24#include <framework/utilities/Utils.h>
27#include <valgrind/callgrind.h>
34#define CALL_MODULE(module,x) \
35 if(m_profileModule && m_profileModule==module && RUNNING_ON_VALGRIND){\
36 CALLGRIND_START_INSTRUMENTATION;\
38 CALLGRIND_STOP_INSTRUMENTATION;\
43#define CALL_MODULE(module, x) module->x()
56 static int gSignalReceived = 0;
57 static void signalHandler(
int signal)
59 gSignalReceived = signal;
61 if (signal == SIGINT) {
62 EventProcessor::writeToStdErr(
"Received Ctrl+C, basf2 will exit safely. (Press Ctrl+\\ (SIGQUIT) to abort immediately - this will break output files.)\n");
67 runtime_error(
"Execution stopped by signal " + to_string(signal_) +
"!"),
78 const int len = strlen(msg);
80 int rc = write(STDERR_FILENO, msg, len);
96 struct NumberEventsOverrideGuard {
98 explicit NumberEventsOverrideGuard(
unsigned int newValue)
104 ~NumberEventsOverrideGuard()
109 unsigned int m_maxEvent;
117 if ((numEventsArgument > 0) && ((maxEvent == 0) || (maxEvent > numEventsArgument))) {
118 return numEventsArgument;
129 NumberEventsOverrideGuard numberOfEventsOverrideGuard(maxEvent);
136 for (
const auto& module : moduleList) {
143 B2FATAL(
"Module profiling was requested via --profile, but no module '" <<
m_profileModuleName <<
"' was found!");
150 for (
const auto& module : moduleList) {
151 if (module->getType() ==
"SteerRootInput") {
153 B2INFO(
"Module 'SteerRootInputModule' is controlling the number of processed events.");
169 B2ERROR(
"There is no module that provides event and run numbers (EventMetaData). You must add either the EventInfoSetter or an input module (e.g. RootInput) to the beginning of your path.");
174 if ((numLogError == 0) &&
m_master) {
181 gROOT->GetListOfFiles()->Delete();
188 B2ERROR(
"Exception occured in exp/run/evt: "
196 B2FATAL(numLogError <<
" ERROR(S) occurred! The processing of events will not be started.");
204 if (gSignalReceived == SIGINT) {
205 const auto msg = R
"(Processing aborted via SIGINT, terminating.
206 Output files have been closed safely and should be readable. However
207 processing was NOT COMPLETE. The output files do contain only events
208 processed until this point.)";
231 logSystem.
updateModule(&(module->getLogConfig()), module->getName());
235 CALL_MODULE(module, event);
257 for (
const ModulePtr& modPtr : modulePathList) {
258 Module* module = modPtr.get();
260 if (module->hasUnsetForcedParams()) {
266 logSystem.
updateModule(&(module->getLogConfig()), module->getName());
272 CALL_MODULE(module, initialize);
280 B2DEBUG(100,
"Found module providing EventMetaData: " << module->getName());
290 if (gSignalReceived != 0) {
300 memset(&s,
'\0',
sizeof(s));
303 sigemptyset(&s.sa_mask);
305 s.sa_flags |= SA_NOCLDSTOP;
307 if (sigaction(sig, &s,
nullptr) != 0) {
308 B2FATAL(
"Cannot setup signal handler for signal " << sig);
331 while (!moduleIter.
isDone()) {
335 if (!(skipMasterModule && module ==
m_master)) {
343 B2WARNING(
"Event processing stopped by module '" << module->getName() <<
344 "', which is not in control of event processing (does not provide EventMetaData)");
382 B2FATAL(
"Two modules setting EventMetaData were discovered: " <<
m_master->
getName() <<
" and " << module->getName());
386 if (gSignalReceived != 0) {
391 if (module->evalCondition()) {
392 PathPtr condPath = module->getConditionPath();
394 if (module->getAfterConditionPath() == Module::EAfterConditionPath::c_Continue) {
417 bool endProcess =
false;
418 while (!endProcess) {
423 endProcess =
processEvent(moduleIter, isInputProcess && currEvent == 0);
429 if ((maxEvent > 0) && (currEvent >= maxEvent)) endProcess =
true;
445 ModulePtrList::const_reverse_iterator listIter;
448 for (listIter = modulePathList.rbegin(); listIter != modulePathList.rend(); ++listIter) {
449 Module* module = listIter->get();
452 logSystem.
updateModule(&(module->getLogConfig()), module->getName());
456 CALL_MODULE(module, terminate);
483 Module* module = modPtr.get();
486 logSystem.
updateModule(&(module->getLogConfig()), module->getName());
490 CALL_MODULE(module, beginRun);
519 Module* module = modPtr.get();
522 logSystem.
updateModule(&(module->getLogConfig()), module->getName());
526 CALL_MODULE(module, endRun);
class to visualize data flow between modules.
void visualizePath(const std::string &filename, const Path &path)
Create graphs with datastore inputs/outputs of each module in path.
In the store you can park objects that have to be accessed by various modules.
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
static DataStore & Instance()
Instance of singleton Store.
void setInitializeActive(bool active)
Setter for m_initializeActive.
void invalidateData(EDurability durability)
Clears all registered StoreEntry objects of a specified durability, invalidating all objects.
DependencyMap & getDependencyMap()
Return map of depedencies between modules.
void setModule(const Module &mod)
Set the current module (for getCurrentModuleInfo())
void setNumberEventsOverride(unsigned int nevents)
Override the number of events in run 1 for EventInfoSetter module.
bool getNoStats() const
Disable collection of statistics during event processing.
static Environment & Instance()
Static method to get a reference to the Environment instance.
unsigned int getNumberEventsOverride() const
Returns number of events in run 1 for EventInfoSetter module, or 0 for no override.
Exception thrown when execution is stopped by a signal.
int signal
see 'man 7 signal'.
StoppedBySignalException(int signal)
Constructor.
void processEndRun()
Calls the end run methods of all modules.
void processInitialize(const ModulePtrList &modulePathList, bool setEventInfo=true)
Initializes the modules.
bool m_inRun
Are we currently in a run? If yes, processEndRun() needs to do something.
std::string m_profileModuleName
Name of the module which should be profiled, empty if no profiling is requested.
void processBeginRun(bool skipDB=false)
Calls the begin run methods of all modules.
void processCore(const PathPtr &startPath, const ModulePtrList &modulePathList, long maxEvent=0, bool isInputProcess=true)
Processes the full module chain consisting of an arbitrary number of connected paths,...
double m_lastMetadataUpdate
Time in seconds of last call for metadata update in event loop.
static void installSignalHandler(int sig, void(*fn)(int))
Install a signal handler 'fn' for given signal.
StoreObjPtr< ProcessStatistics > m_processStatisticsPtr
Also used in a number of places.
void process(const PathPtr &startPath, long maxEvent=0)
Processes the full module chain, starting with the first module in the given path.
void callEvent(Module *module)
Calls event() on one single module, setting up logging and statistics as needed.
void processTerminate(const ModulePtrList &modulePathList)
Terminates the modules.
Module * m_profileModule
Adress of the module which we want to profile, nullptr if no profiling is requested.
static void writeToStdErr(const char msg[])
async-safe method to write something to STDERR.
bool processEvent(PathIterator moduleIter, bool skipMasterModule)
Calls event() functions on all modules for the current event.
virtual ~EventProcessor()
Destructor.
const Module * m_master
The master module that determines the experiment/run/event number.
EventProcessor()
Constructor.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
EventMetaData is used by processEvent()/processCore().
ModulePtrList m_moduleList
List of all modules in order initialized.
long getMaximumEventNumber(long maxEvent) const
Calculate the maximum event number out of the argument from command line and the environment.
EventMetaData m_previousEventMetaData
Stores state of EventMetaData before it was last changed.
bool m_steerRootInputModuleOn
True if the SteerRootInputModule is in charge for event processing.
double m_metadataUpdateInterval
Minimal time difference in seconds for metadata updates in event loop.
static void installMainSignalHandlers(void(*fn)(int)=nullptr)
Install signal handler for INT, TERM and QUIT signals.
@ c_Error
Error: for things that went wrong and have to be fixed.
Class for logging debug, info and error messages.
void updateModule(const LogConfig *moduleLogConfig=nullptr, const std::string &moduleName="")
Sets the log configuration to the given module log configuration and sets the module name This method...
void printErrorSummary()
Print error/warning summary at end of execution.
int getMessageCounter(LogConfig::ELogLevel logLevel) const
Returns the number of logging calls per log level.
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
@ c_Init
Counting time/calls in initialize()
@ c_EndRun
Counting time/calls in endRun()
@ c_Term
Counting time/calls in terminate()
@ c_BeginRun
Counting time/calls in beginRun()
@ c_Event
Counting time/calls in event()
const std::string & getName() const
Returns the name of the module.
Iterator over a Path (returning Module pointers).
bool isDone() const
Are we finished iterating?
Module * get() const
dereference.
static void initializeEndRun()
Initialize run independent random generator for end run.
static void initializeBeginRun()
Initialize run independent random generator for begin run.
static void useEventDependent()
Set Event dependent Random Generator as current one.
static void initializeEvent(bool force=false)
Initialize event information.
static const double s
[second]
Class to store variables with their name which were sent to the logging service.
std::shared_ptr< Path > PathPtr
Defines a pointer to a path object as a boost shared pointer.
static Database & Instance()
Instance of a singleton Database.
static DBStore & Instance()
Instance of a singleton DBStore.
std::shared_ptr< Module > ModulePtr
Defines a pointer to a module object as a boost shared pointer.
std::list< ModulePtr > ModulePtrList
Defines a std::list of shared module pointers.
void updateEvent()
Updates all intra-run dependent objects.
void update()
Updates all objects that are outside their interval of validity.
ScopeGuard createScopedUpdateSession()
Make sure we have efficient http pipelinging during initialize/beginRun but don't keep session alive ...
double getClock()
Return current value of the real-time clock.
Abstract base class for different kinds of events.