diff --git a/DDCore/include/DD4hep/IDDescriptor.h b/DDCore/include/DD4hep/IDDescriptor.h index 07dab4362d9cfe56039aa6619c4d0b141e098300..1095005b48c99941112b909e2d4c0f9dabd8a068 100644 --- a/DDCore/include/DD4hep/IDDescriptor.h +++ b/DDCore/include/DD4hep/IDDescriptor.h @@ -63,6 +63,10 @@ namespace dd4hep { #ifndef __MAKECINT__ /// Encode a set of volume identifiers (corresponding to this description of course!) to a volumeID. VolumeID encode(const std::vector<std::pair<std::string, int> >& ids) const; + /// Encode a set of volume identifiers to a volumeID with the system ID on the top bits + VolumeID encode_reverse(const std::vector<std::pair<std::string, int> >& id_vector) const; + /// Compute the submask for a given set of volume IDs + VolumeID get_mask(const std::vector<std::pair<std::string, int> >& id_vector) const; #endif /// Decode volume IDs and return filled descriptor with all fields void decodeFields(VolumeID vid, std::vector<std::pair<const BitFieldElement*, VolumeID> >& fields) const; @@ -73,7 +77,7 @@ namespace dd4hep { /// Access string representation std::string toString() const; /// Access the BitFieldCoder object - BitFieldCoder* decoder(); + BitFieldCoder* decoder() const; /// Re-build object in place void rebuild(const std::string& description); }; diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index b919b1f01e2f97e7a1c329051fa61a2f084a012c..3aaba2e61837df6f21da119abc97ecf1d592e1ed 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -134,6 +134,9 @@ namespace dd4hep { /// Set new shape name Solid_type<T>& setName(const std::string& value); + /// Access to shape title (GetTitle accessor of the TGeoShape) + const char* title() const; + /// Access to shape type (The TClass name of the ROOT implementation) const char* type() const; /// Auto conversion to underlying ROOT object diff --git a/DDCore/include/DDSegmentation/BitField64.h b/DDCore/include/DDSegmentation/BitField64.h index 1e02050c5abfbf0d1dd3440508ca7ef4a178e1bd..21a189c7e630f40223f8a8028d3de7fa30436762 100644 --- a/DDCore/include/DDSegmentation/BitField64.h +++ b/DDCore/include/DDSegmentation/BitField64.h @@ -45,7 +45,7 @@ namespace dd4hep { /// only c'tor with reference to bitfield and BitFieldElement BitFieldValue( long64& bitfield, const BitFieldElement& bv ) : - _value( bitfield ), _bv( bv) {} + _value( bitfield ), _bv( bv) {} /** Returns the current field value */ @@ -56,8 +56,8 @@ namespace dd4hep { //// Assignment operator for user convenience BitFieldValue& operator=(long64 in) { - _bv.set( _value, in ) ; - return *this ; + _bv.set( _value, in ) ; + return *this ; } /** Conversion operator for long64 - allows to write:<br> @@ -115,8 +115,8 @@ namespace dd4hep { public : virtual ~BitField64() { - if( _owner) - delete _coder ; + if( _owner) + delete _coder ; } ; /** No default c'tor */ @@ -138,7 +138,7 @@ namespace dd4hep { */ BitField64( const std::string& initString ){ - _coder = new BitFieldCoder( initString ) ; + _coder = new BitFieldCoder( initString ) ; } /// Initialize from existing BitFieldCoder @@ -157,7 +157,7 @@ namespace dd4hep { /** Set a new 64bit value given as high and low 32bit words. */ void setValue(unsigned low_Word, unsigned high_Word ) { - setValue( ( low_Word & 0xffffffffULL ) | ( ( high_Word & 0xffffffffULL ) << 32 ) ) ; + setValue( ( low_Word & 0xffffffffULL ) | ( ( high_Word & 0xffffffffULL ) << 32 ) ) ; } /** Operator for setting a new value and accessing the BitField directly */ @@ -170,7 +170,7 @@ namespace dd4hep { /** Acces to field through index */ BitFieldValue operator[](size_t idx) { - return BitFieldValue( _value, _coder->operator[]( idx ) ) ; + return BitFieldValue( _value, _coder->operator[]( idx ) ) ; } // /** Const acces to field through index @@ -195,7 +195,7 @@ namespace dd4hep { */ BitFieldValue operator[](const std::string& name) { - return BitFieldValue( _value, _coder->operator[]( name ) ) ; + return BitFieldValue( _value, _coder->operator[]( name ) ) ; } // /** Const Access to field through name . // */ diff --git a/DDCore/include/Parsers/Primitives.h b/DDCore/include/Parsers/Primitives.h index 7251a07c142ce8d6d89df5c6e6ea3fb919e317c5..c91f3a8e595faf1e3f6f3f476a13ed3d0e11a429 100644 --- a/DDCore/include/Parsers/Primitives.h +++ b/DDCore/include/Parsers/Primitives.h @@ -178,10 +178,23 @@ namespace dd4hep { hash ^= (hash >> 11); hash += (hash << 15); return hash; } + inline unsigned int hash32(const std::string& key) { return hash32(key.c_str()); } + template <typename T> T reverseBits(T num) { + static constexpr size_t NO_OF_BITS = sizeof(num) * 8 - 1; + static constexpr T _zero = 0; + static constexpr T _one = 1; + T reverse_num = _zero; + for (size_t i = 0; i <= NO_OF_BITS; i++) { + if( (num & (_one << i)) ) + reverse_num |= (_one << (NO_OF_BITS - i)); + } + return reverse_num; + } + /// Convert date into epoch time (seconds since 1970) long int makeTime(int year, int month, int day, int hour=0, int minutes=0, int seconds=0); diff --git a/DDCore/src/IDDescriptor.cpp b/DDCore/src/IDDescriptor.cpp index 981b3f4a8898671fe981a94d55929d523492536a..75ad66f068a8d57782c0ef5cc996e4e577471f18 100644 --- a/DDCore/src/IDDescriptor.cpp +++ b/DDCore/src/IDDescriptor.cpp @@ -116,6 +116,16 @@ size_t IDDescriptor::fieldID(const string& field_name) const { throw runtime_error("dd4hep"); // Never called. Simply make the compiler happy! } +/// Compute the submask for a given set of volume IDs +VolumeID IDDescriptor::get_mask(const std::vector<std::pair<std::string, int> >& id_vector) const { + VolumeID mask = 0ULL; + for (const auto& i : id_vector ) { + const auto* fld = field(i.first); + mask |= fld->mask(); + } + return mask; +} + /// Encode a set of volume identifiers (corresponding to this description of course!) to a volumeID. VolumeID IDDescriptor::encode(const std::vector<std::pair<std::string, int> >& id_vector) const { @@ -126,11 +136,17 @@ VolumeID IDDescriptor::encode(const std::vector<std::pair<std::string, int> >& i const BitFieldElement* fld = field(i.first); int off = fld->offset(); VolumeID val = i.second; - id |= ((fld->value(val<<off) << off)&fld->mask()); + id |= ((fld->value(val << off) << off)&fld->mask()); } return id; } +/// Encode a set of volume identifiers to a volumeID with the system ID on the top bits +VolumeID IDDescriptor::encode_reverse(const std::vector<std::pair<std::string, int> >& id_vector) const +{ + return detail::reverseBits<VolumeID>(encode(id_vector)); +} + /// Decode volume IDs and return filled descriptor with all fields void IDDescriptor::decodeFields(VolumeID vid, vector<pair<const BitFieldElement*, VolumeID> >& flds) const @@ -164,6 +180,6 @@ string IDDescriptor::str(VolumeID vid, VolumeID mask) const { } /// Access the BitFieldCoder object -BitFieldCoder* IDDescriptor::decoder() { +BitFieldCoder* IDDescriptor::decoder() const { return &(data<Object>()->decoder); } diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 6e604d9df560701b63aa021cee4ec5ffc7db809e..8b47177c2cade8365ab878cfb0347e6e73b9ce3f 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -56,6 +56,11 @@ template <typename T> const char* Solid_type<T>::name() const { return this->ptr()->GetName(); } +/// Access to shape name +template <typename T> const char* Solid_type<T>::title() const { + return this->ptr()->GetTitle(); +} + /// Set new shape name template <typename T> Solid_type<T>& Solid_type<T>::setName(const char* value) { this->access()->SetName(value); diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 754d4f432a99ed6a093886638c9e6903505ea9ec..c38958bb1abd811795354fcc83c7e431da425826 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -392,13 +392,13 @@ template <> void Converter<Header>::operator()(xml_h e) const { */ template <> void Converter<Material>::operator()(xml_h e) const { xml_ref_t x_mat(e); - TGeoManager& mgr = description.manager(); - xml_tag_t mname = x_mat.name(); + TGeoManager& mgr = description.manager(); + xml_tag_t mname = x_mat.name(); const char* matname = mname.c_str(); - TGeoElementTable* table = mgr.GetElementTable(); - TGeoMaterial* mat = mgr.GetMaterial(matname); - TGeoMixture* mix = dynamic_cast<TGeoMixture*>(mat); - xml_coll_t fractions(x_mat, _U(fraction)); + TGeoElementTable* table = mgr.GetElementTable(); + TGeoMaterial* mat = mgr.GetMaterial(matname); + TGeoMixture* mix = dynamic_cast<TGeoMixture*>(mat); + xml_coll_t fractions (x_mat, _U(fraction)); xml_coll_t composites(x_mat, _U(composite)); if (0 == mat) { @@ -425,11 +425,11 @@ template <> void Converter<Material>::operator()(xml_h e) const { "++ Converting material %-16s Density: %.3f.",matname, dens_val); //throw 1; mat = mix = new TGeoMixture(matname, composites.size(), dens_val); - size_t ifrac = 0; + size_t ifrac = 0; vector<double> composite_fractions; - double composite_fractions_total = 0.0; + double composite_fractions_total = 0.0; for (composites.reset(); composites; ++composites) { - string nam = composites.attr<string>(_U(ref)); + string nam = composites.attr<string>(_U(ref)); double fraction = composites.attr<double>(_U(n)); if (0 != (comp_mat = mgr.GetMaterial(nam.c_str()))) fraction *= comp_mat->GetA(); @@ -441,7 +441,7 @@ template <> void Converter<Material>::operator()(xml_h e) const { composite_fractions.emplace_back(fraction); } for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) { - string nam = composites.attr<string>(_U(ref)); + string nam = composites.attr<string>(_U(ref)); double fraction = composite_fractions[ifrac]/composite_fractions_total; if (0 != (comp_mat = mgr.GetMaterial(nam.c_str()))) mix->AddElement(comp_mat, fraction); @@ -449,7 +449,7 @@ template <> void Converter<Material>::operator()(xml_h e) const { mix->AddElement(comp_elt, fraction); } for (fractions.reset(); fractions; ++fractions) { - string nam = fractions.attr<string>(_U(ref)); + string nam = fractions.attr<string>(_U(ref)); double fraction = fractions.attr<double>(_U(n)); if (0 != (comp_mat = mgr.GetMaterial(nam.c_str()))) mix->AddElement(comp_mat, fraction); @@ -467,7 +467,7 @@ template <> void Converter<Material>::operator()(xml_h e) const { for(xml_coll_t properties(x_mat, _U(constant)); properties; ++properties) { xml_elt_t p = properties; if ( p.hasAttr(_U(ref)) ) { - bool err = kFALSE; + bool err = kFALSE; string ref = p.attr<string>(_U(ref)); mgr.GetProperty(ref.c_str(), &err); /// Check existence if ( err == kFALSE ) { @@ -514,14 +514,14 @@ template <> void Converter<Material>::operator()(xml_h e) const { #endif xml_h temp = x_mat.child(_U(T), false); if ( temp.ptr() ) { - double temp_val = temp.attr<double>(_U(value)); - double temp_unit = temp.attr<double>(_U(unit), 1.0 /* _toDouble("kelvin") */); + double temp_val = temp.attr<double>(_U(value)); + double temp_unit = temp.attr<double>(_U(unit), 1.0 /* _toDouble("kelvin") */); mat->SetTemperature(temp_val*temp_unit); } xml_h pressure = x_mat.child(_U(P), false); if ( pressure.ptr() ) { - double pressure_val = pressure.attr<double>(_U(value)); - double pressure_unit = pressure.attr<double>(_U(unit),1.0 /* _toDouble("pascal") */); + double pressure_val = pressure.attr<double>(_U(value)); + double pressure_unit = pressure.attr<double>(_U(unit),1.0 /* _toDouble("pascal") */); mat->SetPressure(pressure_val*pressure_unit); } } @@ -556,10 +556,10 @@ template <> void Converter<Material>::operator()(xml_h e) const { */ template <> void Converter<Isotope>::operator()(xml_h e) const { xml_dim_t isotope(e); - TGeoManager& mgr = description.manager(); - string nam = isotope.nameStr(); - TGeoElementTable* tab = mgr.GetElementTable(); - TGeoIsotope* iso = tab->FindIsotope(nam.c_str()); + TGeoManager& mgr = description.manager(); + string nam = isotope.nameStr(); + TGeoElementTable* tab = mgr.GetElementTable(); + TGeoIsotope* iso = tab->FindIsotope(nam.c_str()); // Create the isotope object in the event it is not yet present from the XML data if ( !iso ) { diff --git a/DDCore/src/segmentations/BitFieldCoder.cpp b/DDCore/src/segmentations/BitFieldCoder.cpp index d0d45ab965e9d86c16fef62f4ba745fe7eee11a5..d00800e650e0936056dc9105c079a9a2604e1457 100644 --- a/DDCore/src/segmentations/BitFieldCoder.cpp +++ b/DDCore/src/segmentations/BitFieldCoder.cpp @@ -6,225 +6,211 @@ namespace dd4hep{ -namespace DDSegmentation { + namespace DDSegmentation { - BitFieldElement::BitFieldElement( const std::string& fieldName, - unsigned fieldOffset, int signedWidth ) : - _mask(0), - _offset( fieldOffset ), - _width( abs( signedWidth ) ), - _minVal(0), - _maxVal(0), - _isSigned( signedWidth < 0 ), - _name( fieldName ) { - - // sanity check - if( _offset > 63 || _offset+_width > 64 ) { - - std::stringstream s ; - s << " BitFieldElement '" << _name << "': out of range - offset : " - << _offset << " width " << _width ; - - throw( std::runtime_error( s.str() ) ) ; - } + BitFieldElement::BitFieldElement( const std::string& fieldName, + unsigned fieldOffset, int signedWidth ) : + _mask(0), + _offset( fieldOffset ), + _width( abs( signedWidth ) ), + _minVal(0), + _maxVal(0), + _isSigned( signedWidth < 0 ), + _name( fieldName ) { + + // sanity check + if( _offset > 63 || _offset+_width > 64 ) { + + std::stringstream s ; + s << " BitFieldElement '" << _name << "': out of range - offset : " + << _offset << " width " << _width ; + + throw( std::runtime_error( s.str() ) ) ; + } - _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ; + _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ; - // compute extreme values for later checks - if( _isSigned ){ + // compute extreme values for later checks + if( _isSigned ){ - _minVal = ( 1LL << ( _width - 1 ) ) - ( 1LL << _width ) ; - _maxVal = ( 1LL << ( _width - 1 ) ) - 1 ; + _minVal = ( 1LL << ( _width - 1 ) ) - ( 1LL << _width ) ; + _maxVal = ( 1LL << ( _width - 1 ) ) - 1 ; - } else { - - _maxVal = 0x0001<<_width ; + } else { + _maxVal = 0x0001<<_width ; + } } - - } - - long64 BitFieldElement::value(long64 id) const { - - if( _isSigned ) { - - long64 val = ( id & _mask ) >> _offset ; - - if( ( val & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value - - val -= ( 1LL << _width ); + long64 BitFieldElement::value(long64 id) const { + if( _isSigned ) { + long64 val = ( id & _mask ) >> _offset ; + if( ( val & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value + val -= ( 1LL << _width ); + } + return val ; + } else { + return ( id & _mask ) >> _offset ; } - - return val ; - - } else { - - return ( id & _mask ) >> _offset ; } - } - void BitFieldElement::set(long64& field, long64 in) const { - - // check range - if( in < _minVal || in > _maxVal ) { - - std::stringstream s ; - s << " BitFieldElement '" << _name << "': out of range : " << in - << " for width " << _width ; - - throw( std::runtime_error( s.str() ) ); - } + void BitFieldElement::set(long64& field, long64 in) const { - field &= ~_mask ; // zero out the field's range + // check range + if( in < _minVal || in > _maxVal ) { + std::stringstream s ; + s << " BitFieldElement '" << _name << "': out of range : " << in + << " for width " << _width ; + throw( std::runtime_error( s.str() ) ); + } - field |= ( ( in << _offset ) & _mask ) ; - - } + field &= ~_mask ; // zero out the field's range + field |= ( ( in << _offset ) & _mask ) ; + } - size_t BitFieldCoder::index( const std::string& name) const { + size_t BitFieldCoder::index( const std::string& name) const { - IndexMap::const_iterator it = _map.find( name ) ; + IndexMap::const_iterator it = _map.find( name ) ; - if( it != _map.end() ) + if( it != _map.end() ) - return it->second ; + return it->second ; - else - throw std::runtime_error(" BitFieldElement: unknown name: " + name ) ; - } + else + throw std::runtime_error(" BitFieldElement: unknown name: " + name ) ; + } - unsigned BitFieldCoder::highestBit() const { + unsigned BitFieldCoder::highestBit() const { - unsigned hb(0) ; + unsigned hb(0) ; - for(unsigned i=0;i<_fields.size();i++){ + for(unsigned i=0;i<_fields.size();i++){ - if( hb < ( _fields[i].offset() + _fields[i].width() ) ) - hb = _fields[i].offset() + _fields[i].width() ; - } - return hb ; - } + if( hb < ( _fields[i].offset() + _fields[i].width() ) ) + hb = _fields[i].offset() + _fields[i].width() ; + } + return hb ; + } - std::string BitFieldCoder::valueString(ulong64 bitfield) const { + std::string BitFieldCoder::valueString(ulong64 bitfield) const { - std::stringstream os ; + std::stringstream os ; - for(unsigned i=0;i<_fields.size();i++){ + for(unsigned i=0;i<_fields.size();i++){ - if( i != 0 ) os << "," ; + if( i != 0 ) os << "," ; - os << _fields[i].name() << ":" << _fields[i].value(bitfield) ; + os << _fields[i].name() << ":" << _fields[i].value(bitfield) ; + } + return os.str() ; } - return os.str() ; - } - std::string BitFieldCoder::fieldDescription() const { + std::string BitFieldCoder::fieldDescription() const { - std::stringstream os ; + std::stringstream os ; - for(unsigned i=0;i<_fields.size();i++){ + for(unsigned i=0;i<_fields.size();i++){ - if( i != 0 ) os << "," ; + if( i != 0 ) os << "," ; - os << _fields[i].name() << ":" - << _fields[i].offset() << ":" ; + os << _fields[i].name() << ":" + << _fields[i].offset() << ":" ; - if( _fields[i].isSigned() ) - os << "-" ; + if( _fields[i].isSigned() ) + os << "-" ; - os << _fields[i].width() ; + os << _fields[i].width() ; - } + } - return os.str() ; - } + return os.str() ; + } - void BitFieldCoder::addField( const std::string& name, unsigned offset, int width ){ + void BitFieldCoder::addField( const std::string& name, unsigned offset, int width ){ - _fields.emplace_back(name, offset, width); - BitFieldElement& bfv = _fields.back() ; + _fields.emplace_back(name, offset, width); + BitFieldElement& bfv = _fields.back() ; - _map[ name ] = _fields.size()-1 ; + _map[ name ] = _fields.size()-1 ; - if( _joined & bfv.mask() ) { + if( _joined & bfv.mask() ) { - std::stringstream s ; - s << " BitFieldElement::addField(" << name << "): bits already used " << std::hex << _joined - << " for mask " << bfv.mask() ; + std::stringstream s ; + s << " BitFieldElement::addField(" << name << "): bits already used " << std::hex << _joined + << " for mask " << bfv.mask() ; - throw( std::runtime_error( s.str() ) ) ; + throw( std::runtime_error( s.str() ) ) ; - } + } - _joined |= bfv.mask() ; + _joined |= bfv.mask() ; - } + } - void BitFieldCoder::init( const std::string& initString) { + void BitFieldCoder::init( const std::string& initString) { - unsigned offset = 0 ; + unsigned offset = 0 ; - // need to compute bit field masks and offsets ... - std::vector<std::string> fieldDescriptors ; - StringTokenizer t( fieldDescriptors ,',') ; + // need to compute bit field masks and offsets ... + std::vector<std::string> fieldDescriptors ; + StringTokenizer t( fieldDescriptors ,',') ; - std::for_each( initString.begin(), initString.end(), t ) ; + std::for_each( initString.begin(), initString.end(), t ) ; - for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){ + for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){ - std::vector<std::string> subfields ; - StringTokenizer ts( subfields ,':') ; + std::vector<std::string> subfields ; + StringTokenizer ts( subfields ,':') ; - std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts ); + std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts ); - std::string name ; - int width ; - unsigned thisOffset ; + std::string name ; + int width ; + unsigned thisOffset ; - switch( subfields.size() ){ + switch( subfields.size() ){ - case 2: + case 2: - name = subfields[0] ; - width = atol( subfields[1].c_str() ) ; - thisOffset = offset ; + name = subfields[0] ; + width = atol( subfields[1].c_str() ) ; + thisOffset = offset ; - offset += abs( width ) ; + offset += abs( width ) ; - break ; + break ; - case 3: - name = subfields[0] ; - thisOffset = atol( subfields[1].c_str() ) ; - width = atol( subfields[2].c_str() ) ; + case 3: + name = subfields[0] ; + thisOffset = atol( subfields[1].c_str() ) ; + width = atol( subfields[2].c_str() ) ; - offset = thisOffset + abs( width ) ; + offset = thisOffset + abs( width ) ; - break ; + break ; - default: + default: - std::stringstream s ; - s << " BitFieldCoder: invalid number of subfields " - << fieldDescriptors[i] ; + std::stringstream s ; + s << " BitFieldCoder: invalid number of subfields " + << fieldDescriptors[i] ; - throw( std::runtime_error( s.str() ) ) ; - } + throw( std::runtime_error( s.str() ) ) ; + } - addField( name , thisOffset, width ) ; + addField( name , thisOffset, width ) ; + } } - } -} // namespace + } // namespace } // namespace diff --git a/DDDigi/CMakeLists.txt b/DDDigi/CMakeLists.txt index d6f26201f0e6c92d8a67bb7cf23e83f384fcf997..bac993b915670d6881c18daaeeae044d5a007924 100644 --- a/DDDigi/CMakeLists.txt +++ b/DDDigi/CMakeLists.txt @@ -9,7 +9,8 @@ # #========================================================================== SET_PROPERTY(DIRECTORY . PROPERTY PACKAGE_NAME DDDigi) -file(GLOB DDDigi_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB DDDigi_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/segmentations/*.cpp) add_library(DDDigi ${DDDigi_SOURCES}) add_library(DD4hep::DDDigi ALIAS DDDigi) diff --git a/DDDigi/include/DDDigi/DigiAction.h b/DDDigi/include/DDDigi/DigiAction.h index c86633ef38f900b82da310044111e610a0ce588d..66d8e18c8135ee7557c161f31cdc7d5ae0e82b36 100644 --- a/DDDigi/include/DDDigi/DigiAction.h +++ b/DDDigi/include/DDDigi/DigiAction.h @@ -110,10 +110,6 @@ namespace dd4hep { long m_refCount = 1; /// Default property: Output level int m_outputLevel = 3; - /// - - /// Property: Support parallel execution - bool m_parallel = false; protected: @@ -266,12 +262,6 @@ namespace dd4hep { } /// Set the output level; returns previous value PrintLevel setOutputLevel(PrintLevel new_level); - /// Access parallization flag - bool executeParallel() const { - return m_parallel; - } - /// Set the parallization flag; returns previous value - bool setExecuteParallel(bool new_value); /// Declare property template <typename T> DigiAction& declareProperty(const std::string& nam, T& val); @@ -307,8 +297,8 @@ namespace dd4hep { /// Support of exceptions: Print fatal message and throw runtime_error. void except(const char* fmt, ...) const; - /// Main functional callback - virtual void execute(DigiContext& context) const = 0; + /// Optional action initialization if required + virtual void initialize(); }; /// Declare property diff --git a/DDDigi/include/DDDigi/DigiActionSequence.h b/DDDigi/include/DDDigi/DigiActionSequence.h index ce27fbc0af690cedc9b5cffb7d247ad799668ff2..98441018ea51dbe7b75eaa35743222b1b3cc519f 100644 --- a/DDDigi/include/DDDigi/DigiActionSequence.h +++ b/DDDigi/include/DDDigi/DigiActionSequence.h @@ -23,7 +23,7 @@ namespace dd4hep { namespace digi { // Forward declarations - class DigiAction; + class DigiEventAction; class DigiActionSequence; /// Concrete implementation of the Digitization event action sequence @@ -57,7 +57,7 @@ namespace dd4hep { /// Default destructor virtual ~DigiActionSequence(); /// Adopt a new action as part of the sequence. Sequence takes ownership. - void adopt(DigiAction* action); + void adopt(DigiEventAction* action); /// Register external listener callbacks before starting the sequence template <typename Q, typename T> void begin(Q* p, void (T::*f)(DigiContext* context)) { diff --git a/DDDigi/include/DDDigi/DigiAttenuator.h b/DDDigi/include/DDDigi/DigiAttenuator.h new file mode 100644 index 0000000000000000000000000000000000000000..a94e029e24042c530b3919e6a5e7fe92442df936 --- /dev/null +++ b/DDDigi/include/DDDigi/DigiAttenuator.h @@ -0,0 +1,54 @@ +//========================================================================== +// 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_DDDIGI_DIGIATTENUATOR_H +#define DD4HEP_DDDIGI_DIGIATTENUATOR_H + +/// Framework include files +#include "DDDigi/DigiSignalProcessor.h" + +/// C/C++ include files +#include <functional> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + /// Base class for attenuator actions to the digitization + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiAttenuator : public DigiSignalProcessor { + protected: + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiAttenuator); + /// Function object to be executed + std::function<double(const DigiCellData&)> processor; + public: + /// Standard constructor + DigiAttenuator(const DigiKernel& kernel, const std::string& nam); + /// Default destructor + virtual ~DigiAttenuator(); + /// Callback to read event attenuator + virtual double operator()(const DigiCellData& data) const override { + return processor(data); + } + }; + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGIATTENUATOR_H diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h index 524162d5126c5a162e626c29aeedef7eecfcc7eb..69e739c494956db3e255c2f9a1c81e6663f06b19 100644 --- a/DDDigi/include/DDDigi/DigiData.h +++ b/DDDigi/include/DDDigi/DigiData.h @@ -15,14 +15,16 @@ /// Framework include files #include "DD4hep/Any.h" +#include "DD4hep/Objects.h" #include "DD4hep/Printout.h" #include "DD4hep/Primitives.h" #include "DD4hep/ObjectExtensions.h" /// C/C++ include files -#include <memory> +#include <functional> #include <stdexcept> #include <cstdint> +#include <memory> #include <map> /// Namespace for the AIDA detector description toolkit @@ -61,6 +63,99 @@ namespace dd4hep { DigiContainer& operator=(const DigiContainer& copy) = delete; }; + /// + /* + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class EnergyDeposit { + public: + class FunctionTable { + friend class EnergyDeposit; + public: + std::function<long long int(const void*)> cellID; + std::function<long(const void*)> flag; + FunctionTable() = default; + ~FunctionTable() = default; + }; + template <typename Q, typename T> static const Q* vtable(); + std::pair<const void*, const FunctionTable*> object; + + public: + /// Initializing constructor + template <typename T> EnergyDeposit(const T* object); + /// Default constructor + EnergyDeposit() = delete; + /// Disable move constructor + EnergyDeposit(EnergyDeposit&& copy) = default; + /// Disable copy constructor + EnergyDeposit(const EnergyDeposit& copy) = default; + /// Default destructor + virtual ~EnergyDeposit() = default; + /// Disable move assignment + EnergyDeposit& operator=(EnergyDeposit&& copy) = default; + /// Disable copy assignment + EnergyDeposit& operator=(const EnergyDeposit& copy) = default; + + long long int cellID() const { return object.second->cellID(object.first); } + long flag() const { return object.second->flag(object.first); } + }; + + template <typename T> inline EnergyDeposit::EnergyDeposit(const T* ptr) + : object(ptr, vtable<EnergyDeposit::FunctionTable,T>()) + { + } + + /// + /* + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class TrackerDeposit : public EnergyDeposit { + public: + class FunctionTable : public EnergyDeposit::FunctionTable { + friend class TrackerDeposit; + friend class EnergyDeposit; + public: + std::function<const Position& (const void*)> position; + std::function<const Direction& (const void*)> momentum; + std::function<double(const void*)> deposit; + std::function<double(const void*)> length; + FunctionTable() = default; + ~FunctionTable() = default; + }; + std::pair<const void*, const FunctionTable*> object; + + public: + /// Initializing constructor + template <typename T> TrackerDeposit(const T* object); + /// Default constructor + TrackerDeposit() = delete; + /// Disable move constructor + TrackerDeposit(TrackerDeposit&& copy) = default; + /// Disable copy constructor + TrackerDeposit(const TrackerDeposit& copy) = default; + /// Default destructor + virtual ~TrackerDeposit() = default; + /// Disable move assignment + TrackerDeposit& operator=(TrackerDeposit&& copy) = default; + /// Disable copy assignment + TrackerDeposit& operator=(const TrackerDeposit& copy) = default; + + const Position& position() const { return object.second->position(object.first); } + const Direction& momentum() const { return object.second->momentum(object.first); } + double deposit() const { return object.second->deposit(object.first); } + double length() const { return object.second->length(object.first); } + }; + + template <typename T> inline TrackerDeposit::TrackerDeposit(const T* ptr) + : object(ptr, vtable<TrackerDeposit::FunctionTable,T>()) + { + } /// /* @@ -69,22 +164,71 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiDeposit { + class CaloDeposit : public EnergyDeposit { + public: + class FunctionTable : public EnergyDeposit::FunctionTable { + friend class CaloDeposit; + friend class EnergyDeposit; + public: + std::function<const Position& (const void*)> position; + std::function<double(const void*)> deposit; + FunctionTable() = default; + ~FunctionTable() = default; + }; + std::pair<const void*, const FunctionTable*> object; + public: + /// Initializing constructor + template <typename T> CaloDeposit(const T* object); /// Default constructor - DigiDeposit() = default; + CaloDeposit() = delete; /// Disable move constructor - DigiDeposit(DigiDeposit&& copy) = delete; + CaloDeposit(CaloDeposit&& copy) = default; /// Disable copy constructor - DigiDeposit(const DigiDeposit& copy) = delete; + CaloDeposit(const CaloDeposit& copy) = default; /// Default destructor - virtual ~DigiDeposit() = default; + virtual ~CaloDeposit() = default; /// Disable move assignment - DigiDeposit& operator=(DigiDeposit&& copy) = delete; + CaloDeposit& operator=(CaloDeposit&& copy) = default; /// Disable copy assignment - DigiDeposit& operator=(const DigiDeposit& copy) = delete; + CaloDeposit& operator=(const CaloDeposit& copy) = default; + + const Position& position() const { return object.second->position(object.first); } + double deposit() const { return object.second->deposit(object.first); } }; + template <typename T> inline CaloDeposit::CaloDeposit(const T* ptr) + : object(ptr, vtable<CaloDeposit::FunctionTable,T>()) + { + } + + /// + /* + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiCellData { + public: + double raw_value { 0.0 }; + double delay { 0.0 }; + mutable bool kill { false }; + + /// Default constructor + DigiCellData() = default; + /// Default move constructor + DigiCellData(DigiCellData&& copy) = default; + /// Default copy constructor + DigiCellData(const DigiCellData& copy) = default; + /// Default destructor + virtual ~DigiCellData() = default; + /// Default move assignment + DigiCellData& operator=(DigiCellData&& copy) = delete; + /// Default copy assignment + DigiCellData& operator=(const DigiCellData& copy) = delete; + }; + /// /* * @@ -96,20 +240,20 @@ namespace dd4hep { public: /// Default constructor DigiCount() = default; - /// Disable move constructor + /// Default move constructor DigiCount(DigiCount&& copy) = default; - /// Disable copy constructor + /// Default copy constructor DigiCount(const DigiCount& copy) = default; /// Default destructor virtual ~DigiCount() = default; - /// Disable move assignment + /// Default move assignment DigiCount& operator=(DigiCount&& copy) = delete; - /// Disable copy assignment + /// Default copy assignment DigiCount& operator=(const DigiCount& copy) = delete; }; - typedef DigiContainer<DigiDeposit*> DigiEnergyDeposits; - typedef DigiContainer<DigiCount*> DigiCounts; + typedef DigiContainer<EnergyDeposit*> DigiEnergyDeposits; + typedef DigiContainer<DigiCount*> DigiCounts; /// Key defintion to access the event data /** diff --git a/DDDigi/include/DDDigi/DigiEventAction.h b/DDDigi/include/DDDigi/DigiEventAction.h new file mode 100644 index 0000000000000000000000000000000000000000..43db5a53afa09343ad411359c8d54f2c2872136d --- /dev/null +++ b/DDDigi/include/DDDigi/DigiEventAction.h @@ -0,0 +1,63 @@ +//========================================================================== +// 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_DDDIGI_DIGIEVENTACTION_H +#define DD4HEP_DDDIGI_DIGIEVENTACTION_H + +// Framework include files +#include "DDDigi/DigiAction.h" + + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + /// 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 DigiEventAction : public DigiAction { + friend class DigiKernel; + + protected: + /// Property: Support parallel execution + bool m_parallel = false; + + protected: + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiEventAction); + + /// Default destructor + virtual ~DigiEventAction(); + + public: + /// Standard constructor + DigiEventAction(const DigiKernel& kernel, const std::string& nam); + /// Access parallization flag + bool executeParallel() const { + return m_parallel; + } + /// Set the parallization flag; returns previous value + bool setExecuteParallel(bool new_value); + /// Main functional callback + virtual void execute(DigiContext& context) const = 0; + }; + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGIEVENTACTION_H diff --git a/DDDigi/include/DDDigi/DigiFactories.h b/DDDigi/include/DDDigi/DigiFactories.h index e7254dfdcc9c2e0661227bbe676ca972bb97ae54..13eb6561b96327ed208639289892e26d1d4a2633 100644 --- a/DDDigi/include/DDDigi/DigiFactories.h +++ b/DDDigi/include/DDDigi/DigiFactories.h @@ -22,40 +22,57 @@ #include <string> #include <map> +class TGeoShape; + /// Namespace for the AIDA detector description toolkit namespace dd4hep { + class SegmentationObject; class DetElement; class Detector; /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { class DigiKernel; - class DigiAction; + class DigiEventAction; + class DigiCellScanner; + class DigiSignalProcessor; } } namespace { - namespace DS = dd4hep::digi; - struct _ns { - typedef DS::DigiAction DA; - typedef DS::DigiKernel K; - typedef std::map<std::string,std::string> STRM; - }; /// Factory to create Digi action objects - DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::DigiAction*,const _ns::K*, std::string) + DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::DigiEventAction*,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); } + /// Factory to create Digi cell scanner objects + DD4HEP_PLUGIN_FACTORY_ARGS_1(DS::DigiCellScanner*, dd4hep::SegmentationObject*) + { return new P(dd4hep::Segmentation(a0)); } } /// Plugin defintion to create DigiAction objects -#define DECLARE_DIGIACTION_NS(name_space,name) namespace {\ +#define DECLARE_DIGIEVENTACTION_NS(name_space,name) namespace {\ using name_space::name; \ - DD4HEP_PLUGINSVC_FACTORY(name,name,dd4hep::digi::DigiAction*(const _ns::K*,std::string),__LINE__) \ - } - + DD4HEP_PLUGINSVC_FACTORY(name,name,dd4hep::digi::DigiEventAction*(const DS::DigiKernel*,std::string),__LINE__) } /// Plugin defintion to create DigiAction objects -#define DECLARE_DIGIACTION(name) DECLARE_DIGIACTION_NS(dd4hep::digi,name) +#define DECLARE_DIGIEVENTACTION(name) DECLARE_DIGIEVENTACTION_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_DIGICELLSCANNER_NS(name_space,typ,seg,sol) namespace { \ +typedef name_space :: CellScanner<dd4hep:: seg , dd4hep:: sol > Scanner_##typ##_##seg##_##sol##_t; \ + DD4HEP_PLUGINSVC_FACTORY( Scanner_##typ##_##seg##_##sol##_t, typ##_##seg##_##sol , \ + dd4hep::digi::DigiCellScanner*(dd4hep::SegmentationObject*),__LINE__) } + +/// Plugin defintion to create DigiCellscanner objects +#define DECLARE_DIGICELLSCANNER(typ,seg,sol) DECLARE_DIGICELLSCANNER_NS(dd4hep::digi,typ,seg,sol) #endif // DDG4_DIGI_DIGIFACTORIES_H diff --git a/DDDigi/include/DDDigi/DigiHandle.h b/DDDigi/include/DDDigi/DigiHandle.h index 13ec8cacdb3392f369359933933752b7acd29a3c..df52df6bea3e3057e8c4d22e9b4afeb966f523f6 100644 --- a/DDDigi/include/DDDigi/DigiHandle.h +++ b/DDDigi/include/DDDigi/DigiHandle.h @@ -30,6 +30,8 @@ namespace dd4hep { /// Forward declarations class DigiKernel; class DigiAction; + class DigiEventAction; + class DigiSignalProcessor; /// Handle to Digi actions with built-in creation mechanism /** diff --git a/DDDigi/include/DDDigi/DigiInputAction.h b/DDDigi/include/DDDigi/DigiInputAction.h index 5ed83e10fd297c11a47e1ed45053c229667543fb..a6c7f7444b29a19668e2f0b35c8ad43ef0137909 100644 --- a/DDDigi/include/DDDigi/DigiInputAction.h +++ b/DDDigi/include/DDDigi/DigiInputAction.h @@ -14,7 +14,7 @@ #define DD4HEP_DDDIGI_DIGIINPUTACTION_H /// Framework include files -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -33,7 +33,7 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiInputAction : public DigiAction { + class DigiInputAction : public DigiEventAction { protected: /// Input data specification std::vector<std::string> m_input; diff --git a/DDDigi/include/DDDigi/DigiKernel.h b/DDDigi/include/DDDigi/DigiKernel.h index f652aa2e6d82139c7a692ff543b41a52d737789a..059280e474eece8734dd835a6f5f8135e02c7a29 100644 --- a/DDDigi/include/DDDigi/DigiKernel.h +++ b/DDDigi/include/DDDigi/DigiKernel.h @@ -14,13 +14,11 @@ #define DD4HEP_DDDIGI_DIGIKERNEL_H // Framework include files -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" // C/C++ include files -#include <map> #include <mutex> #include <atomic> -#include <typeinfo> /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -135,9 +133,9 @@ namespace dd4hep { /// Access to the main output action sequence from the kernel object DigiActionSequence& outputAction() const; /// Submit a bunch of actions to be executed in parallel - virtual void submit (const DigiAction::Actors<DigiAction>& algorithms, DigiContext& context) const; + virtual void submit (const DigiAction::Actors<DigiEventAction>& algorithms, DigiContext& context) const; /// Submit a bunch of actions to be executed serially - virtual void execute(const DigiAction::Actors<DigiAction>& algorithms, DigiContext& context) const; + virtual void execute(const DigiAction::Actors<DigiEventAction>& algorithms, DigiContext& context) const; virtual void wait(DigiContext& context) const; }; /// Declare property diff --git a/DDDigi/include/DDDigi/DigiLockedAction.h b/DDDigi/include/DDDigi/DigiLockedAction.h index c38ca7231559b71f6b96a1391da580d789cdab23..eddfdbd0cf9be9994f731a16a384c1f10cb2c113 100644 --- a/DDDigi/include/DDDigi/DigiLockedAction.h +++ b/DDDigi/include/DDDigi/DigiLockedAction.h @@ -14,7 +14,7 @@ #define DD4HEP_DDDIGI_DIGILOCKEDACTION_H /// Framework include files -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" /// C/C++ include files #include <mutex> @@ -36,12 +36,12 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiLockedAction : public DigiAction { + class DigiLockedAction : public DigiEventAction { protected: /// Action lock to inhibit calling the non-reentrant underlying std::mutex m_lock; /// Reference to underlying action - DigiAction* m_action = 0; + DigiEventAction* m_action = 0; protected: /// Define standard assignments and constructors @@ -53,7 +53,7 @@ namespace dd4hep { /// Default destructor virtual ~DigiLockedAction(); /// Underlying object to be used during the locked execution - void use(DigiAction* action); + void use(DigiEventAction* action); /// Callback to read event locked virtual void execute(DigiContext& context) const override; }; diff --git a/DDDigi/include/DDDigi/DigiSegmentation.h b/DDDigi/include/DDDigi/DigiSegmentation.h new file mode 100644 index 0000000000000000000000000000000000000000..d72c1d1ac2c7a1c5ebe2079923708d6aaae397a3 --- /dev/null +++ b/DDDigi/include/DDDigi/DigiSegmentation.h @@ -0,0 +1,64 @@ +//========================================================================== +// 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_DDDIGI_DIGISEGMENTATION_H +#define DD4HEP_DDDIGI_DIGISEGMENTATION_H + +/// Framework include files +#include <DD4hep/Segmentations.h> +#include <DD4hep/Volumes.h> +#include <DD4hep/Shapes.h> + +/// C/C++ include files +#include <functional> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + // Forward declarations + + struct CellDataBase { + CellID cell_id {0}; + PlacedVolume placement; + Volume volume; + Solid solid; + }; + template <typename SEGMENTATION> struct cell_data; + template <typename SEGMENTATION> struct segmentation_data; + + template <typename SEGMENTATION> + void init_segmentation_data(segmentation_data<SEGMENTATION>& data, const Segmentation& seg); + + /// + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + struct DigiCellScanner { + public: + typedef std::function<void(const DigiCellScanner& env, const CellDataBase&)> cell_handler_t; + public: + DigiCellScanner() = default; + virtual ~DigiCellScanner() = default; + virtual void operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) = 0; + }; + std::shared_ptr<DigiCellScanner> create_cell_scanner(Solid solid, Segmentation segment); + std::shared_ptr<DigiCellScanner> create_cell_scanner(const std::string& typ, Segmentation segment); + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGISEGMENTATION_H diff --git a/DDDigi/include/DDDigi/DigiSignalProcessor.h b/DDDigi/include/DDDigi/DigiSignalProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..fc7298d46a5f9507fefd741d8d31e27689524cde --- /dev/null +++ b/DDDigi/include/DDDigi/DigiSignalProcessor.h @@ -0,0 +1,56 @@ +//========================================================================== +// 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_DDDIGI_DIGISIGNALPROCESSOR_H +#define DD4HEP_DDDIGI_DIGISIGNALPROCESSOR_H + +/// Framework include files +#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiData.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + // Forward declarations + class DigiAction; + class DigiCellData; + class DigiSignalProcessor; + + /// Base class for signal processing actions to the digitization + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiSignalProcessor : public DigiAction { + protected: + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSignalProcessor); + + /// Main functional callback + virtual void execute(DigiContext&) const {} + + public: + /// Standard constructor + DigiSignalProcessor(const DigiKernel& kernel, const std::string& nam); + /// Default destructor + virtual ~DigiSignalProcessor(); + /// Callback to read event signalprocessor + virtual double operator()(const DigiCellData& data) const = 0; + }; + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGISIGNALPROCESSOR_H diff --git a/DDDigi/include/DDDigi/DigiSignalProcessorSequence.h b/DDDigi/include/DDDigi/DigiSignalProcessorSequence.h new file mode 100644 index 0000000000000000000000000000000000000000..0a55aea2b5172dd526ba6d224d450a9715c6cc49 --- /dev/null +++ b/DDDigi/include/DDDigi/DigiSignalProcessorSequence.h @@ -0,0 +1,65 @@ +//========================================================================== +// 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_DDDIGI_DIGISIGNALPROCESSORSEQUENCE_H +#define DD4HEP_DDDIGI_DIGISIGNALPROCESSORSEQUENCE_H + +// Framework include files +#include "DDDigi/DigiSignalProcessor.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + // Forward declarations + class DigiSignalProcessor; + class DigiSignalProcessorSequence; + + /// Concrete implementation of the Digitization event action sequence + /** + * The sequence dispatches the callbacks to all registered DigiAction + * members and all registered callbacks. + * + * Note Multi-Threading issue: + * Neither callbacks not the action list is protected against multiple + * threads calling the Digi callbacks! + * These must be protected in the user actions themselves. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiSignalProcessorSequence : public DigiSignalProcessor { + protected: + /// The list of action objects to be called + Actors<DigiSignalProcessor> m_actors; + + protected: + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSignalProcessorSequence); + + public: + /// Standard constructor + DigiSignalProcessorSequence(const DigiKernel& kernel, const std::string& nam); + /// Default destructor + virtual ~DigiSignalProcessorSequence(); + /// Adopt a new action as part of the sequence. Sequence takes ownership. + void adopt(DigiSignalProcessor* action); + /// Begin-of-event callback + virtual double operator()(const DigiCellData& data) const override; + }; + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGISIGNALPROCESSORSEQUENCE_H diff --git a/DDDigi/include/DDDigi/DigiSubdetectorSequence.h b/DDDigi/include/DDDigi/DigiSubdetectorSequence.h new file mode 100644 index 0000000000000000000000000000000000000000..096658f9e68d3c1021b3194df44050e8bae4c158 --- /dev/null +++ b/DDDigi/include/DDDigi/DigiSubdetectorSequence.h @@ -0,0 +1,110 @@ +//========================================================================== +// 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_DDDIGI_DIGISUBDETECTORSEQUENCE_H +#define DD4HEP_DDDIGI_DIGISUBDETECTORSEQUENCE_H + +// Framework include files +#include <DDDigi/DigiActionSequence.h> +#include <DDDigi/DigiSegmentation.h> +#include <DD4hep/DetElement.h> +#include <DD4hep/Any.h> + +/// C/C++ include files +#include <functional> +#include <map> + +class TClass; + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + class CartesianGridXY; + class CartesianGridXYZ; + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + // Forward declarations + class DigiCellScanner; + class CellDataBase; + class DigiEventAction; + class DigiSubdetectorSequence; + + /// Concrete implementation of the Digitization event action sequence + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiSubdetectorSequence : public DigiActionSequence { + protected: + struct Context { + DetElement detector; + VolumeID detector_id; + VolumeID reverse_id; + VolumeID detector_mask; + std::shared_ptr<DigiCellScanner> scanner; + Context(DetElement de, VolumeID vid, VolumeID rid, VolumeID mask) + : detector(de), detector_id(vid), reverse_id(rid), detector_mask(mask) {} + Context() = delete; + Context(Context&& copy) = default; + Context(const Context& copy) = default; + Context& operator=(Context&& copy) = default; + Context& operator=(const Context& copy) = default; + }; + + typedef std::map<std::pair<const TClass*,Segmentation>, std::shared_ptr<DigiCellScanner> > Scanners; + std::string m_detectorName; + std::string m_segmentName; + SensitiveDetector m_sensDet; + DetElement m_detector; + IDDescriptor m_idDesc; + Segmentation m_segmentation; + std::map<DetElement, VolumeID> m_parallelDet; + std::map<VolumeID, Context> m_parallelVid; + Scanners m_scanners; + + std::function<void(const DigiCellScanner&, const CellDataBase&)> m_cellHandler; + + protected: + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSubdetectorSequence); + + /// Access subdetector from the detector description + DetElement subdetector(const std::string& name) const; + + /// Access sensitive detector from the detector description + SensitiveDetector sensitiveDetector(const std::string& nam) const; + + typedef PlacedVolume::VolIDs VolIDs; + + void process_cell(const DigiCellScanner& , const CellDataBase& data) const; + void scan_detector(DetElement de, VolumeID vid, VolumeID mask); + void scan_sensitive(PlacedVolume pv, VolumeID vid, VolumeID mask); + void process_context(const Context& c, PlacedVolume pv, VolumeID vid, VolumeID mask) const; + + public: + /// Standard constructor + DigiSubdetectorSequence(const DigiKernel& kernel, const std::string& nam); + /// Default destructor + virtual ~DigiSubdetectorSequence(); + /// Iniitalize subdetector sequencer + virtual void initialize(); + /// Begin-of-event callback + virtual void execute(DigiContext& context) const override; + }; + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGISUBDETECTORSEQUENCE_H diff --git a/DDDigi/include/DDDigi/DigiSynchronize.h b/DDDigi/include/DDDigi/DigiSynchronize.h index eb76a1e225ce771c91056ca730776615db350db1..eb7bf772842d38926cf01c6c6ab27385d570e4b1 100644 --- a/DDDigi/include/DDDigi/DigiSynchronize.h +++ b/DDDigi/include/DDDigi/DigiSynchronize.h @@ -14,7 +14,7 @@ #define DD4HEP_DDDIGI_DIGISYNCHRONIZE_H // Framework incloude files -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -31,10 +31,10 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiSynchronize : public DigiAction { + class DigiSynchronize : public DigiEventAction { protected: /// The list of action objects to be called - Actors<DigiAction> m_actors; + Actors<DigiEventAction> m_actors; protected: /// Define standard assignments and constructors @@ -46,13 +46,13 @@ namespace dd4hep { /// Default destructor virtual ~DigiSynchronize(); /// Get an action member by name - DigiAction* get(const std::string& name) const; + DigiEventAction* get(const std::string& name) const; /// Access the children - const Actors<DigiAction>& children() const { + const Actors<DigiEventAction>& children() const { return m_actors; } /// Adopt a new action as part of the sequence. Sequence takes ownership. - void adopt(DigiAction* action); + void adopt(DigiEventAction* action); /// Begin-of-event callback virtual void execute(DigiContext& context) const override; /// diff --git a/DDDigi/include/DDDigi/segmentations/CartesianGridXY.h b/DDDigi/include/DDDigi/segmentations/CartesianGridXY.h new file mode 100644 index 0000000000000000000000000000000000000000..a3e8d5b2b49b673bb6e27f71352618d342b124ef --- /dev/null +++ b/DDDigi/include/DDDigi/segmentations/CartesianGridXY.h @@ -0,0 +1,48 @@ +//========================================================================== +// 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_DDDIGI_SEGMENTATION_CARTESIANGRIDXY_H +#define DD4HEP_DDDIGI_SEGMENTATION_CARTESIANGRIDXY_H + +/// Framework include files +#include <DDDigi/DigiSegmentation.h> +#include <DD4hep/CartesianGridXY.h> +#include <DDSegmentation/CartesianGridXY.h> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + template <> struct cell_data<CartesianGridXY> : public CellDataBase { + public: + CellID x_cid {0}, y_cid {0}; + CellID x_bin {0}, y_bin {0}; + }; + + template <> struct segmentation_data<CartesianGridXY> { + public: + DDSegmentation::CartesianGridXY* segmentation_xy {0}; + double x_grid_size {0.0}; + double x_offset {0.0}; + double y_grid_size {0.0}; + double y_offset {0.0}; + CellID x_mask {0}; + CellID y_mask {0}; + int x_f_offset {0}; + int y_f_offset {0}; + }; + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_SEGMENTATION_CARTESIANGRIDXY_H diff --git a/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h b/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h new file mode 100644 index 0000000000000000000000000000000000000000..83fd67d7646d8fdec827373f12b4c1f2eac86b5d --- /dev/null +++ b/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h @@ -0,0 +1,50 @@ +//========================================================================== +// 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_DDDIGI_SEGMENTATION_CARTESIANGRIDXYZ_H +#define DD4HEP_DDDIGI_SEGMENTATION_CARTESIANGRIDXYZ_H + +/// Framework include files +#include <DDDigi/DigiSegmentation.h> +#include <DD4hep/CartesianGridXYZ.h> +#include <DDSegmentation/CartesianGridXYZ.h> + +/// C/C++ include files +#include <functional> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + template <> struct cell_data<CartesianGridXYZ> : public CellDataBase { + public: + CellID x_cid {0}, y_cid {0}, z_cid {0}; + CellID x_bin {0}, y_bin {0}, z_bin {0}; + }; + + template <> struct segmentation_data<CartesianGridXYZ> { + public: + DDSegmentation::CartesianGridXYZ* segmentation_xyz {0}; + double x_grid_size {0.0}, x_offset {0.0}; + double y_grid_size {0.0}, y_offset {0.0}; + double z_grid_size {0.0}, z_offset {0.0}; + CellID x_mask {0}; + CellID y_mask {0}; + CellID z_mask {0}; + int x_f_offset {0}, y_f_offset {0}, z_f_offset {0}; + }; + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_SEGMENTATION_CARTESIANGRIDXYZ_H diff --git a/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h b/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h new file mode 100644 index 0000000000000000000000000000000000000000..ac769fdf987c9ad98fb0175bf01e5bd5210229da --- /dev/null +++ b/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h @@ -0,0 +1,50 @@ +//========================================================================== +// 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_DDDIGI_SEGMENTATIONSCANNER_H +#define DD4HEP_DDDIGI_SEGMENTATIONSCANNER_H + +/// Framework include files +#include <DDDigi/DigiSegmentation.h> +#include <DDDigi/DigiFactories.h> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + /// + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + template <typename SEGMENTATION, typename SOLID> struct CellScanner : public DigiCellScanner { + public: + typedef SOLID solid_t; + typedef SEGMENTATION segmentation_t; + typedef CellScanner<segmentation_t, solid_t> self_t; + typedef cell_data<segmentation_t> cell_data_t; + typedef segmentation_data<segmentation_t> segmentation_data_t; + typedef DigiCellScanner::cell_handler_t cell_handler_t; + + segmentation_data_t segment; + CellScanner(segmentation_t seg) { + init_segmentation_data<segmentation_t>(segment, seg); + } + virtual void operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) override; + }; + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_SEGMENTATIONSCANNER_H diff --git a/DDDigi/plugins/CellScanner_CartesianGridXY.cpp b/DDDigi/plugins/CellScanner_CartesianGridXY.cpp new file mode 100644 index 0000000000000000000000000000000000000000..627be9d9ee69fb3cc0ed1d06076ea5fd8550c28d --- /dev/null +++ b/DDDigi/plugins/CellScanner_CartesianGridXY.cpp @@ -0,0 +1,163 @@ +//========================================================================== +// 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/Printout.h> +#include <DD4hep/detail/SegmentationsInterna.h> +#include <DDDigi/segmentations/CartesianGridXY.h> +#include <DDDigi/segmentations/SegmentationScanner.h> + + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + template <typename SEGMENTATION, typename SOLID> void + CellScanner<SEGMENTATION,SOLID>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) { + typename self_t::cell_data_t e; + e.placement = pv; + e.volume = pv.volume(); + e.solid = e.volume.solid(); + Box b = e.solid; + double pos[3] = {0e0, 0e0, 0e0}; + typename self_t::solid_t sol = e.solid; + long nx = 2e0 * b->GetDX() / segment.x_grid_size; + long ny = 2e0 * b->GetDY() / segment.y_grid_size; + for ( e.x_bin = 0; e.x_bin < nx; ++e.x_bin ) { + pos[0] = (e.x_bin + 0.5) * segment.x_grid_size; + e.x_cid = (e.x_bin << segment.x_f_offset) & segment.x_mask; + for ( e.y_bin = 0; e.y_bin < ny; ++e.y_bin ) { + pos[1] = (e.x_bin + 0.5) * segment.x_grid_size; + if ( !sol->Contains(pos) ) continue; + e.y_cid = (e.y_bin << segment.y_f_offset) & segment.y_mask; + e.cell_id = vid | e.x_cid | e.y_cid; + cell_handler(*this, e); + } + } + } + } // End namespace digi +} // End namespace dd4hep + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + template <> + void init_segmentation_data<CartesianGridXY>(segmentation_data<CartesianGridXY>& data, + const Segmentation& seg) + { + CartesianGridXYHandle xy_seg = seg; + const auto& x_f = (*seg.decoder())["x"]; + const auto& y_f = (*seg.decoder())["y"]; + data.segmentation_xy = xy_seg->implementation; + data.x_grid_size = data.segmentation_xy->gridSizeX(); + data.y_grid_size = data.segmentation_xy->gridSizeY(); + data.x_offset = data.segmentation_xy->offsetX(); + data.y_offset = data.segmentation_xy->offsetY(); + data.x_f_offset = x_f.offset(); + data.y_f_offset = y_f.offset(); + data.x_mask = x_f.mask(); + data.y_mask = y_f.mask(); + } + + template <> void + CellScanner<CartesianGridXY,Box>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) + { + cell_data_t e; + e.placement = pv; + e.volume = pv.volume(); + e.solid = e.volume.solid(); + Box b = e.solid; + long nx = 2e0 * b->GetDX() / segment.x_grid_size; + long ny = 2e0 * b->GetDY() / segment.y_grid_size; + for ( e.x_bin = 0; e.x_bin < nx; ++e.x_bin ) { + e.x_cid = (e.x_bin << segment.x_f_offset) & segment.x_mask; + for ( e.y_bin = 0; e.y_bin < ny; ++e.y_bin ) { + e.y_cid = (e.y_bin << segment.y_f_offset) & segment.y_mask; + e.cell_id = vid | e.x_cid | e.y_cid; + cell_handler(*this, e); + } + } + } + } // End namespace digi +} // End namespace dd4hep + +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Box) + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + template <typename self_t> void + scan_poly(PlacedVolume pv, VolumeID vid, const typename self_t::cell_handler_t& cell_handler, const self_t& scanner) { + typename self_t::cell_data_t e; + const auto& segment = scanner.segment; + e.placement = pv; + e.volume = pv.volume(); + e.solid = e.volume.solid(); + Box b = e.solid; + typename self_t::solid_t h = e.solid; + long nx = 2e0 * b->GetDX() / segment.x_grid_size; + long ny = 2e0 * b->GetDY() / segment.y_grid_size; + double pos[3] = {0e0, 0e0, 0e0}, r; + double rmin = h->GetRmin(0) * h->GetRmin(0); + double rmax = h->GetRmax(0) * h->GetRmax(0); + + for ( e.x_bin = 0; e.x_bin < nx; ++e.x_bin ) { + pos[0] = (e.x_bin + 0.5) * segment.x_grid_size; + pos[0] *= pos[0]; + if ( pos[0] > rmax ) continue; + e.x_cid = (e.x_bin << segment.x_f_offset) & segment.x_mask; + for ( e.y_bin = 0; e.y_bin < ny; ++e.y_bin ) { + pos[1] = (e.x_bin + 0.5) * segment.x_grid_size; + r = pos[0]*pos[0] + pos[1]*pos[1]; + if ( r < rmin || r > rmax ) continue; + if ( !h->Contains(pos) ) continue; + e.y_cid = (e.y_bin << segment.y_f_offset) & segment.y_mask; + e.cell_id = vid | e.x_cid | e.y_cid; + cell_handler(scanner, e); + } + } + } + + template <> void + CellScanner<CartesianGridXY,PolyhedraRegular>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) { + scan_poly<self_t>(pv, vid, cell_handler, *this); + } + template <> void + CellScanner<CartesianGridXY,Polyhedra>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) { + scan_poly<self_t>(pv, vid, cell_handler, *this); + } + template <> void + CellScanner<CartesianGridXY,Polycone>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) { + scan_poly<self_t>(pv, vid, cell_handler, *this); + } + } // End namespace digi +} // End namespace dd4hep + +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,PolyhedraRegular) +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Polyhedra) +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Polycone) + +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Polycone) +namespace dd4hep { + typedef IntersectionSolid Intersection; + typedef SubtractionSolid Subtraction; + typedef UnionSolid Union; +} +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Intersection) +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Subtraction) +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXY,Union) diff --git a/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp b/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp new file mode 100644 index 0000000000000000000000000000000000000000..815254e728adff160ed15e995e0eed650a2272f1 --- /dev/null +++ b/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp @@ -0,0 +1,74 @@ +//========================================================================== +// 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/detail/SegmentationsInterna.h> +#include <DDDigi/segmentations/CartesianGridXYZ.h> +#include <DDDigi/segmentations/SegmentationScanner.h> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + template <> + void init_segmentation_data<CartesianGridXYZ>(segmentation_data<CartesianGridXYZ>& data, + const Segmentation& seg) + { + CartesianGridXYZHandle xyz_seg = seg; + const auto& x_f = (*seg.decoder())["x"]; + const auto& y_f = (*seg.decoder())["y"]; + const auto& z_f = (*seg.decoder())["z"]; + data.segmentation_xyz = xyz_seg->implementation; + data.x_grid_size = data.segmentation_xyz->gridSizeX(); + data.y_grid_size = data.segmentation_xyz->gridSizeY(); + data.z_grid_size = data.segmentation_xyz->gridSizeZ(); + data.x_offset = data.segmentation_xyz->offsetX(); + data.y_offset = data.segmentation_xyz->offsetY(); + data.z_offset = data.segmentation_xyz->offsetZ(); + data.x_f_offset = x_f.offset(); + data.y_f_offset = y_f.offset(); + data.z_f_offset = z_f.offset(); + data.x_mask = x_f.mask(); + data.y_mask = y_f.mask(); + data.z_mask = z_f.mask(); + } + + template <> void + CellScanner<CartesianGridXYZ,Box>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler) + { + cell_data_t e; + e.placement = pv; + e.volume = pv.volume(); + e.solid = e.volume.solid(); + Box b = e.solid; + long nx = 2e0 * b->GetDX() / segment.x_grid_size; + long ny = 2e0 * b->GetDY() / segment.y_grid_size; + long nz = 2e0 * b->GetDZ() / segment.z_grid_size; + for ( e.x_bin=0; e.x_bin < nx; ++e.x_bin ) { + e.x_cid = (e.x_bin << segment.x_f_offset) & segment.x_mask; + for ( e.y_bin=0; e.y_bin < ny; ++e.y_bin ) { + e.y_cid = (e.y_bin << segment.y_f_offset) & segment.y_mask; + for ( e.z_bin=0; e.z_bin < nz; ++e.z_bin ) { + e.z_cid = (e.z_bin << segment.z_f_offset) & segment.z_mask; + e.cell_id = vid | e.x_cid | e.y_cid | e.y_cid; + cell_handler(*this, e); + } + } + } + } + } // End namespace digi +} // End namespace dd4hep + +DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Box) diff --git a/DDDigi/plugins/Components.cpp b/DDDigi/plugins/Components.cpp index b34f3609ed4baa9dd88d01732e9258117c0a99e4..7ed029637c7eb3e552f9024fd63c9c48e57ab1ec 100644 --- a/DDDigi/plugins/Components.cpp +++ b/DDDigi/plugins/Components.cpp @@ -22,16 +22,23 @@ #include <sstream> #include "DDDigi/DigiInputAction.h" -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiInputAction) +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiInputAction) + +#include "DDDigi/DigiSynchronize.h" +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiSynchronize) #include "DDDigi/DigiActionSequence.h" -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiActionSequence) +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiActionSequence) -#include "DDDigi/DigiSynchronize.h" -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiSynchronize) +#include "DDDigi/DigiSubdetectorSequence.h" +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiSubdetectorSequence) #include "DDDigi/DigiLockedAction.h" -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiLockedAction) +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiLockedAction) + +#include "DDDigi/DigiSignalProcessorSequence.h" +DECLARE_DIGISIGNALPROCESSOR_NS(dd4hep::digi,DigiSignalProcessorSequence) + using namespace std; using namespace dd4hep; diff --git a/DDDigi/plugins/DigiRandomNoise.cpp b/DDDigi/plugins/DigiRandomNoise.cpp index 5df242a4c8c6a6e50df82038c63eb6a2b7002f2e..93427ae893aa097efbcbc89cc744652349df3e39 100644 --- a/DDDigi/plugins/DigiRandomNoise.cpp +++ b/DDDigi/plugins/DigiRandomNoise.cpp @@ -14,7 +14,7 @@ #define DD4HEP_DDDIGI_DIGIRANDOMNOISE_H // Framework include files -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -35,7 +35,7 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiRandomNoise : public DigiAction { + class DigiRandomNoise : public DigiEventAction { protected: double m_probability = 1.0; double m_amplitude = 1.0; @@ -85,11 +85,11 @@ namespace dd4hep { using namespace std; using namespace dd4hep::digi; -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiRandomNoise) +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiRandomNoise) /// Standard constructor DigiRandomNoise::DigiRandomNoise(const DigiKernel& kernel, const string& nam) - : DigiAction(kernel, nam) + : DigiEventAction(kernel, nam) { declareProperty("Probability", m_probability); declareProperty("Amplitude", m_amplitude); diff --git a/DDDigi/python/DDDigi.py b/DDDigi/python/DDDigi.py index 7333f6a838ae495da7ff4eb8a5d25771626311d4..2ef3316c5886f82adad2ea7d0942480cecd8b62f 100644 --- a/DDDigi/python/DDDigi.py +++ b/DDDigi/python/DDDigi.py @@ -169,9 +169,15 @@ def Action(kernel, nam, parallel=False): return obj # --------------------------------------------------------------------------- +def EventAction(kernel, nam, parallel=False): + obj = Interface.createEventAction(kernel, str(nam)) + obj.parallel = parallel + return obj +# --------------------------------------------------------------------------- + def TestAction(kernel, nam, sleep=0): - obj = Interface.createAction(kernel, str('DigiTestAction/' + nam)) + obj = Interface.createEventAction(kernel, str('DigiTestAction/' + nam)) if sleep != 0: obj.sleep = sleep return obj diff --git a/DDDigi/python/DDDigiDict.C b/DDDigi/python/DDDigiDict.C index 68e153eda559b426ef91f8e6e57c8712661a95d5..3edc28d41c1fd8d2779bee82646cf5cf8d4fa41e 100644 --- a/DDDigi/python/DDDigiDict.C +++ b/DDDigi/python/DDDigiDict.C @@ -37,6 +37,7 @@ #include "DDDigi/DigiContext.h" #include "DDDigi/DigiSynchronize.h" #include "DDDigi/DigiActionSequence.h" +#include "DDDigi/DigiSignalProcessor.h" struct DDDigiDict {}; @@ -58,7 +59,9 @@ namespace dd4hep { Digi##x* get() const { return action; } \ } + ACTIONHANDLE(SignalProcessor); ACTIONHANDLE(Action); + ACTIONHANDLE(EventAction); ACTIONHANDLE(ActionSequence); ACTIONHANDLE(Synchronize); @@ -80,6 +83,8 @@ namespace dd4hep { } static ActionHandle createAction(KernelHandle& kernel, const std::string& name_type) { return cr<ActionHandle,DigiHandle<DigiAction> >(kernel,name_type); } + static EventActionHandle createEventAction(KernelHandle& kernel, const std::string& name_type) + { return cr<EventActionHandle,DigiHandle<DigiEventAction> >(kernel,name_type); } static ActionSequenceHandle createSequence(KernelHandle& kernel, const std::string& name_type) { return cr<ActionSequenceHandle,DigiHandle<DigiActionSequence> >(kernel,name_type); } static SynchronizeHandle createSync(KernelHandle& kernel, const std::string& name_type) @@ -88,10 +93,12 @@ namespace dd4hep { static DigiAction* toAction(DigiAction* f) { return f; } static DigiAction* toAction(DigiActionSequence* f) { return f; } static DigiAction* toAction(DigiSynchronize* f) { return f; } + static DigiAction* toAction(DigiSignalProcessor* f) { return f; } static DigiAction* toAction(ActionHandle f) { return f.action; } static DigiAction* toAction(ActionSequenceHandle f) { return f.action; } static DigiAction* toAction(SynchronizeHandle f) { return f.action; } + static DigiAction* toAction(SignalProcessorHandle f) { return f.action; } static PropertyResult getProperty(DigiAction* action, const std::string& name) { if ( action->hasProperty(name) ) { @@ -136,19 +143,27 @@ using namespace std; #pragma link C++ namespace dd4hep::digi; #pragma link C++ class dd4hep::digi::DigiActionCreation; -#pragma link C++ class dd4hep::digi::KernelHandle; -#pragma link C++ class dd4hep::digi::DigiKernel; #pragma link C++ class dd4hep::digi::DigiContext; +#pragma link C++ class dd4hep::digi::DigiKernel; +#pragma link C++ class dd4hep::digi::KernelHandle; + #pragma link C++ class dd4hep::digi::DigiAction; #pragma link C++ class dd4hep::digi::ActionHandle; +#pragma link C++ class dd4hep::digi::DigiEventAction; +#pragma link C++ class dd4hep::digi::EventActionHandle; + #pragma link C++ class dd4hep::digi::DigiActionSequence; #pragma link C++ class dd4hep::digi::ActionSequenceHandle; #pragma link C++ class dd4hep::digi::DigiSynchronize; #pragma link C++ class dd4hep::digi::SynchronizeHandle; +#pragma link C++ class dd4hep::digi::DigiSignalProcessor; +#pragma link C++ class dd4hep::digi::SignalProcessorHandle; + +/// Digi data item wrappers #pragma link C++ class dd4hep::digi::DigiEvent; #pragma link C++ class dd4hep::digi::DigiEnergyDeposits+; #pragma link C++ class dd4hep::digi::DigiCounts+; diff --git a/DDDigi/src/DigiAction.cpp b/DDDigi/src/DigiAction.cpp index adc16b1e2b8295777f72640af2af782e6d5a651f..401e27fe8e95ece6924295e8839954997ea20e2d 100644 --- a/DDDigi/src/DigiAction.cpp +++ b/DDDigi/src/DigiAction.cpp @@ -44,7 +44,6 @@ DigiAction::DigiAction(const DigiKernel& krnl, const string& nam) InstanceCount::increment(this); declareProperty("Name", m_name); declareProperty("name", m_name); - declareProperty("parallel", m_parallel); declareProperty("OutputLevel", m_outputLevel); } @@ -76,13 +75,6 @@ PrintLevel DigiAction::setOutputLevel(PrintLevel new_level) { return (PrintLevel)old; } -/// Set the parallization flag; returns previous value -bool DigiAction::setExecuteParallel(bool new_value) { - bool old = m_parallel; - m_parallel = new_value; - return old; -} - /// Check property for existence bool DigiAction::hasProperty(const string& nam) const { return m_properties.exists(nam); @@ -206,3 +198,8 @@ void DigiAction::except(const char* fmt, ...) const { va_end(args); throw runtime_error(err); } + +/// Optional action initialization if required +void DigiAction::initialize() { +} + diff --git a/DDDigi/src/DigiActionSequence.cpp b/DDDigi/src/DigiActionSequence.cpp index 31cf428d2a32883b517d761e7e1a12c7718cffd0..b98370dcf4d598a25fe4dc94b777df9e9eff9312 100644 --- a/DDDigi/src/DigiActionSequence.cpp +++ b/DDDigi/src/DigiActionSequence.cpp @@ -36,7 +36,7 @@ DigiActionSequence::~DigiActionSequence() { } /// Adopt a new action as part of the sequence. Sequence takes ownership. -void DigiActionSequence::adopt(DigiAction* action) { +void DigiActionSequence::adopt(DigiEventAction* action) { this->DigiSynchronize::adopt(action); } diff --git a/DDDigi/src/DigiEventAction.cpp b/DDDigi/src/DigiEventAction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c1eb5c62ac7749bd766fb08cdabb7839cddd89f --- /dev/null +++ b/DDDigi/src/DigiEventAction.cpp @@ -0,0 +1,37 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/InstanceCount.h" +#include "DDDigi/DigiEventAction.h" + +/// Standard constructor +dd4hep::digi::DigiEventAction::DigiEventAction(const DigiKernel& krnl, const std::string& nam) + : DigiAction(krnl, nam) +{ + InstanceCount::increment(this); + declareProperty("parallel", m_parallel); +} + +/// Default destructor +dd4hep::digi::DigiEventAction::~DigiEventAction() { + InstanceCount::decrement(this); +} + +/// Set the parallization flag; returns previous value +bool dd4hep::digi::DigiEventAction::setExecuteParallel(bool new_value) { + bool old = m_parallel; + m_parallel = new_value; + return old; +} + diff --git a/DDDigi/src/DigiHandle.cpp b/DDDigi/src/DigiHandle.cpp index 09500703d63507757de98489976f6ee8e4ba33da..4dc7bf3eb37eecfa37609e226af4bd7fd492f295 100644 --- a/DDDigi/src/DigiHandle.cpp +++ b/DDDigi/src/DigiHandle.cpp @@ -18,7 +18,8 @@ #include "DDDigi/DigiHandle.h" #include "DDDigi/DigiKernel.h" -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" +#include "DDDigi/DigiSignalProcessor.h" // C/C++ include files #include <stdexcept> @@ -57,31 +58,36 @@ namespace dd4hep { handle.value = 0; } + template <typename T> T* _raw_create(const std::string& t, const DigiKernel& kernel, const std::string& n) { + DigiEventAction* object = PluginService::Create<DigiEventAction*>(t, &kernel, n); + return object ? dynamic_cast<T*>(object) : nullptr; + } + template <> DigiAction* _raw_create<DigiAction>(const std::string& t, const DigiKernel& kernel, const std::string& n) { + return PluginService::Create<DigiAction*>(t, &kernel, n); + } + template <> DigiSignalProcessor* _raw_create<DigiSignalProcessor>(const std::string& t, const DigiKernel& kernel, const std::string& n) { + return PluginService::Create<DigiSignalProcessor*>(t, &kernel, n); + } template <typename TYPE> TYPE* _create_object(const DigiKernel& kernel, const TypeName& typ) { - DigiAction* object = PluginService::Create<DigiAction*>(typ.first, &kernel, typ.second); + TYPE* object = _raw_create<TYPE>(typ.first, kernel, typ.second); if (!object && typ.first == typ.second) { string _t = typeName(typeid(TYPE)); printout(DEBUG, "DigiHandle", "Object factory for %s not found. Try out %s", typ.second.c_str(), _t.c_str()); - object = PluginService::Create<DigiAction*>(_t, &kernel, typ.second); + object = _raw_create<TYPE>(_t, kernel, typ.second); if (!object) { size_t idx = _t.rfind(':'); if (idx != string::npos) _t = string(_t.substr(idx + 1)); printout(DEBUG, "DigiHandle", "Try out object factory for %s",_t.c_str()); - object = PluginService::Create<DigiAction*>(_t, &kernel, typ.second); + object = _raw_create<TYPE>(_t, kernel, typ.second); } } if (object) { - TYPE* ptr = dynamic_cast<TYPE*>(object); - if (ptr) { - return ptr; - } - except("DigiHandle", "Failed to convert object of type %s to handle of type %s!", - typ.first.c_str(),typ.second.c_str()); + return object; } except("DigiHandle", "Failed to create object of type %s!", typ.first.c_str()); - return 0; + return nullptr; } template <typename TYPE> @@ -184,7 +190,9 @@ namespace dd4hep { /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { template class DigiHandle<DigiAction>; + template class DigiHandle<DigiEventAction>; template class DigiHandle<DigiSynchronize>; template class DigiHandle<DigiActionSequence>; + template class DigiHandle<DigiSignalProcessor>; } } diff --git a/DDDigi/src/DigiInputAction.cpp b/DDDigi/src/DigiInputAction.cpp index b3604b1f14bff375f439f2dd1b002d311361315b..98b1589a5e3fffb0b4e17e7b8e77b31e35826384 100644 --- a/DDDigi/src/DigiInputAction.cpp +++ b/DDDigi/src/DigiInputAction.cpp @@ -24,7 +24,7 @@ using namespace dd4hep::digi; /// Standard constructor DigiInputAction::DigiInputAction(const DigiKernel& kernel, const string& nam) - : DigiAction(kernel, nam) + : DigiEventAction(kernel, nam) { declareProperty("Input", m_input); InstanceCount::increment(this); diff --git a/DDDigi/src/DigiKernel.cpp b/DDDigi/src/DigiKernel.cpp index c6924a1403e455dd9801c2f6fbe05941179f61b1..d62c6694cf836d93d8581cffe3c4b40dc8162a91 100644 --- a/DDDigi/src/DigiKernel.cpp +++ b/DDDigi/src/DigiKernel.cpp @@ -88,8 +88,8 @@ public: class DigiKernel::Wrapper { public: DigiContext& context; - DigiAction* action = 0; - Wrapper(DigiContext& c, DigiAction* a) + DigiEventAction* action = 0; + Wrapper(DigiContext& c, DigiEventAction* a) : context(c), action(a) {} Wrapper(Wrapper&& copy) = delete; Wrapper(const Wrapper& copy) = default; @@ -266,19 +266,19 @@ DigiActionSequence& DigiKernel::outputAction() const { return *internals->outputAction; } -void DigiKernel::submit(const DigiAction::Actors<DigiAction>& actions, DigiContext& context) const { +void DigiKernel::submit(const DigiAction::Actors<DigiEventAction>& actions, DigiContext& context) const { chrono::system_clock::time_point start = chrono::system_clock::now(); bool parallel = 0 != internals->tbbInit && internals->numThreads>0; #ifdef DD4HEP_USE_TBB if ( parallel ) { tbb::task_group que; - for(auto i=actions.begin(); i!=actions.end(); ++i) + for ( auto* i : actions ) que.run(Wrapper(context, *i)); que.wait(); goto print_stamp; } #endif - actions(&DigiAction::execute,context); + actions(&DigiEventAction::execute,context); goto print_stamp; print_stamp: @@ -288,8 +288,8 @@ void DigiKernel::submit(const DigiAction::Actors<DigiAction>& actions, DigiConte secs.count()); } -void DigiKernel::execute(const DigiAction::Actors<DigiAction>& actions, DigiContext& context) const { - actions(&DigiAction::execute,context); +void DigiKernel::execute(const DigiAction::Actors<DigiEventAction>& actions, DigiContext& context) const { + actions(&DigiEventAction::execute,context); } void DigiKernel::wait(DigiContext& context) const { diff --git a/DDDigi/src/DigiLockedAction.cpp b/DDDigi/src/DigiLockedAction.cpp index 21623e2796cf6bba7ec7d508d7d4ebfdd4ce8d2a..b6dc4997127b9ddd2d3daaf6923889bbb07cab6e 100644 --- a/DDDigi/src/DigiLockedAction.cpp +++ b/DDDigi/src/DigiLockedAction.cpp @@ -24,7 +24,7 @@ using namespace dd4hep::digi; /// Standard constructor DigiLockedAction::DigiLockedAction(const DigiKernel& kernel, const string& nam) - : DigiAction(kernel, nam) + : DigiEventAction(kernel, nam) { InstanceCount::increment(this); } @@ -36,7 +36,7 @@ DigiLockedAction::~DigiLockedAction() { } /// Underlying object to be used during the locked execution -void DigiLockedAction::use(DigiAction* action) { +void DigiLockedAction::use(DigiEventAction* action) { if (action) { action->addRef(); m_properties.adopt(action->properties()); diff --git a/DDDigi/src/DigiSegmentation.cpp b/DDDigi/src/DigiSegmentation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdbedb446794d7d72bc5b616678d212014a8ac7f --- /dev/null +++ b/DDDigi/src/DigiSegmentation.cpp @@ -0,0 +1,43 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include <DDDigi/DigiSegmentation.h> +#include <DD4hep/Segmentations.h> +#include <DD4hep/Printout.h> +#include <DD4hep/Plugins.h> +#include <DD4hep/Shapes.h> + + +std::shared_ptr<dd4hep::digi::DigiCellScanner> +dd4hep::digi::create_cell_scanner(Solid solid, Segmentation segment) { + std::string typ = "DigiCellScanner" + + std::string("_") + segment.type() + + std::string("_") + solid.title(); + return create_cell_scanner(typ, segment); +} + +std::shared_ptr<dd4hep::digi::DigiCellScanner> +dd4hep::digi::create_cell_scanner(const std::string& typ, Segmentation segment) { + using namespace dd4hep; + SegmentationObject* seg = segment.ptr(); + DigiCellScanner* scan = PluginService::Create<DigiCellScanner*>(typ, seg); + if ( !scan ) { + PluginDebug dbg; + PluginService::Create<DigiCellScanner*>(typ, seg); + except("create_cell_scanner", + "Failed to create cell scanner of type %s [%s]", + typ.c_str(),dbg.missingFactory(typ).c_str()); + } + return std::shared_ptr<DigiCellScanner>(scan); +} diff --git a/DDDigi/src/DigiSignalProcessor.cpp b/DDDigi/src/DigiSignalProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3595541e05ef61db395ed9f9dac178790b1e4243 --- /dev/null +++ b/DDDigi/src/DigiSignalProcessor.cpp @@ -0,0 +1,29 @@ +//========================================================================== +// 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/DigiSignalProcessor.h" + +/// Standard constructor +dd4hep::digi::DigiSignalProcessor::DigiSignalProcessor(const DigiKernel& krnl, const std::string& nam) + : DigiAction(krnl, nam) +{ + InstanceCount::increment(this); +} + +/// Default destructor +dd4hep::digi::DigiSignalProcessor::~DigiSignalProcessor() { + InstanceCount::decrement(this); +} + diff --git a/DDDigi/src/DigiSignalProcessorSequence.cpp b/DDDigi/src/DigiSignalProcessorSequence.cpp new file mode 100644 index 0000000000000000000000000000000000000000..388ce9ff5faaf44bfbf0e7ab9eb6465a22165060 --- /dev/null +++ b/DDDigi/src/DigiSignalProcessorSequence.cpp @@ -0,0 +1,51 @@ +//========================================================================== +// 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/DigiSignalProcessorSequence.h" + +// C/C++ include files +#include <stdexcept> + +using namespace dd4hep::digi; + +/// Standard constructor +DigiSignalProcessorSequence::DigiSignalProcessorSequence(const DigiKernel& kernel, const std::string& nam) + : DigiSignalProcessor(kernel, nam) +{ + InstanceCount::increment(this); +} + +/// Default destructor +DigiSignalProcessorSequence::~DigiSignalProcessorSequence() { + InstanceCount::decrement(this); +} + +/// Adopt a new action as part of the sequence. Sequence takes ownership. +void DigiSignalProcessorSequence::adopt(DigiSignalProcessor* action) { + if ( action ) { + action->addRef(); + m_actors.add(action); + return; + } + except("DigiSignalProcessorSequence","++ Attempt to add invalid actor!"); +} + +/// Pre-track action callback +double DigiSignalProcessorSequence::operator()(const DigiCellData& data) const { + double result = data.raw_value; + for ( const auto* p : m_actors ) + result += p->operator()(data); + return data.kill ? 0e0 : result; +} diff --git a/DDDigi/src/DigiSubdetectorSequence.cpp b/DDDigi/src/DigiSubdetectorSequence.cpp new file mode 100644 index 0000000000000000000000000000000000000000..34fc2e6b884685e691ccab6aab16bc65d2cdbd62 --- /dev/null +++ b/DDDigi/src/DigiSubdetectorSequence.cpp @@ -0,0 +1,175 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DDDigi/DigiSubdetectorSequence.h" +#include "DDDigi/DigiSegmentation.h" +#include "DDDigi/DigiKernel.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/Detector.h" +#include "DD4hep/IDDescriptor.h" +#include "DD4hep/detail/VolumeManagerInterna.h" +#include "TClass.h" + +// C/C++ include files +#include <stdexcept> + +using namespace std; +using namespace dd4hep::digi; + +/// Standard constructor +DigiSubdetectorSequence::DigiSubdetectorSequence(const DigiKernel& kernel, const string& nam) + : DigiActionSequence(kernel, nam) +{ + declareProperty("detector",m_detectorName); + declareProperty("parallize_by",m_segmentName); + m_cellHandler = [this](const DigiCellScanner& scanner, const CellDataBase& data) { + this->process_cell(scanner, data); + }; + InstanceCount::increment(this); +} + +/// Default destructor +DigiSubdetectorSequence::~DigiSubdetectorSequence() { + InstanceCount::decrement(this); +} + +/// Iniitalize subdetector sequencer +void DigiSubdetectorSequence::initialize() { + info("Initializing detector sequencer for detector: %s",m_detectorName.c_str()); + m_detector = subdetector(m_detectorName); + m_sensDet = sensitiveDetector(m_detectorName); + m_parallelVid.clear(); + m_parallelDet.clear(); + if ( m_detector.isValid() && m_sensDet.isValid() ) { + m_idDesc = m_sensDet.readout().idSpec(); + m_segmentation = m_sensDet.readout().segmentation(); + const VolIDs& ids = m_detector.placement().volIDs(); + VolumeID vid = m_idDesc.encode(ids); + VolumeID msk = m_idDesc.get_mask(ids); + scan_detector(m_detector, vid, msk); + } +} + +void DigiSubdetectorSequence::scan_sensitive(PlacedVolume pv, VolumeID vid, VolumeID mask) { + Volume vol = pv.volume(); + if ( vol.isSensitive() ) { + VolumeID rid = detail::reverseBits<VolumeID>(vid); + Solid sol = vol.solid(); + auto key = make_pair(sol->IsA(), m_segmentation); + auto is = m_scanners.find(key); + if ( is == m_scanners.end() ) { + is = m_scanners.insert(make_pair(key, create_cell_scanner(sol, m_segmentation))).first; + } + } + for (int idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) { + PlacedVolume p(pv->GetDaughter(idau)); + const VolIDs& new_ids = p.volIDs(); + Volume v = p.volume(); + VolumeID new_vid = vid; + VolumeID new_msk = mask; + if ( !new_ids.empty() ) { + new_vid |= m_idDesc.encode(new_ids); + new_msk |= m_idDesc.get_mask(new_ids); + } + scan_sensitive(p, new_vid, new_msk); + } +} + +void DigiSubdetectorSequence::scan_detector(DetElement de, VolumeID vid, VolumeID mask) { + const VolIDs& new_ids = de.placement().volIDs(); + VolumeID new_vid = vid; + VolumeID new_msk = mask; + if ( !new_ids.empty() ) { + new_vid |= m_idDesc.encode(new_ids); + new_msk |= m_idDesc.get_mask(new_ids); + } + for (const auto& id : new_ids) { + if ( id.first == m_segmentName ) { + VolumeID rid = detail::reverseBits<VolumeID>(new_vid); + m_parallelVid.emplace(make_pair(rid, Context(de, new_vid, rid, new_msk))); + m_parallelDet.emplace(make_pair(de, new_vid)); + scan_sensitive(de.placement(), new_vid, new_msk); + return; + } + } + for ( const auto& c : de.children() ) + scan_detector(c.second, new_vid, new_msk); +} + + +void DigiSubdetectorSequence::process_cell(const DigiCellScanner& , const CellDataBase& data) const { +#if 0 + Segmentation seg = m_sensDet.readout().segmentation(); + string desc = m_idDesc.str(data.cell_id); + info("Sensitive: [%s/%s] vid:%s %s", + data.solid->IsA()->GetName(), + seg.type().c_str(), + volumeID(data.cell_id).c_str(), + desc.c_str()); +#endif + if ( data.cell_id ) { + } +} + +void DigiSubdetectorSequence::process_context(const Context& c, PlacedVolume pv, VolumeID vid, VolumeID mask) const { + Volume vol = pv.volume(); + if ( vol.isSensitive() ) { + auto key = make_pair(vol->GetShape()->IsA(), m_segmentation); + auto is = m_scanners.find(key); + if ( is == m_scanners.end() ) { + except("Fatal error in process_context: Invalid cell scanner. vid: %016X",vid); + } + (*(is->second))(pv, vid, m_cellHandler); + return; + } + for (int idau = 0, ndau = pv->GetNdaughters(); idau < ndau; ++idau) { + PlacedVolume p(pv->GetDaughter(idau)); + const VolIDs& new_ids = p.volIDs(); + if ( !new_ids.empty() ) + process_context(c, p, vid | m_idDesc.encode(new_ids), mask | m_idDesc.get_mask(new_ids)); + else + process_context(c, p, vid, mask); + } +} + +/// Pre-track action callback +void DigiSubdetectorSequence::execute(DigiContext& context) const { + //static bool first = true; + //if ( first ) { + for( const auto& d : m_parallelVid ) { + const Context& c = d.second; + auto vid = c.detector_id; + auto det = c.detector; + string id_desc = m_idDesc.str(vid); + info(" Order:%-64s vid:%s %s %s", + det.path().c_str(), volumeID(d.first).c_str(), volumeID(vid).c_str(), id_desc.c_str()); + process_context(c, c.detector.placement(), c.detector_id, c.detector_mask); + } + //} + + this->DigiSynchronize::execute(context); + debug("+++ Event: %8d (DigiSubdetectorSequence) Parallel: %s Done.", + context.event().eventNumber, yes_no(m_parallel)); + //m_end(&context); +} + +/// Access subdetector from the detector description +dd4hep::DetElement DigiSubdetectorSequence::subdetector(const string& nam) const { + return m_kernel.detectorDescription().detector(nam); +} + +/// Access sensitive detector from the detector description +dd4hep::SensitiveDetector DigiSubdetectorSequence::sensitiveDetector(const string& nam) const { + return m_kernel.detectorDescription().sensitiveDetector(nam); +} diff --git a/DDDigi/src/DigiSynchronize.cpp b/DDDigi/src/DigiSynchronize.cpp index 23ff00f051c80bd2b8fa6454ae90d813d7ac0854..49a9660fe696bdbd85e4d484127a6a1d8d9bfe62 100644 --- a/DDDigi/src/DigiSynchronize.cpp +++ b/DDDigi/src/DigiSynchronize.cpp @@ -25,20 +25,20 @@ using namespace dd4hep::digi; /// Standard constructor DigiSynchronize::DigiSynchronize(const DigiKernel& kernel, const string& nam) - : DigiAction(kernel, nam) + : DigiEventAction(kernel, nam) { InstanceCount::increment(this); } /// Default destructor DigiSynchronize::~DigiSynchronize() { - m_actors(&DigiAction::release); + m_actors(&DigiEventAction::release); m_actors.clear(); InstanceCount::decrement(this); } /// Get an action sequence member by name -DigiAction* DigiSynchronize::get(const string& nam) const { +DigiEventAction* DigiSynchronize::get(const string& nam) const { return m_actors.get(FindByName(TypeName::split(nam).second)); } @@ -56,7 +56,7 @@ void DigiSynchronize::execute(DigiContext& context) const { } /// Add an actor responding to all callbacks. Sequence takes ownership. -void DigiSynchronize::adopt(DigiAction* action) { +void DigiSynchronize::adopt(DigiEventAction* action) { if (action) { action->addRef(); m_actors.add(action); diff --git a/DDG4/include/DDG4/Geant4Converter.h b/DDG4/include/DDG4/Geant4Converter.h index 7b46df9526b7562547745cacd85608e6898cf497..a3d19d7b116b65a440362d965cb2162b22323e00 100644 --- a/DDG4/include/DDG4/Geant4Converter.h +++ b/DDG4/include/DDG4/Geant4Converter.h @@ -84,6 +84,9 @@ namespace dd4hep { /// Convert the geometry type material into the corresponding Geant4 object(s). virtual void* handleMaterial(const std::string& name, Material medium) const; + /// Handle the conversion of isotopes + virtual void* handleIsotope(const std::string& name, const TGeoIsotope* iso) const; + /// Convert the geometry type element into the corresponding Geant4 object(s). virtual void* handleElement(const std::string& name, Atom element) const; diff --git a/DDG4/include/DDG4/Geant4GeometryInfo.h b/DDG4/include/DDG4/Geant4GeometryInfo.h index c27f91e4993484eba1c91d3f9826aa301fcab198..c43ff98fa05ed663a7fb87874983cdc895a5c42e 100644 --- a/DDG4/include/DDG4/Geant4GeometryInfo.h +++ b/DDG4/include/DDG4/Geant4GeometryInfo.h @@ -32,6 +32,7 @@ class TGeoVolume; class TGeoShape; class TGeoNode; // Forward declarations (Geant4) +class G4Isotope; class G4Element; class G4Material; class G4VSolid; @@ -66,6 +67,7 @@ namespace dd4hep { namespace Geant4GeometryMaps { //typedef std::vector<const G4VPhysicalVolume*> Geant4PlacementPath; typedef std::map<Atom, G4Element*> ElementMap; + typedef std::map<const TGeoIsotope*, G4Isotope*> IsotopeMap; typedef std::map<Material, G4Material*> MaterialMap; //typedef std::map<LimitSet, G4UserLimits*> LimitMap; typedef std::map<PlacedVolume, G4VPhysicalVolume*> PlacementMap; @@ -92,6 +94,7 @@ namespace dd4hep { public: typedef std::vector<const G4VPhysicalVolume*> Geant4PlacementPath; TGeoManager* manager = 0; + Geant4GeometryMaps::IsotopeMap g4Isotopes; Geant4GeometryMaps::ElementMap g4Elements; Geant4GeometryMaps::MaterialMap g4Materials; Geant4GeometryMaps::SolidMap g4Solids; diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index ad7665add08f4284b039b24ee85b75e376f8ec9c..231f38610bb1aaa154c62701e542851e813f1f1e 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -347,56 +347,43 @@ Geant4Converter::Geant4Converter(const Detector& description_ref, PrintLevel lev Geant4Converter::~Geant4Converter() { } -/// Dump element in GDML format to output stream +/// Handle the conversion of isotopes +void* Geant4Converter::handleIsotope(const string& /* name */, const TGeoIsotope* iso) const { + G4Isotope* g4i = data().g4Isotopes[iso]; + if (!g4i) { + double a_conv = (CLHEP::g / CLHEP::mole); + g4i = new G4Isotope(iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA()*a_conv); + printout(debugElements ? ALWAYS : outputLevel, + "Geant4Converter", "++ Created G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", + iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA()); + data().g4Isotopes[iso] = g4i; + } + return g4i; +} + +/// Handle the conversion of elements void* Geant4Converter::handleElement(const string& name, const Atom element) const { G4Element* g4e = data().g4Elements[element]; if (!g4e) { - g4e = G4Element::GetElement(name, false); - if (!g4e) { - PrintLevel lvl = debugElements ? ALWAYS : outputLevel; - double a_conv = (CLHEP::g / CLHEP::mole); - if (element->GetNisotopes() > 0) { - g4e = new G4Element(name, element->GetTitle(), element->GetNisotopes()); - for (int i = 0, n = element->GetNisotopes(); i < n; ++i) { - TGeoIsotope* iso = element->GetIsotope(i); - G4Isotope* g4iso = G4Isotope::GetIsotope(iso->GetName(), false); - if (!g4iso) { - g4iso = new G4Isotope(iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA()*a_conv); - printout(lvl, "Geant4Converter", "++ Created G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", - iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA()); - } - else { - printout(lvl, "Geant4Converter", "++ Re-used G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", - iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA()); - } - g4e->AddIsotope(g4iso, element->GetRelativeAbundance(i)); - } - } - else { - // This adds in Geant4 the natural isotopes, which we normally do not want. We want to steer it outselves. - g4e = new G4Element(element->GetTitle(), name, element->Z(), element->A()*a_conv); - printout(lvl, "Geant4Converter", "++ Created G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", - element->GetName(), element->Z(), element->N(), element->A()); -#if 0 // Disabled for now! - g4e = new G4Element(name, element->GetTitle(), 1); - G4Isotope* g4iso = G4Isotope::GetIsotope(name, false); - if (!g4iso) { - g4iso = new G4Isotope(name, element->Z(), element->N(), element->A()*a_conv); - printout(lvl, "Geant4Converter", "++ Created G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", - element->GetName(), element->Z(), element->N(), element->A()); - } - else { - printout(lvl, "Geant4Converter", "++ Re-used G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", - element->GetName(), element->Z(), element->N(), element->A()); - } - g4e->AddIsotope(g4iso, 1.0); -#endif + PrintLevel lvl = debugElements ? ALWAYS : outputLevel; + if (element->GetNisotopes() > 0) { + g4e = new G4Element(name, element->GetTitle(), element->GetNisotopes()); + for (int i = 0, n = element->GetNisotopes(); i < n; ++i) { + TGeoIsotope* iso = element->GetIsotope(i); + G4Isotope* g4iso = (G4Isotope*)handleIsotope(iso->GetName(), iso); + g4e->AddIsotope(g4iso, element->GetRelativeAbundance(i)); } - stringstream str; - str << (*g4e); - printout(lvl, "Geant4Converter", "++ Created G4 %s No.Isotopes:%d", - str.str().c_str(),element->GetNisotopes()); } + else { + // This adds in Geant4 the natural isotopes, which we normally do not want. We want to steer it outselves. + double a_conv = (CLHEP::g / CLHEP::mole); + g4e = new G4Element(element->GetTitle(), name, element->Z(), element->A()*a_conv); + printout(lvl, "Geant4Converter", "++ Created G4 Isotope %s from data: Z=%d N=%d A=%.3f [g/mole]", + element->GetName(), element->Z(), element->N(), element->A()); + } + stringstream str; + str << (*g4e) << endl; + printout(lvl, "Geant4Converter", "++ Created G4 element %s", str.str().c_str()); data().g4Elements[element] = g4e; } return g4e; @@ -405,133 +392,130 @@ void* Geant4Converter::handleElement(const string& name, const Atom element) con /// Dump material in GDML format to output stream void* Geant4Converter::handleMaterial(const string& name, Material medium) const { Geant4GeometryInfo& info = data(); - G4Material* mat = info.g4Materials[medium]; - if (!mat) { + G4Material* mat = info.g4Materials[medium]; + if ( !mat ) { PrintLevel lvl = debugMaterials ? ALWAYS : outputLevel; - mat = G4Material::GetMaterial(name, false); - if (!mat) { - TGeoMaterial* material = medium->GetMaterial(); - G4State state = kStateUndefined; - double density = material->GetDensity() * (CLHEP::gram / CLHEP::cm3); - if (density < 1e-25) - density = 1e-25; - switch (material->GetState()) { - case TGeoMaterial::kMatStateSolid: - state = kStateSolid; - break; - case TGeoMaterial::kMatStateLiquid: - state = kStateLiquid; - break; - case TGeoMaterial::kMatStateGas: - state = kStateGas; - break; - default: - case TGeoMaterial::kMatStateUndefined: - state = kStateUndefined; - break; + TGeoMaterial* material = medium->GetMaterial(); + G4State state = kStateUndefined; + double density = material->GetDensity() * (CLHEP::gram / CLHEP::cm3); + if (density < 1e-25) + density = 1e-25; + switch (material->GetState()) { + case TGeoMaterial::kMatStateSolid: + state = kStateSolid; + break; + case TGeoMaterial::kMatStateLiquid: + state = kStateLiquid; + break; + case TGeoMaterial::kMatStateGas: + state = kStateGas; + break; + default: + case TGeoMaterial::kMatStateUndefined: + state = kStateUndefined; + break; + } + if (material->IsMixture()) { + double A_total = 0.0; + double W_total = 0.0; + TGeoMixture* mix = (TGeoMixture*) material; + int nElements = mix->GetNelements(); + mat = new G4Material(name, density, nElements, state, + material->GetTemperature(), material->GetPressure()); + for (int i = 0; i < nElements; ++i) { + A_total += (mix->GetAmixt())[i]; + W_total += (mix->GetWmixt())[i]; } - if (material->IsMixture()) { - double A_total = 0.0; - double W_total = 0.0; - TGeoMixture* mix = (TGeoMixture*) material; - int nElements = mix->GetNelements(); - mat = new G4Material(name, density, nElements, state, - material->GetTemperature(), material->GetPressure()); - for (int i = 0; i < nElements; ++i) { - A_total += (mix->GetAmixt())[i]; - W_total += (mix->GetWmixt())[i]; + for (int i = 0; i < nElements; ++i) { + TGeoElement* e = mix->GetElement(i); + G4Element* g4e = (G4Element*) handleElement(e->GetName(), Atom(e)); + if (!g4e) { + printout(ERROR, "Material", + "Missing component %s for material %s. A=%f W=%f", + e->GetName(), mix->GetName(), A_total, W_total); } - for (int i = 0; i < nElements; ++i) { - TGeoElement* e = mix->GetElement(i); - G4Element* g4e = (G4Element*) handleElement(e->GetName(), Atom(e)); - if (!g4e) { - printout(ERROR, "Material", - "Missing component %s for material %s. A=%f W=%f", - e->GetName(), mix->GetName(), A_total, W_total); - } - //mat->AddElement(g4e, (mix->GetAmixt())[i] / A_total); - mat->AddElement(g4e, (mix->GetWmixt())[i] / W_total); - } - } - else { - double z = material->GetZ(), a = material->GetA(); - if ( z < 1.0000001 ) z = 1.0; - if ( a < 0.5000001 ) a = 1.0; - mat = new G4Material(name, z, a, density, state, - material->GetTemperature(), material->GetPressure()); + //mat->AddElement(g4e, (mix->GetAmixt())[i] / A_total); + mat->AddElement(g4e, (mix->GetWmixt())[i] / W_total); } + } + else { + double z = material->GetZ(), a = material->GetA(); + if ( z < 1.0000001 ) z = 1.0; + if ( a < 0.5000001 ) a = 1.0; + mat = new G4Material(name, z, a, density, state, + material->GetTemperature(), material->GetPressure()); + } #if ROOT_VERSION_CODE >= ROOT_VERSION(6,17,0) - /// Attach the material properties if any - G4MaterialPropertiesTable* tab = 0; - TListIter propIt(&material->GetProperties()); - for(TObject* obj=propIt.Next(); obj; obj = propIt.Next()) { - TNamed* named = (TNamed*)obj; - TGDMLMatrix* matrix = info.manager->GetGDMLMatrix(named->GetTitle()); - Geant4GeometryInfo::PropertyVector* v = - (Geant4GeometryInfo::PropertyVector*)handleMaterialProperties(matrix); - if ( 0 == v ) { - except("Geant4Converter", "++ FAILED to create G4 material %s [Cannot convert property:%s]", - material->GetName(), named->GetName()); - } - if ( 0 == tab ) { - tab = new G4MaterialPropertiesTable(); - mat->SetMaterialPropertiesTable(tab); - } - int idx = tab->GetPropertyIndex(named->GetName(), false); - if ( idx < 0 ) { - printout(ERROR, "Geant4Converter", "++ UNKNOWN Geant4 CONST Property: %-20s [IGNORED]", named->GetName()); - continue; - } - // We need to convert the property from TGeo units to Geant4 units - auto conv = g4PropertyConversion(idx); - vector<double> bins(v->bins), vals(v->values); - for(size_t i=0, count=bins.size(); i<count; ++i) - bins[i] *= conv.first, vals[i] *= conv.second; - - G4MaterialPropertyVector* vec = new G4MaterialPropertyVector(&bins[0], &vals[0], bins.size()); - tab->AddProperty(named->GetName(), vec); - printout(lvl, "Geant4Converter", "++ Property: %-20s [%ld x %ld] -> %s ", - named->GetName(), matrix->GetRows(), matrix->GetCols(), named->GetTitle()); - for(size_t i=0, count=v->bins.size(); i<count; ++i) - printout(lvl,named->GetName()," Geant4: %8.3g [MeV] TGeo: %8.3g [GeV] Conversion: %8.3g", - bins[i], v->bins[i], conv.first); + /// Attach the material properties if any + G4MaterialPropertiesTable* tab = 0; + TListIter propIt(&material->GetProperties()); + for(TObject* obj=propIt.Next(); obj; obj = propIt.Next()) { + TNamed* named = (TNamed*)obj; + TGDMLMatrix* matrix = info.manager->GetGDMLMatrix(named->GetTitle()); + Geant4GeometryInfo::PropertyVector* v = + (Geant4GeometryInfo::PropertyVector*)handleMaterialProperties(matrix); + if ( 0 == v ) { + except("Geant4Converter", "++ FAILED to create G4 material %s [Cannot convert property:%s]", + material->GetName(), named->GetName()); } - /// Attach the material properties if any - TListIter cpropIt(&material->GetConstProperties()); - for(TObject* obj=cpropIt.Next(); obj; obj = cpropIt.Next()) { - Bool_t err = kFALSE; - TNamed* named = (TNamed*)obj; - double v = info.manager->GetProperty(named->GetTitle(),&err); - if ( err != kFALSE ) { - except("Geant4Converter", - "++ FAILED to create G4 material %s " - "[Cannot convert const property: %s]", - material->GetName(), named->GetName()); - } - if ( 0 == tab ) { - tab = new G4MaterialPropertiesTable(); - mat->SetMaterialPropertiesTable(tab); - } - int idx = tab->GetConstPropertyIndex(named->GetName(), false); - if ( idx < 0 ) { - printout(ERROR, "Geant4Converter", "++ UNKNOWN Geant4 CONST Property: %-20s [IGNORED]", named->GetName()); - continue; - } - // We need to convert the property from TGeo units to Geant4 units - double conv = g4ConstPropertyConversion(idx); - printout(lvl, "Geant4Converter", "++ CONST Property: %-20s %g ", named->GetName(), v); - tab->AddConstProperty(named->GetName(), v * conv); + if ( 0 == tab ) { + tab = new G4MaterialPropertiesTable(); + mat->SetMaterialPropertiesTable(tab); } -#endif - auto* ionization = mat->GetIonisation(); - stringstream str; - str << (*mat) << endl; - if ( ionization ) - str << " log(MEE): " << ionization->GetLogMeanExcEnergy(); - else - str << " log(MEE): UNKNOWN"; - printout(lvl, "Geant4Converter", "++ Created G4 %s", str.str().c_str()); + int idx = tab->GetPropertyIndex(named->GetName(), false); + if ( idx < 0 ) { + printout(ERROR, "Geant4Converter", "++ UNKNOWN Geant4 CONST Property: %-20s [IGNORED]", named->GetName()); + continue; + } + // We need to convert the property from TGeo units to Geant4 units + auto conv = g4PropertyConversion(idx); + vector<double> bins(v->bins), vals(v->values); + for(size_t i=0, count=bins.size(); i<count; ++i) + bins[i] *= conv.first, vals[i] *= conv.second; + + G4MaterialPropertyVector* vec = new G4MaterialPropertyVector(&bins[0], &vals[0], bins.size()); + tab->AddProperty(named->GetName(), vec); + printout(lvl, "Geant4Converter", "++ Property: %-20s [%ld x %ld] -> %s ", + named->GetName(), matrix->GetRows(), matrix->GetCols(), named->GetTitle()); + for(size_t i=0, count=v->bins.size(); i<count; ++i) + printout(lvl,named->GetName()," Geant4: %8.3g [MeV] TGeo: %8.3g [GeV] Conversion: %8.3g", + bins[i], v->bins[i], conv.first); } + /// Attach the material properties if any + TListIter cpropIt(&material->GetConstProperties()); + for(TObject* obj=cpropIt.Next(); obj; obj = cpropIt.Next()) { + Bool_t err = kFALSE; + TNamed* named = (TNamed*)obj; + double v = info.manager->GetProperty(named->GetTitle(),&err); + if ( err != kFALSE ) { + except("Geant4Converter", + "++ FAILED to create G4 material %s " + "[Cannot convert const property: %s]", + material->GetName(), named->GetName()); + } + if ( 0 == tab ) { + tab = new G4MaterialPropertiesTable(); + mat->SetMaterialPropertiesTable(tab); + } + int idx = tab->GetConstPropertyIndex(named->GetName(), false); + if ( idx < 0 ) { + printout(ERROR, "Geant4Converter", "++ UNKNOWN Geant4 CONST Property: %-20s [IGNORED]", named->GetName()); + continue; + } + // We need to convert the property from TGeo units to Geant4 units + double conv = g4ConstPropertyConversion(idx); + printout(lvl, "Geant4Converter", "++ CONST Property: %-20s %g ", named->GetName(), v); + tab->AddConstProperty(named->GetName(), v * conv); + } +#endif + auto* ionization = mat->GetIonisation(); + stringstream str; + str << (*mat) << endl; + if ( ionization ) + str << " log(MEE): " << ionization->GetLogMeanExcEnergy(); + else + str << " log(MEE): UNKNOWN"; + printout(lvl, "Geant4Converter", "++ Created G4 material %s", str.str().c_str()); info.g4Materials[medium] = mat; } return mat; @@ -1413,7 +1397,9 @@ Geant4Converter& Geant4Converter::create(DetElement top) { //outputLevel = WARNING; //setPrintLevel(VERBOSE); - + debugMaterials = true; + debugElements = true; + #if ROOT_VERSION_CODE >= ROOT_VERSION(6,17,0) handleArray(this, geo.manager->GetListOfGDMLMatrices(), &Geant4Converter::handleMaterialProperties); handleArray(this, geo.manager->GetListOfOpticalSurfaces(), &Geant4Converter::handleOpticalSurface); diff --git a/cmake/DD4hepBuild.cmake b/cmake/DD4hepBuild.cmake index 7c6089d978e48ea5347e34af524f7ef6fb5e8bfc..83c834610f9d6db891b24a3d7a60f9a41f398689 100644 --- a/cmake/DD4hepBuild.cmake +++ b/cmake/DD4hepBuild.cmake @@ -746,7 +746,13 @@ MACRO(DD4HEP_SETUP_GEANT4_TARGETS) if(Geant4_builtin_clhep_FOUND) dd4hep_debug("Using Geant4 internal CLHEP") - set(CLHEP "") + ADD_LIBRARY(CLHEP::CLHEP INTERFACE IMPORTED GLOBAL) + SET_TARGET_PROPERTIES(CLHEP::CLHEP + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${Geant4_INCLUDE_DIRS}" + ) + TARGET_LINK_LIBRARIES(CLHEP::CLHEP INTERFACE G4clhep) + else() IF(NOT TARGET CLHEP::CLHEP) FIND_PACKAGE(CLHEP REQUIRED) diff --git a/examples/DDCMS/CMakeLists.txt b/examples/DDCMS/CMakeLists.txt index 5bb65f9dba08d43a98a6d7a8216ead8094567b98..12acee37287cd29b47a5a413b76b15b8ce4e3e9c 100644 --- a/examples/DDCMS/CMakeLists.txt +++ b/examples/DDCMS/CMakeLists.txt @@ -24,36 +24,19 @@ ENDIF() dd4hep_set_compiler_flags() # #========================================================================== -# Configure Geant4 to if we have a builtin CLHEP -if(DD4HEP_USE_GEANT4) - find_package( Geant4 REQUIRED ) - if(Geant4_builtin_clhep_FOUND) - include_directories(${Geant4_INCLUDE_DIRS}) - DD4HEP_SETUP_GEANT4_TARGETS() - endif() -endif() -# # CLHEP dependent stuff if(NOT TARGET CLHEP::CLHEP) # ensure we only look for CLHEP once find_package(CLHEP QUIET) endif() -if (TARGET CLHEP::CLHEP OR Geant4_builtin_clhep_FOUND) +if (TARGET CLHEP::CLHEP) dd4hep_print("|++> CLHEP PRESENT. Building DDCMS examples.") else() dd4hep_print("|++> CLHEP is not present. NOT building DDCMS examples.") return() endif() - -dd4hep_configure_output () -# -#---Trick to allow building with Geant4 internal CLHEP -if ( DD4HEP_USE_GEANT4 AND Geant4_builtin_clhep_FOUND) - set(CLHEP "") -else() - set(CLHEP CLHEP::CLHEP) -endif() # +dd4hep_configure_output () # #------------------------------------------------------------------------------- # we only create only library for DDCMS. The whole package is a single component @@ -64,8 +47,8 @@ endif() # #---DDCMS plugin library ------------------------------------------------------- dd4hep_add_plugin ( DDCMS SOURCES src/*.cpp src/plugins/*.cpp - USES DD4hep::DDParsers DD4hep::DDCore DD4hep::DDAlign DD4hep::DDCond ROOT::Core ROOT::Geom ROOT::GenVector - ) + USES DD4hep::DDParsers DD4hep::DDCore DD4hep::DDAlign DD4hep::DDCond ROOT::Core ROOT::Geom ROOT::GenVector CLHEP::CLHEP +) install(TARGETS DDCMS LIBRARY DESTINATION lib) target_include_directories(DDCMS PUBLIC include) install(DIRECTORY include/DDCMS DESTINATION include) diff --git a/examples/DDDigi/scripts/TestFramework.py b/examples/DDDigi/scripts/TestFramework.py index e2d731fff6f4e0ca1da2aefed4634e361bb391d4..44f744d395cf933b6d088ad38ce46ce801a6d616 100644 --- a/examples/DDDigi/scripts/TestFramework.py +++ b/examples/DDDigi/scripts/TestFramework.py @@ -1,25 +1,24 @@ - - +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== from __future__ import absolute_import, unicode_literals import os import DDDigi -DDDigi.setPrintFormat(str('%-32s %5s %s')) -kernel = DDDigi.Kernel() -install_dir = os.environ['DD4hepExamplesINSTALL'] -fname = "file:" + install_dir + "/examples/ClientTests/compact/MiniTel.xml" -kernel.loadGeometry(str(fname)) -kernel.printProperties() -digi = DDDigi.Digitize(kernel) -digi.printDetectors() - -def make_input(): - input_1 = DDDigi.TestAction(kernel, 'input_01', 100) - input_2 = DDDigi.TestAction(kernel, 'input_02', 200) - input_3 = DDDigi.TestAction(kernel, 'input_03', 150) - input_4 = DDDigi.TestAction(kernel, 'input_04', 60) - seq = kernel.inputAction() +def make_input(kernel): + input_1 = DDDigi.TestAction(kernel,'input_01', 100) + input_2 = DDDigi.TestAction(kernel,'input_02', 200) + input_3 = DDDigi.TestAction(kernel,'input_03', 150) + input_4 = DDDigi.TestAction(kernel,'input_04', 60) + seq = kernel.inputAction() seq.adopt(input_1) seq.adopt(input_2) seq.adopt(input_3) @@ -27,13 +26,13 @@ def make_input(): return seq -def make_subdetector(name): - action_1 = DDDigi.TestAction(kernel, name + '_deposits', 150) - action_2 = DDDigi.TestAction(kernel, name + '_rndmNoise', 100) - action_3 = DDDigi.TestAction(kernel, name + '_deadChan', 100) - action_4 = DDDigi.TestAction(kernel, name + '_noiseChan', 50) - action_5 = DDDigi.TestAction(kernel, name + '_merge', 200) - seq = DDDigi.ActionSequence(kernel, 'DigiActionSequence/' + name + '_sequence', True) +def make_subdetector(kernel, name): + action_1 = DDDigi.TestAction(kernel,name+'_deposits', 150) + action_2 = DDDigi.TestAction(kernel,name+'_rndmNoise', 100) + action_3 = DDDigi.TestAction(kernel,name+'_deadChan', 100) + action_4 = DDDigi.TestAction(kernel,name+'_noiseChan', 50) + action_5 = DDDigi.TestAction(kernel,name+'_merge', 200) + seq = DDDigi.ActionSequence(kernel,'DigiActionSequence/'+name+'_sequence',True) seq.adopt(action_1) seq.adopt(action_2) seq.adopt(action_3) @@ -42,25 +41,42 @@ def make_subdetector(name): return seq -event_processor = DDDigi.Synchronize(kernel, 'DigiSynchronize/MainDigitizer', True) -event_processor.parallel = True -detectors = DDDigi -# input -make_input() -# Subdetector digitization -dets = digi.activeDetectors() -for d in dets: - seq = make_subdetector(d['name']) - event_processor.adopt(seq) -kernel.eventAction().adopt(event_processor) -# Output -output = DDDigi.TestAction(kernel, 'output_01', 200) -kernel.outputAction().adopt(output) +def run(): + ##import pdb + ##pdb.set_trace() + DDDigi.setPrintFormat(str('%-32s %5s %s')) + kernel = DDDigi.Kernel() + install_dir = os.environ['DD4hepExamplesINSTALL'] + fname = "file:" + install_dir + "/examples/ClientTests/compact/MiniTel.xml" + kernel.loadGeometry(str(fname)) + kernel.printProperties() + digi = DDDigi.Digitize(kernel) + digi.printDetectors() + + event_processor = DDDigi.Synchronize(kernel, 'DigiSynchronize/MainDigitizer', True) + event_processor.parallel = True + detectors = DDDigi + # input + make_input(kernel) + # Subdetector digitization + dets = digi.activeDetectors() + for d in dets: + seq = make_subdetector(kernel, d['name']) + event_processor.adopt(seq) + kernel.eventAction().adopt(event_processor) + # Output + output = DDDigi.TestAction(kernel, 'output_01', 200) + kernel.outputAction().adopt(output) + + DDDigi.setPrintLevel(DDDigi.OutputLevel.DEBUG) + kernel.numThreads = 0 # = number of concurrent threads + kernel.numEvents = 10 + kernel.maxEventsParallel = 3 + kernel.run() + DDDigi.setPrintLevel(DDDigi.OutputLevel.INFO) + +if __name__ == '__main__': + run() + -DDDigi.setPrintLevel(DDDigi.OutputLevel.DEBUG) -kernel.numThreads = 0 # = number of concurrent threads -kernel.numEvents = 10 -kernel.maxEventsParallel = 3 -kernel.run() -DDDigi.setPrintLevel(DDDigi.OutputLevel.INFO) diff --git a/examples/DDDigi/src/DigiTestAction.cpp b/examples/DDDigi/src/DigiTestAction.cpp index c821b65d437b947216ab1f19032a8067caadc033..b7888f99a77acb0578caa0bd4e2b7971056b9cd2 100644 --- a/examples/DDDigi/src/DigiTestAction.cpp +++ b/examples/DDDigi/src/DigiTestAction.cpp @@ -14,7 +14,7 @@ #define DD4HEP_DDDIGI_DIGITESTACTION_H // Framework include files -#include "DDDigi/DigiAction.h" +#include "DDDigi/DigiEventAction.h" /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -35,7 +35,7 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_DIGITIZATION */ - class DigiTestAction : public DigiAction { + class DigiTestAction : public DigiEventAction { protected: /// Sleep period to fake execution [milliseconds] int m_sleep = 0; @@ -85,11 +85,11 @@ static void noop(int) {} using namespace std; using namespace dd4hep::digi; -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiTestAction) +DECLARE_DIGIEVENTACTION_NS(dd4hep::digi,DigiTestAction) /// Standard constructor DigiTestAction::DigiTestAction(const DigiKernel& kernel, const string& nam) - : DigiAction(kernel, nam) + : DigiEventAction(kernel, nam) { declareProperty("sleep", m_sleep = 0); InstanceCount::increment(this); diff --git a/examples/DDDigi/src/DigiTestSignalProcessor.cpp b/examples/DDDigi/src/DigiTestSignalProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1c24f7da62a8d08c94d04cecff7997ddd9b73e6 --- /dev/null +++ b/examples/DDDigi/src/DigiTestSignalProcessor.cpp @@ -0,0 +1,100 @@ +//========================================================================== +// 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_DDDIGI_DIGITESTSIGNALPROCESSOR_H +#define DD4HEP_DDDIGI_DIGITESTSIGNALPROCESSOR_H + +// Framework include files +#include "DDDigi/DigiSignalProcessor.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + // Forward declarations + class DigiSignalProcessor; + class DigiTestSignalProcessor; + + /// Class which applies random noise hits of a given amplitude + /** + * Class which applies random noise hits of a given amplitude + * to a segmented sensitive element. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiTestSignalProcessor : public DigiSignalProcessor { + protected: + double m_attenuation = 1.0; + protected: + /// Define standard assignments and constructors + DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiTestSignalProcessor); + + public: + /// Standard constructor + DigiTestSignalProcessor(const DigiKernel& kernel, const std::string& nam); + /// Default destructor + virtual ~DigiTestSignalProcessor(); + /// Process signal data + virtual double operator()(const DigiCellData& data) const override; + }; + + } // End namespace digi +} // End namespace dd4hep +#endif // DD4HEP_DDDIGI_DIGITESTSIGNALPROCESSOR_H + +//========================================================================== +// 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/Printout.h" +#include "DD4hep/InstanceCount.h" +#include "DDDigi/DigiFactories.h" +//#include "DDDigi/DigiTestSignalProcessor.h" + +// C/C++ include files + +using namespace std; +using namespace dd4hep::digi; + +DECLARE_DIGISIGNALPROCESSOR_NS(dd4hep::digi,DigiTestSignalProcessor) + +/// Standard constructor +DigiTestSignalProcessor::DigiTestSignalProcessor(const DigiKernel& kernel, const string& nam) + : DigiSignalProcessor(kernel, nam) +{ + declareProperty("attenuation", m_attenuation = 1.0); + InstanceCount::increment(this); +} + +/// Default destructor +DigiTestSignalProcessor::~DigiTestSignalProcessor() { + InstanceCount::decrement(this); +} + +/// Process signal data +double DigiTestSignalProcessor::operator()(const DigiCellData& data) const { + return m_attenuation * data.raw_value; +}