From 44e4f5ee9014fa868e910fe9c23b0c97eae66cb7 Mon Sep 17 00:00:00 2001
From: Frank Gaede <frank.gaede@desy.de>
Date: Fri, 5 Feb 2016 14:11:59 +0000
Subject: [PATCH]   - added DetElement::typeFlag() and
 DetElement::setTypeFlag(unsigned int types)   - added
 LCDDImp::detectors(unsigned int typeFlag, bool bitsSet)   -> allows to set
 detector properties (with DetType) for DetElements and     get sets of
 detectors with certain properties, e.g.     ( DetType::TRACKER |
 DetType::BARREL ) selects all barrel trackers

---
 DDCore/include/DD4hep/DetType.h               |  5 ++++
 DDCore/include/DD4hep/Detector.h              | 10 ++++++--
 DDCore/include/DD4hep/LCDD.h                  |  6 +++++
 .../include/DD4hep/objects/DetectorInterna.h  |  2 ++
 DDCore/src/Detector.cpp                       | 12 ++++++++++
 DDCore/src/DetectorInterna.cpp                |  5 ++--
 DDCore/src/LCDDImp.cpp                        | 23 ++++++++++++++++++
 DDCore/src/LCDDImp.h                          |  4 ++++
 UtilityApps/src/dumpdetector.cpp              | 24 +++++++++++++++++++
 9 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/DDCore/include/DD4hep/DetType.h b/DDCore/include/DD4hep/DetType.h
index 26db8d95a..fe881a348 100644
--- a/DDCore/include/DD4hep/DetType.h
+++ b/DDCore/include/DD4hep/DetType.h
@@ -82,6 +82,11 @@ namespace DD4hep {
       return ( _type & prop ) == 0 ;
     }
 
+    /// return the flag word
+    inline unsigned long to_ulong() const {
+      return _type ;
+    }
+
   private:
     unsigned long _type ;
   } ;
diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index e2cf3ca49..d54c285e0 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -328,13 +328,19 @@ namespace DD4hep {
       /// Getter: Combine hits attribute
       bool combineHits() const;
 
-      /// Access detector type (structure, tracker, calorimeter, etc.).
-      /** Required for determination of G4 sensitive detector.
+      /** Access detector type (structure, tracker, calorimeter, etc.).
+       *  Required for determination of G4 sensitive detector.
        */
       std::string type() const;
       ///  Set detector type (structure, tracker, calorimeter, etc.).
       DetElement& setType(const std::string& typ);
 
+      // Return flag word encoding detector types ( ideally use DD4hep::DetType for decoding )
+      unsigned int typeFlag() const;
+
+      ///  Set the flag word encoding detector types ( ideally use DD4hep::DetType for encoding )
+      DetElement& setTypeFlag(unsigned int types);
+
       /// Path of the detector element (not necessarily identical to placement path!)
       std::string path() const;
       /// Access to the full path to the placed object
diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h
index ec4126837..adfa62832 100644
--- a/DDCore/include/DD4hep/LCDD.h
+++ b/DDCore/include/DD4hep/LCDD.h
@@ -177,6 +177,12 @@ namespace DD4hep {
 
       /// Access the availible detector types
       virtual std::vector<std::string> detectorTypes() const = 0;
+
+
+      /** return a vector with all detectors that have all the given type properties set
+       *  or not set depending on bitsSet.
+       */
+      virtual std::vector<DetElement> detectors(unsigned int typeFlag, bool bitsSet=true ) const = 0 ;
 #endif
 
       /** Miscaneleous accessors to the detexctor description  */
diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h
index e913ae95b..d10fdeb06 100644
--- a/DDCore/include/DD4hep/objects/DetectorInterna.h
+++ b/DDCore/include/DD4hep/objects/DetectorInterna.h
@@ -97,6 +97,8 @@ namespace DD4hep {
       int id;
       /// Flag to process hits
       int combineHits;
+     /// Flag to encode detector types
+      unsigned int typeFlag;
       /// Full path to this detector element. May be invalid
       std::string path;
       /// The path to the placement of the detector element (if placed)
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index 5b1aeb1ed..5742b477a 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -89,6 +89,18 @@ DetElement& DetElement::setType(const string& typ) {
   return *this;
 }
 
+
+unsigned int DetElement::typeFlag() const {
+  return m_element ? m_element->typeFlag :  0 ;
+}
+
+/// Set the type of the sensitive detector
+DetElement& DetElement::setTypeFlag(unsigned int types) {
+  Object* o = access();
+  o->typeFlag = types ;
+  return *this;
+}
+
 string DetElement::path() const {
   Object* o = ptr();
   if ( o ) {
diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp
index 6eb172600..98965a2ec 100644
--- a/DDCore/src/DetectorInterna.cpp
+++ b/DDCore/src/DetectorInterna.cpp
@@ -61,7 +61,7 @@ SensitiveDetectorObject::~SensitiveDetectorObject() {
 /// Default constructor
 DetElementObject::DetElementObject()
   : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()),
-    flag(0), id(0), combineHits(0), path(), placementPath(),
+    flag(0), id(0), combineHits(0), typeFlag(0), path(), placementPath(),
     idealPlace(), placement(), volumeID(0), parent(), reference(), children(),
     alignment(), volume_alignments(), conditions(),
     worldTrafo(), parentTrafo(), referenceTrafo(0) {
@@ -72,7 +72,7 @@ DetElementObject::DetElementObject()
 /// Initializing constructor
 DetElementObject::DetElementObject(const std::string& nam, int ident)
   : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()),
-    flag(0), id(ident), combineHits(0), path(), placementPath(),
+    flag(0), id(ident), combineHits(0), typeFlag(0), path(), placementPath(),
     idealPlace(), placement(), volumeID(0), parent(), reference(), children(),
     alignment(), volume_alignments(), conditions(),
     worldTrafo(), parentTrafo(), referenceTrafo(0) {
@@ -98,6 +98,7 @@ DetElementObject::~DetElementObject() {
 DetElementObject* DetElementObject::clone(int new_id, int flg) const {
   DetElementObject* obj = new DetElementObject();
   obj->id = new_id;
+  obj->typeFlag = typeFlag;
   obj->flag = 0;
   obj->combineHits = combineHits;
   obj->alignment = Alignment();
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index 016d0a684..c29136112 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -343,6 +343,29 @@ const vector<DetElement>& LCDDImp::detectors(const string& type)  {
   throw runtime_error("detectors("+type+"): Detectors can only selected by type once the geometry is closed!");
 }
 
+vector<DetElement> LCDDImp::detectors(unsigned int typeFlag, bool bitsSet) const  {
+  if( ! m_manager->IsClosed() ) {
+    throw runtime_error("detectors(typeFlag): Detectors can only selected by typeFlag once the geometry is closed!");
+  }
+  vector<DetElement> dets ;
+  dets.reserve( m_detectors.size() ) ;
+  
+  unsigned int compFlag = ( bitsSet ? typeFlag : 0 ) ;
+  
+  for(HandleMap::const_iterator i=m_detectors.begin(); i!=m_detectors.end(); ++i)   {
+    DetElement det((*i).second);
+    if ( det.parent().isValid() )  { // Exclude 'world'
+      
+      //fixme: what to do with compounds - add their daughters  ?
+      // ...
+
+      if( ( det.typeFlag() &  typeFlag ) == compFlag )
+	dets.push_back( det ) ;
+    }
+  }
+  return dets ;
+}
+
 /// Access a set of subdetectors according to several sensitive types.
 vector<DetElement> LCDDImp::detectors(const string& type1,
                                       const string& type2,
diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h
index e3af755d1..bb35c2ebf 100644
--- a/DDCore/src/LCDDImp.h
+++ b/DDCore/src/LCDDImp.h
@@ -271,6 +271,10 @@ namespace DD4hep {
       /// Access the availible detector types
       virtual std::vector<std::string> detectorTypes() const;
 
+      /// return a vector with all detectors that have all the given type properties set/ not set.
+      virtual std::vector<DetElement> detectors(unsigned int typeFlag, bool bitsSet=true ) const ;
+
+
 #define __R  return *this
       /// Add a new constant to the detector description
       virtual LCDD& add(Constant x) {
diff --git a/UtilityApps/src/dumpdetector.cpp b/UtilityApps/src/dumpdetector.cpp
index a0d37d087..bfd01b217 100644
--- a/UtilityApps/src/dumpdetector.cpp
+++ b/UtilityApps/src/dumpdetector.cpp
@@ -18,6 +18,7 @@
 
 // Framework include files
 #include "DD4hep/LCDD.h"
+#include "DD4hep/DetType.h"
 #include "DD4hep/DD4hepUnits.h"
 
 #include "DDRec/Surface.h"
@@ -62,6 +63,17 @@ void printDetectorData( DetElement det ){
 
 }
 
+void printDetectorSets( std::string name, unsigned int typeFlag ){
+
+  LCDD& lcdd = LCDD::getInstance();
+  const std::vector<DetElement>& dets = lcdd.detectors( typeFlag ) ;
+  std::cout << " " << name  ;
+  for(int i=0,N=dets.size();i<N;++i)  
+    std::cout << dets[i].name() << ", " ;
+  std::cout << endl ;
+} 
+
+
 //=============================================================================
 
 int main(int argc, char** argv ){
@@ -99,6 +111,14 @@ int main(int argc, char** argv ){
 	    << "    author : " << h.author() << std::endl 
 	    << "    status : " << h.status() << std::endl ;
 
+
+  printDetectorSets( " barrel trackers : " , ( DetType::TRACKER | DetType::BARREL ) ) ; 
+  printDetectorSets( " endcap trackers : " , ( DetType::TRACKER | DetType::ENDCAP ) ) ; 
+
+  printDetectorSets( " barrel calorimeters : " , ( DetType::CALORIMETER | DetType::BARREL ) ) ; 
+  printDetectorSets( " endcap calorimeters : " , ( DetType::CALORIMETER | DetType::ENDCAP ) ) ; 
+
+
   if( printDetData ){
 
     DD4hep::Geometry::LCDD::HandleMap dets = lcdd.detectors() ;
@@ -109,6 +129,10 @@ int main(int argc, char** argv ){
 
       std::cout << " ---------------------------- " << det.name() << " ----------------------------- " << std::endl ;
 
+      DetType type( det.typeFlag() ) ;
+      
+      std::cout << " ------     " << type << std:: endl ;
+
       printDetectorData( det ) ;
 
     }
-- 
GitLab