Loading etc/scripts/make_module.sh +63 −48 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ read -p "Input message type? " MESSAGETYPE # Check that message type exists OBJDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P )" OBJDIR=$OBJDIR/../../src/objects if [ ! -e ${OBJDIR}/${MESSAGETYPE}.hpp ] if [ ! -z "${MESSAGETYPE}" ] && [ ! -e ${OBJDIR}/${MESSAGETYPE}.hpp ] then echo -e "\nMessage type ${MESSAGETYPE} does not exist. \nPlease see the message types in ${OBJDIR}\n" exit 1 Loading @@ -57,6 +57,9 @@ done # Create directory mkdir "$MODDIR/$MODNAME" if [ $? != 0 ]; then exit 1 fi # Copy over CMake file and sources from Dummy: sed -e "s/Dummy/$MODNAME/g" $MODDIR/Dummy/CMakeLists.txt > $MODDIR/$MODNAME/CMakeLists.txt Loading Loading @@ -105,9 +108,10 @@ if [ "$type" = 2 ]; then command="sed ${opt} \ -e 's/GeometryManager\* geo_manager/std::shared\_ptr\<Detector\> detector/g' \ -e 's/Module(config)/Module\(config\, detector\)/g' \ -e 's/geo_manager_(geo_manager)/detector_(detector)/g' \ -e 's/bindMulti/bindSingle/g' \ -e '/for(auto/d' \ -e 's/geo_manager_(geo_manager)/detector_(detector)/g' \ -e 's/\s\{8\}/\ \ \ \ /' \ -e '/geo_manager_/d' \ -e 's/detector->get/detector_->get/g' \ -e '/ }/d' \ Loading @@ -122,7 +126,7 @@ fi if [ "$sequence" = 1 ]; then # Change header file command="sed ${opt} \ -e 's/ Module/ SequentialModule/g' \ -e 's/public Module/public SequentialModule/g' \ $MODDIR/$MODNAME/${MODNAME}Module.hpp" eval $command # Change implementation file Loading @@ -132,10 +136,19 @@ if [ "$sequence" = 1 ]; then eval $command fi if [ ! -z "${MESSAGETYPE}" ]; then # Replace the corresponding message type in the header and source file command="sed ${opt} \ -e 's/PixelHit/${MESSAGETYPE}/g' \ $MODDIR/$MODNAME/${MODNAME}Module.*pp" else command="sed ${opt} \ -e '/PixelHit/d' \ -e '/\/\/ Messages:/d' \ -e '/for(auto\& message/,+4d' \ -e '/particular message/,+2d' \ $MODDIR/$MODNAME/${MODNAME}Module.*pp" fi eval $command # Print a summary of the module created: Loading @@ -143,7 +156,9 @@ FINALPATH=`realpath $MODDIR/$MODNAME` echo "Name: $MODNAME" echo "Author: $MYNAME ($MYMAIL)" echo "Path: $FINALPATH" if [ ! -z "${MESSAGETYPE}" ]; then echo "This module listens to \"$MESSAGETYPE\" messages from" $([ "$type" = 2 ] && echo "one detector" || echo "all detectors") fi if [ "$sequence" = 1 ]; then echo "This module requires sequential processing of events in multithreaded environments." fi Loading src/modules/Dummy/DummyModule.cpp +30 −14 Original line number Diff line number Diff line /** * @file * @brief Implementation of [Dummy] module * @copyright Copyright (c) 2017-2020 CERN and the Allpix Squared authors. * @brief Implementation of Dummy module * * @copyright Copyright (c) 2017-2022 CERN and the Allpix Squared 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. Loading @@ -19,27 +20,42 @@ using namespace allpix; DummyModule::DummyModule(Configuration& config, Messenger* messenger, GeometryManager* geo_manager) : Module(config), geo_manager_(geo_manager), messenger_(messenger) { // ... Implement ... (Typically bounds the required messages and optionally sets configuration defaults) // Input required by this module // Allow multithreading of the simulation. Only enabled if this module is thread-safe. See manual for more details. // allow_multithreading(); // Set a default for a configuration parameter, this will be used if no user configuration is provided: config_.setDefault<int>("setting", 13); // Parsing of the parameter "setting" into a member variable for later use: setting_ = config_.get<int>("setting"); // Messages: register this module with the central messenger to request a certaintype of input messages: messenger_->bindMulti<PixelHitMessage>(this, MsgFlags::REQUIRED); } void DummyModule::initialize() { // Loop over detectors and do something std::vector<std::shared_ptr<Detector>> detectors = geo_manager_->getDetectors(); for(auto& detector : detectors) { // Get the detector name std::string detectorName = detector->getName(); LOG(DEBUG) << "Detector with name " << detectorName; // Loop over detectors and perform some initialization or similar: for(auto& detector : geo_manager_->getDetectors()) { // In this simple case we just print the name of this detector: LOG(DEBUG) << "Detector with name " << detector->getName(); } } void DummyModule::run(Event* event) { // Messages: Fetch the (previously registered) messages for this event from the messenger: auto messages = messenger_->fetchMultiMessage<PixelHitMessage>(this, event); // ... Implement ... (Typically uses the configuration to execute function and outputs an message) // Loop through all received messages and print some information // Messages: Loop through all received messages for(auto& message : messages) { std::string detectorName = message->getDetector()->getName(); LOG(DEBUG) << "Picked up " << message->getData().size() << " objects from detector " << detectorName; // Print the name of the detector for which this particular message has been dispatched: LOG(DEBUG) << "Picked up " << message->getData().size() << " objects from detector " << message->getDetector()->getName(); } } void DummyModule::finalize() { // Possibly perform finalization of the module - if not, this method does not need to be implemented and can be removed! LOG(INFO) << "Successfully finalized!"; } src/modules/Dummy/DummyModule.hpp +45 −6 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ * * Contains minimal dummy module to use as a start for the development of your own module * * Refer to the User's Manual for more details. * Please refer to the User Manual for more details on the different files of a module and the methods of the module class.. */ #include <string> Loading @@ -24,14 +24,22 @@ namespace allpix { /** * @ingroup Modules * @brief Module to do function * @brief Module which serves as a demonstrator and wireframe for new modules * * More detailed explanation of module * This module is only a dummy and here to demonstrate the general structure of a module with its different member * methods, the messenger and event interfaces. It also serves as wireframe for new modules, which can take the structure * for a quicker start. */ class DummyModule : public Module { public: /** * @brief Constructor for this unique module * * The constructor of the module is called right after the module has been instantiated. It has access to the module * configuration and can set defaults and retrieve values from the config. The constructor is also the place where * multithreading capabilities of the module need to be announced, and where the messenger should be notified about * desired input messages that should be relayed to this module. * * @param config Configuration object for this module as retrieved from the steering file * @param messenger Pointer to the messenger object to allow binding to messages on the bus * @param geo_manager Pointer to the geometry manager, containing the detectors Loading @@ -39,18 +47,49 @@ namespace allpix { DummyModule(Configuration& config, Messenger* messenger, GeometryManager* geo_manager); /** * @brief [Initialise this module] * @brief Initialization method of the module * * This method is called during the initialization phase of the framework. In this method, all necessary setup steps * for this module should be conducted, such that the module is ready to perform simulations. Typically at this stage * additional checks on compatibility of the user-configured parameters and the information such as fields and maps * obtained from the detector models are implemented. * * This method is called once per simulation run, before the event loop is started. * * Implementing this method is optional, if no initialization is required there is no need to override and implement * this method. */ void initialize() override; /** * @brief [Run the function of this module] * @brief Run method of the module * * This is the event processing method of the module and is called for every single event in the event loop once. The * method should retrieve potentially registered messages, process them, dispatch possible output messages to the * messenger of the framework, and the return control to the caller by ending the method. */ void run(Event* event) override; /** * @brief Finalization method of the module * * In this method, finalization steps of the module can be performed after the event loop has been finished. This * could for example comprise aggregation of final histograms, the calculation of a final value averaged over all * events, or the closing of an output file. * * This method is called once per simulation run, after the event loop has been finished. * * Implementing this method is optional, if no finalization is required there is no need to override and implement * this method. */ void finalize() override; private: // General module members // Pointers to the central geometry manager and the messenger for interaction with the framework core: GeometryManager* geo_manager_; Messenger* messenger_; // A local module member variable which is set on the constructor and only read during runtime: int setting_{}; }; } // namespace allpix Loading
etc/scripts/make_module.sh +63 −48 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ read -p "Input message type? " MESSAGETYPE # Check that message type exists OBJDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd -P )" OBJDIR=$OBJDIR/../../src/objects if [ ! -e ${OBJDIR}/${MESSAGETYPE}.hpp ] if [ ! -z "${MESSAGETYPE}" ] && [ ! -e ${OBJDIR}/${MESSAGETYPE}.hpp ] then echo -e "\nMessage type ${MESSAGETYPE} does not exist. \nPlease see the message types in ${OBJDIR}\n" exit 1 Loading @@ -57,6 +57,9 @@ done # Create directory mkdir "$MODDIR/$MODNAME" if [ $? != 0 ]; then exit 1 fi # Copy over CMake file and sources from Dummy: sed -e "s/Dummy/$MODNAME/g" $MODDIR/Dummy/CMakeLists.txt > $MODDIR/$MODNAME/CMakeLists.txt Loading Loading @@ -105,9 +108,10 @@ if [ "$type" = 2 ]; then command="sed ${opt} \ -e 's/GeometryManager\* geo_manager/std::shared\_ptr\<Detector\> detector/g' \ -e 's/Module(config)/Module\(config\, detector\)/g' \ -e 's/geo_manager_(geo_manager)/detector_(detector)/g' \ -e 's/bindMulti/bindSingle/g' \ -e '/for(auto/d' \ -e 's/geo_manager_(geo_manager)/detector_(detector)/g' \ -e 's/\s\{8\}/\ \ \ \ /' \ -e '/geo_manager_/d' \ -e 's/detector->get/detector_->get/g' \ -e '/ }/d' \ Loading @@ -122,7 +126,7 @@ fi if [ "$sequence" = 1 ]; then # Change header file command="sed ${opt} \ -e 's/ Module/ SequentialModule/g' \ -e 's/public Module/public SequentialModule/g' \ $MODDIR/$MODNAME/${MODNAME}Module.hpp" eval $command # Change implementation file Loading @@ -132,10 +136,19 @@ if [ "$sequence" = 1 ]; then eval $command fi if [ ! -z "${MESSAGETYPE}" ]; then # Replace the corresponding message type in the header and source file command="sed ${opt} \ -e 's/PixelHit/${MESSAGETYPE}/g' \ $MODDIR/$MODNAME/${MODNAME}Module.*pp" else command="sed ${opt} \ -e '/PixelHit/d' \ -e '/\/\/ Messages:/d' \ -e '/for(auto\& message/,+4d' \ -e '/particular message/,+2d' \ $MODDIR/$MODNAME/${MODNAME}Module.*pp" fi eval $command # Print a summary of the module created: Loading @@ -143,7 +156,9 @@ FINALPATH=`realpath $MODDIR/$MODNAME` echo "Name: $MODNAME" echo "Author: $MYNAME ($MYMAIL)" echo "Path: $FINALPATH" if [ ! -z "${MESSAGETYPE}" ]; then echo "This module listens to \"$MESSAGETYPE\" messages from" $([ "$type" = 2 ] && echo "one detector" || echo "all detectors") fi if [ "$sequence" = 1 ]; then echo "This module requires sequential processing of events in multithreaded environments." fi Loading
src/modules/Dummy/DummyModule.cpp +30 −14 Original line number Diff line number Diff line /** * @file * @brief Implementation of [Dummy] module * @copyright Copyright (c) 2017-2020 CERN and the Allpix Squared authors. * @brief Implementation of Dummy module * * @copyright Copyright (c) 2017-2022 CERN and the Allpix Squared 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. Loading @@ -19,27 +20,42 @@ using namespace allpix; DummyModule::DummyModule(Configuration& config, Messenger* messenger, GeometryManager* geo_manager) : Module(config), geo_manager_(geo_manager), messenger_(messenger) { // ... Implement ... (Typically bounds the required messages and optionally sets configuration defaults) // Input required by this module // Allow multithreading of the simulation. Only enabled if this module is thread-safe. See manual for more details. // allow_multithreading(); // Set a default for a configuration parameter, this will be used if no user configuration is provided: config_.setDefault<int>("setting", 13); // Parsing of the parameter "setting" into a member variable for later use: setting_ = config_.get<int>("setting"); // Messages: register this module with the central messenger to request a certaintype of input messages: messenger_->bindMulti<PixelHitMessage>(this, MsgFlags::REQUIRED); } void DummyModule::initialize() { // Loop over detectors and do something std::vector<std::shared_ptr<Detector>> detectors = geo_manager_->getDetectors(); for(auto& detector : detectors) { // Get the detector name std::string detectorName = detector->getName(); LOG(DEBUG) << "Detector with name " << detectorName; // Loop over detectors and perform some initialization or similar: for(auto& detector : geo_manager_->getDetectors()) { // In this simple case we just print the name of this detector: LOG(DEBUG) << "Detector with name " << detector->getName(); } } void DummyModule::run(Event* event) { // Messages: Fetch the (previously registered) messages for this event from the messenger: auto messages = messenger_->fetchMultiMessage<PixelHitMessage>(this, event); // ... Implement ... (Typically uses the configuration to execute function and outputs an message) // Loop through all received messages and print some information // Messages: Loop through all received messages for(auto& message : messages) { std::string detectorName = message->getDetector()->getName(); LOG(DEBUG) << "Picked up " << message->getData().size() << " objects from detector " << detectorName; // Print the name of the detector for which this particular message has been dispatched: LOG(DEBUG) << "Picked up " << message->getData().size() << " objects from detector " << message->getDetector()->getName(); } } void DummyModule::finalize() { // Possibly perform finalization of the module - if not, this method does not need to be implemented and can be removed! LOG(INFO) << "Successfully finalized!"; }
src/modules/Dummy/DummyModule.hpp +45 −6 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ * * Contains minimal dummy module to use as a start for the development of your own module * * Refer to the User's Manual for more details. * Please refer to the User Manual for more details on the different files of a module and the methods of the module class.. */ #include <string> Loading @@ -24,14 +24,22 @@ namespace allpix { /** * @ingroup Modules * @brief Module to do function * @brief Module which serves as a demonstrator and wireframe for new modules * * More detailed explanation of module * This module is only a dummy and here to demonstrate the general structure of a module with its different member * methods, the messenger and event interfaces. It also serves as wireframe for new modules, which can take the structure * for a quicker start. */ class DummyModule : public Module { public: /** * @brief Constructor for this unique module * * The constructor of the module is called right after the module has been instantiated. It has access to the module * configuration and can set defaults and retrieve values from the config. The constructor is also the place where * multithreading capabilities of the module need to be announced, and where the messenger should be notified about * desired input messages that should be relayed to this module. * * @param config Configuration object for this module as retrieved from the steering file * @param messenger Pointer to the messenger object to allow binding to messages on the bus * @param geo_manager Pointer to the geometry manager, containing the detectors Loading @@ -39,18 +47,49 @@ namespace allpix { DummyModule(Configuration& config, Messenger* messenger, GeometryManager* geo_manager); /** * @brief [Initialise this module] * @brief Initialization method of the module * * This method is called during the initialization phase of the framework. In this method, all necessary setup steps * for this module should be conducted, such that the module is ready to perform simulations. Typically at this stage * additional checks on compatibility of the user-configured parameters and the information such as fields and maps * obtained from the detector models are implemented. * * This method is called once per simulation run, before the event loop is started. * * Implementing this method is optional, if no initialization is required there is no need to override and implement * this method. */ void initialize() override; /** * @brief [Run the function of this module] * @brief Run method of the module * * This is the event processing method of the module and is called for every single event in the event loop once. The * method should retrieve potentially registered messages, process them, dispatch possible output messages to the * messenger of the framework, and the return control to the caller by ending the method. */ void run(Event* event) override; /** * @brief Finalization method of the module * * In this method, finalization steps of the module can be performed after the event loop has been finished. This * could for example comprise aggregation of final histograms, the calculation of a final value averaged over all * events, or the closing of an output file. * * This method is called once per simulation run, after the event loop has been finished. * * Implementing this method is optional, if no finalization is required there is no need to override and implement * this method. */ void finalize() override; private: // General module members // Pointers to the central geometry manager and the messenger for interaction with the framework core: GeometryManager* geo_manager_; Messenger* messenger_; // A local module member variable which is set on the constructor and only read during runtime: int setting_{}; }; } // namespace allpix