diff --git a/DDDigi/include/DDDigi/DigiSegmentation.h b/DDDigi/include/DDDigi/DigiSegmentation.h
index d72c1d1ac2c7a1c5ebe2079923708d6aaae397a3..cdad0fa57999a47e93ab389793d5584023bd003a 100644
--- a/DDDigi/include/DDDigi/DigiSegmentation.h
+++ b/DDDigi/include/DDDigi/DigiSegmentation.h
@@ -29,14 +29,15 @@ namespace dd4hep {
 
     // Forward declarations
 
-    struct CellDataBase  {
+    class CellDataBase  {
+    public:
       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> class cell_data;
+    template <typename SEGMENTATION> class segmentation_data;
     
     template <typename SEGMENTATION> 
     void init_segmentation_data(segmentation_data<SEGMENTATION>& data, const Segmentation& seg);
@@ -48,7 +49,7 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_DIGITIZATION
      */
-    struct DigiCellScanner  {
+    class DigiCellScanner  {
     public:
       typedef std::function<void(const DigiCellScanner& env, const CellDataBase&)> cell_handler_t;
     public:
diff --git a/DDDigi/include/DDDigi/DigiSubdetectorSequence.h b/DDDigi/include/DDDigi/DigiSubdetectorSequence.h
index 096658f9e68d3c1021b3194df44050e8bae4c158..03ffaed760452b443ccc44ab1a2e2ad7bc7621ed 100644
--- a/DDDigi/include/DDDigi/DigiSubdetectorSequence.h
+++ b/DDDigi/include/DDDigi/DigiSubdetectorSequence.h
@@ -49,7 +49,8 @@ namespace dd4hep {
      */
     class DigiSubdetectorSequence : public DigiActionSequence {
     protected:
-      struct Context  {
+      class Context  {
+      public:
         DetElement detector;
         VolumeID   detector_id;
         VolumeID   reverse_id;
@@ -100,7 +101,7 @@ namespace dd4hep {
       /// Default destructor
       virtual ~DigiSubdetectorSequence();
       /// Iniitalize subdetector sequencer
-      virtual void initialize();
+      virtual void initialize()  override;
       /// 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
index a3e8d5b2b49b673bb6e27f71352618d342b124ef..3030bf5bf14040ca2e306165b53774b248ba56d1 100644
--- a/DDDigi/include/DDDigi/segmentations/CartesianGridXY.h
+++ b/DDDigi/include/DDDigi/segmentations/CartesianGridXY.h
@@ -24,13 +24,13 @@ namespace dd4hep {
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
-    template <> struct cell_data<CartesianGridXY> : public CellDataBase {
+    template <> class 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> {
+    template <> class segmentation_data<CartesianGridXY> {
     public:
       DDSegmentation::CartesianGridXY* segmentation_xy {0};
       double x_grid_size {0.0};
diff --git a/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h b/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h
index 83fd67d7646d8fdec827373f12b4c1f2eac86b5d..6c65a9cabf2807b504e7a7b134298966317d16f3 100644
--- a/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h
+++ b/DDDigi/include/DDDigi/segmentations/CartesianGridXYZ.h
@@ -27,13 +27,13 @@ namespace dd4hep {
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
-    template <> struct cell_data<CartesianGridXYZ> : public CellDataBase {
+    template <> class 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> {
+    template <> class segmentation_data<CartesianGridXYZ> {
     public:
       DDSegmentation::CartesianGridXYZ* segmentation_xyz {0};
       double x_grid_size {0.0}, x_offset {0.0};
diff --git a/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h b/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h
index ac769fdf987c9ad98fb0175bf01e5bd5210229da..80ce58378e0505a7b1dbee6536a6a59410c15da4 100644
--- a/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h
+++ b/DDDigi/include/DDDigi/segmentations/SegmentationScanner.h
@@ -30,7 +30,7 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_DIGITIZATION
      */
-    template <typename SEGMENTATION, typename SOLID> struct CellScanner : public DigiCellScanner  {
+    template <typename SEGMENTATION, typename SOLID> class CellScanner : public DigiCellScanner  {
     public:
       typedef SOLID                                   solid_t;
       typedef SEGMENTATION                            segmentation_t;
diff --git a/DDDigi/plugins/CellScanner_CartesianGridXY.cpp b/DDDigi/plugins/CellScanner_CartesianGridXY.cpp
index 627be9d9ee69fb3cc0ed1d06076ea5fd8550c28d..365d6590b181bb95999d68f07e00611164f5c0ed 100644
--- a/DDDigi/plugins/CellScanner_CartesianGridXY.cpp
+++ b/DDDigi/plugins/CellScanner_CartesianGridXY.cpp
@@ -23,6 +23,24 @@ 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 <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;
@@ -49,29 +67,12 @@ namespace dd4hep {
   }    // 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)
     {
diff --git a/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp b/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp
index 815254e728adff160ed15e995e0eed650a2272f1..5352303dcccdfdb7a35b1d696200775347d320ab 100644
--- a/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp
+++ b/DDDigi/plugins/CellScanner_CartesianGridXYZ.cpp
@@ -45,6 +45,44 @@ namespace dd4hep {
       data.z_mask           = z_f.mask();
     }
 
+    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;
+      long nz = 2e0 * b->GetDZ() / segment.z_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;
+          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;
+            pos[2] = (e.z_bin + 0.5) * segment.z_grid_size;
+            if ( !sol->Contains(pos) ) continue;
+            e.cell_id = vid | e.x_cid | e.y_cid | e.y_cid;
+            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
     CellScanner<CartesianGridXYZ,Box>::operator()(PlacedVolume pv, VolumeID vid, const cell_handler_t& cell_handler)
     {
@@ -72,3 +110,13 @@ namespace dd4hep {
 }      // End namespace dd4hep
 
 DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Box)
+
+namespace dd4hep  {
+  typedef IntersectionSolid Intersection;
+  typedef SubtractionSolid Subtraction;
+  typedef UnionSolid Union;
+}
+DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Intersection)
+DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Subtraction)
+DECLARE_DIGICELLSCANNER(DigiCellScanner,CartesianGridXYZ,Union)
+
diff --git a/DDDigi/src/DigiSubdetectorSequence.cpp b/DDDigi/src/DigiSubdetectorSequence.cpp
index 34fc2e6b884685e691ccab6aab16bc65d2cdbd62..7476aec8d7920128ee3c6421587e5df447199a99 100644
--- a/DDDigi/src/DigiSubdetectorSequence.cpp
+++ b/DDDigi/src/DigiSubdetectorSequence.cpp
@@ -64,7 +64,6 @@ void DigiSubdetectorSequence::initialize()   {
 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);
@@ -75,14 +74,13 @@ void DigiSubdetectorSequence::scan_sensitive(PlacedVolume pv, VolumeID vid, Volu
   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);
+      VolumeID new_vid = vid  | m_idDesc.encode(new_ids);
+      VolumeID new_msk = mask | m_idDesc.get_mask(new_ids);
+      scan_sensitive(p, new_vid, new_msk);
+      continue;
     }
-    scan_sensitive(p, new_vid, new_msk);
+    scan_sensitive(p, vid, mask);
   }
 }
 
@@ -93,14 +91,14 @@ void DigiSubdetectorSequence::scan_detector(DetElement de, VolumeID vid, VolumeI
   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& 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() )