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_CONDITIONDERIVED_H
0014 #define DD4HEP_CONDITIONDERIVED_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Memory.h>
0018 #include <DD4hep/Conditions.h>
0019 #include <DD4hep/detail/ConditionsInterna.h>
0020 
0021 // C/C++ include files
0022 #include <memory>
0023 
0024 /// Namespace for the AIDA detector description toolkit
0025 namespace dd4hep {
0026 
0027   /// Grammar definition for type binding
0028   class BasicGrammar;
0029 
0030   /// Namespace for the conditions part of the AIDA detector description toolkit
0031   namespace cond   {
0032 
0033     /// Forward declarations
0034     class DependencyBuilder;
0035     class ConditionResolver;
0036     class ConditionDependency;
0037     class ConditionUpdateCall;
0038     class ConditionUpdateContext;
0039     class ConditionUpdateUserContext;
0040 
0041     /// ConditionUpdateUserContext class used by the derived conditions calculation mechanism
0042     /** 
0043      *  Used to pass user data to the update calls during ConditionsManager::prepare
0044      *
0045      *  \author  M.Frank
0046      *  \version 1.0
0047      *  \ingroup DD4HEP_CONDITIONS
0048      */
0049     class ConditionUpdateUserContext  {
0050     public:
0051       /// Default destructor
0052       virtual ~ConditionUpdateUserContext();
0053     };
0054     
0055     /// ConditionResolver class used by the derived conditions calculation mechanism
0056     /**
0057      *  \author  M.Frank
0058      *  \version 1.0
0059      *  \ingroup DD4HEP_CONDITIONS
0060      */
0061     class ConditionResolver   {
0062     public:
0063       /// Standard destructor
0064       virtual ~ConditionResolver();
0065       /// Access to the conditions manager
0066       virtual Handle<NamedObject> manager() const = 0;
0067       /// Access to the detector description instance
0068       virtual Detector& detectorDescription() const = 0;
0069       /// Required IOV value for update cycle
0070       virtual const IOV& requiredValidity()  const = 0;
0071       /// Accessor for the current conditons mapping
0072       virtual ConditionsMap& conditionsMap() const = 0;
0073       /// Interface to access conditions by conditions key
0074       virtual Condition get(const ConditionKey& key) = 0;
0075       /// Interface to access conditions by conditions key
0076       virtual Condition get(const ConditionKey& key, bool throw_if_not) = 0;
0077       /// Interface to access conditions by hash value
0078       virtual Condition get(Condition::key_type key) = 0;
0079       /// Interface to access conditions by hash value
0080       virtual Condition get(Condition::key_type key, bool throw_if_not) = 0;
0081       /// Interface to access conditions by hash value
0082       virtual Condition get(Condition::key_type key,
0083                             const ConditionDependency* dependency,
0084                             bool throw_if_not) = 0;
0085       /// Interface to access conditions by hash value of the DetElement (only valid at resolve!)
0086       virtual std::vector<Condition> get(DetElement de) = 0;
0087       /// Interface to access conditions by hash value of the DetElement (only valid at resolve!)
0088       virtual std::vector<Condition> get(Condition::detkey_type key) = 0;
0089       /// Interface to access conditions by hash value of the item (only valid at resolve!)
0090       virtual std::vector<Condition> getByItem(Condition::itemkey_type key) = 0;
0091 
0092       /// Interface to handle multi-condition inserts by callbacks: One single insert
0093       /** Note: block insertions are nearly ALWAYS preferred!!! 
0094        */
0095       virtual bool registerOne(const IOV& iov, Condition cond)  = 0;
0096       /// Handle multi-condition inserts by callbacks: block insertions of conditions with identical IOV
0097       virtual size_t registerMany(const IOV& iov, const std::vector<Condition>& values) = 0;
0098       /// Handle multi-condition inserts by callbacks with identical key. Handle unmapped containers
0099       template <typename CONT> size_t registerUnmapped(const IOV& iov, CONT& c)   {
0100         std::vector<Condition> conditions;
0101         conditions.reserve(c.size());
0102         std::copy(std::begin(c), std::end(c), std::back_inserter(conditions));
0103         return this->registerMany(iov, conditions);
0104       }
0105       /// Handle multi-condition inserts by callbacks with identical key. Handle mapped containers
0106       template <typename CONT> size_t registerMapping(const IOV& iov, CONT& c)     {
0107         std::vector<Condition> conditions;
0108         conditions.reserve(c.size());
0109         std::transform(std::begin(c), std::end(c), std::back_inserter(conditions), detail::get_2nd<CONT>());
0110         return this->registerMany(iov, conditions);
0111       }
0112     };
0113 
0114     /// ConditionUpdateContext class used by the derived conditions calculation mechanism
0115     /** 
0116      *  This is the central object used by the functional callbacks to
0117      *  build derived conditions. All optionally necessary information
0118      *  can and must be accessed by this object.
0119      *
0120      *  Please node:
0121      *  1) Be careful when resolving other conditions
0122      *     These calls are IN GENERAL ONLY VALID AT RESOLVE !
0123      *     Otherwise the resulting IOV shall be wrong !
0124      *  2) Only accessing the conditions using the context ensure that the
0125      *     IOV of the resulting derived condition is correct.
0126      *     The conditions resolver does not affect the resulting IOV.
0127      *  3) Though the access to the resolver under certain circumstances
0128      *     is useful, you should always be aware that to IOV intersection
0129      *     shall be wrong, since these accessed conditions are not taken 
0130      *     into account.
0131      *
0132      *  \author  M.Frank
0133      *  \version 1.0
0134      *  \ingroup DD4HEP_CONDITIONS
0135      */
0136     class ConditionUpdateContext final  {
0137     public:
0138       /// Internal reference to the resolver to access other conditions (Be careful)
0139       ConditionResolver*          resolver;
0140       /// The dependency to be handled within this context
0141       const ConditionDependency*  dependency;
0142       /// The reference to the combined IOV resulting from the cumputation
0143       IOV*                        iov;
0144       /// A refernce to the user parameter
0145       ConditionUpdateUserContext* parameter;
0146 
0147     public:
0148       /// Initializing constructor
0149       ConditionUpdateContext(ConditionResolver* r,
0150                              const ConditionDependency* d,
0151                              IOV* iov,
0152                              ConditionUpdateUserContext* parameter);
0153       
0154       /// Throw exception on conditions access failure
0155       void accessFailure(const ConditionKey& key_value)  const;
0156 
0157       /// Access to the detector description instance
0158       Detector& detectorDescription() const   {
0159         return resolver->detectorDescription();
0160       }
0161 
0162       /// Access to the top level detector element
0163       DetElement world()  const;
0164 
0165       /// Required IOV value for update cycle
0166       const IOV& requiredValidity()  const   {
0167         return resolver->requiredValidity();
0168       }
0169 
0170       /// Accessor for the current conditons mapping
0171       ConditionsMap& conditionsMap() const    {
0172         return resolver->conditionsMap();
0173       }
0174 
0175       /// Access to dependency keys
0176       const ConditionKey& key(size_t which)  const;
0177 
0178       /// Access user parameter
0179       template<typename Q> Q* param()  const  {
0180         return static_cast<Q*>(parameter);
0181       }
0182 
0183       /// Access to all conditions of a detector element.
0184       /** Careful: This limits the validity!
0185        *  ONLY VALID AT RESOLVE !
0186        *  Otherwise the resulting IOV shall be wrong !
0187        */
0188       std::vector<Condition> conditions(DetElement det)  const    {
0189         return conditions(det.key());
0190       }
0191 
0192       /// Access to all conditions of a detector element key.
0193       /** Careful: This limits the validity!
0194        *  ONLY VALID AT RESOLVE !
0195        *  Otherwise the resulting IOV shall be wrong !
0196        */
0197       std::vector<Condition> conditions(Condition::detkey_type det_key)  const;
0198 
0199       /// Access conditions by the condition item key
0200       /** Careful: This limits the validity!
0201        *  ONLY VALID AT RESOLVE !
0202        *  Otherwise the resulting IOV shall be wrong !
0203        */
0204       std::vector<Condition> getByItem(Condition::itemkey_type key)   const;
0205 
0206       /// Access to condition object by dependency key
0207       /** Careful: This limits the validity!
0208        *  ONLY VALID AT RESOLVE !
0209        *  Otherwise the resulting IOV shall be wrong !
0210        */
0211       Condition condition(const ConditionKey& key_value)  const;
0212 
0213       /// Access to condition object by dependency key
0214       /** Careful: This limits the validity!
0215        *  ONLY VALID AT RESOLVE !
0216        *  Otherwise the resulting IOV shall be wrong !
0217        */
0218       Condition condition(Condition::key_type key_value)  const;
0219 
0220       /// Access to condition object by dependency key
0221       /** Careful: This limits the validity!
0222        *  ONLY VALID AT RESOLVE !
0223        *  Otherwise the resulting IOV shall be wrong !
0224        */
0225       Condition condition(Condition::key_type key_value, bool throw_if_not)  const;
0226 
0227       /// Access of other conditions data from the resolver
0228       /** Careful: This limits the validity!
0229        *  ONLY VALID AT RESOLVE !
0230        *  Otherwise the resulting IOV shall be wrong !
0231        */
0232       template<typename T> T& get(const ConditionKey& key_value);
0233 
0234       /// Access of other conditions data from the resolver
0235       /** Careful: This limits the validity!
0236        *  ONLY VALID AT RESOLVE !
0237        *  Otherwise the resulting IOV shall be wrong !
0238        */
0239       template<typename T> const T& get(const ConditionKey& key_value)  const;
0240 
0241       /// Access of other conditions data from the resolver
0242       /** Careful: This limits the validity!
0243        *  ONLY VALID AT RESOLVE !
0244        *  Otherwise the resulting IOV shall be wrong !
0245        */
0246       template<typename T> T& get(Condition::key_type key_value);
0247 
0248       /// Access of other conditions data from the resolver
0249       /** Careful: This limits the validity!
0250        *  ONLY VALID AT RESOLVE !
0251        *  Otherwise the resulting IOV shall be wrong !
0252        */
0253       template<typename T> const T& get(Condition::key_type key_value)  const;
0254 
0255       /// Interface to handle multi-condition inserts by callbacks: One single insert
0256       /** Note: block insertions are nearly ALWAYS preferred!!! 
0257        */
0258       bool registerOne(const IOV& iov, Condition cond);
0259       /// Handle multi-condition inserts by callbacks: block insertions of conditions with identical IOV
0260       size_t registerMany(const IOV& iov, const std::vector<Condition>& values);
0261       /// Handle multi-condition inserts by callbacks with identical key. Handle unmapped containers
0262       template <typename CONT> size_t registerUnmapped(const IOV& iov_val, CONT& values)   {
0263         std::vector<Condition> conds;
0264         conds.reserve(values.size());
0265         std::copy(std::begin(values), std::end(values), std::back_inserter(conds));
0266         return this->registerMany(iov_val, conds);
0267       }
0268       /// Handle multi-condition inserts by callbacks with identical key. Handle mapped containers
0269       template <typename CONT> size_t registerMapping(const IOV& iov_val, CONT& values)     {
0270         std::vector<Condition> conds;
0271         conds.reserve(values.size());
0272         std::transform(std::begin(values), std::end(values), std::back_inserter(conds), detail::get_2nd<CONT>());
0273         return this->registerMany(iov_val, conds);
0274       }
0275     };
0276 
0277     /// Callback interface
0278     /**
0279      *  \author  M.Frank
0280      *  \version 1.0
0281      *  \ingroup DD4HEP_CONDITIONS
0282      */
0283     class ConditionUpdateCall  {
0284     protected:
0285       /// Standard destructor
0286       ConditionUpdateCall();
0287       /// No copy constructor
0288       ConditionUpdateCall(const ConditionUpdateCall& copy) = delete;
0289       /// Standard destructor
0290       virtual ~ConditionUpdateCall();
0291       /// No assignment operator
0292       ConditionUpdateCall& operator=(const ConditionUpdateCall& copy) = delete;
0293 
0294     public:
0295       /// Interface to client callback in order to update/create the condition
0296       virtual Condition operator()(const ConditionKey& target,
0297                                    ConditionUpdateContext& ctxt) = 0;
0298       /// Interface to client callback for resolving references or to use data from other conditions
0299       virtual void resolve(Condition /* c */, ConditionUpdateContext& /* ctxt */)   {}
0300     };
0301 
0302     /// Condition dependency definition
0303     /**
0304      *  Used by clients to update a condition.
0305      *
0306      *  Note:
0307      *  We later in DDCond have to do many many set intersections of references to these
0308      *  objects. For this reason we do not want to use std::shared_ptr<ConditionDependency>.
0309      *  For this reason we implement here a simple ref'counting mechanism, which later
0310      *  allows us to use bare pointers.
0311      *
0312      *  \author  M.Frank
0313      *  \version 1.0
0314      *  \ingroup DD4HEP_CONDITIONS
0315      */
0316     class ConditionDependency    {
0317       friend std::default_delete<ConditionDependency>;
0318     protected:
0319       /// Reference count
0320       int                                  m_refCount {0};
0321 
0322     public:
0323       /// Reference to the target's detector element
0324       DetElement                           detector;
0325       /// Key to the condition to be updated
0326       ConditionKey                         target {0};
0327       /// Dependency keys this condition depends on
0328       std::vector<ConditionKey>            dependencies;
0329       /// Reference to the update callback. No auto pointer. callback may be shared
0330       std::shared_ptr<ConditionUpdateCall> callback;
0331 
0332     protected:
0333       /// Copy constructor
0334       ConditionDependency(const ConditionDependency& c) = delete;
0335       /// Assignment operator
0336       ConditionDependency& operator=(const ConditionDependency& c) = delete;
0337       /// Default destructor
0338       virtual ~ConditionDependency();
0339 
0340     public:
0341       /// Initializing constructor used by builder
0342       ConditionDependency(DetElement de, const std::string& item, std::shared_ptr<ConditionUpdateCall> call);
0343       /// Initializing constructor used by builder
0344       ConditionDependency(DetElement de, Condition::itemkey_type item_key, std::shared_ptr<ConditionUpdateCall> call);
0345       /// Default constructor
0346       ConditionDependency();
0347       /// Access the dependency key
0348       Condition::key_type key()  const    {  return target.hash;                   }
0349 #if defined(DD4HEP_CONDITIONS_HAVE_NAME)
0350       /// Access the dependency key
0351       const char* name()  const           {  return target.name.c_str();           }
0352 #endif
0353       /// Add use count to the object
0354       ConditionDependency* addRef()       {  ++m_refCount; return this;            }
0355       /// Release object. May not be used any longer
0356       void release()                      {  if ( --m_refCount <= 0 ) delete this; }
0357     };
0358 
0359     /// Condition dependency builder
0360     /**
0361      *  \author  M.Frank
0362      *  \version 1.0
0363      *  \ingroup DD4HEP_CONDITIONS
0364      */
0365     class DependencyBuilder  {
0366     protected:
0367       /// The created dependency
0368       std::unique_ptr<ConditionDependency> m_dependency;
0369     public:
0370       /// Initializing constructor
0371       DependencyBuilder(DetElement de, Condition::itemkey_type item_key, std::shared_ptr<ConditionUpdateCall> call);
0372       /// Initializing constructor
0373       DependencyBuilder(DetElement de, const std::string& item, std::shared_ptr<ConditionUpdateCall> call);
0374       /// Default destructor
0375       virtual ~DependencyBuilder();
0376       /// Access underlying object directly
0377       ConditionDependency* operator->()  {   return m_dependency.operator->(); }
0378       /// Add a new dependency
0379       void add(const ConditionKey& source_key);
0380       /// Release the created dependency and take ownership.
0381       ConditionDependency* release();
0382     };
0383 
0384     /// Initializing constructor
0385     inline ConditionUpdateContext::ConditionUpdateContext(ConditionResolver* resolv,
0386                                                           const ConditionDependency* dep,
0387                                                           IOV* i,
0388                                                           ConditionUpdateUserContext* user_param)
0389       : resolver(resolv), dependency(dep), iov(i), parameter(user_param)
0390     {
0391     }
0392 
0393     /// Access to dependency keys
0394     inline const ConditionKey&
0395     ConditionUpdateContext::key(size_t which)  const  {
0396       return dependency->dependencies.at(which);
0397     }
0398 
0399     /// Access of other conditions data from the resolver
0400     template<typename T> inline T&
0401     ConditionUpdateContext::get(const ConditionKey& key_value)   {
0402       Condition cond = condition(key_value);
0403       if ( cond.isValid() )  {
0404         return cond.get<T>();       /// return already bound data to wanted type
0405       }
0406       accessFailure(key_value);
0407       throw std::runtime_error("ConditionUpdateCall");
0408     }
0409 
0410     /// Access of other conditions data from the resolver
0411     template<typename T> inline const T&
0412     ConditionUpdateContext::get(const ConditionKey& key_value)  const  {
0413       Condition cond = condition(key_value);
0414       if ( cond.isValid() )  {
0415         return cond.get<T>();       /// return already bound data to wanted type
0416       }
0417       accessFailure(key_value);
0418       throw std::runtime_error("ConditionUpdateCall");
0419     }
0420 
0421     /// Access of other conditions data from the resolver
0422     template<typename T> inline T&
0423     ConditionUpdateContext::get(Condition::key_type key_value)    {
0424       return condition(key_value).get<T>();
0425     }
0426 
0427     /// Access of other conditions data from the resolver
0428     template<typename T> inline const T&
0429     ConditionUpdateContext::get(Condition::key_type key_value)  const   {
0430       return condition(key_value).get<T>();
0431     }
0432 
0433   }       /* End namespace cond               */
0434 }         /* End namespace dd4hep                   */
0435 #endif // DD4HEP_CONDITIONDERIVED_H