Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:21

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DDDIGI_DIGIDATA_H
0014 #define DDDIGI_DIGIDATA_H
0015 
0016 /// Framework include files
0017 #include <DD4hep/Objects.h>
0018 
0019 /// C/C++ include files
0020 #include <cstdint>
0021 #include <memory>
0022 #include <limits>
0023 #include <mutex>
0024 #include <map>
0025 #include <any>
0026 
0027 /// Namespace for the AIDA detector description toolkit
0028 namespace dd4hep {
0029 
0030   namespace detail  {
0031     static constexpr double numeric_epsilon = 10.0 * std::numeric_limits<double>::epsilon();
0032   }
0033 
0034   /// Namespace for the Digitization part of the AIDA detector description toolkit
0035   namespace digi {
0036 
0037     /// Forward declarations
0038     union Key;
0039     class Particle;
0040     class EnergyDeposit;
0041     class ParticleMapping;
0042     class DepositMapping;
0043     class DigiEvent;
0044     class DataSegment;
0045 
0046     using Position = dd4hep::Position;
0047     using Direction = dd4hep::Direction;
0048 
0049     ///  Key defintion to access the event data
0050     /**
0051      *  Helper to convert item and mask to a 64 bit integer
0052      *
0053      *  \author  M.Frank
0054      *  \version 1.0
0055      *  \ingroup DD4HEP_DIGITIZATION
0056      */
0057     union Key   {
0058       typedef std::uint64_t key_type;
0059       typedef std::uint32_t itemkey_type;
0060       typedef std::uint16_t mask_type;
0061       typedef std::uint8_t  segment_type;
0062       typedef std::uint8_t  submask_type;
0063 
0064     private:      
0065       /// First union entry used for fast initialization
0066       key_type key;
0067       /// Second union entry to use for discrimination
0068       struct {
0069         // Ordering is important here: 
0070         // We want to group the containers by item ie. by container name
0071         // and not by mask
0072         segment_type segment;
0073         submask_type submask;
0074         mask_type    mask;
0075         itemkey_type item;
0076       } values;
0077 
0078     public:
0079       /// Default constructor
0080       Key();
0081       /// Move constructor
0082       Key(Key&&);
0083       /// Copy constructor
0084       Key(const Key&);
0085       /// Initializaing constructor (fast)
0086       Key(key_type full_mask);
0087       /// Initializing constructor with key generation using hash algorithm
0088       explicit Key(const char* item, mask_type mask);
0089       /// Initializing constructor with key generation using hash algorithm
0090       explicit Key(const std::string& item, mask_type mask);
0091       /// Initializing constructor with key generation using hash algorithm
0092       explicit Key(const std::string& item, segment_type segment, mask_type mask);
0093       /// Assignment operator
0094       Key& operator = (const Key::key_type) = delete;
0095       /// Assignment operator
0096       Key& operator = (const Key&);
0097       /// Move assignment operator
0098       Key& operator = (Key&& copy);
0099       /// Equality operator
0100       bool operator == (const Key&)   const;
0101       /// Operator less
0102       bool operator < (const Key&)   const;
0103       /// Operator greator
0104       bool operator > (const Key&)   const;
0105 
0106       /// Generate key using hash algorithm
0107       Key& set(const std::string& name, int mask);
0108       /// Generate key using hash algorithm
0109       Key& set(const std::string& name, int segment, int mask);
0110 
0111       /// Set key mask
0112       Key& set_mask(mask_type m);
0113       /// Set key item identifier
0114       Key& set_item(itemkey_type i);
0115       /// Set key mask
0116       Key& set_segment(segment_type seg);
0117       /// Set key submask
0118       Key& set_submask(submask_type m);
0119       /// Set key submask
0120       Key& set_submask(const char* opt_tag);
0121 
0122       /// Project the item part of the key
0123       mask_type mask()  const;
0124       /// Project the mask part of the key
0125       itemkey_type item()  const;
0126       /// Project the segment part of the key
0127       segment_type segment()  const;
0128       /// Project the item part of the key
0129       submask_type submask()  const;
0130       /// Access key as long integer
0131       key_type value()  const;
0132 
0133       operator key_type()  const  {
0134         return this->key;
0135       }
0136       
0137       /// Project the mask part of the key
0138       static itemkey_type item(Key k);
0139       /// Project the item part of the key
0140       static mask_type mask(Key k);
0141       /// Project the item part of the key
0142       static segment_type segment(Key k);
0143       /// Project the item part of the key
0144       static submask_type submask(Key k);
0145       /// Access key name (if registered properly)
0146       static std::string key_name(const Key& key);
0147     };
0148 
0149     /// Default constructor
0150     inline Key::Key()    {
0151       this->key = 0;
0152     }
0153 
0154     /// Move constructor
0155     inline Key::Key(Key&& copy)   {
0156       this->key = copy.key;
0157     }
0158 
0159     /// Copy constructor
0160     inline Key::Key(const Key& copy)   {
0161       this->key = copy.key;
0162     }
0163 
0164     /// Initializaing constructor (fast)
0165     inline Key::Key(key_type full_mask)   {
0166       this->key = full_mask;
0167     }
0168       
0169     /// Initializaing constructor with key generation using hash algorithm
0170     inline Key::Key(const char* item, mask_type mask)  {
0171       this->set(item, mask);
0172     }
0173 
0174     /// Initializaing constructor with key generation using hash algorithm
0175     inline Key::Key(const std::string& item, mask_type mask)  {
0176       this->set(item, mask);
0177     }
0178 
0179     /// Initializing constructor with key generation using hash algorithm
0180     inline Key::Key(const std::string& item, segment_type segmnt, mask_type msk)   {
0181       this->set(item, segmnt, msk);
0182     }
0183 
0184     /// Move assignment operator
0185     inline Key& Key::operator = (Key&& copy)   {
0186       this->key = copy.key;
0187       return *this;
0188     }
0189 
0190     /// Assignment operator
0191     inline Key& Key::operator = (const Key& copy)   {
0192       this->key = copy.key;
0193       return *this;
0194     }
0195 
0196     /// Equality operator
0197     inline bool Key::operator == (const Key& other)   const    {
0198       return this->key == other.key;
0199     }
0200 
0201     /// Operator less
0202     inline bool Key::operator < (const Key& other)   const    {
0203       return this->key < other.key;
0204     }
0205 
0206     /// Operator greator
0207     inline bool Key::operator > (const Key& other)   const    {
0208       return this->key > other.key;
0209     }
0210 
0211     /// Set key mask
0212     inline Key& Key::set_mask(mask_type m)  {
0213       this->values.mask = m;
0214       return *this;
0215     }
0216     
0217     /// Set key submask
0218     inline Key& Key::set_submask(submask_type m)  {
0219       this->values.submask = m;
0220       return *this;
0221     }
0222 
0223     /// Set key item identifier
0224     inline Key& Key::set_item(itemkey_type i)  {
0225       this->values.item = i;
0226       return *this;
0227     }
0228 
0229     /// Set key mask
0230     inline Key& Key::set_segment(segment_type seg)  {
0231       this->values.segment = seg;
0232       return *this;
0233     }
0234 
0235     /// Access key as long integer
0236     inline Key::key_type Key::value()  const {
0237       return this->key;
0238     }
0239     /// Project the item part of the key
0240     inline Key::mask_type Key::mask()  const {
0241       return this->values.mask;
0242     }
0243     /// Project the mask part of the key
0244     inline Key::itemkey_type Key::item()  const  {
0245       return this->values.item;
0246     }
0247     /// Project the segment part of the key
0248     inline Key::segment_type Key::segment()  const  {
0249       return this->values.segment;
0250     }
0251     /// Project the item part of the key
0252     inline Key::submask_type Key::submask()  const {
0253       return this->values.submask;
0254     }
0255 
0256     /// Project the mask part of the key
0257     inline Key::itemkey_type Key::item(Key k)  {
0258       return k.values.item;
0259     }
0260     /// Project the item part of the key
0261     inline Key::mask_type Key::mask(Key k)  {
0262       return k.values.mask;
0263     }
0264     /// Project the item part of the key
0265     inline Key::segment_type Key::segment(Key k)  {
0266       return k.values.segment;
0267     }
0268     /// Project the item part of the key
0269     inline Key::submask_type Key::submask(Key k)  {
0270       return k.values.submask;
0271     }
0272     
0273     /// Base class for objects in a DataSegment 
0274     /**
0275      *
0276      *  \author  M.Frank
0277      *  \version 1.0
0278      *  \ingroup DD4HEP_DIGITIZATION
0279      */
0280     class SegmentEntry   {
0281     public:
0282       enum data_type_t  {
0283         UNKNOWN            = 0,
0284         PARTICLES          = 1 << 1,
0285         TRACKER_HITS       = 1 << 2,
0286         CALORIMETER_HITS   = 1 << 3,
0287         HISTORY            = 1 << 4,
0288         DETECTOR_RESPONSE  = 1 << 5,
0289       };
0290       std::string      name { };
0291       Key              key  { };
0292       data_type_t      data_type  { UNKNOWN };
0293     public:
0294       /// Initializing constructor
0295       SegmentEntry(const std::string& name, Key::mask_type mask, data_type_t typ);
0296       /// Default constructor
0297       SegmentEntry() = default;
0298       /// Disable move constructor
0299       SegmentEntry(SegmentEntry&& copy) = default;
0300       /// Disable copy constructor
0301       SegmentEntry(const SegmentEntry& copy) = default;      
0302       /// Default destructor
0303       virtual ~SegmentEntry() = default;
0304       /// Disable move assignment
0305       SegmentEntry& operator=(SegmentEntry&& copy) = default;
0306       /// Disable copy assignment
0307       SegmentEntry& operator=(const SegmentEntry& copy) = default;      
0308     };
0309 
0310     /// Initializing constructor
0311     inline SegmentEntry::SegmentEntry(const std::string& nam, Key::mask_type msk, data_type_t typ)
0312       : name(nam), data_type(typ)
0313     {
0314       key.set(nam, msk);
0315     }
0316 
0317     /// Particle definition for digitization
0318     /** Particle definition for digitization
0319      *
0320      *  \author  M.Frank
0321      *  \version 1.0
0322      *  \ingroup DD4HEP_DIGITIZATION
0323      */
0324     class Particle   {
0325     public:
0326       Position  start_position { };
0327       Position  end_position   { };
0328       Direction momentum       { };
0329       double    mass           { 0e0 };
0330       int       time           { 0 };
0331       int       pdgID          { 0 };
0332       char      charge         { 0 };
0333       /// Source contributing
0334       std::any  source         { };  //! not persistent
0335 
0336     public:
0337       /// Default constructor
0338       Particle() = default;
0339       /// Disable move constructor
0340       Particle(Particle&& copy) = default;
0341       /// Disable copy constructor
0342       Particle(const Particle& copy) = default;
0343       /// Default destructor
0344       virtual ~Particle() = default;
0345       /// Disable move assignment
0346       Particle& operator=(Particle&& copy) = default;
0347       /// Disable copy assignment
0348       Particle& operator=(const Particle& copy) = default;
0349       /// Move particle
0350       void move_position(const Position& delta);
0351     };
0352 
0353     /// Particle mapping definition for digitization
0354     /**
0355      *
0356      *  \author  M.Frank
0357      *  \version 1.0
0358      *  \ingroup DD4HEP_DIGITIZATION
0359      */
0360     class ParticleMapping : public SegmentEntry   {
0361     public:
0362       using container_t    = std::map<Key::key_type, Particle>;
0363       using value_type     = container_t::value_type;
0364       using mapped_type    = container_t::mapped_type;
0365       using key_type       = container_t::key_type;
0366       using iterator       = container_t::iterator;
0367       using const_iterator = container_t::const_iterator;
0368     protected:
0369       container_t data;
0370 
0371     public: 
0372       /// Initializing constructor
0373       ParticleMapping(const std::string& name, Key::mask_type mask);
0374       /// Default constructor
0375       ParticleMapping() = default;
0376       /// Disable move constructor
0377       ParticleMapping(ParticleMapping&& copy) = default;
0378       /// Disable copy constructor
0379       ParticleMapping(const ParticleMapping& copy) = default;
0380       /// Default destructor
0381       virtual ~ParticleMapping() = default;
0382       /// Disable move assignment
0383       ParticleMapping& operator=(ParticleMapping&& copy) = default;
0384       /// Disable copy assignment
0385       ParticleMapping& operator=(const ParticleMapping& copy) = default;
0386 
0387       /// Merge new deposit map onto existing map (not thread safe!)
0388       std::size_t merge(ParticleMapping&& updates);
0389       /// Add new entry to the particle mapping (not thread safe!)
0390       void push(Key key, Particle&& particle);
0391 
0392       /// Merge new deposit map onto existing map (not thread safe!) (CONST)
0393       std::size_t insert(const ParticleMapping& updates);
0394       /// Add new entry to the particle mapping (not thread safe!) (CONST)
0395       void insert(Key key, const Particle& particle);
0396 
0397       /// Access container size
0398       std::size_t size()  const           { return this->data.size();        }
0399       /// Check container if empty
0400       bool        empty() const           { return this->data.empty();       }
0401       /// Insert new entry
0402       //std::pair<iterator, bool> emplace(key_type entry_key, mapped_type&& entry_data);
0403       void emplace(Key entry_key, Particle&& entry_data);
0404 
0405       /** Iteration support */
0406       /// Begin iteration
0407       iterator begin()                    { return this->data.begin();       }
0408       /// End iteration
0409       iterator end()                      { return this->data.end();         }
0410       /// Begin iteration (CONST)
0411       const_iterator begin() const        { return this->data.begin();       }
0412       /// End iteration (CONST)
0413       const_iterator end()   const        { return this->data.end();         }
0414       /// Access particle by key
0415       const Particle& get(Key key)   const;
0416     };
0417 
0418     /// Initializing constructor
0419     inline ParticleMapping::ParticleMapping(const std::string& nam, Key::mask_type msk)
0420       : SegmentEntry(nam, msk, SegmentEntry::PARTICLES)
0421     {
0422     }
0423 
0424     ///  Class to hold the processing history of the detector response
0425     /**
0426      *
0427      *  \author  M.Frank
0428      *  \version 1.0
0429      *  \ingroup DD4HEP_DIGITIZATION
0430      */
0431     class History   {
0432     public:
0433       struct hist_entry_t   {
0434         Key::key_type source { };
0435         double weight { 0e0 };
0436         hist_entry_t(Key s, double w);
0437         hist_entry_t() = default;
0438         hist_entry_t(hist_entry_t&& copy) = default;
0439         hist_entry_t(const hist_entry_t& copy) = default;
0440         hist_entry_t& operator=(hist_entry_t&& copy) = default;
0441         hist_entry_t& operator=(const hist_entry_t& copy) = default;
0442         ~hist_entry_t() = default;
0443         const Particle& get_particle(const DigiEvent& event)  const;
0444         const EnergyDeposit& get_deposit(const DigiEvent& event, Key::itemkey_type container_item)  const;
0445       };
0446       /// Sources contributing to the deposit indexed by the cell identifier
0447       std::vector<hist_entry_t> hits;
0448       std::vector<hist_entry_t> particles;
0449 
0450     public:
0451       /// Default constructor
0452       History() = default;
0453       /// Disable move constructor
0454       History(History&& copy) = default;
0455       /// Disable copy constructor
0456       History(const History& copy) = default;
0457       /// Default destructor
0458       virtual ~History() = default;
0459       /// Disable move assignment
0460       History& operator=(History&& copy) = default;
0461       /// Disable copy assignment
0462       History& operator=(const History& copy) = default;
0463 
0464       /// Update history
0465       void update(const History& upda);
0466       /// Drop history information
0467       std::pair<std::size_t,std::size_t> drop();
0468 
0469       /// Number of hits contributing to history entry
0470       std::size_t num_hits()   const   {
0471         return hits.size();
0472       }
0473       /// Number of particles contributing to history entry
0474       std::size_t num_particles()   const   {
0475         return particles.size();
0476       }
0477       /// Retrieve the weighted momentum of all contributing particles
0478       Direction average_particle_momentum(const DigiEvent& event)  const;
0479     };
0480 
0481     inline History::hist_entry_t::hist_entry_t(Key s, double w)
0482       : source(s), weight(w)  {
0483     }
0484 
0485     /// Energy deposit definition for digitization
0486     /**
0487      *
0488      *  \author  M.Frank
0489      *  \version 1.0
0490      *  \ingroup DD4HEP_DIGITIZATION
0491      */
0492     class EnergyDeposit   {
0493     public:
0494       enum { 
0495         KILLED             = 1 << 0,
0496         ENERGY_SMEARED     = 1 << 1,
0497         POSITION_SMEARED   = 1 << 2,
0498         TIME_SMEARED       = 1 << 3,
0499         ZERO_SUPPRESSED    = 1 << 4,
0500         DEPOSIT_NOISE      = 1 << 5,
0501         RECALIBRATED       = 1 << 6,
0502       };
0503 
0504       /// Hit position
0505       Position       position     { };
0506       /// Hit direction
0507       Direction      momentum     { };
0508       /// Length of the track segment contributing to this hit
0509       double         length       { 0e0 };
0510       /// Total energy deposit
0511       double         deposit      { 0e0 };
0512       /// Total energy deposit
0513       double         depositError { -1e0 };
0514       /// Proper creation time of the deposit with rescpect to beam crossing
0515       double         time         { 0e0 };
0516       /// Optional flag for user masks
0517       uint64_t       flag         { 0UL };
0518       /// Source mask of this deposit
0519       Key::mask_type mask         { 0 };
0520       /// Deposit history
0521       History        history      { };
0522 
0523     public:
0524       /// Default constructor
0525       EnergyDeposit() = default;
0526       /// Disable move constructor
0527       EnergyDeposit(EnergyDeposit&& copy) = default;
0528       /// Disable copy constructor
0529       EnergyDeposit(const EnergyDeposit& copy) = default;
0530       /// Default destructor
0531       virtual ~EnergyDeposit() = default;
0532       /// Disable move assignment
0533       EnergyDeposit& operator=(EnergyDeposit&& copy) = default;
0534       /// Disable copy assignment
0535       EnergyDeposit& operator=(const EnergyDeposit& copy) = default;
0536       /// Update the deposit using deposit weighting
0537       void update_deposit_weighted(EnergyDeposit&& update);
0538       /// Update the deposit using deposit weighting
0539       void update_deposit_weighted(const EnergyDeposit& update);
0540     };
0541 
0542 
0543     /// Base class to select energy deposits
0544     /**
0545      *
0546      *  \author  M.Frank
0547      *  \version 1.0
0548      *  \ingroup DD4HEP_DIGITIZATION
0549      */
0550     template <typename USERDATA=int> class DepositPredicate   {
0551     public:
0552       using userdata_t = USERDATA;
0553       /// User data block
0554       userdata_t data;
0555       /// Standard constructor
0556       DepositPredicate(const userdata_t& data=userdata_t());
0557       /// Default destructor
0558       virtual ~DepositPredicate() = default;
0559       /// Selector function
0560       template <typename ARG> bool operator()(ARG argument)  const;
0561     };
0562 
0563     /// Standard constructor
0564     template <typename USERDATA> inline 
0565     DepositPredicate<USERDATA>::DepositPredicate(const userdata_t& d)
0566       : data(d)
0567     {
0568     }
0569 
0570     struct EnergyCut {
0571       double cutoff;
0572     };
0573     
0574     /// Energy deposit vector definition for digitization
0575     /**
0576      *
0577      *  \author  M.Frank
0578      *  \version 1.0
0579      *  \ingroup DD4HEP_DIGITIZATION
0580      */
0581     class DepositVector : public SegmentEntry  {
0582     public: 
0583       using container_t    = std::vector<std::pair<const CellID, EnergyDeposit> >;
0584       using value_type     = container_t::value_type;
0585       using mapped_type    = container_t::value_type::second_type;
0586       using key_type       = container_t::value_type::first_type;
0587       using iterator       = container_t::iterator;
0588       using const_iterator = container_t::const_iterator;
0589 
0590     protected:
0591       container_t    data      { };
0592 
0593     public: 
0594       /// Initializing constructor
0595       DepositVector(const std::string& name, Key::mask_type mask, data_type_t typ);
0596       /// Default constructor
0597       DepositVector() = default;
0598       /// Disable move constructor
0599       DepositVector(DepositVector&& copy) = default;
0600       /// Disable copy constructor
0601       DepositVector(const DepositVector& copy) = default;      
0602       /// Default destructor
0603       virtual ~DepositVector() = default;
0604       /// Disable move assignment
0605       DepositVector& operator=(DepositVector&& copy) = default;
0606       /// Disable copy assignment
0607       DepositVector& operator=(const DepositVector& copy) = default;      
0608       /// Merge new deposit map onto existing vector (destroys inputs. not thread safe!)
0609       std::size_t merge(DepositVector&& updates);
0610       /// Merge new deposit map onto existing vector (destroys inputs. not thread safe!)
0611       std::size_t merge(const DepositVector& updates);
0612       /// Merge new deposit map onto existing map (destroys inputs. not thread safe!)
0613       std::size_t merge(DepositMapping&& updates);
0614       /// Merge new deposit map onto existing map (destroys inputs. not thread safe!)
0615       std::size_t merge(const DepositMapping& updates);
0616       /// Merge new deposit map onto existing vector (keep inputs. not thread safe!)
0617       std::size_t insert(const DepositVector& updates);
0618       /// Merge new deposit map onto existing map (keep inputs. not thread safe!)
0619       std::size_t insert(const DepositMapping& updates);
0620       /// Emplace entry
0621       void emplace(CellID cell, EnergyDeposit&& deposit);
0622 
0623       /// Access container size
0624       std::size_t size()  const           { return this->data.size();        }
0625       /// Check container if empty
0626       bool        empty() const           { return this->data.empty();       }
0627       /// Access energy deposit by key
0628       const EnergyDeposit& get(CellID cell)   const;
0629       /// Access energy deposit by key
0630       const EnergyDeposit& at(std::size_t cell)   const;
0631 
0632       /** Iteration support */
0633       /// Begin iteration
0634       iterator begin()                    { return this->data.begin();       }
0635       /// End iteration
0636       iterator end()                      { return this->data.end();         }
0637       /// Begin iteration (CONST)
0638       const_iterator begin() const        { return this->data.begin();       }
0639       /// End iteration (CONST)
0640       const_iterator end()   const        { return this->data.end();         }
0641       /// Remove entry
0642       void remove(iterator position);
0643     };
0644 
0645     /// Initializing constructor
0646     inline DepositVector::DepositVector(const std::string& nam, Key::mask_type msk, data_type_t typ)
0647       : SegmentEntry(nam, msk, typ)
0648     {
0649     }
0650 
0651     /// Emplace entry
0652     inline void DepositVector::emplace(CellID cell, EnergyDeposit&& deposit)   {
0653       this->data.emplace_back(cell, std::move(deposit));
0654     }
0655 
0656     /// Energy deposit mapping definition for digitization
0657     /**
0658      *
0659      *  \author  M.Frank
0660      *  \version 1.0
0661      *  \ingroup DD4HEP_DIGITIZATION
0662      */
0663     class DepositMapping : public SegmentEntry  {
0664     public: 
0665       using container_t    = std::multimap<CellID, EnergyDeposit>;
0666       using value_type     = container_t::value_type;
0667       using mapped_type    = container_t::mapped_type;
0668       using key_type       = container_t::key_type;
0669       using iterator       = container_t::iterator;
0670       using const_iterator = container_t::const_iterator;
0671 
0672       container_t    data      { };
0673 
0674     public: 
0675       /// Initializing constructor
0676       DepositMapping(const std::string& name, Key::mask_type mask, data_type_t typ);
0677       /// Default constructor
0678       DepositMapping() = default;
0679       /// Disable move constructor
0680       DepositMapping(DepositMapping&& copy) = default;
0681       /// Disable copy constructor
0682       DepositMapping(const DepositMapping& copy) = default;      
0683       /// Default destructor
0684       virtual ~DepositMapping() = default;
0685       /// Disable move assignment
0686       DepositMapping& operator=(DepositMapping&& copy) = default;
0687       /// Disable copy assignment
0688       DepositMapping& operator=(const DepositMapping& copy) = default;      
0689 
0690       /// Merge new deposit map onto existing map (not thread safe!)
0691       std::size_t merge(DepositMapping&& updates);
0692       /// Merge new deposit map onto existing map (not thread safe!)
0693       std::size_t insert(const DepositMapping& updates);
0694 
0695       /// Merge new deposit map onto existing map (not thread safe!)
0696       std::size_t merge(DepositVector&& updates);
0697       /// Merge new deposit map onto existing map (not thread safe!)
0698       std::size_t insert(const DepositVector& updates);
0699       /// Emplace entry
0700       void emplace(CellID cell, EnergyDeposit&& deposit);
0701 
0702       /// Access container size
0703       std::size_t size()  const           { return this->data.size();        }
0704       /// Check container if empty
0705       bool        empty() const           { return this->data.empty();       }
0706       /// Access energy deposit by key
0707       const EnergyDeposit& get(CellID cell)   const;
0708 
0709       /** Iteration support */
0710       /// Begin iteration
0711       iterator begin()                    { return this->data.begin();       }
0712       /// End iteration
0713       iterator end()                      { return this->data.end();         }
0714       /// Begin iteration (CONST)
0715       const_iterator begin() const        { return this->data.begin();       }
0716       /// End iteration (CONST)
0717       const_iterator end()   const        { return this->data.end();         }
0718       /// Remove entry
0719       void remove(iterator position);
0720     };
0721 
0722     /// Initializing constructor
0723     inline DepositMapping::DepositMapping(const std::string& nam, Key::mask_type msk, data_type_t typ)
0724       : SegmentEntry(nam, msk, typ)
0725     {
0726     }
0727 
0728     class ADCValue   {
0729     public:
0730       using value_t = uint32_t;
0731       using address_t = uint64_t;
0732     public:
0733       value_t    value;
0734       address_t  address;
0735     };
0736     
0737     /// Detector response vector definition for digitization
0738     /**
0739      *
0740      *  \author  M.Frank
0741      *  \version 1.0
0742      *  \ingroup DD4HEP_DIGITIZATION
0743      */
0744     class DetectorResponse : public SegmentEntry  {
0745     public: 
0746       using container_t    = std::vector<std::pair<CellID, ADCValue> >;
0747       using iterator       = container_t::iterator;
0748       using const_iterator = container_t::const_iterator;
0749 
0750       container_t    data { };
0751 
0752     public: 
0753       /// Initializing constructor
0754       DetectorResponse(const std::string& name, Key::mask_type mask);
0755       /// Default constructor
0756       DetectorResponse() = default;
0757       /// Disable move constructor
0758       DetectorResponse(DetectorResponse&& copy) = default;
0759       /// Disable copy constructor
0760       DetectorResponse(const DetectorResponse& copy) = default;      
0761       /// Default destructor
0762       virtual ~DetectorResponse() = default;
0763       /// Disable move assignment
0764       DetectorResponse& operator=(DetectorResponse&& copy) = default;
0765       /// Disable copy assignment
0766       DetectorResponse& operator=(const DetectorResponse& copy) = default;      
0767 
0768       /// Merge new deposit map onto existing map (not thread safe!)
0769       std::size_t merge(DetectorResponse&& updates);
0770       /// Merge new deposit map onto existing map (not thread safe!)
0771       std::size_t insert(const DetectorResponse& updates);
0772       /// Emplace entry
0773       void emplace(CellID cell, ADCValue&& value);
0774 
0775       /// Access container size
0776       std::size_t size()  const           { return this->data.size();        }
0777       /// Check container if empty
0778       bool        empty() const           { return this->data.empty();       }
0779 
0780       /** Iteration support */
0781       /// Begin iteration
0782       iterator begin()                    { return this->data.begin();       }
0783       /// End iteration
0784       iterator end()                      { return this->data.end();         }
0785       /// Begin iteration (CONST)
0786       const_iterator begin() const        { return this->data.begin();       }
0787       /// End iteration (CONST)
0788       const_iterator end()   const        { return this->data.end();         }
0789     };
0790 
0791     /// Initializing constructor
0792     inline DetectorResponse::DetectorResponse(const std::string& nam, Key::mask_type msk)
0793       : SegmentEntry(nam, msk, SegmentEntry::DETECTOR_RESPONSE)
0794     {
0795     }
0796 
0797 
0798     /// Emplace entry
0799     inline void DetectorResponse::emplace(CellID cell, ADCValue&& value)   {
0800       this->data.emplace_back(cell, std::move(value));
0801     }
0802 
0803     /// Detector history vector definition for digitization
0804     /**
0805      *
0806      *  \author  M.Frank
0807      *  \version 1.0
0808      *  \ingroup DD4HEP_DIGITIZATION
0809      */
0810     class DetectorHistory : public SegmentEntry  {
0811     public: 
0812       using container_t    = std::vector<std::pair<CellID, History> >;
0813       using iterator       = container_t::iterator;
0814       using const_iterator = container_t::const_iterator;
0815 
0816       container_t    data { };
0817 
0818     public: 
0819       /// Initializing constructor
0820       DetectorHistory(const std::string& name, Key::mask_type mask);
0821       /// Default constructor
0822       DetectorHistory() = default;
0823       /// Disable move constructor
0824       DetectorHistory(DetectorHistory&& copy) = default;
0825       /// Disable copy constructor
0826       DetectorHistory(const DetectorHistory& copy) = default;      
0827       /// Default destructor
0828       virtual ~DetectorHistory() = default;
0829       /// Disable move assignment
0830       DetectorHistory& operator=(DetectorHistory&& copy) = default;
0831       /// Disable copy assignment
0832       DetectorHistory& operator=(const DetectorHistory& copy) = default;      
0833 
0834       /// Merge new deposit map onto existing map (not thread safe!)
0835       std::size_t merge(DetectorHistory&& updates);
0836       /// Merge new deposit map onto existing map (not thread safe!)
0837       std::size_t insert(const DetectorHistory& updates);
0838 
0839       /// Insert new entry
0840       void insert(CellID cell, const History& value);
0841       /// Emplace new entry
0842       void emplace(CellID cell, History&& value);
0843 
0844       /// Access container size
0845       std::size_t size()  const           { return this->data.size();        }
0846       /// Check container if empty
0847       bool        empty() const           { return this->data.empty();       }
0848 
0849       /** Iteration support */
0850       /// Begin iteration
0851       iterator begin()                    { return this->data.begin();       }
0852       /// End iteration
0853       iterator end()                      { return this->data.end();         }
0854       /// Begin iteration (CONST)
0855       const_iterator begin() const        { return this->data.begin();       }
0856       /// End iteration (CONST)
0857       const_iterator end()   const        { return this->data.end();         }
0858     };
0859 
0860     /// Initializing constructor
0861     inline DetectorHistory::DetectorHistory(const std::string& nam, Key::mask_type msk)
0862       : SegmentEntry(nam, msk, SegmentEntry::HISTORY)
0863     {
0864     }
0865 
0866     /// Emplace new entry
0867     inline void DetectorHistory::emplace(CellID cell, History&& value)   {
0868       this->data.emplace_back(cell, std::move(value));
0869     }
0870 
0871     /// Insert new entry
0872     inline void DetectorHistory::insert(CellID cell, const History& value)   {
0873       this->data.emplace_back(cell, value);
0874     }
0875     typedef DetectorHistory DepositsHistory;
0876 
0877     /// Detector history vector definition for digitization
0878     /**
0879      *
0880      *  \author  M.Frank
0881      *  \version 1.0
0882      *  \ingroup DD4HEP_DIGITIZATION
0883      */
0884     class DataParameters : public SegmentEntry  {
0885     public: 
0886       template <typename T> using map_type_t = std::map<std::string, std::vector<T> >;
0887       struct header_data  {
0888         map_type_t<std::string> stringParams;
0889         map_type_t<float>       floatParams;
0890         map_type_t<int>         intParams;
0891         std::int32_t            run_number    {  -1 };
0892         std::int32_t            event_number  {  -1 };
0893         std::int64_t            time_stamp    {   0 };
0894         double                  event_weight  { 0e0 };
0895       };
0896       std::shared_ptr<header_data> data;
0897     public: 
0898       /// Initializing constructor
0899       DataParameters(const std::string& name, Key::mask_type mask);
0900       /// Default constructor
0901       DataParameters() = default;
0902       /// Disable move constructor
0903       DataParameters(DataParameters&& copy) = default;
0904       /// Disable copy constructor
0905       DataParameters(const DataParameters& copy) = default;
0906       /// Default destructor
0907       virtual ~DataParameters() = default;
0908       /// Disable move assignment
0909       DataParameters& operator=(DataParameters&& copy) = default;
0910       /// Disable copy assignment
0911       DataParameters& operator=(const DataParameters& copy) = default;
0912       /// Access  data size
0913       std::size_t size()  const;
0914       /// Access the event number
0915       std::int32_t getEventNumber() const   {
0916         return data->event_number;
0917       }
0918       /// Access the run number
0919       std::int32_t getRunNumber() const   {
0920         return data->run_number;
0921       }
0922       /// Access the time stamp
0923       std::uint64_t getTimeStamp() const   {
0924         return data->time_stamp;
0925       }
0926       /// Access the event weight
0927       float getWeight() const   {
0928         return data->event_weight;
0929       }
0930       /// Set the event number
0931       void setEventNumber(std::int32_t value)   {
0932         data->event_number = value;
0933       }
0934       /// Set the run number
0935       void setRunNumber(std::int32_t value)   {
0936         data->run_number = value;
0937       }
0938       /// Set the time stamp
0939       void setTimeStamp(std::uint64_t value)   {
0940         data->time_stamp = value;
0941       }
0942       /// Set the event weight
0943       void setWeight(float value)   {
0944         data->event_weight = value;
0945       }
0946     };
0947 
0948     /// Initializing constructor
0949     inline DataParameters::DataParameters(const std::string& nam, Key::mask_type msk)
0950       : SegmentEntry(nam, msk, SegmentEntry::HISTORY)
0951     {
0952       this->data = std::make_shared<header_data>();
0953     }
0954 
0955 
0956     ///  Data segment definition (locked map)
0957     /**
0958      *
0959      *  \author  M.Frank
0960      *  \version 1.0
0961      *  \ingroup DD4HEP_DIGITIZATION
0962      */
0963     class DataSegment   {
0964     public:
0965       using key_t = Key::key_type;
0966       using container_map_t = std::map<Key, std::any>;
0967       using iterator        = container_map_t::iterator;
0968       using const_iterator  = container_map_t::const_iterator;
0969 
0970     private:
0971       /// Call on failed any-casts
0972       std::string invalid_cast(Key key, const std::type_info& type)  const;
0973       /// Call on failed data requests during data requests
0974       std::string invalid_request(Key key)  const;
0975 
0976       /// Access data item by key
0977       std::any* get_item(Key key, bool exc);
0978       /// Access data item by key  (CONST)
0979       const std::any* get_item(Key key, bool exc)  const;
0980 
0981     public:
0982       container_map_t   data;
0983       std::mutex&       lock;
0984       Key::segment_type id  { 0 };
0985     public:
0986       /// Initializing constructor
0987       DataSegment(std::mutex& lock, Key::segment_type id);
0988       /// Default constructor
0989       DataSegment() = delete;
0990       /// Disable move constructor
0991       DataSegment(DataSegment&& copy) = delete;
0992       /// Disable copy constructor
0993       DataSegment(const DataSegment& copy) = delete;      
0994       /// Default destructor
0995       virtual ~DataSegment() = default;
0996       /// Disable move assignment
0997       DataSegment& operator=(DataSegment&& copy) = delete;
0998       /// Disable copy assignment
0999       DataSegment& operator=(const DataSegment& copy) = delete;      
1000 
1001       /** Locked operations */
1002       /// Emplace data item (locked)
1003       bool emplace_any(Key key, std::any&& data);
1004       /// Emplace arbitrary data item
1005       template <typename T> bool emplace(Key key, T&& data_item)   {
1006         key.set_segment(this->id);
1007         data_item.key.set_segment(this->id);
1008         return this->emplace_any(std::move(key), std::move(data_item));
1009       }
1010       /// Move data items other than std::any to the data segment
1011       template <typename DATA> bool put(Key key, DATA&& data);
1012       /// Remove data item from segment (locked)
1013       bool erase(Key key);
1014       /// Remove data items from segment (locked)
1015       std::size_t erase(const std::vector<Key>& keys);
1016       /// Print segment keys
1017       void print_keys()   const;
1018       
1019       /** Unlocked operations */
1020       /// Access data by key. If not existing, nullptr is returned
1021       std::any* entry(Key key)              { return this->get_item(key, false); }
1022       /// Access data by key. If not existing, nullptr is returned
1023       const std::any* entry(Key key)  const { return this->get_item(key, false); }
1024 
1025       /// Access data as reference by key. If not existing, an exception is thrown
1026       template<typename T> T& get(Key key);
1027       /// Access data as reference by key. If not existing, an exception is thrown
1028       template<typename T> const T& get(Key key)  const;
1029 
1030       /// Access data as pointers by key. If not existing, nullptr is returned
1031       template<typename T> T* pointer(Key key);
1032       /// Access data as pointers by key. If not existing, nullptr is returned
1033       template<typename T> const T* pointer(Key key)  const;
1034 
1035       /// Access container size
1036       std::size_t size()  const           { return this->data.size();        }
1037       /// Check container if empty
1038       bool        empty() const           { return this->data.empty();       }
1039       /// Begin iteration
1040       iterator begin()                    { return this->data.begin();       }
1041       /// End iteration
1042       iterator end()                      { return this->data.end();         }
1043       /// Find entry by key
1044       iterator find(Key key)              { return this->data.find(key);     }
1045       /// Begin iteration (CONST)
1046       const_iterator begin() const        { return this->data.begin();       }
1047       /// End iteration (CONST)
1048       const_iterator end()   const        { return this->data.end();         }
1049       /// Find entry by key
1050       const_iterator find(Key key) const  { return this->data.find(key);     }
1051     };
1052 
1053     /// Access data as reference by key. If not existing, an exception is thrown
1054     template<typename DATA> inline DATA& DataSegment::get(Key key)     {
1055       if ( DATA* ptr = std::any_cast<DATA>(this->get_item(key, true)) )
1056         return *ptr;
1057       throw std::runtime_error(this->invalid_cast(std::move(key), typeid(DATA)));
1058     }
1059     /// Access data as reference by key. If not existing, an exception is thrown
1060     template<typename DATA> inline const DATA& DataSegment::get(Key key)  const   {
1061       if ( const DATA* ptr = std::any_cast<DATA>(this->get_item(key, true)) )
1062         return *ptr;
1063       throw std::runtime_error(this->invalid_cast(std::move(key), typeid(DATA)));
1064     }
1065 
1066     /// Access data as pointers by key. If not existing, nullptr is returned
1067     template<typename DATA> inline DATA* DataSegment::pointer(Key key)     {
1068       if ( DATA* ptr = std::any_cast<DATA>(this->get_item(std::move(key), false)) )
1069         return ptr;
1070       return nullptr;
1071     }
1072     /// Access data as pointers by key. If not existing, nullptr is returned
1073     template<typename DATA> inline const DATA* DataSegment::pointer(Key key)  const   {
1074       if ( const DATA* ptr = std::any_cast<DATA>(this->get_item(std::move(key), false)) )
1075         return ptr;
1076       return nullptr;
1077     }
1078 
1079     /// Move data items other than std::any to the data segment
1080     template <typename DATA> inline bool DataSegment::put(Key key, DATA&& value)   {
1081       key.set_segment(this->id);
1082       value.key.set_segment(this->id);
1083       std::any item = std::make_any<DATA>(std::move(value));
1084       return this->emplace_any(std::move(key), std::move(item));
1085     }
1086 
1087     /// Helper to place data to data segment
1088     template <typename KEY, typename DATA> 
1089     bool put_data(DataSegment& segment, KEY key, DATA&& value)    {
1090       std::any item = std::make_any<DATA>(std::move(value));
1091       return segment.emplace_any(std::move(key), std::move(item));
1092     }
1093 
1094     ///  User event data for DDDigi
1095     /**
1096      *
1097      *  \author  M.Frank
1098      *  \version 1.0
1099      *  \ingroup DD4HEP_DIGITIZATION
1100      */
1101     class  DigiEvent  {
1102     private:
1103       using segment_t = std::unique_ptr<DataSegment>;
1104       /// Event lock
1105       std::mutex  m_lock;
1106       /// String identifier of this event (for debug printouts)
1107       std::string m_id;
1108       /// Reference to the general purpose data segment
1109       segment_t m_data;
1110       /// Reference to the counts data segment
1111       segment_t m_counts;
1112       /// Reference to the input data segment
1113       segment_t m_inputs;
1114       /// Reference to the output data segment
1115       segment_t m_outputs;
1116       /// Reference to the deposit data segment
1117       segment_t m_deposits;
1118 
1119       /// Helper: Save access with segment creation if it does not exist
1120       DataSegment& access_segment(segment_t& seg, Key::segment_type id);
1121 
1122     public:
1123       /// Current event number
1124       int eventNumber  { 0 };
1125 
1126     public:
1127 #if defined(DD4HEP_INTERPRETER_MODE) || defined(G__ROOT)
1128       /// Inhibit default constructor
1129       DigiEvent();
1130 #endif
1131       /// Inhibit move constructor
1132       DigiEvent(DigiEvent&& copy) = delete;
1133       /// Inhibit copy constructor
1134       DigiEvent(const DigiEvent& copy) = delete;
1135       /// Intializing constructor
1136       DigiEvent(int num);
1137       /// Default destructor
1138       virtual ~DigiEvent();
1139       /// String identifier of this event
1140       const char* id()   const    {   return this->m_id.c_str();   }
1141       /// Retrieve data segment from the event structure by name
1142       DataSegment& get_segment(const std::string& name);
1143       /// Retrieve data segment from the event structure by name (CONST)
1144       const DataSegment& get_segment(const std::string& name)  const;
1145       /// Retrieve data segment from the event structure by identifier
1146       DataSegment& get_segment(Key::segment_type id);
1147       /// Retrieve data segment from the event structure by identifier (CONST)
1148       const DataSegment& get_segment(Key::segment_type id)  const;
1149     };
1150 
1151     /// Static global functions
1152     std::string digiTypeName(const std::type_info& info);
1153     std::string digiTypeName(const std::any& data);
1154     const Particle& get_history_particle(const DigiEvent& event, Key history_key);
1155     const EnergyDeposit& get_history_deposit(const DigiEvent& event, Key::itemkey_type container_item, Key history_key);
1156 
1157   }    // End namespace digi
1158 }      // End namespace dd4hep
1159 #endif // DDDIGI_DIGIDATA_H