Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:32

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DD4HEP_DETELEMENT_H
0014 #define DD4HEP_DETELEMENT_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Handle.h>
0018 #include <DD4hep/Callback.h>
0019 #include <DD4hep/Objects.h>
0020 #include <DD4hep/Volumes.h>
0021 #include <DD4hep/Readout.h>
0022 #include <DD4hep/Alignments.h>
0023 #include <DD4hep/Segmentations.h>
0024 #include <DD4hep/ObjectExtensions.h>
0025 
0026 // C/C++ include files
0027 #include <map>
0028 #include <typeinfo>
0029 
0030 /// Namespace for the AIDA detector description toolkit
0031 namespace dd4hep {
0032 
0033   // Forward declarations
0034   class Detector;
0035   class DetElementObject;
0036   class SensitiveDetectorObject;
0037 
0038   /// Handle class to hold the information of a sensitive detector.
0039   /**
0040    *  \author  M.Frank
0041    *  \version 1.0
0042    *  \ingroup DD4HEP_CORE
0043    */
0044   class SensitiveDetector: public Handle<SensitiveDetectorObject> {
0045   public:
0046 
0047     /// Default constructor
0048     SensitiveDetector() : Handle<SensitiveDetectorObject>() {     }
0049 
0050     /// Constructor to copy handled object
0051     SensitiveDetector(Object* obj_pointer)
0052       : Handle<SensitiveDetectorObject>(obj_pointer) {      }
0053 
0054     /// Move from named handle
0055     SensitiveDetector(Handle<SensitiveDetectorObject>&& sd)
0056       : Handle<SensitiveDetectorObject>(sd) {      }
0057 
0058     /// Copy from named handle
0059     SensitiveDetector(const Handle<SensitiveDetectorObject>& sd)
0060       : Handle<SensitiveDetectorObject>(sd) {      }
0061 
0062     /// Move from handle
0063     SensitiveDetector(SensitiveDetector&& sd) = default;
0064 
0065     /// Copy from handle
0066     SensitiveDetector(const SensitiveDetector& sd) = default;
0067 
0068     /// Templated constructor for handle conversions
0069     template <typename Q> SensitiveDetector(const Handle<Q>& e)
0070       : Handle<SensitiveDetectorObject>(e) { }
0071 
0072     /// Constructor for a new sensitive detector element
0073     SensitiveDetector(const std::string& name, const std::string& type = "sensitive");
0074 
0075     /// Assignment move operator
0076     SensitiveDetector& operator=(SensitiveDetector&& sd)  = default;
0077 
0078     /// Assignment copy operator
0079     SensitiveDetector& operator=(const SensitiveDetector& sd)  = default;
0080 
0081     /// Equality operator
0082     template <typename T> bool operator ==(const Handle<T>& e) const {
0083       return ptr() == e.ptr();
0084     }
0085     /// Non-Equality operator
0086     template <typename T> bool operator !=(const Handle<T>& e) const {
0087       return ptr() != e.ptr();
0088     }
0089 
0090     /// Access the type of the sensitive detector
0091     std::string type() const;
0092 
0093     ///  Set detector type (structure, tracker, calorimeter, etc.).
0094     SensitiveDetector& setType(const std::string& typ);
0095 
0096     /// Set flag to handle hits collection
0097     SensitiveDetector& setVerbose(bool value);
0098 
0099     /// Access flag to combine hist
0100     bool verbose() const;
0101 
0102     /// Set flag to handle hits collection
0103     SensitiveDetector& setCombineHits(bool value);
0104 
0105     /// Access flag to combine hist
0106     bool combineHits() const;
0107 
0108     /// Assign the name of the hits collection
0109     SensitiveDetector& setHitsCollection(const std::string& spec);
0110 
0111     /// Access the hits collection name
0112     const std::string& hitsCollection() const;
0113 
0114     /// Assign the IDDescriptor reference
0115     SensitiveDetector& setReadout(Readout readout);
0116 
0117     /// Access readout structure of the sensitive detector
0118     Readout readout() const;
0119 
0120     /// Access IDDescription structure
0121     IDDescriptor idSpec() const;
0122 
0123     /// Set energy cut off
0124     SensitiveDetector& setEnergyCutoff(double value);
0125 
0126     /// Access energy cut off
0127     double energyCutoff() const;
0128 
0129     /// Set the regional attributes to the sensitive detector
0130     SensitiveDetector& setRegion(Region reg);
0131 
0132     /// Access to the region setting of the sensitive detector (not mandatory)
0133     Region region() const;
0134 
0135     /// Set the limits to the sensitive detector
0136     SensitiveDetector& setLimitSet(LimitSet limits);
0137 
0138     /// Access to the limit set of the sensitive detector (not mandatory).
0139     LimitSet limits() const;
0140 
0141     /// Add an extension object to the detector element
0142     void* addExtension(unsigned long long int key, ExtensionEntry* entry)  const;
0143 
0144     /// Access an existing extension object from the detector element
0145     void* extension(unsigned long long int key) const;
0146 
0147     /// Access an existing extension object from the detector element
0148     void* extension(unsigned long long int key, bool alert) const;
0149 
0150     /// Extend the sensitive detector element with an arbitrary structure accessible by the type
0151     template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c)  const {
0152       return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(),
0153                                          new detail::DeleteExtension<IFACE,CONCRETE>(c));
0154     }
0155 
0156     /// Access extension element by the type
0157     template <typename IFACE> IFACE* extension() const {
0158       return (IFACE*) this->extension(detail::typeHash64<IFACE>());
0159     }
0160   };
0161 
0162   /// Handle class describing a detector element
0163   /**
0164    * Detector elements (class DetElement are entities which represent
0165    * subdetectors or sizable parts of a subdetector.
0166    * A DetElement instance has the means to provide to clients information about
0167    *
0168    *    -  the detector hierarchy by exposing its children.
0169    *    -  its placement within the overall experiment if it represents an
0170    *       entire subdetector or its placement with respect to its parent
0171    *       if the \em DetElement represents a part of a subdetector.
0172    *    -  information about the \em Readout structure if the object is
0173    *       instrumented and read-out. Otherwise this link is empty.
0174    *    -  information about the environmental conditions etc. \em conditons.
0175    *       The access to conditions is exposed via the DetConditions interface.
0176    *       See dd4hep/DetConditions.h for further details.
0177    *    -  alignment information.
0178    *
0179    *  Reflection Note:
0180    *    -  Reflecting a detector element is NOT the same as "clone".
0181    *       The placed volumes of the reflected detector element and the
0182    *       corresponding volumes/shapes have left-handed coordinates!
0183    *
0184    *  \author  M.Frank
0185    *  \version 1.0
0186    *  \ingroup DD4HEP_CORE
0187    */
0188   class DetElement: public Handle<DetElementObject>  {
0189   public:
0190     /// Abstract base for processing callbacks to DetElement objects
0191     /**
0192      *  \author  M.Frank
0193      *  \version 1.0
0194      *  \ingroup DD4HEP_CORE
0195      */
0196     class Processor {
0197     public:
0198       /// Default constructor
0199       Processor();
0200       /// Default destructor
0201       virtual ~Processor();
0202       /// Container callback for object processing
0203       virtual int processElement(DetElement detector) = 0;
0204     };
0205 
0206     typedef std::map<std::string, DetElement> Children;
0207 
0208     enum CopyParameters {
0209       COPY_NONE           = 0,
0210       COPY_PLACEMENT      = 1 << 0,
0211       COPY_PARENT         = 1 << 1,
0212       COPY_ALIGNMENT      = 1 << 2,
0213       PROPAGATE_PARENT_ID = 1 << 3,
0214       LAST
0215     };
0216 
0217     enum UpdateParam {
0218       CONDITIONS_CHANGED  = 1<<0,
0219       PLACEMENT_CHANGED   = 1<<1,
0220       SOMETHING_CHANGED   = 1<<2,
0221       PLACEMENT_ELEMENT   = 1<<20,
0222       PLACEMENT_HIGHEST   = 1<<21,
0223       PLACEMENT_DETECTOR  = 1<<22,
0224       PLACEMENT_NONE
0225     };
0226 
0227     /// Internal assert function to check conditions
0228     void check(bool condition, const std::string& msg) const;
0229 
0230   protected:
0231 
0232     /// Wrapper class for detector element extension objects
0233     /** A wrapper class is necessary for the ROOT persistency of extension objects
0234      *
0235      *  \author  M.Frank
0236      *  \version 1.0
0237      *  \ingroup DD4HEP_CORE
0238      */
0239     template <typename Q, typename T> class DetElementExtension : public ExtensionEntry  {
0240     protected:
0241       T* ptr = 0;
0242       mutable Q* iface = 0;  //!
0243     public:
0244       /// Inhibit default constructor
0245       DetElementExtension() = delete;
0246       /// Typed objects constructor
0247       DetElementExtension(T* p) : ptr(p) {  iface = dynamic_cast<Q*>(p); }
0248       /// Copy constructor
0249       DetElementExtension(const DetElementExtension& copy) = default;
0250       /// Assignment operator
0251       DetElementExtension& operator=(const DetElementExtension& copy) = default;
0252       /// Default destructor
0253       virtual ~DetElementExtension() = default;
0254       /// This one ensures we have the correct signatures
0255       T* copy(DetElement de)  const                 { return new T(*ptr,de);   }
0256       /// Wrapper for the object destruction
0257       virtual void  destruct()  const override      { delete ptr;              }
0258       /// Wrapper to access the desired interface
0259       virtual void* object()  const override
0260       { return iface ? iface : (iface=dynamic_cast<Q*>(ptr));                  }
0261       /// Copy/clone the object
0262       virtual void* copy(void* det)  const override
0263       { return copy(DetElement((Object*)det));                                 }
0264       /// Copy/clone the object
0265       virtual ExtensionEntry* clone(void* det)  const  override
0266       {  return new DetElementExtension<Q,T>((T*)this->copy(det));             }
0267       /// Hash value
0268       virtual unsigned long long int hash64()  const override
0269       {  return detail::typeHash64<Q>();                                       }
0270     };
0271 
0272     /// Internal call to extend the detector element with an arbitrary structure accessible by the type
0273     void i_addUpdateCall(unsigned int callback_type, const Callback& callback)  const;
0274 
0275   public:
0276 
0277     /// Default constructor
0278     DetElement() = default;
0279 
0280     /// Constructor to move handle
0281     DetElement(DetElement&& e) = default;
0282 
0283     /// Constructor to copy handle
0284     DetElement(const DetElement& e) = default;
0285 
0286     /// Constructor to hold handled object
0287     DetElement(Object* obj) : Handle<DetElementObject>(obj) { }
0288 
0289     /// Clone constructor
0290     DetElement(Object* obj, const std::string& name, const std::string& type);
0291 
0292     /// Templated constructor for handle conversions
0293     template <typename Q> DetElement(const Handle<Q>& e) : Handle<DetElementObject>(e) {}
0294 
0295     /// Constructor to hold handled object
0296     DetElement(NamedObject* obj) : Handle<DetElementObject>(obj) { }
0297 
0298 #ifdef __MAKECINT__
0299     /// Constructor to copy handle
0300     DetElement(const Ref_t& e) : Handle<DetElementObject>(e) {  }
0301 #endif
0302     /// Constructor for a new subdetector element
0303     DetElement(const std::string& name, const std::string& type, int id);
0304 
0305     /// Constructor for a new subdetector element
0306     DetElement(const std::string& name, int id);
0307 
0308     /// Constructor for a new subdetector element
0309     DetElement(DetElement parent, const std::string& name, int id);
0310 
0311     /// Assignment move operator
0312     DetElement& operator=(DetElement&& sd)  = default;
0313     /// Assignment copy operator
0314     DetElement& operator=(const DetElement& e) = default;
0315 
0316     /// Additional data accessor
0317     Object& _data() const {
0318       return object<Object>();
0319     }
0320 
0321     /// Operator less to insert into a map
0322     bool operator <(const DetElement e) const {
0323       return ptr() < e.ptr();
0324     }
0325     /// Equality operator
0326     template <typename T> bool operator ==(const Handle<T>& e) const {
0327       return ptr() == e.ptr();
0328     }
0329     /// Non-Equality operator
0330     template <typename T> bool operator !=(const Handle<T>& e) const {
0331       return ptr() != e.ptr();
0332     }
0333 
0334     /// Clone (Deep copy) the DetElement structure
0335     DetElement clone(int flag) const;
0336 
0337     /// Clone (Deep copy) the DetElement structure with a new name
0338     DetElement clone(const std::string& new_name) const;
0339 
0340     /// Clone (Deep copy) the DetElement structure with a new name and new identifier
0341     DetElement clone(const std::string& new_name, int new_id) const;
0342 
0343     /// Reflect (Deep copy) the DetElement structure with a new name
0344     std::pair<DetElement,Volume> reflect(const std::string& new_name) const;
0345 
0346     /// Reflect (Deep copy) the DetElement structure with a new name and new identifier
0347     std::pair<DetElement,Volume> reflect(const std::string& new_name, int new_id) const;
0348     /// Reflect (Deep copy) the DetElement structure with a new name and new identifier and new sensitive detector
0349     std::pair<DetElement,Volume> reflect(const std::string& new_name, int new_id, SensitiveDetector sd) const;
0350 
0351     /// Add an extension object to the detector element
0352     void* addExtension(ExtensionEntry* entry) const;
0353 
0354     /// Access an existing extension object from the detector element
0355     void* extension(unsigned long long int key, bool alert) const;
0356 
0357     /// Extend the detector element with an arbitrary structure accessible by the type
0358     template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) const {
0359       CallbackSequence::checkTypes(typeid(IFACE), typeid(CONCRETE), dynamic_cast<IFACE*>(c));
0360       return (IFACE*) this->addExtension(new DetElementExtension<IFACE,CONCRETE>(c));
0361     }
0362     /// Access extension element by the type
0363     template <typename IFACE> IFACE* extension() const {
0364       return (IFACE*) this->extension(detail::typeHash64<IFACE>(),true);
0365     }
0366     /// Access extension element by the type
0367     template <typename IFACE> IFACE* extension(bool alert) const {
0368       return (IFACE*) this->extension(detail::typeHash64<IFACE>(),alert);
0369     }
0370     /// Extend the detector element with an arbitrary callback
0371     template <typename Q, typename T>
0372     void callAtUpdate(unsigned int typ, Q* pointer,
0373                       void (T::*pmf)(unsigned long typ, DetElement& det, void* opt_par)) const
0374     {
0375       CallbackSequence::checkTypes(typeid(T), typeid(Q), dynamic_cast<T*>(pointer));
0376       i_addUpdateCall(typ, Callback(pointer).make(pmf));
0377     }
0378     /// Remove callback from object
0379     void removeAtUpdate(unsigned int type, void* pointer) const;
0380 
0381     /// Get the detector identifier
0382     int id() const;
0383     /// Setter: Combine hits attribute
0384     DetElement& setCombineHits(bool value, SensitiveDetector& sens);
0385     /// Getter: Combine hits attribute
0386     bool combineHits() const;
0387 
0388     /** Access detector type (structure, tracker, calorimeter, etc.).
0389      *  Required for determination of G4 sensitive detector.
0390      */
0391     std::string type() const;
0392     ///  Set detector type (structure, tracker, calorimeter, etc.).
0393     DetElement&  setType(const std::string& typ);
0394 
0395     // Return flag word encoding detector types ( ideally use dd4hep::DetType for decoding )
0396     unsigned int typeFlag() const;
0397 
0398     ///  Set the flag word encoding detector types ( ideally use dd4hep::DetType for encoding )
0399     DetElement&  setTypeFlag(unsigned int types);
0400 
0401     /// Access hash key of this detector element (Only valid once geometry is closed!)
0402     unsigned int key()  const;
0403     /// Access the hierarchical level of the detector element (Only valid once geometry is closed!)
0404     int level()  const;
0405     /// Path of the detector element (not necessarily identical to placement path!)
0406     const std::string& path() const;
0407     /// Access to the full path to the placed object
0408     const std::string& placementPath() const;
0409 
0410     /// Set all attributes in one go
0411     DetElement& setAttributes(const Detector& description,
0412                               const Volume& volume,
0413                               const std::string& region,
0414                               const std::string& limits,
0415                               const std::string& vis);
0416 
0417     /// Set Visualization attributes to the detector element
0418     DetElement& setVisAttributes(const Detector& description, const std::string& name, const Volume& volume);
0419     /// Set the regional attributes to the detector element
0420     DetElement& setRegion(const Detector& description, const std::string& name, const Volume& volume);
0421     /// Set the limits to the detector element
0422     DetElement& setLimitSet(const Detector& description, const std::string& name, const Volume& volume);
0423 
0424     /// Access to the logical volume of the detector element's placement
0425     Volume volume() const;
0426     /// Access to the shape of the detector element's placement
0427     Solid solid() const;
0428 
0429     /// Access to the physical volume of this detector element
0430     /** This is the current placement value of the detector eleemnt.
0431      *  A possible global re-alignment may alter the value.
0432      *  Hence, it should hence not be cached.
0433      */
0434     PlacedVolume placement() const;
0435     /// Access to the ideal physical volume of this detector element
0436     /** This is the original placement set in the detector constructor.
0437      *  A possible global re-alignment make this value different
0438      *  from the regular placement() call.
0439      */
0440     PlacedVolume idealPlacement() const;
0441     /// Set the physical volumes of the detector element
0442     DetElement&  setPlacement(const PlacedVolume& volume);
0443     /// The cached VolumeID of this subdetector element
0444     VolumeID     volumeID() const;
0445 
0446     /// Add new child to the detector structure
0447     DetElement&  add(DetElement sub_element);
0448     /// Access to the list of children
0449     const Children& children() const;
0450     /// Access to individual children by name
0451     DetElement child(const std::string& name) const;
0452     /// Access to individual children by name. Have option to not throw an exception
0453     DetElement child(const std::string& child_name, bool throw_if_not_found) const;
0454     /// Access to the detector elements's parent
0455     DetElement parent() const;
0456     /// Access to the world object. Only possible once the geometry is closed.
0457     DetElement world()  const;
0458 
0459     /// Access to the constant ideal (nominal) alignment information
0460     Alignment nominal() const;
0461     /// Access to the constant survey alignment information
0462     Alignment survey() const;
0463   };
0464 } /* End namespace dd4hep        */
0465 
0466 #include <DD4hep/AlignmentData.h>
0467 
0468 #endif // DD4HEP_DETELEMENT_H