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;
+}