diff --git a/DDDigi/include/DDDigi/DigiContainerProcessor.h b/DDDigi/include/DDDigi/DigiContainerProcessor.h index 0dcfee5e137bc89b421df12f094b02bb3ef15bfe..9be4485e7f907546178cffaeecbd3039479f87bb 100644 --- a/DDDigi/include/DDDigi/DigiContainerProcessor.h +++ b/DDDigi/include/DDDigi/DigiContainerProcessor.h @@ -66,18 +66,21 @@ namespace dd4hep { /// Hit processing predicate struct predicate_t { - Callback callback { }; - uint32_t id { 0 }; + using deposit_t = std::pair<const CellID, EnergyDeposit>; + using callback_t = std::function<bool(const deposit_t&)>; + callback_t callback { }; + uint32_t id { 0 }; const segmentation_t* segmentation { nullptr }; predicate_t() = default; + predicate_t(std::function<bool(const deposit_t&)> func, uint32_t i, const segmentation_t* s) + : callback(func), id(i), segmentation(s) {} predicate_t(predicate_t&& copy) = default; predicate_t(const predicate_t& copy) = default; - predicate_t(const Callback& c, uint32_t i, const segmentation_t* s) - : callback(c), id(i), segmentation(s) {} predicate_t& operator = (predicate_t&& copy) = default; predicate_t& operator = (const predicate_t& copy) = default; /// Check if a deposit should be processed - bool operator()(const std::pair<const CellID, EnergyDeposit>& deposit) const; + bool operator()(const deposit_t& deposit) const; + static bool always_true(const deposit_t&) { return true; } }; /// Work definition @@ -122,11 +125,36 @@ namespace dd4hep { }; /// Check if a deposit should be processed - inline bool DigiContainerProcessor::predicate_t::operator()(const std::pair<const CellID, EnergyDeposit>& deposit) const { - const void* args[] = { &deposit }; - return this->callback.execute(args); + inline bool DigiContainerProcessor::predicate_t::operator()(const deposit_t& deposit) const { + return this->callback(deposit); } + /// Worker class act on ONLY act on energy deposit containers in an event + /** + * Worker class act on ONLY act on energy deposit containers in an event. + * The deposit containers are identified by input masks and container name. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiDepositsProcessor : public DigiContainerProcessor { + protected: + std::function<void(context_t& context, DepositVector& cont, work_t& work, const predicate_t& predicate)> m_handleVector; + std::function<void(context_t& context, DepositMapping& cont, work_t& work, const predicate_t& predicate)> m_handleMapping; + + public: + /// Standard constructor + using DigiContainerProcessor::DigiContainerProcessor; + + /// Main functional callback adapter + virtual void execute(context_t& context, work_t& work, const predicate_t& predicate) const; + }; + +#define DEPOSIT_PROCESSOR_BIND_HANDLERS(X) { using namespace std::placeholders; \ + this->m_handleVector = std::bind( &X<DepositVector>, this, _1, _2, _3, _4); \ + this->m_handleMapping = std::bind( &X<DepositMapping>, this, _1, _2, _3, _4); } + /// Worker class act on containers in an event identified by input masks and container name /** * The sequencer calls all registered processors for the contaiers registered. diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h index 2ae18985ade8eb8a6960f978a22d24c12d318b58..4937b1753ed351c9c395eba6e084a93b19280a04 100644 --- a/DDDigi/include/DDDigi/DigiData.h +++ b/DDDigi/include/DDDigi/DigiData.h @@ -471,7 +471,8 @@ namespace dd4hep { ENERGY_SMEARED = 1 << 1, POSITION_SMEARED = 1 << 2, TIME_SMEARED = 1 << 3, - RECALIBRATED = 1 << 4 + ZERO_SUPPRESSED = 1 << 4, + RECALIBRATED = 1 << 5 }; /// Hit position diff --git a/DDDigi/include/DDDigi/DigiKernel.h b/DDDigi/include/DDDigi/DigiKernel.h index 041cf245490e80b4b1a3aa9ebe4003bc0a1064c5..85b374db36d6c713603aab255ec56796319ff96c 100644 --- a/DDDigi/include/DDDigi/DigiKernel.h +++ b/DDDigi/include/DDDigi/DigiKernel.h @@ -14,7 +14,6 @@ #define DDDIGI_DIGIKERNEL_H // Framework include files -#include <DD4hep/Callback.h> #include <DDDigi/DigiEventAction.h> #include <DDDigi/DigiParallelWorker.h> @@ -132,15 +131,15 @@ namespace dd4hep { std::size_t events_processing() const; /// Register configure callback. Signature: (function)() - void register_configure(const Callback& callback) const; + void register_configure(const std::function<void()>& callback) const; /// Register initialize callback. Signature: (function)() - void register_initialize(const Callback& callback) const; + void register_initialize(const std::function<void()>& callback) const; /// Register terminate callback. Signature: (function)() - void register_terminate(const Callback& callback) const; + void register_terminate(const std::function<void()>& callback) const; /// Register start event callback. Signature: (function)(DigiContext*) - void register_start_event(const Callback& callback) const; + void register_start_event(const std::function<void(DigiContext&)>& callback) const; /// Register end event callback. Signature: (function)(DigiContext*) - void register_end_event(const Callback& callback) const; + void register_end_event(const std::function<void(DigiContext&)>& callback) const; /// Construct detector geometry using description plugin virtual void loadGeometry(const std::string& compact_file); diff --git a/DDDigi/include/DDDigi/DigiSegmentSplitter.h b/DDDigi/include/DDDigi/DigiSegmentSplitter.h index 85a046b55b99a79d8956ac044e95d05a4e238ab7..0c59ba13e5fa8ba95eef4d8129e0c868fa7e8fb8 100644 --- a/DDDigi/include/DDDigi/DigiSegmentSplitter.h +++ b/DDDigi/include/DDDigi/DigiSegmentSplitter.h @@ -69,8 +69,8 @@ namespace dd4hep { } /// Check if a deposit should be processed - bool use_depo(const std::pair<const CellID, EnergyDeposit>* deposit) const { - return this->matches(deposit->first); + bool use_depo(const std::pair<const CellID, EnergyDeposit>& deposit) const { + return this->matches(deposit.first); } void enable(uint32_t split_id); }; @@ -84,12 +84,11 @@ namespace dd4hep { */ struct accept_segment_t : public DigiContainerProcessor::predicate_t { accept_segment_t(const DigiSegmentContext* s, uint32_t i) - : predicate_t( {}, i, s) { - callback = Callback(this).make(&accept_segment_t::use_depo); + : predicate_t(std::bind(&accept_segment_t::use_depo, this, std::placeholders::_1), i, s) { } /// Check if a deposit should be processed - bool use_depo(const std::pair<const CellID, EnergyDeposit>* deposit) const { - return this->segmentation->split_id(deposit->first) == this->id; + bool use_depo(const deposit_t& deposit) const { + return this->segmentation->split_id(deposit.first) == this->id; } }; @@ -108,8 +107,7 @@ namespace dd4hep { /** Local use definitions */ using self_t = DigiSegmentSplitter; using tool_t = DigiSegmentationTool; - using split_t = std::pair<DetElement, VolumeID>; - using splits_t = std::map<VolumeID, split_t>; + using splits_t = std::set<uint32_t>; using segment_t = DigiSegmentProcessContext; using processor_t = DigiContainerProcessor; diff --git a/DDDigi/include/DDDigi/DigiSegmentationTool.h b/DDDigi/include/DDDigi/DigiSegmentationTool.h index 713a4afa9568ccdbb6ecaa04d7fd4ff576105e03..9d6a802f71fb5b7d2c8591de8499c2847ba1a607 100644 --- a/DDDigi/include/DDDigi/DigiSegmentationTool.h +++ b/DDDigi/include/DDDigi/DigiSegmentationTool.h @@ -123,8 +123,7 @@ namespace dd4hep { DigiSegmentContext split_context(const std::string& split_by) const; /// Create full set of detector segments which can be split according to the context - std::map<VolumeID, std::pair<DetElement, VolumeID> > - split_segmentation(const std::string& split_by) const; + std::set<uint32_t> split_segmentation(const std::string& split_by) const; }; } // End namespace digi } // End namespace dd4hep diff --git a/DDDigi/plugins/DigiDepositSmearTime.cpp b/DDDigi/plugins/DigiDepositSmearTime.cpp index 7925d1f82dfb8f31de661b9e77e0137dd370e730..e3e208de30a412dcfa3ee0c56efac508fbc8af14 100644 --- a/DDDigi/plugins/DigiDepositSmearTime.cpp +++ b/DDDigi/plugins/DigiDepositSmearTime.cpp @@ -13,7 +13,6 @@ // Framework include files #include <DDDigi/DigiContainerProcessor.h> -#include <DD4hep/InstanceCount.h> #include <DD4hep/DD4hepUnits.h> /// C/C++ include files @@ -33,80 +32,45 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiDepositSmearTime : public DigiContainerProcessor { + class DigiDepositSmearTime : public DigiDepositsProcessor { protected: using limit_t = std::numeric_limits<double>; /// Property: Intrinsic energy resolution constant (gaussian ~ std::sqrt(energy)) double m_resolution_time { 0e0 }; /// Property: Time window within the smeared deposits shall be accepted std::pair<double, double> m_window_time { limit_t::min(), limit_t::max() }; - /// Property: Flag to update existing container in-place or create a new container - bool m_update_in_place { true }; public: - /// Standard constructor - DigiDepositSmearTime(const DigiKernel& krnl, const std::string& nam) - : DigiContainerProcessor(krnl, nam) - { - declareProperty("resolution_time", m_resolution_time); - declareProperty("window_time", m_window_time); - InstanceCount::increment(this); - } - - /// Default destructor - virtual ~DigiDepositSmearTime() { - InstanceCount::decrement(this); - } - /// Create deposit mapping with updates on same cellIDs template <typename T> void - smear(DigiContext& context, T& cont, work_t& work, const predicate_t& predicate) const { + smear(DigiContext& context, T& cont, work_t& /* work */, const predicate_t& predicate) const { auto& random = context.randomGenerator(); - T output_cont(cont.name, work.output.mask); std::size_t killed = 0UL; std::size_t updated = 0UL; - std::size_t created = 0UL; - - info("%s+++ TIME smearing deposit container: %s %6ld entries", - context.event->id(), cont.name.c_str(), cont.size()); - for( auto& dep : cont ) { - if ( predicate(dep) ) { + for( auto& dep : cont ) { + if ( predicate(dep) ) { int flag = EnergyDeposit::TIME_SMEARED; double delta_T = m_resolution_time * random.gaussian(); if ( delta_T < m_window_time.first || delta_T > m_window_time.second ) { flag |= EnergyDeposit::KILLED; ++killed; } - if ( m_update_in_place ) { - EnergyDeposit& d = dep.second; - d.time += delta_T; - d.flag |= flag; - ++updated; - } - else if ( !(flag&EnergyDeposit::KILLED) ) { - EnergyDeposit d(dep.second); - d.time += delta_T; - d.flag |= flag; - output_cont.emplace(dep.first, std::move(d)); - ++created; - } + dep.second.time += delta_T; + dep.second.flag |= flag; + ++updated; } } - if ( !m_update_in_place ) { - work.output.data.put(output_cont.key, std::move(output_cont)); - } - info("%s+++ %-32s Smearing: created %6ld updated %6ld killed %6ld entries from mask: %04X", - context.event->id(), cont.name.c_str(), created, updated, killed, cont.key.mask()); + info("%s+++ %-32s Smeared time resolution: %6ld entries, updated %6ld killed %6ld entries from mask: %04X", + context.event->id(), cont.name.c_str(), cont.size(), updated, killed, cont.key.mask()); } - /// Main functional callback - virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate) const override final { - if ( auto* v = work.get_input<DepositVector>() ) - smear(context, *v, work, predicate); - else if ( auto* m = work.get_input<DepositMapping>() ) - smear(context, *m, work, predicate); - else - except("Request to handle unknown data type: %s", work.input_type_name().c_str()); + /// Standard constructor + DigiDepositSmearTime(const DigiKernel& krnl, const std::string& nam) + : DigiDepositsProcessor(krnl, nam) + { + declareProperty("resolution_time", m_resolution_time); + declareProperty("window_time", m_window_time); + DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositSmearTime::smear) } }; } // End namespace digi diff --git a/DDDigi/plugins/DigiDepositWeightedPosition.cpp b/DDDigi/plugins/DigiDepositWeightedPosition.cpp index 4bde23c5af4449c5ca588e6398b4f18018db8bba..36e1f1ed04da3fd7110532b8cf93dac6f6843ff0 100644 --- a/DDDigi/plugins/DigiDepositWeightedPosition.cpp +++ b/DDDigi/plugins/DigiDepositWeightedPosition.cpp @@ -20,6 +20,7 @@ /// Namespace for the AIDA detector description toolkit namespace dd4hep { + /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { @@ -34,28 +35,15 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiDepositWeightedPosition : public DigiContainerProcessor { + class DigiDepositWeightedPosition : public DigiDepositsProcessor { protected: /// Property: Energy cutoff. No hits will be merged with a deposit smaller double m_cutoff { -std::numeric_limits<double>::epsilon() }; public: - /// Standard constructor - DigiDepositWeightedPosition(const DigiKernel& krnl, const std::string& nam) - : DigiContainerProcessor(krnl, nam) - { - declareProperty("deposit_cutoff", m_cutoff); - InstanceCount::increment(this); - } - - /// Default destructor - virtual ~DigiDepositWeightedPosition() { - InstanceCount::decrement(this); - } - /// Create deposit mapping with updates on same cellIDs template <typename T> void - create_deposits(const char* tag, const T& cont, work_t& work, const predicate_t& predicate) const { + create_deposits(context_t& context, const T& cont, work_t& work, const predicate_t& predicate) const { Key key(cont.name, work.output.mask); DepositMapping m(cont.name, work.output.mask); std::size_t dropped = 0UL, updated = 0UL, added = 0UL; @@ -75,19 +63,22 @@ namespace dd4hep { } } info("%s+++ %-32s added %6ld updated %6ld dropped %6ld entries (now: %6ld) from mask: %04X to mask: %04X", - tag, cont.name.c_str(), added, updated, dropped, m.size(), cont.key.mask(), m.key.mask()); + context.event->id(), cont.name.c_str(), added, updated, dropped, m.size(), cont.key.mask(), m.key.mask()); work.output.data.put(m.key, std::move(m)); } - /// Main functional callback - virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate) const override final { - if ( const auto* v = work.get_input<DepositVector>() ) - create_deposits(context.event->id(), *v, work, predicate); - else if ( const auto* m = work.get_input<DepositMapping>() ) - create_deposits(context.event->id(), *m, work, predicate); - else - except("%s+++ Request to handle unknown data type: %s", - context.event->id(), work.input_type_name().c_str()); + /// Standard constructor + DigiDepositWeightedPosition(const DigiKernel& krnl, const std::string& nam) + : DigiDepositsProcessor(krnl, nam) + { + InstanceCount::increment(this); + declareProperty("deposit_cutoff", m_cutoff); + DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositWeightedPosition::create_deposits) + } + + /// Default destructor + virtual ~DigiDepositWeightedPosition() { + InstanceCount::decrement(this); } }; } // End namespace digi diff --git a/DDDigi/plugins/DigiDepositZeroSuppress.cpp b/DDDigi/plugins/DigiDepositZeroSuppress.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f245f43a60017a12fa277e007e7f35caa98c13d --- /dev/null +++ b/DDDigi/plugins/DigiDepositZeroSuppress.cpp @@ -0,0 +1,72 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include <DDDigi/DigiContainerProcessor.h> +#include <DD4hep/DD4hepUnits.h> + +/// C/C++ include files +#include <limits> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + /// Actor to zero-suppress a container of energy deposits + /** + * + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiDepositZeroSuppress : public DigiDepositsProcessor { + protected: + /// Property: Intrinsic energy resolution constant (gaussian ~ std::sqrt(energy)) + double m_energy_threshold { 0e0 }; + + public: + /// Create deposit mapping with updates on same cellIDs + template <typename T> void + handle_deposits(DigiContext& context, T& cont, work_t& /* work */, const predicate_t& predicate) const { + std::size_t killed = 0UL; + std::size_t handled = 0UL; + for( auto& dep : cont ) { + if ( predicate(dep) ) { + int flag = EnergyDeposit::ZERO_SUPPRESSED; + if ( dep.second.deposit * dd4hep::GeV < m_energy_threshold ) { + flag |= EnergyDeposit::KILLED; + ++killed; + } + dep.second.flag |= flag; + ++handled; + } + } + info("%s+++ %-32s Zero suppression: entries: %6ld handled: %6ld killed %6ld entries from mask: %04X", + context.event->id(), cont.name.c_str(), cont.size(), handled, killed, cont.key.mask()); + } + /// Standard constructor + DigiDepositZeroSuppress(const DigiKernel& krnl, const std::string& nam) + : DigiDepositsProcessor(krnl, nam) + { + declareProperty("threshold", m_energy_threshold); + DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositZeroSuppress::handle_deposits) + } + }; + } // End namespace digi +} // End namespace dd4hep + +#include <DDDigi/DigiFactories.h> +DECLARE_DIGIACTION_NS(dd4hep::digi,DigiDepositZeroSuppress) diff --git a/DDDigi/plugins/DigiResegment.cpp b/DDDigi/plugins/DigiResegment.cpp index c34298d75cb7a77755aef287710a4db3eb4c53f2..70faf83aa7711dee7cc1362cdfe4f76d9ddfef17 100644 --- a/DDDigi/plugins/DigiResegment.cpp +++ b/DDDigi/plugins/DigiResegment.cpp @@ -63,7 +63,7 @@ namespace dd4hep { declareProperty("detector", m_detector_name); declareProperty("readout", m_readout_name); declareProperty("descriptor", m_readout_descriptor); - m_kernel.register_initialize(Callback(this).make(&DigiResegment::initialize)); + m_kernel.register_initialize(std::bind(&DigiResegment::initialize, this)); } void initialize() { diff --git a/DDDigi/python/dddigi.py b/DDDigi/python/dddigi.py index eb9028727dbd1731f14f3614a833effd9b8e428c..2f53ab5ad35577face9a1db7846a38fd429cbc8c 100644 --- a/DDDigi/python/dddigi.py +++ b/DDDigi/python/dddigi.py @@ -314,7 +314,7 @@ def _props(obj, **extensions): # print('Overloading: ' + str(cls) + ' ' + call + ' to __' + call) setattr(cls, '__' + call, getattr(cls, call)) else: - print('FAILED: Overloading: ' + str(cls) + ' '+call + ' to __' + call + ' ' + str(hasattr(cls, call))) + print('FAILED: Overloading: ' + str(cls) + ' ' + call + ' to __' + call + ' ' + str(hasattr(cls, call))) setattr(cls, call, extension[1]) cls.__getattr__ = _get cls.__setattr__ = _set diff --git a/DDDigi/src/DigiContainerCombine.cpp b/DDDigi/src/DigiContainerCombine.cpp index e6dc17af81469f4f5bf573b701db90d3dcce5649..22939f5a5cdef5e8d43a75aae9fa1a382c0c2127 100644 --- a/DDDigi/src/DigiContainerCombine.cpp +++ b/DDDigi/src/DigiContainerCombine.cpp @@ -231,7 +231,7 @@ DigiContainerCombine::DigiContainerCombine(const DigiKernel& krnl, const std::st declareProperty("output_mask", m_deposit_mask); declareProperty("output_name_flag", m_output_name_flag); declareProperty("erase_combined", m_erase_combined); - m_kernel.register_initialize(Callback(this).make(&DigiContainerCombine::initialize)); + m_kernel.register_initialize(std::bind(&DigiContainerCombine::initialize,this)); InstanceCount::increment(this); } diff --git a/DDDigi/src/DigiContainerDrop.cpp b/DDDigi/src/DigiContainerDrop.cpp index 550288c007ba318acacfec17ff7eab7505cd9751..efdcd5f3a6d56a72dde8e1378ff1daf8410ddd75 100644 --- a/DDDigi/src/DigiContainerDrop.cpp +++ b/DDDigi/src/DigiContainerDrop.cpp @@ -99,7 +99,7 @@ DigiContainerDrop::DigiContainerDrop(const DigiKernel& krnl, const std::string& declareProperty("containers", m_containers); declareProperty("input_masks", m_input_masks); declareProperty("input_segment", m_input_segment = "inputs"); - m_kernel.register_initialize(Callback(this).make(&DigiContainerDrop::initialize)); + m_kernel.register_initialize(std::bind(&DigiContainerDrop::initialize,this)); InstanceCount::increment(this); } diff --git a/DDDigi/src/DigiContainerProcessor.cpp b/DDDigi/src/DigiContainerProcessor.cpp index c93dba1926c6c88eb0b683bddc08ba73f4842fff..0fe42335f6bbb21e6aba1a75a943e55f5c94deca 100644 --- a/DDDigi/src/DigiContainerProcessor.cpp +++ b/DDDigi/src/DigiContainerProcessor.cpp @@ -81,12 +81,7 @@ std::string DigiContainerProcessor::work_t::input_type_name() const { /// Access to default callback const DigiContainerProcessor::predicate_t& DigiContainerProcessor::accept_all() { - struct true_t { - bool use(const std::pair<const CellID, EnergyDeposit>&) const { - return true; - } - } s_true; - static predicate_t s_pred { Callback(&s_true).make(&true_t::use), 0, nullptr }; + static predicate_t s_pred { std::bind(predicate_t::always_true, std::placeholders::_1), 0, nullptr }; return s_pred; } @@ -108,6 +103,16 @@ void DigiContainerProcessor::execute(context_t& /* context */, const predicate_t& /* predicate */) const { } +/// Main functional callback adapter +void DigiDepositsProcessor::execute(context_t& context, work_t& work, const predicate_t& predicate) const { + if ( auto* v = work.get_input<DepositVector>() ) + m_handleVector(context, *v, work, predicate); + else if ( auto* m = work.get_input<DepositMapping>() ) + m_handleMapping(context, *m, work, predicate); + else + except("Request to handle unknown data type: %s", work.input_type_name().c_str()); +} + /// Standard constructor DigiContainerSequence::DigiContainerSequence(const kernel_t& krnl, const std::string& nam) : DigiContainerProcessor(krnl, nam) @@ -152,7 +157,7 @@ DigiContainerSequenceAction::DigiContainerSequenceAction(const kernel_t& krnl, c declareProperty("input_segment", m_input_segment); declareProperty("output_mask", m_output_mask); declareProperty("output_segment", m_output_segment); - m_kernel.register_initialize(Callback(this).make(&DigiContainerSequenceAction::initialize)); + m_kernel.register_initialize(std::bind(&DigiContainerSequenceAction::initialize,this)); InstanceCount::increment(this); } @@ -261,7 +266,7 @@ DigiMultiContainerProcessor::DigiMultiContainerProcessor(const kernel_t& krnl, c declareProperty("input_segment", m_input_segment); declareProperty("output_mask", m_output_mask); declareProperty("output_segment", m_output_segment); - m_kernel.register_initialize(Callback(this).make(&DigiMultiContainerProcessor::initialize)); + m_kernel.register_initialize(std::bind(&DigiMultiContainerProcessor::initialize,this)); InstanceCount::increment(this); } diff --git a/DDDigi/src/DigiKernel.cpp b/DDDigi/src/DigiKernel.cpp index 920dbd630f5015d2527ed85b41c1aa9b04b7cfe8..cbf1a625624b580b97628b741334629c986f7bad 100644 --- a/DDDigi/src/DigiKernel.cpp +++ b/DDDigi/src/DigiKernel.cpp @@ -76,16 +76,18 @@ public: /// Lock for global output logging std::mutex global_output_lock { }; + using callbacks_t = std::vector<std::function<void()> >; + using ev_callbacks_t = std::vector<std::function<void(DigiContext&)> >; /// Configure callbacks - CallbackSequence configurators { }; + callbacks_t configurators { }; /// Initialize callbacks - CallbackSequence initializers { }; + callbacks_t initializers { }; //// Termination callback - CallbackSequence terminators { }; + callbacks_t terminators { }; /// Register start event callback - CallbackSequence start_event { }; + ev_callbacks_t start_event { }; /// Register end event callback - CallbackSequence end_event { }; + ev_callbacks_t end_event { }; /// The main data input action sequence DigiActionSequence* input_action { nullptr }; @@ -311,42 +313,42 @@ void DigiKernel::loadXML(const char* fname) { /// Configure the digitization: call all registered configurators int DigiKernel::configure() { - internals->configurators(); + for(auto& call : internals->configurators) call(); return 1; } /// Initialize the digitization: call all registered initializers int DigiKernel::initialize() { - internals->initializers(); + for(auto& call : internals->initializers) call(); return 1; } /// Register configure callback -void DigiKernel::register_configure(const Callback& callback) const { +void DigiKernel::register_configure(const std::function<void()>& callback) const { std::lock_guard<std::mutex> lock(initializer_lock()); - internals->configurators.add(callback); + internals->configurators.push_back(callback); } /// Register initialize callback -void DigiKernel::register_initialize(const Callback& callback) const { +void DigiKernel::register_initialize(const std::function<void()>& callback) const { std::lock_guard<std::mutex> lock(initializer_lock()); - internals->initializers.add(callback); + internals->initializers.push_back(callback); } /// Register terminate callback -void DigiKernel::register_terminate(const Callback& callback) const { +void DigiKernel::register_terminate(const std::function<void()>& callback) const { std::lock_guard<std::mutex> lock(initializer_lock()); - internals->terminators.add(callback); + internals->terminators.push_back(callback); } /// Register start event callback -void DigiKernel::register_start_event(const Callback& callback) const { - internals->start_event.add(callback); +void DigiKernel::register_start_event(const std::function<void(DigiContext&)>& callback) const { + internals->start_event.push_back(callback); } /// Register end event callback -void DigiKernel::register_end_event(const Callback& callback) const { - internals->end_event.add(callback); +void DigiKernel::register_end_event(const std::function<void(DigiContext&)>& callback) const { + internals->end_event.push_back(callback); } /// Access to the main input action sequence from the kernel object @@ -396,11 +398,11 @@ void DigiKernel::wait(DigiContext& context) const { void DigiKernel::executeEvent(std::unique_ptr<DigiContext>&& context) { DigiContext& refContext = *context; try { - internals->start_event(&refContext); + for(auto& call : internals->start_event) call(refContext); inputAction().execute(refContext); eventAction().execute(refContext); outputAction().execute(refContext); - internals->end_event(&refContext); + for(auto& call : internals->end_event) call(refContext); notify(std::move(context)); } catch(const std::exception& e) { @@ -474,7 +476,7 @@ int DigiKernel::run() { /// Terminate the digitization: call all registered terminators and release the allocated resources int DigiKernel::terminate() { printout(INFO, "DigiKernel", "++ Terminate Digi and delete associated actions."); - internals->terminators(); + for(auto& call : internals->terminators) call(); m_detDesc->destroyInstance(); m_detDesc = 0; return 1; diff --git a/DDDigi/src/DigiSegmentSplitter.cpp b/DDDigi/src/DigiSegmentSplitter.cpp index 1f016a5aae7b83289b39c0beec2f80094913b698..0b25a61e3fc4b533c6638c0bbe3717e92c14b918 100644 --- a/DDDigi/src/DigiSegmentSplitter.cpp +++ b/DDDigi/src/DigiSegmentSplitter.cpp @@ -42,7 +42,7 @@ DigiSegmentProcessContext::operator=(const DigiSegmentContext& copy) { void DigiSegmentProcessContext::enable(uint32_t split_id) { this->predicate.id = split_id; this->predicate.segmentation = this; - this->predicate.callback = Callback(this).make(&DigiSegmentProcessContext::use_depo); + this->predicate.callback = std::bind(&DigiSegmentProcessContext::use_depo, this, std::placeholders::_1); } /// Worker adaptor for caller DigiContainerSequence @@ -63,7 +63,7 @@ DigiSegmentSplitter::DigiSegmentSplitter(const kernel_t& kernel, const std::stri declareProperty("split_by", m_split_by); declareProperty("processor_type", m_processor_type); declareProperty("share_processor", m_share_processor = false); - m_kernel.register_initialize(Callback(this).make(&DigiSegmentSplitter::initialize)); + m_kernel.register_initialize(std::bind(&DigiSegmentSplitter::initialize,this)); InstanceCount::increment(this); } @@ -100,9 +100,8 @@ void DigiSegmentSplitter::initialize() { auto group = m_workers.get_group(); const auto& workers = group.actors(); /// Create the processors: - for( auto& p : m_splits ) { + for( auto split_id : m_splits ) { bool ok = false; - auto split_id = p.second.second; for( auto* w : workers ) { if ( w->options.predicate.id == split_id ) { w->options = m_split_context; @@ -125,15 +124,14 @@ void DigiSegmentSplitter::initialize() { } /// IF NOT: /// 2) Create the processors using the 'processor_type' option - for( auto& p : m_splits ) { - uint32_t id = m_split_context.split_id(p.first); + for( auto id : m_splits ) { ::snprintf(text, sizeof(text), "_%05X", id); std::string nam = this->name() + text; auto* proc = createAction<DigiContainerProcessor>(m_processor_type, m_kernel, nam); if ( !proc ) { except("+++ Failed to create split worker: %s/%s", m_processor_type.c_str(), nam.c_str()); } - info("+++ Created worker: %s layer: %d %d", nam.c_str(), p.first, id); + info("+++ Created worker: %s layer: %d", nam.c_str(), id); auto* w = new worker_t(proc, m_split_context); w->options.enable(id); m_workers.insert(w); @@ -165,8 +163,8 @@ void DigiSegmentSplitter::execute(context_t& context, work_t& work, const predic unmasked_key.set_item(key.item()); if ( std::find(m_keys.begin(), m_keys.end(), unmasked_key) != m_keys.end() ) { if ( work.has_input() ) { - info("+++ Got hit collection %04X %08X. Prepare processors for %sparallel execution.", - key.mask(), key.item(), m_parallel ? "" : "NON-"); + info("%s+++ Got hit collection %04X %08X. Prepare processors for %sparallel execution.", + context.event->id(), key.mask(), key.item(), m_parallel ? "" : "NON-"); m_kernel.submit(context, m_workers.get_group(), m_workers.size(), &work, m_parallel); } } diff --git a/DDDigi/src/DigiSegmentationTool.cpp b/DDDigi/src/DigiSegmentationTool.cpp index c8f94fde03f0f7b56ff69344f06bcc2ef3db574c..b25be527bbc0849258a9755f546e38f82ddd6683 100644 --- a/DDDigi/src/DigiSegmentationTool.cpp +++ b/DDDigi/src/DigiSegmentationTool.cpp @@ -183,9 +183,7 @@ DigiSegmentationTool::split_context(const string& split_by) const { } /// Create full set of detector segments which can be split according to the context -map<dd4hep::VolumeID, pair<dd4hep::DetElement, dd4hep::VolumeID> > -DigiSegmentationTool::split_segmentation(const string& split_by) const -{ +set<uint32_t> DigiSegmentationTool::split_segmentation(const string& split_by) const { map<VolumeID, pair<DetElement, VolumeID> > segmentation_splits; const auto& ids = this->detector.placement().volIDs(); VolumeID vid = this->iddescriptor.encode(ids); @@ -198,17 +196,19 @@ DigiSegmentationTool::split_segmentation(const string& split_by) const split_by.c_str(), this->iddescriptor.name()); } ::scan_detector(*this, split_by, segmentation_splits, this->detector, vid, msk); - printout(INFO,"DigiSegmentationTool", - "%-24s has %ld parallel entries when splitting by \"%s\"", - det, segmentation_splits.size(), split_by.c_str()); - stringstream str1, str2; + stringstream str; + set<uint32_t> splits; for( const auto& id : segmentation_splits ) { - str1 << setw(16) << hex << setfill('0') << id.first << " "; - str2 << setw(16) << hex << setfill(' ') << ((id.first&fld->mask())>>fld->offset()) << " "; + auto val = ((id.first&fld->mask())>>fld->offset()); + splits.insert(val); } - printout(INFO,"DigiSegmentationTool","%-24s --> Parallel Entries: %s", - det, str1.str().c_str()); + for( const auto& id : splits ) { + str << setw(16) << hex << setfill(' ') << id << " "; + } + printout(INFO,"DigiSegmentationTool", + "%-24s has %ld entries and %ld parallel entries when splitting by \"%s\"", + det, segmentation_splits.size(), splits.size(), split_by.c_str()); printout(INFO,"DigiSegmentationTool","%-24s --> %-12s ids: %s", - "", split_by.c_str(), str2.str().c_str()); - return segmentation_splits; + "", split_by.c_str(), str.str().c_str()); + return splits; } diff --git a/DDDigi/src/DigiStoreDump.cpp b/DDDigi/src/DigiStoreDump.cpp index a07881ee06573f955cb1195ad83a0ed0bb0117e0..c0e1d07efa5c26e7767771f331934b445d0db1a8 100644 --- a/DDDigi/src/DigiStoreDump.cpp +++ b/DDDigi/src/DigiStoreDump.cpp @@ -34,7 +34,7 @@ DigiStoreDump::DigiStoreDump(const DigiKernel& krnl, const std::string& nam) m_segments.push_back("output"); declareProperty("containers", m_containers); declareProperty("masks", m_masks); - m_kernel.register_initialize(Callback(this).make(&DigiStoreDump::initialize)); + m_kernel.register_initialize(std::bind(&DigiStoreDump::initialize,this)); InstanceCount::increment(this); } diff --git a/examples/DDDigi/scripts/TestDepositSmearTime.py b/examples/DDDigi/scripts/TestDepositSmearTime.py new file mode 100644 index 0000000000000000000000000000000000000000..48b68cc5c8347acb1b98d461406839755dc05b0e --- /dev/null +++ b/examples/DDDigi/scripts/TestDepositSmearTime.py @@ -0,0 +1,37 @@ +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== +from __future__ import absolute_import + + +def run(): + import DigiTest + from dd4hep import units + digi = DigiTest.Test(geometry=None) + digi.load_geo(volume_manager=True) + + event = DigiTest.test_setup_1(digi) + # ======================================================================================================== + proc = event.adopt_action('DigiContainerSequenceAction/Smearing', + parallel=False, + input_mask=0xEEE5, + input_segment='deposits') + smear = digi.create_action('DigiDepositSmearTime/Smear', + resolution_time=1e-6 * units.second) + proc.adopt_container_processor(smear, ['SiVertexEndcapHits', 'SiVertexBarrelHits']) + + event.adopt_action('DigiStoreDump/HeaderDump') + # ======================================================================================================== + digi.info('Starting digitization core') + digi.run_checked(num_events=3, num_threads=10, parallel=5) + + +if __name__ == '__main__': + run() diff --git a/examples/DDDigi/scripts/TestSegmentationSplit2.py b/examples/DDDigi/scripts/TestSegmentationSplit2.py index f0611c0dc648dfcf13c94f6e4127936260649a39..63fba35f90c3f1627e455adeeb8f8f5446ef35c2 100644 --- a/examples/DDDigi/scripts/TestSegmentationSplit2.py +++ b/examples/DDDigi/scripts/TestSegmentationSplit2.py @@ -31,13 +31,13 @@ def run(): splitter = digi.create_action('DigiSegmentSplitter/Splitter', parallel=True, split_by='layer', - detector='SiTrackerBarrel') + detector='SiTrackerEndcap') printer = digi.create_action('DigiSegmentDepositPrint/P1') splitter.get().adopt_segment_processor(printer, 1) printer = digi.create_action('DigiSegmentDepositPrint/P2') - splitter.adopt_segment_processor(printer, [2, 3, 4]) + splitter.adopt_segment_processor(printer, [2, 3]) printer = digi.create_action('DigiSegmentDepositPrint/P3') - splitter.adopt_segment_processor(printer, [5]) + splitter.adopt_segment_processor(printer, [4]) split_action.adopt_container_processor(splitter, splitter.collection_names()) event.adopt_action('DigiStoreDump/StoreDump')