From 20d09e467c8e13eff9a55152005b8a61b033088b Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Tue, 26 Nov 2019 18:17:12 +0100
Subject: [PATCH] DDDigi: Start implementing noise chains

---
 DDDigi/include/DDDigi/DigiSegmentation.h      |  9 ++--
 .../include/DDDigi/DigiSubdetectorSequence.h  |  5 +-
 .../DDDigi/segmentations/CartesianGridXY.h    |  4 +-
 .../DDDigi/segmentations/CartesianGridXYZ.h   |  4 +-
 .../segmentations/SegmentationScanner.h       |  2 +-
 .../plugins/CellScanner_CartesianGridXY.cpp   | 37 +++++++-------
 .../plugins/CellScanner_CartesianGridXYZ.cpp  | 48 +++++++++++++++++++
 DDDigi/src/DigiSubdetectorSequence.cpp        | 28 +++++------
 8 files changed, 93 insertions(+), 44 deletions(-)

diff --git a/DDDigi/include/DDDigi/DigiSegmentation.h b/DDDigi/include/DDDigi/DigiSegmentation.h
index d72c1d1ac..cdad0fa57 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 096658f9e..03ffaed76 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 a3e8d5b2b..3030bf5bf 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 83fd67d76..6c65a9cab 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 ac769fdf9..80ce58378 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 627be9d9e..365d6590b 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 815254e72..5352303dc 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 34fc2e6b8..7476aec8d 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() )
-- 
GitLab