Commit 986d3d7c authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Module: split in declaration & implementation. Behavior change:

functions now not purely virtual, is is now possible to ignore
initialise()/run()/finalise() when implementing modules, they
then just do nothing
parent 86d6aed4
......@@ -12,6 +12,7 @@ ADD_LIBRARY(CorryvreckanCore SHARED
config/ConfigReader.cpp
config/Configuration.cpp
config/exceptions.cpp
module/Module.cpp
)
# Link the dependencies
......
/** @file
* @brief Implementation of the base module class
* @copyright Copyright (c) 2017 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
#include "Module.hpp"
using namespace corryvreckan;
Module::Module(Configuration config, std::vector<Detector*> detectors) {
m_name = config.getName();
m_config = config;
m_detectors = detectors;
m_stopwatch = new TStopwatch();
IFLOG(TRACE) {
std::stringstream det;
for(auto& d : m_detectors) {
det << d->name() << ", ";
}
LOG(TRACE) << "Module determined to run on detectors: " << det.str();
}
}
Module::~Module() {}
Detector* Module::get_detector(std::string name) {
auto it = find_if(m_detectors.begin(), m_detectors.end(), [&name](Detector* obj) { return obj->name() == name; });
if(it == m_detectors.end()) {
throw ModuleError("Device with detector ID " + name + " is not registered.");
}
return (*it);
}
bool Module::has_detector(std::string name) {
auto it = find_if(m_detectors.begin(), m_detectors.end(), [&name](Detector* obj) { return obj->name() == name; });
if(it == m_detectors.end()) {
return false;
}
return true;
}
#ifndef MODULE_H
#define MODULE_H 1
/** @file
* @brief Base class for Corryvreckan modules
* @copyright Copyright (c) 2017 CERN and the Corryvreckan authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
#ifndef CORRYVRECKAN_MODULE_H
#define CORRYVRECKAN_MODULE_H
// Include files
#include <string>
#include "TStopwatch.h"
#include "core/clipboard/Clipboard.hpp"
......@@ -9,19 +16,19 @@
#include "core/detector/Detector.hpp"
#include "exceptions.h"
//-------------------------------------------------------------------------------
// The module class is the base class that all user modules are built on.
// It
// allows the analysis class to hold modules of different types, without
// knowing
// what they are, and provides the functions initialise, run and finalise. It
// also
// gives some basic tools like the "tcout" replacement for "cout" (appending the
// module name) and the stopwatch for timing measurements.
//-------------------------------------------------------------------------------
namespace corryvreckan {
/**
* @brief Flags to signal the status of a module processing a given event
*
* These flags are to be used as return values for the Module::run() function to signal the framework the outcome of the
* event processing. Here, three different states are supported:
* - Success: the event processing finished successfully and the framework should continue processing this event with the
* next module.
* - NoData: there was no data found to process by this module. The framework should skip all following modules and
* proceed with the next event.
* - Failure: the module failed to process the event correctly or requests an end of the event processing for other
* reasons. The framework should stop processing events and call Module::finalise for all modules.
*/
enum StatusCode {
Success,
NoData,
......@@ -31,31 +38,67 @@ namespace corryvreckan {
/** Base class for all modules
* @defgroup Modules Modules
*/
/**
* @brief Base class for all modules
*
* The module base is the core of the modular framework. All modules should be descendants of this class. The base class
* defines the methods the children can implement:
* - Module::initialise(): for initializing the module at the start
* - Module::run(Clipoard* Clipboard): for doing the job of every module for every event
* - Module::finalise(): for finalising the module at the end
*
* The module class also provides a few utility methods such as a stopwatch for timing measurements.
*/
class Module {
public:
// Constructors and destructors
Module() {}
Module(Configuration config, std::vector<Detector*> detectors) {
m_name = config.getName();
m_config = config;
m_detectors = detectors;
m_stopwatch = new TStopwatch();
IFLOG(TRACE) {
std::stringstream det;
for(auto& d : m_detectors) {
det << d->name() << ", ";
}
LOG(TRACE) << "Module determined to run on detectors: " << det.str();
}
}
virtual ~Module() {}
// Three main functions - initialise, run and finalise. Called for every
// module
virtual void initialise() = 0;
virtual StatusCode run(Clipboard*) = 0;
virtual void finalise() = 0;
/**
* @brief Delete default constructor (configuration required)
*/
Module() = delete;
/**
* @brief Base constructor for modules
* @param config Configuration for this module
* @param detectors List of detectors this module should be aware of
*/
Module(Configuration config, std::vector<Detector*> detectors);
/**
* @brief Essential virtual destructor.
*/
virtual ~Module();
/**
* @brief Copying a module is not allowed
*/
Module(const Module&) = delete;
Module& operator=(const Module&) = delete;
/**
* @brief Initialise the module before the event sequence
*
* Does nothing if not overloaded.
*/
virtual void initialise() {}
/**
* @brief Execute the function of the module for every event
* @param clipboard Pointer to the central clipboard to store and fetch information
* @return Status code of the event processing
*
* Does nothing if not overloaded.
*/
virtual StatusCode run(Clipboard* clipboard) { (void)clipboard; }
/**
* @brief Finalise the module after the event sequence
* @note Useful to have before destruction to allow for raising exceptions
*
* Does nothing if not overloaded.
*/
virtual void finalise(){};
// Methods to get member variables
std::string getName() { return m_name; }
......@@ -64,32 +107,18 @@ namespace corryvreckan {
protected:
// Member variables
TStopwatch* m_stopwatch;
std::string m_name;
Configuration m_config;
std::vector<Detector*> get_detectors() { return m_detectors; };
std::size_t num_detectors() { return m_detectors.size(); };
Detector* get_detector(std::string name) {
auto it =
find_if(m_detectors.begin(), m_detectors.end(), [&name](Detector* obj) { return obj->name() == name; });
if(it == m_detectors.end()) {
throw ModuleError("Device with detector ID " + name + " is not registered.");
}
return (*it);
}
bool has_detector(std::string name) {
auto it =
find_if(m_detectors.begin(), m_detectors.end(), [&name](Detector* obj) { return obj->name() == name; });
if(it == m_detectors.end()) {
return false;
}
return true;
}
Detector* get_detector(std::string name);
bool has_detector(std::string name);
private:
TStopwatch* m_stopwatch;
std::vector<Detector*> m_detectors;
};
} // namespace corryvreckan
#endif
#endif // CORRYVRECKAN_MODULE_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment