From 8a2acb7549c2aaf2a856cb6ebe7eeadcb03941b0 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Tue, 18 Oct 2016 17:23:00 +0200
Subject: [PATCH] See doc/release.notes. First trial to get segmentations into
 a more DD4hep like shape.

---
 DDCore/include/DD4hep/Alignments.h            |  2 +-
 DDCore/include/DD4hep/Primitives.h            |  2 +
 DDCore/include/DD4hep/Segmentations.h         | 42 ++++++-----
 DDCore/src/Alignments.cpp                     | 30 ++++----
 DDCore/src/Segmentations.cpp                  | 69 ++++++++++++++++++-
 DDCore/src/plugins/Compact2Objects.cpp        | 11 ++-
 .../DDSegmentation/MegatileLayerGridXY.h      |  6 +-
 doc/release.notes                             | 12 ++++
 8 files changed, 136 insertions(+), 38 deletions(-)

diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h
index aec4263ee..13950dea1 100644
--- a/DDCore/include/DD4hep/Alignments.h
+++ b/DDCore/include/DD4hep/Alignments.h
@@ -87,7 +87,7 @@ namespace DD4hep {
       /// Constructor to be used when reading the already parsed object
       template <typename Q> Alignment(const Handle<Q>& e) : Handle<Object>(e)  {}
       /// Object constructor for pure alignment objects
-      //      template <typename Q=Interna::AlignmentNamedObject> Alignment(const std::string& name);
+      //template <typename Q=Interna::AlignmentNamedObject> Alignment(const std::string& name);
       Alignment(const std::string& name) ;
 
       /// Hash code generation from input string
diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h
index c9fb3a352..54d880660 100644
--- a/DDCore/include/DD4hep/Primitives.h
+++ b/DDCore/include/DD4hep/Primitives.h
@@ -17,6 +17,8 @@
 
 // C/C++ include files
 #include <map>
+#include <vector>
+#include <string>
 #include <limits>
 #include <typeinfo>
 #include <algorithm>
diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h
index 9553f94a9..89b5e486b 100644
--- a/DDCore/include/DD4hep/Segmentations.h
+++ b/DDCore/include/DD4hep/Segmentations.h
@@ -31,6 +31,10 @@ namespace DD4hep {
   /// Namespace for the geometry part of the AIDA detector description toolkit
   namespace Geometry {
 
+    // Forward declarations
+    class DetElementObject;
+    class SensitiveDetectorObject;
+
     /// Implementation class supporting generic Segmentation of sensitive detectors
     /**
      * \author  M.Frank
@@ -43,14 +47,12 @@ namespace DD4hep {
       typedef DDSegmentation::Parameters Parameters;
       typedef DDSegmentation::Parameter Parameter;
     public:
-      /// Magic word to check object integrity
-      unsigned long magic;
-      /// Flag to use segmentation for hit positioning
-      unsigned char useForHitPosition;
       /// determine the local position based on the cell ID
       DDSegmentation::Vector3D position(const long64& cellID) const;
       /// determine the cell ID based on the local position
-      long64 cellID(const DDSegmentation::Vector3D& localPosition, const DDSegmentation::Vector3D& globalPosition, const long64& volumeID) const;
+      long64 cellID(const DDSegmentation::Vector3D& localPosition,
+                    const DDSegmentation::Vector3D& globalPosition,
+                    const long64& volumeID) const;
       /// Standard constructor
       SegmentationObject(BaseSegmentation* s = 0);
       /// Default destructor
@@ -75,8 +77,17 @@ namespace DD4hep {
       Parameters parameters() const;
       /// Set all parameters from an existing set of parameters
       void setParameters(const Parameters& parameters);
+
+      /// Magic word to check object integrity
+      unsigned long magic;
+      /// Flag to use segmentation for hit positioning
+      unsigned char useForHitPosition;
+      /// Reference to hosting top level DetElement structure
+      Handle<DetElementObject> detector;      
+      /// Reference to hosting top level sensitve detector structure
+      Handle<SensitiveDetectorObject> sensitive;
       /// Reference to base segmentation
-      BaseSegmentation* segmentation;
+      BaseSegmentation* segmentation;      
     };
 
 
@@ -91,25 +102,19 @@ namespace DD4hep {
     public:
       typedef SegmentationObject Object;
       typedef DDSegmentation::Segmentation BaseSegmentation;
-      typedef DDSegmentation::Parameter Parameter;
-      typedef DDSegmentation::Parameters Parameters;
+      typedef DDSegmentation::Parameter    Parameter;
+      typedef DDSegmentation::Parameters   Parameters;
 
     public:
       /// Initializing constructor creating a new object of the given DDSegmentation type
       Segmentation(const std::string& type, const std::string& name);
       /// Default constructor
-      Segmentation()
-        : Handle<Implementation>() {
-      }
+      Segmentation() : Handle<Object>() {    }
       /// Copy Constructor from object
-      Segmentation(const Segmentation& e)
-        : Handle<Object>(e) {
-      }
+      Segmentation(const Segmentation& e) : Handle<Object>(e) {   }
 #ifndef __CINT__
       /// Copy Constructor from handle
-      Segmentation(const Handle<SegmentationObject>& e)
-        : Handle<Object>(e) {
-      }
+      Segmentation(const Handle<Object>& e) : Handle<Object>(e) { }
 #endif
       /// Constructor to be used when reading the already parsed object
       template <typename Q> Segmentation(const Handle<Q>& e)
@@ -133,6 +138,9 @@ namespace DD4hep {
       Position position(const long64& cellID) const;
       /// determine the cell ID based on the local position
       long64 cellID(const Position& localPosition, const Position& globalPosition, const long64& volumeID) const;
+
+      /// Access the concrete underlying segmentation implementation from DDSegmentation
+      template <typename T> static T* get(const Object* object);
     };
 
   } /* End namespace Geometry              */
diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp
index e532e0b16..97e5688e3 100644
--- a/DDCore/src/Alignments.cpp
+++ b/DDCore/src/Alignments.cpp
@@ -1,4 +1,3 @@
-// $Id$
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
@@ -30,28 +29,31 @@ namespace DD4hep {
   /// Namespace for the alignment part of the AIDA detector description toolkit
   namespace Alignments {
     
-    // // /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
-    // // template <> Alignment::Alignment<Alignment::Object>(const string& nam) {
-    // //   assign(new Alignment::Object(), nam, "alignment");
-    // // }
+#if 0
+    /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
+    template <> Alignment::Alignment<Alignment::Object>(const string& nam) {
+      assign(new Alignment::Object(), nam, "alignment");
+    }
     
-    // // /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
-    // // template <> Alignment::Alignment<Interna::AlignmentNamedObject>(const string& nam) {
-    // //   assign(new Interna::AlignmentNamedObject(nam, "alignment"), nam, "alignment");
-    // // }
+    /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
+    template <> Alignment::Alignment<Interna::AlignmentNamedObject>(const string& nam) {
+      assign(new Interna::AlignmentNamedObject(nam, "alignment"), nam, "alignment");
+    }
+#endif    
     /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
     Alignment::Alignment(const string& nam) {
       assign(new Interna::AlignmentNamedObject(nam, "alignment"), nam, "alignment");
     }
-    
     /// Initializing constructor to create a new object (Specialized for AlignmentConditionObject)
     AlignmentCondition::AlignmentCondition(const string& nam) {
       assign(new AlignmentCondition::Object(nam, "alignment"), nam, "alignment");
     }
-    // // /// Initializing constructor to create a new object (Specialized for AlignmentConditionObject)
-    // // template <> AlignmentCondition::AlignmentCondition<AlignmentCondition::Object>(const string& nam) {
-    // //   assign(new Object(nam, "alignment"), nam, "alignment");
-    // // }
+#if 0
+    /// Initializing constructor to create a new object (Specialized for AlignmentConditionObject)
+    template <> AlignmentCondition::AlignmentCondition<AlignmentCondition::Object>(const string& nam) {
+      assign(new Object(nam, "alignment"), nam, "alignment");
+    }
+#endif
   } /* End namespace Aligments                  */
 } /* End namespace DD4hep                       */
 
diff --git a/DDCore/src/Segmentations.cpp b/DDCore/src/Segmentations.cpp
index f666fd02a..a34fdc88a 100644
--- a/DDCore/src/Segmentations.cpp
+++ b/DDCore/src/Segmentations.cpp
@@ -16,6 +16,7 @@
 #include "DD4hep/Segmentations.h"
 #include "DD4hep/InstanceCount.h"
 #include "DD4hep/Handle.inl"
+#include "DD4hep/Printout.h"
 
 // C/C++ include files
 #include <iostream>
@@ -32,7 +33,9 @@ DD4HEP_INSTANTIATE_HANDLE_UNNAMED(SegmentationObject);
 
 /// Standard constructor
 SegmentationObject::SegmentationObject(BaseSegmentation* s)
-  : magic(magic_word()), useForHitPosition(0), segmentation(s) {
+  : magic(magic_word()), useForHitPosition(0),
+    detector(0), sensitive(0), segmentation(s)
+{
   InstanceCount::increment(this);
 }
 
@@ -50,7 +53,9 @@ DDSegmentation::Vector3D SegmentationObject::position(const long64& cell) const
 }
 
 /// determine the cell ID based on the local position
-long64 SegmentationObject::cellID(const DDSegmentation::Vector3D& localPosition, const DDSegmentation::Vector3D& globalPosition, const long64& volID) const {
+long64 SegmentationObject::cellID(const DDSegmentation::Vector3D& localPosition,
+                                  const DDSegmentation::Vector3D& globalPosition,
+                                  const long64& volID) const {
   return segmentation->cellID(localPosition, globalPosition, volID);
 }
 
@@ -142,3 +147,63 @@ Position Segmentation::position(const long64& cell) const {
 long64 Segmentation::cellID(const Position& localPosition, const Position& globalPosition, const long64& volID) const {
   return segmentation()->cellID(localPosition, globalPosition, volID);
 }
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the geometry part of the AIDA detector description toolkit
+  namespace Geometry {
+
+    /// Access the concrete underlying segmentation implementation from DDSegmentation
+    template <typename T> T*
+    Segmentation::get(const Object* obj)   {
+      if ( obj )  {
+        DDSegmentation::Segmentation* seg = obj->segmentation;
+        T* dd_seg = dynamic_cast<T*>(seg);
+        if ( dd_seg )  {
+          return dd_seg;
+        }
+        except("CartesianGridXY",
+               "Cannot convert segmentation:%s to CartesianGridXY.",
+               seg->name());
+      }
+      return 0;
+    }
+  } /* End namespace Geometry              */
+} /* End namespace DD4hep                */
+
+#define IMPLEMENT_SEGMENTATION_HANDLE(X)                                \
+  namespace DD4hep { namespace Geometry {                               \
+      template DDSegmentation::X*                                       \
+      Segmentation::get<DDSegmentation::X>(const Object* obj); }}
+
+#include "DDSegmentation/CartesianGridXY.h"
+IMPLEMENT_SEGMENTATION_HANDLE(CartesianGridXY)
+
+#include "DDSegmentation/CartesianGridXZ.h"
+IMPLEMENT_SEGMENTATION_HANDLE(CartesianGridXZ)
+
+#include "DDSegmentation/CartesianGridYZ.h"
+IMPLEMENT_SEGMENTATION_HANDLE(CartesianGridYZ)
+
+#include "DDSegmentation/CartesianGridXYZ.h"
+IMPLEMENT_SEGMENTATION_HANDLE(CartesianGridXYZ)
+
+#include "DDSegmentation/TiledLayerGridXY.h"
+IMPLEMENT_SEGMENTATION_HANDLE(TiledLayerGridXY)
+
+#include "DDSegmentation/MegatileLayerGridXY.h"
+IMPLEMENT_SEGMENTATION_HANDLE(MegatileLayerGridXY)
+
+#include "DDSegmentation/WaferGridXY.h"
+IMPLEMENT_SEGMENTATION_HANDLE(WaferGridXY)
+
+#include "DDSegmentation/PolarGridRPhi.h"
+IMPLEMENT_SEGMENTATION_HANDLE(PolarGridRPhi)
+
+#include "DDSegmentation/PolarGridRPhi2.h"
+IMPLEMENT_SEGMENTATION_HANDLE(PolarGridRPhi2)
+
+#include "DDSegmentation/ProjectiveCylinder.h"
+IMPLEMENT_SEGMENTATION_HANDLE(ProjectiveCylinder)
+
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index b307fefd6..5299d7f21 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -580,7 +580,8 @@ template <> void Converter<Segmentation>::operator()(xml_h seg) const {
           p->setValue(seg.attr<string>(pNam));
         }
       } else if (not p->isOptional()) {
-        throw_print("FAILED to create segmentation: " + type + ". Missing mandatory parameter: " + p->name() + "!");
+        throw_print("FAILED to create segmentation: " + type +
+                    ". Missing mandatory parameter: " + p->name() + "!");
       }
     }
     long key_min = 0, key_max = 0;
@@ -889,6 +890,7 @@ template <> void Converter<DetElement>::operator()(xml_h element) const {
     }
     xml_attr_t attr_ro  = element.attr_nothrow(_U(readout));
     SensitiveDetector sd;
+    Segmentation seg;
     if (attr_ro)   {
       Readout ro = lcdd.readout(element.attr<string>(attr_ro));
       if (!ro.isValid()) {
@@ -898,6 +900,10 @@ template <> void Converter<DetElement>::operator()(xml_h element) const {
       sd.setHitsCollection(ro.name());
       sd.setReadout(ro);
       lcdd.addSensitiveDetector(sd);
+      seg = ro.segmentation();
+      if ( seg.isValid() )  {
+        seg->sensitive = sd;
+      }
     }
     Ref_t sens = sd;
     DetElement det(Ref_t(PluginService::Create<NamedObject*>(type, &lcdd, &element, &sens)));
@@ -906,6 +912,9 @@ template <> void Converter<DetElement>::operator()(xml_h element) const {
       if ( sd.isValid() )  {
         det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
       }
+      if ( seg.isValid() )  {
+        seg->detector = det;
+      }
     }
     printout(det.isValid() ? INFO : ERROR, "Compact", "%s subdetector:%s of type %s %s",
              (det.isValid() ? "++ Converted" : "FAILED    "), name.c_str(), type.c_str(),
diff --git a/DDSegmentation/include/DDSegmentation/MegatileLayerGridXY.h b/DDSegmentation/include/DDSegmentation/MegatileLayerGridXY.h
index 26f4ee591..72f9afd15 100644
--- a/DDSegmentation/include/DDSegmentation/MegatileLayerGridXY.h
+++ b/DDSegmentation/include/DDSegmentation/MegatileLayerGridXY.h
@@ -5,8 +5,8 @@
  *      Author: S. Lu, DESY
  */
 
-#ifndef DDSegmentation_WAFERGRIDXY_H_
-#define DDSegmentation_WAFERGRIDXY_H_
+#ifndef DDSegmentation_MEGATILELAYERGRIDXY_H_
+#define DDSegmentation_MEGATILELAYERGRIDXY_H_
 
 #include "DDSegmentation/CartesianGrid.h"
 
@@ -204,4 +204,4 @@ protected:
 
 } /* namespace DDSegmentation */
 } /* namespace DD4hep */
-#endif /* DDSegmentation_WAFERGRIDXY_H_ */
+#endif /* DDSegmentation_MEGATILELAYERGRIDXY_H_ */
diff --git a/doc/release.notes b/doc/release.notes
index 0bc60ab40..78d1f4637 100644
--- a/doc/release.notes
+++ b/doc/release.notes
@@ -2,6 +2,18 @@
 =================================
 DD4hep  ----  Release Notes
 =================================
+
+2016-10-18 M.Frank
+  Due to pressure of the FCC folks, I tried to implement a more DD4hep like implementation of the
+  the segmentation objects. For testing only CartesianGridXY. If this mechanism works,
+  it could be a starting recipe for the rest of the segmentations. The draw-back of this approach is,
+  that assignments are not reversible:
+  DD4hep::CartesianGridXY xy = readout.segmentation();  // Works
+  DD4hep::Segmentation seg = xy;                        // Should not work
+
+  Reason: the managed objects are different....at some point in time I will have to find a
+  clean solution for this, but the required changes for such a solution shall be manageable.
+
   --------
  | v00-17 |
   --------
-- 
GitLab