Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:58:00

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_CONDITIONS_H
0014 #define DD4HEP_CONDITIONS_H
0015 
0016 // Framework include files
0017 #include <DD4hep/IOV.h>
0018 #include <DD4hep/Handle.h>
0019 #include <DD4hep/OpaqueData.h>
0020 
0021 // C/C++ include files
0022 #include <vector>
0023 
0024 /// Namespace for the AIDA detector description toolkit
0025 namespace dd4hep {
0026 
0027   // Forward declarations
0028   class BasicGrammar;
0029   class DetElement;
0030   class Detector;
0031 
0032   /// Conditions internal namespace
0033   namespace detail  {
0034     class ConditionObject;
0035   }
0036 
0037   /// Main condition object handle.
0038   /**
0039    *  This objects allows access to the data block and
0040    *  the interval of validity for a single condition.
0041    *
0042    *  Note:
0043    *  Conditions may be shared between several DetElement objects.
0044    *  Hence, the back-link to the DetElement structure cannot be
0045    *  set - it would be ambiguous.
0046    *
0047    *  \author  M.Frank
0048    *  \version 1.0
0049    *  \ingroup DD4HEP_CONDITIONS
0050    */
0051   class Condition: public Handle<detail::ConditionObject> {
0052   public:
0053     /// Forward definition of the key type
0054     typedef unsigned long long int key_type;
0055     /// High part of the key identifies the detector element
0056     typedef unsigned int           detkey_type;
0057     /// Low part of the key identifies the item identifier
0058     typedef unsigned int           itemkey_type;
0059     /// Forward definition of the object properties
0060     typedef unsigned int           mask_type;
0061 
0062   public:
0063     /// Flags to steer the conditions conversion to string
0064     enum StringFlags  {
0065       WITH_IOV            =  1<<0,
0066       WITH_ADDRESS        =  1<<1,
0067       WITH_TYPE           =  1<<2,
0068       WITH_COMMENT        =  1<<4,
0069       WITH_DATATYPE       =  1<<5,
0070       WITH_DATA           =  1<<6,
0071       NO_NAME             =  1<<20,
0072       NONE
0073     };
0074     /// Flags to indicate the conditions type ans state
0075     enum ConditionState {
0076       INACTIVE            =  0,
0077       ACTIVE              =  1<<0,
0078       CHECKED             =  1<<2,
0079       DERIVED             =  1<<3,
0080       ONSTACK             =  1<<4,
0081       // Flags for specific conditions
0082       TEMPERATURE         =  1<<5,
0083       TEMPERATURE_DERIVED =  1<<6|DERIVED,
0084       PRESSURE            =  1<<7,
0085       PRESSURE_DERIVED    =  1<<8|DERIVED,
0086       ALIGNMENT_DELTA     =  1<<9,
0087       ALIGNMENT_DERIVED   =  1<<10|DERIVED,
0088       // Keep bit 10-15 for other generic types
0089       // Bit 16-31 is reserved for user classifications
0090       USER_FLAGS_FIRST    =  1<<16,
0091       USER_FLAGS_LAST     =  1<<31
0092     };
0093     /// Flags to indicate conditions item ranges (low word of the conditions key)
0094     enum ConditionItemRangeKeys {
0095       FIRST_ITEM_KEY      =  0x0U,
0096       LAST_ITEM_KEY       = ~0x0U
0097     };
0098     /// Flags to indicate conditions detector ranges (high word of the conditions key)
0099     enum ConditionDetectorRangeKeys {
0100       FIRST_DET_KEY       =  0x0U,
0101       LAST_DET_KEY        = ~0x0U
0102     };
0103     /// Flags to indicate global conditions ranges
0104     enum {
0105       FIRST_KEY           =  0x0ULL,
0106       LAST_KEY            = ~0x0ULL        
0107     };
0108 
0109     /// Abstract base for processing callbacks to conditions objects
0110     /**
0111      *  \author  M.Frank
0112      *  \version 1.0
0113      *  \ingroup DD4HEP_CONDITIONS
0114      */
0115     class Processor {
0116     protected:
0117       /// Move constructor
0118       Processor(Processor&& copy) = default;
0119       /// Copy constructor
0120       Processor(const Processor& copy) = default;
0121       /// Assignment operator
0122       Processor& operator=(const Processor& copy) = delete;
0123     public:
0124       /// Default constructor
0125       Processor() = default;
0126       /// Default destructor
0127       virtual ~Processor() = default;
0128       /// Processing callback
0129       virtual int process(Condition c)  const = 0;
0130       /// Conditions callback for object processing
0131       virtual int operator()(Condition c)  const
0132       {  return this->process(c);                   }
0133       /// Conditions callback for object processing in maps
0134       virtual int operator()(const std::pair<Condition::key_type,Condition>& e)  const
0135       {  return this->process(e.second);            }
0136     };
0137 
0138     /// Default constructor
0139     Condition() = default;
0140     /// Move constructor
0141     Condition(Condition&& c) = default;
0142     /// Copy constructor
0143     Condition(const Condition& c) = default;
0144     /// Initializing constructor
0145     Condition(Object* p);
0146     /// Constructor to be used when reading the already parsed object
0147     template <typename Q> Condition(const Handle<Q>& e);
0148     /// Initializing constructor for a pure, undecorated conditions object
0149     Condition(key_type hash_key);
0150     /// Initializing constructor for a pure, undecorated conditions object
0151     Condition(const std::string& name, const std::string& type);
0152     /// Initializing constructor for a pure, undecorated conditions object with payload buffer
0153     Condition(const std::string& name, const std::string& type, size_t memory);
0154     /// Assignment move operator
0155     Condition& operator=(Condition&& c) = default;
0156     /// Assignment copy operator
0157     Condition& operator=(const Condition& c) = default;
0158 
0159     /// Output method
0160     std::string str(int with_data=WITH_IOV|WITH_ADDRESS|WITH_DATATYPE)  const;
0161 
0162     /** Data block (bound type)         */
0163     /// Access the data type
0164     int dataType()  const;
0165 
0166     /** Interval of validity            */
0167     /// Access the IOV type
0168     const IOVType& iovType()  const;
0169     /// Access the IOV block
0170     const IOV& iov()  const;
0171 
0172     /** Conditions identification using integer keys.   */
0173     /// Hash identifier
0174     key_type key()  const;
0175     /// DetElement part of the identifier
0176     detkey_type  detector_key()  const;
0177     /// Item part of the identifier
0178     itemkey_type item_key()  const;
0179 
0180     /** Direct data items in string form */
0181 #if defined(DD4HEP_CONDITIONS_DEBUG) || !defined(DD4HEP_MINIMAL_CONDITIONS)
0182     /// Access the type field of the condition
0183     const std::string& type()  const;
0184     /// Access the value field of the condition as a string
0185     const std::string& value()  const;
0186     /// Access the comment field of the condition
0187     const std::string& comment()  const;
0188     /// Access the address string [e.g. database identifier]
0189     const std::string& address()  const;
0190 #endif
0191     /// Flag operations: Get condition flags
0192     mask_type flags()  const;
0193     /// Flag operations: Set a conditons flag
0194     void setFlag(mask_type option);
0195     /// Flag operations: UN-Set a conditons flag
0196     void unFlag(mask_type option);
0197     /// Flag operations: Test for a given a conditons flag
0198     bool testFlag(mask_type option) const;
0199 
0200     /** Conditions meta-data and handling of the data binding  */
0201     /// Access the opaque data block
0202     OpaqueDataBlock& data()  const;
0203     /// Access to the type information
0204     const std::type_info& typeInfo() const;
0205     /// Access to the grammar type
0206     const BasicGrammar& descriptor() const;
0207     /// Check if object is already bound....
0208     bool is_bound()  const  {  return isValid() ? data().is_bound() : false;  }
0209     /** Construct conditions object and bind the data
0210      *
0211      *  Note: The type definition is possible exactly once.
0212      *  Any further rebindings MUST match the identical type.
0213      */
0214     template <typename T, typename... Args> T& construct(Args... args);
0215     /** Bind the data of the conditions object to a given format.
0216      *
0217      *  Note: The type definition is possible exactly once.
0218      *  Any further rebindings MUST match the identical type.
0219      */
0220     template <typename T> T& bind();
0221     /** Set and bind the data of the conditions object to a given format.
0222      *
0223      *  Note: The type definition is possible exactly once.
0224      *  Any further rebindings MUST match the identical type.
0225      */
0226     template <typename T> T& bind(const std::string& val);
0227     /// Generic getter. Specify the exact type, not a polymorph type
0228     template <typename T> T& get();
0229     /// Generic getter (const version). Specify the exact type, not a polymorph type
0230     template <typename T> const T& get() const;
0231     /// Generic getter. Resolves polymorph types. It is mandatory that the datatype is polymorph!
0232     template <typename T> T& as();
0233     /// Generic getter (const version). Resolves polymorph types. It is mandatory that the datatype is polymorph!
0234     template <typename T> const T& as() const;
0235 
0236     /// Allow to trace condition names from keys for debugging
0237     static int haveInventory(int value = -1);
0238   };
0239 
0240   /// Initializing constructor
0241   inline Condition::Condition(Condition::Object* p)
0242     : Handle<Condition::Object>(p)  {}
0243 
0244   /// Constructor to be used when reading the already parsed object
0245   template <typename Q> inline Condition::Condition(const Handle<Q>& e)
0246     : Handle<Condition::Object>(e) {}
0247 
0248   /// Construct conditions object and bind the data
0249   template <typename T, typename... Args> T& Condition::construct(Args... args)   {
0250     return data().construct<T,Args...>(args...);
0251   }
0252   /// Bind the data of the conditions object to a given format.
0253   template <typename T> inline T& Condition::bind()   {
0254     return data().bind<T>();
0255   }
0256   /// Bind the data of the conditions object to a given format and fill data from string representation.
0257   template <typename T> inline T& Condition::bind(const std::string& val)   {
0258     return data().bind<T>(val);
0259   }
0260   /// Generic getter. Specify the exact type, not a polymorph type
0261   template <typename T> inline T& Condition::get() {
0262     return data().get<T>();
0263   }
0264   /// Generic getter (const version). Specify the exact type, not a polymorph type
0265   template <typename T> inline const T& Condition::get() const {
0266     return data().get<T>();
0267   }    
0268   /// Generic getter. Specify the exact type, not a polymorph type
0269   template <typename T> inline T& Condition::as() {
0270     return data().as<T>();
0271   }
0272   /// Generic getter (const version). Specify the exact type, not a polymorph type
0273   template <typename T> inline const T& Condition::as() const {
0274     return data().as<T>();
0275   }
0276     
0277   /// Key definition to optimize ans simplyfy the access to conditions entities
0278   /**
0279    *  \author  M.Frank
0280    *  \version 1.0
0281    *  \ingroup DD4HEP_CONDITIONS
0282    */
0283   class ConditionKey  {
0284   public:
0285 #if defined(DD4HEP_CONDITIONS_HAVE_NAME)
0286     /// Optional string identifier. Helps debugging a lot!
0287     std::string  name;
0288 #endif
0289     /// Hashed key representation
0290     Condition::key_type     hash = 0;
0291 
0292     /// Helper union to interprete conditions keys
0293     /**
0294      *  \author  M.Frank
0295      *  \version 1.0
0296      *  \ingroup DD4HEP_CONDITIONS
0297      */
0298     union KeyMaker  {
0299       Condition::key_type  hash;
0300       /** Note: The memory layout is important here to have properly
0301        *        ordered maps. The detector key MUST be on the high end 
0302        *        of the resulting int64 'hash'.
0303        */
0304       struct {
0305         Condition::itemkey_type item_key;
0306         Condition::detkey_type  det_key;
0307       } values;
0308       KeyMaker()  {
0309         this->hash = 0;
0310       }
0311       KeyMaker(Condition::key_type k)  {
0312         this->hash = k;
0313       }
0314       KeyMaker(Condition::detkey_type det, Condition::itemkey_type item)  {
0315         this->values.det_key  = det;
0316         this->values.item_key = item;
0317       }
0318       /// Constructor from string
0319       KeyMaker(Condition::detkey_type det, const std::string& value);
0320       /// Constructor from string
0321       KeyMaker(DetElement detector, const std::string& value);
0322       /// Constructor from detector element and item sub-key
0323       KeyMaker(DetElement detector, Condition::itemkey_type item_key);
0324     };
0325     
0326     /// Compare keys by the hash value
0327     /**
0328      *  \author  M.Frank
0329      *  \version 1.0
0330      *  \ingroup DD4HEP_CONDITIONS
0331      */
0332     struct HashCompare {
0333       Condition::key_type key;
0334       HashCompare(Condition::key_type k) : key(k) {}
0335       bool operator==(const ConditionKey& k) const { return key==k.hash; }
0336     };
0337   public:
0338     /// Default constructor
0339     ConditionKey() = default;
0340     /// Constructor from fully qualified key
0341     ConditionKey(Condition::key_type key) : hash(key) {}
0342     /// Constructor from string
0343     ConditionKey(DetElement detector, const std::string& identifier);
0344     /// Constructor from detector element key and item sub-key
0345     ConditionKey(Condition::detkey_type det_key, const std::string& identifier);
0346     /// Constructor from detector element and item sub-key
0347     ConditionKey(DetElement detector, Condition::itemkey_type item_key);
0348     /// Constructor from detector element key and item sub-key
0349     ConditionKey(Condition::detkey_type det_key, Condition::itemkey_type item_key);
0350     /// Copy constructor
0351     ConditionKey(const ConditionKey& c) = default;
0352 
0353     /// Access the detector element part of the key
0354     Condition::detkey_type detector_key()  const   {
0355       return KeyMaker(hash).values.det_key;
0356     }
0357     /// Access the detector element part of the key
0358     Condition::itemkey_type item_key()  const   {
0359       return KeyMaker(hash).values.item_key;
0360     }
0361     /// Hash code generation from input string
0362     static Condition::key_type hashCode(DetElement detector, const char* value);
0363     /// Hash code generation from input string
0364     static Condition::key_type hashCode(DetElement detector, const std::string& value);
0365     /// 32 bit hashcode of the item
0366     static Condition::itemkey_type itemCode(const char* value);
0367     /// 32 bit hashcode of the item
0368     static Condition::itemkey_type itemCode(const std::string& value);
0369        
0370     /// Assignment operator from object copy
0371     ConditionKey& operator=(const ConditionKey& key) = default;
0372     /// Equality operator using key object
0373     bool operator==(const ConditionKey& compare)  const;
0374     /// Equality operator using hash value
0375     bool operator==(const Condition::key_type compare)  const;
0376     /// Equality operator using the string representation
0377     //bool operator==(const std::string& compare)  const;
0378 
0379     /// Operator less (for map insertions) using key object
0380     bool operator<(const ConditionKey& compare)  const;
0381     /// Operator less (for map insertions) using hash value
0382     bool operator<(const Condition::key_type compare)  const;
0383     /// Automatic conversion to the hashed representation of the key object
0384     operator Condition::key_type () const   {  return hash;     }
0385     /// Conversion to string
0386     std::string toString()  const;
0387   };
0388 
0389   /// Constructor from detector element key and item sub-key
0390   inline ConditionKey::ConditionKey(Condition::detkey_type det_key, Condition::itemkey_type item_key)  {
0391     hash = KeyMaker(det_key,item_key).hash;
0392   }
0393     
0394   /// Equality operator using key object
0395   inline bool ConditionKey::operator==(const ConditionKey& compare)  const
0396   {  return hash == compare.hash;                            }
0397 
0398   /// Equality operator using hash value
0399   inline bool ConditionKey::operator==(const Condition::key_type compare)  const
0400   {  return hash == compare;                                 }
0401 
0402   /// Operator less (for map insertions) using key object
0403   inline bool ConditionKey::operator<(const ConditionKey& compare)  const
0404   {  return hash < compare.hash;                             }
0405 
0406   /// Operator less (for map insertions) using hash value
0407   inline bool ConditionKey::operator<(const Condition::key_type compare)  const
0408   {  return hash < compare;                                  }
0409 
0410 
0411   /// Conditions selector functor. Default implementation selects everything evaluated.
0412   /**
0413    *  Please note:
0414    *  This class should never be directly instantiated by the user.
0415    *  A typical use-case is to do so in a wrapper class, which contains a refernce
0416    *  to a counter object, which in turn allows to deduce information from the
0417    *  processed objects.
0418    *
0419    *  See class ConditionsSelectWrapper below
0420    *
0421    *  \author  M.Frank
0422    *  \version 1.0
0423    *  \ingroup DD4HEP_CONDITIONS
0424    */
0425   class ConditionsSelect   {
0426   protected:
0427     /// Default constructor
0428     ConditionsSelect() = default;
0429     /// Copy constructor
0430     ConditionsSelect(const ConditionsSelect& copy) = default;
0431     /// Default destructor. 
0432     virtual ~ConditionsSelect();
0433     /// Default assignment operator
0434     ConditionsSelect& operator=(const ConditionsSelect& copy) = default;
0435 
0436   public:
0437     /// Selection callback: return true if the condition should be selected
0438     bool operator()(Condition cond)  const  { return (*this)(cond.ptr()); }
0439     /// Selection callback: return true if the condition should be selected
0440     bool operator()(std::pair<Condition::key_type,Condition::Object*> cond) const
0441     /** Arg is 2 longwords. No need to pass by reference.                      */
0442     { return (*this)(cond.second);            }
0443     /// Selection callback: return true if the condition should be selected
0444     /** Arg is 2 longwords. No need to pass by reference.                      */
0445     bool operator()(std::pair<Condition::key_type,Condition> cond) const
0446     { return (*this)(cond.second.ptr());      }
0447 
0448     /// Overloadable entry: Return number of conditions selected. Default does nothing....
0449     virtual size_t size()  const  { return 0; }
0450     /// Overloadable entry: Selection callback: return true if the condition should be selected
0451     virtual bool operator()(Condition::Object* cond) const = 0;
0452   };
0453 
0454   /// Conditions selector functor. Wraps a user defined object by reference
0455   /**
0456    *  Example usage for the slow ones:
0457    *
0458    *  class MyCounter : public ConditionsSelectWrapper<long> {
0459    *    MyCounter(long& cnt) : ConditionsSelectWrapper<long>(cnt) {}
0460    *    virtual bool operator()(Condition::Object* cond) const { if ( cond != 0 ) ++object; }
0461    *    // Optionally overload: virtual size_t size()  const  { return object; }
0462    *  };
0463    *  
0464    *  long counter = 0;
0465    *  for_each(std::begin(conditons), std::end(conditions), MyCounter(counter));
0466    *
0467    *  \author  M.Frank
0468    *  \version 1.0
0469    *  \ingroup DD4HEP_CONDITIONS
0470    */
0471   template <typename OBJECT> class ConditionsSelectWrapper : public ConditionsSelect {
0472   private:
0473     /// Default constructor
0474     ConditionsSelectWrapper() = delete;
0475     /// Default assignment operator
0476     bool operator==(const ConditionsSelectWrapper& compare) = delete;
0477 
0478   public:
0479     /// Reference to the infomation collector
0480     OBJECT& object;
0481 
0482   public:
0483     /// Default constructor
0484     ConditionsSelectWrapper(OBJECT& o) : ConditionsSelect(), object(o) {}
0485     /// Copy constructor
0486     ConditionsSelectWrapper(const ConditionsSelectWrapper& copy) = default;
0487     /// Default destructor. 
0488     virtual ~ConditionsSelectWrapper() = default;
0489     /// Default assignment operator
0490     ConditionsSelectWrapper& operator=(const ConditionsSelectWrapper& copy) = default;
0491   };
0492 
0493   // Utility type definitions
0494   typedef std::vector<Condition>          RangeConditions;
0495 
0496   /// Conditions internal namespace
0497   namespace detail  {
0498     /// Setup conditions item name inventory for debugging
0499     /** Populate a conditions item name inventory to ease debugging
0500      *  missing dependencies for derived conditions, which otherwise is
0501      *  difficult in optimized mode where all string values are suppressed.
0502      *
0503      *  Note: the inventory gets populated while creating item dependencies etc.
0504      *  Enabling afterwards has no effect.
0505      *
0506      *  value < 0  Return current value
0507      *  value = 0  Disable inventory for performance issues
0508      *  value > 0  Enable inventory population
0509      *
0510      *  \author  M.Frank
0511      *  \version 1.0
0512      *  \ingroup DD4HEP_CONDITIONS
0513      */
0514     int have_condition_item_inventory(int value = -1);
0515 
0516     
0517     /// Resolve key from conditions item name inventory for debugging
0518     /** The functionhave_condition_item_inventory must be called
0519      *  before items get populated to fill the inventory.....
0520      *
0521      *  key: conditions item key
0522      *
0523      *  \author  M.Frank
0524      *  \version 1.0
0525      *  \ingroup DD4HEP_CONDITIONS
0526      */
0527     std::string get_condition_item_name(Condition::itemkey_type key);
0528 
0529     /// Resolve key from conditions item name inventory for debugging
0530     /** The functionhave_condition_item_inventory must be called
0531      *  before items get populated to fill the inventory.....
0532      *
0533      *  key: full condition item hash
0534      *
0535      *  \author  M.Frank
0536      *  \version 1.0
0537      *  \ingroup DD4HEP_CONDITIONS
0538      */
0539     std::string get_condition_item_name(Condition::key_type key);
0540   }
0541   
0542 }          /* End namespace dd4hep                   */
0543 #endif // DD4HEP_CONDITIONS_H