diff --git a/DDCore/include/DD4hep/Any.h b/DDCore/include/DD4hep/Any.h new file mode 100644 index 0000000000000000000000000000000000000000..569fff21e55acb745d5843670999c42a4f7dc587 --- /dev/null +++ b/DDCore/include/DD4hep/Any.h @@ -0,0 +1,42 @@ +//========================================================================== +// 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 DD4HEP_ANY_H +#define DD4HEP_ANY_H + +#if __cplusplus >= 201703L +// C/C++ include files +#include <any> +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + using std::any; + using std::any_cast; + using std::make_any; +} + +#else + +#include "boost/any.hpp" +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + using boost::any; + using boost::any_cast; + /// Create an any holding a @c _Tp constructed from @c __args. + template <typename T, typename... _Args> + any make_any(_Args&&... __args) { + return any(T(std::forward<_Args>(__args)...)); + } +} +#endif + +#endif // DD4HEP_ANY_H diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h index cd4de7190165dbaf7be3bc7cfa038e159d512442..7f3dc6cbf99cfe3b874051780e1c0b5661143116 100644 --- a/DDDigi/include/DDDigi/DigiData.h +++ b/DDDigi/include/DDDigi/DigiData.h @@ -14,11 +14,15 @@ #define DD4HEP_DDDIGI_DIGIDATA_H /// Framework include files +#include "DD4hep/Any.h" #include "DD4hep/Primitives.h" #include "DD4hep/ObjectExtensions.h" /// C/C++ include files #include <memory> +#include <stdexcept> +#include <cstdint> +#include <map> /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -101,6 +105,32 @@ namespace dd4hep { typedef DigiContainer<DigiDeposit> DigiEnergyDeposits; typedef DigiContainer<DigiCount> DigiCounts; + /// Key defintion to access the event data + /** + * Helper to convert item and mask to a 64 bit integer + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + union Key { + typedef std::uint64_t key_type; + typedef std::uint32_t itemkey_type; + typedef std::uint8_t mask_type; + key_type key; + struct { + itemkey_type item; + mask_type mask; + mask_type spare[3]; + } values; + Key(); + Key(const Key&); + Key(mask_type mask, itemkey_type item); + Key(mask_type mask, const std::string& item); + Key& operator=(const Key&); + key_type toLong() const { return key; } + }; + /// User event data for DDDigi /** * @@ -110,9 +140,14 @@ namespace dd4hep { */ class DigiEvent : public ObjectExtensions { public: + /// Forward definition of the key type + typedef Key::key_type key_type; std::map<unsigned long, std::shared_ptr<DigiEnergyDeposits> > energyDeposits; std::map<unsigned long, std::shared_ptr<DigiCounts> > digitizations; + int eventNumber = 0; + std::map<key_type, dd4hep::any> data; + public: #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__) /// Inhibit default constructor @@ -126,7 +161,24 @@ namespace dd4hep { DigiEvent(int num); /// Default destructor virtual ~DigiEvent(); - + /// Add item by key to the data + template<typename T> bool put(const Key& key, dd4hep::any&& object) { + bool ret = data.emplace(key.toLong(),object).second; + if ( ret ) return ret; + throw std::runtime_error("Invalid requested to store data in event container. Key:%ld",key.toLong()); + } + /// 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() ) return dd4hep::any_cast<T&>((*iter).second); + throw std::runtime_error("Invalid data requested from event container. Key:%ld",key.toLong()); + } + /// Retrieve item by key from the event data container + template<typename T> const T& get(const Key& key) const { + auto iter = data.find(key.toLong()); + if ( iter != data.end() ) return dd4hep::any_cast<const T&>((*iter).second); + throw std::runtime_error("Invalid data requested from event container. Key:%ld",key.toLong()); + } /// Add an extension object to the detector element void* addExtension(unsigned long long int k, ExtensionEntry* e) { return ObjectExtensions::addExtension(k, e); diff --git a/DDDigi/src/DigiData.cpp b/DDDigi/src/DigiData.cpp index 80c92748b69f2606eb28c64f4ae6d2b17ced7823..6f484f9a92b6fb04a7d4486751a2b2179fc901f1 100644 --- a/DDDigi/src/DigiData.cpp +++ b/DDDigi/src/DigiData.cpp @@ -13,6 +13,7 @@ // Framework include files #include "DD4hep/Printout.h" +#include "DD4hep/Primitives.h" #include "DD4hep/InstanceCount.h" #define G__ROOT #include "DDDigi/DigiData.h" @@ -23,6 +24,31 @@ using namespace std; using namespace dd4hep; using namespace dd4hep::digi; +Key::Key() { + key = 0; +} + +Key::Key(const Key& copy) { + key = copy.key; +} + +Key::Key(mask_type mask, itemkey_type item) { + key = 0; + values.mask = mask; + values.item = item; +} + +Key::Key(mask_type mask, const std::string& item) { + key = 0; + values.mask = mask; + values.item = detail::hash32(item); +} + +Key& Key::operator=(const Key& copy) { + key = copy.key; + return *this; +} + /// Intializing constructor DigiEvent::DigiEvent() : ObjectExtensions(typeid(DigiEvent))