Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-03 07:54:14

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