diff --git a/DDCore/include/DDSegmentation/BitField64.h b/DDCore/include/DDSegmentation/BitField64.h index b3a7db0620c8d44ccbad8427dd5ddab2a8046c32..1697404a6e43d6292cb3de463ef06b8b89c9300d 100644 --- a/DDCore/include/DDSegmentation/BitField64.h +++ b/DDCore/include/DDSegmentation/BitField64.h @@ -21,11 +21,13 @@ #include "DDSegmentation/BitFieldCoder.h" +/// Namespace for the AIDA detector description toolkit namespace dd4hep { typedef long long int long64 ; typedef unsigned long long ulong64 ; + /// DDSegmentation namespace declaration namespace DDSegmentation { /// Lightweight helper class for BitField64 that corresponds to one field value. diff --git a/DDDigi/include/DDDigi/DigiContainerCombine.h b/DDDigi/include/DDDigi/DigiContainerCombine.h index 76cda89f1176b057281b671f12d91a646db3d3c7..a4bc569068d72196f43a597f2061ae86974d5c25 100644 --- a/DDDigi/include/DDDigi/DigiContainerCombine.h +++ b/DDDigi/include/DDDigi/DigiContainerCombine.h @@ -49,8 +49,8 @@ namespace dd4hep { /// Combine selected containers to one single deposit container template <typename PREDICATE> std::size_t combine_containers(DigiEvent& event, - DigiEvent::container_map_t& inputs, - DigiEvent::container_map_t& outputs, + DataSegment& inputs, + DataSegment& outputs, const PREDICATE& predicate) const; public: diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h index 9995201105f9e3ac213294675955d9b262b9d2c4..1340308930ae59a74a0595816d92fac25b0e2c2e 100644 --- a/DDDigi/include/DDDigi/DigiData.h +++ b/DDDigi/include/DDDigi/DigiData.h @@ -14,22 +14,13 @@ #define DDDIGI_DIGIDATA_H /// Framework include files -#include <DD4hep/config.h> -#include <DD4hep/Objects.h> -#include <DD4hep/Printout.h> #include <DD4hep/Primitives.h> -#include <DD4hep/ObjectExtensions.h> /// C/C++ include files -#include <functional> -#include <stdexcept> #include <cstdint> #include <memory> #include <mutex> #include <map> -#include <set> -#include <unordered_map> -#include <unordered_set> #include <any> /// Namespace for the AIDA detector description toolkit @@ -39,11 +30,13 @@ namespace dd4hep { namespace digi { /// Forward declarations - class DigiEvent; + union Key; class Particle; - class ParticleMapping; class EnergyDeposit; + class ParticleMapping; class DepositMapping; + class DigiEvent; + class DataSegment; /// Key defintion to access the event data /** @@ -58,19 +51,43 @@ namespace dd4hep { typedef std::uint32_t itemkey_type; typedef std::uint16_t mask_type; + /// First union entry used for fast initialization key_type key; + /// Second union entry to use for discrimination struct { itemkey_type item; mask_type mask; mask_type spare; } values; + + /// Default constructor Key(); + /// Move constructor + Key(Key&&); + /// Copy constructor Key(const Key&); + /// Initializaing constructor (fast) Key(key_type full_mask); + /// Initializaing constructor with key generation using hash algorithm Key(mask_type mask, const std::string& item); - Key& operator=(const Key&); - key_type toLong() const { return key; } + /// Assignment operator + Key& operator = (const Key&); + /// Move assignment operator + Key& operator = (Key&& copy); + /// Equality operator + bool operator == (const Key&) const; + /// Operator less + bool operator < (const Key&) const; + /// Operator greator + bool operator > (const Key&) const; + + /// Conversion to uint64 + key_type toLong() const { + return key; + } + /// Generate key using hash algorithm void set(const std::string& name, int mask); + /// Project the mask part of the key static itemkey_type item(key_type k) { return Key(k).values.item; @@ -83,6 +100,58 @@ namespace dd4hep { static std::string key_name(const Key& key); }; + /// Default constructor + inline Key::Key() { + this->key = 0; + } + + /// Move constructor + inline Key::Key(Key&& copy) { + this->key = copy.key; + } + + /// Copy constructor + inline Key::Key(const Key& copy) { + this->key = copy.key; + } + + /// Initializaing constructor (fast) + inline Key::Key(key_type full_mask) { + this->key = full_mask; + } + + /// Initializaing constructor with key generation using hash algorithm + inline Key::Key(mask_type mask, const std::string& item) { + this->set(item, mask); + } + + /// Move assignment operator + inline Key& Key::operator = (Key&& copy) { + this->key = copy.key; + return *this; + } + + /// Assignment operator + inline Key& Key::operator = (const Key& copy) { + this->key = copy.key; + return *this; + } + + /// Equality operator + inline bool Key::operator == (const Key& other) const { + return this->key == other.key; + } + + /// Operator less + inline bool Key::operator < (const Key& other) const { + return this->key < other.key; + } + + /// Operator greator + inline bool Key::operator > (const Key& other) const { + return this->key > other.key; + } + /// Particle definition for digitization /** Particle definition for digitization * @@ -146,8 +215,9 @@ namespace dd4hep { /// Disable copy assignment ParticleMapping& operator=(const ParticleMapping& copy) = default; - /// Merge new deposit map onto existing map + /// Merge new deposit map onto existing map (not thread safe!) std::size_t merge(ParticleMapping&& updates); + /// Add new entry to the particle mapping (not thread safe!) void push(Key::key_type key, Particle&& particle); }; @@ -223,7 +293,7 @@ namespace dd4hep { /// Disable copy assignment DepositMapping& operator=(const DepositMapping& copy) = default; - /// Merge new deposit map onto existing map + /// Merge new deposit map onto existing map (not thread safe!) std::size_t merge(DepositMapping&& updates); }; @@ -233,21 +303,113 @@ namespace dd4hep { { } - } // End namespace digi -} // End namespace dd4hep - + /// Data segment definition (locked map) + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DataSegment { + public: + using key_type = Key::key_type; + using container_map_t = std::map<key_type, std::any>; + using iterator = container_map_t::iterator; + using const_iterator = container_map_t::const_iterator; -/// <any> is not properly processed by cling. -/// We need to exclude any reference to it. -#if !defined(DD4HEP_INTERPRETER_MODE) -#include <DD4hep/Any.h> -#endif + private: + /// Call on failed any-casts + std::string invalid_cast(key_type key, const std::type_info& type) const; + /// Call on failed data requests during data requests + std::string invalid_request(key_type key) const; -/// Namespace for the AIDA detector description toolkit -namespace dd4hep { + /// Access data item by key + std::any* get_item(key_type key, bool exc); + /// Access data item by key (CONST) + const std::any* get_item(key_type key, bool exc) const; - /// Namespace for the Digitization part of the AIDA detector description toolkit - namespace digi { + public: + container_map_t data; + std::mutex& lock; + + public: + /// Initializing constructor + DataSegment(std::mutex& lock); + /// Default constructor + DataSegment() = delete; + /// Disable move constructor + DataSegment(DataSegment&& copy) = delete; + /// Disable copy constructor + DataSegment(const DataSegment& copy) = delete; + /// Default destructor + virtual ~DataSegment() = default; + /// Disable move assignment + DataSegment& operator=(DataSegment&& copy) = delete; + /// Disable copy assignment + DataSegment& operator=(const DataSegment& copy) = delete; + + /** Locked operations */ + /// Emplace data item (locked) + bool emplace(key_type key, std::any&& data); + /// Remove data item from segment (locked) + bool erase(key_type key); + /// Remove data items from segment (locked) + std::size_t erase(const std::vector<key_type>& keys); + + /** Unlocked operations */ + /// Access data as reference by key. If not existing, an exception is thrown + template<typename T> T& get(key_type key); + /// Access data as reference by key. If not existing, an exception is thrown + template<typename T> const T& get(key_type key) const; + + /// Access data as pointers by key. If not existing, nullptr is returned + template<typename T> T* pointer(key_type key); + /// Access data as pointers by key. If not existing, nullptr is returned + template<typename T> const T* pointer(key_type key) const; + + /// Access container size + std::size_t size() const { return this->data.size(); } + /// Check container if empty + bool empty() const { return this->data.empty(); } + /// Begin iteration + iterator begin() { return this->data.begin(); } + /// End iteration + iterator end() { return this->data.end(); } + /// Find entry by key + iterator find(key_type key) { return this->data.find(key); } + /// Begin iteration (CONST) + const_iterator begin() const { return this->data.begin(); } + /// End iteration (CONST) + const_iterator end() const { return this->data.end(); } + /// Find entry by key + const_iterator find(key_type key) const { return this->data.find(key); } + }; + + /// Access data as reference by key. If not existing, an exception is thrown + template<typename T> inline T& DataSegment::get(key_type key) { + if ( T* ptr = std::any_cast<T>(this->get_item(key, true)) ) + return *ptr; + throw std::runtime_error(this->invalid_cast(key, typeid(T))); + } + /// Access data as reference by key. If not existing, an exception is thrown + template<typename T> inline const T& DataSegment::get(key_type key) const { + if ( const T* ptr = std::any_cast<T>(this->get_item(key, true)) ) + return *ptr; + throw std::runtime_error(this->invalid_cast(key, typeid(T))); + } + + /// Access data as pointers by key. If not existing, nullptr is returned + template<typename T> inline T* DataSegment::pointer(key_type key) { + if ( T* ptr = std::any_cast<T>(this->get_item(key, false)) ) + return ptr; + return nullptr; + } + /// Access data as pointers by key. If not existing, nullptr is returned + template<typename T> inline const T* DataSegment::pointer(key_type key) const { + if ( const T* ptr = std::any_cast<T>(this->get_item(key, false)) ) + return ptr; + return nullptr; + } /// User event data for DDDigi /** @@ -256,26 +418,17 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiEvent : public ObjectExtensions { + class DigiEvent { private: std::mutex m_lock; std::string m_id; + DataSegment m_data { this->m_lock }; + DataSegment m_inputs { this->m_lock }; + DataSegment m_deposits { this->m_lock }; + public: - /// Forward definition of the key type - typedef Key::key_type key_type; - - int eventNumber = 0; -#if defined(DD4HEP_INTERPRETER_MODE) - std::map<key_type, long> data; - std::map<key_type, long> inputs; - std::map<key_type, long> deposits; -#else - typedef std::map<key_type, dd4hep::any> container_map_t; - protected: - container_map_t data; - container_map_t inputs; - container_map_t deposits; -#endif + int eventNumber { 0 }; + public: #if defined(DD4HEP_INTERPRETER_MODE) || defined(G__ROOT) /// Inhibit default constructor @@ -289,67 +442,10 @@ namespace dd4hep { DigiEvent(int num); /// Default destructor virtual ~DigiEvent(); - /// String identifier of this event const char* id() const { return this->m_id.c_str(); } - -#if !defined(DD4HEP_INTERPRETER_MODE) - /// Add item by key to the data segment - bool put_data(unsigned long key, std::any&& object); - - /// Add item by key to the input segment - bool put_input(unsigned long key, std::any&& object); - /// Retrieve data segment from the event structure - container_map_t& get_segment(const std::string& name); - - /// Add item by key to the data - template<typename T> bool put(const Key& key, T&& object) { - bool ret = this->inputs.emplace(key.toLong(),make_any<T>(object)).second; - if ( ret ) return ret; - except("DigiEvent","Invalid requested to store data in event container. Key:%ld",key.toLong()); - throw std::runtime_error("DigiEvent"); // Will never get here! - } - - /// Retrieve item by key from the event data container - template<typename T> T& get(const Key& key) { - auto iter = data.find(key.toLong()); - if ( iter != data.end() ) { - T* ptr = dd4hep::any_cast<T>(&(*iter).second); - if ( ptr ) return *ptr; - except("DigiEvent","Invalid data requested from event container [cast failed]. Key:%ld",key.toLong()); - } - except("DigiEvent","Invalid data requested from event container. Key:%ld",key.toLong()); - throw std::runtime_error("DigiEvent"); // Will never get here! - } - - /// Retrieve item by key from the event data container - template<typename T> const T& get(const Key& key) const { - std::map<key_type, dd4hep::any>::const_iterator iter = data.find(key.toLong()); - if ( iter != data.end() ) { - const T* ptr = dd4hep::any_cast<T>(&(*iter).second); - if ( ptr ) return *ptr; - except("DigiEvent","Invalid data requested from event container [cast failed]. Key:%ld",key.toLong()); - } - except("DigiEvent","Invalid data requested from event container. Key:%ld",key.toLong()); - throw std::runtime_error("DigiEvent"); // Will never get here! - } -#endif - /// Add an extension object to the detector element - void* addExtension(unsigned long long int k, ExtensionEntry* e) { - return ObjectExtensions::addExtension(k, e); - } - /// Add user extension object. Ownership is transferred and object deleted at the end of the event. - template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { - ExtensionEntry* e = take_ownership - ? (ExtensionEntry*)new detail::DeleteExtension<T,T>(ptr) - : (ExtensionEntry*)new detail::SimpleExtension<T,T>(ptr); - return (T*)ObjectExtensions::addExtension(detail::typeHash64<T>(),e); - } - /// Access to type safe extension object. Exception is thrown if the object is invalid - template <typename T> T* extension(bool alert=true) { - return (T*)ObjectExtensions::extension(detail::typeHash64<T>(),alert); - } + DataSegment& get_segment(const std::string& name); }; } // End namespace digi } // End namespace dd4hep diff --git a/DDDigi/include/DDDigi/DigiFactories.h b/DDDigi/include/DDDigi/DigiFactories.h index 8a28d2c175f18a801482a104cb75fdf11175bbbc..9116f745c653739e83f189eb77c3592927b4bcae 100644 --- a/DDDigi/include/DDDigi/DigiFactories.h +++ b/DDDigi/include/DDDigi/DigiFactories.h @@ -33,7 +33,10 @@ namespace dd4hep { /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { class DigiKernel; + class DigiAction; + class DigiInputAction; class DigiEventAction; + class DigiSegmentAction; class DigiCellScanner; class DigiSignalProcessor; } @@ -42,9 +45,15 @@ namespace dd4hep { namespace { namespace DS = dd4hep::digi; + /// Factory to create Digi action objects + DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::DigiAction*,const DS::DigiKernel*, std::string) + { return new P(*a0,a1); } /// Factory to create Digi action objects DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::DigiEventAction*,const DS::DigiKernel*, std::string) { return new P(*a0,a1); } + /// Factory to create Digi action objects + DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::DigiSegmentAction*,const DS::DigiKernel*, std::string) + { return new P(*a0,a1); } /// Factory to create Digi signal processor objects DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::DigiSignalProcessor*,const DS::DigiKernel*, std::string) { return new P(*a0,a1); } @@ -53,19 +62,33 @@ namespace { { return new P(dd4hep::Segmentation(a0)); } } +/// Plugin defintion to create DigiAction objects +#define DECLARE_DIGIACTION_NS(name_space,name) namespace {\ + using name_space::name; \ + DD4HEP_PLUGINSVC_FACTORY(name,name,dd4hep::digi::DigiAction*(const DS::DigiKernel*,std::string),__LINE__) } +/// Plugin defintion to create DigiAction objects +#define DECLARE_DIGIACTION(name) DECLARE_DIGIACTION_NS(dd4hep::digi,name) + /// Plugin defintion to create DigiAction objects #define DECLARE_DIGIEVENTACTION_NS(name_space,name) namespace {\ using name_space::name; \ DD4HEP_PLUGINSVC_FACTORY(name,name,dd4hep::digi::DigiEventAction*(const DS::DigiKernel*,std::string),__LINE__) } /// Plugin defintion to create DigiAction objects -#define DECLARE_DIGIEVENTACTION(name) DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,name) +#define DECLARE_DIGIEVENTACTION(name) DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,name) + +/// Plugin defintion to create DigiAction objects +#define DECLARE_DIGISEGMENTACTION_NS(name_space,name) namespace {\ + using name_space::name; \ + DD4HEP_PLUGINSVC_FACTORY(name,name,dd4hep::digi::DigiSegmentAction*(const DS::DigiKernel*,std::string),__LINE__) } +/// Plugin defintion to create DigiAction objects +#define DECLARE_DIGISEGMENTACTION(name) DECLARE_DIGISEGMENTACTION_NS(dd4hep::digi,name) #define DECLARE_DIGISIGNALPROCESSOR_NS(name_space,name) namespace { \ using name_space::name; \ DD4HEP_PLUGINSVC_FACTORY(name,name,dd4hep::digi::DigiSignalProcessor*(const DS::DigiKernel*,std::string),__LINE__) } /// Plugin defintion to create DigiSignalProcessor objects -#define DECLARE_DIGISIGNALPROCESSOR(name) DECLARE_DIGISIGNALPROCESSOR_NS(dd4hep::digi,name) +#define DECLARE_DIGISIGNALPROCESSOR(name) DECLARE_DIGISIGNALPROCESSOR_NS(dd4hep::digi,name) #define DECLARE_DIGICELLSCANNER_NS(name_space,typ,seg,sol) namespace { \ typedef name_space :: CellScanner<dd4hep:: seg , dd4hep:: sol > Scanner_##typ##_##seg##_##sol##_t; \ diff --git a/DDDigi/include/DDDigi/DigiGrammars.h b/DDDigi/include/DDDigi/DigiGrammars.h deleted file mode 100644 index 7d2ae834de1dfd18ef35d0db1c0a222a9857b8d2..0000000000000000000000000000000000000000 --- a/DDDigi/include/DDDigi/DigiGrammars.h +++ /dev/null @@ -1,25 +0,0 @@ -//========================================================================== -// 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 -// -//========================================================================== -#ifndef DDDIGI_DIGIGRAMMARS_H -#define DDDIGI_DIGIGRAMMARS_H - -/// Namespace for the AIDA detector description toolkit -namespace dd4hep { - - /// Namespace for the Digitization part of the AIDA detector description toolkit - namespace digi { - - - } // End namespace digi -} // End namespace dd4hep -#endif // DDDIGI_DIGIGRAMMARS_H diff --git a/DDDigi/include/DDDigi/DigiROOTInput.h b/DDDigi/include/DDDigi/DigiROOTInput.h index da30a24056ef59f53bd3d88274b5a73ac3ecb357..46d9425ffd7bd670bf6806422a1c06fe4a945026 100644 --- a/DDDigi/include/DDDigi/DigiROOTInput.h +++ b/DDDigi/include/DDDigi/DigiROOTInput.h @@ -48,10 +48,13 @@ namespace dd4hep { std::string m_tree_name { }; /// Property: Container names to be loaded std::vector<std::string> m_containers { }; + /// Property: Segment name to place input data default: inputs + std::string m_location { }; + /// Current input id mutable int m_curr_input { 0 }; /// Connection parameters to the "current" input source - mutable std::unique_ptr<internals_t> imp { }; + mutable std::unique_ptr<internals_t> imp { }; /// Open new input file void open_new_file() const; diff --git a/DDDigi/include/DDDigi/DigiSegmentation.h b/DDDigi/include/DDDigi/DigiSegmentation.h index 3507a2b9a7a8981e756b84c6d368aa61df3e5b48..2a31984dce4726c69dbe0078da8e4f1f469f3365 100644 --- a/DDDigi/include/DDDigi/DigiSegmentation.h +++ b/DDDigi/include/DDDigi/DigiSegmentation.h @@ -42,12 +42,15 @@ namespace dd4hep { */ class DigiCellData { public: +#if 0 PlacedVolume placement { }; Volume volume { }; Solid solid { }; CellID cell_id { 0 }; +#endif double signal { 0.0 }; mutable bool kill { false }; + /// Default constructor DigiCellData() = default; /// Default move constructor diff --git a/DDDigi/include/DDDigi/DigiSegmentationSplitter.h b/DDDigi/include/DDDigi/DigiSegmentationSplitter.h index fac34979d1f14c533f1f546a84938a6e6fdd106a..163380384c68adc8ee1b4de55006846c47be0114 100644 --- a/DDDigi/include/DDDigi/DigiSegmentationSplitter.h +++ b/DDDigi/include/DDDigi/DigiSegmentationSplitter.h @@ -14,14 +14,52 @@ #define DDDIGI_DIGISEGMENTATIONSPLITTER_H // Framework include files -#include <DDDigi/DigiEventAction.h> +#include <DDDigi/DigiActionSequence.h> +#include <DDDigi/DigiData.h> /// Namespace for the AIDA detector description toolkit namespace dd4hep { + /// DDSegmentation namespace declaration + namespace DDSegmentation { + class BitFieldElement; + } + /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { + class DigiSegmentContext; + class DigiSegmentAction; + class DigiSegmentationSplitter; + + class DigiSegmentContext { + public: + DetElement detector { }; + IDDescriptor idspec { }; + const BitFieldElement* field { nullptr }; + uint64_t cell_mask { ~0x0UL }; + uint64_t det_mask { 0UL }; + uint64_t split_mask { 0UL }; + int32_t offset { 0 }; + int32_t width { 0 }; + int32_t max_split { 0 }; + uint32_t id { 0 }; + + public: + uint32_t split_id(uint64_t cell_id) const { + return int( (cell_id & this->split_mask) >> this->offset ); + } + uint64_t cell_id(uint64_t cell_id) const { + return (cell_id & this->cell_mask) >> this->offset; + } + const std::string& name() const { + return this->field->name(); + } + const char* cname() const { + return this->field->name().c_str(); + } + }; + /// Default base class for all Digitizer actions and derivates thereof. /** * This is a utility class supporting properties, output and access to @@ -31,14 +69,53 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_SIMULATION */ - class DigiSegmentationSplitter : public DigiEventAction { - protected: + class DigiSegmentAction : public DigiEventAction { + private: + friend class DigiSegmentationSplitter; + /// Implementation declaration class internals_t; + /// Reference to the implementation + std::unique_ptr<internals_t> internals; + + /// Main functional callback + virtual void execute(DigiContext& context) const final; + + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSegmentAction); + + public: + /// Standard constructor + DigiSegmentAction(const DigiKernel& kernel, const std::string& name); + + /// Default destructor + virtual ~DigiSegmentAction(); + /// Main functional callback + std::map<Key::key_type, std::any> + handleSegment(DigiContext& context, + const DigiSegmentContext& segment, + const DepositMapping& deposits) const; + }; + + /// Default base class for all Digitizer actions and derivates thereof. + /** + * This is a utility class supporting properties, output and access to + * event and run objects through the context. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class DigiSegmentationSplitter : public DigiActionSequence { + protected: + /// Implementation declaration + class internals_t; /// Reference to the implementation std::unique_ptr<internals_t> internals; + public: + protected: /// Define standard assignments and constructors DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSegmentationSplitter); @@ -47,7 +124,9 @@ namespace dd4hep { virtual ~DigiSegmentationSplitter(); /// Split actions according to the segmentation - void split_segments(DigiEvent& event, DigiEvent::container_map_t& data) const; + //void split_segments(DigiEvent& event, DataSegment& data) const; + + void init_processors(); public: /// Standard constructor diff --git a/DDDigi/include/DDDigi/DigiStore.h b/DDDigi/include/DDDigi/DigiStore.h deleted file mode 100644 index d34b8028e2b3cbd2dd2511d6a50164ef7278fffb..0000000000000000000000000000000000000000 --- a/DDDigi/include/DDDigi/DigiStore.h +++ /dev/null @@ -1,141 +0,0 @@ -//========================================================================== -// 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 -// -//========================================================================== -#ifndef DDDIGI_DIGISTORE_H -#define DDDIGI_DIGISTORE_H - -// Framework incloude files -#include <DDDigi/DigiAction.h> -#include <DDDigi/DigiData.h> - -#include <mutex> - -/// Namespace for the AIDA detector description toolkit -namespace dd4hep { - - // Forward declarations - - /// Namespace for the Digitization part of the AIDA detector description toolkit - namespace digi { - - /// - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_DIGITIZATION - */ - class DigiInputs { - public: - friend class DigiStore; - - /// Forward definition of the key type - typedef Key::key_type key_type; - - protected: -#if defined(DD4HEP_INTERPRETER_MODE) - std::map<key_type, long> data; -#else - std::map<key_type, dd4hep::any> data; -#endif - public: - /// Define standard assignments and constructors - DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiInputs); - -#if !defined(DD4HEP_INTERPRETER_MODE) - /// Retrieve item by key from the data container - template <typename T> const T& get(const Key& key) const { - auto iter = data.find(key.toLong()); - if ( iter != data.end() ) { - T* ptr = dd4hep::any_cast<T>(&(*iter).second); - if ( ptr ) return *ptr; - except("DigiEvent","Invalid data requested from store [cast failed]. Key:%ld",key.toLong()); - } - except("DigiEvent","Invalid data requested from store. Key:%ld",key.toLong()); - throw std::runtime_error("DigiEvent"); // Will never get here! - } -#endif - }; - - /// - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_DIGITIZATION - */ - class DigiOutputs { - public: - friend class DigiStore; - - /// Forward definition of the key type - typedef Key::key_type key_type; - - protected: -#if defined(DD4HEP_INTERPRETER_MODE) - std::map<key_type, long> data; -#else - std::map<key_type, dd4hep::any> data; -#endif - std::mutex lock; - public: - /// Define standard assignments and constructors - DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiOutputs); - -#if !defined(DD4HEP_INTERPRETER_MODE) - /// Add item by key to the data - template<typename T> bool put(const Key& key, T&& object) { - std::lock_guard<std::mutex> guard(lock); - bool ret = data.emplace(key.toLong(),make_any<T>(object)).second; - if ( ret ) return ret; - except("DigiEvent","Invalid request to store data in store. Key:%ld",key.toLong()); - return false; - } -#endif - }; - - /// - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_DIGITIZATION - */ - class DigiStore { - public: - /// Forward definition of the key type - typedef Key::key_type key_type; - - /// Container of input data - DigiInputs inputs; - /// Container of output data - DigiOutputs outputs; - - protected: - /// Define standard assignments and constructors - DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiStore); - - public: - /// Standard constructor - DigiStore(const DigiKernel& kernel, const std::string& nam); - /// Default destructor - virtual ~DigiStore(); - /// Add a set of input data to the store - void add_inputs(const std::map<key_type,dd4hep::any>& items); - /// Move produced results out of the store - std::map<key_type,dd4hep::any> move_outputs(); - }; - - } // End namespace digi -} // End namespace dd4hep - -#endif // DDDIGI_DIGISTORE_H diff --git a/DDDigi/include/DDDigi/DigiExponentialNoise.h b/DDDigi/include/DDDigi/noise/DigiExponentialNoise.h similarity index 100% rename from DDDigi/include/DDDigi/DigiExponentialNoise.h rename to DDDigi/include/DDDigi/noise/DigiExponentialNoise.h diff --git a/DDDigi/include/DDDigi/DigiGaussianNoise.h b/DDDigi/include/DDDigi/noise/DigiGaussianNoise.h similarity index 100% rename from DDDigi/include/DDDigi/DigiGaussianNoise.h rename to DDDigi/include/DDDigi/noise/DigiGaussianNoise.h diff --git a/DDDigi/include/DDDigi/DigiLandauNoise.h b/DDDigi/include/DDDigi/noise/DigiLandauNoise.h similarity index 100% rename from DDDigi/include/DDDigi/DigiLandauNoise.h rename to DDDigi/include/DDDigi/noise/DigiLandauNoise.h diff --git a/DDDigi/include/DDDigi/DigiPoissonNoise.h b/DDDigi/include/DDDigi/noise/DigiPoissonNoise.h similarity index 100% rename from DDDigi/include/DDDigi/DigiPoissonNoise.h rename to DDDigi/include/DDDigi/noise/DigiPoissonNoise.h diff --git a/DDDigi/include/DDDigi/DigiRandomNoise.h b/DDDigi/include/DDDigi/noise/DigiRandomNoise.h similarity index 100% rename from DDDigi/include/DDDigi/DigiRandomNoise.h rename to DDDigi/include/DDDigi/noise/DigiRandomNoise.h diff --git a/DDDigi/include/DDDigi/DigiSignalProcessorSequence.h b/DDDigi/include/DDDigi/noise/DigiSignalProcessorSequence.h similarity index 100% rename from DDDigi/include/DDDigi/DigiSignalProcessorSequence.h rename to DDDigi/include/DDDigi/noise/DigiSignalProcessorSequence.h diff --git a/DDDigi/include/DDDigi/DigiSubdetectorSequence.h b/DDDigi/include/DDDigi/noise/DigiSubdetectorSequence.h similarity index 100% rename from DDDigi/include/DDDigi/DigiSubdetectorSequence.h rename to DDDigi/include/DDDigi/noise/DigiSubdetectorSequence.h diff --git a/DDDigi/include/DDDigi/DigiUniformNoise.h b/DDDigi/include/DDDigi/noise/DigiUniformNoise.h similarity index 100% rename from DDDigi/include/DDDigi/DigiUniformNoise.h rename to DDDigi/include/DDDigi/noise/DigiUniformNoise.h diff --git a/DDDigi/include/DDDigi/FalphaNoise.h b/DDDigi/include/DDDigi/noise/FalphaNoise.h similarity index 100% rename from DDDigi/include/DDDigi/FalphaNoise.h rename to DDDigi/include/DDDigi/noise/FalphaNoise.h diff --git a/DDDigi/plugins/CellScanner_CartesianGridXY.cpp b/DDDigi/plugins/CellScanner_CartesianGridXY.cpp index a940257667ad3e52949c3321e9c119ec258ed159..cb13d8ccf3032329c514046fe81e2bb67333feca 100644 --- a/DDDigi/plugins/CellScanner_CartesianGridXY.cpp +++ b/DDDigi/plugins/CellScanner_CartesianGridXY.cpp @@ -17,7 +17,7 @@ #include <DDDigi/segmentations/CartesianGridXY.h> #include <DDDigi/segmentations/SegmentationScanner.h> - +#if 0 /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -178,3 +178,5 @@ namespace dd4hep { DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Intersection) DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Subtraction) DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Union) + +#endif diff --git a/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp b/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp index 8e81820830dddd7cbc51a7c0df66e5adaf8ca00e..d73af620179e6ccf0db951094639cc1fbbcb5b63 100644 --- a/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp +++ b/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp @@ -16,6 +16,8 @@ #include <DDDigi/segmentations/CartesianGridXYZ.h> #include <DDDigi/segmentations/SegmentationScanner.h> + +#if 0 /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -125,4 +127,5 @@ namespace dd4hep { DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Intersection) DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Subtraction) DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Union) +#endif diff --git a/DDDigi/plugins/Components.cpp b/DDDigi/plugins/Components.cpp index 92d97d7a24541600dcf39f65466a57250f99e3d2..c277b79c0c7bd3df6038ca5dd872c110df3d99ed 100644 --- a/DDDigi/plugins/Components.cpp +++ b/DDDigi/plugins/Components.cpp @@ -35,14 +35,14 @@ DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiActionSequence) DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiParallelActionSequence) DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiSequentialActionSequence) -#include <DDDigi/DigiSubdetectorSequence.h> -DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiSubdetectorSequence) +//#include <DDDigi/DigiSubdetectorSequence.h> +// DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiSubdetectorSequence) #include <DDDigi/DigiLockedAction.h> DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiLockedAction) -#include <DDDigi/DigiSignalProcessorSequence.h> -DECLARE_DIGISIGNALPROCESSOR_NS(dd4hep::digi,DigiSignalProcessorSequence) +//#include <DDDigi/DigiSignalProcessorSequence.h> +// DECLARE_DIGISIGNALPROCESSOR_NS(dd4hep::digi,DigiSignalProcessorSequence) #include <DDDigi/DigiStoreDump.h> DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiStoreDump) @@ -54,25 +54,11 @@ DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiHitAttenuatorExp) DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiContainerCombine) #include <DDDigi/DigiSegmentationSplitter.h> +DECLARE_DIGISEGMENTACTION_NS(dd4hep::digi,DigiSegmentAction) DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiSegmentationSplitter) - - -using namespace std; -using namespace dd4hep; -using namespace dd4hep::detail; - - - /// Basic entry point -/** - * Factory: DD4hep_GeometryDisplay - * - * \author M.Frank - * \version 1.0 - * \date 01/04/2014 - */ -static long dummy(Detector&, int, char**) { +static long dummy(dd4hep::Detector&, int, char**) { return 0; } DECLARE_APPLY(DDDigi_dummy,dummy) diff --git a/DDDigi/python/dddigi.py b/DDDigi/python/dddigi.py index 0702a86db43c938e45798702b52d5eaaf604d724..53b97320a26a3f2a196b3f6ad74ea962e845a3fe 100644 --- a/DDDigi/python/dddigi.py +++ b/DDDigi/python/dddigi.py @@ -35,15 +35,20 @@ def loadDDDigi(): import platform if platform.system() == "Darwin": gSystem.SetDynamicPath(os.environ['DD4HEP_LIBRARY_PATH']) - + # + # load with ROOT the DDDigi plugin library, which in turn loads the DDigi module result = gSystem.Load("libDDDigiPlugins") if result < 0: raise Exception('DDDigi.py: Failed to load the DDDigi library libDDDigiPlugins: ' + gSystem.GetErrorStr()) logger.info('DDDigi.py: Successfully loaded DDDigi plugin library libDDDigiPlugins!') + # + # import with ROOT the I/O module to read DDG4 output result = gSystem.Load("libDDDigi_DDG4_IO") if result < 0: raise Exception('DDDigi.py: Failed to load the DDG4 IO library libDDDigi_DDG4_IO: ' + gSystem.GetErrorStr()) logger.info('DDDigi.py: Successfully loaded DDG4 IO plugin library libDDDigi_DDG4_IO!') + # + # import the main dd4hep module from ROOT from ROOT import dd4hep as module return module @@ -62,10 +67,10 @@ def _import_class(ns, nam): try: dd4hep = loadDDDigi() except Exception as X: - logger.error('+--%-100s--+', 100 * '-') - logger.error('| %-100s |', 'Failed to load DDDigi library:') - logger.error('| %-100s |', str(X)) - logger.error('+--%-100s--+', 100 * '-') + logger.error('+--%-100s--+' % (100 * '-',)) + logger.error('| %-100s |' % ('Failed to load DDDigi library:',)) + logger.error('| %-100s |' % (str(X),)) + logger.error('+--%-100s--+' % (100 * '-',)) exit(1) core = dd4hep @@ -107,15 +112,15 @@ def importConstants(description, namespace=None, debug=False): while len(todo) and cnt < 100: cnt = cnt + 1 if cnt == 100: - logger.info('%s %d out of %d %s "%s": [%s]\n+++ %s', - '+++ FAILED to import', - len(todo), len(todo) + num, - 'global values into namespace', - ns.__name__, 'Try to continue anyway', 100 * '=') + logger.info('%s %d out of %d %s "%s": [%s]\n+++ %s' % + ('+++ FAILED to import', + len(todo), len(todo) + num, + 'global values into namespace', + ns.__name__, 'Try to continue anyway', 100 * '=',)) for k, v in todo.items(): if not hasattr(ns, k): logger.info('+++ FAILED to import: "' + k + '" = "' + str(v) + '"') - logger.info('+++ %s', 100 * '=') + logger.info('+++ %s' % (100 * '=',)) for k, v in todo.items(): if not hasattr(ns, k): @@ -129,7 +134,7 @@ def importConstants(description, namespace=None, debug=False): del todo[k] num = num + 1 if cnt < 100: - logger.info('+++ Imported %d global values to namespace:%s', num, ns.__name__,) + logger.info('+++ Imported %d global values to namespace:%s' % (num, ns.__name__),) # --------------------------------------------------------------------------- diff --git a/DDDigi/src/DigiContainerCombine.cpp b/DDDigi/src/DigiContainerCombine.cpp index 28d08d3b36598daace391922a07a1b5de3df713c..5871265c12f383075589aa8dcc6cd505126bb930 100644 --- a/DDDigi/src/DigiContainerCombine.cpp +++ b/DDDigi/src/DigiContainerCombine.cpp @@ -18,6 +18,9 @@ #include <DDDigi/DigiContext.h> #include <DDDigi/DigiContainerCombine.h> +/// C/C++ include files +#include <set> + using dd4hep::digi::DigiContainerCombine; class DigiContainerCombine::internals_t { @@ -103,8 +106,8 @@ dd4hep::digi::DigiContainerCombine::~DigiContainerCombine() { /// Combine selected containers to one single deposit container template <typename PREDICATE> std::size_t dd4hep::digi::DigiContainerCombine::combine_containers(DigiEvent& event, - DigiEvent::container_map_t& inputs, - DigiEvent::container_map_t& outputs, + DataSegment& inputs, + DataSegment& outputs, const PREDICATE& predicate) const { std::size_t cnt_depos = 0; @@ -171,12 +174,7 @@ dd4hep::digi::DigiContainerCombine::combine_containers(DigiEvent& event, } } if ( this->internals->erase_combined ) { - for(auto key : to_erase) { - auto iter = inputs.find(key); - if ( iter != inputs.end() ) { - inputs.erase(iter); - } - } + inputs.erase(to_erase); } this->info("%s+++ Merged %ld particles and %ld deposits from %ld containers", event.id(), cnt_parts, cnt_depos, cnt_conts); diff --git a/DDDigi/src/DigiData.cpp b/DDDigi/src/DigiData.cpp index bf569485255da9d9836ac9094d0bacaf9925efd5..e9ad1a36713291c3090c2564dd8385b704a4a02e 100644 --- a/DDDigi/src/DigiData.cpp +++ b/DDDigi/src/DigiData.cpp @@ -32,33 +32,9 @@ namespace { } } -dd4hep::digi::Key::Key() { - this->key = 0; -} - -dd4hep::digi::Key::Key(const Key& copy) { - this->key = copy.key; -} - -dd4hep::digi::Key::Key(key_type full_mask) { - this->key = full_mask; -} - -dd4hep::digi::Key::Key(mask_type mask, const std::string& item) { - auto& _k = keys(); - this->key = 0; - this->values.mask = mask; - this->values.item = detail::hash32(item); - std::lock_guard<std::mutex> lock(_k.lock); - _k.map[key] = item; -} - -dd4hep::digi::Key& dd4hep::digi::Key::operator=(const Key& copy) { - this->key = copy.key; - return *this; -} +using namespace dd4hep::digi; -void dd4hep::digi::Key::set(const std::string& name, int mask) { +void Key::set(const std::string& name, int mask) { auto& _k = keys(); if ( name.empty() ) { std::lock_guard<std::mutex> lock(_k.lock); @@ -71,7 +47,7 @@ void dd4hep::digi::Key::set(const std::string& name, int mask) { } /// Access key name (if registered properly) -std::string dd4hep::digi::Key::key_name(const Key& k) { +std::string Key::key_name(const Key& k) { auto& _k = keys(); std::lock_guard<std::mutex> lock(_k.lock); std::map<unsigned long, std::string>::const_iterator it = _k.map.find(k.key); @@ -86,7 +62,7 @@ std::string dd4hep::digi::Key::key_name(const Key& k) { } /// Merge new deposit map onto existing map -std::size_t dd4hep::digi::DepositMapping::merge(DepositMapping&& updates) { +std::size_t DepositMapping::merge(DepositMapping&& updates) { std::size_t update_size = updates.size(); for( auto& c : updates ) { CellID cell = c.first; @@ -104,7 +80,7 @@ std::size_t dd4hep::digi::DepositMapping::merge(DepositMapping&& updates) { } /// Merge new deposit map onto existing map -std::size_t dd4hep::digi::ParticleMapping::merge(ParticleMapping&& updates) { +std::size_t ParticleMapping::merge(ParticleMapping&& updates) { std::size_t update_size = updates.size(); for( ParticleMapping::value_type& c : updates ) { Particle part(std::move(c.second)); @@ -113,10 +89,11 @@ std::size_t dd4hep::digi::ParticleMapping::merge(ParticleMapping&& updates) { return update_size; } -void dd4hep::digi::ParticleMapping::push(Key::key_type k, Particle&& part) { +void ParticleMapping::push(Key::key_type k, Particle&& part) { #if defined(__GNUC__) && (__GNUC__ < 10) /// Lower compiler version have a bad implementation of std::any bool ret = false; + if ( part.history.has_value() ) {} #else bool ret = this->emplace(k, std::move(part)).second; #endif @@ -127,16 +104,89 @@ void dd4hep::digi::ParticleMapping::push(Key::key_type k, Particle&& part) { } } +/// Initializing constructor +DataSegment::DataSegment(std::mutex& l) : lock(l) +{ +} + +/// Remove data item from segment +bool DataSegment::emplace(key_type key, std::any&& item) { + std::lock_guard<std::mutex> l(lock); +#if defined(__GNUC__) && (__GNUC__ < 10) + /// Lower compiler version have a bad implementation of std::any + bool ret = false; + if ( item.has_value() ) {} +#else + bool ret = data.emplace(key, std::move(item)).second; +#endif + if ( !ret ) { + Key k(key); + except("DataSegment","Error in DataSegment map. Duplicate ID: mask:%04X Number:%d", + k.values.mask, k.values.item); + } + return ret; +} + +/// Remove data item from segment +bool DataSegment::erase(key_type key) { + std::lock_guard<std::mutex> l(lock); + auto iter = data.find(key); + if ( iter != data.end() ) { + data.erase(iter); + return true; + } + return false; +} + +/// Remove data items from segment (locked) +std::size_t DataSegment::erase(const std::vector<key_type>& keys) { + std::size_t count = 0; + std::lock_guard<std::mutex> l(lock); + for(auto key : keys) { + auto iter = data.find(key); + if ( iter != data.end() ) { + data.erase(iter); + ++count; + } + } + return count; +} + +/// Call on failed any-casts during data requests +std::string DataSegment::invalid_cast(key_type key, const std::type_info& type) const { + return dd4hep::format(0, "Invalid segment data cast. Key:%ld type:%s", + key, typeName(type).c_str()); +} + +/// Call on failed data requests during data requests +std::string DataSegment::invalid_request(key_type key) const { + return dd4hep::format(0, "Invalid segment data requested. Key:%ld",key); +} + +/// Access data item by key +std::any* DataSegment::get_item(key_type key, bool exc) { + auto it = this->data.find(key); + if (it != this->data.end()) return &it->second; + if ( exc ) throw std::runtime_error(invalid_request(key)); + return nullptr; +} + +/// Access data item by key (CONST) +const std::any* DataSegment::get_item(key_type key, bool exc) const { + auto it = this->data.find(key); + if (it != this->data.end()) return &it->second; + if ( exc ) throw std::runtime_error(invalid_request(key)); + return nullptr; +} + /// Intializing constructor -dd4hep::digi::DigiEvent::DigiEvent() - : ObjectExtensions(typeid(DigiEvent)) +DigiEvent::DigiEvent() { InstanceCount::increment(this); } /// Intializing constructor -dd4hep::digi::DigiEvent::DigiEvent(int ev_num) - : ObjectExtensions(typeid(DigiEvent)), eventNumber(ev_num) +DigiEvent::DigiEvent(int ev_num) : eventNumber(ev_num) { char text[32]; ::snprintf(text, sizeof(text), "Ev:%06d ", ev_num); @@ -145,56 +195,26 @@ dd4hep::digi::DigiEvent::DigiEvent(int ev_num) } /// Default destructor -dd4hep::digi::DigiEvent::~DigiEvent() +DigiEvent::~DigiEvent() { InstanceCount::decrement(this); } /// Retrieve data segment from the event structure -dd4hep::digi::DigiEvent::container_map_t& -dd4hep::digi::DigiEvent::get_segment(const std::string& name) { +DataSegment& DigiEvent::get_segment(const std::string& name) { switch(::toupper(name[0])) { case 'I': - return this->inputs; + return this->m_inputs; case 'D': switch(::toupper(name[1])) { case 'E': - return this->deposits; + return this->m_deposits; default: - return this->data; + return this->m_data; } break; - case 'O': - return this->data; default: - return this->data; + break; } throw std::runtime_error("Invalid segment name: "+name); } - -/// Add item by key to the data -bool dd4hep::digi::DigiEvent::put_data(unsigned long key, std::any&& object) { - std::lock_guard<std::mutex> lock(m_lock); - bool ret = data.emplace(key,object).second; - if ( ret ) return ret; - - std::string name = Key::key_name(key); - uint32_t mask = Key::mask(key); - except("DigiEvent","%s+++ Invalid requested to store object in data container [key present]." - " Key:%ld [Mask:%04X, name:%s]", this->id(), key, mask, name.c_str()); - throw std::runtime_error("DigiEvent"); // Will never get here! -} - -/// Add item by key to the data -bool dd4hep::digi::DigiEvent::put_input(unsigned long key, std::any&& object) { - std::lock_guard<std::mutex> lock(m_lock); - bool ret = inputs.emplace(key,object).second; - if ( ret ) return ret; - - std::string name = Key::key_name(key); - uint32_t mask = Key::mask(key); - except("DigiEvent","%s+++ Invalid requested to store object in input container [key present]." - " Key:%ld [Mask:%04X, name:%s]", this->id(), key, mask, name.c_str()); - throw std::runtime_error("DigiEvent"); // Will never get here! -} - diff --git a/DDDigi/src/DigiHitAttenuatorExp.cpp b/DDDigi/src/DigiHitAttenuatorExp.cpp index 1adda1b2064967495a69fe0ab909d161d1e4cd5d..fb883f524d9eaf7a6d42952d5d845c464668e874 100644 --- a/DDDigi/src/DigiHitAttenuatorExp.cpp +++ b/DDDigi/src/DigiHitAttenuatorExp.cpp @@ -18,6 +18,11 @@ #include <DDDigi/DigiContext.h> #include <DDDigi/DigiHitAttenuatorExp.h> +/// C/C++ include files +#include <cmath> + + + class dd4hep::digi::DigiHitAttenuatorExp::internals_t { public: /// Property: Input data segment name @@ -70,27 +75,22 @@ dd4hep::digi::DigiHitAttenuatorExp::~DigiHitAttenuatorExp() { void dd4hep::digi::DigiHitAttenuatorExp::execute(DigiContext& context) const { internals->initialize(context); std::size_t count = 0; - auto& event = context.event; - auto& inputs = event->get_segment(internals->input); + auto& event = *context.event; + auto& inputs = event.get_segment(internals->input); for ( const auto& k : internals->attenuation ) { - auto iter = inputs.find(k.first); - if ( iter != inputs.end() ) { - std::any& obj = (*iter).second; - DepositMapping* m = std::any_cast<DepositMapping>(&obj); + DepositMapping* m = inputs.pointer<DepositMapping>(k.first); + if ( m ) { double factor = k.second; - if ( m ) { - for( auto& c : *m ) { - c.second.deposit *= factor; - } - count += m->size(); - std::string nam = Key::key_name(k.first)+":"; - debug("%s+++ %-32s Mask: %06X Attenuated exponentially %6ld hits by %8.5f", - event->id(), nam.c_str(), m->mask, m->size(), factor); - continue; + for( auto& c : *m ) { + c.second.deposit *= factor; } - error("Invalid data type in container"); + count += m->size(); + std::string nam = Key::key_name(k.first)+":"; + debug("%s+++ %-32s Mask: %06X Attenuated exponentially %6ld hits by %8.5f", + event.id(), nam.c_str(), m->mask, m->size(), factor); + continue; } } - info("%s+++ Attenuated exponentially %6ld hits", event->id(), count); + info("%s+++ Attenuated exponentially %6ld hits", event.id(), count); } diff --git a/DDDigi/src/DigiROOTInput.cpp b/DDDigi/src/DigiROOTInput.cpp index 670bce10118903e3174019f3b589d7166764d751..18a1bea03a87edb7b96a07d0b0ffe64934ee38c9 100644 --- a/DDDigi/src/DigiROOTInput.cpp +++ b/DDDigi/src/DigiROOTInput.cpp @@ -89,6 +89,7 @@ DigiROOTInput::DigiROOTInput(const DigiKernel& kernel, const std::string& nam) : DigiInputAction(kernel, nam) { declareProperty("tree", m_tree_name = "EVENT"); + declareProperty("location", m_location = "inputs"); declareProperty("containers", m_containers); InstanceCount::increment(this); } @@ -189,6 +190,7 @@ void DigiROOTInput::execute(DigiContext& context) const { void* obj = br.second.cls->New(); br.second.branch->SetAddress(&obj); } + DataSegment& segment = event->get_segment(this->m_location); for( const auto& br : imp->branches ) { TBranch* b = br.second.branch; int nb = b->GetEntry( imp->entry ); @@ -200,7 +202,7 @@ void DigiROOTInput::execute(DigiContext& context) const { const auto& func = *br.second.call; void** addr = (void**)b->GetAddress(); auto data = func(this->m_mask, b->GetName(), *addr); - event->put_input(br.first, std::move(data)); + segment.emplace(br.first, std::move(data)); } info("%s+++ Read event %6ld [%ld bytes] from tree %s file: %s", event->id(), imp->entry, input_len, imp->tree->GetName(), imp->file->GetName()); diff --git a/DDDigi/src/DigiSegmentationSplitter.cpp b/DDDigi/src/DigiSegmentationSplitter.cpp index e43e6fc2b34765c1824d0ce1f5406019b6fe29fa..560d18f650b77559f0c14d89884f0d67fc7af0d4 100644 --- a/DDDigi/src/DigiSegmentationSplitter.cpp +++ b/DDDigi/src/DigiSegmentationSplitter.cpp @@ -12,6 +12,7 @@ //========================================================================== // Framework include files +#include <DD4hep/Plugins.h> #include <DD4hep/Detector.h> #include <DD4hep/InstanceCount.h> @@ -20,7 +21,15 @@ #include <DDDigi/DigiContext.h> #include <DDDigi/DigiSegmentationSplitter.h> -using dd4hep::digi::DigiSegmentationSplitter; +#include <sstream> + +using namespace dd4hep::digi; + +class DigiSegmentAction::internals_t { +public: + const DigiSegmentContext* split { nullptr }; + const DepositMapping* input { nullptr }; +}; class DigiSegmentationSplitter::internals_t { public: @@ -28,8 +37,18 @@ public: std::string input_id; /// Property: Subdetector to handle std::string detector_name; - /// Property: Input masks in the repository - std::vector<int> masks; + /// Property: Factory name of the processor type + std::string split_by; + /// Property: Split element of the ID descriptor + std::string processor_type; + /// Property: Flag if processors should be shared + bool share_processor { true }; + /// Property: Input mask in the repository + int input_mask; + + std::vector<Key::key_type> data_keys; + + DigiSegmentContext splitter; const DigiKernel& kernel; Detector& description; @@ -38,13 +57,103 @@ public: IDDescriptor iddescriptor; DigiSegmentationSplitter* split { nullptr }; + std::map<uint64_t, DigiSegmentContext> split_processors; + /// Flag to check the initialization bool inited { false }; internals_t(const DigiKernel& krnl, DigiSegmentationSplitter* s) : kernel(krnl), description(kernel.detectorDescription()), split(s) { + } + void scan_detector(DetElement de, VolumeID vid, VolumeID mask) { + const auto& new_ids = de.placement().volIDs(); + VolumeID new_vid = vid; + VolumeID new_msk = mask; + if ( !new_ids.empty() ) { + new_vid |= this->iddescriptor.encode(new_ids); + new_msk |= this->iddescriptor.get_mask(new_ids); + for (const auto& id : new_ids) { + if ( id.first == this->split_by ) { + DigiSegmentContext context = this->splitter; + context.detector = de; + context.id = id.second; + this->split_processors.emplace(new_vid, std::move(context)); + return; + } + } + } + for ( const auto& c : de.children() ) + scan_detector(c.second, new_vid, new_msk); + } + + void init_basics() { + const char* det = this->detector_name.c_str(); + this->detector = this->description.detector(det); + if ( !this->detector.isValid() ) { + split->except("FAILED: Cannot access subdetector %s from the detector description.", det); + } + this->sensitive = this->description.sensitiveDetector(det); + if ( !sensitive.isValid() ) { + split->except("FAILED: Cannot access sensitive detector for %s.", det); + } + this->iddescriptor = this->sensitive.idSpec(); + if ( !this->iddescriptor.isValid() ) { + split->except("FAILED: Cannot access ID descriptor for detector %s.", det); + } + Readout rd = this->sensitive.readout(); + auto colls = rd.collectionNames(); + if ( colls.empty() ) colls.emplace_back(rd.name()); + for( const auto& c : colls ) { + this->data_keys.emplace_back(Key(this->input_mask, c).key); + } + } + + void init_splitting() { + const char* det = this->detector_name.c_str(); + /// Setup the splitter + this->splitter.cell_mask = ~0x0UL; + this->splitter.detector = this->detector; + this->splitter.idspec = this->iddescriptor; + for(const auto& f : this->iddescriptor.fields()) { + const BitFieldElement* e = f.second; + if ( e->name() == this->split_by ) { + this->splitter.field = e; + this->splitter.split_mask = e->mask(); + this->splitter.width = e->width(); + this->splitter.offset = e->offset(); + this->splitter.max_split = 1 << e->width(); + } + else { + this->splitter.det_mask |= e->mask(); + } + this->splitter.cell_mask = (splitter.cell_mask << e->width()); + split->info("%-24s %-8s [%3d,%7d] width:%2d offset:%2d mask:%016lX Split:%016lX Det:%016lX Cells:%016lX", + iddescriptor.name(), e->name().c_str(), + e->minValue(), e->maxValue(), e->width(), e->offset(), + e->mask(), this->splitter.split_mask, this->splitter.det_mask, this->splitter.cell_mask); + if ( this->splitter.field ) break; + } + if ( !this->splitter.field ) { + split->except("FAILED: The ID descriptor for detector %s has no field %s.", + det, split_by.c_str()); + } + this->split_processors.clear(); + const auto& ids = this->detector.placement().volIDs(); + VolumeID vid = this->iddescriptor.encode(ids); + VolumeID msk = this->iddescriptor.get_mask(ids); + this->scan_detector(this->detector, vid, msk); + split->info("%-24s has %ld parallel entries in when splitting by \"%s\"", + det, this->split_processors.size(), this->split_by.c_str()); + std::stringstream str; + for( auto id : this->split_processors ) + str << std::setw(16) << std::hex << std::setfill('0') << id.first << " "; + split->info("%-24s --> Parallel Vid: %s", det, str.str().c_str()); + str.str(""); + for( auto id : this->split_processors ) + str << std::setw(16) << std::dec << std::setfill(' ') << this->splitter.split_id(id.first) << " "; + split->info("%-24s --> Parallel ID: %s", det, str.str().c_str()); } /// Initializing function: compute values which depend on properties @@ -52,50 +161,111 @@ public: if ( !this->inited ) { std::lock_guard<std::mutex> lock(context.initializer_lock()); if ( !this->inited ) { + const std::string det = this->detector_name; this->inited = true; - detector = description.detector(detector_name); - if ( !detector.isValid() ) { - split->except("FAILED: Cannot access subdetector %s from the detector description.", detector_name.c_str()); - } - sensitive = description.sensitiveDetector(detector_name); - if ( !sensitive.isValid() ) { - split->except("FAILED: Cannot access sensitive detector for %s.", detector_name.c_str()); - } - iddescriptor = sensitive.idSpec(); - if ( !iddescriptor.isValid() ) { - split->except("FAILED: Cannot access ID descriptor for detector %s.", detector_name.c_str()); - } + this->init_basics(); + this->init_splitting(); + this->split->init_processors(); + split->info("+++ Detector splitter is now fully initialized!"); } } } }; /// Standard constructor -dd4hep::digi::DigiSegmentationSplitter::DigiSegmentationSplitter(const DigiKernel& krnl, const std::string& nam) - : DigiEventAction(krnl, nam) +DigiSegmentationSplitter::DigiSegmentationSplitter(const DigiKernel& krnl, const std::string& nam) + : DigiActionSequence(krnl, nam) { this->internals = std::make_unique<internals_t>(m_kernel, this); - declareProperty("input", this->internals->input_id = "deposits"); - declareProperty("detector", this->internals->detector_name); - declareProperty("masks", this->internals->masks); + declareProperty("input", this->internals->input_id = "deposits"); + declareProperty("detector", this->internals->detector_name); + declareProperty("mask", this->internals->input_mask); + declareProperty("split_by", this->internals->split_by); + declareProperty("processor_type", this->internals->processor_type); + declareProperty("share_processor", this->internals->share_processor = true); InstanceCount::increment(this); } /// Default destructor -dd4hep::digi::DigiSegmentationSplitter::~DigiSegmentationSplitter() { +DigiSegmentationSplitter::~DigiSegmentationSplitter() { InstanceCount::decrement(this); } -/// Split actions according to the segmentation -void dd4hep::digi::DigiSegmentationSplitter::split_segments(DigiEvent& /* event */, - DigiEvent::container_map_t& /* data */) const +void DigiSegmentationSplitter::init_processors() { + char text[256]; + std::size_t count = 0; + auto& imp = *this->internals; + std::string typ = imp.processor_type; + DigiSegmentAction* proc = nullptr; + /// Create the processors: + for( const auto& p : imp.split_processors ) { + auto& split = p.second; + ::snprintf(text, sizeof(text), "_%05X", split.split_id(p.first)); + std::string nam = this->name() + text; + proc = PluginService::Create<DigiSegmentAction*>(typ, &m_kernel, nam); + proc->internals = std::make_unique<DigiSegmentAction::internals_t>(); + proc->internals->split = &split; + this->DigiActionSequence::adopt(proc); + ++count; + } +} + +/// Main functional callback +void DigiSegmentationSplitter::execute(DigiContext& context) const { + auto& imp = *this->internals; + auto& event = *context.event; + auto& input = event.get_segment(imp.input_id); + + this->internals->initialize(context); + for( auto k : imp.data_keys ) { + auto* hits = input.pointer<DepositMapping>(k); + if ( hits ) { + /// prepare processors for execution + for ( auto* a : this->m_actors ) { + auto* proc = (DigiSegmentAction*)a; + proc->internals->input = hits; + } + /// Now submit them + this->DigiActionSequence::execute(context); + } + } +} + +/// Standard constructor +DigiSegmentAction::DigiSegmentAction(const DigiKernel& krnl, const std::string& nam) + : DigiEventAction(krnl, nam) { + this->internals = std::make_unique<internals_t>(); + InstanceCount::increment(this); +} + +/// Default destructor +DigiSegmentAction::~DigiSegmentAction() { + InstanceCount::decrement(this); +} +void DigiSegmentAction::execute(DigiContext& context) const { + auto& input = *this->internals->input; + auto& split = *this->internals->split; + auto ret = this->handleSegment(context, split, input); + if ( !ret.empty() ) { + //auto& segment = context.event->get_segment(); + } } /// Main functional callback -void dd4hep::digi::DigiSegmentationSplitter::execute(DigiContext& context) const { - this->internals->initialize(context); - auto& data = context.event->get_segment(this->internals->input_id); - this->split_segments(*context.event, data); +std::map<Key::key_type, std::any> +DigiSegmentAction::handleSegment(DigiContext& context, + const DigiSegmentContext& segment, + const DepositMapping& deposits) const { + for( const auto& depo : deposits ) { + if ( segment.split_id(depo.first) == segment.id ) { + auto cell = depo.first; + const auto& d = depo.second; + info("%s[%s] %s-id: %d [processor:%d] Cell: %016lX mask: %016lX hist:%4ld entries deposit: %f", + context.event->id(), segment.idspec.name(), segment.cname(), + segment.split_id(cell), segment.id, cell, segment.split_mask, d.history.size(), d.deposit); + } + } + return {}; } diff --git a/DDDigi/src/DigiStore.cpp b/DDDigi/src/DigiStore.cpp deleted file mode 100644 index 829444cba1630041e80aeb01b1282d89886771ff..0000000000000000000000000000000000000000 --- a/DDDigi/src/DigiStore.cpp +++ /dev/null @@ -1,25 +0,0 @@ -//========================================================================== -// 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 <DD4hep/InstanceCount.h> -#include <DDDigi/DigiKernel.h> -#include <DDDigi/DigiContext.h> -#include <DDDigi/DigiStore.h> - -// C/C++ include files -#include <stdexcept> - -using namespace std; -using namespace dd4hep::digi; - diff --git a/DDDigi/src/DigiStoreDump.cpp b/DDDigi/src/DigiStoreDump.cpp index 774907bec390d64891c17f948d8d1eb407ace2a4..50c8d29787ef058476fbb8eadf68efaebe053e98 100644 --- a/DDDigi/src/DigiStoreDump.cpp +++ b/DDDigi/src/DigiStoreDump.cpp @@ -46,6 +46,7 @@ void dd4hep::digi::DigiStoreDump::dump(const std::string& tag, std::vector<std::string> records; using detail::str_replace; info("%s+---- %s segment: %ld entries", event.id(), tag.c_str(), data_segment.size()); + std::lock_guard<std::mutex> lock(data_segment.lock); for ( const auto& e : data_segment ) { Key key {e.first}; const std::any& data = e.second; diff --git a/DDDigi/src/DigiExponentialNoise.cpp b/DDDigi/src/noise/DigiExponentialNoise.cpp similarity index 100% rename from DDDigi/src/DigiExponentialNoise.cpp rename to DDDigi/src/noise/DigiExponentialNoise.cpp diff --git a/DDDigi/src/DigiGaussianNoise.cpp b/DDDigi/src/noise/DigiGaussianNoise.cpp similarity index 100% rename from DDDigi/src/DigiGaussianNoise.cpp rename to DDDigi/src/noise/DigiGaussianNoise.cpp diff --git a/DDDigi/src/DigiLandauNoise.cpp b/DDDigi/src/noise/DigiLandauNoise.cpp similarity index 100% rename from DDDigi/src/DigiLandauNoise.cpp rename to DDDigi/src/noise/DigiLandauNoise.cpp diff --git a/DDDigi/src/DigiPoissonNoise.cpp b/DDDigi/src/noise/DigiPoissonNoise.cpp similarity index 100% rename from DDDigi/src/DigiPoissonNoise.cpp rename to DDDigi/src/noise/DigiPoissonNoise.cpp diff --git a/DDDigi/src/DigiRandomNoise.cpp b/DDDigi/src/noise/DigiRandomNoise.cpp similarity index 100% rename from DDDigi/src/DigiRandomNoise.cpp rename to DDDigi/src/noise/DigiRandomNoise.cpp diff --git a/DDDigi/src/DigiSignalProcessorSequence.cpp b/DDDigi/src/noise/DigiSignalProcessorSequence.cpp similarity index 100% rename from DDDigi/src/DigiSignalProcessorSequence.cpp rename to DDDigi/src/noise/DigiSignalProcessorSequence.cpp diff --git a/DDDigi/src/DigiSubdetectorSequence.cpp b/DDDigi/src/noise/DigiSubdetectorSequence.cpp similarity index 99% rename from DDDigi/src/DigiSubdetectorSequence.cpp rename to DDDigi/src/noise/DigiSubdetectorSequence.cpp index 97cb96b731f72eb51d7ae67041873110b9dba7d8..a56e098d06b5bc61137bfa845c0b6e142f3a8f7a 100644 --- a/DDDigi/src/DigiSubdetectorSequence.cpp +++ b/DDDigi/src/noise/DigiSubdetectorSequence.cpp @@ -106,7 +106,7 @@ void DigiSubdetectorSequence::scan_detector(DetElement de, VolumeID vid, VolumeI } -void DigiSubdetectorSequence::process_cell(DigiContext&, const DigiCellScanner& , const DigiCellData& data) const { +void DigiSubdetectorSequence::process_cell(DigiContext&, const DigiCellScanner& , const DigiCellData& /* data */) const { #if 0 Segmentation seg = m_sensDet.readout().segmentation(); string desc = m_idDesc.str(data.cell_id); @@ -115,9 +115,9 @@ void DigiSubdetectorSequence::process_cell(DigiContext&, const DigiCellScanner& seg.type().c_str(), volumeID(data.cell_id).c_str(), desc.c_str()); -#endif if ( data.cell_id ) { } +#endif } void DigiSubdetectorSequence::process_context(DigiContext& context, diff --git a/DDDigi/src/DigiUniformNoise.cpp b/DDDigi/src/noise/DigiUniformNoise.cpp similarity index 100% rename from DDDigi/src/DigiUniformNoise.cpp rename to DDDigi/src/noise/DigiUniformNoise.cpp diff --git a/DDDigi/src/FalphaNoise.cpp b/DDDigi/src/noise/FalphaNoise.cpp similarity index 100% rename from DDDigi/src/FalphaNoise.cpp rename to DDDigi/src/noise/FalphaNoise.cpp diff --git a/examples/DDDigi/scripts/DigiTest.py b/examples/DDDigi/scripts/DigiTest.py index 7299be1861ee629fc0f05755d08c756d82dbabd7..b47182e09478e548eca02b99bf09ffdfb0221a9a 100644 --- a/examples/DDDigi/scripts/DigiTest.py +++ b/examples/DDDigi/scripts/DigiTest.py @@ -9,6 +9,7 @@ # # ========================================================================== from __future__ import absolute_import +import os import dddigi import logging from g4units import ns @@ -69,6 +70,12 @@ class Test(dddigi.Digitize): 'CLICSiD_2022-10-05_14-40.root'] self.used_inputs = [] + def load_geo(self): + install_dir = os.environ['DD4hepINSTALL'] + fname = "file:" + install_dir + "/DDDetectors/compact/SiD.xml" + self.kernel().loadGeometry(str(fname)) + self.printDetectors() + def check_creation(self, objs): for o in objs: if o is None: diff --git a/examples/DDDigi/scripts/TestSegmentationSplit.py b/examples/DDDigi/scripts/TestSegmentationSplit.py index b3c52db6f7453494637668d3c626b7b842ba0770..e5acd8ab868153b5537e7b61daeb3909a17a0115 100644 --- a/examples/DDDigi/scripts/TestSegmentationSplit.py +++ b/examples/DDDigi/scripts/TestSegmentationSplit.py @@ -14,25 +14,28 @@ from __future__ import absolute_import def run(): import DigiTest digi = DigiTest.Test(geometry=None) - + digi.load_geo() input = digi.input_action('DigiParallelActionSequence/READER') - # ======================================================================================================== + # ======================================================================== digi.info('Created SIGNAL input') signal = input.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()]) digi.check_creation([signal]) - # ======================================================================================================== + # ======================================================================== event = digi.event_action('DigiSequentialActionSequence/EventAction') combine = event.adopt_action('DigiContainerCombine/Combine', masks=[0x0, 0x1, 0x2, 0x3], deposit_mask=0xFEED) combine.erase_combined = True # Not thread-safe! only do in SequentialActionSequence splitter = event.adopt_action('DigiSegmentationSplitter/Splitter', input='deposits', - masks=[0xFEED], - detector='SiTrackerBarrel') + mask=0xFEED, + detector='SiTrackerBarrel', + split_by='layer', + processor_type='DigiSegmentAction') + splitter.parallel = True dump = event.adopt_action('DigiStoreDump/StoreDump') digi.check_creation([combine, dump, splitter]) digi.info('Created event.dump') - # ======================================================================================================== - digi.run_checked(num_events=5, num_threads=5, parallel=3) + # ======================================================================== + digi.run_checked(num_events=1, num_threads=5, parallel=3) if __name__ == '__main__':