diff --git a/DDCond/include/DDCond/ConditionsAccess.h b/DDCond/include/DDCond/ConditionsAccess.h new file mode 100644 index 0000000000000000000000000000000000000000..c467dc1acc783c24e842ad4b64b31a358b3f8ac0 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsAccess.h @@ -0,0 +1,83 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_DDCOND_CONDITIONSACCESS_H +#define DD4HEP_DDCOND_CONDITIONSACCESS_H + +// Framework include files +#include "DD4hep/Conditions.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class ConditionsManagerObject; + + /// Manager class for condition handles + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsAccess : public Handle<ConditionsManagerObject> { + public: + + /// Standard object type + typedef ConditionsManagerObject Object; + + public: + + /// Default constructor + ConditionsAccess() : Handle<Object>() {} + + /// Constructor to be used with valid pointer to object + ConditionsAccess(Object* p) : Handle<Object>(p) {} + + /// Constructor to assing handle of the same type + ConditionsAccess(const ConditionsAccess& c) + : Handle<Object>(c) { + } + + /// Constructor to be used assigning from different type + template <typename Q> ConditionsAccess(const Handle<Q>& e) + : Handle<Object>(e) { + } + + /// Default destructor + ~ConditionsAccess(); + + /// Access the used/registered IOV types + const std::vector<const IOVType*> iovTypesUsed() const; + + /// Access IOV by its name + const IOVType* iovType (const std::string& iov_name) const; + + /// Clean conditions, which are above the age limit. + void clean(const IOVType* typ, int max_age); + + /// Retrieve a condition given a Detector Element and the conditions name + Condition get(Condition::key_type key, const Condition::iov_type& req_validity); + /// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> + Condition get(const std::string& path, const Condition::iov_type& req_validity); + /// Retrieve a condition given a Detector Element and the conditions name + RangeConditions getRange(Condition::key_type key, const Condition::iov_type& req_validity); + /// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> + RangeConditions getRange(const std::string& path, const Condition::iov_type& req_validity); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDCOND_CONDITIONSACCESS_H */ diff --git a/DDCond/include/DDCond/ConditionsDataLoader.h b/DDCond/include/DDCond/ConditionsDataLoader.h index 78948d20fe4effc0dca3956d57a1bb34844bd162..213c89a9dab71939fae119a6fe280cea206d387b 100644 --- a/DDCond/include/DDCond/ConditionsDataLoader.h +++ b/DDCond/include/DDCond/ConditionsDataLoader.h @@ -45,16 +45,18 @@ namespace DD4hep { class ConditionsDataLoader : public NamedObject, public PropertyConfigurable { public: typedef std::pair<std::string, IOV> Source; - typedef std::vector<Source> Sources; - typedef ConditionsDataLoader base_t; + typedef std::vector<Source> Sources; + typedef ConditionsDataLoader base_t; + typedef Condition::iov_type iov_type; + typedef Condition::key_type key_type; protected: /// Reference to main detector description object - LCDD& m_lcdd; + LCDD& m_lcdd; /// Reference to conditions manager used to queue update requests ConditionsManager m_mgr; /// Property: input data source definitions - Sources m_sources; + Sources m_sources; protected: /// Queue update to manager. @@ -68,20 +70,18 @@ namespace DD4hep { /// Default destructor virtual ~ConditionsDataLoader(); /// Add data source definition to loader - void addSource(const std::string& source, const IOV& iov); + void addSource(const std::string& source, const iov_type& iov); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load(DetElement det, - const std::string& cond, - const IOV& req_validity, + virtual size_t load(key_type key, + const iov_type& req_validity, RangeConditions& conditions) = 0; /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load_range(DetElement det, - const std::string& cond, - const IOV& req_validity, + virtual size_t load_range(key_type key, + const iov_type& req_validity, RangeConditions& conditions) = 0; - virtual size_t update(const IOV& req_validity, + virtual size_t update(const iov_type& req_validity, RangeConditions& conditions, - IOV& conditions_validity) = 0; + iov_type& conditions_validity) = 0; }; } /* End namespace Conditions */ diff --git a/DDCond/include/DDCond/ConditionsDependencyHandler.h b/DDCond/include/DDCond/ConditionsDependencyHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..f9d742d2aa5c68c1801901504392ddd9d01f6b05 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsDependencyHandler.h @@ -0,0 +1,81 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSDEPENDENCYHANDLER_H +#define DDCOND_CONDITIONSDEPENDENCYHANDLER_H + +// Framework include files +#include "DD4hep/Detector.h" +#include "DD4hep/Conditions.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsManager.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class UserPool; + + /// Callback handler to update condition dependencies. + /** + * + * \author M.Frank + * \version 1.0 + */ + class ConditionsDependencyHandler : public ConditionResolver { + public: + typedef Geometry::LCDD LCDD; + typedef ConditionsManager::Dependencies Dependencies; + + protected: + /// Reference to conditions manager + ConditionsManager::Object* m_manager; + /// Reference to the user pool object + UserPool& m_pool; + /// Dependency container to be resolved. + const Dependencies& m_dependencies; + + /// Internal call to trigger update callback + Condition::Object* do_callback(const ConditionDependency* dep) const; + + public: + /// Initializing constructor + ConditionsDependencyHandler(ConditionsManager::Object* mgr, + UserPool& pool, + const Dependencies& dependencies); + /// Default destructor + ~ConditionsDependencyHandler(); + /// ConditionResolver implementation: Access to the conditions manager + virtual Ref_t manager() const + { return m_manager; } + /// ConditionResolver implementation: Access to the detector description instance + virtual LCDD& lcdd() const + { return m_manager->lcdd(); } + virtual const IOV& requiredValidity() const + { return m_pool.validity(); } + /// ConditionResolver implementation: Interface to access conditions. + virtual Condition get(const ConditionKey& key) const + { return get(key.hash); } + /// ConditionResolver implementation: Interface to access conditions + virtual Condition get(unsigned int key) const; + /// Handler callback to process multiple derived conditions + Condition::Object* operator()(const ConditionDependency* dep) const; + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSDEPENDENCYHANDLER_H */ diff --git a/DDCond/include/DDCond/ConditionsEntry.h b/DDCond/include/DDCond/ConditionsEntry.h index e34b6dc2c8c97fd41de69868d44e39fd2b78eb6c..769881c4e356c27c73ebb316d5b99acade9a47de 100644 --- a/DDCond/include/DDCond/ConditionsEntry.h +++ b/DDCond/include/DDCond/ConditionsEntry.h @@ -37,7 +37,7 @@ namespace DD4hep { class Entry : public NamedObject { public: /// Reference to the detector element - DetElement detector; + Geometry::DetElement detector; /// The actual conditions data std::string value; /// The validity string to be interpreted by the updating engine @@ -47,7 +47,7 @@ namespace DD4hep { /// Default constructor Entry() {} /// Initializing constructor - Entry(const DetElement& det, const std::string& nam, const std::string& typ, const std::string& valid, int hash); + Entry(const Geometry::DetElement& det, const std::string& nam, const std::string& typ, const std::string& valid, int hash); /// Copy constructor Entry(const Entry& c); /// Default destructor diff --git a/DDCond/include/DDCond/ConditionsIOVPool.h b/DDCond/include/DDCond/ConditionsIOVPool.h index 7319c39deba76e1fb75458d78e8aea8a1b205f0e..2b67ecfa66128a42a549341ed5352ce506d56728 100644 --- a/DDCond/include/DDCond/ConditionsIOVPool.h +++ b/DDCond/include/DDCond/ConditionsIOVPool.h @@ -40,34 +40,24 @@ namespace DD4hep { */ class ConditionsIOVPool { public: - typedef ConditionsPool* Entry; - typedef std::map<IOV::Key, Entry > Entries; - typedef std::set<int> Keys; - - Entries entries; - Keys keys; - Keys traced_keys; + typedef ConditionsPool* Element; + typedef std::map<IOV::Key, Element > Elements; + Elements elements; + public: /// Default constructor ConditionsIOVPool(); /// Default destructor virtual ~ConditionsIOVPool(); - bool addKey(Condition c); - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - void __find(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result); - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - void __find_range(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result); + /// Retrieve a condition set given the key according to their validity + void select(Condition::key_type key, const Condition::iov_type& req_validity, RangeConditions& result); + /// Retrieve a condition set given the key according to their validity + void selectRange(Condition::key_type key, const Condition::iov_type& req_validity, RangeConditions& result); /// Select all ACTIVE conditions, which do no longer match the IOV requirement - void select(const IOV& required_validity, + void select(const Condition::iov_type& required_validity, RangeConditions& valid, RangeConditions& expired, - IOV& conditions_validity); + Condition::iov_type& conditions_validity); /// Remove all key based pools with an age beyon the minimum age. /** @return Number of conditions cleaned up and removed. */ int clean(int max_age); diff --git a/DDCond/include/DDCond/ConditionsInterna.h b/DDCond/include/DDCond/ConditionsInterna.h index 90f775f50877d8c5bd681184a0a2d294bb47a13b..ff6b06f8baa7371384a58f6abd6f91adf5c8b029 100644 --- a/DDCond/include/DDCond/ConditionsInterna.h +++ b/DDCond/include/DDCond/ConditionsInterna.h @@ -17,7 +17,11 @@ // Framework include files% #include "DD4hep/Mutex.h" #include "DD4hep/Memory.h" +#include "DD4hep/Callback.h" #include "DD4hep/Conditions.h" +#include "DD4hep/ConditionDerived.h" +#include "DD4hep/ObjectExtensions.h" + #include "DDCond/ConditionsPool.h" #include "DDCond/ConditionsIOVPool.h" #include "DDCond/ConditionsDataLoader.h" @@ -46,7 +50,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - namespace Interna { + //namespace Interna { /// The data class behind a conditions manager handle /** @@ -57,173 +61,165 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - class ConditionsManagerObject : public NamedObject, public PropertyConfigurable { - friend class DD4hep::Conditions::ConditionsPool; - friend class DD4hep::Conditions::ConditionsDataLoader; - - public: - typedef dd4hep_ptr<ConditionsDataLoader> Loader; - typedef std::vector<IOVType> IOVTypes; - typedef std::vector<ConditionsIOVPool*> TypedConditionPool; - - typedef std::map<IOV::Key, ReplacementPool*> ReplacementCache; - typedef std::vector<ReplacementPool*> FreePools; - typedef std::pair<ConditionsListener*,void*> Listener; - typedef std::set<Listener> Listeners; - - public: - /// Property: maximal number of IOV types to be handled - int m_maxIOVTypes; - /// Property: ConditionsPool constructor type (default: empty. MUST BE SET!) - std::string m_poolType; - /// Property: UpdatePool constructor type (default: DD4hep_ConditionsLinearUpdatePool) - std::string m_updateType; - /// Property: UserPool constructor type (default: DD4hep_ConditionsLinearUserPool) - std::string m_userType; - /// Property: Conditions loader type (default: "multi" -> DD4hep_Conditions_multi_Loader) - std::string m_loaderType; - - /// Reference to main detector description object - LCDD& m_lcdd; - /// Collection of IOV types managed - IOVTypes m_iovTypes; - /// Managed pool of typed conditions idexed by IOV-type and IOV key - TypedConditionPool m_pool; - /// Conditions listeners on registration of new conditions - Listeners m_onRegister; - /// Conditions listeners on de-registration of new conditions - Listeners m_onRemove; - /// Lock to protect the update/delayed conditions pool - dd4hep_mutex_t m_updateLock; - /// Lock to protect the pool of all known conditions - dd4hep_mutex_t m_poolLock; - /// Reference to data loader - Loader m_loader; - /// Reference to update conditions pool - dd4hep_ptr<UpdatePool> m_updatePool; - /// Public access: if locked, DetElements stay intact and are not altered - int locked; - - protected: - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - bool __find(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& conditions); - - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - bool __find_range(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& conditions); - - /// Load a condition set given a Detector Element and the conditions name according to their validity - bool __load_immediate(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& conditions); - /// Load a condition set given a Detector Element and the conditions name according to their validity - bool __load_range_immediate(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& conditions); - /// Register a set of new managed condition for an IOV range. Called by __load_immediate - void __register_immediate(RangeConditions& c); - - /// Push registered set of conditions to the corresponding detector elements - void __push_immediate(RangeConditions& rc); - - void registerCallee(Listeners& listeners, const Listener& callee, bool add); - - /// Listener invocation when a condition is registered to the cache - void onRegister(Condition condition); - - /// Listener invocation when a condition is deregistered from the cache - void onRemove(Condition condition); - - public: - /// Set a single conditions value to be managed. - /// Requires EXTERNALLY held lock on update pool! - Condition __queue_update(Entry* data); - - public: - /// Standard constructor - ConditionsManagerObject(LCDD& lcdd); - - /// Default destructor - virtual ~ConditionsManagerObject(); - - void initialize(); - - /// (Un)Registration of conditions listeners with callback when a new condition is registered - void callOnRegister(const Listener& callee, bool add); - /// (Un)Registration of conditions listeners with callback when a condition is unregistered - void callOnRemove(const Listener& callee, bool add); - - /// Register new IOV type if it does not (yet) exist. - /** Returns (false,pointer) if IOV existed and - * (true,pointer) if new IOV was registered to the manager. - */ - std::pair<bool, const IOVType*> registerIOVType(size_t iov_type, const std::string& iov_name); + class ConditionsManagerObject : public NamedObject, + public PropertyConfigurable, + public ObjectExtensions + { + friend class DD4hep::Conditions::ConditionsPool; + friend class DD4hep::Conditions::ConditionsDataLoader; + + public: + typedef dd4hep_ptr<ConditionsDataLoader> Loader; + typedef std::vector<IOVType> IOVTypes; + typedef std::vector<ConditionsIOVPool*> TypedConditionPool; + typedef std::pair<ConditionsListener*,void*> Listener; + typedef std::set<Listener> Listeners; + typedef ConditionsManager::Dependencies Dependencies; + typedef Condition::key_type key_type; + typedef Condition::iov_type iov_type; + + public: + /// Property: maximal number of IOV types to be handled + int m_maxIOVTypes; + /// Property: ConditionsPool constructor type (default: empty. MUST BE SET!) + std::string m_poolType; + /// Property: UpdatePool constructor type (default: DD4hep_ConditionsLinearUpdatePool) + std::string m_updateType; + /// Property: UserPool constructor type (default: DD4hep_ConditionsLinearUserPool) + std::string m_userType; + /// Property: Conditions loader type (default: "multi" -> DD4hep_Conditions_multi_Loader) + std::string m_loaderType; + + /// Reference to main detector description object + LCDD& m_lcdd; + /// Collection of IOV types managed + IOVTypes m_iovTypes; + /// Managed pool of typed conditions indexed by IOV-type and IOV key + TypedConditionPool m_rawPool; + /// Conditions listeners on registration of new conditions + Listeners m_onRegister; + /// Conditions listeners on de-registration of new conditions + Listeners m_onRemove; + /// Lock to protect the update/delayed conditions pool + dd4hep_mutex_t m_updateLock; + /// Lock to protect the pool of all known conditions + dd4hep_mutex_t m_poolLock; + /// Reference to data loader + Loader m_loader; + /// Reference to update conditions pool + dd4hep_ptr<UpdatePool> m_updatePool; + + /// Public access: if locked, DetElements stay intact and are not altered + int locked; + + protected: + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + bool select(key_type key, const iov_type& req_validity, RangeConditions& conditions); + + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + bool select_range(key_type key, const iov_type& req_validity, RangeConditions& conditions); + + /// Register a set of new managed condition for an IOV range. Called by __load_immediate + // void __register_immediate(RangeConditions& c); + + void registerCallee(Listeners& listeners, const Listener& callee, bool add); + + /// Listener invocation when a condition is registered to the cache + void onRegister(Condition condition); + + /// Listener invocation when a condition is deregistered from the cache + void onRemove(Condition condition); + + public: + /// Set a single conditions value to be managed. + /// Requires EXTERNALLY held lock on update pool! + Condition __queue_update(Conditions::Entry* data); + + public: + /// Standard constructor + ConditionsManagerObject(LCDD& lcdd); + + /// Default destructor + virtual ~ConditionsManagerObject(); + + /// Access to the detector description instance + LCDD& lcdd() const { return m_lcdd; } + + /// Access to managed pool of typed conditions indexed by IOV-type and IOV key + const TypedConditionPool& conditionsPool() const { return m_rawPool; } + + ConditionsDataLoader* loader() const { return m_loader.get(); } + + void initialize(); + + /// (Un)Registration of conditions listeners with callback when a new condition is registered + void callOnRegister(const Listener& callee, bool add); + /// (Un)Registration of conditions listeners with callback when a condition is unregistered + void callOnRemove(const Listener& callee, bool add); + + /// Register new IOV type if it does not (yet) exist. + /** Returns (false,pointer) if IOV existed and + * (true,pointer) if new IOV was registered to the manager. + */ + std::pair<bool, const IOVType*> registerIOVType(size_t iov_type, const std::string& iov_name); - /// Access IOV by its type - const IOVTypes& iovTypes () const { return m_iovTypes; } + /// Access IOV by its type + const IOVTypes& iovTypes () const { return m_iovTypes; } - /// Access IOV by its type - const IOVType* iovType (size_t iov_type) const; + /// Access IOV by its type + const IOVType* iovType (size_t iov_type) const; - /// Access IOV by its name - const IOVType* iovType (const std::string& iov_name) const; + /// Access IOV by its name + const IOVType* iovType (const std::string& iov_name) const; - /// Create IOV from string - void fromString(const std::string& iov_str, IOV& iov); + /// Create IOV from string + void fromString(const std::string& iov_str, IOV& iov); - /// Register IOV using new string data - ConditionsPool* registerIOV(const std::string& data); + /// Register IOV using new string data + ConditionsPool* registerIOV(const std::string& data); - /// Register IOV with type and key - ConditionsPool* registerIOV(const IOVType& typ, IOV::Key key); + /// Register IOV with type and key + ConditionsPool* registerIOV(const IOVType& typ, IOV::Key key); - /// Register new condition with the conditions store. Unlocked version, not multi-threaded - bool registerUnlocked(ConditionsPool* pool, Condition cond); + /// Register new condition with the conditions store. Unlocked version, not multi-threaded + bool registerUnlocked(ConditionsPool* pool, Condition cond); - /// Prepare all updates to the clients with the defined IOV - long prepare(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool); + /// Prepare all updates to the clients with the defined IOV + long prepare(const IOV& required_validity, dd4hep_ptr<UserPool>& user_pool); - /// Enable all updates to the clients with the defined IOV - long enable(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool); + /// Prepare all updates to the clients with the defined IOV + long prepare(const IOV& required_validity, + dd4hep_ptr<UserPool>& user_pool, + const Dependencies& dependencies, + bool verify_dependencies=true); - /// Clean conditions, which are above the age limit. - /** @return Number of conditions cleaned up and removed */ - int clean(const IOVType* typ, int max_age); + /// Clean conditions, which are above the age limit. + /** @return Number of conditions cleaned up and removed */ + int clean(const IOVType* typ, int max_age); - /// Full cleanup of all managed conditions. - /** @return pair<Number of pools cleared, Number of conditions cleaned up and removed> */ - std::pair<int,int> clear(); + /// Full cleanup of all managed conditions. + /** @return pair<Number of pools cleared, Number of conditions cleaned up and removed> */ + std::pair<int,int> clear(); - /// Push all pending updates to the conditions store. - /** Note: - * This does not yet make the new conditions availible to the clients - */ - void pushUpdates(); + /// Push all pending updates to the conditions store. + /** Note: + * This does not yet make the new conditions availible to the clients + */ + void pushUpdates(); - /// Register a new managed condition. - /** The condition is created externally by the user. - * Lengthy and tedious procedure. - */ - void registerCondition(Condition c); - - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - Condition get(DetElement detector, - const std::string& condition_name, - const IOV& req_validity); - - /// Retrieve a condition given a Detector Element and the conditions name - RangeConditions getRange(DetElement detector, - const std::string& condition_name, - const IOV& req_range_validity); - }; - } /* End namespace Interna */ + /// Register a new managed condition. + /** The condition is created externally by the user. + * Lengthy and tedious procedure. + */ + void registerCondition(Condition c); + + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + Condition get(key_type key, const iov_type& req_validity); + + /// Retrieve a condition given a Detector Element and the conditions name + RangeConditions getRange(key_type key, const iov_type& req_validity); + }; + // } /* End namespace Interna */ } /* End namespace Conditions */ } /* End namespace DD4hep */ diff --git a/DDCond/include/DDCond/ConditionsLoaderImp.h b/DDCond/include/DDCond/ConditionsLoaderImp.h new file mode 100644 index 0000000000000000000000000000000000000000..b3464d9ccf07455b5e12a6c766aa9a830e178dc3 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsLoaderImp.h @@ -0,0 +1,57 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSLOADERIMP_H +#define DDCOND_CONDITIONSLOADERIMP_H + +// Framework include files +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsManager.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Concrete class to interface conditions loading from DetElements + /** + * + * \author M.Frank + * \version 1.0 + */ + class ConditionsLoaderImp : public ConditionsLoader { + protected: + /// Reference to conditions manager + ConditionsManager m_manager; + /// Referenec count + long m_refCount; + public: + /// Default constructor + ConditionsLoaderImp(ConditionsManager mgr); + /// Default destructor + virtual ~ConditionsLoaderImp(); + /// Addreference count. Use object + virtual void addRef(); + /// Release object. The client may not use any reference any further. + virtual void release(); + /// Access the conditions loading mechanism + virtual Condition get(key_type key, const iov_type& iov); + /// Access the conditions loading mechanism. Only conditions in the user pool will be accessed. + virtual Condition get(key_type key, const UserPool& pool); + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSDATALOADERIMP_H */ diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h index db58d9e47ab8709ebfd347690e41f6185b147b22..e48a14dd18036f7e69e279a619f6ddf211da80b1 100644 --- a/DDCond/include/DDCond/ConditionsManager.h +++ b/DDCond/include/DDCond/ConditionsManager.h @@ -16,6 +16,7 @@ // Framework include files #include "DD4hep/Memory.h" +#include "DD4hep/Detector.h" #include "DD4hep/Conditions.h" #include "DD4hep/ComponentProperties.h" @@ -27,14 +28,12 @@ namespace DD4hep { // Forward declarations class Entry; + class UserPool; class ConditionsPool; class ConditionsIOVPool; + class ConditionDependency; class ConditionsDataLoader; - - /// Conditions internal namespace - namespace Interna { - class ConditionsManagerObject; - } + class ConditionsManagerObject; /// Manager class for condition handles /** @@ -42,15 +41,16 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - class ConditionsManager : public Handle<Interna::ConditionsManagerObject> { + class ConditionsManager : public Handle<ConditionsManagerObject> { public: /// Standard object type - typedef Interna::ConditionsManagerObject Object; - typedef ConditionsDataLoader Loader; - typedef std::vector<IOVType> IOVTypes; - typedef std::map<IOVType*,Container> TypeConditions; - typedef std::map<DetElement,Container> DetectorConditions; + typedef ConditionsManagerObject Object; + typedef ConditionsDataLoader Loader; + typedef std::vector<IOVType> IOVTypes; + typedef std::map<IOVType*,Container> TypeConditions; + typedef std::map<DetElement,Container> DetectorConditions; + typedef std::map<unsigned int,ConditionDependency*> Dependencies; public: @@ -86,6 +86,9 @@ namespace DD4hep { /// Default destructor ~ConditionsManager(); + /// Initialize the object after having set the properties + ConditionsManager& initialize(); + /// Access to properties Property& operator[](const std::string& property_name) const; @@ -95,13 +98,13 @@ namespace DD4hep { /// Access the conditions loader Handle<Loader> loader() const; - /// Access the availible/known IOV types - const IOVTypes& iovTypes() const; - /// Access the used/registered IOV types const std::vector<const IOVType*> iovTypesUsed() const; - /// Access conditions pool by iov type + /// Access IOV by its name + const IOVType* iovType (const std::string& iov_name) const; + + /// Access conditions multi IOV pool by iov type ConditionsIOVPool* iovPool(const IOVType& type) const; /// Create IOV from string @@ -116,23 +119,8 @@ namespace DD4hep { /// Register IOV with type and key ConditionsPool* registerIOV(const IOVType& typ, IOV::Key key); - /// Register new condition with the conditions store. Unlocked version, not multi-threaded - bool registerUnlocked(const IOVType* type, IOV::Key key, Condition cond); - /// Register new condition with the conditions store. Unlocked version, not multi-threaded bool registerUnlocked(ConditionsPool* pool, Condition cond); - - /// Access IOV by its type - const IOVType* iovType (size_t iov_type) const; - - /// Access IOV by its name - const IOVType* iovType (const std::string& iov_name) const; - - /// Lock the internal data structures. This disables calls to "register", etc. - void lock(); - - /// Unlock the internal data structures. This enables calls to "register", etc. - void unlock(); /// Clean conditions, which are above the age limit. void clean(const IOVType* typ, int max_age); @@ -140,45 +128,14 @@ namespace DD4hep { /// Full cleanup of all managed conditions. void clear(); - /// Push all pending updates to the conditions store. - /** Note: - * This does not yet make the new conditions availible to the clients - */ - void pushUpdates(); + /// Prepare all updates to the clients with the defined IOV + long prepare(const IOV& required_validity, dd4hep_ptr<UserPool>& user_pool); /// Prepare all updates to the clients with the defined IOV - long prepare(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool); - - /// Enable all updates to the clients with the defined IOV - long enable(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool); - - /// Retrieve a condition given a Detector Element and the conditions name - Condition get(DetElement detector, - const std::string& condition_name, - const IOV& req_validity); - - /// Retrieve a condition given a Detector Element path and the conditions name - Condition get(const std::string& detector_path, - const std::string& condition_name, - const IOV& req_validity); - - /// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> - Condition get(const std::string& conditions_path, - const IOV& req_validity); - - /// Retrieve a condition given a Detector Element and the conditions name - RangeConditions getRange(DetElement detector, - const std::string& condition_name, - const IOV& req_range_validity); - - /// Retrieve a condition given a Detector Element path and the conditions name - RangeConditions getRange(const std::string& detector_path, - const std::string& condition_name, - const IOV& req_range_validity); - - /// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> - RangeConditions getRange(const std::string& conditions_path, - const IOV& req_range_validity); + long prepare(const IOV& required_validity, + dd4hep_ptr<UserPool>& user_pool, + const Dependencies& dependencies, + bool verify_dependencies=true); }; } /* End namespace Geometry */ diff --git a/DDCond/include/DDCond/ConditionsOperators.h b/DDCond/include/DDCond/ConditionsOperators.h index 0cceccc717416ab21e9582e9406408b4e742b766..bc00fa482e9f642cd074362e71940620dc68c049 100644 --- a/DDCond/include/DDCond/ConditionsOperators.h +++ b/DDCond/include/DDCond/ConditionsOperators.h @@ -15,6 +15,8 @@ #define DD4HEP_CONDITIONS_CONDITIONSOPERATORS_H // Framework include files +#include "DD4hep/Conditions.h" +#include "DDCond/ConditionsManager.h" // C/C++ include files @@ -22,10 +24,29 @@ namespace DD4hep { /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { + namespace Geometry { + class LCDD; + } + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Helper class for common stuff used frequently + class Operators { + public: + /// Select all condition from the conditions manager registered at the LCDD object + static size_t collectAllConditions(Geometry::LCDD& lcdd, RangeConditions& conditions); + /// Select all condition from the conditions manager registered at the LCDD object + static size_t collectAllConditions(ConditionsManager mgr, RangeConditions& conditions); + /// Select all condition from the conditions manager registered at the LCDD object + static size_t collectAllConditions(Geometry::LCDD& lcdd, std::map<int,Condition>& conditions); + /// Select all condition from the conditions manager registered at the LCDD object + static size_t collectAllConditions(ConditionsManager mgr, std::map<int,Condition>& conditions); + }; + - } /* End namespace Geometry */ + } /* End namespace Conditions */ } /* End namespace DD4hep */ #endif /* DD4HEP_CONDITIONS_CONDITIONSOPERATORS_H */ diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index 9d824916edd073ee455624788055b56ea1f9f87f..dca41bc4eb5dd6b65cefc1c80f03c139fa38a7f6 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -15,7 +15,6 @@ #define DDCOND_CONDITIONSPOOL_H // Framework include files -#include "DD4hep/Mutex.h" #include "DD4hep/Detector.h" #include "DD4hep/Conditions.h" #include "DDCond/ConditionsManager.h" @@ -27,9 +26,8 @@ namespace DD4hep { namespace Conditions { // Forward declarations - class Entry; - class ConditionsPool; - class ReplacementPool; + class ConditionsPoolInsert; + class ConditionsManagerObject; /// Class implementing the conditions collection for a given IOV type /** @@ -49,42 +47,27 @@ namespace DD4hep { protected: /// Handle to conditions manager object ConditionsManager m_manager; - + public: + /// Forward definition of the key type + typedef Condition::key_type key_type; + enum { AGE_NONE = 0, AGE_ANY = 9999999, AGE_EXPIRED = 12345678 }; - enum { NO_POOL_TYPE = 0, - UPDATE_POOL_TYPE = 1, - USER_POOL_TYPE = 2 - }; /// IOV type of the conditions hosted by this pool const IOVType* iovType; /// The IOV of the conditions hosted IOV* iov; /// Aging value int age_value; - /// Pool type (regular, user, ipdate,...) - int pool_type; protected: + friend class ConditionsPoolInsert; + friend class ConditionsPoolRemove; + friend class ConditionsManagerObject; - /// Unconditionally create a new condition from the input data - /** - * Common function for all pools..... - * \author M.Frank - * \version 1.0 - */ - virtual Condition create(ConditionsPool* pool, const Entry* cond); - - public: - /// Default constructor - ConditionsPool(ConditionsManager mgr); - /// Default destructor. Note: pool must be cleared by the subclass! - virtual ~ConditionsPool(); - /// Print pool basics - void print(const std::string& opt) const; /// Listener invocation when a condition is registered to the cache void onRegister(Condition condition); /// Listener invocation when a condition is deregistered from the cache @@ -93,14 +76,20 @@ namespace DD4hep { virtual void insert(Condition cond) = 0; /// Register a new condition to this pool. May overload for performance reasons. virtual void insert(RangeConditions& cond) = 0; + + public: + /// Default constructor + ConditionsPool(ConditionsManager mgr); + /// Default destructor. Note: pool must be cleared by the subclass! + virtual ~ConditionsPool(); + /// Print pool basics + void print(const std::string& opt) const; /// Full cleanup of all managed conditions. virtual void clear() = 0; /// Check if a condition exists in the pool - virtual Condition exists(DetElement, const std::string&) const = 0; - /// Check if a condition exists in the pool - virtual Condition exists(Condition) const = 0; + virtual Condition exists(Condition::key_type key) const = 0; /// Select the conditions matching the DetElement and the conditions name - virtual void select(DetElement det, const std::string& cond_name, RangeConditions& result) = 0; + virtual void select(Condition::key_type key, RangeConditions& result) = 0; /// Select all conditions contained virtual void select_all(RangeConditions& result) = 0; /// Select all conditions contained @@ -108,7 +97,7 @@ namespace DD4hep { /// Select the conditons, used also by the DetElement of the condition virtual void select_used(RangeConditions& result) = 0; /// Total entry count - virtual int count() const = 0; + virtual size_t count() const = 0; }; /// Interface for conditions pool optimized to host conditions updates. @@ -128,16 +117,11 @@ namespace DD4hep { UpdatePool(ConditionsManager mgr); /// Default destructor. virtual ~UpdatePool(); - /// Pool type identifier - static int poolType() { return UPDATE_POOL_TYPE; } /// Adopt all entries sorted by IOV. Entries will be removed from the pool virtual void popEntries(UpdateEntries& entries) = 0; - /// Register a new condition to this pool - virtual Condition insertEntry(ConditionsPool* pool, Entry* cond) = 0; - /// Select the conditions matching the DetElement and the conditions name - virtual void select_range(DetElement det, - const std::string& cond_name, - const IOV& req_validity, + /// Select the conditions matching the key + virtual void select_range(Condition::key_type key, + const Condition::iov_type& req_validity, RangeConditions& result) = 0; }; @@ -146,21 +130,57 @@ namespace DD4hep { * \author M.Frank * \version 1.0 */ - class UserPool : public ConditionsPool { + class UserPool { + public: + /// Forward definition of the key type + typedef Condition::key_type key_type; + /// Forward definition of the dependency container + typedef ConditionsManager::Dependencies Dependencies; + + protected: + /// The pool's interval of validity + IOV m_iov; + /// Handle to conditions manager object + ConditionsManager m_manager; + /// IOV Pool as data source + ConditionsIOVPool* m_iovPool; + public: /// Default constructor - UserPool(ConditionsManager mgr); + UserPool(ConditionsManager mgr, ConditionsIOVPool* pool); /// Default destructor. virtual ~UserPool(); - /// Pool type identifier - static int poolType() { return USER_POOL_TYPE; } /// Access the interval of validity for this user pool - virtual const IOV& validity() const = 0; - /// Update interval of validity for this user pool (should only be called by ConditionsManager) - virtual void setValidity(const IOV& value) = 0; + const IOV& validity() const { return m_iov; } + /// Access the interval of validity for this user pool + const IOV* validityPtr() const { return &m_iov; } + /// Print pool content + virtual void print(const std::string& opt) const = 0; + /// Total entry count + virtual size_t count() const = 0; + /// Full cleanup of all managed conditions. + virtual void clear() = 0; + /// Check a condition for existence + virtual bool exists(key_type key) const = 0; + /// Check a condition for existence + virtual bool exists(const ConditionKey& key) const = 0; + /// Check if a condition exists in the pool and return it to the caller + virtual Condition get(key_type key) const = 0; + /// Check if a condition exists in the pool and return it to the caller + virtual Condition get(const ConditionKey& key) const = 0; + /// Remove condition by key from pool. + virtual bool remove(key_type hash_key) = 0; + /// Remove condition by key from pool. + virtual bool remove(const ConditionKey& key) = 0; + /// Register a new condition to this pool + virtual bool insert(Condition cond) = 0; + /// Prepare user pool for usage (load, fill etc.) according to required IOV + virtual long prepare(const IOV& required) = 0; + /// Evaluate and register all derived conditions from the dependency list + virtual long compute(const Dependencies& dependencies) = 0; }; } /* End namespace Conditions */ } /* End namespace DD4hep */ -#endif /* DDCOND_CONDITIONSPOOL_H */ +#endif /* DDCOND_CONDITIONSPOOL_H */ diff --git a/DDCond/include/DDCond/ConditionsSelectors.h b/DDCond/include/DDCond/ConditionsSelectors.h new file mode 100644 index 0000000000000000000000000000000000000000..215cecbbe9fa0006d94885e53998248964abeb5f --- /dev/null +++ b/DDCond/include/DDCond/ConditionsSelectors.h @@ -0,0 +1,167 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSSELECTORS_H +#define DDCOND_CONDITIONSSELECTORS_H + +// Framework include files +#include "DD4hep/objects/ConditionsInterna.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + class Cond__Oper { + public: + typedef Condition cond_t; + typedef Condition::Object object_t; + typedef std::pair<const Condition::key_type,Condition> mapentry_t; + typedef std::pair<const Condition::key_type,object_t*> ptr_mapentry_t; + }; + + /// Helper to insert objects into a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + class ConditionsPoolInsert : public Cond__Oper { + ConditionsPool& pool; + public: + ConditionsPoolInsert(ConditionsPool& p) : pool(p) { } + void operator()(object_t* o) const { pool.insert(o); } + void operator()(const cond_t& o) const { pool.insert(o.ptr()); } + void operator()(const mapentry_t& o) const { (*this)(o.second.ptr()); } + void operator()(const ptr_mapentry_t& o) const { (*this)(o.second); } + }; + + /// Helper to insert objects into a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + class ConditionsPoolRemove : public Cond__Oper { + ConditionsPool& pool; + public: + ConditionsPoolRemove(ConditionsPool& p) : pool(p) { } + void operator()(object_t* o) const { + pool.onRemove(o); + delete o; + } + void operator()(const cond_t& o) const { (*this)(o.ptr()); } + void operator()(const mapentry_t& o) const { (*this)(o.second.ptr()); } + void operator()(const ptr_mapentry_t& o) const { (*this)(o.second); } + }; + + /// Helper to insert objects into a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + template<typename pool_type> class PoolInsert : public Cond__Oper { + pool_type& pool; + public: + PoolInsert(pool_type& p) : pool(p) { } + void operator()(object_t* o) const { pool.insert(o); } + void operator()(const cond_t& o) const { pool.insert(o.ptr()); } + void operator()(const mapentry_t& o) const { (*this)(o.second.ptr()); } + void operator()(const ptr_mapentry_t& o) const { (*this)(o.second); } + }; + template <typename pool_type> PoolInsert<pool_type> poolInsert(pool_type& pool) { + return PoolInsert<pool_type>(pool); + } + + /// Helper to select objects from a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + template<typename collection_type> class CollectionSelect : public Cond__Oper { + collection_type& coll; + public: + CollectionSelect(collection_type& p) : coll(p) { } + void operator()(object_t* o) const { coll.insert(coll.end(),o); } + void operator()(const cond_t& o) const { coll.insert(coll.end(),o.ptr()); } + void operator()(const mapentry_t& o) const { (*this)(o.second.ptr()); } + void operator()(const ptr_mapentry_t& o) { (*this)(o.second); } + }; + template <typename collection_type> + CollectionSelect<collection_type> collectionSelect(collection_type& collection) { + return CollectionSelect<collection_type>(collection); + } + + /// Helper to select active objects from a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + template<typename collection_type> class ActiveSelect : public Cond__Oper { + collection_type& collection; + public: + ActiveSelect(collection_type& p) : collection(p) {} + void operator()(object_t* o) const { + if ( (o->flags & cond_t::ACTIVE) ) + collection.insert(collection.end(),o); + } + void operator()(const cond_t& o) const { (*this)(o.ptr()); } + void operator()(const mapentry_t& o) const { (*this)(o.second.ptr()); } + void operator()(const ptr_mapentry_t& o) const { (*this)(o.second); } + }; + template <typename collection_type> + ActiveSelect<collection_type> activeSelect(collection_type& active) { + return ActiveSelect<collection_type>(active); + } + + /// Helper to select keyed objects from a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + template<typename collection_type> class KeyedSelect : public Cond__Oper { + cond_t::key_type key; + collection_type& collection; + public: + KeyedSelect(cond_t::key_type k, collection_type& p) : key(k), collection(p) {} + void operator()(object_t* o) const { + if ( o->hash == key ) + collection.insert(collection.end(),o); + } + void operator()(const cond_t& o) const { (*this)(o.ptr()); } + void operator()(const mapentry_t& o) const { (*this)(o.second.ptr()); } + void operator()(const ptr_mapentry_t& o) const { (*this)(o.second); } + }; + template <typename collection_type> + KeyedSelect<collection_type> keyedSelect(Condition::key_type k, collection_type& keyed) { + return KeyedSelect<collection_type>(k, keyed); + } + + /// Helper to select condition objects by hash key from a conditions pool + /** + * \author M.Frank + * \version 1.0 + */ + class HashConditionFind : public Cond__Oper { + cond_t::key_type hash; + public: + HashConditionFind(cond_t::key_type h) : hash(h) { } + bool operator()(const cond_t& o) const { return o->hash == hash; } + bool operator()(const object_t* o) const { return o->hash == hash; } + bool operator()(const mapentry_t& o) const { return (*this)(o.second); } + bool operator()(const ptr_mapentry_t& o) const { return (*this)(o.second); } + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSSELECTORS_H */ diff --git a/DDCond/include/DDCond/ConditionsTest.h b/DDCond/include/DDCond/ConditionsTest.h index b6d519ae2c44bd04f6b6bda2fb8a00b655dd6f01..a2153ad7112be0fb97169fd801bde74ca8b4d071 100644 --- a/DDCond/include/DDCond/ConditionsTest.h +++ b/DDCond/include/DDCond/ConditionsTest.h @@ -18,9 +18,11 @@ #include "DD4hep/LCDD.h" #include "DD4hep/Printout.h" #include "DD4hep/Conditions.h" +#include "DD4hep/DetConditions.h" #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/objects/ConditionsInterna.h" +#include "DDCond/ConditionsAccess.h" #include "DDCond/ConditionsManager.h" #include "DDCond/ConditionsIOVPool.h" #include "DDCond/ConditionsInterna.h" diff --git a/DDCond/src/ConditionsAccess.cpp b/DDCond/src/ConditionsAccess.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f13737504038043a98b95c612c8a527ddc3dc0a3 --- /dev/null +++ b/DDCond/src/ConditionsAccess.cpp @@ -0,0 +1,71 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Errors.h" +#include "DD4hep/Printout.h" +#include "DD4hep/DetectorTools.h" + +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsAccess.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; + +/// Default destructor +ConditionsAccess::~ConditionsAccess() { +} + +/// Access IOV by its name +const IOVType* ConditionsAccess::iovType (const string& iov_name) const { + return access()->iovType(iov_name); +} + +/// Access the used/registered IOV types +const vector<const IOVType*> ConditionsAccess::iovTypesUsed() const { + Object* obj = access(); + vector<const IOVType*> result; + const Object::IOVTypes& types = obj->iovTypes(); + for(Object::IOVTypes::const_iterator i=types.begin(); i!=types.end(); ++i) + if ( int((*i).type) != IOVType::UNKNOWN_IOV ) result.push_back(&(*i)); + return result; +} + +/// Retrieve a condition given a Detector Element and the conditions name +Condition +ConditionsAccess::get(Condition::key_type key, const Condition::iov_type& req_validity) { + return access()->get(key, req_validity); +} + +/// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> +Condition +ConditionsAccess::get(const string& path, const Condition::iov_type& req_validity) { + Condition::key_type key = ConditionKey::hashCode(path); + return access()->get(key, req_validity); +} + +/// Retrieve a condition given a Detector Element and the conditions name +RangeConditions +ConditionsAccess::getRange(Condition::key_type key, const Condition::iov_type& req_validity) { + return access()->getRange(key, req_validity); +} + +/// Retrieve a condition given a Detector Element path and the conditions name +RangeConditions +ConditionsAccess::getRange(const string& path, const Condition::iov_type& req_validity) { + Condition::key_type key = ConditionKey::hashCode(path); + return access()->getRange(key, req_validity); +} diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9fd430cebbf4ad591b1ddeaed9a08f90a0709f1 --- /dev/null +++ b/DDCond/src/ConditionsDependencyHandler.cpp @@ -0,0 +1,94 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/Printout.h" +#include "DDCond/ConditionsDependencyHandler.h" + +using namespace DD4hep; +using namespace DD4hep::Conditions; + +/// Default constructor +ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager::Object* mgr, + UserPool& pool, + const Dependencies& dependencies) + : m_manager(mgr), m_pool(pool), m_dependencies(dependencies) +{ +} + +/// Default destructor +ConditionsDependencyHandler::~ConditionsDependencyHandler() { +} + +/// ConditionResolver implementation: Interface to access conditions +Condition ConditionsDependencyHandler::get(unsigned int key) const { + Condition c = m_pool.get(key); + if ( c.isValid() ) { + Condition::Object* obj = c.ptr(); + const IOV& required = m_pool.validity(); + if ( obj->iov && IOV::key_is_contained(required.keyData,obj->iov->keyData) ) + return c; + Dependencies::const_iterator i = m_dependencies.find(key); + if ( i != m_dependencies.end() ) { + /// This condition is no longer valid. remove it! Will be added again afterwards. + m_pool.remove(key); + return do_callback((*i).second); + } + } + Dependencies::const_iterator i = m_dependencies.find(key); + if ( i != m_dependencies.end() ) + return do_callback((*i).second); + return Condition(); +} + + +/// Internal call to trigger update callback +Condition::Object* +ConditionsDependencyHandler::do_callback(const ConditionDependency* dep) const { + try { + Condition::iov_type iov(m_pool.validity().iovType); + ConditionUpdateCall::Context ctxt(*this, *dep, iov.reset().invert()); + Condition cond = (*dep->callback)(dep->target, ctxt); + Condition::Object* obj = cond.ptr(); + if ( obj ) { + if ( !obj->hash ) obj->hash = ConditionKey::hashCode(obj->name); + cond->setFlag(Condition::DERIVED); + cond->iov = m_pool.validityPtr(); + // Must IMMEDIATELY insert to handle inter-dependencies. + m_pool.insert(cond); + } + return obj; + } + catch(const std::exception& e) { + printout(ERROR,"ConditionDependency", + "+++ Exception while creating dependent Condition %s:", + dep->target.name.c_str()); + printout(ERROR,"ConditionDependency","\t\t%s", e.what()); + } + catch(...) { + printout(ERROR,"ConditionDependency", + "+++ UNKNOWN exception while creating dependent Condition %s.", + dep->target.name.c_str()); + } + m_pool.print("*"); + except("ConditionDependency", + "++ Exception while creating dependent Condition %s.", + dep->target.name.c_str()); + return 0; +} + +/// Handler callback to process multiple derived conditions +Condition::Object* ConditionsDependencyHandler::operator()(const ConditionDependency* dep) const { + return do_callback(dep); +} diff --git a/DDCond/src/ConditionsIOVPool.cpp b/DDCond/src/ConditionsIOVPool.cpp index 5c057c314fbc72814abb88c85fabb131c0e27e25..0647c6d4d2c75abde1cf42d8623a3925b87d8c47 100644 --- a/DDCond/src/ConditionsIOVPool.cpp +++ b/DDCond/src/ConditionsIOVPool.cpp @@ -32,54 +32,40 @@ ConditionsIOVPool::~ConditionsIOVPool() { InstanceCount::decrement(this); } -bool ConditionsIOVPool::addKey(Condition c) { - // TODO: Should be: det.path()+'#'+c->name; instead of c->comment - int hash = c->hash; - c->flags |= Interna::ConditionObject::ACTIVE; - keys.insert(hash); - return true; -} - -void ConditionsIOVPool::__find(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result) +void ConditionsIOVPool::select(Condition::key_type key, const Condition::iov_type& req_validity, RangeConditions& result) { - if ( !entries.empty() ) { + if ( !elements.empty() ) { const IOV::Key req_key = req_validity.key(); // 16 bytes => better copy! - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + for(Elements::const_iterator i=elements.begin(); i!=elements.end(); ++i) { if ( IOV::key_contains_range((*i).first, req_key) ) { - (*i).second->select(detector, condition_name, result); + (*i).second->select(key, result); } } } } -void ConditionsIOVPool::__find_range(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result) +void ConditionsIOVPool::selectRange(Condition::key_type key, const Condition::iov_type& req_validity, RangeConditions& result) { const IOV::Key range = req_validity.key(); - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { - const IOV::Key& key = (*i).first; - if ( IOV::key_is_contained(key,range) ) + for(Elements::const_iterator i=elements.begin(); i!=elements.end(); ++i) { + const IOV::Key& k = (*i).first; + if ( IOV::key_is_contained(k,range) ) // IOV test contained in key. Take it! - (*i).second->select(detector, condition_name, result); - else if ( IOV::key_overlaps_lower_end(key,range) ) + (*i).second->select(key, result); + else if ( IOV::key_overlaps_lower_end(k,range) ) // IOV overlap on test on the lower end of key - (*i).second->select(detector, condition_name, result); - else if ( IOV::key_overlaps_higher_end(key,range) ) + (*i).second->select(key, result); + else if ( IOV::key_overlaps_higher_end(k,range) ) // IOV overlap of test on the higher end of key - (*i).second->select(detector, condition_name, result); + (*i).second->select(key, result); } } /// Remove all key based pools with an age beyon the minimum age int ConditionsIOVPool::clean(int max_age) { - Entries rest; + Elements rest; int count = 0; - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + for(Elements::const_iterator i=elements.begin(); i!=elements.end(); ++i) { ConditionsPool* pool = (*i).second; if ( pool->age_value >= max_age ) { count += pool->count(); @@ -89,19 +75,19 @@ int ConditionsIOVPool::clean(int max_age) { else rest.insert(make_pair(pool->iov->keyData,pool)); } - entries = rest; + elements = rest; return count; } /// Select all ACTIVE conditions, which do no longer match the IOV requirement -void ConditionsIOVPool::select(const IOV& required_validity, +void ConditionsIOVPool::select(const Condition::iov_type& required_validity, RangeConditions& valid, RangeConditions& expired, - IOV& conditions_validity) + Condition::iov_type& conditions_validity) { - if ( !entries.empty() ) { + if ( !elements.empty() ) { const IOV::Key req_key = required_validity.key(); // 16 bytes => better copy! - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + for(Elements::const_iterator i=elements.begin(); i!=elements.end(); ++i) { ConditionsPool* pool = (*i).second; if ( !IOV::key_contains_range((*i).first, req_key) ) { if ( pool->age_value == ConditionsPool::AGE_NONE ) { diff --git a/DDCond/src/ConditionsInterna.cpp b/DDCond/src/ConditionsInterna.cpp index cb516d200d188fc029c4c35e4a7e8c6d19cd9a3b..afbec6cbf0e4afbf01d6b0f080e8552a14df062f 100644 --- a/DDCond/src/ConditionsInterna.cpp +++ b/DDCond/src/ConditionsInterna.cpp @@ -32,15 +32,16 @@ #include "DDCond/ConditionsDataLoader.h" #include "DDCond/ConditionsInterna.h" #include "DDCond/ConditionsListener.h" +#include "DDCond/ConditionsLoaderImp.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Conditions; -using namespace DD4hep::Conditions::Interna; typedef UpdatePool::UpdateEntries Updates; +typedef RangeConditions RC; -DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionsManagerObject); +DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsManagerObject); #define NO_AGE 0 @@ -59,8 +60,8 @@ namespace { const IOVType* typ = iov->iovType ? iov->iovType : o->iovType(iov->type); if ( typ ) { if ( iov->type == typ->type ) { - if ( typ->type < o->m_pool.size() ) { - if ( o->m_pool[typ->type] != 0 ) { + if ( typ->type < o->m_rawPool.size() ) { + if ( o->m_rawPool[typ->type] != 0 ) { return typ; } } @@ -84,30 +85,22 @@ namespace { } /// Helper: Check conditions result for consistency - template <typename T> void __check_values__(const ConditionsManagerObject* o, - Geometry::DetElement det, - const std::string& cond, - const IOV* iov) + template <typename T> void __check_values__(const ConditionsManagerObject* o, Condition::key_type key, const IOV* iov) { if ( !iov ) { - except("ConditionsManager","+++ Invalid IOV to access condition: %s.%s. [Null-reference]", - det.path().c_str(), cond.c_str()); + except("ConditionsManager","+++ Invalid IOV to access condition: %08X. [Null-reference]",key); } const IOVType* typ = check_iov_type<T>(o,iov); if ( !typ ) { // Severe: We have an unknown IOV type. This is not allowed, // because we do not known hot to handle it..... - except("ConditionsManager","+++ Invalid IOV type [%d] to access condition: %s.%s.", - iov->type, det.path().c_str(), cond.c_str()); - } - if ( !det.isValid() ) { - except("ConditionsManager","+++ Attempt to use the conditions manager %s for " - "an unknown detector element [Invalid Handle].", cond.c_str()); + except("ConditionsManager","+++ Invalid IOV type [%d] to access condition: %08X.", + iov->type, key); } } /// Helper: Check if the conditions range covers the entire IOV span - bool is_range_complete(const IOV& iov, const RangeConditions& conditions) { + bool is_range_complete(const IOV& iov, const RC& conditions) { if ( !conditions.empty() ) { // We need to check if the entire range is covered. // For every key.second we must find a key.first, which is at least as big @@ -115,7 +108,7 @@ namespace { // The range may be returned unordered. Hence, // we have to try to match at most conditions.size() times until we really know for(size_t j = 0; j < conditions.size(); ++j ) { - for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { + for(RC::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { const IOV::Key& k = (*i)->iov->key(); if ( k.first <= test.first+1 && k.second >= test.first ) test.first = k.second; if ( k.first+1 <= test.second && k.second >= test.second ) test.second = k.first; @@ -130,9 +123,8 @@ namespace { void __print(const char* prefix, Condition c) { if ( s_debug > INFO ) { - printout(INFO,"ConditionsManager","+++ %s %s.%s [%s] = %s", - prefix, c->detector.path().c_str(), c.name().c_str(), - c->iov->str().c_str(), c->value.c_str()); + printout(INFO,"ConditionsManager","+++ %s %s [%s] = %s", + prefix, c.name().c_str(), c->iov->str().c_str(), c->value.c_str()); } } @@ -143,22 +135,11 @@ namespace { (listener.first->*pmf)(cond, listener.second); } } - - /// Helper class to be injected into the world object to allow loading from DetElements directly..... - struct lcdd_cond_loader : public ConditionsLoader { - ConditionsManager m_manager; - lcdd_cond_loader(ConditionsManager m) : m_manager(m) {} - virtual ~lcdd_cond_loader() {} - /// Access the conditions loading - virtual Condition get(Geometry::DetElement element, const std::string& key, const IOV& iov) { - return m_manager->get(element, key, iov); - } - }; } /// Standard constructor -ConditionsManagerObject::ConditionsManagerObject(LCDD& lcdd) - : NamedObject(), m_lcdd(lcdd), m_iovTypes(), m_pool(), +ConditionsManagerObject::ConditionsManagerObject(LCDD& lcdd_instance) + : NamedObject(), ObjectExtensions(typeid(ConditionsManagerObject)), m_lcdd(lcdd_instance), m_iovTypes(), m_rawPool(), m_updateLock(), m_poolLock(), m_loader(), m_updatePool(), locked(0) @@ -167,15 +148,19 @@ ConditionsManagerObject::ConditionsManagerObject(LCDD& lcdd) declareProperty("MaxIOVTypes", m_maxIOVTypes=32); declareProperty("PoolType", m_poolType = ""); declareProperty("UpdatePoolType", m_updateType = "DD4hep_ConditionsLinearUpdatePool"); - declareProperty("UserPoolType", m_userType = "DD4hep_ConditionsLinearUserPool"); + declareProperty("UserPoolType", m_userType = "DD4hep_ConditionsMapUserPool"); declareProperty("LoaderType", m_loaderType = "multi"); m_iovTypes.resize(m_maxIOVTypes,IOVType()); - m_pool.resize(m_maxIOVTypes,0); + m_rawPool.resize(m_maxIOVTypes,0); } /// Default destructor ConditionsManagerObject::~ConditionsManagerObject() { - for_each(m_pool.begin(), m_pool.end(), DestroyObject<ConditionsIOVPool*>()); + Geometry::World world(m_lcdd.world()); + for_each(m_rawPool.begin(), m_rawPool.end(), DestroyObject<ConditionsIOVPool*>()); + ConditionsLoader* ld = world->conditionsLoader; + world->conditionsLoader = 0; + if ( ld ) ld->release(); InstanceCount::decrement(this); } @@ -194,7 +179,7 @@ void ConditionsManagerObject::initialize() { ref->SetName("updates"); ref->SetTitle("updates"); Geometry::World world(m_lcdd.world()); - world->conditionsLoader = new lcdd_cond_loader(ConditionsManager(this)); + world->conditionsLoader = new ConditionsLoaderImp(this); } } @@ -242,7 +227,7 @@ pair<bool, const IOVType*> ConditionsManagerObject::registerIOVType(size_t iov_t } t.name = iov_name; t.type = iov_type; - m_pool[t.type] = new ConditionsIOVPool(); + m_rawPool[t.type] = new ConditionsIOVPool(); return make_pair(true,&t); } except("ConditionsManager","Cannot register IOV section %d of type %d. Value out of bounds: [%d,%d]", @@ -315,13 +300,13 @@ ConditionsPool* ConditionsManagerObject::registerIOV(const string& data) { /// Register IOV with type and key ConditionsPool* ConditionsManagerObject::registerIOV(const IOVType& typ, IOV::Key key) { // IOV read and checked. Now register it, but always locked! - ConditionsIOVPool* pool = m_pool[typ.type]; + ConditionsIOVPool* pool = m_rawPool[typ.type]; dd4hep_lock_t lock(m_poolLock); if ( !pool ) { - m_pool[typ.type] = pool = new ConditionsIOVPool(); + m_rawPool[typ.type] = pool = new ConditionsIOVPool(); } - ConditionsIOVPool::Entries::const_iterator i = pool->entries.find(key); - if ( i != pool->entries.end() ) { + ConditionsIOVPool::Elements::const_iterator i = pool->elements.find(key); + if ( i != pool->elements.end() ) { return (*i).second; } const void* argv_pool[] = {this, 0}; @@ -330,15 +315,13 @@ ConditionsPool* ConditionsManagerObject::registerIOV(const IOVType& typ, IOV::Ke iov->type = typ.type; iov->keyData = key; cond_pool->iov = iov; - pool->entries.insert(make_pair(key,cond_pool)); + pool->elements.insert(make_pair(key,cond_pool)); return cond_pool; } /// Register new condition with the conditions store. Unlocked version, not multi-threaded bool ConditionsManagerObject::registerUnlocked(ConditionsPool* pool, Condition cond) { if ( pool && cond.isValid() ) { - ConditionsIOVPool* iov_pool = m_pool[pool->iov->type]; - iov_pool->addKey(cond); cond->pool = pool; cond->iov = pool->iov; pool->insert(cond); @@ -356,14 +339,24 @@ bool ConditionsManagerObject::registerUnlocked(ConditionsPool* pool, Condition c /// Set a single conditions value to be managed. /// Requires external lock on update pool! -Condition ConditionsManagerObject::__queue_update(Entry* e) { +Condition ConditionsManagerObject::__queue_update(Conditions::Entry* e) { if ( e ) { ConditionsPool* p = registerIOV(e->validity); - Condition c = m_updatePool->insertEntry(p, e); + Condition condition(e->name,e->type); + Condition::Object* c = condition.ptr(); + //c->name = e->name; + // c->type = e->type; + c->value = e->value; + c->comment = "----"; + c->address = "----"; + c->validity = e->validity; + c->iov = p->iov; + c->pool = p; + p->insert(c); if ( s_debug > INFO ) { printout(INFO,"Conditions","+++ Loaded condition: %s.%s to %s [%s] V: %s", - c.detector().path().c_str(), c.name().c_str(), c->value.c_str(), - c->type.c_str(),c->validity.c_str()); + e->detector.path().c_str(), c->name.c_str(), + c->value.c_str(), c->type.c_str(), c->validity.c_str()); } return c; } @@ -374,7 +367,7 @@ Condition ConditionsManagerObject::__queue_update(Entry* e) { int ConditionsManagerObject::clean(const IOVType* typ, int max_age) { int count = 0; dd4hep_lock_t lock(m_updateLock); - ConditionsIOVPool* pool = m_pool[typ->type]; + ConditionsIOVPool* pool = m_rawPool[typ->type]; if ( pool ) { count += pool->clean(max_age); } @@ -384,7 +377,7 @@ int ConditionsManagerObject::clean(const IOVType* typ, int max_age) { /// Full cleanup of all managed conditions. pair<int,int> ConditionsManagerObject::clear() { pair<int,int> count(0,0); - for( TypedConditionPool::iterator i=m_pool.begin(); i != m_pool.end(); ++i) { + for( TypedConditionPool::iterator i=m_rawPool.begin(); i != m_rawPool.end(); ++i) { ConditionsIOVPool* p = *i; if ( p ) { ++count.first; @@ -409,34 +402,28 @@ void ConditionsManagerObject::pushUpdates() { if ( !ents.empty() ) { for(_E::const_iterator j=ents.begin(); j != ents.end(); ++j) { (*j)->pool->insert(*j); - __print("__register(2):",*j); } - //for_each(ents.begin(), ents.end(), [](_E::reference c) { c->pool->insert(c); }); - //for_each(ents.begin(), ents.end(), [](_E::reference c) { __print("__register(2):",c); }); } } } - +#if 0 /// Prepare all updates to the clients with the defined IOV -long ConditionsManagerObject::prepare(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& up) { +long ConditionsManagerObject::prepare(const Condition::iov_type& required_validity, + dd4hep_ptr<UserPool>& up) +{ const IOVType* typ = check_iov_type<Discrete>(this, &required_validity); if ( typ ) { - RangeConditions valid, expired; - ConditionsIOVPool* pool = m_pool[typ->type]; + RC valid, expired; + ConditionsIOVPool* pool = m_rawPool[typ->type]; if ( 0 == up.get() || up->pool_type != ConditionsPool::USER_POOL_TYPE ) { const void* argv_pool[] = {this, 0}; - ConditionsPool* cp = createPlugin<ConditionsPool>(m_userType,m_lcdd,1,argv_pool); + UserPool* cp = createPlugin<UserPool>(m_userType,m_lcdd,1,argv_pool); up.adopt(cp); } - UserPool *user_pool = (UserPool*)up.get(); - if ( user_pool->pool_type != UserPool::poolType() ) { - except("ConditionsManager","+++ Unknown User POOL type:%d", - user_pool->pool_type, Errors::invalidArg().c_str()); - } + UserPool *user_pool = up.get(); /// First push any pending updates and register them to pending pools... - IOV pool_iov(typ); - pool_iov.reset(); - pool_iov.invert(); + Condition::iov_type pool_iov(typ); + pool_iov.reset().invert(); pushUpdates(); pool->select(required_validity, valid, expired, pool_iov); @@ -448,68 +435,71 @@ long ConditionsManagerObject::prepare(const IOV& required_validity, dd4hep_ptr<C user_pool->insert(expired); } user_pool->setValidity(pool_iov); + user_pool->setReqValidity(required_validity); return num_expired; } except("ConditionsManager","+++ Unknown IOV type requested to enable conditions. [%s]", Errors::invalidArg().c_str()); return -1; } - -/// Enable all updates to the clients with the defined IOV -long ConditionsManagerObject::enable(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool) { - if ( !locked ) { - ConditionsIOVPool* pool = m_pool[required_validity.type]; - if ( pool ) { -#if 0 - UserPool* rep_pool = 0; - pushUpdates(); - { - dd4hep_lock_t lock(m_poolLock); - ConditionsIOVPool::Entries::iterator i = pool->entries.find(required_validity.key()); - if ( i == pool->entries.end() ) { - except("ConditionsManager","+++ Unknown IOV [%s] requested to enable conditions. [%s]", - required_validity.str().c_str(), Errors::invalidArg().c_str()); - } - rep_pool = (*i).second->updates; - } - RangeConditions entries; - rep_pool->popEntries(entries); - __push_immediate(entries); #endif - return 0; + +/// Prepare all updates to the clients with the defined IOV +long ConditionsManagerObject::prepare(const Condition::iov_type& req_iov, dd4hep_ptr<UserPool>& up) { + const IOVType* typ = check_iov_type<Discrete>(this, &req_iov); + if ( typ ) { + RC valid, expired; + ConditionsIOVPool* pool = m_rawPool[typ->type]; + if ( 0 == up.get() ) { + const void* argv[] = {this, pool, 0}; + UserPool* p = createPlugin<UserPool>(m_userType,m_lcdd,2,argv); + up.adopt(p); } - except("ConditionsManager","+++ Unknown IOV type requested to enable conditions. [%s]", - Errors::invalidArg().c_str()); + /// First push any pending updates and register them to pending pools... + pushUpdates(); + /// Now update/fill the user pool + return up->prepare(req_iov); } - except("ConditionsManager","+++ Cannot enable new conditions for IOV:%s in locked state! [%s]", - required_validity.str().c_str(), Errors::invalidArg().c_str()); - return 0; + except("ConditionsManager","+++ Unknown IOV type requested to enable conditions. [%s]", + Errors::invalidArg().c_str()); + return -1; +} + +/// Prepare all updates to the clients with the defined IOV +long ConditionsManagerObject::prepare(const Condition::iov_type& req_iov, + dd4hep_ptr<UserPool>& up, + const Dependencies& dependencies, + bool verify_dependencies) +{ + long num_raw_updates = prepare(req_iov, up); + if ( num_raw_updates > 0 || verify_dependencies ) { + long num_dep_updates = up->compute(dependencies); + return num_raw_updates+num_dep_updates; + } + return num_raw_updates; } /// Register a new managed condition void ConditionsManagerObject::registerCondition(Condition c) { - dd4hep_ptr<ConditionObject> cond(c.ptr()); + dd4hep_ptr<Condition::Object> cond(c.ptr()); if ( !cond.get() ) { except("ConditionsManager","+++ Failed to register invalid handle."); } if ( !locked ) { - DetElement det = cond->detector; IOV* iov = const_cast<IOV*>(cond->iov); - // Check arguments. This also checks the existence of the proper pool - __check_values__<Discrete>(this,det,c.name(),iov); - ConditionsIOVPool* pool = m_pool[iov->type]; + __check_values__<Discrete>(this,cond->hash,iov); + ConditionsIOVPool* pool = m_rawPool[iov->type]; { // We are now modifying the pool: need to lock any access dd4hep_lock_t lock(m_poolLock); - ConditionsIOVPool::Entries::iterator it = pool->entries.find(iov->keyData); - if ( it != pool->entries.end() ) { + ConditionsIOVPool::Elements::iterator it = pool->elements.find(iov->keyData); + if ( it != pool->elements.end() ) { (*it).second->insert(c); return; } const void* argv_pool[] = {this, 0}; ConditionsPool* cp = createPlugin<ConditionsPool>(m_poolType,m_lcdd,1,argv_pool); - pool->entries.insert(make_pair(iov->keyData,cp)); - pool->addKey(c); + pool->elements.insert(make_pair(iov->keyData,cp)); cp->insert(c); onRegister(c); } @@ -519,162 +509,118 @@ void ConditionsManagerObject::registerCondition(Condition c) { } /// Retrieve a condition set given a Detector Element and the conditions name according to their validity -bool ConditionsManagerObject::__find(DetElement det, - const std::string& cond, - const IOV& req_validity, +bool ConditionsManagerObject::select(Condition::key_type key, + const Condition::iov_type& req_validity, RangeConditions& conditions) { { ConditionsIOVPool* p = 0; dd4hep_lock_t locked_action(m_poolLock); - p = m_pool[req_validity.type]; // Existence already checked by caller! - p->__find(det, cond, req_validity, conditions); + p = m_rawPool[req_validity.type]; // Existence already checked by caller! + p->select(key, req_validity, conditions); } { dd4hep_lock_t locked_action(m_updateLock); - m_updatePool->select_range(det, cond, req_validity, conditions); + m_updatePool->select_range(key, req_validity, conditions); } return !conditions.empty(); } /// Retrieve a condition set given a Detector Element and the conditions name according to their validity -bool ConditionsManagerObject::__find_range(DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions) +bool ConditionsManagerObject::select_range(Condition::key_type key, + const Condition::iov_type& req_validity, + RangeConditions& conditions) { { ConditionsIOVPool* p = 0; dd4hep_lock_t locked_action(m_poolLock); - p = m_pool[req_validity.type]; // Existence alread checked by caller! - p->__find_range(det, cond, req_validity, conditions); + p = m_rawPool[req_validity.type]; // Existence alread checked by caller! + p->selectRange(key, req_validity, conditions); } { dd4hep_lock_t locked_action(m_updateLock); - m_updatePool->select_range(det, cond, req_validity, conditions); + m_updatePool->select_range(key, req_validity, conditions); } return is_range_complete(req_validity,conditions); } +#if 0 /// Register a new managed condition. void ConditionsManagerObject::__register_immediate(RangeConditions& rc) { // We modify the pool. For this we need a lock, // since this may happen during the event processing in parallel dd4hep_lock_t locked_action(m_poolLock); - for(RangeConditions::iterator i=rc.begin(); i != rc.end(); ++i) { + for(RC::iterator i=rc.begin(); i != rc.end(); ++i) { Condition c = *i; if ( !c->pool ) { except("ConditionsManager","+++ __register_immediate: Invalid pool. [Fatal, Internal or Usage Error]"); } if ( s_debug > INFO ) { - printout(INFO,"ConditionsManager","+++ __register(1): %s.%s [%s]", - c->detector.path().c_str(), c.name().c_str(), c->iov->str().c_str()); + printout(INFO,"ConditionsManager","+++ __register(1): %s [%s]", + c.name().c_str(), c->iov->str().c_str()); } c->pool->insert(c); } } - -/// Push registered set of conditions to the corresponding detector elements -void ConditionsManagerObject::__push_immediate(RangeConditions& rc) { - for(RangeConditions::iterator i=rc.begin(); i!=rc.end(); ++i) { - Condition::Object* c = (*i).ptr(); - Interna::ConditionContainer* cnt = c->detector.conditions().ptr(); - if ( s_debug > INFO ) { - printout(INFO,"ConditionsManager","Register condition %s.%s [%s] = %s to Conditions::Container....", - c->detector.path().c_str(), c->name.c_str(), c->iov->str().c_str(), c->value.c_str()); - } - cnt->add(c); - } -} - -/// Load a condition set given a Detector Element and the conditions name according to their validity -bool ConditionsManagerObject::__load_immediate(DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions) -{ - const IOV& iov = req_validity; - { - dd4hep_lock_t locked_action(m_updateLock); - m_loader->load(det, cond, iov, conditions); - } - if ( conditions.size() == 0 ) { - except("ConditionsManager","+++ Condition %s.%s for the requested IOV %s do not exist.", - det.path().c_str(), cond.c_str(), iov.str().c_str()); - } - __push_immediate(conditions); - return true; -} - -/// Load a condition set given a Detector Element and the conditions name according to their validity -bool ConditionsManagerObject::__load_range_immediate(DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions) -{ - const IOV& iov = req_validity; - { - dd4hep_lock_t locked_action(m_updateLock); - m_loader->load_range(det, cond, iov, conditions); - } - if ( conditions.size() == 0 ) { - except("ConditionsManager","+++ Condition %s.%s for the requested IOV %s do not exist.", - det.path().c_str(), cond.c_str(), iov.str().c_str()); - } - __push_immediate(conditions); - conditions.clear(); - return __find_range(det, cond, iov, conditions); -} +#endif /// Retrieve a condition given a Detector Element and the conditions name Condition -ConditionsManagerObject::get(DetElement det, const string& cond, const IOV& req_validity) +ConditionsManagerObject::get(Condition::key_type key, const Condition::iov_type& iov) { - RangeConditions conditions; - const IOV& iov = req_validity; - __check_values__<Discrete>(this, det, cond, &iov); - bool rc = __find(det, cond, iov, conditions); + RC conditions; + __check_values__<Discrete>(this, key, &iov); + bool rc = select(key, iov, conditions); if ( !rc ) { - rc = __load_immediate(det, cond, iov, conditions); + dd4hep_lock_t locked_load(m_updateLock); + m_loader->load(key, iov, conditions); + } + if ( conditions.size() == 1 ) { + conditions[0]->flags |= Condition::ACTIVE; + return conditions[0]; } - if ( !rc ) { - except("ConditionsManager","+++ Condition %s.%s for the requested IOV %s do not exist.", - det.path().c_str(), cond.c_str(), iov.str().c_str()); + else if ( conditions.empty() ) { + except("ConditionsManager","+++ Condition %08X for the requested IOV %s do not exist.", + key, iov.str().c_str()); } else if ( conditions.size() > 1 ) { - printout(ERROR,"ConditionsManager","+++ Condition %s.%s is ambiguous for IOV %s:", - det.path().c_str(), cond.c_str(), iov.str().c_str()); - for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { + RC::const_iterator start = conditions.begin(); + Condition first = *start; + printout(ERROR,"ConditionsManager","+++ Condition %s [%08X] is ambiguous for IOV %s:", + first.name().c_str(), key, iov.str().c_str()); + for(RC::const_iterator i=start; i!=conditions.end(); ++i) { Condition c = *i; - printout(ERROR,"ConditionsManager","+++ %s.%s [%s] = %s", - c->detector.path().c_str(), c.name().c_str(), c->iov->str().c_str(), c->value.c_str()); + printout(ERROR,"ConditionsManager","+++ %s [%s] = %s", + c.name().c_str(), c->iov->str().c_str(), c->value.c_str()); } - except("ConditionsManager","+++ Condition %s.%s is ambiguous for IOV %s:", - det.path().c_str(), cond.c_str(), iov.str().c_str()); - } - if ( conditions.size() == 1 ) { - conditions[0]->flags |= ConditionObject::ACTIVE; - return conditions[0]; + except("ConditionsManager","+++ Condition %s [%08X] is ambiguous for IOV %s:", + first.name().c_str(), key, iov.str().c_str()); } return Condition(); } /// Retrieve a condition given a Detector Element and the conditions name RangeConditions -ConditionsManagerObject::getRange(DetElement det, - const std::string& cond, - const IOV& req_range_validity) +ConditionsManagerObject::getRange(Condition::key_type key, const Condition::iov_type& iov) { - RangeConditions conditions; - const IOV& iov = req_range_validity; - __check_values__<Range>(this, det, cond, &iov); - bool rc = __find_range(det, cond, iov, conditions); + RC conditions; + __check_values__<Range>(this, key, &iov); + bool rc = select_range(key, iov, conditions); if ( rc ) { return conditions; } - rc = __load_range_immediate(det, cond, iov, conditions); + else { + dd4hep_lock_t locked_load(m_updateLock); + m_loader->load_range(key, iov, conditions); + if ( conditions.empty() ) { + except("ConditionsManager","+++ Conditions %08X for IOV %s do not exist.", + key, iov.str().c_str()); + } + conditions.clear(); + } + rc = select_range(key, iov, conditions); if ( !rc ) { - except("ConditionsManager","+++ Conditions %s.%s for IOV %s do not exist.", - det.path().c_str(), cond.c_str(), iov.str().c_str()); + except("ConditionsManager","+++ Conditions %08X for IOV %s do not exist.", + key, iov.str().c_str()); } return conditions; } diff --git a/DDCond/src/ConditionsLoaderImp.cpp b/DDCond/src/ConditionsLoaderImp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f0d69afc1e4c8058f8e210eff0ab3ee0b998c822 --- /dev/null +++ b/DDCond/src/ConditionsLoaderImp.cpp @@ -0,0 +1,52 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsLoaderImp.h" + +using namespace DD4hep::Conditions; + +/// Default constructor +ConditionsLoaderImp::ConditionsLoaderImp(ConditionsManager mgr) + : m_manager(mgr), m_refCount(1) +{ +} + +/// Default destructor +ConditionsLoaderImp::~ConditionsLoaderImp() { +} + +/// Addreference count. Use object +void ConditionsLoaderImp::addRef() { + ++m_refCount; +} + +/// Release object. The client may not use any reference any further. +void ConditionsLoaderImp::release() { + if ( --m_refCount <= 0 ) { + delete this; + } +} + +/// Access the conditions loading mechanism +Condition ConditionsLoaderImp::get(key_type key, const Condition::iov_type& iov) { + return m_manager.ptr()->get(key, iov); +} + +/// Access the conditions loading mechanism. Only conditions in the user pool will be accessed. +Condition ConditionsLoaderImp::get(key_type key, const UserPool& pool) { + return pool.get(key); +} diff --git a/DDCond/src/ConditionsManager.cpp b/DDCond/src/ConditionsManager.cpp index 2b873384370c1b2a185ff174b7f7eee43e642769..ff58c5da23c44f9f095fdfb378ae937a74be88a0 100644 --- a/DDCond/src/ConditionsManager.cpp +++ b/DDCond/src/ConditionsManager.cpp @@ -14,13 +14,9 @@ // Framework include files #include "DD4hep/LCDD.h" -#include "DD4hep/Errors.h" #include "DD4hep/Printout.h" -#include "DD4hep/DetectorTools.h" - #include "DDCond/ConditionsInterna.h" #include "DDCond/ConditionsManager.h" -#include "DDCond/ConditionsPool.h" using namespace std; using namespace DD4hep; @@ -51,6 +47,11 @@ ConditionsManager::ConditionsManager(LCDD& lcdd) { ConditionsManager::~ConditionsManager() { } +ConditionsManager& ConditionsManager::initialize() { + access()->initialize(); + return *this; +} + /// Access to the property manager PropertyManager& ConditionsManager::properties() const { return access()->properties(); @@ -61,20 +62,20 @@ Property& ConditionsManager::operator[](const std::string& property_name) const return access()->properties().property(property_name); } -/// Access the conditions loader -Handle<ConditionsManager::Loader> ConditionsManager::loader() const { - return Handle<Loader>(access()->m_loader.get()); -} - /// Register new IOV type if it does not (yet) exist. pair<bool, const IOVType*> ConditionsManager::registerIOVType(size_t iov_type, const string& iov_name) { return access()->registerIOVType(iov_type, iov_name); } -/// Access the availible/known IOV types -const ConditionsManager::IOVTypes& ConditionsManager::iovTypes() const { - return access()->iovTypes(); +/// Access IOV by its name +const IOVType* ConditionsManager::iovType (const string& iov_name) const { + return access()->iovType(iov_name); +} + +/// Access conditions multi IOV pool by iov type +ConditionsIOVPool* ConditionsManager::iovPool(const IOVType& iov_type) const { + return access()->m_rawPool[iov_type.type]; } /// Access the used/registered IOV types @@ -86,29 +87,10 @@ const vector<const IOVType*> ConditionsManager::iovTypesUsed() const { if ( int((*i).type) != IOVType::UNKNOWN_IOV ) result.push_back(&(*i)); return result; } - -/// Access IOV by its type -const IOVType* ConditionsManager::iovType (size_t iov_type) const { - return access()->iovType(iov_type); -} - -/// Access IOV by its name -const IOVType* ConditionsManager::iovType (const string& iov_name) const { - return access()->iovType(iov_name); -} -/// Access conditions pool by iov type -ConditionsIOVPool* ConditionsManager::iovPool(const IOVType& type) const { - Object* obj = access(); - if ( int(type.type) != IOVType::UNKNOWN_IOV && type.type < obj->m_pool.size() ) { - ConditionsIOVPool* pool = obj->m_pool[type.type]; - if ( pool ) { - return pool; - } - } - except("ConditionsManager","+++ Attempt to access invalid iov pool of type:%d. [%s]", - type.type, Errors::linkRange().c_str()); - return 0; +/// Register IOV with type and key +ConditionsPool* ConditionsManager::registerIOV(const IOVType& typ, IOV::Key key) { + return access()->registerIOV(typ, key); } /// Create IOV from string @@ -116,13 +98,6 @@ void ConditionsManager::fromString(const string& iov_str, IOV& iov) { access()->fromString(iov_str, iov); } -/// Register new condition with the conditions store. Unlocked version, not multi-threaded -bool ConditionsManager::registerUnlocked(const IOVType* type, IOV::Key key, Condition cond) { - Object* obj = access(); - ConditionsPool* pool = obj->registerIOV(*type, key); - return obj->registerUnlocked(pool, cond); -} - /// Register new condition with the conditions store. Unlocked version, not multi-threaded bool ConditionsManager::registerUnlocked(ConditionsPool* pool, Condition cond) { return access()->registerUnlocked(pool, cond); @@ -138,98 +113,15 @@ void ConditionsManager::clear() { access()->clear(); } -/// Retrieve a condition given a Detector Element and the conditions name -Condition -ConditionsManager::get(DetElement detector, - const string& cond, - const IOV& req_validity) -{ - return access()->get(detector, cond, req_validity); -} - -/// Retrieve a condition given a Detector Element path and the conditions name -Condition -ConditionsManager::get(const string& detector_path, - const string& cond, - const IOV& req_validity) -{ - Interna::ConditionsManagerObject* o = access(); - DetElement detector = Geometry::DetectorTools::findDaughterElement(o->m_lcdd.world(), detector_path); - return o->get(detector, cond, req_validity); -} - -/// Push all pending updates to the conditions store -void ConditionsManager::pushUpdates() { - access()->pushUpdates(); -} - -/// Lock the internal data structures. This disables calls to "register", etc. -void ConditionsManager::lock() { - access()->locked = 1; -} - -/// Unlock the internal data structures. This enables calls to "register", etc. -void ConditionsManager::unlock() { - access()->locked = 0; -} - -/// Enable all updates to the clients with the defined IOV -long ConditionsManager::enable(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool) { - return access()->enable(required_validity, user_pool); -} - /// Prepare all updates to the clients with the defined new IOV. Changes are not yet applied -long ConditionsManager::prepare(const IOV& required_validity, dd4hep_ptr<ConditionsPool>& user_pool) { +long ConditionsManager::prepare(const IOV& required_validity, dd4hep_ptr<UserPool>& user_pool) { return access()->prepare(required_validity, user_pool); } - -/// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> -Condition -ConditionsManager::get(const string& conditions_path, const IOV& req_validity) -{ - size_t idx = conditions_path.rfind("."); - if ( idx != string::npos ) { - string detector_path = conditions_path.substr(0,idx); - string condition_name = conditions_path.substr(idx+1, string::npos); - return this->get(detector_path,condition_name, req_validity); - } - except("ConditionsManager","+++ Badly formed conditions path %s. [%s]", - conditions_path.c_str(),Errors::linkRange().c_str()); - return Condition(); -} - -/// Retrieve a condition given a Detector Element and the conditions name -RangeConditions -ConditionsManager::getRange(DetElement detector, - const std::string& condition_name, - const IOV& req_range_validity) -{ - return access()->getRange(detector, condition_name, req_range_validity); -} - -/// Retrieve a condition given a Detector Element path and the conditions name -RangeConditions -ConditionsManager::getRange(const std::string& detector_path, - const std::string& condition_name, - const IOV& req_range_validity) -{ - Interna::ConditionsManagerObject* o = access(); - DetElement detector = Geometry::DetectorTools::findDaughterElement(o->m_lcdd.world(), detector_path); - return o->getRange(detector, condition_name, req_range_validity); -} - -/// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> -RangeConditions -ConditionsManager::getRange(const std::string& conditions_path, - const IOV& req_range_validity) -{ - size_t idx = conditions_path.rfind("."); - if ( idx != string::npos ) { - string detector_path = conditions_path.substr(0,idx); - string condition_name = conditions_path.substr(idx+1, string::npos); - return this->getRange(detector_path,condition_name, req_range_validity); - } - except("ConditionsManager","+++ Badly formed conditions path %s. [%s]", - conditions_path.c_str(),Errors::linkRange().c_str()); - return RangeConditions(); + +/// Prepare all updates to the clients with the defined IOV +long ConditionsManager::prepare(const IOV& required_validity, + dd4hep_ptr<UserPool>& user_pool, + const Dependencies& dependencies, + bool verify_dependencies) { + return access()->prepare(required_validity, user_pool, dependencies, verify_dependencies); } diff --git a/DDCond/src/ConditionsOperators.cpp b/DDCond/src/ConditionsOperators.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb8f4a2d6240edd6a62590f670b23704c543ab23 --- /dev/null +++ b/DDCond/src/ConditionsOperators.cpp @@ -0,0 +1,93 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/Printout.h" +#include "DD4hep/InstanceCount.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsOperators.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsInterna.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; +using DD4hep::Geometry::LCDD; + +/// Select all condition from the conditions manager registered at the LCDD object +size_t Operators::collectAllConditions(LCDD& lcdd, RangeConditions& conditions) { + ConditionsManager manager = ConditionsManager::from(lcdd); + return collectAllConditions(manager, conditions); +} + +/// Select all condition from the conditions manager registered at the LCDD object +size_t Operators::collectAllConditions(ConditionsManager manager, RangeConditions& conditions) { + typedef vector<const IOVType*> _T; + typedef ConditionsIOVPool::Elements _E; + const _T types = manager.iovTypesUsed(); + size_t num_conditions = 0; + for( _T::const_iterator i = types.begin(); i != types.end(); ++i ) { + const IOVType* type = *i; + if ( type ) { + ConditionsIOVPool* pool = manager.iovPool(*type); + if ( pool ) { + const _E& e = pool->elements; + for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { + ConditionsPool* cp = (*j).second; + RangeConditions rc; + cp->select_all(rc); + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) + conditions.push_back(*ic); + num_conditions += rc.size(); + } + } + } + } + return num_conditions; +} + +/// Select all condition from the conditions manager registered at the LCDD object +size_t Operators::collectAllConditions(LCDD& lcdd, std::map<int,Condition>& conditions) { + ConditionsManager manager = ConditionsManager::from(lcdd); + return collectAllConditions(manager, conditions); +} + +/// Select all condition from the conditions manager registered at the LCDD object +size_t Operators::collectAllConditions(ConditionsManager manager, std::map<int,Condition>& conditions) { + typedef vector<const IOVType*> _T; + typedef ConditionsIOVPool::Elements _E; + const _T types = manager.iovTypesUsed(); + size_t num_conditions = 0; + for( _T::const_iterator i = types.begin(); i != types.end(); ++i ) { + const IOVType* type = *i; + if ( type ) { + ConditionsIOVPool* pool = manager.iovPool(*type); + if ( pool ) { + const _E& e = pool->elements; + for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { + ConditionsPool* cp = (*j).second; + RangeConditions rc; + cp->select_all(rc); + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) + conditions.insert(make_pair((*ic)->hash,*ic)); + num_conditions += rc.size(); + } + } + } + } + return num_conditions; +} + diff --git a/DDCond/src/ConditionsPool.cpp b/DDCond/src/ConditionsPool.cpp index 4e726197fed65ee97b000fec2e1e80c44295e3e8..3a651dc315dd1d69cabb4591d5faa6bafa13fb0f 100644 --- a/DDCond/src/ConditionsPool.cpp +++ b/DDCond/src/ConditionsPool.cpp @@ -16,10 +16,7 @@ #include "DD4hep/Handle.inl" #include "DD4hep/Printout.h" #include "DD4hep/InstanceCount.h" -#include "DD4hep/objects/ConditionsInterna.h" - #include "DDCond/ConditionsPool.h" -#include "DDCond/ConditionsEntry.h" #include "DDCond/ConditionsInterna.h" using std::string; @@ -30,8 +27,7 @@ DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsPool); /// Default constructor ConditionsPool::ConditionsPool(ConditionsManager mgr) - : NamedObject(), m_manager(mgr), - iovType(0), iov(0), age_value(AGE_NONE), pool_type(NO_POOL_TYPE) + : NamedObject(), m_manager(mgr), iovType(0), iov(0), age_value(AGE_NONE) { InstanceCount::increment(this); } @@ -42,39 +38,10 @@ ConditionsPool::~ConditionsPool() { InstanceCount::decrement(this); } -/// Unconditionally create a new condition from the input data -Condition ConditionsPool::create(ConditionsPool* pool, const Entry* entry) { - Condition condition(entry->name,entry->type); - Condition::Object* c = condition.ptr(); - //c->name = entry->name; - // c->type = entry->type; - c->value = entry->value; - c->comment = "----"; - c->address = "----"; - c->validity = entry->validity; - c->detector = entry->detector; - c->iov = pool->iov; - c->pool = pool; - return c; -} - /// Print pool basics void ConditionsPool::print(const string& opt) const { - const IOVType* iov_type = iov->iovType; - if ( iov_type->name == "epoch" ) { - time_t since = iov->key().first; - time_t until = iov->key().second; - char c_since[64], c_until[64]; - struct tm time_buff; - ::strftime(c_since,sizeof(c_since),"%d-%m-%Y %H:%M:%S",::gmtime_r(&since,&time_buff)); - ::strftime(c_until,sizeof(c_until),"%d-%m-%Y %H:%M:%S",::gmtime_r(&until,&time_buff)); - printout(INFO,"Conditions","+++ %s Conditions for pool with IOV: %s(%d) age:%3d [%4d entries] [%s -> %s] ", - opt.c_str(), iov_type->name.c_str(), iov_type->type, age_value, count(), c_since, c_until); - } - else { - printout(INFO,"Example","+++ %s Conditions for pool with IOV: %-32s age:%3d [%4d entries]", - opt.c_str(), iov->str().c_str(), age_value, count()); - } + printout(INFO,"Example","+++ %s Conditions for pool with IOV: %-32s age:%3d [%4d entries]", + opt.c_str(), iov->str().c_str(), age_value, count()); } /// Listener invocation when a condition is registered to the cache @@ -90,7 +57,6 @@ void ConditionsPool::onRemove(Condition condition) { /// Default constructor UpdatePool::UpdatePool(ConditionsManager mgr) : ConditionsPool(mgr) { - pool_type = UPDATE_POOL_TYPE; } /// Default destructor @@ -98,10 +64,13 @@ UpdatePool::~UpdatePool() { } /// Default constructor -UserPool::UserPool(ConditionsManager mgr) : ConditionsPool(mgr) { - pool_type = USER_POOL_TYPE; +UserPool::UserPool(ConditionsManager mgr, ConditionsIOVPool* pool) + : m_iov(0), m_manager(mgr), m_iovPool(pool) +{ + InstanceCount::increment(this); } /// Default destructor. UserPool::~UserPool() { + InstanceCount::decrement(this); } diff --git a/DDCond/src/ConditionsTest.cpp b/DDCond/src/ConditionsTest.cpp index d017bb8f17cd3cc9bb79fc16efd858d04956b723..93f0e2e0b1b046f4d61faf35a8de9f21b07aa735 100644 --- a/DDCond/src/ConditionsTest.cpp +++ b/DDCond/src/ConditionsTest.cpp @@ -13,8 +13,10 @@ //========================================================================== // Framework include files +#include "DD4hep/DetConditions.h" #include "DD4hep/DetectorTools.h" #include "DDCond/ConditionsTest.h" +#include "DD4hep/objects/DetectorInterna.h" #include "DD4hep/objects/ConditionsInterna.h" // C/C++ include files @@ -41,31 +43,28 @@ namespace DD4hep { template<typename T> void __print_bound_val(Condition c, const char* norm) { - const char* test = c.detector().name(); char text_format[1024]; const T& value = access_val<T>(c); if ( norm ) { T val = _multiply(c.get<T>(),norm); ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s [%s] Type: %%s", Primitive<T>::default_format(),Primitive<T>::default_format()); - printout(INFO,test,text_format, c.name().c_str(), value, val, typeName(c.typeInfo()).c_str()); + printout(INFO,"Cond_Value",text_format, c.name().c_str(), value, val, typeName(c.typeInfo()).c_str()); return; } ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s Type: %%s", Primitive<T>::default_format()); - printout(INFO,test,text_format, c.name().c_str(), value, typeName(c.typeInfo()).c_str()); + printout(INFO,"Cond_Value",text_format, c.name().c_str(), value, typeName(c.typeInfo()).c_str()); } template <> void __print_bound_val<string>(Condition c, const char*) { - const char* test = c.detector().name(); const string& v = access_val<string>(c); - printout(INFO,test," Bound value %s : string value:%s Type: %s Ptr:%016X", + printout(INFO,"Cond_Value"," Bound value %s : string value:%s Type: %s Ptr:%016X", c.name().c_str(), c.get<string>().c_str(),typeName(c.typeInfo()).c_str(), (void*)&v); } template <typename T> void __print_bound_container(Condition c, const char*) { - const char* test = c.detector().name(); const T& v = access_val<T>(c); - printout(INFO,test," Bound value %s : size:%d = %s Type: %s Ptr:%016X", + printout(INFO,"Cond_Value"," Bound value %s : size:%d = %s Type: %s Ptr:%016X", c.name().c_str(), int(v.size()), c.block().str().c_str(), typeName(c.typeInfo()).c_str(), (void*)&v); } @@ -113,11 +112,10 @@ namespace DD4hep { TEMPLATE_TYPE(std::string,"%c") template <> void print_condition<void>(Condition c) { - const char* test = c.detector().name(); string type = c.type(); - printout(INFO,test,"%-32s [%16s] : %s [%s] ", - (c.detector().path()+"."+c.name()).c_str(),c.type().c_str(), - c.value().c_str(),c.validity().c_str()); + printout(INFO,"Cond_Value","%-32s [%16s] : %s [%s] ", + c.name().c_str(),c.type().c_str(), + c.value().c_str(),c->validity.c_str()); if ( type == "alignment" ) print_bound_value<string>(c); else if ( type == "temperature" ) @@ -162,11 +160,11 @@ namespace DD4hep { if ( iov.contains(*i) ) { return; } - except("Example", "+++ The condition %s.%s [%s] is not fully contained in iov:%s", - c->detector.path().c_str(), c->name.c_str(), i->str().c_str(), iov.str().c_str()); + except("Example", "+++ The condition %s [%s] is not fully contained in iov:%s", + c->name.c_str(), i->str().c_str(), iov.str().c_str()); } - except("Example", "+++ The condition %s.%s [%s] has no discrete type matching iov:%s", - c->detector.path().c_str(), c->name.c_str(), i->str().c_str(), iov.str().c_str()); + except("Example", "+++ The condition %s [%s] has no discrete type matching iov:%s", + c->name.c_str(), i->str().c_str(), iov.str().c_str()); } } } @@ -180,7 +178,7 @@ Test::TestEnv::TestEnv(LCDD& _lcdd, const string& detector_name) manager["PoolType"] = "DD4hep_ConditionsLinearPool"; manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; manager["UserPoolType"] = "DD4hep_ConditionsLinearUserPool"; - manager->initialize(); + manager.initialize(); detector = lcdd.detector(detector_name); if ( detector.isValid() ) { pair<bool, const IOVType*> e = manager.registerIOVType(0, "epoch"); @@ -211,14 +209,14 @@ void Test::TestEnv::add_xml_data_source(const string& file, const string& iov_st void Test::TestEnv::dump_conditions_pools() { typedef RangeConditions _R; - typedef ConditionsIOVPool::Entries _E; - typedef Interna::ConditionsManagerObject::TypedConditionPool _P; + typedef ConditionsIOVPool::Elements _E; + typedef ConditionsManagerObject::TypedConditionPool _P; int cnt = 0; - _P& p = this->manager->m_pool; + const _P& p = manager->conditionsPool(); for(_P::const_iterator i=p.begin(); i != p.end(); ++i, ++cnt) { - ConditionsIOVPool* pool = (*i); + const ConditionsIOVPool* pool = (*i); if ( pool ) { - const _E& e = pool->entries; + const _E& e = pool->elements; const IOVType* typ = this->manager->iovType(cnt); printout(INFO,"Example","+++ ConditionsIOVPool for type %s", typ->str().c_str()); for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { @@ -239,21 +237,23 @@ void Test::TestEnv::dump_conditions_pools() /// Dump the conditions of one detectpr element void Test::TestEnv::dump_detector_element(DetElement elt) { - Container conds = elt.conditions(); - printout(INFO,"conditions","DetElement:%s # of conditons:%d",elt.path().c_str(),int(conds.count())); - const Container::Entries& entries = conds.entries(); - for(Container::Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + DetConditions c(elt); + Container conds = c.conditions(); + printout(INFO,"conditions","DetElement:%s # of conditons keys:%d",elt.path().c_str(),int(conds.numKeys())); +#if 0 + const Container::Elements& elements = conds.elements(); + for(Container::Elements::const_iterator i=elements.begin(); i!=elements.end(); ++i) { Condition cond((*i).second); print_condition<void>(cond); } +#endif } /// Dump conditions tree of a detector element void Test::TestEnv::dump_conditions_tree(DetElement elt) { - Container conds = elt.conditions(); const DetElement::Children& children = elt.children(); - if ( !conds.isValid() ) + if ( !elt->conditions.isValid() ) printout(INFO,"conditions_tree","DetElement:%s NO CONDITIONS present",elt.path().c_str()); else dump_detector_element(elt); diff --git a/DDCond/src/plugins/ConditionsExample.cpp b/DDCond/src/plugins/ConditionsExample.cpp index b78f049aebb222c5c990fa7000d08f4135c23115..cbd8a38eabd9b9e8b5ab77ca6062400c0403fdb6 100644 --- a/DDCond/src/plugins/ConditionsExample.cpp +++ b/DDCond/src/plugins/ConditionsExample.cpp @@ -24,17 +24,22 @@ using Geometry::DetElement; namespace { + struct _Key : public std::string { + _Key(DetElement d, const std::string& nam) : std::string(d.path()+"."+nam) {} + }; void print_tpc_epoch_conditions(Test::TestEnv& env, const IOV& iov_epoch, bool check = true) { - Condition cond = env.manager.get(env.detector,"AmbientTemperature",iov_epoch); + DetConditions dc(env.detector); + ConditionsAccess access(env.manager); + Condition cond = access.get(_Key(env.detector,"AmbientTemperature"),iov_epoch); Test::print_condition<void>(cond); - cond = env.detector.condition("AmbientTemperature",iov_epoch); + cond = dc.get("AmbientTemperature",iov_epoch); if ( check ) Test::check_discrete_condition(cond, iov_epoch); Test::print_condition<void>(cond); - cond = env.detector.condition("ExternalPressure",iov_epoch); + cond = dc.get("ExternalPressure",iov_epoch); if ( check ) Test::check_discrete_condition(cond, iov_epoch); Test::print_condition<void>(cond); - cond = env.detector.condition("SomeMultiParams",iov_epoch); + cond = dc.get("SomeMultiParams",iov_epoch); if ( check ) Test::check_discrete_condition(cond, iov_epoch); Test::print_condition<void>(cond); cond->value = "[5,6,7,8,9,10,11,12,13,14]"; @@ -42,13 +47,14 @@ namespace { Test::print_condition<void>(cond); } void print_tpc_run_conditions(Test::TestEnv& env, const IOV& iov_run, bool check = true) { - Condition cond = env.detector.condition("alignment",iov_run); + DetConditions dc(env.detector); + Condition cond = dc.get("alignment",iov_run); if ( check ) Test::check_discrete_condition(cond, iov_run); Test::print_condition<void>(cond); - cond = env.detector.condition("TPC_A_align",iov_run); + cond = dc.get("TPC_A_align",iov_run); if ( check ) Test::check_discrete_condition(cond, iov_run); Test::print_condition<void>(cond); - cond = env.daughter("TPC_SideA").condition("alignment",iov_run); + cond = DetConditions(env.daughter("TPC_SideA")).get("alignment",iov_run); if ( check ) Test::check_discrete_condition(cond, iov_run); Test::print_condition<void>(cond); } @@ -64,15 +70,13 @@ namespace { } void print_tpc_discrete_conditions(Test::TestEnv& env, int epoch_min, int epoch_max, int run_min, int run_max) { - dd4hep_ptr<ConditionsPool> pool_run, pool_epoch; + dd4hep_ptr<UserPool> pool_run, pool_epoch; IOV iov_epoch(env.epoch), iov_run(env.run); iov_epoch.set(epoch_min, epoch_max); iov_run.set(run_min, run_max); env.manager.prepare(iov_run, pool_run); - env.manager.enable(iov_run, pool_run); env.manager.prepare(iov_epoch, pool_epoch); - env.manager.enable(iov_epoch, pool_epoch); print_tpc_discrete_conditions(env, iov_epoch, iov_run); } @@ -87,7 +91,8 @@ namespace { IOV iov_run(env.run); iov_run.set(run_min, run_max); try { - cond = env.manager.getRange(env.detector,"TPC_A_align",iov_run); + ConditionsAccess access(env.manager); + cond = access.getRange(_Key(env.detector,"TPC_A_align"),iov_run); Test::print_conditions<void>(cond); printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); printout(INFO,"Example","SUCCESS: +++ RANGE Conditions access OK for iov:%s!",iov_run.str().c_str()); @@ -135,7 +140,7 @@ namespace { int example3(LCDD& lcdd, int, char** ) { printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - printout(INFO,"Example1","+++ Executing Conditions example No. 3: Conditions register/enable"); + printout(INFO,"Example1","+++ Executing Conditions example No. 3: Conditions registration "); printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); Test::TestEnv env(lcdd, "TPC"); @@ -147,14 +152,12 @@ namespace { IOV iov_epoch(env.epoch), iov_run(env.run); - dd4hep_ptr<ConditionsPool> pool_run, pool_epoch; + dd4hep_ptr<UserPool> pool_run, pool_epoch; iov_epoch.set(1396887257); iov_run.set(563543); env.manager.prepare(iov_run, pool_run); - env.manager.enable(iov_run, pool_run); env.manager.prepare(iov_epoch, pool_epoch); - env.manager.enable(iov_epoch, pool_epoch); print_tpc_epoch_conditions(env, iov_epoch); print_tpc_run_conditions(env, iov_run, true); printout(INFO,"Example1","==================================================================="); @@ -168,7 +171,6 @@ namespace { printout(INFO,"Example1","==================================================================="); iov_run.set(123456); - env.manager.enable(iov_run, pool_run); print_tpc_run_conditions(env, iov_run, true); return 1; } @@ -208,7 +210,7 @@ namespace { } -DECLARE_APPLY(DD4hepConditionsAccessTest,example1) -DECLARE_APPLY(DD4hepExample3,example3) -DECLARE_APPLY(DD4hepConditionsTreeDump,example2) -DECLARE_APPLY(DD4hepCallbackInstallTest,DD4hep_CallbackInstallTest) +DECLARE_APPLY(DD4hep_Test_ConditionsAccess,example1) +DECLARE_APPLY(DD4hep_Test_ConditionsExample3,example3) +DECLARE_APPLY(DD4hep_Test_ConditionsTreeDump,example2) +DECLARE_APPLY(DD4hep_Test_CallbackInstall,DD4hep_CallbackInstallTest) diff --git a/DDCond/src/plugins/ConditionsLinearPool.cpp b/DDCond/src/plugins/ConditionsLinearPool.cpp index 97f5ef50f3e1b1eb3394b5fd72970d70b77ccbef..241e32856e96567135c5eef01af75f46423c400e 100644 --- a/DDCond/src/plugins/ConditionsLinearPool.cpp +++ b/DDCond/src/plugins/ConditionsLinearPool.cpp @@ -15,10 +15,10 @@ #define DDCOND_CONDITIONSLINEARPOOL_H // Framework include files -#include "DD4hep/objects/DetectorInterna.h" #include "DD4hep/objects/ConditionsInterna.h" #include "DDCond/ConditionsPool.h" -#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsSelectors.h" // C/C++ include files #include <list> @@ -39,9 +39,11 @@ namespace DD4hep { template<typename MAPPING, typename BASE> class ConditionsLinearPool : public BASE { protected: - typedef BASE Base; - typedef MAPPING Mapping; - Mapping m_conditions; + typedef BASE Base; + typedef MAPPING Mapping; + typedef typename BASE::key_type key_type; + Mapping m_entries; + public: /// Default constructor ConditionsLinearPool(ConditionsManager mgr); @@ -50,179 +52,48 @@ namespace DD4hep { virtual ~ConditionsLinearPool(); /// Total entry count - virtual int count() const { - return (int)m_conditions.size(); - } - /// Check if detector and name match - bool __match(const DetElement::Object* det, int hash, const Condition::Object* c) const { - return det == c->detector.ptr() && hash == c->hash; - } - - /// Register a new condition to this pool - virtual void insert(Condition condition) { - Condition::Object* c = condition.access(); - m_conditions.insert(m_conditions.end(),c); - } - - /// Register a new condition to this pool. May overload for performance reasons. - virtual void insert(RangeConditions& new_entries) { - for(RangeConditions::iterator i=new_entries.begin(); i!=new_entries.end(); ++i) { - Condition::Object* c = (*i).access(); - m_conditions.insert(m_conditions.end(),c); - } - } - - /// Register a new condition to this pool - virtual Condition insertEntry(ConditionsPool* pool, Entry* cond) { - Condition c = this->create(pool, cond); - this->insert(c); - return c; + virtual size_t count() const { + return m_entries.size(); } /// Full cleanup of all managed conditions. virtual void clear() { - for(typename Mapping::iterator i=m_conditions.begin(); i != m_conditions.end(); ++i) - this->ConditionsPool::onRemove(*i); - for(typename Mapping::iterator i=m_conditions.begin(); i != m_conditions.end(); ++i) - DD4hep::deleteObject<Condition::Object>(*i); - m_conditions.clear(); + for_each(m_entries.begin(), m_entries.end(), ConditionsPoolRemove(*this)); + m_entries.clear(); } /// Check if a condition exists in the pool - virtual Condition exists(DetElement det, const std::string& cond_name) const { - if ( !m_conditions.empty() ) { - int hash = DD4hep::hash32(cond_name); - DetElement::Object* ptr = det.ptr(); - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) - if ( __match(ptr,hash,(*i)) ) return *i; - } - return Condition(); + virtual Condition exists(Condition::key_type key) const { + typename Mapping::const_iterator i= + find_if(m_entries.begin(), m_entries.end(), HashConditionFind(key)); + return i==m_entries.end() ? Condition() : (*i); } - /// Check if a condition exists in the pool - virtual Condition exists(Condition test) const { - int hash = DD4hep::hash32(test->name); - DetElement::Object* ptr = test->detector.ptr(); - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { - if ( __match(ptr,hash,(*i)) ) return *i; - } - return Condition(); - } + /// Register a new condition to this pool + virtual void insert(Condition condition) + { m_entries.insert(m_entries.end(),condition.access()); } + + /// Register a new condition to this pool. May overload for performance reasons. + virtual void insert(RangeConditions& new_entries) + { for_each(new_entries.begin(), new_entries.end(), collectionSelect(m_entries)); } /// Select the conditions matching the DetElement and the conditions name - virtual void select(DetElement det, const std::string& cond_name, RangeConditions& result) { - if ( !m_conditions.empty() ) { - int hash = DD4hep::hash32(cond_name); - DetElement::Object* ptr = det.ptr(); - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) - if ( __match(ptr,hash,(*i)) ) result.push_back(*i); - } - } + virtual void select(Condition::key_type key, RangeConditions& result) + { for_each(m_entries.begin(), m_entries.end(), keyedSelect(key, result)); } /// Select the conditons, used also by the DetElement of the condition - virtual void select_used(RangeConditions& result) { - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { - Condition::Object* c = *i; - if ( (c->flags & Interna::ConditionObject::ACTIVE) ) result.push_back(c); -#if 0 - // Too slow. Simple check the conditions flag. If it is set to ACTIVE, take it. - const Container::Entries& cond = c->detector->conditions->elements(); - Container::Entries::const_iterator k=cond.find(c->hash); - if ( k != cond.end() ) { - if ( (*k).second->pool == this ) { - result.push_back(c); - } - } -#endif - } - } + virtual void select_used(RangeConditions& result) + { for_each(m_entries.begin(), m_entries.end(), activeSelect(result)); } /// Select the conditons, used also by the DetElement of the condition - virtual void select_all(RangeConditions& result) { - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) - result.push_back(*i); - } + virtual void select_all(RangeConditions& result) + { for_each(m_entries.begin(), m_entries.end(), collectionSelect(result)); } /// Select the conditons, used also by the DetElement of the condition - virtual void select_all(ConditionsPool& selection_pool) { - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { - selection_pool.insert(*i); - } - } - - /// Select the conditions matching the DetElement and the conditions name - virtual void select_range(DetElement det, - const std::string& cond_name, - const IOV& req, - RangeConditions& result) - { - if ( !m_conditions.empty() ) { - unsigned int req_typ = req.iovType ? req.iovType->type : req.type; - const IOV::Key& req_key = req.key(); - int hash = DD4hep::hash32(cond_name); - DetElement::Object* ptr = det.ptr(); - for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { - if ( __match(ptr,hash,(*i)) ) { - const IOV* _iov = (*i)->iov; - unsigned int typ = _iov->iovType ? _iov->iovType->type : _iov->type; - if ( req_typ == typ ) { - if ( IOV::key_is_contained(_iov->key(),req_key) ) - // IOV test contained in key. Take it! - result.push_back(*i); - else if ( IOV::key_overlaps_lower_end(_iov->key(),req_key) ) - // IOV overlap on test on the lower end of key - result.push_back(*i); - else if ( IOV::key_overlaps_higher_end(_iov->key(),req_key) ) - // IOV overlap of test on the higher end of key - result.push_back(*i); - } - } - } - } - } + virtual void select_all(ConditionsPool& selection_pool) + { for_each(m_entries.begin(), m_entries.end(), ConditionsPoolInsert(selection_pool)); } }; - /// Class implementing the conditions user pool for a given IOV type - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - template<typename MAPPING> class ConditionsLinearUserPool - : public ConditionsLinearPool<MAPPING,UserPool> - { - IOV m_iov; - public: - /// Default constructor - ConditionsLinearUserPool(ConditionsManager mgr) - : ConditionsLinearPool<MAPPING,UserPool>(mgr), m_iov(0) - { - this->ConditionsPool::iov = &m_iov; - this->ConditionsPool::iovType = 0; - } - - /// Default destructor - virtual ~ConditionsLinearUserPool() {} - - /// Access the interval of validity for this user pool - virtual const IOV& validity() const { - return this->m_iov; - } - /// Update interval of validity for this user pool (should only be called by ConditionsManager) - virtual void setValidity(const IOV& value) { - this->m_iov = value; - this->ConditionsPool::iovType = m_iov.iovType; - } - - /// Full cleanup of all managed conditions. - virtual void clear() { - m_iov = IOV(0); - this->ConditionsLinearPool<MAPPING,UserPool>::m_conditions.clear(); - } - }; - - /// Class implementing the conditions update pool for a given IOV type /** * @@ -230,13 +101,14 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - template<typename MAPPING> class ConditionsLinearUpdatePool - : public ConditionsLinearPool<MAPPING,UpdatePool> + template<typename MAPPING, typename BASE> class ConditionsLinearUpdatePool + : public ConditionsLinearPool<MAPPING,BASE> { + typedef typename ConditionsLinearPool<MAPPING,BASE>::key_type key_type; public: /// Default constructor ConditionsLinearUpdatePool(ConditionsManager mgr) - : ConditionsLinearPool<MAPPING,UpdatePool>(mgr) + : ConditionsLinearPool<MAPPING,BASE>(mgr) { } @@ -245,15 +117,45 @@ namespace DD4hep { /// Adopt all entries sorted by IOV. Entries will be removed from the pool virtual void popEntries(UpdatePool::UpdateEntries& entries) { - MAPPING& m = this->ConditionsLinearPool<MAPPING,UpdatePool>::m_conditions; + MAPPING& m = this->ConditionsLinearPool<MAPPING,BASE>::m_entries; if ( !m.empty() ) { for(typename MAPPING::iterator i=m.begin(); i!=m.end(); ++i) { - Interna::ConditionObject* o = *i; + Condition::Object* o = *i; entries[o->iov].push_back(Condition(o)); } m.clear(); } } + + /// Select the conditions matching the DetElement and the conditions name + virtual void select_range(Condition::key_type key, + const Condition::iov_type& req, + RangeConditions& result) + { + MAPPING& m = this->ConditionsLinearPool<MAPPING,BASE>::m_entries; + if ( !m.empty() ) { + unsigned int req_typ = req.iovType ? req.iovType->type : req.type; + const IOV::Key& req_key = req.key(); + for(typename MAPPING::const_iterator i=m.begin(); i != m.end(); ++i) { + if ( key == (*i)->hash ) { + const IOV* _iov = (*i)->iov; + unsigned int typ = _iov->iovType ? _iov->iovType->type : _iov->type; + if ( req_typ == typ ) { + if ( IOV::key_is_contained(_iov->key(),req_key) ) + // IOV test contained in key. Take it! + result.push_back(*i); + else if ( IOV::key_overlaps_lower_end(_iov->key(),req_key) ) + // IOV overlap on test on the lower end of key + result.push_back(*i); + else if ( IOV::key_overlaps_higher_end(_iov->key(),req_key) ) + // IOV overlap of test on the higher end of key + result.push_back(*i); + } + } + } + } + } + }; @@ -295,6 +197,15 @@ ConditionsLinearPool<MAPPING,BASE>::~ConditionsLinearPool() { InstanceCount::decrement(this); } +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + #include "DD4hep/Factories.h" namespace { ConditionsManager _mgr(int argc, char** argv) { @@ -305,21 +216,23 @@ namespace { DD4hep::except("ConditionsLinearPool","++ Insufficient arguments: arg[0] = ConditionManager!"); return ConditionsManager(0); } - void* create_vector_pool(DD4hep::Geometry::LCDD&, int argc, char** argv) - { return new ConditionsLinearPool<std::vector<Condition::Object*> , ConditionsPool>(_mgr(argc,argv)); } - void* create_list_pool(DD4hep::Geometry::LCDD&, int argc, char** argv) - { return new ConditionsLinearPool<std::list<Condition::Object*> , ConditionsPool>(_mgr(argc,argv)); } - void* create_user_pool(DD4hep::Geometry::LCDD&, int argc, char** argv) { - UserPool* pool = new ConditionsLinearUserPool<std::vector<Condition::Object*> >(_mgr(argc,argv)); - return pool; - } - void* create_update_pool(DD4hep::Geometry::LCDD&, int argc, char** argv) { - UpdatePool* pool = new ConditionsLinearUpdatePool<std::vector<Condition::Object*> >(_mgr(argc,argv)); - return pool; - } + +#define _CR(fun,x,b,y) void* fun(DD4hep::Geometry::LCDD&, int argc, char** argv) \ + { return new b<x<Condition::Object*>,y>(_mgr(argc,argv)); } + /// Create a conditions pool based on STL vectors + _CR(create_vector_pool,std::vector,ConditionsLinearPool,ConditionsPool) + /// Create a conditions pool based on STL lists + _CR(create_list_pool,std::list,ConditionsLinearPool,ConditionsPool) + /// Create a conditions update pool based on STL vectors + _CR(create_vector_update_pool,std::vector,ConditionsLinearUpdatePool,UpdatePool) + /// Create a conditions update pool based on STL list + _CR(create_list_update_pool,std::list,ConditionsLinearUpdatePool,UpdatePool) } + DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearPool, create_vector_pool) -DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearListPool, create_list_pool) DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearVectorPool, create_vector_pool) -DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearUserPool, create_user_pool) -DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearUpdatePool, create_update_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearUpdatePool, create_vector_update_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearVectorUpdatePool,create_vector_update_pool) + +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearListPool, create_list_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearListUpdatePool, create_list_update_pool) diff --git a/DDCond/src/plugins/ConditionsManagerInstaller.cpp b/DDCond/src/plugins/ConditionsManagerInstaller.cpp deleted file mode 100644 index 5463d660bfa4126b80480a25dad6466f5490fa2b..0000000000000000000000000000000000000000 --- a/DDCond/src/plugins/ConditionsManagerInstaller.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// $Id$ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DD4hep/LCDD.h" -#include "DD4hep/Plugins.h" -#include "DD4hep/Printout.h" -#include "DD4hep/Factories.h" -#include "DDCond/ConditionsManager.h" -#include "DDCond/ConditionsInterna.h" - -namespace { - using namespace DD4hep; - using namespace DD4hep::Conditions; - - int install_cond_mgr (Geometry::LCDD& lcdd, int /* argc */, char** /* argv */) { - typedef Interna::ConditionsManagerObject ConditionsManagerObject; - Handle<ConditionsManagerObject> mgr(lcdd.extension<ConditionsManagerObject>(false)); - if ( !mgr.isValid() ) { - ConditionsManager mgr_handle(lcdd); - lcdd.addExtension<ConditionsManagerObject>(mgr_handle.ptr()); - printout(INFO,"ConditionsManager","+++ Successfully installed conditions manager instance."); - } - return 1; - } -} - -DECLARE_APPLY(DD4hepConditionsManagerInstaller,install_cond_mgr) diff --git a/DDCond/src/plugins/ConditionsMappedPool.cpp b/DDCond/src/plugins/ConditionsMappedPool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4564fee595856196ae4fe3cb106cf06fb71f796a --- /dev/null +++ b/DDCond/src/plugins/ConditionsMappedPool.cpp @@ -0,0 +1,231 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSMAPPEDPOOL_H +#define DDCOND_CONDITIONSMAPPEDPOOL_H + +// Framework include files +#include "DD4hep/objects/ConditionsInterna.h" +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsSelectors.h" + +// C/C++ include files +#include <map> +#include <unordered_map> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Class implementing the conditions collection for a given IOV type + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + template<typename MAPPING, typename BASE> + class ConditionsMappedPool : public BASE { + protected: + typedef BASE Base; + typedef MAPPING Mapping; + typedef typename BASE::key_type key_type; + Mapping m_entries; + public: + /// Default constructor + ConditionsMappedPool(ConditionsManager mgr); + + /// Default destructor + virtual ~ConditionsMappedPool(); + + /// Total entry count + virtual size_t count() const { + return m_entries.size(); + } + + /// Register a new condition to this pool + virtual void insert(Condition condition) { + Condition::Object* c = condition.access(); + m_entries.insert(std::make_pair(c->hash,c)); + } + + /// Register a new condition to this pool. May overload for performance reasons. + virtual void insert(RangeConditions& new_entries) { + for(RangeConditions::iterator i=new_entries.begin(); i!=new_entries.end(); ++i) { + Condition::Object* c = (*i).access(); + m_entries.insert(std::make_pair(c->hash,c)); + } + } + + /// Full cleanup of all managed conditions. + virtual void clear() { + for_each(m_entries.begin(), m_entries.end(), ConditionsPoolRemove(*this)); + m_entries.clear(); + } + + /// Check if a condition exists in the pool + virtual Condition exists(Condition::key_type key) const { + typename Mapping::const_iterator i= + find_if(m_entries.begin(), m_entries.end(), HashConditionFind(key)); + return i==m_entries.end() ? Condition() : (*i).second; + } + /// Select the conditions matching the DetElement and the conditions name + virtual void select(Condition::key_type key, RangeConditions& result) + { for_each(m_entries.begin(),m_entries.end(),keyedSelect(key,result)); } + + /// Select the conditons, used also by the DetElement of the condition + virtual void select_used(RangeConditions& result) + { for_each(m_entries.begin(),m_entries.end(),activeSelect(result)); } + + /// Select the conditons, used also by the DetElement of the condition + virtual void select_all(RangeConditions& result) + { for_each(m_entries.begin(),m_entries.end(),collectionSelect(result)); } + + /// Select the conditons, used also by the DetElement of the condition + virtual void select_all(ConditionsPool& selection_pool) + { for_each(m_entries.begin(),m_entries.end(),ConditionsPoolInsert(selection_pool)); } + }; + + /// Class implementing the conditions update pool for a given IOV type + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + template<typename MAPPING, typename BASE> class ConditionsMappedUpdatePool + : public ConditionsMappedPool<MAPPING,BASE> + { + typedef typename ConditionsMappedPool<MAPPING,BASE>::key_type key_type; + public: + /// Default constructor + ConditionsMappedUpdatePool(ConditionsManager mgr) + : ConditionsMappedPool<MAPPING,BASE>(mgr) + { + } + + /// Default destructor + virtual ~ConditionsMappedUpdatePool() {} + + /// Adopt all entries sorted by IOV. Entries will be removed from the pool + virtual void popEntries(UpdatePool::UpdateEntries& entries) { + MAPPING& m = this->ConditionsMappedPool<MAPPING,BASE>::m_entries; + if ( !m.empty() ) { + for(typename MAPPING::iterator i=m.begin(); i!=m.end(); ++i) { + Condition::Object* o = (*i).second; + entries[o->iov].push_back(Condition(o)); + } + m.clear(); + } + } + + /// Select the conditions matching the DetElement and the conditions name + virtual void select_range(Condition::key_type key, + const Condition::iov_type& req, + RangeConditions& result) + { + MAPPING& m = this->ConditionsMappedPool<MAPPING,BASE>::m_entries; + if ( !m.empty() ) { + unsigned int req_typ = req.iovType ? req.iovType->type : req.type; + const IOV::Key& req_key = req.key(); + for(typename MAPPING::const_iterator i=m.begin(); i != m.end(); ++i) { + Condition::Object* o = (*i).second; + if ( key == o->hash ) { + const IOV* _iov = o->iov; + unsigned int typ = _iov->iovType ? _iov->iovType->type : _iov->type; + if ( req_typ == typ ) { + if ( IOV::key_is_contained(_iov->key(),req_key) ) + // IOV test contained in key. Take it! + result.push_back(o); + else if ( IOV::key_overlaps_lower_end(_iov->key(),req_key) ) + // IOV overlap on test on the lower end of key + result.push_back(o); + else if ( IOV::key_overlaps_higher_end(_iov->key(),req_key) ) + // IOV overlap of test on the higher end of key + result.push_back(o); + } + } + } + } + } + }; + + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif // DDCOND_CONDITIONSMAPPEDPOOL_H + +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +//#include "DDCond/ConditionsMappedPool.h" +#include "DD4hep/Printout.h" +#include "DD4hep/InstanceCount.h" + +using namespace DD4hep::Conditions; + +/// Default constructor +template<typename MAPPING, typename BASE> +ConditionsMappedPool<MAPPING,BASE>::ConditionsMappedPool(ConditionsManager mgr) : BASE(mgr) { + InstanceCount::increment(this); +} + +/// Default destructor +template<typename MAPPING, typename BASE> +ConditionsMappedPool<MAPPING,BASE>::~ConditionsMappedPool() { + clear(); + InstanceCount::decrement(this); +} + +#include "DD4hep/Factories.h" +namespace { + typedef Condition::key_type key_type; + ConditionsManager _mgr(int argc, char** argv) { + if ( argc > 0 ) { + ConditionsManager::Object* m = (ConditionsManager::Object*)argv[0]; + return m; + } + DD4hep::except("ConditionsMappedPool","++ Insufficient arguments: arg[0] = ConditionManager!"); + return ConditionsManager(0); + } +#define _CR(fun,x,b,y) void* fun(DD4hep::Geometry::LCDD&, int argc, char** argv) \ + { return new b<x<key_type,Condition::Object*>,y>(_mgr(argc,argv)); } + + /// Create a conditions pool based on STL maps + _CR(create_map_pool,std::map,ConditionsMappedPool,ConditionsPool) + /// Create a conditions pool based on STL hash-maps (unordered_map) + _CR(create_unordered_map_pool,std::unordered_map,ConditionsMappedPool,ConditionsPool) + /// Create a conditions update pool based on STL maps + _CR(create_map_update_pool,std::map,ConditionsMappedUpdatePool,UpdatePool) + /// Create a conditions update pool based on STL hash-maps (unordered_map) + _CR(create_unordered_map_update_pool,std::unordered_map,ConditionsMappedUpdatePool,UpdatePool) +} +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsMappedPool, create_map_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsHashedPool, create_unordered_map_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsMappedUpdatePool, create_map_update_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsHashedUpdatePool, create_unordered_map_update_pool) diff --git a/DDCond/src/plugins/ConditionsMultiLoader.cpp b/DDCond/src/plugins/ConditionsMultiLoader.cpp index 9931ea7c8800cf444790d785a815550d5c24f5ea..9dd9b4b4d3f207facdc553514eab543598bd9989 100644 --- a/DDCond/src/plugins/ConditionsMultiLoader.cpp +++ b/DDCond/src/plugins/ConditionsMultiLoader.cpp @@ -39,6 +39,7 @@ namespace DD4hep { Loaders m_loaders; OpenSources m_openSources; + ConditionsDataLoader* load_source(const std::string& nam,const iov_type& req_validity); public: /// Default constructor @@ -46,20 +47,17 @@ namespace DD4hep { /// Default destructor virtual ~ConditionsMultiLoader(); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load(DetElement det, - const std::string& cond, - const IOV& req_validity, + virtual size_t load(key_type key, + const iov_type& req_validity, RangeConditions& conditions); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load_range(DetElement det, - const std::string& cond, - const IOV& req_validity, + virtual size_t load_range(key_type key, + const iov_type& req_validity, RangeConditions& conditions); /// Update a range of conditions according to the required IOV - virtual size_t update(const IOV& req_validity, + virtual size_t update(const iov_type& req_validity, RangeConditions& conditions, - IOV& conditions_validity); - ConditionsDataLoader* load_source(const std::string& nam,const IOV& req_validity); + iov_type& conditions_validity); }; } /* End namespace Geometry */ } /* End namespace DD4hep */ @@ -79,7 +77,7 @@ using namespace DD4hep::Conditions; namespace { void* create_loader(DD4hep::Geometry::LCDD& lcdd, int argc, char** argv) { const char* name = argc>0 ? argv[0] : "MULTILoader"; - Interna::ConditionsManagerObject* mgr = (Interna::ConditionsManagerObject*)(argc>0 ? argv[1] : 0); + ConditionsManagerObject* mgr = (ConditionsManagerObject*)(argc>0 ? argv[1] : 0); return new ConditionsMultiLoader(lcdd,ConditionsManager(mgr),name); } } @@ -95,7 +93,9 @@ ConditionsMultiLoader::ConditionsMultiLoader(LCDD& lcdd, ConditionsManager mgr, ConditionsMultiLoader::~ConditionsMultiLoader() { } -ConditionsDataLoader* ConditionsMultiLoader::load_source(const std::string& nam,const IOV& req_validity) +ConditionsDataLoader* +ConditionsMultiLoader::load_source(const std::string& nam, + const iov_type& req_validity) { OpenSources::iterator iop = m_openSources.find(nam); if ( iop == m_openSources.end() ) { @@ -128,10 +128,10 @@ ConditionsDataLoader* ConditionsMultiLoader::load_source(const std::string& nam, } /// Load a condition set given a Detector Element and the conditions name according to their validity -size_t ConditionsMultiLoader::load_range(DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions) { +size_t ConditionsMultiLoader::load_range(key_type key, + const iov_type& req_validity, + RangeConditions& conditions) +{ size_t len = conditions.size(); // No better idea: Must chack all sources to find the required condition for(Sources::const_iterator i=m_sources.begin(); i != m_sources.end(); ++i) { @@ -140,7 +140,7 @@ size_t ConditionsMultiLoader::load_range(DetElement det, if ( IOV::key_partially_contained(iov.keyData,req_validity.keyData) ) { const string& nam = (*i).first; ConditionsDataLoader* loader = load_source(nam, req_validity); - loader->load(det, cond, req_validity, conditions); + loader->load(key, req_validity, conditions); } } } @@ -148,10 +148,10 @@ size_t ConditionsMultiLoader::load_range(DetElement det, } -size_t ConditionsMultiLoader::load(DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions) { +size_t ConditionsMultiLoader::load(key_type key, + const iov_type& req_validity, + RangeConditions& conditions) +{ size_t len = conditions.size(); // No better idea: Must chack all sources to find the required condition for(Sources::const_iterator i=m_sources.begin(); i != m_sources.end(); ++i) { @@ -160,7 +160,7 @@ size_t ConditionsMultiLoader::load(DetElement det, if ( IOV::key_partially_contained(iov.keyData,req_validity.keyData) ) { const string& nam = (*i).first; ConditionsDataLoader* loader = load_source(nam, req_validity); - loader->load(det, cond, req_validity, conditions); + loader->load(key, req_validity, conditions); } } } @@ -168,23 +168,23 @@ size_t ConditionsMultiLoader::load(DetElement det, } /// Update a range of conditions according to the required IOV -size_t ConditionsMultiLoader::update(const IOV& req_iov, - RangeConditions& updates, - IOV& conditions_validity) { +size_t ConditionsMultiLoader::update(const iov_type& req_validity, + RangeConditions& conditions, + iov_type& conditions_validity) +{ RangeConditions upda; - for(RangeConditions::const_iterator i=updates.begin(); i!=updates.end(); ++i) { + for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { Condition::Object* cond = (*i).ptr(); - size_t items = load(cond->detector,cond->name,req_iov,upda); + size_t items = load(cond->hash,req_validity,upda); if ( items < 1 ) { // Error: no such condition except("ConditionsManager", - "+++ update_expired: Cannot update condition %s.%s [%s] to iov:%s.", - cond->detector.path().c_str(), cond->name.c_str(), - cond->iov->str().c_str(), req_iov.str().c_str()); + "+++ update_expired: Cannot update condition %s [%s] to iov:%s.", + cond->name.c_str(), cond->iov->str().c_str(), req_validity.str().c_str()); } } - updates = upda; - for(RangeConditions::const_iterator i=updates.begin(); i!=updates.end(); ++i) + conditions = upda; + for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) conditions_validity.iov_intersection((*i).iov()); - return updates.size(); + return conditions.size(); } diff --git a/DDCond/src/plugins/ConditionsPlugins.cpp b/DDCond/src/plugins/ConditionsPlugins.cpp index f18aab69c68cdd961168d4c045c2db69423697ed..b0f146833c7e4474b4301833ea6d1373f2d26840 100644 --- a/DDCond/src/plugins/ConditionsPlugins.cpp +++ b/DDCond/src/plugins/ConditionsPlugins.cpp @@ -32,12 +32,34 @@ using Geometry::Position; using Geometry::DetElement; namespace { + using namespace DD4hep; + using namespace DD4hep::Conditions; - int ddcond_dump_conditions_functor(lcdd_t& lcdd, bool print_conditions) { + int ddcond_install_cond_mgr (LCDD& lcdd, int /* argc */, char** /* argv */) { + Handle<ConditionsManagerObject> mgr(lcdd.extension<ConditionsManagerObject>(false)); + if ( !mgr.isValid() ) { + ConditionsManager mgr_handle(lcdd); + lcdd.addExtension<ConditionsManagerObject>(mgr_handle.ptr()); + printout(INFO,"ConditionsManager","+++ Successfully installed conditions manager instance."); + } + return 1; + } +} +DECLARE_APPLY(DD4hep_ConditionsManagerInstaller,ddcond_install_cond_mgr) +// ====================================================================================== + +namespace { + + int ddcond_dump_conditions_functor(lcdd_t& lcdd, bool print_conditions, int argc, char** argv) { typedef std::vector<const IOVType*> _T; - typedef ConditionsIOVPool::Entries _E; + typedef ConditionsIOVPool::Elements _E; typedef RangeConditions _R; ConditionsManager manager = ConditionsManager::from(lcdd); + Condition::Processor* printer = 0; + + if ( argc > 0 ) { + printer = (Condition::Processor*) argv[0]; + } const _T types = manager.iovTypesUsed(); for( _T::const_iterator i = types.begin(); i != types.end(); ++i ) { @@ -45,8 +67,8 @@ namespace { if ( type ) { ConditionsIOVPool* pool = manager.iovPool(*type); if ( pool ) { - const _E& e = pool->entries; - printout(INFO,"CondPoolDump","+++ ConditionsIOVPool for type %s [%d IOV entries]", + const _E& e = pool->elements; + printout(INFO,"CondPoolDump","+++ ConditionsIOVPool for type %s [%d IOV elements]", type->str().c_str(), int(e.size())); for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { ConditionsPool* cp = (*j).second; @@ -54,7 +76,10 @@ namespace { if ( print_conditions ) { _R rc; cp->select_all(rc); - //print_conditions<void>(rc); + for(_R::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) { + if ( printer ) { (*printer)(*ic); } + else { /* print_conditions<void>(rc); */ } + } } } } @@ -66,30 +91,31 @@ namespace { return 1; } - int ddcond_dump_pools(LCDD& lcdd, int /* argc */, char** /* argv */) { - return ddcond_dump_conditions_functor(lcdd,false); + int ddcond_dump_pools(LCDD& lcdd, int argc, char** argv) { + return ddcond_dump_conditions_functor(lcdd,false, argc, argv); } - int ddcond_dump_conditions(LCDD& lcdd, int /* argc */, char** /* argv */) { - return ddcond_dump_conditions_functor(lcdd,true); + int ddcond_dump_conditions(LCDD& lcdd, int argc, char** argv) { + return ddcond_dump_conditions_functor(lcdd,true, argc, argv); } } -DECLARE_APPLY(DD4hepDDCondPoolDump,ddcond_dump_pools) -DECLARE_APPLY(DD4hepDDCondConditionsDump,ddcond_dump_conditions) +DECLARE_APPLY(DD4hep_ConditionsPoolDump,ddcond_dump_pools) +DECLARE_APPLY(DD4hep_ConditionsDump,ddcond_dump_conditions) +// ====================================================================================== namespace { /// Plugin entry point. - static long synchronize_conditions(lcdd_t& lcdd, int argc, char** argv) { + static long ddcond_synchronize_conditions(lcdd_t& lcdd, int argc, char** argv) { if ( argc > 0 ) { string iov_type = argv[0]; IOV::Key::first_type iov_key = *(IOV::Key::first_type*)argv[1]; ConditionsManager manager = ConditionsManager::from(lcdd); const IOVType* epoch = manager.iovType(iov_type); - dd4hep_ptr<ConditionsPool> user_pool; + dd4hep_ptr<UserPool> user_pool; IOV iov(epoch); iov.set(iov_key); - long num_expired = manager.prepare(iov, user_pool); + long num_updated = manager.prepare(iov, user_pool); if ( iov_type == "epoch" ) { char c_evt[64]; struct tm evt; @@ -97,14 +123,13 @@ namespace { ::strftime(c_evt,sizeof(c_evt),"%T %F",&evt); printout(INFO,"Conditions", "+++ ConditionsUpdate: Updated %ld conditions... event time: %s", - num_expired, c_evt); + num_updated, c_evt); } else { printout(INFO,"Conditions", "+++ ConditionsUpdate: Updated %ld conditions... key[%s]: %ld", - num_expired, iov_type.c_str(), iov_key); + num_updated, iov_type.c_str(), iov_key); } - manager.enable(iov, user_pool); user_pool->print("User pool"); manager.clean(epoch, 20); user_pool->clear(); @@ -114,11 +139,12 @@ namespace { return 0; } } -DECLARE_APPLY(DD4hep_ConditionsSynchronize,synchronize_conditions) +DECLARE_APPLY(DD4hep_ConditionsSynchronize,ddcond_synchronize_conditions) +// ====================================================================================== namespace { /// Plugin entry point. - static long clean_conditions(lcdd_t& lcdd, int argc, char** argv) { + static long ddcond_clean_conditions(lcdd_t& lcdd, int argc, char** argv) { if ( argc > 0 ) { string iov_type = argv[0]; int max_age = *(int*)argv[1]; @@ -134,4 +160,6 @@ namespace { return 0; } } -DECLARE_APPLY(DD4hep_ConditionsClean,clean_conditions) +DECLARE_APPLY(DD4hep_ConditionsClean,ddcond_clean_conditions) +// ====================================================================================== + diff --git a/DDCond/src/plugins/ConditionsUpdate.cpp b/DDCond/src/plugins/ConditionsUpdate.cpp deleted file mode 100644 index 4937051bb7d469184155d32652b994c141f361ac..0000000000000000000000000000000000000000 --- a/DDCond/src/plugins/ConditionsUpdate.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// \author Markus Frank -// \date 2016-02-02 -// \version 1.0 -// -//========================================================================== -// $Id$ - diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8655aebffba8081a98366d65bb69fb154102adc7 --- /dev/null +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -0,0 +1,278 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSMAPPEDUSERPOOL_H +#define DDCOND_CONDITIONSMAPPEDUSERPOOL_H + +// Framework include files +#include "DDCond/ConditionsPool.h" + +// C/C++ include files +#include <map> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Class implementing the conditions user pool for a given IOV type + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + template<typename MAPPING> + class ConditionsMappedUserPool : public UserPool + { + typedef MAPPING Mapping; + Mapping m_conditions; + + Condition::Object* i_findCondition(key_type key) const; + + public: + /// Default constructor + ConditionsMappedUserPool(ConditionsManager mgr, ConditionsIOVPool* pool); + /// Default destructor + virtual ~ConditionsMappedUserPool(); + /// Print pool content + virtual void print(const std::string& opt) const; + /// Total entry count + virtual size_t count() const; + /// Full cleanup of all managed conditions. + virtual void clear(); + /// Check a condition for existence + virtual bool exists(key_type hash) const; + /// Check a condition for existence + virtual bool exists(const ConditionKey& key) const; + /// Check if a condition exists in the pool and return it to the caller + virtual Condition get(key_type hash) const; + /// Check if a condition exists in the pool and return it to the caller + virtual Condition get(const ConditionKey& key) const; + /// Remove condition by key from pool. + virtual bool remove(key_type hash_key); + /// Remove condition by key from pool. + virtual bool remove(const ConditionKey& key); + /// Register a new condition to this pool + virtual bool insert(Condition cond); + /// Prepare user pool for usage (load, fill etc.) according to required IOV + virtual long prepare(const IOV& required); + /// Evaluate and register all derived conditions from the dependency list + virtual long compute(const Dependencies& dependencies); + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif // DDCOND_CONDITIONSMAPPEDUSERPOOL_H + +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +//#include "DDCond/ConditionsMappedPool.h" +#include "DD4hep/Printout.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/objects/ConditionsInterna.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsSelectors.h" +#include "DDCond/ConditionsDependencyHandler.h" + +using namespace DD4hep::Conditions; +using namespace std; + +namespace { + template <typename T> struct Inserter { + T& m; + Inserter(T& o) : m(o) {} + void operator()(Condition& c) { + Condition::Object* o = c.ptr(); + m.insert(make_pair(o->hash,o)); + } + }; +} + +/// Default constructor +template<typename MAPPING> +ConditionsMappedUserPool<MAPPING>::ConditionsMappedUserPool(ConditionsManager mgr, ConditionsIOVPool* pool) + : UserPool(mgr, pool) +{ + InstanceCount::increment(this); +} + +/// Default destructor +template<typename MAPPING> +ConditionsMappedUserPool<MAPPING>::~ConditionsMappedUserPool() { + clear(); + InstanceCount::decrement(this); +} + +template<typename MAPPING> inline Condition::Object* +ConditionsMappedUserPool<MAPPING>::i_findCondition(key_type key) const { + typename MAPPING::const_iterator i=m_conditions.find(key); + return i != m_conditions.end() ? (*i).second : 0; +} + +/// Total entry count +template<typename MAPPING> +size_t ConditionsMappedUserPool<MAPPING>::count() const { + return m_conditions.size(); +} + +/// Print pool content +template<typename MAPPING> +void ConditionsMappedUserPool<MAPPING>::print(const std::string& opt) const { + const IOV* iov = &m_iov; + printout(INFO,"UserPool","+++ %s Conditions for USER pool with IOV: %-32s [%4d entries]", + opt.c_str(), iov->str().c_str(), count()); + if ( opt == "*" ) { + typename MAPPING::const_iterator i=m_conditions.begin(); + for( ; i != m_conditions.end(); ++i) { + Condition c = (*i).second; + printout(INFO,"UserPool","++ %08X/%08X Val:%s %s",(*i).first, c->hash, c->value.c_str(), c.str().c_str()); + } + } +} + +/// Full cleanup of all managed conditions. +template<typename MAPPING> +void ConditionsMappedUserPool<MAPPING>::clear() { + m_iov = IOV(0); + m_conditions.clear(); +} + +/// Check a condition for existence +template<typename MAPPING> +bool ConditionsMappedUserPool<MAPPING>::exists(key_type hash) const { + return i_findCondition(hash) != 0; +} + +/// Check a condition for existence +template<typename MAPPING> +bool ConditionsMappedUserPool<MAPPING>::exists(const ConditionKey& key) const { + return i_findCondition(key.hash) != 0; +} + +/// Check if a condition exists in the pool and return it to the caller +template<typename MAPPING> +Condition ConditionsMappedUserPool<MAPPING>::get(key_type hash) const { + return i_findCondition(hash); +} + +/// Check if a condition exists in the pool and return it to the caller +template<typename MAPPING> +Condition ConditionsMappedUserPool<MAPPING>::get(const ConditionKey& key) const { + return i_findCondition(key.hash); +} + +/// Register a new condition to this pool +template<typename MAPPING> +bool ConditionsMappedUserPool<MAPPING>::insert(Condition cond) { + Condition::Object* o = cond.ptr(); + pair<typename MAPPING::iterator,bool> res = m_conditions.insert(make_pair(o->hash,o)); + return res.second; +} + +/// Remove condition by key from pool. +template<typename MAPPING> +bool ConditionsMappedUserPool<MAPPING>::remove(const ConditionKey& key) { + return remove(key.hash); +} + +/// Remove condition by key from pool. +template<typename MAPPING> +bool ConditionsMappedUserPool<MAPPING>::remove(key_type hash_key) { + typename MAPPING::iterator i=m_conditions.find(hash_key); + if ( i != m_conditions.end() ) { + m_conditions.erase(i); + return true; + } + return false; +} + +/// Prepare user pool for usage (load, fill etc.) according to required IOV +template<typename MAPPING> +long ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required) { + if ( m_iovPool ) { + RangeConditions valid, expired; + IOV pool_iov(required.iovType); + pool_iov.reset().invert(); + m_iovPool->select(required, valid, expired, pool_iov); + clear(); + for_each(valid.begin(),valid.end(),Inserter<MAPPING>(m_conditions)); + long num_expired = (long)expired.size(); + if ( num_expired > 0 ) { + m_manager->loader()->update(required, expired, pool_iov); + for_each(expired.begin(),expired.end(),Inserter<MAPPING>(m_conditions)); + } + m_iov = pool_iov; + return num_expired; + } + DD4hep::except("ConditionsMappedUserPool","++ Invalid reference to iov pool! [Internal Error]"); + return -1; +} + +/// Evaluate and register all derived conditions from the dependency list +template<typename MAPPING> +long ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps) { + long num_updates = 0; + if ( !deps.empty() ) { + typedef Dependencies _D; + ConditionsDependencyHandler handler(m_manager.ptr(), *this, deps); + ConditionsPool* pool = m_manager->registerIOV(*m_iov.iovType, m_iov.keyData); + // Loop over the dependencies and check if they have to be upgraded + for(_D::const_iterator i = deps.begin(); i!=deps.end(); ++i) { + key_type key = (*i).first; + const ConditionDependency* d = (*i).second; + typename MAPPING::iterator j = m_conditions.find(key); + Condition::Object* cond = j==m_conditions.end() ? 0 : (*j).second; + if ( cond ) { + if ( IOV::key_is_contained(m_iov.keyData,cond->iov->keyData) ) + continue; + /// This condition is no longer valid. remove it! Will be added again afterwards. + m_conditions.erase(j); + } + cond = handler(d); + m_manager->registerUnlocked(pool, cond); + ++num_updates; + } + } + return num_updates; +} + +#include "DD4hep/Factories.h" +namespace { + void* create_user_pool(DD4hep::Geometry::LCDD&, int argc, char** argv) { + if ( argc > 1 ) { + ConditionsManager::Object* m = (ConditionsManager::Object*)argv[0]; + ConditionsIOVPool* p = (ConditionsIOVPool*)argv[1]; + UserPool* pool = new ConditionsMappedUserPool<std::map<Condition::key_type,Condition::Object*> >(m, p); + return pool; + } + DD4hep::except("ConditionsMappedUserPool","++ Insufficient arguments: arg[0] = ConditionManager!"); + return 0; + } +} +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsMapUserPool, create_user_pool) diff --git a/DDCond/src/plugins/ConditionsXmlLoader.cpp b/DDCond/src/plugins/ConditionsXmlLoader.cpp index 55ac34bb636bd3832db2a82aab2aa32eebbec3c4..394ce94f18c65b2d645ad5f2f5cef07d7d51de57 100644 --- a/DDCond/src/plugins/ConditionsXmlLoader.cpp +++ b/DDCond/src/plugins/ConditionsXmlLoader.cpp @@ -34,33 +34,30 @@ namespace DD4hep { typedef std::vector<Condition> Buffer; Buffer m_buffer; + size_t load_source (const std::string& nam, + key_type key, + const iov_type& req_validity, + RangeConditions& conditions); public: /// Default constructor ConditionsXmlLoader(LCDD& lcdd, ConditionsManager mgr, const std::string& nam); /// Default destructor virtual ~ConditionsXmlLoader(); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load(DetElement det, - const std::string& cond, - const IOV& req_validity, + virtual size_t load(key_type key, + const iov_type& req_validity, RangeConditions& conditions); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load_range(DetElement det, - const std::string& cond, - const IOV& req_validity, + virtual size_t load_range(key_type key, + const iov_type& req_validity, RangeConditions& conditions); - size_t load_source (const std::string& nam, - DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions); /// Update a range of conditions according to the required IOV - virtual size_t update(const IOV& req_validity, + virtual size_t update(const iov_type& req_validity, RangeConditions& conditions, - Conditions::IOV& iov_intersection); + iov_type& iov_intersection); }; - } /* End namespace Geometry */ + } /* End namespace Conditions */ } /* End namespace DD4hep */ #endif /* DD4HEP_CONDITIONS_XMLCONDITONSLOADER_H */ @@ -87,7 +84,7 @@ using namespace DD4hep::Conditions; namespace { void* create_loader(DD4hep::Geometry::LCDD& lcdd, int argc, char** argv) { const char* name = argc>0 ? argv[0] : "XMLLoader"; - Interna::ConditionsManagerObject* mgr = (Interna::ConditionsManagerObject*)(argc>0 ? argv[1] : 0); + ConditionsManagerObject* mgr = (ConditionsManagerObject*)(argc>0 ? argv[1] : 0); return new ConditionsXmlLoader(lcdd,ConditionsManager(mgr),name); } } @@ -104,10 +101,9 @@ ConditionsXmlLoader::~ConditionsXmlLoader() { } size_t ConditionsXmlLoader::load_source(const std::string& nam, - DetElement det, - const std::string& cond, - const IOV& req_validity, - RangeConditions& conditions) + key_type key, + const iov_type& req_validity, + RangeConditions& conditions) { size_t len = conditions.size(); string fac = "XMLConditionsParser"; @@ -122,7 +118,7 @@ size_t ConditionsXmlLoader::load_source(const std::string& nam, Condition condition = queueUpdate(e); delete e; if ( condition.isValid() ) { - if ( det == condition.detector() && cond == condition.name() ) { + if ( key == condition->hash ) { if ( req_validity.contains(condition.iov()) ) { conditions.push_back(condition); continue; @@ -137,49 +133,43 @@ size_t ConditionsXmlLoader::load_source(const std::string& nam, return conditions.size()-len; } -size_t ConditionsXmlLoader::load(DetElement det, - const std::string& cond, - const IOV& req_validity, +size_t ConditionsXmlLoader::load(key_type key, + const iov_type& req_validity, RangeConditions& conditions) { size_t len = conditions.size(); if ( m_buffer.empty() && !m_sources.empty() ) { - return load_source(m_sources.begin()->first, det, cond, req_validity, conditions); + return load_source(m_sources.begin()->first, key, req_validity, conditions); } for (Buffer::iterator j=m_buffer.begin(); j!=m_buffer.end(); ++j) { Condition condition = *j; - if ( det == condition->detector ) { - const IOV* iov = condition->iov; - if ( IOV::partial_match(req_validity,*iov) ) { - if ( cond == condition->name ) { - conditions.push_back(condition); - m_buffer.erase(j); - return conditions.size()-len; - } + const IOV* iov = condition->iov; + if ( IOV::partial_match(req_validity,*iov) ) { + if ( key == condition->hash ) { + conditions.push_back(condition); + m_buffer.erase(j); + return conditions.size()-len; } } } return conditions.size()-len; } -size_t ConditionsXmlLoader::load_range(DetElement det, - const std::string& cond, - const IOV& req_validity, +size_t ConditionsXmlLoader::load_range(key_type key, + const iov_type& req_validity, RangeConditions& conditions) { size_t len = conditions.size(); while ( !m_sources.empty() ) { - load_source(m_sources.begin()->first, det, cond, req_validity, conditions); + load_source(m_sources.begin()->first, key, req_validity, conditions); } std::vector<Condition> keep; for (Buffer::iterator j=m_buffer.begin(); j!=m_buffer.end(); ++j) { Condition condition = *j; - if ( det == condition->detector ) { - const IOV* iov = condition->iov; - if ( IOV::partial_match(req_validity,*iov) ) { - if ( cond == condition->name ) { - conditions.push_back(condition); - } + const IOV* iov = condition->iov; + if ( IOV::partial_match(req_validity,*iov) ) { + if ( key == condition->hash ) { + conditions.push_back(condition); } } keep.push_back(condition); diff --git a/DDCore/include/DD4hep/BasicGrammar.h b/DDCore/include/DD4hep/BasicGrammar.h index 6a999a57d0c0251adb8941dcabdfc2291999201f..20bec995c4f35ea11b75d4d4c8da8eeb5cd5e90c 100644 --- a/DDCore/include/DD4hep/BasicGrammar.h +++ b/DDCore/include/DD4hep/BasicGrammar.h @@ -50,6 +50,8 @@ namespace DD4hep { static void invalidConversion(const std::string& value, const std::type_info& to); /// Access to the type information virtual const std::type_info& type() const = 0; + /// Access to the type information name + virtual const std::string& type_name() const = 0; /// Access the object size (sizeof operator) virtual size_t sizeOf() const = 0; /// Serialize an opaque value to a string diff --git a/DDCore/include/DD4hep/Callback.h b/DDCore/include/DD4hep/Callback.h index 7b0bdc411d2a8f24dfbdd1905e6d8591a7b886d6..eba5ad3db5ca88d3d46f82f5660698b892740162 100644 --- a/DDCore/include/DD4hep/Callback.h +++ b/DDCore/include/DD4hep/Callback.h @@ -270,8 +270,7 @@ namespace DD4hep { return _make(_Wrapper::call, pmf); } /// Callback setup function for Callbacks with const member functions with explicit return type taking 3 arguments - template <typename R, typename T, typename A0, typename A1, typename A2> const Callback& make( - R (T::*pmf)(A0, A1, A2) const) { + template <typename R, typename T, typename A0, typename A1, typename A2> const Callback& make(R (T::*pmf)(A0, A1, A2) const) { typedef R (T::*pfunc_t)(A0, A1, A2); typedef Wrapper<pfunc_t> _W; struct _Wrapper : public _W { diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h new file mode 100644 index 0000000000000000000000000000000000000000..95b05fa484e1a229eabf381988a850425c618ece --- /dev/null +++ b/DDCore/include/DD4hep/ConditionDerived.h @@ -0,0 +1,206 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_GEOMETRY_CONDITIONDERIVED_H +#define DD4HEP_GEOMETRY_CONDITIONDERIVED_H + +// Framework include files +#include "DD4hep/Memory.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/objects/ConditionsInterna.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Grammar definition for type binding + class BasicGrammar; + + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + + class ConditionManager; + class ConditionResolver; + class ConditionDependency; + class ConditionUpdateCall; + + /// + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionResolver { + public: + /// Standard destructor + virtual ~ConditionResolver(); + /// Interface to access conditions by conditions key + virtual Condition get(const ConditionKey& key) const = 0; + /// Interface to access conditions by hash value + virtual Condition get(unsigned int key) const = 0; + /// Access to the conditions manager + virtual Ref_t manager() const = 0; + /// Access to the detector description instance + virtual Geometry::LCDD& lcdd() const = 0; + /// Required IOV value for update cycle + virtual const IOV& requiredValidity() const = 0; + }; + + /// Callback interface + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionUpdateCall { + public: + struct Context { + const ConditionResolver& resolver; + const ConditionDependency& dependency; + Condition::iov_type* iov; + + /// Initializing constructor + Context(const ConditionResolver& r, const ConditionDependency& d, Condition::iov_type& iov); + /// Access to dependency keys + const ConditionKey& key(size_t which) const; + /// Access to condition object by dependency index + Condition condition(size_t which) const; + /// Access to condition object by dependency key + Condition condition(const ConditionKey& key_value) const; + /// Access of other conditions data from the resolver + template<typename T> T& get(const ConditionKey& key_value) { + Condition cond = resolver.get(key_value); + if ( cond.isValid() ) { + T& data = cond.get<T>(); /// Bind data to wanted type + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(cond.iov()); + return data; + } + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name); + } + /// Access of other conditions data from the resolver + template<typename T> const T& get(const ConditionKey& key_value) const { + Condition cond = resolver.get(key_value); + if ( cond.isValid() ) { + const T& data = cond.get<T>(); /// Bind data to wanted type + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(cond.iov()); + return data; + } + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name); + } + /// Access of other conditions data from the resolver + template<typename T> T& get(size_t key_id) { + const ConditionKey& key_value = this->key(key_id); + return this->get<T>(key_value); + } + /// Access of other conditions data from the resolver + template<typename T> const T& get(size_t key_id) const { + const ConditionKey& key_value = this->key(key_id); + return this->get<T>(key_value); + } + }; + /// Standard destructor + virtual ~ConditionUpdateCall(); + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& target, const Context& ctxt) = 0; + }; + + /// Condition dependency definition + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionDependency { + protected: + /// Copy constructor + ConditionDependency(const ConditionDependency& c); + /// Assignment operator + ConditionDependency& operator=(const ConditionDependency& c); + + public: + typedef Geometry::DetElement DetElement; + /// Defintion of the depencency container + typedef std::vector<ConditionKey> Dependencies; + DetElement detector; + /// Key to the condition to be updated + ConditionKey target; + /// Dependency keys this condition depends on + Dependencies dependencies; + /// Reference to the update callback + dd4hep_ptr<ConditionUpdateCall> callback; + + /// Initializing constructor + ConditionDependency(const ConditionKey& tar, const Dependencies deps, ConditionUpdateCall* call); + /// Initializing constructor used by builder + ConditionDependency(const ConditionKey& tar, ConditionUpdateCall* call); + /// Default constructor + ConditionDependency(); + /// Default destructor + virtual ~ConditionDependency(); + }; + + /// Condition dependency builder + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class DependencyBuilder { + public: + /// The created dependency + dd4hep_ptr<ConditionDependency> dependency; + public: + /// Initializing constructor + DependencyBuilder(const ConditionKey& target, ConditionUpdateCall* call); + /// Default destructor + virtual ~DependencyBuilder(); + /// Access underlying object directly + ConditionDependency* operator->() { return dependency.get(); } + /// Add a new dependency + void add(const ConditionKey& source); + /// Release the created dependency and take ownership. + ConditionDependency* release(); + }; + + /// Initializing constructor + inline ConditionUpdateCall::Context::Context(const ConditionResolver& resolv, + const ConditionDependency& dep, + Condition::iov_type& iov_ref) + : resolver(resolv), dependency(dep), iov(&iov_ref) + { + } + + /// Access to dependency keys + inline const ConditionKey& ConditionUpdateCall::Context::key(size_t which) const { + return dependency.dependencies[which]; + } + + /// Access to condition object by dependency key + inline Condition ConditionUpdateCall::Context::condition(const ConditionKey& key_value) const { + Condition c = resolver.get(key_value); + if ( c.isValid() ) return c; + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition:"+key_value.name); + } + + /// Access to condition object by dependency index + inline Condition ConditionUpdateCall::Context::condition(size_t which) const { + const ConditionKey& key_value = this->key(which); + return this->condition(key_value); + } + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_GEOMETRY_CONDITIONDERIVED_H */ diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 93b04fb27ac06fd2d0418a8e23f20c59d60d764c..7ee5e617c5714852a612203ad599ae23ae366c5c 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -41,8 +41,10 @@ namespace DD4hep { using Geometry::LCDD; // Forward declarations + class ConditionsManagerObject; class ConditionsManager; class ConditionsLoader; + class UserPool; class IOVType; class IOV; @@ -114,9 +116,9 @@ namespace DD4hep { /// Set range IOV value void set(Key_first_type val_1, Key_second_type val_2); /// Set keys to unphysical values (LONG_MAX, LONG_MIN) - void reset(); + IOV& reset(); /// Invert the key values (first=second and second=first) - void invert(); + IOV& invert(); /// Set the intersection of this IOV with the argument IOV void iov_intersection(const IOV& comparator); /// Set the intersection of this IOV with the argument IOV @@ -186,9 +188,10 @@ namespace DD4hep { /// Standard Destructor virtual ~Block(); - protected: + public: /// Data type const BasicGrammar* grammar; + protected: /// Pointer to object data void* pointer; @@ -199,6 +202,8 @@ namespace DD4hep { std::string str() const; /// Access type id of the condition const std::type_info& typeInfo() const; + /// Access type name of the condition data block + const std::string& dataType() const; /// Check if object is already bound.... bool is_bound() const { return 0 != pointer; } /// Generic getter. Specify the exact type, not a polymorph type @@ -207,11 +212,103 @@ namespace DD4hep { template <typename T> inline const T& get() const; }; + /// Kaykey definition to optimize the access to conditions entities + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionKey { + public: + typedef unsigned int key_type; + /// String representation of the key object + std::string name; + /// Hashed key representation + key_type hash; + + public: + /// Default constructor + ConditionKey() : hash(0) {} + /// Constructor from string + ConditionKey(const std::string& compare); + /// Constructor from string + ConditionKey(const std::string& s, key_type h) : name(s), hash(h) {} + /// Copy constructor + ConditionKey(const ConditionKey& c) : name(c.name), hash(c.hash) {} + + /// Hash code generation from input string + static key_type hashCode(const char* value); + /// Hash code generation from input string + static key_type hashCode(const std::string& value); + + /// Assignment operator from the string representation + ConditionKey& operator=(const std::string& value); + /// Assignment operator from object copy + ConditionKey& operator=(const ConditionKey& key); + /// Equality operator using key object + bool operator==(const ConditionKey& compare) const; + /// Equality operator using hash value + bool operator==(const key_type compare) const; + /// Equality operator using the string representation + bool operator==(const std::string& compare) const; + + /// Operator less (for map insertions) using key object + bool operator<(const ConditionKey& compare) const; + /// Operator less (for map insertions) using hash value + bool operator<(const key_type compare) const; + /// Operator less (for map insertions) using the string representation + bool operator<(const std::string& compare) const; + + /// Automatic conversion to the string representation of the key object + operator const std::string& () const { return name; } + /// Automatic conversion to the hashed representation of the key object + operator key_type () const { return hash; } + }; + + /// Hash code generation from input string + inline ConditionKey::key_type ConditionKey::hashCode(const char* value) + { return hash32(value); } + + /// Hash code generation from input string + inline ConditionKey::key_type ConditionKey::hashCode(const std::string& value) + { return hash32(value); } + + /// Assignment operator from object copy + inline ConditionKey& ConditionKey::operator=(const ConditionKey& key) { + if ( this != &key ) { + hash = key.hash; + name = key.name; + } + return *this; + } + + /// Equality operator using key object + inline bool ConditionKey::operator==(const ConditionKey& compare) const + { return hash == compare.hash; } + + /// Equality operator using hash value + inline bool ConditionKey::operator==(const key_type compare) const + { return hash == compare; } + + /// Operator less (for map insertions) using key object + inline bool ConditionKey::operator<(const ConditionKey& compare) const + { return hash < compare.hash; } + + /// Operator less (for map insertions) using hash value + inline bool ConditionKey::operator<(const key_type compare) const + { return hash < compare; } + + /// Main condition object handle. /** * This objects allows access to the data block and * the interval of validity for a single condition. * + * Note: + * Conditions may be shared between several DetElement objects. + * Hence, the back-link to the DetElemetn structure cannot be + * set - it would be ambiguous. + * * \author M.Frank * \version 1.0 * \ingroup DD4HEP_CONDITIONS @@ -219,8 +316,37 @@ namespace DD4hep { class Condition: public Handle<Interna::ConditionObject> { public: typedef Interna::ConditionObject Object; - + typedef ConditionKey::key_type key_type; + typedef IOV iov_type; public: + enum StringFlags { + WITH_IOV = 1<<0, + WITH_ADDRESS = 1<<1, + WITH_TYPE = 1<<2, + WITH_COMMENT = 1<<4, + WITH_DATATYPE = 1<<5, + WITH_DATA = 1<<6, + NO_NAME = 1<<20, + NONE + }; + enum ConditionState { + INACTIVE = 0, + ACTIVE = 1<<0, + CHECKED = 1<<2, + DERIVED = 1<<3 + }; + + /// Abstract base for processing callbacks + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class Processor { + public: + virtual int operator()(Condition c) = 0; + }; + /// Default constructor Condition(); /// Copy constructor @@ -236,6 +362,9 @@ namespace DD4hep { /// Assignment operator Condition& operator=(const Condition& c); + /// Output method + std::string str(int with_data=WITH_IOV|WITH_ADDRESS|WITH_DATATYPE) const; + /** Data block (bound type) */ /// Access the data type int dataType() const; @@ -246,7 +375,7 @@ namespace DD4hep { /// Access the IOV type const IOVType& iovType() const; /// Access the IOV block - const IOV& iov() const; + const iov_type& iov() const; /** Direct data items in string form */ /// Access the name of the condition @@ -255,14 +384,12 @@ namespace DD4hep { const std::string& type() const; /// Access the comment field of the condition const std::string& comment() const; - /// Access the validity field of the condition as a string - const std::string& validity() const; /// Access the value field of the condition as a string const std::string& value() const; /// Access the address string [e.g. database identifier] const std::string& address() const; - /// Access the hosting detector element - Geometry::DetElement detector() const; + /// Access the key of the condition + ConditionKey key() const; /** Conditions meta-data */ /// Access to the type information @@ -298,6 +425,7 @@ namespace DD4hep { inline Condition::Condition() : Handle<Condition::Object>() { } + /// Container class for condition handles aggregated by a detector element /** * Note: The conditions container is owner by the detector element @@ -312,28 +440,33 @@ namespace DD4hep { public: /// Standard object type typedef Interna::ConditionContainer Object; - /// Definition of the conditions container of this detector element - //typedef std::map<std::string, Condition> Entries; - typedef std::map<int, Condition> Entries; + typedef Condition::key_type key_type; + typedef Condition::iov_type iov_type; public: /// Default constructor Container(); + /// Constructor to be used when reading the already parsed object template <typename Q> Container(const Container& c) : Handle<Object>(c) {} + /// Constructor to be used when reading the already parsed object template <typename Q> Container(const Handle<Q>& e) : Handle<Object>(e) {} - /// Access the number of conditons available for this detector element - size_t count() const; - /// Access the full map of conditons - Entries& entries() const; - /// Clear all attached DetElement conditions. - void removeElements() const; - /// Access to condition objects. No loading undertaken. The condition must be present - Condition operator[](const std::string& key); + + /// Access the number of conditons keys available for this detector element + size_t numKeys() const; + + /// Access to condition objects by key and IOV. + Condition get(const std::string& condition_key, const iov_type& iov); + /// Access to condition objects directly by their hash key. - /// No loading undertaken. The condition must be present - Condition operator[](int hash_key); + Condition get(key_type condition_key, const iov_type& iov); + + /// Access to condition objects. Only conditions in the pool are accessed. + Condition get(const std::string& condition_key, const UserPool& iov); + + /// Access to condition objects. Only conditions in the pool are accessed. + Condition get(key_type condition_key, const UserPool& iov); }; /// Default constructor diff --git a/DDCore/include/DD4hep/ConditionsData.h b/DDCore/include/DD4hep/ConditionsData.h new file mode 100644 index 0000000000000000000000000000000000000000..b06a0a688c10b5fc60153a6ad63c162797f71f9d --- /dev/null +++ b/DDCore/include/DD4hep/ConditionsData.h @@ -0,0 +1,139 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSDATA_H +#define DD4HEP_CONDITIONS_CONDITIONSDATA_H + +// Framework include files +#include "DD4hep/Objects.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/objects/ConditionsInterna.h" + +// C/C++ include files +#include <vector> +#include <stdexcept> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + + /// Client data addition + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + struct ClientData { + virtual ~ClientData(); + virtual void release() = 0; + }; + + /// Class describing an condition to re-adjust an alignment + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentDelta { + public: + typedef Geometry::Position Position; + typedef Geometry::Position Pivot; + typedef Geometry::RotationZYX Rotation; + Pivot pivot; + Position position; + Rotation rotation; + /// Default constructor + AlignmentDelta(); + /// Copy constructor + AlignmentDelta(const AlignmentDelta& c); + /// Default destructor + ~AlignmentDelta(); + /// Assignment operator + AlignmentDelta& operator=(const AlignmentDelta& c); + }; + + /// Conditions data block. Internally maps other objects to abstract data blocks + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class AbstractMap { + private: + public: + enum { + REGULAR = 0, + ALIGNMENT = 6 + }; + typedef std::map<std::string, BlockData> Params; + ClientData* clientData; + Params params; + int classID; + /// Default constructor + AbstractMap(); + /// Copy constructor + AbstractMap(const AbstractMap& c); + /// Default destructor + virtual ~AbstractMap(); + /// Assignment operator + AbstractMap& operator=(const AbstractMap& c); + /// Simplify access to client data + template <typename T> T* option() const { + return static_cast<T*>(clientData); + } + /// Simplify access to first item of the parameter list (const access) + const Params::value_type& firstParam() const { + Params::const_iterator i=params.begin(); + if ( i != params.end() ) return (*i); + throw std::runtime_error("AbstractMap: Failed to access non-existing first parameter"); + } + /// Simplify access to first item of the parameter list + Params::value_type& firstParam() { + Params::iterator i=params.begin(); + if ( i != params.end() ) return (*i); + throw std::runtime_error("AbstractMap: Failed to access non-existing first parameter"); + } + /// Simplify access to first item of the parameter list (const access) + template <typename T> const T& first() const { + Params::const_iterator i=params.begin(); + if ( i != params.end() ) return (*i).second.get<T>(); + throw std::runtime_error("AbstractMap: Failed to access non-existing first item"); + } + /// Simplify access to first item of the parameter list + template <typename T> T& first() { + Params::iterator i=params.begin(); + if ( i != params.end() ) return (*i).second.get<T>(); + throw std::runtime_error("AbstractMap: Failed to access non-existing first item"); + } + /// Simplify access to mapped item of the parameter list (const access) + template <typename T> const T& operator[](const std::string& item) const { + Params::const_iterator i=params.find(item); + if ( i != params.end() ) return (*i).second.get<T>(); + throw std::runtime_error("AbstractMap: Failed to access non-existing item:"+item); + } + /// Simplify access to mapped item of the parameter list + template <typename T> T& operator[](const std::string& item) { + Params::iterator i=params.find(item); + if ( i != params.end() ) return (*i).second.get<T>(); + throw std::runtime_error("AbstractMap: Failed to access non-existing item:"+item); + } + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_CONDITIONS_CONDITIONSDATA_H */ diff --git a/DDCore/include/DD4hep/DetConditions.h b/DDCore/include/DD4hep/DetConditions.h new file mode 100644 index 0000000000000000000000000000000000000000..3184e9ce0ada2fa6d9c7c468c87ae90c4757ec49 --- /dev/null +++ b/DDCore/include/DD4hep/DetConditions.h @@ -0,0 +1,100 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +#ifndef DD4HEP_DETCONDITIONS_H +#define DD4HEP_DETCONDITIONS_H + +// Framework include files +#include "DD4hep/Detector.h" +#include "DD4hep/Conditions.h" + +// C/C++ include files + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Geometry { + // Forward declarations + class DetElementObject; + } /* End namespace Geometry */ + + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Handle class describing the access to DetElement dependent conditions. + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_GEOMETRY + */ + class DetConditions: public Handle<Geometry::DetElementObject> { + public: + /// Internal object type + typedef Geometry::DetElementObject Object; + /// Definition of the base handle type + typedef Handle<Object> RefObject; + + public: + + /// Default constructor + DetConditions() : RefObject() { } + + /// Constructor to hold handled object + DetConditions(Object* object_ptr) : RefObject(object_ptr) { } + + /// Templated constructor for handle conversions + template <typename Q> DetConditions(const Handle<Q>& e) : RefObject(e) {} + + /// Constructor to copy handle + DetConditions(const DetConditions& e) : RefObject(e) { } + + /// Constructor to copy handle + DetConditions(const Geometry::DetElement& e) : RefObject(e) { } + +#ifdef __MAKECINT__ + /// Constructor to copy handle + DetConditions(const Ref_t& e) + : RefObject(e) { + } +#endif + /// Additional data accessor + Object& _data() const { + return object<Object>(); + } + /// Assignment operator + DetConditions& operator=(const DetConditions& e) { + m_element = e.m_element; + return *this; + } + /// Check if conditions are at all present + bool hasConditions() const; + /// Access to the conditions information + Container conditions() const; + /// Access to condition objects from a given pool + Condition get(const std::string& key, const UserPool& pool); + /// Access to condition objects from a given pool + Condition get(Condition::key_type key, const UserPool& pool); + /// Access to condition objects. Only conditions in the pool are accessed. + Condition get(const std::string& key, const Condition::iov_type& iov); + /// Access to condition objects. Only conditions in the pool are accessed. + Condition get(Condition::key_type key, const Condition::iov_type& iov); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_DETCONDITIONS_H */ diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index 90d7c95b989de0d203befc969f7f8557a35fe822..d03aa08a5769cccac957e25ee306454ed11c00d7 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -22,7 +22,6 @@ #include "DD4hep/Volumes.h" #include "DD4hep/Readout.h" #include "DD4hep/Alignment.h" -#include "DD4hep/Conditions.h" #include "DD4hep/Segmentations.h" // C/C++ include files @@ -176,6 +175,8 @@ namespace DD4hep { * - information about the \em Readout structure if the object is * instrumented and read-out. Otherwise this link is empty. * - information about the environmental conditions etc. \em conditons. + * The access to conditions is exposed via the DetConditions interface. + * See DD4hep/DetConditions.h for further details. * - alignment information. * . * @@ -196,9 +197,6 @@ namespace DD4hep { /// Extensions destructor type typedef void (*destruct_t)(void*); - typedef Conditions::IOV IOV; - typedef Conditions::Condition Condition; - typedef Conditions::Container ConditionsContainer; typedef std::map<std::string, DetElement> Children; typedef std::map<const std::type_info*, void*> Extensions; @@ -370,17 +368,15 @@ namespace DD4hep { DetElement child(const std::string& name) const; /// Access to the detector elements's parent DetElement parent() const; + /// Access to the world object. Only possible once the geometry is closed. + DetElement world() const; + /// Check if this DetElement has Conditions attached + bool hasConditions() const; /// Access to the actual alignment information Alignment alignment() const; /// Access to the survey alignment information Alignment surveyAlignment() const; - /// Access to the conditions information - ConditionsContainer conditions() const; - /// Access to the conditions information. No loading undertaken. The condition must be present - Condition condition(const std::string& key) const; - /// Access to condition objects. If not present, load condition. - Condition condition(const std::string& key, const IOV& iov); /// Set detector element for reference transformations. Will delete existing reference trafo. DetElement& setReference(DetElement reference); diff --git a/DDCore/include/DD4hep/Memory.h b/DDCore/include/DD4hep/Memory.h index 639919863b5166f775c9f0069f643d27dc57b189..f920d142885a875c42f36ec013854305d5fa1f19 100644 --- a/DDCore/include/DD4hep/Memory.h +++ b/DDCore/include/DD4hep/Memory.h @@ -45,6 +45,8 @@ namespace DD4hep { void swap(base_t& c) { this->base_t::operator=(base_t(c.release())); } + /// Constructor from copy + dd4hep_ptr(dd4hep_ptr<T>& c) : base_t(c) {} #endif public: /// Default Constructor. diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index fb9c210601dbf87842b1b43e489bf498f1327e7a..86ab8d2aa9d1e49d9b7b395de4f874d46153db47 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -456,18 +456,57 @@ namespace DD4hep { void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2) const, A1 a1, A2 a2) { std::for_each(object.begin(),object.end(),ApplyMemFuncConst2<R,T,A1,A2>(pmf,a1,a2)); } - /// Generic map Functor to act on second element + + /// Generic map Functor to act on first element (key) + template <typename M, typename FCN> class Apply1rst { + public: + const FCN& func; + Apply1rst(const FCN& f) : func(f) { } + void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& p) const + { (func)(p.first); } + void operator()(const std::pair<typename M::key_type const, typename M::mapped_type>& p) const + { (func)(p.first); } + }; + + template <typename C, typename FCN> Apply1rst<C,FCN> apply__1rst_value(C&,const FCN& func) + { return Apply1rst<C,FCN>(func); } + + template <typename C, typename FCN> void apply1rst(C& object,const FCN& func) + { std::for_each(object.begin(),object.end(),apply__1rst_value(object,func)); } + + template <typename C, typename R, typename T> + void apply1rst(C& object, R (T::*pmf)()) + { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFunc<R,T>(pmf))); } + + template <typename C, typename R, typename T, typename A1> + void apply1rst(C object, R (T::*pmf)(A1 a1), A1 a1) + { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFunc1<R,T,A1>(pmf,a1))); } + + template <typename C, typename R, typename T> + void apply1rst(C& object, R (T::*pmf)() const) + { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFuncConst<R,T>(pmf))); } + + template <typename C, typename R, typename T, typename A1> + void apply1rst(C object, R (T::*pmf)(A1 a1) const, A1 a1) + { std::for_each(object.begin(),object.end(),apply__1rst_value(object,ApplyMemFuncConst1<R,T,A1>(pmf,a1))); } + + /// Generic map Functor to act on second element (mapped type) template <typename M, typename FCN> class Apply2nd { public: const FCN& func; Apply2nd(const FCN& f) : func(f) { } void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& p) const { (func)(p.second); } + void operator()(const std::pair<typename M::key_type const, typename M::mapped_type>& p) const + { (func)(p.second); } }; template <typename C, typename FCN> Apply2nd<C,FCN> apply__2nd_value(C&,const FCN& func) { return Apply2nd<C,FCN>(func); } + template <typename C, typename FCN> void apply2nd(C& object,const FCN& func) + { std::for_each(object.begin(),object.end(),apply__2nd_value(object,func)); } + template <typename C, typename R, typename T> void apply2nd(C& object, R (T::*pmf)()) { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc<R,T>(pmf))); } diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 6fdad02dfe19df1b906c1d89ca8d6dd8cb920b3a..0cb30e36ab05ef9fa81332ca1bfe27944c945545 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -92,7 +92,7 @@ namespace DD4hep { /// Magic word to detect memory corruptions unsigned long magic; /// Reference count on object (used to implement Grab/Release) - long refCount; + long refCount; /// ID container VolIDs volIDs; /// Default constructor @@ -184,11 +184,16 @@ namespace DD4hep { unsigned long magic; /// Reference count on object (used to implement Grab/Release) long refCount; - Region region; - LimitSet limits; - VisAttr vis; - Ref_t sens_det; - int referenced; + /// Region reference + Region region; + /// Limit sets used for simulation + LimitSet limits; + /// Reference to visualization attributes + VisAttr vis; + /// Reference to the sensitive detector + Ref_t sens_det; + + int referenced; /// Default constructor VolumeExtension(); /// Default destructor diff --git a/DDCore/include/DD4hep/World.h b/DDCore/include/DD4hep/World.h index 2eaaf21b482ba3194cc981869238357495377046..789c718dfaf01dc51bedb6dd5938111d9c46056e 100644 --- a/DDCore/include/DD4hep/World.h +++ b/DDCore/include/DD4hep/World.h @@ -42,6 +42,7 @@ namespace DD4hep { typedef Handle<Object> RefObject; /// Conditions stuff typedef Conditions::IOV IOV; + typedef Conditions::UserPool UserPool; typedef Conditions::Condition Condition; public: @@ -49,10 +50,13 @@ namespace DD4hep { World() : RefObject() { } /// Copy from named handle - World(const RefObject& sd) : RefObject(sd) {} + World(const RefObject& o) : RefObject(o) {} /// Copy from handle - World(const World& sd) : RefObject(sd) {} + World(const World& w) : RefObject(w) {} + + /// Copy from pointer + World(Object* p) : RefObject(p) {} /// Templated constructor for handle conversions template <typename Q> World(const Handle<Q>& e) : RefObject(e) {} @@ -66,10 +70,12 @@ namespace DD4hep { LCDD& lcdd() const; #endif /// Access the conditions loading - Condition getCondition(DetElement child,const std::string& key, const IOV& iov) const; + Condition getCondition(Condition::key_type key, const IOV& iov) const; + /// Access the conditions loading. Only conditions in the pool are accessed. + Condition getCondition(Condition::key_type key, const UserPool& pool) const; }; - } /* End namespace Geometry */ -} /* End namespace DD4hep */ + } /* End namespace Conditions */ +} /* End namespace DD4hep */ -#endif /* DD4HEP_DETECTOR_H */ +#endif /* DD4HEP_WORLD_H */ diff --git a/DDCore/include/DD4hep/objects/BasicGrammar_inl.h b/DDCore/include/DD4hep/objects/BasicGrammar_inl.h index b996a40d35dcbd838c2fac2b5573eba7cf1addc1..b15eb53a392ad7f6735f617a4332e01f2b80d796 100644 --- a/DDCore/include/DD4hep/objects/BasicGrammar_inl.h +++ b/DDCore/include/DD4hep/objects/BasicGrammar_inl.h @@ -11,8 +11,8 @@ // Author : M.Frank // //========================================================================== -#ifndef DD4HEP_DDG4_GRAMMAR_INL_H -#define DD4HEP_DDG4_GRAMMAR_INL_H +#ifndef DD4HEP_DDCORE_BASICGRAMMAR_INL_H +#define DD4HEP_DDCORE_BASICGRAMMAR_INL_H // Framework include files #include "DD4hep/Primitives.h" @@ -48,6 +48,8 @@ namespace DD4hep { * \ingroup DD4HEP */ template <typename TYPE> class Grammar : public BasicGrammar { + /// Cached type information name + std::string m_typeName; public: /// Standarsd constructor Grammar(); @@ -55,6 +57,8 @@ namespace DD4hep { virtual ~Grammar(); /// PropertyGrammar overload: Access to the type information virtual const std::type_info& type() const; + /// Access to the type information name + virtual const std::string& type_name() const; /// Access the object size (sizeof operator) virtual size_t sizeOf() const; /// PropertyGrammar overload: Serialize a property to a string @@ -67,6 +71,7 @@ namespace DD4hep { /// Standarsd constructor template <typename TYPE> Grammar<TYPE>::Grammar() { + m_typeName = typeName(typeid(TYPE)); } /// Default destructor @@ -78,6 +83,11 @@ namespace DD4hep { return typeid(TYPE); } + /// PropertyGrammar overload: Access to the type information + template <typename TYPE> const std::string& Grammar<TYPE>::type_name() const { + return m_typeName; + } + /// Access the object size (sizeof operator) template <typename TYPE> size_t Grammar<TYPE>::sizeOf() const { return sizeof(TYPE); @@ -284,7 +294,10 @@ namespace DD4hep { template<typename T> inline int eval_none(T*, const std::string&) { return 1; } - + template <typename T> inline int parse_none(T&, const std::string&) { + return 1; + } + // Containers of objects are not handled! } // End namespace DD4hep @@ -302,12 +315,12 @@ namespace DD4hep { \ DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func) #if defined(DD4HEP_HAVE_ALL_PARSERS) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::deque<x>, eval_container) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::deque<x>, eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_map_t, eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::ulong_map_t, eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_map_t, eval_container) \ @@ -315,35 +328,35 @@ namespace DD4hep { \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::ulong_pair_t, eval_pair) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_pair_t, eval_pair) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \ - DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \ + DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item) \ DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(unsigned x,eval_item) #else -#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_map_t, eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_map_t, eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_pair_t, eval_pair) \ DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_pair_t, eval_pair) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \ DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \ DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item) #endif -#endif /* DD4HEP_DDG4_GRAMMAR_INL_H */ +#endif /* DD4HEP_DDCORE_BASICGRAMMAR_INL_H */ diff --git a/DDCore/include/DD4hep/objects/ConditionsInterna.h b/DDCore/include/DD4hep/objects/ConditionsInterna.h index 5cec605f5986bd948b392c26dcac24529699e84e..c85b8ddb4586251e20ad7712b434c764aa3daae2 100644 --- a/DDCore/include/DD4hep/objects/ConditionsInterna.h +++ b/DDCore/include/DD4hep/objects/ConditionsInterna.h @@ -26,13 +26,6 @@ /// Namespace for the AIDA detector description toolkit namespace DD4hep { - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { - // Forward declarations - class DetElement; - class DetElementObject; - } - /// Namespace for the conditions part of the AIDA detector description toolkit namespace Conditions { @@ -93,23 +86,6 @@ namespace DD4hep { template<typename T> T& set(const std::string& value); }; - /// The data class behind a conditions container handle. - /** - * See ConditionsInterna.cpp for the implementation. - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class ConditionsLoader { - protected: - /// Protected destructor - virtual ~ConditionsLoader(); - public: - /// Access the conditions loading - virtual Condition get(Geometry::DetElement element, const std::string& key, const IOV& iov) = 0; - }; - /// Conditions internal namespace declaration /** Internally defined datastructures are not presented to the * user directly, but are used by dedicated views. @@ -134,10 +110,9 @@ namespace DD4hep { */ class ConditionObject : public NamedObject { public: - enum ConditionState { - INACTIVE = 0, - ACTIVE = 1 - }; + /// Forward definition of the key type + typedef Condition::key_type key_type; + typedef Condition::iov_type iov_type; /// Condition value (in string form) std::string value; /// Condition validity (in string form) @@ -146,16 +121,14 @@ namespace DD4hep { std::string address; /// Comment string std::string comment; - /// The detector element - Geometry::DetElement detector; /// Data block BlockData data; /// Reference to conditions pool ConditionsPool* pool; /// Interval of validity - const IOV* iov; + const iov_type* iov; /// Hash value of the name - int hash; + key_type hash; /// Flags int flags; /// Reference count @@ -167,12 +140,14 @@ namespace DD4hep { /// Move data content: 'from' will be reset to NULL ConditionObject& move(ConditionObject& from); /// Access safely the IOV - const IOV* iov_data() const; + const iov_type* iovData() const; /// Access safely the IOV-type - const IOVType* iov_type() const; + const IOVType* iovType() const; /// Check if object is already bound.... - bool is_bound() const { return data.is_bound(); } - bool is_traced() const { return true; } + bool is_bound() const { return data.is_bound(); } + bool is_traced() const { return true; } + void setFlag(int option) { flags |= option; } + void unFlag(int option) { flags &= ~option; } }; /// The data class behind a conditions container handle. @@ -184,42 +159,76 @@ namespace DD4hep { * \ingroup DD4HEP_CONDITIONS */ class ConditionContainer : public NamedObject { - private: - // We only allow creation and deletion by the central detector element - friend class Geometry::DetElement; - friend class Geometry::DetElementObject; + public: + /// Forward defintion of the key type + typedef Condition::key_type key_type; + typedef Condition::iov_type iov_type; + typedef std::pair<key_type, std::string> key_value; + /// Definition of the keys + typedef std::map<key_type, key_value> Keys; + public: /// Standard constructor - ConditionContainer(); + ConditionContainer(Geometry::DetElementObject* parent); /// Default destructor virtual ~ConditionContainer(); - public: - /// Clear all conditions. Auto-delete of all existing entries - void lock(); - void unlock(); - void removeElements(); - void add(Condition condition); - void remove(int condition_hash); - size_t size() const { return entries.size(); } #ifdef __CINT__ Handle<NamedObject> detector; #else - typedef Container::Entries Entries; - Entries& elements() { return entries; } - const Entries& elements() const { return entries; } - public: /// The hosting detector element - DetElement detector; + DetElement detector; + + /// Access to condition objects by key and IOV. + Condition get(const std::string& condition_key, const iov_type& iov); + + /// Access to condition objects directly by their hash key. + Condition get(key_type hash_key, const iov_type& iov); + + /// Access to condition objects. Only conditions in the pool are accessed. + Condition get(const std::string& condition_key, const UserPool& iov); + + /// Access to condition objects. Only conditions in the pool are accessed. + Condition get(key_type condition_key, const UserPool& iov); #endif - private: - /// Conditions container declaration - Container::Entries entries; - // std::map<std::string,Condition> entries; + public: + /// Known keys of conditions in this container + Keys keys; + + /// Add a new key to the conditions access map + void addKey(const std::string& key_value); + /// Add a new key to the conditions access map: Allow for alias if key_val != data_val + void addKey(const std::string& key_value, const std::string& data_value); }; } /* End namespace Interna */ + /// The data class behind a conditions container handle. + /** + * See ConditionsInterna.cpp for the implementation. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsLoader { + protected: + typedef Condition::key_type key_type; + typedef Condition::iov_type iov_type; + /// Protected destructor + virtual ~ConditionsLoader(); + public: + /// Addreference count. Use object + virtual void addRef() = 0; + /// Release object. The client may not use any reference any further. + virtual void release() = 0; + /// Access the conditions loading mechanism + virtual Condition get(key_type key, const iov_type& iov) = 0; + /// Access the conditions loading mechanism. Only conditions in the user pool will be accessed. + virtual Condition get(key_type key, const UserPool& pool) = 0; + }; + + template <typename T> static void copyObject(void* t, const void* s) { new(t) T(*(const T*)s); } @@ -247,7 +256,7 @@ namespace DD4hep { T& ret = this->bind<T>(); if ( !value.empty() && !this->fromString(value) ) { throw std::runtime_error("BlockData::set> Failed to bind type "+ - typeName(typeid(T))+" to condition data block."); + ::DD4hep::typeName(typeid(T))+" to condition data block."); } return ret; } @@ -268,43 +277,47 @@ namespace DD4hep { } /* End namespace Conditions */ } /* End namespace DD4hep */ -#define DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ - namespace DD4hep { namespace Conditions { \ - template x& Condition::bind<x>(); \ - template x& Condition::get<x>(); \ - template const x& Condition::get<x>() const; \ +#define DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ + namespace DD4hep { namespace Conditions { \ + template x& Condition::bind<x>(); \ + template x& Condition::get<x>(); \ + template const x& Condition::get<x>() const; \ }} -#define DD4HEP_DEFINE_EXTERNAL_CONDITIONS_TYPE(x) \ - namespace DD4hep { namespace Conditions { \ - template <> x& Condition::bind<x>(); \ - template <> x& Condition::get<x>(); \ - template <> const x& Condition::get<x>() const; \ +#define DD4HEP_DEFINE_CONDITIONS_TYPE_DUMMY(x) \ + namespace DD4hep{namespace Parsers{int parse(x&, const std::string&){return 1;}}} \ + DD4HEP_DEFINE_CONDITIONS_TYPE(x) + +#define DD4HEP_DEFINE_EXTERNAL_CONDITIONS_TYPE(x) \ + namespace DD4hep { namespace Conditions { \ + template <> x& Condition::bind<x>(); \ + template <> x& Condition::get<x>(); \ + template <> const x& Condition::get<x>() const; \ }} #if defined(DD4HEP_HAVE_ALL_PARSERS) -#define DD4HEP_DEFINE_CONDITIONS_CONT(x) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::vector<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::list<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::deque<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::int_map_t) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::ulong_map_t) \ +#define DD4HEP_DEFINE_CONDITIONS_CONT(x) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::vector<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::list<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::deque<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::int_map_t) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::ulong_map_t) \ DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::string_map_t) -#define DD4HEP_DEFINE_CONDITIONS_U_CONT(x) \ - DD4HEP_DEFINE_CONDITIONS_CONT(x) \ +#define DD4HEP_DEFINE_CONDITIONS_U_CONT(x) \ + DD4HEP_DEFINE_CONDITIONS_CONT(x) \ DD4HEP_DEFINE_CONDITIONS_CONT(unsigned x) #else -#define DD4HEP_DEFINE_CONDITIONS_CONT(x) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::vector<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::list<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::int_map_t) \ +#define DD4HEP_DEFINE_CONDITIONS_CONT(x) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::vector<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::list<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::int_map_t) \ DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::string_map_t) #define DD4HEP_DEFINE_CONDITIONS_U_CONT(x) DD4HEP_DEFINE_CONDITIONS_CONT(x) diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h index d73644b6f505825874bcd273e27c5fbb84dd70b4..0dfafe558a8aa12e5f9ab2d32cee9cbd64976058 100644 --- a/DDCore/include/DD4hep/objects/DetectorInterna.h +++ b/DDCore/include/DD4hep/objects/DetectorInterna.h @@ -17,12 +17,15 @@ // Framework include files #include "DD4hep/Callback.h" #include "DD4hep/NamedObject.h" +#include "DD4hep/World.h" #include "DD4hep/Objects.h" #include "DD4hep/Detector.h" #include "DD4hep/Alignment.h" #include "DD4hep/Conditions.h" #include "DD4hep/Segmentations.h" #include "DD4hep/ObjectExtensions.h" + +// ROOT include files #include "TGeoMatrix.h" /// Namespace for the AIDA detector description toolkit @@ -76,15 +79,15 @@ namespace DD4hep { // Type definitions. // The full namespace declaration is required by cint.... typedef /* DD4hep::Geometry:: */ DetElement::destruct_t destruct_t; - typedef /* DD4hep::Geometry:: */ DetElement::copy_t copy_t; + typedef /* DD4hep::Geometry:: */ DetElement::copy_t copy_t; - typedef /* DD4hep::Geometry:: */ DetElement::Children Children; + typedef /* DD4hep::Geometry:: */ DetElement::Children Children; typedef /* DD4hep::Geometry:: */ DetElement::Extensions Extensions; - typedef std::pair<Callback,unsigned long> UpdateCall; - typedef std::vector<UpdateCall> UpdateCallbacks; - typedef DetElement::ConditionsContainer ConditionsContainer; - typedef DetElement::Condition Condition; - typedef Conditions::IOV IOV; + typedef std::pair<Callback,unsigned long> UpdateCall; + typedef std::vector<UpdateCall> UpdateCallbacks; + typedef Conditions::Container ConditionsContainer; + typedef Conditions::Condition Condition; + typedef Conditions::IOV IOV; enum DetFlags { HAVE_WORLD_TRAFO = 1<<0, @@ -121,6 +124,8 @@ namespace DD4hep { */ VolumeID volumeID; /// Reference to the parent element + World privateWorld; + /// Reference to the parent element DetElement parent; /// Reference element for stored transformations DetElement reference; @@ -149,6 +154,12 @@ namespace DD4hep { /// Intermediate buffer for the transformation to an arbitrary DetElement TGeoHMatrix* referenceTrafo; //@} + private: + //@{ Private methods used internally by the object itself. */ + /// Resolve the world object. Internal use ONLY. + WorldObject* i_access_world(); + + public: //@{ Public methods to ease the usage of the data. */ /// Initializing constructor DetElementObject(const std::string& nam, int ident); @@ -158,6 +169,10 @@ namespace DD4hep { virtual ~DetElementObject(); /// Deep object copy to replicate DetElement trees e.g. for reflection virtual DetElementObject* clone(int new_id, int flag) const; + /// Access to the world object. Only possible once the geometry is closed. + WorldObject* world() + { return privateWorld.isValid() ? privateWorld.ptr() : i_access_world(); } + ConditionsContainer assign_conditions(); //@} /// Create cached matrix to transform to world coordinates const TGeoHMatrix& worldTransformation(); @@ -183,7 +198,10 @@ namespace DD4hep { */ class WorldObject: public DetElementObject { public: - typedef Conditions::ConditionsLoader ConditionsLoader; + typedef Conditions::UserPool UserPool; + typedef Conditions::Condition Condition; + typedef Conditions::ConditionsLoader ConditionsLoader; + typedef Conditions::ConditionsManagerObject ConditionsManagerObject; /// Reference to the LCDD instance object LCDD* lcdd; @@ -191,10 +209,13 @@ namespace DD4hep { /// Conditions loader for this LCDD instance ConditionsLoader* conditionsLoader; + /// Reference to the conditions manager object + ConditionsManagerObject* conditionsManager; + public: //@{ Public methods to ease the usage of the data. */ /// Default constructor - WorldObject() : DetElementObject(), lcdd(0), conditionsLoader(0) {} + WorldObject() : DetElementObject(), lcdd(0), conditionsLoader(0), conditionsManager(0) {} #ifndef __CINT__ /// Initializing constructor WorldObject(LCDD& lcdd, const std::string& nam); @@ -202,7 +223,9 @@ namespace DD4hep { /// Internal object destructor: release extension object(s) virtual ~WorldObject(); /// Access the conditions loading - Condition getCondition(DetElement child, const std::string& key, const IOV& iov); + Condition getCondition(Condition::key_type key, const Condition::iov_type& iov) const; + /// Access the conditions loading. Only conditions in the pool are accessed. + Condition getCondition(Condition::key_type key, const UserPool& pool) const; }; } /* End namespace Geometry */ diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp new file mode 100644 index 0000000000000000000000000000000000000000..879cc8a84bfedf227eebaa5e8bda971332cbb81f --- /dev/null +++ b/DDCore/src/ConditionDerived.cpp @@ -0,0 +1,100 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework includes +#include "DD4hep/Printout.h" +#include "DD4hep/ConditionDerived.h" + +// C/C++ include files + +using namespace DD4hep; +using namespace DD4hep::Conditions; + +/// Standard destructor +ConditionUpdateCall::~ConditionUpdateCall() { +} + +/// Standard destructor +ConditionResolver::~ConditionResolver() { +} + +/// Default constructor +ConditionDependency::ConditionDependency(const ConditionKey& tar, + const Dependencies deps, + ConditionUpdateCall* call) + : target(tar), dependencies(deps), callback(call) +{ +} + +/// Default constructor +ConditionDependency::ConditionDependency(const ConditionKey& tar, + ConditionUpdateCall* call) + : target(tar), callback(call) +{ +} + +/// Initializing constructor +ConditionDependency::ConditionDependency() { +} + +/// Copy constructor +ConditionDependency::ConditionDependency(const ConditionDependency& c) + : target(c.target), dependencies(c.dependencies) +{ + except("Dependency", + "++ Condition: %s. Dependencies may not be assigned or copied!", + target.name.c_str()); +} + +/// Default destructor +ConditionDependency::~ConditionDependency() { +} + +/// Assignment operator +ConditionDependency& ConditionDependency::operator=(const ConditionDependency& ) { + except("Dependency", + "++ Condition: %s. Dependencies may not be assigned or copied!", + target.name.c_str()); + return *this; +} + +/// Initializing constructor +DependencyBuilder::DependencyBuilder(const ConditionKey& target, ConditionUpdateCall* call) + : dependency(new ConditionDependency(target,call)) +{ +} + +/// Default destructor +DependencyBuilder::~DependencyBuilder() { +} + +/// Add a new dependency +void DependencyBuilder::add(const ConditionKey& source) { + ConditionDependency* dep = dependency.get(); + if ( dep ) { + dep->dependencies.push_back(source); + return; + } + except("Dependency","++ Invalid object. No further source may be added!"); +} + +/// Release the created dependency and take ownership. +ConditionDependency* DependencyBuilder::release() { + if ( dependency.get() ) { + return dependency.release(); + } + except("Dependency","++ Invalid object. Cannot access built objects!"); + return dependency.release(); // Not necessary, but need to satisfy compiler +} + diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp index 392bdc9f2f386c7a15fae309bf4bee9995cbd44e..6a55438cffaa729f6cfac00d2304d3a219851f37 100644 --- a/DDCore/src/Conditions.cpp +++ b/DDCore/src/Conditions.cpp @@ -15,11 +15,11 @@ // Framework includes #include "DD4hep/Handle.inl" #include "DD4hep/Printout.h" -#include "DD4hep/Detector.h" -#include "DD4hep/objects/DetectorInterna.h" #include "DD4hep/objects/ConditionsInterna.h" +// C/C++ include files #include <climits> +#include <iomanip> using namespace std; using namespace DD4hep::Conditions; @@ -74,16 +74,18 @@ void IOV::set(Key::first_type val_1, Key::second_type val_2) { } /// Set keys to unphysical values (LONG_MAX, LONG_MIN) -void IOV::reset() { +IOV& IOV::reset() { keyData.first = LONG_MAX; keyData.second = LONG_MIN; + return *this; } /// Set keys to unphysical values (LONG_MAX, LONG_MIN) -void IOV::invert() { +IOV& IOV::invert() { Key::first_type tmp = keyData.first; keyData.first = keyData.second; keyData.second = tmp; + return *this; } void IOV::iov_intersection(const IOV& validity) { @@ -198,11 +200,38 @@ const std::type_info& Block::typeInfo() const { throw runtime_error("Conditions data block is unbound. Cannot determine type information!"); } +/// Access type name of the condition data block +const std::string& Block::dataType() const { + if ( pointer && grammar ) { + return grammar->type_name(); + } + throw runtime_error("Conditions data block is unbound. Cannot determine type information!"); +} + +/// Constructor from string +ConditionKey::ConditionKey(const std::string& value) + : name(value), hash(hashCode(value)) +{ +} + +/// Assignment operator from the string representation +ConditionKey& ConditionKey::operator=(const std::string& value) { + ConditionKey key(value); + hash = hashCode(value); + name = value; + return *this; +} + +/// Operator less (for map insertions) using the string representation +bool ConditionKey::operator<(const std::string& compare) const { + return hash < hashCode(compare); +} + /// Initializing constructor Condition::Condition(const string& nam,const string& typ) : Handle<Object>() { Object* o = new Object(); assign(o,nam,typ); - o->hash = hash32(nam); + o->hash = ConditionKey::hashCode(nam); } /// Assignment operator @@ -211,6 +240,28 @@ Condition& Condition::operator=(const Condition& c) { return *this; } +/// Output method +std::string Condition::str(int flags) const { + stringstream output; + Object* o = access(); + const IOV* ptr_iov = o->iovData(); + if ( 0 == (flags&NO_NAME) ) + output << setw(16) << left << o->name; + if ( flags&WITH_IOV ) + output << " " << (ptr_iov ? ptr_iov->str().c_str() : "IOV:[UNKNOWN]"); + if ( flags&WITH_TYPE ) + output << " (" << o->type << ")"; + if ( flags&WITH_ADDRESS ) + output << " " << o->address; + if ( flags&WITH_DATATYPE ) + output << " -> " << o->data.dataType(); + if ( flags&WITH_DATA ) + output << " Data:" << o->data.str(); + if ( flags&WITH_COMMENT ) + output << " \"" << o->comment << "\""; + return output.str(); +} + /// Access the data type int Condition::dataType() const { return access()->data.type; @@ -223,12 +274,12 @@ Block& Condition::block() const { /// Access the IOV type const IOVType& Condition::iovType() const { - return *(access()->iov_type()); + return *(access()->iovType()); } /// Access the IOV block const IOV& Condition::iov() const { - return *(access()->iov_data()); + return *(access()->iovData()); } /// Access the name of the condition @@ -241,11 +292,6 @@ const string& Condition::type() const { return access()->type; } -/// Access the validity field of the condition as a string -const string& Condition::validity() const { - return access()->validity; -} - /// Access the value field of the condition as a string const string& Condition::value() const { return access()->value; @@ -261,9 +307,10 @@ const string& Condition::address() const { return access()->address; } -/// Access the hosting detector element -DetElement Condition::detector() const { - return access()->detector; +/// Access the key of the condition +ConditionKey Condition::key() const { + Object* o = access(); + return ConditionKey(o->name,o->hash); } /// Access to the type information @@ -296,49 +343,72 @@ Condition& Condition::rebind() { } #endif o->data.fromString(o->value); - printout(INFO,"Condition","+++ condition:%s : %s rebinding value:%s", - detector().path().c_str(), name().c_str(), o->value.c_str()); + printout(INFO,"Condition","+++ condition:%s rebinding value:%s", + name().c_str(), o->value.c_str()); return *this; } -/// Clear all conditions. Auto-delete of all existing entries -void Container::removeElements() const { - if ( !isValid() ) { +/// Access the number of conditons keys available for this detector element +size_t Container::numKeys() const { + Object* o = ptr(); + if ( !o ) { invalidHandleError<Container>(); } - data<Object>()->removeElements(); + return o->keys.size(); } -/// Access the number of conditons available for this detector element -size_t Container::count() const { - if ( !isValid() ) { - invalidHandleError<Container>(); +/// Access to condition objects +Condition Container::get(const std::string& condition_key, const iov_type& iov) { + Object* o = ptr(); + if ( o ) { + Condition c = o->get(condition_key, iov); + if ( c.isValid() ) { + return c; + } + invalidHandleError<Condition>(); } - return data<Object>()->size(); + invalidHandleError<Container>(); + return Condition(); } -/// Access the full map of conditons -Container::Entries& Container::entries() const { - if ( !isValid() ) { - invalidHandleError<Container>(); +/// Access to condition objects +Condition Container::get(key_type condition_key, const iov_type& iov) { + Object* o = ptr(); + if ( o ) { + Condition c = o->get(condition_key, iov); + if ( c.isValid() ) { + return c; + } + invalidHandleError<Condition>(); } - return data<Object>()->elements(); + invalidHandleError<Container>(); + return Condition(); } /// Access to condition objects -Condition Container::operator[](const std::string& key) { - return this->operator[](hash32(key)); +Condition Container::get(const std::string& condition_key, const UserPool& pool) { + Object* o = ptr(); + if ( o ) { + Condition c = o->get(condition_key, pool); + if ( c.isValid() ) { + return c; + } + invalidHandleError<Condition>(); + } + invalidHandleError<Container>(); + return Condition(); } /// Access to condition objects -Condition Container::operator[](int condition_hash) { - Object* c = ptr(); - if ( !c ) { - invalidHandleError<Container>(); +Condition Container::get(key_type condition_key, const UserPool& pool) { + Object* o = ptr(); + if ( o ) { + Condition c = o->get(condition_key, pool); + if ( c.isValid() ) { + return c; + } + invalidHandleError<Condition>(); } - Entries::iterator i=c->elements().find(condition_hash); - if ( i != c->elements().end() ) return (*i).second; - except("ConditionContainer", - "No condition with key 0x%08X present!",condition_hash); + invalidHandleError<Container>(); return Condition(); } diff --git a/DDCore/src/ConditionsData.cpp b/DDCore/src/ConditionsData.cpp new file mode 100644 index 0000000000000000000000000000000000000000..93138174191f8e125ab30da6cac87ea732548fc3 --- /dev/null +++ b/DDCore/src/ConditionsData.cpp @@ -0,0 +1,118 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework includes +#include "DD4hep/Printout.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/ConditionsData.h" +#include <sstream> + +using namespace DD4hep::Conditions; + +/// print Conditions object +std::ostream& operator << (std::ostream& s, const AlignmentDelta& data) { + std::string res; + std::stringstream str; + str << "[" << data.position << "," << data.rotation << "," << data.pivot << "]"; + res = str.str(); + for(size_t i=0; i<res.length(); ++i) + if ( res[i]=='\n' ) res[i] = ' '; + return s << res; +} + +/// Default constructor +AlignmentDelta::AlignmentDelta() { + InstanceCount::increment(this); +} + +/// Copy constructor +AlignmentDelta::AlignmentDelta(const AlignmentDelta& c) + : pivot(c.pivot), position(c.position), rotation(c.rotation) +{ + InstanceCount::increment(this); +} + +/// Default destructor +AlignmentDelta::~AlignmentDelta() { + InstanceCount::decrement(this); +} + +/// Assignment operator +AlignmentDelta& AlignmentDelta::operator=(const AlignmentDelta& c) { + if ( &c != this ) { + pivot = c.pivot; + position = c.position; + rotation = c.rotation; + } + return *this; +} + +/// print Conditions object +std::ostream& operator << (std::ostream& s, const AbstractMap& data) { + struct _Print { + void operator()(const AbstractMap::Params::value_type& obj) const { + const AbstractMap& d= obj.second.get<AbstractMap>(); + DD4hep::printout(DD4hep::INFO,"Condition","++ %-16s [%d] %-8s -> %s", + obj.first.c_str(), d.classID, + obj.second.dataType().c_str(), + obj.second.str().c_str()); + } + }; + if ( !data.params.empty() ) { + for_each(data.params.begin(), data.params.end(),_Print()); + } + return s; +} + +/// Default destructor +ClientData::~ClientData() { +} + +/// Copy constructor +AbstractMap::AbstractMap(const AbstractMap& c) + : clientData(c.clientData), params(c.params), classID(c.classID) +{ + InstanceCount::increment(this); +} + +/// Default constructor +AbstractMap::AbstractMap() : clientData(0) { + InstanceCount::increment(this); +} + +/// Default destructor +AbstractMap::~AbstractMap() { + if ( clientData ) clientData->release(); + clientData = 0; + InstanceCount::decrement(this); +} + +/// Assignment operator +AbstractMap& AbstractMap::operator=(const AbstractMap& c) { + if ( this != &c ) { + clientData = c.clientData; + params = c.params; + classID = c.classID; + } + return *this; +} + +#include "DD4hep/ToStream.h" +#include "DD4hep/objects/ConditionsInterna.h" +DD4HEP_DEFINE_CONDITIONS_TYPE_DUMMY(AbstractMap) +DD4HEP_DEFINE_CONDITIONS_TYPE_DUMMY(AlignmentDelta) + +#include "DD4hep/objects/BasicGrammar_inl.h" +DD4HEP_DEFINE_PARSER_GRAMMAR(AbstractMap,eval_none<AbstractMap>) +DD4HEP_DEFINE_PARSER_GRAMMAR(AlignmentDelta,eval_none<AlignmentDelta>) diff --git a/DDCore/src/ConditionsInterna.cpp b/DDCore/src/ConditionsInterna.cpp index c5e91ffead795f346443e45f7f0a01e0e692e09c..a120b3e2f8088810226b221aed76c094c6e1aecb 100644 --- a/DDCore/src/ConditionsInterna.cpp +++ b/DDCore/src/ConditionsInterna.cpp @@ -13,21 +13,15 @@ //========================================================================== // Framework includes -#include "DD4hep/Mutex.h" #include "DD4hep/Handle.inl" #include "DD4hep/Printout.h" -#include "DD4hep/Detector.h" -#include "DD4hep/DetectorTools.h" #include "DD4hep/InstanceCount.h" +#include "DD4hep/objects/DetectorInterna.h" #include "DD4hep/objects/ConditionsInterna.h" using namespace std; using namespace DD4hep::Conditions; -namespace { - DD4hep::dd4hep_mutex_t s_conditionsMutex; -} - DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionObject); DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionContainer); @@ -134,7 +128,9 @@ void BlockData::assign(const void* ptr, const type_info& typ) { /// Standard constructor Interna::ConditionObject::ConditionObject() - : NamedObject(), detector(), data(), iov(0), hash(0), flags(0), refCount(0) + : NamedObject(), value(), validity(), address(), comment(), + data(), pool(0), iov(0), + hash(0), flags(0), refCount(0) { InstanceCount::increment(this); } @@ -150,70 +146,92 @@ Interna::ConditionObject& Interna::ConditionObject::move(ConditionObject& /* fro } /// Access safely the IOV -const IOV* Interna::ConditionObject::iov_data() const { +const Condition::iov_type* Interna::ConditionObject::iovData() const { if ( iov ) return iov; invalidHandleError<IOV>(); return 0; } /// Access safely the IOV-type -const IOVType* Interna::ConditionObject::iov_type() const { +const IOVType* Interna::ConditionObject::iovType() const { if ( iov && iov->iovType ) return iov->iovType; invalidHandleError<IOVType>(); return 0; } /// Standard constructor -Interna::ConditionContainer::ConditionContainer() : NamedObject(), entries() { +Interna::ConditionContainer::ConditionContainer(Geometry::DetElementObject* par) + : NamedObject(), detector(par), keys() +{ InstanceCount::increment(this); } /// Default destructor Interna::ConditionContainer::~ConditionContainer() { - removeElements(); InstanceCount::decrement(this); } -/// Clear all attached conditions. -void Interna::ConditionContainer::removeElements() { - dd4hep_lock_t locked_call(s_conditionsMutex); - for(Entries::iterator i=entries.begin(); i!=entries.end();++i) - (*i).second->flags &= ~(ConditionObject::ACTIVE); - entries.clear(); -} - -void Interna::ConditionContainer::add(Condition condition) { - ConditionObject* o = condition.ptr(); - if ( o ) { - if ( !o->hash ) o->hash = hash32(condition.name()); - dd4hep_lock_t locked_call(s_conditionsMutex); - Entries::iterator i=entries.find(o->hash); - o->flags |= ConditionObject::ACTIVE; - if ( i != entries.end() ) { - (*i).second->flags &= ~(ConditionObject::ACTIVE); - (*i).second = o; - return; - } - entries[o->hash] = o; - return; +/// Add a new key to the conditions access map +void Interna::ConditionContainer::addKey(const string& key_val) { + key_type hash = ConditionKey::hashCode(key_val); + if ( !keys.insert(make_pair(hash,make_pair(hash,key_val))).second ) { + except("ConditionContainer","++ Key[%08X]: %s already present. Duplicate insertions inhibited!",hash, key_val.c_str()); + } +} + +/// Add a new key to the conditions access map: Allow for alias if key_val != data_val +void Interna::ConditionContainer::addKey(const string& key_val, const string& data_val) { + key_type key_hash = ConditionKey::hashCode(key_val); + key_type val_hash = ConditionKey::hashCode(data_val); + if ( !keys.insert(make_pair(key_hash,make_pair(val_hash,data_val))).second ) { + except("ConditionContainer","++ Key[%08X]: %s already present. Duplicate insertions inhibited!",key_hash, key_val.c_str()); + } +} + +/// Access to condition objects directly by their hash key. +Condition Interna::ConditionContainer::get(const string& key_val, const iov_type& iov) { + key_type hash = ConditionKey::hashCode(key_val); + Keys::const_iterator i=keys.find(hash); + if ( i != keys.end() ) { + const key_value& k = (*i).second; + return detector->world()->getCondition(k.first, iov); } - invalidHandleError<Condition>(); + /// Last resort: Assume the key value is globally known: + return detector->world()->getCondition(hash, iov); } -void Interna::ConditionContainer::remove(int condition_hash) { - dd4hep_lock_t locked_call(s_conditionsMutex); - Entries::iterator i=entries.find(condition_hash); - if ( i != entries.end() ) { - (*i).second->flags &= ~(ConditionObject::ACTIVE); +/// Access to condition objects directly by their hash key. +Condition Interna::ConditionContainer::get(key_type hash_key, const iov_type& iov) { + Keys::const_iterator i=keys.find(hash_key); + if ( i != keys.end() ) { + const key_value& k = (*i).second; + return detector->world()->getCondition(k.first, iov); } + /// Last resort: Assume the key value is globally known: + return detector->world()->getCondition(hash_key, iov); } -void Interna::ConditionContainer::lock() { - s_conditionsMutex.lock(); +/// Access to condition objects directly by their hash key. +Condition Interna::ConditionContainer::get(const string& key_val, const UserPool& pool) { + key_type hash = ConditionKey::hashCode(key_val); + Keys::const_iterator i=keys.find(hash); + if ( i != keys.end() ) { + const key_value& k = (*i).second; + return detector->world()->getCondition(k.first, pool); + } + /// Last resort: Assume the key value is globally known: + return detector->world()->getCondition(hash, pool); } -void Interna::ConditionContainer::unlock() { - s_conditionsMutex.unlock(); +/// Access to condition objects directly by their hash key. +Condition Interna::ConditionContainer::get(key_type hash_key, const UserPool& pool) { + Keys::const_iterator i=keys.find(hash_key); + if ( i != keys.end() ) { + const key_value& k = (*i).second; + return detector->world()->getCondition(k.first, pool); + } + /// Last resort: Assume the key value is globally known: + return detector->world()->getCondition(hash_key, pool); } /// Protected destructor diff --git a/DDCore/src/DetConditions.cpp b/DDCore/src/DetConditions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5bf8ec6a29dfc23e0854830c7fa880380039b80 --- /dev/null +++ b/DDCore/src/DetConditions.cpp @@ -0,0 +1,61 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" +#include "DD4hep/DetConditions.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/World.h" +#include "DD4hep/LCDD.h" + +using namespace std; +using namespace DD4hep::Conditions; + +/// Check if conditions are at all present +bool DetConditions::hasConditions() const { + Object* o = access(); + if ( o->conditions.isValid() && !o->conditions->keys.empty() ) + return true; + return false; +} + +/// Access to the conditions information +Container DetConditions::conditions() const { + Object* o = access(); + if ( o->conditions.isValid() ) return o->conditions; + o->conditions.assign(new Container::Object(o),"conditions",""); + return o->assign_conditions(); +} + +/// Access to condition objects. +Condition DetConditions::get(const std::string& key, const Condition::iov_type& iov) { + return conditions().get(key, iov); +} + +/// Access to condition objects. +Condition DetConditions::get(Condition::key_type key, const Condition::iov_type& iov) { + return conditions().get(key, iov); +} + +/// Access to condition objects from a given pool. Only conditions in the pool are accessed. +Condition DetConditions::get(const std::string& key, const UserPool& pool) { + return conditions().get(key, pool); +} + +/// Access to condition objects from a given pool. Only conditions in the pool are accessed. +Condition DetConditions::get(Condition::key_type key, const UserPool& pool) { + return conditions().get(key, pool); +} + diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 4cd13cfa26f5f5e721a487b2433d562653bc9452..59faaaa6262fc6aa444bbf5f31c2c79fc528fa86 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -140,32 +140,6 @@ Alignment DetElement::surveyAlignment() const { return access()->survey; } -/// Access to the conditions information -DetElement::ConditionsContainer DetElement::conditions() const { - Object* o = access(); - if ( o->conditions.isValid() ) return o->conditions; - o->conditions.assign(new ConditionsContainer::Object(),"conditions",""); - o->conditions->detector = *this; - return o->conditions; -} - -/// Access to the conditions information -DetElement::Condition -DetElement::condition(const std::string& key) const { - return access()->conditions[key]; -} - -/// Access to condition objects. If not present, load condition. -DetElement::Condition -DetElement::condition(const std::string& key, const IOV& iov) { - typedef DetElement::ConditionsContainer::Object::Entries _E; - _E& ents = conditions()->entries; - _E::iterator i = ents.find(hash32(key)); - if ( i != ents.end() ) return (*i).second; - World world(Geometry::DetectorTools::topElement(*this)); - return world.getCondition(*this,key,iov); -} - const DetElement::Children& DetElement::children() const { return access()->children; } @@ -186,6 +160,20 @@ DetElement DetElement::parent() const { return (o) ? o->parent : 0; } +/// Access to the world object. Only possible once the geometry is closed. +DetElement DetElement::world() const { + Object* o = ptr(); + return (o) ? o->world() : 0; +} + +/// Check if conditions are at all present +bool DetElement::hasConditions() const { + Object* o = access(); + if ( o->conditions.isValid() && !o->conditions->keys.empty() ) + return true; + return false; +} + void DetElement::check(bool cond, const string& msg) const { if (cond) { throw runtime_error("DD4hep: " + msg); diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index 80fa958fc540076d03d558c30e178429d2b05b4c..220d21b50392ae7e9cbcc8165f39db8662d7ccbc 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -141,6 +141,19 @@ DetElementObject* DetElementObject::clone(int new_id, int flg) const { return obj; } +/// Access to the world object. Only possible once the geometry is closed. +WorldObject* DetElementObject::i_access_world() { + if ( !privateWorld.isValid() ) { + DetElementObject* p = parent.ptr(); + if ( 0 == p ) { + privateWorld = (WorldObject*)this; + return privateWorld.ptr(); + } + return p->world(); + } + return privateWorld.ptr(); +} + /// Create cached matrix to transform to world coordinates const TGeoHMatrix& DetElementObject::worldTransformation() { if ( (flag&HAVE_WORLD_TRAFO) == 0 ) { @@ -194,13 +207,13 @@ void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { PlacementPath par_path; DetElement det(this); DetElement par(det.parent()); - DetElement world = DetectorTools::topElement(det); - bool print = (DEBUG > printLevel()); - string place = det.placementPath(); - bool have_world_tr = (flag&HAVE_WORLD_TRAFO); + DetElement wrld = world(); + bool print = (DEBUG > printLevel()); + string place = det.placementPath(); + bool have_trafo = (flag&HAVE_WORLD_TRAFO); DetectorTools::placementPath(par, this, par_path); - PlacedVolume node = DetectorTools::findNode(world.placement(),place); + PlacedVolume node = DetectorTools::findNode(wrld.placement(),place); if ( !node.isValid() ) { throw runtime_error("DD4hep: DetElement: The placement " + place + " is not part of the hierarchy."); } @@ -212,7 +225,7 @@ void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { placement = node; - if ( have_world_tr && print ) worldTrafo.Print(); + if ( have_trafo && print ) worldTrafo.Print(); if ( (flag&HAVE_PARENT_TRAFO) ) { DetectorTools::placementTrafo(par_path,false,parentTrafo); @@ -225,7 +238,7 @@ void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { worldTrafo.Multiply(&parentTransformation()); flag |= HAVE_WORLD_TRAFO; } - else if ( have_world_tr ) { + else if ( have_trafo ) { // Else re-compute the transformation to the world. PlacementPath world_nodes; DetectorTools::placementPath(this, world_nodes); @@ -275,9 +288,16 @@ void DetElementObject::update(unsigned int tags, void* param) { } } +Conditions::Container DetElementObject::assign_conditions() { + if ( !conditions.isValid() ) { + conditions.assign(new Conditions::Container::Object(this),"conditions",""); + } + return conditions; +} + /// Initializing constructor WorldObject::WorldObject(LCDD& _lcdd, const string& nam) - : DetElementObject(nam,0), lcdd(&_lcdd), conditionsLoader(0) + : DetElementObject(nam,0), lcdd(&_lcdd), conditionsLoader(0), conditionsManager(0) { } @@ -286,12 +306,23 @@ WorldObject::~WorldObject() { } /// Access the conditions loading -DetElement::Condition -WorldObject::getCondition(DetElement child,const string& key, const IOV& iov) { +WorldObject::Condition +WorldObject::getCondition(Condition::key_type key, const Condition::iov_type& iov) const { + if ( conditionsLoader ) { + return conditionsLoader->get(key, iov); + } + + except("Conditions","+++ No ConditionsLoader registered to this LCDD instance!"); + return WorldObject::Condition(); +} + +/// Access the conditions loading +WorldObject::Condition +WorldObject::getCondition(Condition::key_type key, const UserPool& pool) const { if ( conditionsLoader ) { - return conditionsLoader->get(child,key,iov); + return conditionsLoader->get(key, pool); } except("Conditions","+++ No ConditionsLoader registered to this LCDD instance!"); - return DetElement::Condition(); + return WorldObject::Condition(); } diff --git a/DDCore/src/Printout.cpp b/DDCore/src/Printout.cpp index 0333eff523321cf7eff8a14075f37b5dd50f7ad4..4f191a1660cb328a17cdae7df5e8d7698b0f5e52 100644 --- a/DDCore/src/Printout.cpp +++ b/DDCore/src/Printout.cpp @@ -135,6 +135,7 @@ int DD4hep::printout(PrintLevel severity, const char* src, const char* fmt, va_l if (severity >= print_lvl) { char str[4096]; size_t len = vsnprintf(str, sizeof(str) - 2, fmt, args); + if ( len>sizeof(str)-2 ) len = sizeof(str) - 2; str[len] = '\n'; str[len + 1] = '\0'; print_func(print_arg, severity, src, str); @@ -266,8 +267,12 @@ string DD4hep::format(const string& src, const string& fmt, va_list& args) { */ string DD4hep::format(const char* src, const char* fmt, va_list& args) { char str[4096]; - size_t len = ::snprintf(str, sizeof(str), "%s: ", src); - ::vsnprintf(str + len, sizeof(str) - len, fmt, args); + size_t len1 = ::snprintf(str, sizeof(str), "%s: ", src); + size_t len2 = ::vsnprintf(str + len1, sizeof(str) - len1, fmt, args); + if ( len2 > sizeof(str) - len1 ) { + len2 = sizeof(str) - len1 - 1; + str[sizeof(str)-1] = 0; + } return string(str); } @@ -295,6 +300,7 @@ void DD4hep::setPrinter(void* arg, output_function_t fcn) { print_arg = arg; print_func = fcn; } +#include "DD4hep/Conditions.h" #include "TMap.h" #include "TROOT.h" @@ -302,6 +308,7 @@ void DD4hep::setPrinter(void* arg, output_function_t fcn) { using namespace std; namespace DD4hep { using namespace Geometry; + using Conditions::Condition; template <typename T> void PrintMap<T>::operator()() const { Printer < T > p(lcdd, os); @@ -311,44 +318,48 @@ namespace DD4hep { } template <> void Printer<Handle<NamedObject> >::operator()(const Handle<NamedObject>& val) const { - printout(INFO, "Printer", "%s ++ Handle:%s %s", prefix.c_str(), val->GetName(), val->GetTitle()); + printout(INFO, "Printer", "++ %s Handle:%s %s", prefix.c_str(), val->GetName(), val->GetTitle()); } template <> void Printer<Handle<TNamed> >::operator()(const Handle<TNamed>& val) const { - printout(INFO, "Printer", "%s ++ Handle:%s %s", prefix.c_str(), val->GetName(), val->GetTitle()); + printout(INFO, "Printer", "++ %s Handle:%s %s", prefix.c_str(), val->GetName(), val->GetTitle()); } template <> void Printer<Constant>::operator()(const Constant& val) const { - printout(INFO, "Printer", "%s ++ Constant:%s %s", prefix.c_str(), val->GetName(), val.toString().c_str()); + printout(INFO, "Printer", "++ %s Constant:%s %s", prefix.c_str(), val->GetName(), val.toString().c_str()); } template <> void Printer<Material>::operator()(const Material& val) const { - printout(INFO, "Printer", "%s ++ Material:%s %s", prefix.c_str(), val->GetName(), val.toString().c_str()); + printout(INFO, "Printer", "++ %s Material:%s %s", prefix.c_str(), val->GetName(), val.toString().c_str()); } template <> void Printer<VisAttr>::operator()(const VisAttr& val) const { - printout(INFO, "Printer", "%s ++ VisAttr: %s", prefix.c_str(), val.toString().c_str()); + printout(INFO, "Printer", "++ %s VisAttr: %s", prefix.c_str(), val.toString().c_str()); } template <> void Printer<Readout>::operator()(const Readout& val) const { - printout(INFO, "Printer", "%s ++ Readout: %s of type %s", prefix.c_str(), val->GetName(), val->GetTitle()); + printout(INFO, "Printer", "++ %s Readout: %s of type %s", prefix.c_str(), val->GetName(), val->GetTitle()); } template <> void Printer<Region>::operator()(const Region& val) const { - printout(INFO, "Printer", "%s ++ Region: %s of type %s", prefix.c_str(), val->GetName(), val->GetTitle()); + printout(INFO, "Printer", "++ %s Region: %s of type %s", prefix.c_str(), val->GetName(), val->GetTitle()); } template <> void Printer<RotationZYX>::operator()(const RotationZYX& val) const { - printout(INFO, "Printer", "%s ++ ZYXRotation: phi: %7.3 rad theta: %7.3 rad psi: %7.3 rad", prefix.c_str(), val.Phi(), + printout(INFO, "Printer", "++ %s ZYXRotation: phi: %7.3 rad theta: %7.3 rad psi: %7.3 rad", prefix.c_str(), val.Phi(), val.Theta(), val.Psi()); } template <> void Printer<Position>::operator()(const Position& val) const { - printout(INFO, "Printer", "%s ++ Position: x: %9.3 mm y: %9.3 mm z: %9.3 mm", prefix.c_str(), val.X(), val.Y(), val.Z()); + printout(INFO, "Printer", "++ %s Position: x: %9.3 mm y: %9.3 mm z: %9.3 mm", prefix.c_str(), val.X(), val.Y(), val.Z()); + } + template <> void Printer<Condition>::operator()(const Condition& val) const { + int flg = Condition::WITH_IOV|Condition::WITH_ADDRESS; + printout(INFO, "Printer", "++ %s %s", prefix.c_str(), val.str(flg).c_str()); } #if 0 template <> void Printer<LimitSet>::operator()(const LimitSet& val) const { const set<Limit>& o = val.limits(); - printout(INFO, "Printer", "%s ++ LimitSet: %s", prefix.c_str(), val.name()); + printout(INFO, "Printer", "++ %s LimitSet: %s", prefix.c_str(), val.name()); val->TNamed::Print(); for (set<Limit>::const_iterator i = o.begin(); i != o.end(); ++i) { os << "++ Limit:" << (*i).name << " " << (*i).particles << " [" << (*i).unit << "] " << (*i).content << " " diff --git a/DDCore/src/World.cpp b/DDCore/src/World.cpp index 57ba6168fbcb47b56c0027e88032415be602e845..27cff9b8d51b8f70d1c87eee92fcbe8d188384b3 100644 --- a/DDCore/src/World.cpp +++ b/DDCore/src/World.cpp @@ -20,8 +20,13 @@ using std::string; using namespace DD4hep::Geometry; /// Access the conditions loading -World::Condition World::getCondition(DetElement child,const string& key, const IOV& iov) const { - return access()->getCondition(child,key,iov); +World::Condition World::getCondition(Condition::key_type key, const Condition::iov_type& iov) const { + return access()->getCondition(key, iov); +} + +/// Access the conditions loading +World::Condition World::getCondition(Condition::key_type key, const UserPool& pool) const { + return access()->getCondition(key, pool); } /// Access the detector descrion tree diff --git a/DDDB/include/DDDB/DDDBConditionData.h b/DDDB/include/DDDB/DDDBConditionData.h deleted file mode 100644 index cff1b4fb9998684e21e8f9228e3569a5630f1090..0000000000000000000000000000000000000000 --- a/DDDB/include/DDDB/DDDBConditionData.h +++ /dev/null @@ -1,59 +0,0 @@ -// $Id$ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -// -// DDDB is a detector description convention developed by the LHCb experiment. -// For further information concerning the DTD, please see: -// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf -// -//========================================================================== -#ifndef DD4HEP_DDDB_DDDBCONDITIONDATA_H -#define DD4HEP_DDDB_DDDBCONDITIONDATA_H - -// Framework includes -#include "DD4hep/objects/ConditionsInterna.h" - -// C/C++ include files -#include <map> - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - - /// Namespace of the DDDB conversion stuff - namespace DDDB { - - // Forward declarations - class Document; - - /// CondDB reader context to support intervals of validity - /** - * \author M.Frank - * \version 1.0 - * \date 31/03/2016 - * \ingroup DD4HEP_DDDB - */ - class DDDBConditionData { - public: - typedef Conditions::BlockData Data; - typedef std::map<std::string, Data> Params; - Document* document; - Params params; - int classID; - /// Default constructor - DDDBConditionData(); - /// Default destructor - virtual ~DDDBConditionData(); - }; - } /* End namespace DDDB */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_DDDB_CONDITIONDATA_H */ diff --git a/DDDB/include/DDDB/DDDBConditionPrinter.h b/DDDB/include/DDDB/DDDBConditionPrinter.h new file mode 100644 index 0000000000000000000000000000000000000000..3aad87842ad0e68066a7bf96ddc8e6d977f140ac --- /dev/null +++ b/DDDB/include/DDDB/DDDBConditionPrinter.h @@ -0,0 +1,92 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== +#ifndef DD4HEP_DDDB_DDDBCONDITIONPRINTER_H +#define DD4HEP_DDDB_DDDBCONDITIONPRINTER_H + +// Framework includes +#include "DD4hep/ConditionsData.h" + +using namespace std; +using namespace DD4hep; + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the AIDA detector description toolkit supporting XML utilities + namespace DDDB { + + /// DDDB Conditions data dumper. + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class ConditionPrinter : public Conditions::Condition::Processor { + public: + + /// DDDB Conditions data dumper helper to output parameter maps. + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class ParamPrinter { + protected: + /// Printout prefix + std::string& m_prefix; + public: + + /// Initializing constructor + ParamPrinter(std::string& prefix); + /// Default destructor + virtual ~ParamPrinter() {} + + /// Set prefix for prinouts + void setPrefix(const std::string& value) { m_prefix = value; } + /// Access prefix value + const std::string& prefix() const { return m_prefix; } + /// Callback to output conditions information + virtual void operator()(const Conditions::AbstractMap::Params::value_type& obj) const; + }; + + protected: + std::string m_prefix; + ParamPrinter* m_print; + int m_flag; + + public: + typedef Conditions::Condition Cond; + + /// Initializing constructor + ConditionPrinter(const std::string& prefix="", + int flag=Cond::NO_NAME|Cond::WITH_IOV|Cond::WITH_ADDRESS, + ParamPrinter* prt=0); + /// Set prefix for prinouts + void setPrefix(const std::string& value) { m_prefix = value; } + /// Callback to output conditions information + virtual int operator()(Cond cond); + }; + + } /* End namespace DDDB */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_DDDB_DDDBCONDITIONPRINTER_H */ diff --git a/DDDB/include/DDDB/DDDBConditionsLoader.h b/DDDB/include/DDDB/DDDBConditionsLoader.h index 943227cf6dd0b80517a549f467f02f13a19a3a07..854eb7a25fbbb1a8f97cf87093df9a21387a3752 100644 --- a/DDDB/include/DDDB/DDDBConditionsLoader.h +++ b/DDDB/include/DDDB/DDDBConditionsLoader.h @@ -33,30 +33,55 @@ namespace DD4hep { * \ingroup DD4HEP_CONDITIONS */ class DDDBConditionsLoader - : public Conditions::ConditionsDataLoader, public Conditions::ConditionsListener + : public Conditions::ConditionsDataLoader, + public Conditions::ConditionsListener { + typedef Conditions::Condition Condition; + typedef Conditions::RangeConditions RangeConditions; + typedef Conditions::ConditionsManager ConditionsManager; + typedef std::pair<std::string, std::string> Key; + typedef std::map<Condition::key_type, Key> KeyMap; + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class KeyCollector : public Conditions::ConditionsListener { + public: + std::pair<ConditionsListener*,void*> call; + KeyMap keys; + /// Initializing constructor + KeyCollector(); + /// ConditionsListener overload: onRegister new condition + virtual void onRegisterCondition(Conditions::Condition cond, void* param); + }; XML::UriReader* m_resolver; + KeyCollector m_keys; + + /// Load single conditions document + void loadDocument(XML::UriContextReader& rdr, const Key& k); + /// Load single conditions document + void loadDocument(XML::UriContextReader& rdr, + const std::string& sys_id, + const std::string& obj_id); public: /// Default constructor - DDDBConditionsLoader(Geometry::LCDD& lcdd, Conditions::ConditionsManager mgr, const std::string& nam); + DDDBConditionsLoader(Geometry::LCDD& lcdd, ConditionsManager mgr, const std::string& nam); /// Default destructor virtual ~DDDBConditionsLoader(); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load(Geometry::DetElement det, - const std::string& cond, - const Conditions::IOV& req_validity, - Conditions::RangeConditions& conditions); + virtual size_t load(key_type key, + const iov_type& req_validity, + RangeConditions& conditions); /// Load a condition set given a Detector Element and the conditions name according to their validity - virtual size_t load_range(Geometry::DetElement det, - const std::string& cond, - const Conditions::IOV& req_validity, - Conditions::RangeConditions& conditions); + virtual size_t load_range(key_type key, + const iov_type& req_validity, + RangeConditions& conditions); /// Update a range of conditions according to the required IOV - virtual size_t update(const Conditions::IOV& req_validity, - Conditions::RangeConditions& conditions, - Conditions::IOV& iov_intersection); - + virtual size_t update(const iov_type& req_validity, + RangeConditions& conditions, + iov_type& conditions_validity); /// ConditionsListener overload: onRegister new condition virtual void onRegisterCondition(Conditions::Condition cond, void* param); diff --git a/DDDB/include/DDDB/DDDBConversion.h b/DDDB/include/DDDB/DDDBConversion.h index b99b2bf11be85a4db7fc42c86d8d1f316e8f99c0..edcdb316e9e5c797eb9b09fb95a2260db4b71e85 100644 --- a/DDDB/include/DDDB/DDDBConversion.h +++ b/DDDB/include/DDDB/DDDBConversion.h @@ -22,7 +22,7 @@ /// Framework include files #include "DD4hep/Objects.h" -#include "DD4hep/objects/ConditionsInterna.h" +#include "DD4hep/ConditionsData.h" #include "DDDB/DDDBReaderContext.h" /// C/C++ include files @@ -37,11 +37,13 @@ namespace DD4hep { namespace DDDB { /// Forward declarations - struct Shape; - struct LogVol; - struct Catalog; - struct Document; + class Shape; + class LogVol; + class Catalog; + class TabProperty; + class Document; + using Geometry::DetElement; using Geometry::VisAttr; using Geometry::Position; using Geometry::RotationZYX; @@ -51,7 +53,8 @@ namespace DD4hep { /// Basic named object /** \ingroup DD4HEP_DDDB */ - struct Named { + class Named : public Conditions::ClientData { + public: typedef std::map<std::string, std::string> StringMap; typedef std::map<std::string, std::pair<std::string,std::string > > StringPairMap; std::string name, id; @@ -79,7 +82,8 @@ namespace DD4hep { /// Structure supporting basic XML document information /** \ingroup DD4HEP_DDDB */ - struct Document : public Named { + class Document : public Named { + public: DDDBReaderContext context; /// Default constructor Document(); @@ -92,21 +96,24 @@ namespace DD4hep { /// Intermediate structure representing author's data /** \ingroup DD4HEP_DDDB */ - struct Author : public Named { + class Author : public Named { + public: Author() : Named() {} }; /// Intermediate structure representing versioning data /** \ingroup DD4HEP_DDDB */ - struct Version : Named { + class Version : Named { + public: Version() : Named() {} }; /// Intermediate structure representing data of one atom /** \ingroup DD4HEP_DDDB */ - struct Atom { + class Atom { + public: double A, Zeff; Atom() : A(0), Zeff(0) {} }; @@ -114,7 +121,8 @@ namespace DD4hep { /// Intermediate structure representing data of a Isotope /** \ingroup DD4HEP_DDDB */ - struct Isotope : public Named { + class Isotope : public Named { + public: double A,Z,density; /// Default constructor Isotope(); @@ -127,11 +135,12 @@ namespace DD4hep { /// Intermediate structure representing data of a Element /** \ingroup DD4HEP_DDDB */ - struct Element : public Named { + class Element : public Named { + public: enum {SOLID,LIQUID,GAS,UNKNOWN}; std::vector<std::pair<std::string,double> > isotopes; std::string path, symbol; - struct Atom atom; + class Atom atom; double density, ionization; int state; @@ -148,7 +157,8 @@ namespace DD4hep { /// Intermediate structure representing data of a material component /** \ingroup DD4HEP_DDDB */ - struct MaterialComponent { + class MaterialComponent { + public: std::string name; double fractionmass; int natoms; @@ -166,7 +176,8 @@ namespace DD4hep { /// Intermediate structure representing data of a material definition /** \ingroup DD4HEP_DDDB */ - struct Material : public Named { + class Material : public Named { + public: typedef std::vector<MaterialComponent> Components; typedef std::vector<std::string> Properties; std::string path; @@ -184,7 +195,8 @@ namespace DD4hep { /// Structure supporting conversion of the Box shape /** \ingroup DD4HEP_DDDB */ - struct Box { + class Box { + public: static int type() { return 100; } double x,y,z; double dot2() const { return x*x + y*y + z*z; } @@ -193,7 +205,8 @@ namespace DD4hep { /// Structure supporting conversion of the Cons shape /** \ingroup DD4HEP_DDDB */ - struct Cons { + class Cons { + public: static int type() { return 102; } double innerRadiusMZ, innerRadiusPZ, outerRadiusMZ, outerRadiusPZ, sizeZ; }; @@ -201,7 +214,8 @@ namespace DD4hep { /// Structure supporting conversion of the ConsSegment shape /** \ingroup DD4HEP_DDDB */ - struct ConeSegment { + class ConeSegment { + public: static int type() { return 103; } double start, delta; double innerRadiusMZ, innerRadiusPZ, outerRadiusMZ, outerRadiusPZ, sizeZ; @@ -210,7 +224,8 @@ namespace DD4hep { /// Structure supporting conversion of the Tubs shape /** \ingroup DD4HEP_DDDB */ - struct Tubs { + class Tubs { + public: static int type() { return 104; } double innerRadius, outerRadius, sizeZ, start, delta; }; @@ -218,7 +233,8 @@ namespace DD4hep { /// Structure supporting conversion of the elliptical tube shape /** \ingroup DD4HEP_DDDB */ - struct EllipticalTube { + class EllipticalTube { + public: static int type() { return 105; } double a, b, dz; }; @@ -226,7 +242,8 @@ namespace DD4hep { /// Structure supporting conversion of a z-plane /** \ingroup DD4HEP_DDDB */ - struct ZPlane { + class ZPlane { + public: static int type() { return 106; } double innerRadius, outerRadius, z; }; @@ -234,7 +251,8 @@ namespace DD4hep { /// Structure supporting conversion of the Polycone shape /** \ingroup DD4HEP_DDDB */ - struct Polycone { + class Polycone { + public: static int type() { return 107; } double start, delta; }; @@ -242,7 +260,8 @@ namespace DD4hep { /// Structure supporting conversion of the Polycone shape /** \ingroup DD4HEP_DDDB */ - struct Polygon { + class Polygon { + public: static int type() { return 108; } double nsides, start, innerRadius, outerRadius, z; }; @@ -250,7 +269,8 @@ namespace DD4hep { /// Structure supporting conversion of the torus /** \ingroup DD4HEP_DDDB */ - struct Torus { + class Torus { + public: static int type() { return 109; } double rmin, rmax, r, phi, dphi; }; @@ -258,7 +278,8 @@ namespace DD4hep { /// Structure supporting conversion of the Sphere /** \ingroup DD4HEP_DDDB */ - struct Sphere { + class Sphere { + public: static int type() { return 110; } double rmin, rmax, theta, delta_theta, phi, delta_phi; }; @@ -266,7 +287,8 @@ namespace DD4hep { /// Structure supporting conversion of the Ellipsoid /** \ingroup DD4HEP_DDDB */ - struct Ellipsoid { + class Ellipsoid { + public: static int type() { return 111; } double rlow, rhigh, dz; }; @@ -274,7 +296,8 @@ namespace DD4hep { /// Structure supporting conversion of the Trap /** \ingroup DD4HEP_DDDB */ - struct Trap { + class Trap { + public: static int type() { return 112; } double dz, phi, theta, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2; }; @@ -282,7 +305,8 @@ namespace DD4hep { /// Structure supporting conversion of the Paraboloid /** \ingroup DD4HEP_DDDB */ - struct Paraboloid { + class Paraboloid { + public: static int type() { return 113; } double rlow, rhigh, dz; }; @@ -290,7 +314,8 @@ namespace DD4hep { /// Structure supporting conversion of the Paraboloid /** \ingroup DD4HEP_DDDB */ - struct Hyperboloid { + class Hyperboloid { + public: static int type() { return 114; } double rmin, rmax, stIn, stOut, dz; }; @@ -298,7 +323,8 @@ namespace DD4hep { /// Structure supporting conversion of the TRD /** \ingroup DD4HEP_DDDB */ - struct TRD { + class TRD { + public: static int type() { return 115; } double x1, x2, y1, y2, z; }; @@ -306,43 +332,49 @@ namespace DD4hep { /// Structure supporting conversion of the Assembly /** \ingroup DD4HEP_DDDB */ - struct Assembly { + class Assembly { + public: static int type() { return 199; } }; /// Structure supporting boolean shapes /** \ingroup DD4HEP_DDDB */ - struct BooleanShape { - struct Shape* first; + class BooleanShape { + public: + class Shape* first; }; /// Structure supporting conversion of boolean unions /** \ingroup DD4HEP_DDDB */ - struct BooleanUnion : public BooleanShape { + class BooleanUnion : public BooleanShape { + public: static int type() { return 206; } }; /// Structure supporting conversion of boolean subtractions /** \ingroup DD4HEP_DDDB */ - struct BooleanSubtraction : public BooleanShape { + class BooleanSubtraction : public BooleanShape { + public: static int type() { return 207; } }; /// Structure supporting conversion of boolean intersections /** \ingroup DD4HEP_DDDB */ - struct BooleanIntersection : public BooleanShape { + class BooleanIntersection : public BooleanShape { + public: static int type() { return 208; } }; /// Structure supporting conversion of boolean operations /** \ingroup DD4HEP_DDDB */ - struct BooleanOperation { - struct Shape* shape; + class BooleanOperation { + public: + class Shape* shape; Transform3D trafo; BooleanOperation() : shape(0) {} }; @@ -351,7 +383,8 @@ namespace DD4hep { /// Structure supporting conversion of a physical volume /** \ingroup DD4HEP_DDDB */ - struct PhysVol : public Named { + class PhysVol : public Named { + public: enum { PHYSVOL_REGULAR=1, PHYSVOL_PARAM1D=2, PHYSVOL_PARAM2D=3, @@ -383,7 +416,8 @@ namespace DD4hep { /// Structure supporting conversion of parametrized physical volumes /** \ingroup DD4HEP_DDDB */ - struct ParamPhysVol : public PhysVol { + class ParamPhysVol : public PhysVol { + public: int number1; Transform3D trafo1; /// Default constructor @@ -403,7 +437,8 @@ namespace DD4hep { /// Structure supporting conversion of 2D parametrized physical volumes /** \ingroup DD4HEP_DDDB */ - struct ParamPhysVol2D : public ParamPhysVol { + class ParamPhysVol2D : public ParamPhysVol { + public: int number2; Transform3D trafo2; /// Default constructor @@ -413,7 +448,8 @@ namespace DD4hep { /// Structure supporting conversion of 3D parametrized physical volumes /** \ingroup DD4HEP_DDDB */ - struct ParamPhysVol3D : public ParamPhysVol2D { + class ParamPhysVol3D : public ParamPhysVol2D { + public: int number3; Transform3D trafo3; /// Default constructor @@ -423,7 +459,8 @@ namespace DD4hep { /// Structure supporting conversion of a logical volume /** \ingroup DD4HEP_DDDB */ - struct LogVol : public Named { + class LogVol : public Named { + public: std::string material, shape, path; std::vector<PhysVol*> physvols; /// Default constructor @@ -437,19 +474,23 @@ namespace DD4hep { /// Structure supporting conversion of a detector element or a catalog /** \ingroup DD4HEP_DDDB */ - struct Catalog : public Named { - typedef std::map<std::string, Catalog*> CatRefs; - typedef std::map<std::string, LogVol*> LvRefs; + class Catalog : public Named { + public: + typedef std::map<std::string, Catalog*> CatRefs; + typedef std::map<std::string, LogVol*> LvRefs; + typedef std::map<std::string, TabProperty*> PropRefs; LvRefs logvolrefs; LvRefs logvols; CatRefs catalogrefs; CatRefs catalogs; + PropRefs tabpropertyrefs; StringPairMap params; StringMap conditioninfo; std::string type, path, author, version, logvol, condition, support, npath; int level, typeID; /// Default constructor Catalog(); + Catalog(const Catalog&, const DetElement&) {} /// Default destructor virtual ~Catalog(); /// Reference count mechanism @@ -460,31 +501,32 @@ namespace DD4hep { /// Structure supporting conversion of any arbitrary shape /** \ingroup DD4HEP_DDDB */ - struct Shape : public Named { + class Shape : public Named { + public: typedef std::vector<ZPlane> ZPlanes; typedef std::vector<BooleanOperation> Operations; typedef std::vector<ParamPhysVol> ParamVolumes; int type; union { - struct Assembly assembly; - struct Box box; - struct Cons cons; - struct Tubs tubs; - struct Polycone polycone; - struct ConeSegment coneSegment; - struct EllipticalTube ellipticalTube; - struct Polygon polygon; - struct Torus torus; - struct Sphere sphere; - struct Ellipsoid ellipsoid; - struct Paraboloid paraboloid; - struct Hyperboloid hyperboloid; - struct TRD trd; - struct Trap trap; - struct BooleanShape boolean; - struct BooleanUnion boolean_union; - struct BooleanSubtraction BooleanSubtraction; - struct BooleanIntersection boolean_intersection; + class Assembly assembly; + class Box box; + class Cons cons; + class Tubs tubs; + class Polycone polycone; + class ConeSegment coneSegment; + class EllipticalTube ellipticalTube; + class Polygon polygon; + class Torus torus; + class Sphere sphere; + class Ellipsoid ellipsoid; + class Paraboloid paraboloid; + class Hyperboloid hyperboloid; + class TRD trd; + class Trap trap; + class BooleanShape boolean; + class BooleanUnion boolean_union; + class BooleanSubtraction BooleanSubtraction; + class BooleanIntersection boolean_intersection; } s; ZPlanes zplanes; Operations boolean_ops; @@ -498,6 +540,26 @@ namespace DD4hep { Shape* addRef() { ++refCount; return this; } }; + /// Tabulated property + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class TabProperty : public Named { + public: + typedef std::pair<double, double> Entry; + std::string path, type, xunit, yunit, xaxis, yaxis; + std::vector<Entry> data; + /// Default constructor + TabProperty(); + /// Default destructor + ~TabProperty(); + /// Reference count mechanism + TabProperty* addRef() { ++refCount; return this; } + }; + /// LHCb geometry description interface to the conditions database /** * \author M.Frank @@ -505,17 +567,19 @@ namespace DD4hep { * \date 31/03/2016 * \ingroup DD4HEP_DDDB */ - struct dddb { + class dddb { + public: typedef std::pair<long long int, long long int> iov_t; - typedef std::map<std::string,std::string> Refs; - typedef std::map<std::string,Document*> Documents; - typedef std::map<std::string,LogVol*> Volumes; - typedef std::map<std::string,PhysVol*> Placements; - typedef std::map<std::string,Catalog*> Catalogs; - typedef std::map<std::string,Isotope*> Isotopes; - typedef std::map<std::string,Element*> Elements; - typedef std::map<std::string,Material*> Materials; - typedef std::map<std::string,Shape*> Shapes; + typedef std::map<std::string,std::string> Refs; + typedef std::map<std::string,Document*> Documents; + typedef std::map<std::string,LogVol*> Volumes; + typedef std::map<std::string,PhysVol*> Placements; + typedef std::map<std::string,Catalog*> Catalogs; + typedef std::map<std::string,Isotope*> Isotopes; + typedef std::map<std::string,Element*> Elements; + typedef std::map<std::string,Material*> Materials; + typedef std::map<std::string,Shape*> Shapes; + typedef std::map<std::string,TabProperty*> TabProperties; typedef std::map<std::string,Conditions::Condition::Object*> Conditions; /// Default constructor @@ -539,6 +603,8 @@ namespace DD4hep { Volumes volumes, volumePaths; /// Inventory of volume placements Placements placements, placementPaths; + /// Inventory of tabulated properties + TabProperties tabproperties, tabpropertyPaths; /// Inventory of conditions Conditions conditions, conditionPaths; /// Inventory of catalogs @@ -546,9 +612,10 @@ namespace DD4hep { /// Detector element hierarchy Catalog *top, *structure, *geometry; }; - struct dddb_conditions {}; + class dddb_conditions {}; - template <typename T> struct Increment { + template <typename T> class Increment { + public: static int& counter() { static int cnt=0; return cnt; } Increment() { ++counter(); } ~Increment() { --counter(); } diff --git a/DDDB/include/DDDB/DDDBDimension.h b/DDDB/include/DDDB/DDDBDimension.h index d463a7f0f95a2999481aea890682c8f1d7be4b2d..5c665c198496afc073374eb622754eab1d160126 100644 --- a/DDDB/include/DDDB/DDDBDimension.h +++ b/DDDB/include/DDDB/DDDBDimension.h @@ -142,6 +142,12 @@ namespace DD4hep { std::string symbol() const; std::string symbol(std::string default_value) const; std::string logvol() const; + std::string xunit() const; + std::string xaxis() const; + std::string yunit() const; + std::string yaxis() const; + std::string zunit() const; + std::string zaxis() const; }; } /* End namespace DDDB */ } /* End namespace DD4hep */ diff --git a/DDDB/include/DDDB/DDDBHelper.h b/DDDB/include/DDDB/DDDBHelper.h index c98218be97b50da5455de7668ded0af165a2bba0..3785dd4e6713932d8798a755a19989559393563b 100644 --- a/DDDB/include/DDDB/DDDBHelper.h +++ b/DDDB/include/DDDB/DDDBHelper.h @@ -27,6 +27,7 @@ #include "DD4hep/Printout.h" #include "DD4hep/Plugins.h" #include "DD4hep/Objects.h" +#include "DD4hep/Conditions.h" #include "XML/DocumentHandler.h" #include "XML/Utilities.h" diff --git a/DDDB/include/DDDB/DDDBTags.h b/DDDB/include/DDDB/DDDBTags.h index 7445ab9ac037e8cd652a52e2e792155f415e9a2a..380451961a47957b140c49503488af80afae3e3b 100644 --- a/DDDB/include/DDDB/DDDBTags.h +++ b/DDDB/include/DDDB/DDDBTags.h @@ -37,6 +37,7 @@ namespace DD4hep { UNICODE(address); UNICODE(alp1); UNICODE(alp2); + UNICODE(author); UNICODE(catalog); UNICODE(catalogref); @@ -86,6 +87,13 @@ namespace DD4hep { UNICODE(number3); + UNICODE(outerRadius); + UNICODE(outerRadiusMZ); + UNICODE(outerRadiusPZ); + + UNICODE(paramphysvol); + UNICODE(paramphysvol2D); + UNICODE(phiAngle); UNICODE(paramVector); UNICODE(posXYZ); @@ -95,25 +103,6 @@ namespace DD4hep { UNICODE(rotY); UNICODE(rotZ); - UNICODE(symbol); - UNICODE(state); - UNICODE(support); - - - UNICODE(tubs); - UNICODE(transformation); - UNICODE(version); - UNICODE(author); - - - UNICODE(outerRadius); - UNICODE(outerRadiusMZ); - UNICODE(outerRadiusPZ); - - UNICODE(paramphysvol); - UNICODE(paramphysvol2D); - UNICODE(phiAngle); - UNICODE(sizeX); UNICODE(sizeX1); UNICODE(sizeX2); @@ -126,21 +115,38 @@ namespace DD4hep { UNICODE(specific); UNICODE(startPhiAngle); UNICODE(startThetaAngle); + UNICODE(state); + UNICODE(support); + UNICODE(symbol); + UNICODE(tabprops); + UNICODE(tabproperty); + UNICODE(tabpropertyref); UNICODE(thetaAngle); + UNICODE(transformation); + UNICODE(tubs); UNICODE(userParameter); UNICODE(val); UNICODE(value); UNICODE(valuetype); + UNICODE(version); UNICODE(volumes); UNICODE(vismapping); UNICODE(x); + UNICODE(xaxis); + UNICODE(xunit); + UNICODE(y); + UNICODE(yaxis); + UNICODE(yunit); + UNICODE(z); + UNICODE(zaxis); + UNICODE(zunit); //UNICODE(); } /* End namespace DDDB */ diff --git a/DDDB/src/AlignmentCondition.cpp b/DDDB/src/AlignmentCondition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7385ab374d4e6a12f08d4f13abe7f469e6314a7 --- /dev/null +++ b/DDDB/src/AlignmentCondition.cpp @@ -0,0 +1,140 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework includes +#include "DD4hep/DetectorTools.h" +//#include "DDCond/AlignmentCondition.h" +#include "AlignmentCondition.h" + +// C/C++ include files +#include <iostream> +#include <stdexcept> + +using namespace DD4hep::Conditions; +using DD4hep::Geometry::DetectorTools::ElementPath; +using DD4hep::Geometry::DetectorTools::PlacementPath; + +/// Standard constructor +AlignmentConditionData::AlignmentConditionData() + : flag(0), magic(magic_word()) +{ +} + +/// Default destructor +AlignmentConditionData::~AlignmentConditionData() { +} + +/// Create cached matrix to transform to world coordinates +const TGeoHMatrix& AlignmentConditionData::worldTransformation() const { + if ( (flag&HAVE_WORLD_TRAFO) == 0 ) { + PlacementPath nodes; + flag |= HAVE_WORLD_TRAFO; + //Geometry::DetectorTools::placementPath(condition->detector, nodes); + //Geometry::DetectorTools::placementTrafo(nodes,false,worldTrafo); + throw std::runtime_error("not implemented"); + } + return worldTrafo; +} + +/// Create cached matrix to transform to parent coordinates +const TGeoHMatrix& AlignmentConditionData::parentTransformation() const { + if ( (flag&HAVE_PARENT_TRAFO) == 0 ) { + PlacementPath nodes; + DetElement det;// = condition->detector; + flag |= HAVE_PARENT_TRAFO; + Geometry::DetectorTools::placementPath(det.parent(), det, nodes); + Geometry::DetectorTools::placementTrafo(nodes,false,parentTrafo); + } + return parentTrafo; +} + +/// Default constructor +AlignmentCondition::AlignmentCondition() : Condition() { +} + +/// Copy constructor +AlignmentCondition::AlignmentCondition(const Condition& c) : Condition(c) { +} + +/// Copy constructor +AlignmentCondition::AlignmentCondition(const AlignmentCondition& c) : Condition(c) { +} + +/// Initializing constructor +AlignmentCondition::AlignmentCondition(Object* p) : Condition(p) { +} + +/// Assignment operator +AlignmentCondition& AlignmentCondition::operator=(const AlignmentCondition& c) { + if ( this != &c ) this->m_element = c.m_element; + return *this; +} + +/// Create cached matrix to transform to world coordinates +const TGeoHMatrix& AlignmentCondition::worldTransformation() const { + return get<AlignmentConditionData>().worldTransformation(); +} + +/// Create cached matrix to transform to parent coordinates +const TGeoHMatrix& AlignmentCondition::parentTransformation() const { + return get<AlignmentConditionData>().parentTransformation(); +} + +/// Transformation from local coordinates of the placed volume to the world system +bool AlignmentCondition::localToWorld(const Position& local, Position& global) const { + Double_t master_point[3] = { 0, 0, 0 }, local_point[3] = { local.X(), local.Y(), local.Z() }; + // If the path is unknown an exception will be thrown inside worldTransformation() ! + worldTransformation().LocalToMaster(local_point, master_point); + global.SetCoordinates(master_point); + return true; +} + +/// Transformation from local coordinates of the placed volume to the parent system +bool AlignmentCondition::localToParent(const Position& local, Position& parent) const { + // If the path is unknown an exception will be thrown inside parentTransformation() ! + Double_t master_point[3] = { 0, 0, 0 }, local_point[3] = { local.X(), local.Y(), local.Z() }; + parentTransformation().LocalToMaster(local_point, master_point); + parent.SetCoordinates(master_point); + return true; +} + +/// Transformation from world coordinates of the local placed volume coordinates +bool AlignmentCondition::worldToLocal(const Position& global, Position& local) const { + // If the path is unknown an exception will be thrown inside worldTransformation() ! + Double_t master_point[3] = { global.X(), global.Y(), global.Z() }, local_point[3] = { 0, 0, 0 }; + worldTransformation().MasterToLocal(master_point, local_point); + local.SetCoordinates(local_point); + return true; +} + +/// Transformation from world coordinates of the local placed volume coordinates +bool AlignmentCondition::parentToLocal(const Position& parent, Position& local) const { + // If the path is unknown an exception will be thrown inside parentTransformation() ! + Double_t master_point[3] = { parent.X(), parent.Y(), parent.Z() }, local_point[3] = { 0, 0, 0 }; + parentTransformation().MasterToLocal(master_point, local_point); + local.SetCoordinates(local_point); + return true; +} + +std::ostream& operator<<(std::ostream& s, const AlignmentConditionData&) { + return s; +} + +#include "DD4hep/ToStream.h" +#include "DD4hep/objects/ConditionsInterna.h" +DD4HEP_DEFINE_CONDITIONS_TYPE_DUMMY(AlignmentConditionData) + +#include "DD4hep/objects/BasicGrammar_inl.h" +DD4HEP_DEFINE_PARSER_GRAMMAR(AlignmentConditionData,eval_none<AlignmentConditionData>) + diff --git a/DDDB/src/AlignmentCondition.h b/DDDB/src/AlignmentCondition.h new file mode 100644 index 0000000000000000000000000000000000000000..83ad2b4c52566b3cca833f2e09dd81431abf84eb --- /dev/null +++ b/DDDB/src/AlignmentCondition.h @@ -0,0 +1,131 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_GEOMETRY_ALIGNMENTCONDITION_H +#define DD4HEP_GEOMETRY_ALIGNMENTCONDITION_H + +// Framework include files +#include "DD4hep/ConditionsData.h" +#include "DD4hep/ConditionDerived.h" + +// ROOT include files +#include "TGeoMatrix.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + + /// Derived condition data-object definition + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentConditionData { + public: + typedef Geometry::PlacedVolume PlacedVolume; + typedef Geometry::DetElement DetElement; + typedef Geometry::Position Position; + typedef Geometry::Position Pivot; + typedef Geometry::RotationZYX Rotation; + + enum AlignmentFlags { + HAVE_NONE = 0, + HAVE_WORLD_TRAFO = 1<<0, + HAVE_PARENT_TRAFO = 1<<1, + HAVE_OTHER = 1<<31 + }; + + AlignmentDelta delta; + /// Intermediate buffer to store the transformation to the world coordination system + mutable TGeoHMatrix worldTrafo; + /// Intermediate buffer to store the transformation to the parent detector element + mutable TGeoHMatrix parentTrafo; + /// The subdetector placement corresponding to the actual detector element's volume + PlacedVolume placement; + /// Parent condition reference + Condition condition; + /// Flag to remember internally calculated quatities + mutable unsigned int flag; + /// Magic word to verify object if necessary + unsigned int magic; + + public: + /// Standard constructor + AlignmentConditionData(); + /// Default destructor + virtual ~AlignmentConditionData(); + /// Create cached matrix to transform to world coordinates + const TGeoHMatrix& worldTransformation() const; + /// Create cached matrix to transform to parent coordinates + const TGeoHMatrix& parentTransformation() const; + }; + + /// Class describing an alignment condition + /** + * The Alignment condition describes an alignment delta applied + * to a given volume. An instance contains all necessary + * alignment data and the corresponding transformations. + * + * Typically this object is derived condition ie. the raw conditions data + * are stored as a 'delta' and then get reformatted and re-computed + * in the derived quantity. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentCondition : public Condition { + public: + typedef Geometry::PlacedVolume PlacedVolume; + typedef Geometry::DetElement DetElement; + typedef Geometry::Position Position; + typedef Geometry::Position Pivot; + typedef Geometry::RotationZYX Rotation; + + public: + /// Default constructor + AlignmentCondition(); + /// Copy constructor + AlignmentCondition(const Condition& c); + /// Copy constructor + AlignmentCondition(const AlignmentCondition& c); + /// Initializing constructor + AlignmentCondition(Object* p); + /// Constructor to be used when reading the already parsed object + template <typename Q> AlignmentCondition(const Handle<Q>& e) + : Condition(e) { + } + /// Assignment operator + AlignmentCondition& operator=(const AlignmentCondition& c); + /// Create cached matrix to transform to world coordinates + const TGeoHMatrix& worldTransformation() const; + /// Create cached matrix to transform to parent coordinates + const TGeoHMatrix& parentTransformation() const; + + /// Transformation from local coordinates of the placed volume to the world system + bool localToWorld(const Position& local, Position& global) const; + /// Transformation from local coordinates of the placed volume to the parent system + bool localToParent(const Position& local, Position& parent) const; + + /// Transformation from world coordinates of the local placed volume coordinates + bool worldToLocal(const Position& global, Position& local) const; + /// Transformation from world coordinates of the local placed volume coordinates + bool parentToLocal(const Position& parent, Position& local) const; + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_GEOMETRY_ALIGNMENTCONDITION_H */ diff --git a/DDDB/src/CondDB2DDDB.cpp b/DDDB/src/CondDB2DDDB.cpp index a2faa266ea068e5a078441b88474d2551c0f2844..f2e8c7c54050798119c504d45779723ef84e34b7 100644 --- a/DDDB/src/CondDB2DDDB.cpp +++ b/DDDB/src/CondDB2DDDB.cpp @@ -23,7 +23,6 @@ #include "DDDB/DDDBDimension.h" #include "DDDB/DDDBHelper.h" #include "DDDB/DDDBConversion.h" -#include "DDDB/DDDBConditionData.h" // C/C++ include files #include "boost/filesystem/path.hpp" @@ -38,14 +37,19 @@ namespace DD4hep { /// Keep all in here anonymous. Does not have to be visible outside. namespace { - typedef Conditions::BlockData BlockData; - typedef Conditions::Condition Condition; - typedef DDDB::DDDBConditionData::Params ConditionParams; + static int preserv_level = 0; + using Conditions::BlockData; + using Conditions::Condition; + using Conditions::AbstractMap; + using Conditions::AlignmentDelta; + + typedef AbstractMap::Params ConditionParams; struct LogVolRef {}; struct ElementRef {}; struct MaterialRef {}; struct CatalogRef {}; struct ConditionRef {}; + struct TabPropertyRef {}; struct DetElemRef {}; struct ConditionInfo {}; @@ -94,12 +98,11 @@ namespace DD4hep { */ class Locals { public: - string doc_path, obj_path; + string obj_path; Document* xml_doc; - Locals() : doc_path(), obj_path(), xml_doc(0) {} - Locals(const Locals& c) : doc_path(c.doc_path), obj_path(c.obj_path), xml_doc(c.xml_doc) {} + Locals() : obj_path(), xml_doc(0) {} + Locals(const Locals& c) : obj_path(c.obj_path), xml_doc(c.xml_doc) {} Locals& operator=(const Locals& c) { - doc_path = c.doc_path; obj_path = c.obj_path; xml_doc = c.xml_doc; return *this; @@ -111,8 +114,23 @@ namespace DD4hep { class PreservedLocals : public Locals { public: Context* context; - PreservedLocals(Context* c) : Locals(c->locals), context(c) {} - ~PreservedLocals() { context->locals = *this; } + PreservedLocals(Context* c) : Locals(c->locals), context(c) { +#ifdef __DEBUG_LOCALS + if ( xml_doc ) + printout(INFO,"Locals","PUSH[%d]: %s [%s]", preserv_level++, obj_path.c_str(), xml_doc->id.c_str()); + else + printout(INFO,"Locals","PUSH[%d]: %s ", preserv_level++, obj_path.c_str()); +#endif + } + ~PreservedLocals() { +#ifdef __DEBUG_LOCALS + if ( xml_doc ) + printout(INFO,"Locals","POP [%d]: %s [%s]", --preserv_level, obj_path.c_str(), xml_doc->id.c_str()); + else + printout(INFO,"Locals","POP [%d]: %s", --preserv_level, obj_path.c_str()); +#endif + context->locals = *this; + } }; public: @@ -134,6 +152,7 @@ namespace DD4hep { bool print_condition_ref; bool print_catalog; bool print_catalog_ref; + bool print_tabprop; /// Default constructor Context(lcdd_t& l) @@ -151,7 +170,8 @@ namespace DD4hep { print_condition(false), print_condition_ref(false), print_catalog(false), - print_catalog_ref(false) + print_catalog_ref(false), + print_tabprop(false) { } /// Default destructor ~Context() { @@ -165,6 +185,7 @@ namespace DD4hep { void print(const PhysVol* obj) const { if ( print_physvol ) dddb_print(obj); } void print(const LogVol* obj) const { if ( print_logvol ) dddb_print(obj); } void print(const Catalog* obj) const { if ( print_catalog ) dddb_print(obj); } + void print(const TabProperty* obj) const { if ( print_tabprop ) dddb_print(obj); } void print(const Document* obj) const { if ( print_docs ) dddb_print(obj); } /** Data collection helpers for indexing by object identifier */ @@ -175,6 +196,7 @@ namespace DD4hep { void collect(const string& id, Isotope* obj) { collect_id(geo->isotopes, id, obj); } void collect(const string& id, Element* obj) { collect_id(geo->elements, id, obj); } void collect(const string& id, Material* obj) { collect_id(geo->materials, id, obj); } + void collect(const string& id, TabProperty* obj) { collect_id(geo->tabproperties, id, obj); } void collect(const string& id, Condition& object) { dddb::Conditions::const_iterator i=geo->conditions.find(id); if ( i != geo->conditions.end() ) { @@ -190,6 +212,7 @@ namespace DD4hep { void collectPath(const string& path, Material* obj) { collect_p(geo->materialPaths, path, obj); } void collectPath(const string& path, PhysVol* obj) { collect_p(geo->placementPaths, path, obj); } void collectPath(const string& path, LogVol* obj) { collect_p(geo->volumePaths, path, obj); } + void collectPath(const string& path, TabProperty* obj) { collect_p(geo->tabpropertyPaths, path, obj); } void collectPath(const string& path, Catalog* obj) { collect_p(geo->catalogPaths, path, obj); } void collectPath(const string& path, Condition& object) { dddb::Conditions::const_iterator i=geo->conditionPaths.find(path); @@ -280,6 +303,7 @@ namespace DD4hep { template <> void Conv<ParamPhysVol2D>::convert(xml_h element) const; template <> void Conv<ParamPhysVol3D>::convert(xml_h element) const; template <> void Conv<ConditionParam>::convert(xml_h element) const; + template <> void Conv<AlignmentDelta>::convert(xml_h element) const; void extract_transformation(lcdd_t& lcdd, void* context, xml_coll_t& collection, Transform3D& tr, int which=-1); void build_transformation(lcdd_t& lcdd, void* context, xml_h element, Transform3D& tr, int which=-1) { @@ -288,6 +312,21 @@ namespace DD4hep { } string reference_href(xml_h element, const string& ref); + xml_h find_local_element(xml_elt_t element, const string& ref, const xml_tag_t& tag) { + size_t hash = ref.find("#"); + if ( hash == 0 ) { + string name = ref.substr(1); + xml_h root = element.document().root(); + for(xml_coll_t coll(root,tag); coll; ++coll ) { + string entry = coll.attr<string>(_U(name)); + if ( entry == name ) { + return coll; + } + } + } + return xml_h(0); + } + string object_path(Context* context, const string& ref) { size_t hash = ref.rfind("#"); boost::filesystem::path path = hash==0 ? ref.substr(1) : ref; @@ -311,7 +350,7 @@ namespace DD4hep { size_t idq = ref.find("/"); boost::filesystem::path path = hash==0 ? ref.substr(1) : ref; if ( (idx == string::npos || idq < idx) && ref[0] != '/' ) { - path = context->locals.doc_path; + path = context->locals.xml_doc->id; if ( hash != 0 ) path = path.parent_path(); path /= ref.substr(0,hash); } @@ -640,63 +679,120 @@ namespace DD4hep { } } + /// Specialized conversion of <param/> and <paramVector> entities in alignments + template <> void Conv<AlignmentDelta>::convert(xml_h element) const { + string nam = element.attr<string>(_U(name)); + string data = element.text(); + AlignmentDelta* a = _option<AlignmentDelta>(); + string d = "("+data+" "; + size_t idx, idq; + + for(idx = d.find_first_not_of(' ',1); idx != string::npos;) { + if ( ::isspace(d[idx]) ) d[idx] = ' '; + idx = d.find_first_not_of(' ',++idx); + } + for(idx = d.find_first_not_of(' ',1); idx != string::npos; ++idx) { + if ( d[idx] != ' ' && ::isspace(d[idx]) ) d[idx] = ' '; + idq = d.find_first_of(' ',idx); + if ( idq != string::npos ) { + idx = d.find_first_not_of(' ',idq); + if ( idx == string::npos ) break; + if ( d[idx] != ' ' && ::isspace(d[idx]) ) d[idx] = ' '; + d[idq] = ','; + continue; + } + break; + } + d[d.length()-1] = ')'; + Geometry::Position pos; + const BasicGrammar& g = BasicGrammar::instance<Geometry::Position>(); + if ( !g.fromString(&pos,d) ) g.invalidConversion(d, g.type()); + if ( nam == "dPosXYZ" ) + a->position = pos; + else if ( nam == "dRotXYZ" ) + a->rotation = AlignmentDelta::Rotation(pos.z(),pos.y(),pos.x()); + else if ( nam == "pivotXYZ" ) + a->pivot = pos; + else + printout(ERROR,"AlignmentDelta","++ Unknown alignment conditions tag: %s",nam.c_str()); + } + /// Specialized conversion of <condition/> entities template <> void Conv<Condition>::convert(xml_h element) const { Context* context = _param<Context>(); - Catalog* catalog = _option<Catalog>(); - Document* doc = context->locals.xml_doc; string name = element.attr<string>(_U(name)); string id = object_href(element,name); - string path = object_path(context,name); - static int num_param = 0, num_vector = 0, num_map = 0, num_spec = 0; - - Condition cond(name,"DDDB"); - cond->address = id; - cond->value = doc->name; - cond->validity = ""; - cond->hash = hash32(cond->value); - if ( element.hasAttr(_U(comment)) ) { - cond->comment = element.attr<string>(_U(comment)); - } - - DDDBConditionData& d = cond.bind<DDDBConditionData>(); - d.document = doc->addRef(); - if ( element.hasAttr(_LBU(classID)) ) { - d.classID = element.attr<int>(_LBU(classID)); - } - Conv<ConditionParam> object_cnv(lcdd,context,&d.params); - xml_coll_t(element,_U(param)).for_each(object_cnv); + if ( !_find(id, context->geo->conditions) ) { + Catalog* catalog = _option<Catalog>(); + Document* doc = context->locals.xml_doc; + + string path = object_path(context,name); + static int num_param=0, num_vector=0, num_map=0, num_spec=0, num_align=0; + + Condition cond(path,"DDDB"); + cond->address = id; + cond->value = path; // doc->name; + cond->validity = ""; + cond->hash = Conditions::ConditionKey::hashCode(cond->value); + cond->setFlag(Condition::ACTIVE); + if ( element.hasAttr(_U(comment)) ) { + cond->comment = element.attr<string>(_U(comment)); + } - Conv<ConditionParamVector> vector_cnv(lcdd,context,&d.params); - xml_coll_t(element,_LBU(paramVector)).for_each(vector_cnv); + AbstractMap& d = cond.bind<AbstractMap>(); + d.clientData = doc->addRef(); + d.classID = -1; + if ( element.hasAttr(_LBU(classID)) ) { + d.classID = element.attr<int>(_LBU(classID)); + } + if ( d.classID == AbstractMap::ALIGNMENT ) { + pair<string,BlockData> block; + AlignmentDelta& align = block.second.bind<AlignmentDelta>(); + Conv<AlignmentDelta> conv(lcdd,context,&align); + block.first = name; + xml_coll_t(element,_LBU(paramVector)).for_each(conv); + pair<ConditionParams::iterator,bool> res = d.params.insert(block); + if ( !res.second ) { + printout(INFO,"ParamVector","++ Failed to insert condition parameter:%s",name.c_str()); + } + ++num_align; + } + else { + Conv<ConditionParam> object_cnv(lcdd,context,&d.params); + xml_coll_t(element,_U(param)).for_each(object_cnv); - Conv<ConditionParamMap> map_cnv(lcdd,context,&d.params); - xml_coll_t(element,_LBU(map)).for_each(map_cnv); + Conv<ConditionParamVector> vector_cnv(lcdd,context,&d.params); + xml_coll_t(element,_LBU(paramVector)).for_each(vector_cnv); - Conv<ConditionParamSpecific> specific_cnv(lcdd,context,&d.params); - xml_coll_t(element,_LBU(specific)).for_each(specific_cnv); + Conv<ConditionParamMap> map_cnv(lcdd,context,&d.params); + xml_coll_t(element,_LBU(map)).for_each(map_cnv); - for(xml_coll_t iter(element,_U(star)); iter; ++iter) { - string tag = iter.tag(); - string nam = iter.hasAttr(_U(name)) ? iter.attr<string>(_U(name)) : string(); - if ( context->print_condition ) { - printout(INFO,"ParamMap","++ Condition:%s -> %s",path.c_str(),nam.c_str()); + Conv<ConditionParamSpecific> specific_cnv(lcdd,context,&d.params); + xml_coll_t(element,_LBU(specific)).for_each(specific_cnv); + } + for(xml_coll_t iter(element,_U(star)); iter; ++iter) { + string tag = iter.tag(); + string nam = iter.hasAttr(_U(name)) ? iter.attr<string>(_U(name)) : string(); + if ( context->print_condition ) { + printout(INFO,"ParamMap","++ Condition:%s -> %s",path.c_str(),nam.c_str()); + } + if ( d.classID == AbstractMap::ALIGNMENT ) { continue; } + if ( tag == "param" ) { ++num_param; continue; } + if ( tag == "paramVector" ) { ++num_vector; continue; } + if ( tag == "map" ) { ++num_map; continue; } + if ( tag == "specific" ) { ++num_spec; continue; } + printout(INFO,"Condition","++ Unknown conditions tag:%s obj:%s id:%s", + tag.c_str(), path.c_str(), id.c_str()); + } + context->collect(id, cond); + if ( catalog ) { + context->collectPath(path, cond); + } + num_param += int(d.params.size()); + if ( (context->geo->conditions.size()%500) == 0 ) { + printout(INFO,"Condition","++ Processed %d conditions....last:%s Number of Params: %d Vec:%d Map:%d Spec:%d Align:%d", + int(context->geo->conditions.size()), path.c_str(), num_param, num_vector, num_map, num_spec, num_align); } - if ( tag == "param" ) { ++num_param; continue; } - if ( tag == "paramVector" ) { ++num_vector; continue; } - if ( tag == "map" ) { ++num_map; continue; } - if ( tag == "specific" ) { ++num_spec; continue; } - printout(INFO,"Condition","++ Unknown conditions tag:%s obj:%s id:%s", - tag.c_str(), path.c_str(), id.c_str()); - } - context->collect(id, cond); - if ( catalog ) { - context->collectPath(path, cond); - } - num_param += int(d.params.size()); - if ( (context->geo->conditions.size()%500) == 0 ) { - printout(INFO,"Condition","++ Processed %d conditions....last:%s Number of Params: %d Vec:%d Map:%d Spec:%d", - int(context->geo->conditions.size()), path.c_str(), num_param, num_vector, num_map, num_spec); } } @@ -708,10 +804,14 @@ namespace DD4hep { string refid = reference_href(element,href); string path; - load_dddb_entity(context, catalog, element, href); + xml_h target = find_local_element(element, href, _LBU(condition)); + if ( target ) + Conv<Condition>(lcdd,context,catalog)(target); + else + load_dddb_entity(context, catalog, element, href); dddb::Conditions::const_iterator i=context->geo->conditions.find(refid); if ( i == context->geo->conditions.end() ) { - printout(ERROR,"ConditionRef","++ MISSING ID: %s Failed to convert ref:%s cat:%s", + printout(ERROR,"ConditionRef","++ MISSING ID: %s Failed to convert ref:%s cat:%s", refid.c_str(),path.c_str(), catalog ? catalog->path.c_str() : "???"); if ( context->print_condition_ref ) { print_ref("ConditionRef", context, element, href, "Path:----"); @@ -722,7 +822,7 @@ namespace DD4hep { path = object_path(context,cond->name); context->collectPath(path, cond); if ( context->print_condition_ref ) { - print_ref("ConditionRef", context, element, href, "Path:"+path); + print_ref("ConditionRef", context, element, href, "Path:"+path); } } @@ -762,12 +862,12 @@ namespace DD4hep { string name = x_i.nameStr(); string id = object_path(context,name); if ( !_find(id, context->geo->isotopes) ) { - Isotope* i = new Isotope(); - i->name = name; - i->A = x_i.A(-1.0); - i->Z = x_i.Z(-1.0); - i->density = x_i.density(-1.0); - context->collect(id, i); + Isotope* i = new Isotope(); + i->name = name; + i->A = x_i.A(-1.0); + i->Z = x_i.Z(-1.0); + i->density = x_i.density(-1.0); + context->collect(id, i); i->setDocument(context->locals.xml_doc); } } @@ -781,7 +881,7 @@ namespace DD4hep { load_dddb_entity(context, catalog, element, href); dddb::Elements::const_iterator i=context->geo->elements.find(refid); if ( i == context->geo->elements.end() ) { - printout(ERROR,"ElementRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); + printout(ERROR,"ElementRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); } Element* e = (*i).second; string path = object_path(context,e->name); @@ -795,30 +895,30 @@ namespace DD4hep { string name = x_elem.nameStr(); string id = object_href(element, name); if ( !_find(id, context->geo->elements) ) { - Element* e = new Element(); - dddb_dim_t atom = x_elem.child(_U(atom),false); - e->id = id; - e->name = name; - e->path = object_path(context,name); - e->density = x_elem.density(-1.0); - e->ionization = x_elem.I(-1.0); - e->symbol = x_elem.symbol(e->name); - e->atom.A = atom ? atom.attr<double>(_U(A)) : -1.0; - e->atom.Zeff = atom ? atom.attr<double>(_U(Zeff)) : -1.0; - string st = x_elem.state(); - if ( st == "solid" ) e->state = Element::SOLID; - else if ( st == "liquid" ) e->state = Element::LIQUID; - else if ( st == "gas" ) e->state = Element::GAS; - else e->state = Element::UNKNOWN; - - for(xml_coll_t p(x_elem,_LBU(isotoperef)); p; ++p) { - dddb_dim_t isotope = p; - double frac = isotope.fractionmass(1.0); - string iso_id = object_path(context,isotope.href()); - e->isotopes.push_back(make_pair(iso_id,frac)); - } - context->collect(e->id, e); - context->collectPath(e->path, e); + Element* e = new Element(); + dddb_dim_t atom = x_elem.child(_U(atom),false); + e->id = id; + e->name = name; + e->path = object_path(context,name); + e->density = x_elem.density(-1.0); + e->ionization = x_elem.I(-1.0); + e->symbol = x_elem.symbol(e->name); + e->atom.A = atom ? atom.attr<double>(_U(A)) : -1.0; + e->atom.Zeff = atom ? atom.attr<double>(_U(Zeff)) : -1.0; + string st = x_elem.state(); + if ( st == "solid" ) e->state = Element::SOLID; + else if ( st == "liquid" ) e->state = Element::LIQUID; + else if ( st == "gas" ) e->state = Element::GAS; + else e->state = Element::UNKNOWN; + + for(xml_coll_t p(x_elem,_LBU(isotoperef)); p; ++p) { + dddb_dim_t isotope = p; + double frac = isotope.fractionmass(1.0); + string iso_id = object_path(context,isotope.href()); + e->isotopes.push_back(make_pair(iso_id,frac)); + } + context->collect(e->id, e); + context->collectPath(e->path, e); e->setDocument(context->locals.xml_doc); } } @@ -843,12 +943,12 @@ namespace DD4hep { load_dddb_entity(context, catalog, element, href); dddb::Materials::const_iterator i=context->geo->materials.find(refid); if ( i == context->geo->materials.end() ) { - printout(ERROR,"MaterialRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); + printout(ERROR,"MaterialRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); } if ( catalog ) { - Material* m = (*i).second; - string path = object_path(context,m->name); - context->collectPath(path, m); + Material* m = (*i).second; + string path = object_path(context,m->name); + context->collectPath(path, m); } } @@ -860,23 +960,23 @@ namespace DD4hep { string name = x_mat.nameStr(); string id = object_href(element, name); if ( !_find(id, context->geo->materials) ) { - Material* m = new Material(); - m->name = name; - m->id = id; - m->path = object_path(context,name); - m->density = x_mat.density(-1.0); - m->pressure = x_mat.pressure(-1.0); - m->temperature = x_mat.temperature(-1.0); - m->radlen = x_mat.radlen(-1.0); - m->lambda = x_mat.lambda(-1.0); - for(xml_coll_t p(element,_LBU(tabprops)); p; ++p) - m->properties.push_back(p.attr<string>(_LBU(address))); - - xml_coll_t(element, _U(component)).for_each(Conv<MaterialComponent>(lcdd,context,m)); - context->collect(m->id, m); // We collect materials by NAME!!! - context->collect(m->name, m); + Material* m = new Material(); + m->name = name; + m->id = id; + m->path = object_path(context,name); + m->density = x_mat.density(-1.0); + m->pressure = x_mat.pressure(-1.0); + m->temperature = x_mat.temperature(-1.0); + m->radlen = x_mat.radlen(-1.0); + m->lambda = x_mat.lambda(-1.0); + for(xml_coll_t p(element,_LBU(tabprops)); p; ++p) + m->properties.push_back(p.attr<string>(_LBU(address))); + + xml_coll_t(element, _U(component)).for_each(Conv<MaterialComponent>(lcdd,context,m)); + context->collect(m->id, m); // We collect materials by NAME!!! + context->collect(m->name, m); m->setDocument(context->locals.xml_doc); - if ( catalog ) context->collectPath(m->path, m); + if ( catalog ) context->collectPath(m->path, m); } } @@ -992,7 +1092,7 @@ namespace DD4hep { dddb_dim_t dim = element; ShapeConv<Shape>(lcdd,param)(element,s); if ( s->name == "Cut_out_right" ) { - s->type = to_type::type(); + s->type = to_type::type(); } s->type = to_type::type(); s->s.trap.dz = dim.sizeZ()/2e0; @@ -1075,24 +1175,24 @@ namespace DD4hep { context->locals.obj_path = id; s->s.boolean.first = 0; for(xml_coll_t p(element,_U(star)); p; ++p) { - if ( p.parent() == element ) { // Only next level is processed here - if ( 0 == s->s.boolean.first ) { - ShapeConv<BooleanOperation>(lcdd,context)(p,s->s.boolean.first); - s->s.boolean.first->id = id + "/" + s->s.boolean.first->name; - ++p; - } - BooleanOperation op; - ShapeConv<BooleanOperation>(lcdd,context)(p,op.shape); - if ( 0 == op.shape ) { - // Error. What to do? - // Anyhow: ShapeConv<BooleanOperation> throws exception if the - // shape is unknown. We never get here. - } - op.shape->id = id + "/" + op.shape->name; - ++p; - extract_transformation(lcdd, param, p, op.trafo); - s->boolean_ops.push_back(op); - } + if ( p.parent() == element ) { // Only next level is processed here + if ( 0 == s->s.boolean.first ) { + ShapeConv<BooleanOperation>(lcdd,context)(p,s->s.boolean.first); + s->s.boolean.first->id = id + "/" + s->s.boolean.first->name; + ++p; + } + BooleanOperation op; + ShapeConv<BooleanOperation>(lcdd,context)(p,op.shape); + if ( 0 == op.shape ) { + // Error. What to do? + // Anyhow: ShapeConv<BooleanOperation> throws exception if the + // shape is unknown. We never get here. + } + op.shape->id = id + "/" + op.shape->name; + ++p; + extract_transformation(lcdd, param, p, op.trafo); + s->boolean_ops.push_back(op); + } } } @@ -1122,32 +1222,32 @@ namespace DD4hep { // Now convert all possible / supported shapes if ( tag == "box" ) - ShapeConv<Box>(lcdd,context)(elt,s); + ShapeConv<Box>(lcdd,context)(elt,s); else if ( tag == "cons" ) - ShapeConv<Cons>(lcdd,context)(elt,s); + ShapeConv<Cons>(lcdd,context)(elt,s); else if ( tag == "tubs" ) - ShapeConv<Tubs>(lcdd,context)(elt,s); + ShapeConv<Tubs>(lcdd,context)(elt,s); else if ( tag == "trap" ) - ShapeConv<Trap>(lcdd,context)(elt,s); + ShapeConv<Trap>(lcdd,context)(elt,s); else if ( tag == "polycone" ) - ShapeConv<Polycone>(lcdd,context)(elt,s); + ShapeConv<Polycone>(lcdd,context)(elt,s); else if ( tag == "polygon" ) - ShapeConv<Polygon>(lcdd,context)(elt,s); + ShapeConv<Polygon>(lcdd,context)(elt,s); else if ( tag == "trd" ) - ShapeConv<TRD>(lcdd,context)(elt,s); + ShapeConv<TRD>(lcdd,context)(elt,s); else if ( tag == "eltu" ) - ShapeConv<EllipticalTube>(lcdd,context)(elt,s); + ShapeConv<EllipticalTube>(lcdd,context)(elt,s); else if ( tag == "sphere" ) - ShapeConv<Sphere>(lcdd,context)(elt,s); + ShapeConv<Sphere>(lcdd,context)(elt,s); else if ( tag == "union" ) - ShapeConv<BooleanUnion>(lcdd,context)(elt,s); + ShapeConv<BooleanUnion>(lcdd,context)(elt,s); else if ( tag == "subtraction" ) - ShapeConv<BooleanSubtraction>(lcdd,context)(elt,s); + ShapeConv<BooleanSubtraction>(lcdd,context)(elt,s); else if ( tag == "intersection" ) - ShapeConv<BooleanIntersection>(lcdd,context)(elt,s); + ShapeConv<BooleanIntersection>(lcdd,context)(elt,s); else { - XML::dump_tree(element.parent()); - except("BooleanOperation","Unknown shape conversion requested:"+tag); + XML::dump_tree(element.parent()); + except("BooleanOperation","Unknown shape conversion requested:"+tag); } } @@ -1161,15 +1261,15 @@ namespace DD4hep { load_dddb_entity(context, catalog, element, href); dddb::Volumes::const_iterator i=context->geo->volumes.find(refid); if ( i == context->geo->volumes.end() ) { - string r = reference_href(element,href); - printout(ERROR,"LogVolRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); + string r = reference_href(element,href); + printout(ERROR,"LogVolRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); } LogVol* vol = (*i).second; catalog->logvolrefs[vol->id] = vol; string path = object_path(context,vol->name); context->collectPath(path, vol); if ( context->print_logvol ) { - print_ref("LogVolRef", context, element, href, "Path:"+path); + print_ref("LogVolRef", context, element, href, "Path:"+path); } } @@ -1179,67 +1279,67 @@ namespace DD4hep { string name = element.attr<string>(_U(name)); string id = object_href(element, name); if ( !_find(id, context->geo->volumes) ) { - Catalog* catalog = _option<Catalog>(); - string material; - LogVol* vol = new LogVol; - xml_h elt; - vol->name = name; - vol->path = object_path(context,name); - if ( element.hasAttr(_U(material)) ) { - vol->material = element.attr<string>(_U(material)); - } - Shape* s = 0; - // Now convert all possible / supported shapes - if ( (elt=element.child(_U(box),false)) ) - ShapeConv<Box>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(cons),false)) ) - ShapeConv<Cons>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(tubs),false)) ) - ShapeConv<Tubs>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(trap),false)) ) - ShapeConv<Trap>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(trd),false)) ) - ShapeConv<TRD>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(polycone),false)) ) - ShapeConv<Polycone>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(sphere),false)) ) - ShapeConv<Sphere>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(union),false)) ) - ShapeConv<BooleanUnion>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(subtraction),false)) ) - ShapeConv<BooleanSubtraction>(lcdd,context)(elt,s); - else if ( (elt=element.child(_U(intersection),false)) ) - ShapeConv<BooleanIntersection>(lcdd,context)(elt,s); - else { - ShapeConv<Assembly>(lcdd,context)(elt,s); - // Dump element if not known and processed.... - for(xml_coll_t p(element,_U(star)); p; ++p) { - if ( p.parent() == element ) { - string tag = p.tag(); - if ( tag == "physvol" ) continue; - if ( tag == "paramphysvol" ) continue; - if ( tag == "paramphysvol2D" ) continue; - if ( tag == "paramphysvol3D" ) continue; - printout(WARNING,"LogVol","++ Unknown and not processed tag found: %s",tag.c_str()); - XML::dump_tree(element); - break; - } - } - } - // Now collect the information - vol->shape = id; + Catalog* catalog = _option<Catalog>(); + string material; + LogVol* vol = new LogVol; + xml_h elt; + vol->name = name; + vol->path = object_path(context,name); + if ( element.hasAttr(_U(material)) ) { + vol->material = element.attr<string>(_U(material)); + } + Shape* s = 0; + // Now convert all possible / supported shapes + if ( (elt=element.child(_U(box),false)) ) + ShapeConv<Box>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(cons),false)) ) + ShapeConv<Cons>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(tubs),false)) ) + ShapeConv<Tubs>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(trap),false)) ) + ShapeConv<Trap>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(trd),false)) ) + ShapeConv<TRD>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(polycone),false)) ) + ShapeConv<Polycone>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(sphere),false)) ) + ShapeConv<Sphere>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(union),false)) ) + ShapeConv<BooleanUnion>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(subtraction),false)) ) + ShapeConv<BooleanSubtraction>(lcdd,context)(elt,s); + else if ( (elt=element.child(_U(intersection),false)) ) + ShapeConv<BooleanIntersection>(lcdd,context)(elt,s); + else { + ShapeConv<Assembly>(lcdd,context)(elt,s); + // Dump element if not known and processed.... + for(xml_coll_t p(element,_U(star)); p; ++p) { + if ( p.parent() == element ) { + string tag = p.tag(); + if ( tag == "physvol" ) continue; + if ( tag == "paramphysvol" ) continue; + if ( tag == "paramphysvol2D" ) continue; + if ( tag == "paramphysvol3D" ) continue; + printout(WARNING,"LogVol","++ Unknown and not processed tag found: %s",tag.c_str()); + XML::dump_tree(element); + break; + } + } + } + // Now collect the information + vol->shape = id; s->setDocument(context->locals.xml_doc); vol->setDocument(context->locals.xml_doc); - context->collect(id, s); - context->collect(id, vol); - if ( catalog ) context->collectPath(vol->path, vol); - { - Context::PreservedLocals locals(context); - context->locals.obj_path = id; - xml_coll_t(element, _U(physvol)).for_each(Conv<PhysVol>(lcdd,context,vol)); - xml_coll_t(element, _LBU(paramphysvol)).for_each(Conv<ParamPhysVol>(lcdd,context,vol)); - xml_coll_t(element, _LBU(paramphysvol2D)).for_each(Conv<ParamPhysVol2D>(lcdd,context,vol)); - } + context->collect(id, s); + context->collect(id, vol); + if ( catalog ) context->collectPath(vol->path, vol); + { + Context::PreservedLocals locals(context); + context->locals.obj_path = id; + xml_coll_t(element, _U(physvol)).for_each(Conv<PhysVol>(lcdd,context,vol)); + xml_coll_t(element, _LBU(paramphysvol)).for_each(Conv<ParamPhysVol>(lcdd,context,vol)); + xml_coll_t(element, _LBU(paramphysvol2D)).for_each(Conv<ParamPhysVol2D>(lcdd,context,vol)); + } } } @@ -1261,14 +1361,14 @@ namespace DD4hep { string name = x_vol.nameStr(); string id = object_href(element, name); if ( !_find(id, context->geo->placements) ) { - PhysVol* vol = new PhysVol(); - this->fill(element, vol); - context->collect(id, vol); - context->collectPath(vol->path,vol); + PhysVol* vol = new PhysVol(); + this->fill(element, vol); + context->collect(id, vol); + context->collectPath(vol->path,vol); vol->setDocument(context->locals.xml_doc); - if ( optional ) { - _option<LogVol>()->physvols.push_back(vol); - } + if ( optional ) { + _option<LogVol>()->physvols.push_back(vol); + } } } @@ -1313,6 +1413,50 @@ namespace DD4hep { _option<LogVol>()->physvols.push_back(pv); } + /// Specialized conversion of <geometryinfo/> entities + template <> void Conv<TabProperty>::convert(xml_h element) const { + Context* context = _param<Context>(); + dddb_dim_t x_dim = element; + string name = x_dim.nameStr(); + string id = object_href(element, name); + if ( !_find(id, context->geo->tabproperties) ) { + TabProperty* p = new TabProperty(); + p->name = name; + p->path = object_path(context,name); + if ( element.hasAttr(_U(type)) ) p->type = element.attr<string>(_U(type)); + if ( element.hasAttr(_LBU(xunit)) ) p->xunit = element.attr<string>(_LBU(xunit)); + if ( element.hasAttr(_LBU(yunit)) ) p->yunit = element.attr<string>(_LBU(yunit)); + if ( element.hasAttr(_LBU(xaxis)) ) p->xaxis = element.attr<string>(_LBU(xaxis)); + if ( element.hasAttr(_LBU(yaxis)) ) p->yaxis = element.attr<string>(_LBU(yaxis)); + context->collect(id, p); + context->collectPath(p->path, p); + p->setDocument(context->locals.xml_doc); + } + } + + /// Specialized conversion of <tabpropertyref/> entities + template <> void Conv<TabPropertyRef>::convert(xml_h element) const { + Context* context = _param<Context>(); + Catalog* catalog = _option<Catalog>(); + string href = element.attr<string>(_LBU(href)); + string refid = reference_href(element,href); + + load_dddb_entity(context, catalog, element, href); + dddb::TabProperties::const_iterator i=context->geo->tabproperties.find(refid); + if ( i == context->geo->tabproperties.end() ) { + string r = reference_href(element,href); + printout(ERROR,"TabPropertyRef","++ MISSING ID: %s Failed to convert ref:%s",refid.c_str(),href.c_str()); + return; + } + TabProperty* p = (*i).second; + catalog->tabpropertyrefs[p->id] = p; + string path = object_path(context,p->name); + context->collectPath(path, p); + if ( context->print_tabprop ) { + print_ref("TabPropertyRef", context, element, href, "Path:"+path); + } + } + /// Specialized conversion of <parameter/> entities template <> void Conv<Parameter>::convert(xml_h element) const { Context* context = _param<Context>(); @@ -1320,7 +1464,7 @@ namespace DD4hep { string value = element.attr<string>(_U(value)); _toDictionary(name,value); if ( context->print_params ) { - printout(INFO,"Parameter","++ %s = %s",name.c_str(),value.c_str()); + printout(INFO,"Parameter","++ %s = %s",name.c_str(),value.c_str()); } } @@ -1329,12 +1473,17 @@ namespace DD4hep { Context* context = _param<Context>(); Catalog* catalog = _option<Catalog>(); string href = element.attr<string>(_LBU(href)); - string refid = reference_href(element,href); - load_dddb_entity(context, catalog, element, href); + string refid = reference_href(element, href); + + xml_h target = find_local_element(element, href, _LBU(detelem)); + if ( target ) + Conv<DetElem>(lcdd,context,catalog)(target); + else + load_dddb_entity(context, catalog, element, href); dddb::Catalogs::const_iterator i=context->geo->catalogs.find(refid); catalog->catalogrefs[refid] = (i==context->geo->catalogs.end()) ? 0 : (*i).second; if ( context->print_detelem_ref ) { - print_ref("DetElemRef", context, element, href); + print_ref("DetElemRef", context, element, href); } } @@ -1346,52 +1495,52 @@ namespace DD4hep { string name = x_det.nameStr(); string id = object_href(element, name); - dddb::Catalogs::iterator i = geo->catalogs.find(id); - if ( i != geo->catalogs.end() ) { - printout(ERROR,"DetElem", "++ Attempt to add same detector element '%s' twice!",id.c_str()); - return; - } - xml_h elt; - string path = object_path(context, name); - boost::filesystem::path p(path); - string parent = p.parent_path().native(); - Catalog* det = new Catalog(); - det->typeID = 1; - det->name = name; - det->type = x_det.typeStr(); - det->path = path; - det->id = id; - det->support = parent; - det->setDocument(context->locals.xml_doc); - if ( context->print_detelem ) { - printout(INFO,"DetElem"," xml:%s id=%s [%s/%s] doc:%s obj:%s / %s", - element.parent().tag().c_str(), - det->id.c_str(), - det->name.c_str(), - det->type.c_str(), - context->locals.doc_path.c_str(), - context->locals.obj_path.c_str(), - det->name.c_str() - ); - } - // Now extract all availible information from the xml - if ( (elt=x_det.child(_U(author),false)) ) - Conv<Author>(lcdd,context,&det->author)(elt); - if ( (elt=x_det.child(_U(version),false)) ) - Conv<Version>(lcdd,context,&det->version)(elt); - xml_coll_t(element, _U(param)).for_each(Conv<Param>(lcdd,context,det)); - xml_coll_t(element, _LBU(userParameter)).for_each(Conv<Param>(lcdd,context,det)); - xml_coll_t(element, _LBU(conditioninfo)).for_each(Conv<ConditionInfo>(lcdd,context,det)); - { - Context::PreservedLocals locals(context); - context->locals.obj_path = det->path; - xml_coll_t(element, _LBU(geometryinfo)).for_each(Conv<GeometryInfo>(lcdd,context,det)); - xml_coll_t(element, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,det)); + dddb::Catalogs::iterator idet = geo->catalogs.find(id); + if ( idet == geo->catalogs.end() ) { + xml_h elt; + string path = object_path(context, name); + boost::filesystem::path p(path); + string parent = p.parent_path().native(); + Catalog* det = new Catalog(); + det->typeID = 1; + det->name = name; + det->type = x_det.typeStr(); + det->path = path; + det->id = id; + det->support = parent; + det->setDocument(context->locals.xml_doc); + if ( context->print_detelem ) { + printout(INFO,"DetElem"," xml:%s id=%s [%s/%s] doc:%s obj:%s / %s", + element.parent().tag().c_str(), + det->id.c_str(), + det->name.c_str(), + det->type.c_str(), + context->locals.xml_doc->id.c_str(), + context->locals.obj_path.c_str(), + det->name.c_str() + ); + } + // Now extract all availible information from the xml + if ( (elt=x_det.child(_U(author),false)) ) + Conv<Author>(lcdd,context,&det->author)(elt); + if ( (elt=x_det.child(_U(version),false)) ) + Conv<Version>(lcdd,context,&det->version)(elt); + xml_coll_t(element, _U(param)).for_each(Conv<Param>(lcdd,context,det)); + xml_coll_t(element, _LBU(userParameter)).for_each(Conv<Param>(lcdd,context,det)); + xml_coll_t(element, _LBU(conditioninfo)).for_each(Conv<ConditionInfo>(lcdd,context,det)); + { + Context::PreservedLocals locals(context); + context->locals.obj_path = det->path; + xml_coll_t(element, _LBU(geometryinfo)).for_each(Conv<GeometryInfo>(lcdd,context,det)); + xml_coll_t(element, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,det)); + } + det->path = det->support + "/" + det->name; + context->collect(det->id, det); + context->collectPath(det->path, det); + context->print(det); + return; } - det->path = det->support + "/" + det->name; - context->collect(det->id, det); - context->collectPath(det->path, det); - context->print(det); + printout(DEBUG,"DetElem","ALREADY PROCESSED: xid:%s -> %s",id.c_str(),(*idet).second->path.c_str()); } /// Specialized conversion of references to catalogs @@ -1400,12 +1549,22 @@ namespace DD4hep { Catalog* catalog = _option<Catalog>(); string href = element.attr<string>(_LBU(href)); string refid = reference_href(element,href); - - load_dddb_entity(context, catalog, element, href); +#if 0 + if ( href.find("@ChamAlign.xml#") != string::npos ) { + print_ref("CatalogRef", context, element, href); + } +#endif + xml_h target = find_local_element(element, href,_LBU(catalog)); + if ( target ) { + Conv<Catalog>(lcdd,context,catalog)(target); + } + else { + load_dddb_entity(context, catalog, element, href); + } dddb::Catalogs::const_iterator i=context->geo->catalogs.find(refid); catalog->catalogrefs[refid] = (i == context->geo->catalogs.end()) ? 0 : (*i).second; if ( context->print_catalog_ref ) { - print_ref("CatalogRef", context, element, href); + print_ref("CatalogRef", context, element, href); } } @@ -1414,113 +1573,136 @@ namespace DD4hep { Context* context = _param<Context>(); string name = e.attr<string>(_U(name)); string id = object_href(e,name); - Catalog* catalog = new Catalog(); - - catalog->name = name; - catalog->path = object_path(context,name); - catalog->level = Increment<Catalog>::counter(); - catalog->type = "Logical"; - catalog->support = ""; - catalog->setDocument(context->locals.xml_doc); - context->collect(id, catalog); - context->collectPath(catalog->path, catalog); - if ( catalog->path == "/dd" ) { - catalog->type = "World"; - context->geo->top = catalog; - } - else if ( catalog->path == "/dd/Structure" ) { - catalog->type = "Structure"; - context->geo->structure = catalog; - } - else if ( catalog->path == "/dd/Geometry" ) { - catalog->type = "Geometry"; - context->geo->geometry = catalog; - } - { - Context::PreservedLocals locals(context); - context->locals.obj_path = catalog->path; - xml_coll_t(e, _U(parameter)).for_each(Conv<Parameter>(lcdd,context,catalog)); - xml_coll_t(e, _U(isotope)).for_each(Conv<Isotope>(lcdd,context,catalog)); - xml_coll_t(e, _U(element)).for_each(Conv<Element>(lcdd,context,catalog)); - xml_coll_t(e, _U(material)).for_each(Conv<Material>(lcdd,context,catalog)); - xml_coll_t(e, _U(logvol)).for_each(Conv<LogVol>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); - - xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); - - xml_coll_t(e, _LBU(elementref)).for_each(Conv<ElementRef>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(materialref)).for_each(Conv<MaterialRef>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(logvolref)).for_each(Conv<LogVolRef>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); - xml_coll_t(e, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); + dddb::Catalogs::const_iterator icat = context->geo->catalogs.find(id); + + if ( icat == context->geo->catalogs.end() ) { + Catalog* catalog = new Catalog(); + catalog->name = name; + catalog->path = object_path(context,name); + //printout(INFO,"Catalog","PROCESSING: xid:%s -> %s",id.c_str(),catalog->path.c_str()); + catalog->level = Increment<Catalog>::counter(); + catalog->type = "Logical"; + catalog->support = ""; + catalog->setDocument(context->locals.xml_doc); + context->collect(id, catalog); + context->collectPath(catalog->path, catalog); + if ( catalog->path == "/dd" ) { + catalog->type = "World"; + context->geo->top = catalog; + } + else if ( catalog->path == "/dd/Structure" ) { + catalog->type = "Structure"; + context->geo->structure = catalog; + } + else if ( catalog->path == "/dd/Geometry" ) { + catalog->type = "Geometry"; + context->geo->geometry = catalog; + } + { + Context::PreservedLocals locals(context); + context->locals.obj_path = catalog->path; + xml_coll_t(e, _U(parameter)).for_each(Conv<Parameter>(lcdd,context,catalog)); + xml_coll_t(e, _U(isotope)).for_each(Conv<Isotope>(lcdd,context,catalog)); + xml_coll_t(e, _U(element)).for_each(Conv<Element>(lcdd,context,catalog)); + xml_coll_t(e, _U(material)).for_each(Conv<Material>(lcdd,context,catalog)); + xml_coll_t(e, _U(logvol)).for_each(Conv<LogVol>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(tabproperty)).for_each(Conv<TabProperty>(lcdd,context,catalog)); + + //xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); + //xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); + //xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(elementref)).for_each(Conv<ElementRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(materialref)).for_each(Conv<MaterialRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(logvolref)).for_each(Conv<LogVolRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(tabpropertyref)).for_each(Conv<TabPropertyRef>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); + } + return; } + printout(DEBUG,"Catalog","ALREADY PROCESSED: xid:%s -> %s",id.c_str(),(*icat).second->path.c_str()); } /// Specialized conversion of <DDDB/> entities - template <> void Conv<dddb>::convert(xml_h element) const { + template <> void Conv<dddb>::convert(xml_h e) const { Catalog* catalog = 0; Context* context = _param<Context>(); - Context::PreservedLocals locals(context); - xml_coll_t(element, _U(parameter)).for_each(Conv<Parameter>(lcdd,context,catalog)); - xml_coll_t(element, _U(isotope)).for_each(Conv<Isotope>(lcdd,context,catalog)); - xml_coll_t(element, _U(element)).for_each(Conv<Element>(lcdd,context,catalog)); - xml_coll_t(element, _U(material)).for_each(Conv<Material>(lcdd,context,catalog)); - xml_coll_t(element, _U(logvol)).for_each(Conv<LogVol>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(elementref)).for_each(Conv<ElementRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(materialref)).for_each(Conv<MaterialRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(logvolref)).for_each(Conv<LogVolRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); + xml_coll_t(e, _U(parameter)).for_each(Conv<Parameter>(lcdd,context,catalog)); + xml_coll_t(e, _U(isotope)).for_each(Conv<Isotope>(lcdd,context,catalog)); + xml_coll_t(e, _U(element)).for_each(Conv<Element>(lcdd,context,catalog)); + xml_coll_t(e, _U(material)).for_each(Conv<Material>(lcdd,context,catalog)); + xml_coll_t(e, _U(logvol)).for_each(Conv<LogVol>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(tabproperty)).for_each(Conv<TabProperty>(lcdd,context,catalog)); + + //xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); + //xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); + //xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(elementref)).for_each(Conv<ElementRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(materialref)).for_each(Conv<MaterialRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(logvolref)).for_each(Conv<LogVolRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(tabpropertyref)).for_each(Conv<TabPropertyRef>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); + + xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); } /// Specialized conversion of <DDDB/> entities - template <> void Conv<dddb_conditions>::convert(xml_h element) const { + template <> void Conv<dddb_conditions>::convert(xml_h e) const { Catalog* catalog = 0; Context* context = _param<Context>(); - Context::PreservedLocals locals(context); - xml_coll_t(element, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); + { + Context::PreservedLocals locals(context); + xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + } } void apply_trafo(int apply, Position& pos, RotationZYX& rot, Transform3D& trafo, Transform3D& tr) { switch(apply) { case 99: { - tr *= trafo; - trafo = Transform3D(); - pos = Position(); - rot = RotationZYX(); - break; + tr *= trafo; + trafo = Transform3D(); + pos = Position(); + rot = RotationZYX(); + break; } case 2: { - Transform3D r(rot); - trafo = Transform3D(pos); - trafo = trafo * r; - tr = trafo * tr; - trafo = Transform3D(); - pos = Position(); - rot = RotationZYX(); - break; + Transform3D r(rot); + trafo = Transform3D(pos); + trafo = trafo * r; + tr = trafo * tr; + trafo = Transform3D(); + pos = Position(); + rot = RotationZYX(); + break; } case 1: { - trafo = Transform3D(pos); - tr *= trafo; - trafo = Transform3D(); - pos = Position(); - rot = RotationZYX(); - break; + trafo = Transform3D(pos); + tr *= trafo; + trafo = Transform3D(); + pos = Position(); + rot = RotationZYX(); + break; } case 0: default: - break; + break; } } @@ -1531,37 +1713,37 @@ namespace DD4hep { RotationZYX rot; Transform3D trafo; for(xml_h element = p.parent(); p; ++p ) { - if ( p.parent() == element ) { // Only next level is processed here - dddb_dim_t dim = p; - string tag = p.tag(); - if ( tag == "transformation" && (which<0 || count == which) ) { - apply_trafo(apply, pos, rot, trafo, tr); - Conv<Transform3D>(lcdd,context,&trafo)(p); - apply = 99; - } - else if ( tag == "posXYZ" && (which<0 || count == which) ) { - apply_trafo(apply, pos, rot, trafo, tr); - pos.SetXYZ(dim.x(0.0), dim.y(0.0), dim.z(0.0)); - apply = 1; - ++count; - } - else if ( tag == "rotXYZ" && (which<0 || count == (which+1)) ) { - rot.SetComponents(dim.rotZ(0.0), dim.rotY(0.0), dim.rotX(0.0)); - apply = 2; - } - else { - --p; - apply_trafo(apply, pos, rot, trafo, tr); - return; - } - if ( apply > 1 ) { - apply_trafo(apply, pos, rot, trafo, tr); - apply = 0; - } - } + if ( p.parent() == element ) { // Only next level is processed here + dddb_dim_t dim = p; + string tag = p.tag(); + if ( tag == "transformation" && (which<0 || count == which) ) { + apply_trafo(apply, pos, rot, trafo, tr); + Conv<Transform3D>(lcdd,context,&trafo)(p); + apply = 99; + } + else if ( tag == "posXYZ" && (which<0 || count == which) ) { + apply_trafo(apply, pos, rot, trafo, tr); + pos.SetXYZ(dim.x(0.0), dim.y(0.0), dim.z(0.0)); + apply = 1; + ++count; + } + else if ( tag == "rotXYZ" && (which<0 || count == (which+1)) ) { + rot.SetComponents(dim.rotZ(0.0), dim.rotY(0.0), dim.rotX(0.0)); + apply = 2; + } + else { + --p; + apply_trafo(apply, pos, rot, trafo, tr); + return; + } + if ( apply > 1 ) { + apply_trafo(apply, pos, rot, trafo, tr); + apply = 0; + } + } } if ( apply > 0 ) { - apply_trafo(apply, pos, rot, trafo, tr); + apply_trafo(apply, pos, rot, trafo, tr); } } string reference_href(xml_h element, const string& ref) { @@ -1579,10 +1761,10 @@ namespace DD4hep { // Resolve relative path string p = XML::DocumentHandler::system_path(element); if ( hash == 0 ) { // This is a local object. Take the element's path - p += ref; - boost::filesystem::path path = p; // Remote object. Parent + local path - p = path.normalize().native(); - return p; + p += ref; + boost::filesystem::path path = p; // Remote object. Parent + local path + p = path.normalize().native(); + return p; } boost::filesystem::path path = p; // Remote object. Parent + local path path = path.parent_path(); @@ -1613,29 +1795,29 @@ namespace DD4hep { { size_t hash = ref.find("#"); if ( hash != 0 ) { - try { - string doc_path = element.ptr() ? reference_href(element,ref) : ref; + try { + string doc_path = element.ptr() ? reference_href(element,ref) : ref; if ( ref == "conddb:/Conditions/Online" ) doc_path = reference_href(element,ref); - hash = doc_path.find('#'); - if ( hash != string::npos ) doc_path = doc_path.substr(0,hash); + hash = doc_path.find('#'); + if ( hash != string::npos ) doc_path = doc_path.substr(0,hash); #if 0 - if ( doc_path.find("conddb:/Rich") != string::npos ) { - printout(INFO, "load_dddb", "SKIPPING DOC %s", doc_path.c_str()); - return; - } + if ( doc_path.find("conddb:/Rich") != string::npos ) { + printout(INFO, "load_dddb", "SKIPPING DOC %s", doc_path.c_str()); + return; + } #endif dddb::Documents& docs = context->geo->documents; - if ( _find(doc_path,docs) ) - return; - - size_t idx = doc_path.find('['); - size_t idq = doc_path.find(']'); - string key, fp = doc_path; - if ( idq != string::npos && idx != string::npos ) { - key = doc_path.substr(idx+1,idq-idx-1); - fp = doc_path.substr(0,idx); - } + if ( _find(doc_path,docs) ) + return; + + size_t idx = doc_path.find('['); + size_t idq = doc_path.find(']'); + string key, fp = doc_path; + if ( idq != string::npos && idx != string::npos ) { + key = doc_path.substr(idx+1,idq-idx-1); + fp = doc_path.substr(0,idx); + } XML::UriReader* rdr = context->resolver; DDDBReaderContext* ctx = (DDDBReaderContext*)rdr->context(); Document* xml_doc = new Document(); @@ -1647,37 +1829,36 @@ namespace DD4hep { xml_doc->context.valid_until = 0; docs.insert(make_pair(doc_path,xml_doc->addRef())); XML::UriContextReader reader(rdr, &xml_doc->context); - xml_doc_holder_t doc(xml_handler_t().load(fp, &reader)); - xml_h e = doc.root(); + xml_doc_holder_t doc(xml_handler_t().load(fp, &reader)); + xml_h e = doc.root(); context->print(xml_doc); - if ( e ) { - if ( !key.empty() ) { - stringstream str; - XML::dump_tree(e, str); - string buffer = str.str(); - while( (idx=buffer.find("-KEY-")) != string::npos ) - buffer.replace(idx,5,key); - doc.assign(xml_handler_t().parse(buffer.c_str(), + if ( e ) { + if ( !key.empty() ) { + stringstream str; + XML::dump_tree(e, str); + string buffer = str.str(); + while( (idx=buffer.find("-KEY-")) != string::npos ) + buffer.replace(idx,5,key); + doc.assign(xml_handler_t().parse(buffer.c_str(), buffer.length(), doc_path.c_str(), &reader)); - e = doc.root(); - } - Context::PreservedLocals locals(context); - context->locals.doc_path = doc_path; + e = doc.root(); + } + Context::PreservedLocals locals(context); context->locals.xml_doc = xml_doc; - Conv<ACTION> converter(context->lcdd, context, catalog); + Conv<ACTION> converter(context->lcdd, context, catalog); context->print_condition = prt; if ( prt || context->print_xml ) XML::dump_tree(e); - converter(e); - } - } - catch(const exception& e) { - printout(INFO,"load_dddb","Failed to load %s [%s]",ref.c_str(),e.what()); - } - catch(...) { - printout(INFO,"load_dddb","Failed to load %s",ref.c_str()); - } + converter(e); + } + } + catch(const exception& e) { + printout(INFO,"load_dddb","Failed to load %s [%s]",ref.c_str(),e.what()); + } + catch(...) { + printout(INFO,"load_dddb","Failed to load %s",ref.c_str()); + } } } @@ -1694,13 +1875,12 @@ namespace DD4hep { doc->context.valid_until = ctx->valid_until; context.resolver = rdr; context.geo = new dddb(); - context.locals.doc_path = doc_path; context.locals.obj_path = obj_path; context.locals.xml_doc = doc; context.geo->documents.insert(make_pair("Initial_dummy_doc",doc->addRef())); context.print_xml = false; - context.print_docs = true; + context.print_docs = false; context.print_materials = false; context.print_logvol = false; context.print_shapes = false; @@ -1742,7 +1922,7 @@ namespace DD4hep { ctx->event_time = evt_time; } config_context(ctxt, rdr, sys_id, obj_path); - load_dddb_entity<ACTION>(&ctxt,0,0,ctxt.locals.doc_path); + load_dddb_entity<ACTION>(&ctxt,0,0,ctxt.locals.xml_doc->id); checkParents( &ctxt ); fixCatalogs( &ctxt ); /// Transfer ownership from local context to the helper @@ -1784,8 +1964,8 @@ namespace DD4hep { } } DECLARE_XML_DOC_READER(DDDB,load_dddb_from_handle) -DECLARE_APPLY(DDDBLoader,load_dddb_from_uri) -DECLARE_APPLY(DDDBConditionsLoader,load_dddb_conditions_from_uri) +DECLARE_APPLY(DDDB_Loader,load_dddb_from_uri) +DECLARE_APPLY(DDDB_ConditionsLoader,load_dddb_conditions_from_uri) /// Plugin entry point. static long install_helper(lcdd_t& lcdd, int argc, char** argv) { @@ -1799,4 +1979,4 @@ static long install_helper(lcdd_t& lcdd, int argc, char** argv) { } return 1; } -DECLARE_APPLY(DDDBInstallHelper,install_helper) +DECLARE_APPLY(DDDB_InstallHelper,install_helper) diff --git a/DDDB/src/DDDB2Objects.cpp b/DDDB/src/DDDB2Objects.cpp index a3151ff8956a073866973ba5d9a91fe9b2fbb426..6fd4a52b1a6b02a5ee341eae8ac773855448381c 100644 --- a/DDDB/src/DDDB2Objects.cpp +++ b/DDDB/src/DDDB2Objects.cpp @@ -23,15 +23,16 @@ #include "DDDB/DDDBDimension.h" #include "DDDB/DDDBHelper.h" #include "DDDB/DDDBConversion.h" -#include "DDDB/DDDBConditionData.h" #include "DD4hep/LCDD.h" +#include "DD4hep/DetConditions.h" +#include "DD4hep/ConditionsData.h" #include "DD4hep/DetectorTools.h" #include "DD4hep/InstanceCount.h" #include "DDCond/ConditionsManager.h" -#include "DDCond/ConditionsIOVPool.h" -#include "DDCond/ConditionsInterna.h" +//#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsPool.h" // ROOT include files #include "TGeoManager.h" @@ -57,7 +58,9 @@ namespace DD4hep { typedef Conditions::Interna::ConditionObject GeoCondition; typedef Conditions::ConditionsManager ConditionsManager; + typedef Conditions::ConditionsPool ConditionsPool; typedef Conditions::IOVType IOVType; + typedef Conditions::AbstractMap AbstractMap; typedef Geometry::PlacedVolume GeoPlacement; typedef Geometry::Volume GeoVolume; typedef Geometry::Material GeoMaterial; @@ -109,7 +112,6 @@ namespace DD4hep { typedef std::map<std::string, DetElement> DetectorMap; typedef std::map<std::string, TGeoVolume*> VolumeMap; typedef std::map<DetElement, Catalog*> DetectorElements; - typedef std::map<std::string, DetElement> DetConditions; Isotopes isotopes; Elements elements; @@ -121,7 +123,6 @@ namespace DD4hep { DetElement detectors; DetectorMap catalogPaths; DetectorElements detelements; - DetConditions detconditions; GeoVolume lvDummy; ConditionsManager manager; const IOVType* epoch; @@ -230,18 +231,19 @@ namespace DD4hep { /// Convert single condition objects template <> void* CNV<GeoCondition>::convert(GeoCondition *obj) const { Context* context = _param<Context>(); - Conditions::Condition cond = obj; - if ( cond.isValid() ) { + if ( obj ) { typedef Conditions::IOV::Key _K; - DDDBConditionData& d = cond.get<DDDBConditionData>(); - Document* doc = d.document; - string cond_path = doc->name+"/"+obj->name; + Conditions::Condition cond = obj; + AbstractMap& d = cond.get<AbstractMap>(); + Document* doc = d.option<Document>(); _K::first_type since = doc->context.valid_since; _K::second_type until = doc->context.valid_until; _K iov_key(since,until); - context->manager.registerUnlocked(context->epoch, iov_key, cond); + ConditionsPool* pool = context->manager.registerIOV(*(context->epoch), iov_key); + context->manager.registerUnlocked(pool, cond); + //context->manager.registerKey(cond->hash, cond->name); } - return cond.ptr(); + return obj; } /// Convert single isotope objects @@ -778,8 +780,9 @@ namespace DD4hep { DetElement det(0), parent_element(0); if ( context->print_detelem ) { support = context->detelements[parent_element]; - printout(INFO,"CNV<Catalog>","++ Starting catalog %p [cref:%d/%d lref:%d/%d lv:%s sup:%s np:%s] %s ", + printout(INFO,"CNV<Catalog>","++ Starting catalog %p %s [cref:%d/%d lref:%d/%d lv:%s sup:%s np:%s] Cond:%s ", (void*)object, + object->path.c_str(), int(object->catalogrefs.size()), int(object->catalogs.size()), int(object->logvolrefs.size()), @@ -787,7 +790,7 @@ namespace DD4hep { object->logvol.empty() ? "--" : object->logvol.c_str(), object->support.empty() ? "--" : object->support.c_str(), object->npath.empty() ? "--" : object->npath.c_str(), - object->path.c_str()); + object->condition.c_str()); } if ( object->path == "/dd/Structure" ) { const Box& o = geo->world; @@ -808,6 +811,7 @@ namespace DD4hep { } else if ( object->path.find("/dd/Structure") == 0 ) { det = DetElement(object->name,object->type,0); + det.addExtension<Catalog>(object->addRef()); if ( !object->support.empty() ) { try { j = context->catalogPaths.find(object->support); @@ -894,14 +898,21 @@ namespace DD4hep { context->volumePaths[lp] = gv.ptr(); } #endif + /// Attach conditions keys to the detector element if present if ( !object->condition.empty() ) { - Context::DetConditions::iterator i = context->detconditions.find(object->condition); - if ( i != context->detconditions.end() ) { - printout(ERROR,"CNV<DetElem>","++ DetElement %s has multiple conditions assigned: %s + %s", - det.name(), (*i).first.c_str(), object->condition.c_str()); + Conditions::Container::Object* conditions = Conditions::DetConditions(det).conditions().ptr(); + conditions->addKey(object->condition); + conditions->addKey("Alignment", object->condition); + } + if ( !object->conditioninfo.empty() ) { + Conditions::Container::Object* conditions = Conditions::DetConditions(det).conditions().ptr(); + for(Catalog::StringMap::const_iterator i=object->conditioninfo.begin(); i!=object->conditioninfo.end(); ++i) { + const string& cond_name = (*i).second; + conditions->addKey(cond_name); + conditions->addKey((*i).first, cond_name); } - context->detconditions.insert(make_pair(object->condition,det)); } + if ( context->print_detelem ) { printout(INFO,"CNV<Catalog>","++ Converting catalog %p -> %p [cref:%d/%d lref:%d/%d lv:%s [%p] sup:%s np:%s] %s ", (void*)object, det.ptr(), @@ -997,17 +1008,19 @@ namespace DD4hep { } obj->world = s->s.box; } + /// Main detector conversion invokation cnv<Catalog>().convert(obj->top); if ( !world.isValid() && lcdd.worldVolume().isValid() ) { lcdd.endDocument(); } + /// Now configure the conditions manager if ( !context->manager.isValid() ) { Conditions::ConditionsManager manager = Conditions::ConditionsManager::from(lcdd); manager["PoolType"] = "DD4hep_ConditionsLinearPool"; manager["LoaderType"] = "dddb"; - manager["UserPoolType"] = "DD4hep_ConditionsLinearUserPool"; + manager["UserPoolType"] = "DD4hep_ConditionsMapUserPool"; manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; - manager->initialize(); + manager.initialize(); pair<bool,const Conditions::IOVType*> e = manager.registerIOVType(0, "epoch"); context->manager = manager; context->epoch = e.second; @@ -1078,5 +1091,5 @@ namespace DD4hep { } /* End namespace DDDB */ } /* End namespace DD4hep */ -DECLARE_APPLY(DDDB2DD4hep,dddb_2_dd4hep) -DECLARE_APPLY(DDDBConditions2DD4hep,dddb_conditions_2_dd4hep) +DECLARE_APPLY(DDDB_2DD4hep,dddb_2_dd4hep) +DECLARE_APPLY(DDDB_Conditions2DD4hep,dddb_conditions_2_dd4hep) diff --git a/DDDB/src/DDDBAlignmentTest.cpp b/DDDB/src/DDDBAlignmentTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d5c388d021ce05ae505911d9b8c82ac9563b4a2 --- /dev/null +++ b/DDDB/src/DDDBAlignmentTest.cpp @@ -0,0 +1,323 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== + +// Framework includes +#include "DD4hep/LCDD.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/ConditionsData.h" +#include "DD4hep/ConditionDerived.h" + +#include "DDCond/ConditionsAccess.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsOperators.h" + + +#include "DDDB/DDDBConversion.h" +#include "DDDB/DDDBConditionPrinter.h" + +//#include "DDCond/AlignmentCondition.h" +#include "AlignmentCondition.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; + +using DDDB::Document; +using Geometry::LCDD; +using Geometry::DetElement; + +/// Anonymous namespace for plugins +namespace { + + class AlignmentTypes { + public: + typedef AbstractMap::Params::const_iterator ParamIter; + typedef AlignmentConditionData _AD; + typedef AlignmentDelta _Delta; + typedef AbstractMap _Map; + typedef AbstractMap::Params::value_type::second_type _Param; + typedef DDDB::ConditionPrinter _Printer; + }; + + /// Specialized conditions update callback for alignments + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentUpdate1 : public ConditionUpdateCall, public AlignmentTypes { + public: + AlignmentUpdate1() { } + virtual ~AlignmentUpdate1() { } + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& key, const Context& context) { + printout(INFO,"AlignmentUpdate1","++ Building dependent condition: %s",key.name.c_str()); + Condition target(key.name,"Alignment"); + _AD& data = target.bind<AlignmentConditionData>(); + Condition cond0 = context.condition(0); + const _Map& src0 = cond0.get<_Map>(); + const _Param& par0 = src0.firstParam().second; + if ( par0.typeInfo() == typeid(_Delta) ) { + const _Delta& delta = src0.first<_Delta>(); + data.delta = delta; + data.flag = _AD::HAVE_NONE; + } + else { + printout(INFO,"AlignmentUpdate1","++ Failed to access AlignmentDelta from %s", + cond0->value.c_str()); + _Printer()(cond0); + } + data.condition = target; + return target; + } + }; + /// Specialized conditions update callback for alignments + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentUpdate2 : public ConditionUpdateCall, public AlignmentTypes { + public: + AlignmentUpdate2() { } + virtual ~AlignmentUpdate2() { } + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& key, const Context& context) { + printout(INFO,"AlignmentUpdate2","++ Building dependent condition: %s",key.name.c_str()); + Condition target(key.name,"Alignment"); + _AD& data = target.bind<_AD>(); + Condition cond0 = context.condition(0); + const _Map& src0 = cond0.get<_Map>(); + const _Param& par0 = src0.firstParam().second; + + if ( par0.typeInfo() == typeid(_Delta) ) { + const _Delta& delta0 = src0.first<_Delta>(); + const _AD& delta1 = context.get<_AD>(1); + data.delta = delta0; + data.delta = delta1.delta; + data.flag = _AD::HAVE_NONE; + } + else { + printout(INFO,"AlignmentUpdate2","++ Failed to access AlignmentDelta from %s", + cond0->value.c_str()); + _Printer()(cond0); + } + data.condition = target; + return target; + } + }; + /// Specialized conditions update callback for alignments + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentUpdate3 : public ConditionUpdateCall, public AlignmentTypes { + public: + AlignmentUpdate3() { } + virtual ~AlignmentUpdate3() { } + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& key, const Context& context) { + printout(INFO,"AlignmentUpdate3","++ Building dependent condition: %s",key.name.c_str()); + Condition target(key.name,"Alignment"); + _AD& data = target.bind<_AD>(); + + Condition cond0 = context.condition(0); + const _Map& src0 = cond0.get<_Map>(); + const _Param& par0 = src0.firstParam().second; + + if ( par0.typeInfo() == typeid(_Delta) ) { + const _Delta& delta0 = src0.first<_Delta>(); + const _AD& delta1 = context.get<_AD>(1); + const _AD& delta2 = context.get<_AD>(2); + data.delta = delta0; + data.delta = delta1.delta; + data.delta = delta2.delta; + data.flag = _AD::HAVE_NONE; + } + else { + printout(INFO,"AlignmentUpdate2","++ Failed to access AlignmentDelta from %s", + cond0->value.c_str()); + _Printer()(cond0); + } + data.condition = target; + return target; + } + }; + + /// DDDB Conditions analyser to select alignments. + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class AlignmentSelector { + public: + typedef ConditionsManager::Dependencies Dependencies; + string m_name; + RangeConditions m_allConditions; + Dependencies m_allDependencies; + ConditionsManager m_manager; + struct Counters { + size_t numAlignments; + size_t numNoCatalogs; + void reset() { numAlignments=numNoCatalogs=0; } + } m_counters; + + /// Initializing constructor + AlignmentSelector(ConditionsAccess mgr) : m_manager(mgr) { + Operators::collectAllConditions(mgr, m_allConditions); + } + + virtual ~AlignmentSelector() { + destroyObjects(m_allDependencies); + } + + void addDependency(ConditionDependency* dependency) { + const ConditionKey& key = dependency->target; + m_allDependencies.insert(make_pair(key.hash,dependency)); + } + + RangeConditions findCond(const string& match) { + RangeConditions result; + if ( !match.empty() ) { + for(RangeConditions::iterator ic=m_allConditions.begin(); ic!=m_allConditions.end(); ++ic) { + Condition cond = (*ic); + size_t idx = cond->value.find(match); + if ( idx == 0 ) { + if (cond->value.length() == match.length() ) { + result.push_back(cond); + } + else if ( cond->value[match.length()] == '/' ) { + size_t idq = cond->value.find('/',match.length()+1); + if ( idq == string::npos ) { + result.push_back(cond); + } + } + } + } + } + return result; + } + long collectDependencies(DetElement de, int level) { + char fmt[64], text[256]; + DDDB::Catalog* cat = 0; + DDDB::ConditionPrinter prt; + const DetElement::Children& c = de.children(); + + ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5); + ::snprintf(text,sizeof(text),fmt,""); + prt.setPrefix(text); + + try { + ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1); + printout(INFO,m_name,fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID()); + cat = de.extension<DDDB::Catalog>(); + ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3); + if ( !cat->condition.empty() ) { + RangeConditions rc = findCond(cat->condition); + printout(INFO,m_name,fmt,"","Alignment: ", + rc.empty() ? (cat->condition+" !!!UNRESOLVED!!!").c_str() : cat->condition.c_str()); + if ( !rc.empty() ) { + ConditionKey target1(cat->condition+"/derived_1"); + ConditionKey target2(cat->condition+"/derived_2"); + ConditionKey target3(cat->condition+"/derived_3"); + DependencyBuilder build_1(target1, new AlignmentUpdate1()); + DependencyBuilder build_2(target2, new AlignmentUpdate2()); + DependencyBuilder build_3(target3, new AlignmentUpdate3()); + + build_1->detector = de; + build_2->detector = de; + build_3->detector = de; + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) { + Condition cond = *ic; + const AbstractMap& data = cond.get<AbstractMap>(); + //const Document* doc = data.option<Document>(); + ConditionKey key(cond->value); + if ( cond->value.find("/dd/Conditions/Alignment/Velo/Detector10-01") != string::npos ) { + printout(INFO,m_name,fmt,"","Alignment--2: ", cond->value.c_str()); + } + build_1.add(key); + + build_2.add(key); + build_2.add(target1); + + build_3.add(key); + build_3.add(target1); + build_3.add(target2); + } + addDependency(build_1.release()); + addDependency(build_2.release()); + addDependency(build_3.release()); + } + ++m_counters.numAlignments; + } + } + catch(...) { + ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3); + printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", ""); + ++m_counters.numNoCatalogs; + } + for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) + collectDependencies((*i).second,level+1); + return 1; + } + + int computeDependencies(long time) { + dd4hep_ptr<UserPool> user_pool; + const Dependencies& dependencies = m_allDependencies; + const IOVType* iovType = m_manager.iovType("epoch"); + IOV iov(iovType, IOV::Key(time,time)); + long num_expired = m_manager.prepare(iov, user_pool, dependencies); + printout(INFO,"Conditions", + "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s", + num_expired, iov.str().c_str()); + user_pool->clear(); + return 1; + } + }; + + /// Plugin function + long dddb_derived_alignments(LCDD& lcdd, int , char** argv) { + long init_time = *(long*)argv[0]; + ConditionsManager manager = ConditionsManager::from(lcdd); + AlignmentSelector selector(manager); + int ret = selector.collectDependencies(lcdd.world(), 0); + if ( ret == 1 ) { + ret = selector.computeDependencies(init_time); + } + return ret; + } +} /* End anonymous namespace */ + +DECLARE_APPLY(DDDB_DerivedAlignmentsTest,dddb_derived_alignments) +//========================================================================== diff --git a/DDDB/src/DDDBConditionData.cpp b/DDDB/src/DDDBConditionData.cpp deleted file mode 100644 index deb7615d12ac7fd59df73d0135ddaf1ed742c418..0000000000000000000000000000000000000000 --- a/DDDB/src/DDDBConditionData.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// $Id$ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -// -// DDDB is a detector description convention developed by the LHCb experiment. -// For further information concerning the DTD, please see: -// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf -// -//========================================================================== - -// Framework includes -#include "DD4hep/Printout.h" -#include "DDDB/DDDBConversion.h" -#include "DDDB/DDDBConditionData.h" - -using namespace DD4hep; - -/// Default constructor -DDDB::DDDBConditionData::DDDBConditionData() : document(0) { -} - -/// Default destructor -DDDB::DDDBConditionData::~DDDBConditionData() { - if ( document ) document->release(); - document = 0; -} - -typedef DDDB::DDDBConditionData data_t; - -/// print Conditions object -std::ostream& operator << (std::ostream& s, const data_t& data) { - struct _Print { - void operator()(const data_t::Params::value_type& obj) const { - printout(INFO,"Condition","++ %-16s %-8s -> %s", - obj.first.c_str(), - typeName(obj.second.typeInfo()).c_str(), - obj.second.str().c_str()); - } - }; - if ( !data.params.empty() ) { - for_each(data.params.begin(), data.params.end(),_Print()); - } - return s; -} - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - /// Do NOTHING version! Function present to formally satisfy code. User implementation required - int __eval_none(data_t*, const std::string&) { - return 1; - } - /// Namespace for the AIDA detector for utilities using boost::spirit parsers - namespace Parsers { - int parse(data_t& data,const std::string& input) { - if ( data.params.empty() || input.empty() ) { - return 0; - } - return 1; - } - } -} - -#include "DD4hep/ToStream.h" -#include "DD4hep/objects/BasicGrammar_inl.h" -#include "DD4hep/objects/ConditionsInterna.h" - -DD4HEP_DEFINE_PARSER_GRAMMAR(data_t,__eval_none) -DD4HEP_DEFINE_CONDITIONS_TYPE(data_t) diff --git a/DDDB/src/DDDBConditionPrinter.cpp b/DDDB/src/DDDBConditionPrinter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14c53825417042d1cb0dd8d80544bb9ba8a64dcd --- /dev/null +++ b/DDDB/src/DDDBConditionPrinter.cpp @@ -0,0 +1,106 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== + +// Framework includes +#include "DD4hep/Printout.h" +#include "DDDB/DDDBConversion.h" +#include "DDDB/DDDBConditionPrinter.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::DDDB; + +using Conditions::AbstractMap; +using Conditions::Condition; + +/// Initializing constructor +ConditionPrinter::ParamPrinter::ParamPrinter(string& p) : m_prefix(p) { +} + +/// Callback to output conditions information +void ConditionPrinter::ParamPrinter::operator()(const AbstractMap::Params::value_type& obj) const { + const std::type_info& type = obj.second.typeInfo(); + if ( type == typeid(string) ) { + string value = obj.second.get<string>().c_str(); + size_t len = value.length(); + if ( len > 100 ) { + value.erase(100); + value += "..."; + } + printout(INFO,"Condition","++ %s\t-> Param: %-16s %-8s -> %s", + m_prefix.c_str(), + obj.first.c_str(), + obj.second.dataType().c_str(), + value.c_str()); + } + else if ( type == typeid(AbstractMap) ) { + const AbstractMap& d= obj.second.get<AbstractMap>(); + printout(INFO,"Condition","++ %s\t-> [%s] CL:%d %-8s -> %s", + m_prefix.c_str(), + obj.first.c_str(), d.classID, + obj.second.dataType().c_str(), + obj.second.str().c_str()); + } + else { + string value = obj.second.str(); + size_t len = value.length(); + if ( len > 100 ) { + value.erase(100); + value += "..."; + } + printout(INFO,"Condition","++ %s\t-> [%s] %-8s -> %s", + m_prefix.c_str(), + obj.first.c_str(), + obj.second.dataType().c_str(), + value.c_str()); + } +} + +/// Initializing constructor +ConditionPrinter::ConditionPrinter(const string& prefix, int flg, ParamPrinter* prt) + : m_prefix(prefix), m_print(prt), m_flag(flg) +{ +} + +/// Callback to output conditions information +int ConditionPrinter::operator()(Condition cond) { + if ( cond.isValid() ) { + printout(INFO,"Condition","++ %s%s",m_prefix.c_str(),cond.str(m_flag).c_str()); + const AbstractMap& data = cond.get<AbstractMap>(); + string new_prefix = m_prefix; + new_prefix.assign(m_prefix.length(),' '); + printout(INFO,"Condition","++ %s Path:%s Class:%d [%s]", + m_prefix.c_str(), + cond.name().c_str(), + data.classID, + cond.block().dataType().c_str()); + if ( !data.params.empty() ) { + if ( m_print ) { + const string& tmp = m_print->prefix(); + m_print->setPrefix(new_prefix); + for_each(data.params.begin(), data.params.end(),*m_print); + m_print->setPrefix(tmp); + return 1; + } + for_each(data.params.begin(), data.params.end(),ParamPrinter(new_prefix)); + } + } + return 1; +} diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/DDDBConditionsLoader.cpp index 3f6637763c8dd5cafd2e9d3573e5a757ab642d0e..58640f4acea15716facd99d81b919c846fe2ad4e 100644 --- a/DDDB/src/DDDBConditionsLoader.cpp +++ b/DDDB/src/DDDBConditionsLoader.cpp @@ -30,17 +30,27 @@ using namespace std; using namespace DD4hep::DDDB; using DD4hep::Geometry::LCDD; -using DD4hep::Geometry::DetElement; -using DD4hep::Conditions::IOV; using DD4hep::Conditions::Condition; -using DD4hep::Conditions::ConditionsManager; -using DD4hep::Conditions::Interna::ConditionsManagerObject; -using DD4hep::Conditions::ConditionsDataLoader; -using DD4hep::Conditions::ConditionsListener; using DD4hep::Conditions::RangeConditions; +typedef DD4hep::Conditions::RangeConditions RC; namespace { + enum CMD { + INSERT=1, + REPLACE=2, + NONE + }; + struct CallArgs { + CMD cmd; + Condition::key_type key; + Condition::iov_type& iov; + RC& rc; + CallArgs(CMD c, Condition::key_type k, Condition::iov_type& i, RC& r) + : cmd(c), key(k), iov(i), rc(r) {} + }; void* create_loader(LCDD& lcdd, int argc, char** argv) { + using DD4hep::Conditions::ConditionsManager; + using DD4hep::Conditions::ConditionsManagerObject; const char* name = argc>0 ? argv[0] : "DDDBLoader"; ConditionsManagerObject* m = (ConditionsManagerObject*)(argc>0 ? argv[1] : 0); return new DDDBConditionsLoader(lcdd,ConditionsManager(m),name); @@ -62,91 +72,173 @@ namespace DD4hep { } /* End namespace DDDB */ } /* End namespace DD4hep */ + +/// Initializing constructor +DDDBConditionsLoader::KeyCollector::KeyCollector() : call(this,0) { +} + +/// ConditionsListener overload: onRegister new condition +void DDDBConditionsLoader::KeyCollector::onRegisterCondition(Conditions::Condition cond, void*) { + Condition::Object* c = cond.ptr(); + // Register address key + if ( !c->address.empty() ) { + KeyMap::const_iterator k = keys.find(c->hash); + if ( k != keys.end() ) { + size_t idx = c->address.find('#'); + string url = (idx == string::npos) ? c->address : c->address.substr(0,idx); + keys.insert(make_pair(c->hash,make_pair(url,c->name))); + } + } +} + /// Standard constructor, initializes variables DDDBConditionsLoader::DDDBConditionsLoader(LCDD& lcdd, ConditionsManager mgr, const string& nam) -: Conditions::ConditionsDataLoader(lcdd, mgr, nam) + : Conditions::ConditionsDataLoader(lcdd, mgr, nam) { DDDBHelper* helper = lcdd.extension<DDDBHelper>(); // Ensures object existence! + m_mgr->callOnRegister(m_keys.call,true); m_resolver = helper->xmlReader(); } /// Default Destructor DDDBConditionsLoader::~DDDBConditionsLoader() { + m_mgr->callOnRegister(m_keys.call,false); } -/// Load a condition set given a Detector Element and the conditions name according to their validity -size_t DDDBConditionsLoader::load_range(DetElement det, - const string& cond, - const IOV& req_validity, - RangeConditions& conditions) { - return 0; +/// Load single conditions document +void DDDBConditionsLoader::loadDocument(XML::UriContextReader& rdr, const Key& k) +{ + loadDocument(rdr, k.first, k.second); +} + +/// Load single conditions document +void DDDBConditionsLoader::loadDocument(XML::UriContextReader& rdr, + const string& sys_id, + const string& obj_id) +{ + const void* argv_conddb[] = {&rdr, sys_id.c_str(), obj_id.c_str(), 0}; + long result = load_dddb_conditions_from_uri(m_lcdd, 3, (char**)argv_conddb); + if ( 0 == result ) { + except("DDDB","++ Failed to load conditions from URI:%s",sys_id.c_str()); + } + const void* argv_dddb[] = {"conditions_only", 0}; + result = dddb_conditions_2_dd4hep(m_lcdd, 1, (char**)argv_dddb); + if ( 0 == result ) { + except("DDDB","++ Failed to process conditions from URI:%s",sys_id.c_str()); + } } -size_t DDDBConditionsLoader::load(DetElement det, - const string& cond, - const IOV& req_validity, - RangeConditions& conditions) { +/// Load a condition set given a Detector Element and the conditions name according to their validity +size_t DDDBConditionsLoader::load_range(key_type key, + const iov_type& req_validity, + RangeConditions& conditions) { + KeyMap::const_iterator k = m_keys.keys.find(key); + if ( k != m_keys.keys.end() ) { + size_t len = conditions.size(); + DDDBReaderContext local; + const Key& url_key = (*k).second; + Condition::iov_type iov(req_validity.iovType); + long start = req_validity.keyData.first; + CallArgs arg(INSERT, key, iov, conditions); + XML::UriContextReader local_reader(m_resolver, &local); + pair<ConditionsListener*,void*> call(this,&arg); + + m_mgr->callOnRegister(call,true); + while (start < req_validity.keyData.second ) { + local.event_time = start; + local.valid_since = 0; + local.valid_until = 0; + iov.reset().invert(); + loadDocument(local_reader, url_key); + start = iov.keyData.second+1; + } + m_mgr->callOnRegister(call,false); + return conditions.size() - len; + } return 0; } -/// ConditionsListener overload: onRegister new condition -void DDDBConditionsLoader::onRegisterCondition(Condition cond, void* param) { - pair<RangeConditions*,IOV*>* arg = (pair<RangeConditions*,IOV*>*)param; - RangeConditions* range = arg->first; - Condition::Object* c = cond.ptr(); - RangeConditions::iterator i=std::find_if(range->begin(),range->end(),byName(cond)); - if ( i != range->end() ) { - (*i) = cond; - printout(DEBUG,"DDDB","++ Got MATCH: %-40s [%08X] --> %s.", - (c->value+"/"+c->name).c_str(), c->hash, c->address.c_str()); - arg->second->iov_intersection(cond.iov()); - return; +size_t DDDBConditionsLoader::load(key_type key, + const iov_type& req_validity, + RangeConditions& conditions) { + KeyMap::const_iterator k = m_keys.keys.find(key); + if ( k != m_keys.keys.end() ) { + size_t len = conditions.size(); + DDDBReaderContext local; + Condition::iov_type iov(req_validity.iovType); + CallArgs arg(INSERT, key, iov, conditions); + pair<ConditionsListener*,void*> call(this,&arg); + XML::UriContextReader local_reader(m_resolver, &local); + + iov.reset().invert(); + local.event_time = req_validity.keyData.first; + local.valid_since = 0; + local.valid_until = 0; + m_mgr->callOnRegister(call,true); + loadDocument(local_reader, (*k).second); + m_mgr->callOnRegister(call,false); + return conditions.size() - len; } - printout(INFO,"DDDB","++ Got update: %-40s [%08X] --> %s.", - (c->value+"/"+c->name).c_str(), c->hash, c->address.c_str()); + return 0; } /// Update a range of conditions according to the required IOV -size_t DDDBConditionsLoader::update(const IOV& req_iov, +size_t DDDBConditionsLoader::update(const iov_type& req_validity, RangeConditions& conditions, - IOV& conditions_validity) + iov_type& conditions_validity) { - pair<RangeConditions*,IOV*> arg(&conditions,&conditions_validity); + CallArgs arg(REPLACE, 0, conditions_validity, conditions); pair<ConditionsListener*,void*> call(this,&arg); map<string,Condition::Object*> urls; DDDBReaderContext local; - local.event_time = req_iov.keyData.first; + local.event_time = req_validity.keyData.first; local.valid_since = 0; local.valid_until = 0; m_mgr->callOnRegister(call,true); XML::UriContextReader local_reader(m_resolver, &local); /// First collect all required URIs - for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { + for(RC::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { Condition::Object* c = (*i).ptr(); size_t idx = c->address.find('#'); string url = (idx == string::npos) ? c->address : c->address.substr(0,idx); printout(INFO,"DDDB","++ Need to update: %-40s [%08X] --> %s", - (c->value+"/"+c->name).c_str(), c->hash, url.c_str()); + c->name.c_str(), c->hash, url.c_str()); urls.insert(make_pair(url,c)); } /// Now load them. In the callbacks we can check if we got all required conditions for(map<string,Condition::Object*>::const_iterator j=urls.begin(); j!=urls.end(); ++j) { const string& sys_id = (*j).first; - const string& obj_path = (*j).second->value; - const void* argv_conddb[] = {&local_reader, sys_id.c_str(), obj_path.c_str(), 0}; - long result = load_dddb_conditions_from_uri(m_lcdd, 3, (char**)argv_conddb); - if ( 0 == result ) { - except("DDDB","++ Failed to load conditions from URI:%s",sys_id.c_str()); + const string& obj_path = (*j).second->name; + loadDocument(local_reader, sys_id, obj_path); + } + m_mgr->callOnRegister(call,false); + return 0; +} + +/// ConditionsListener overload: onRegister new condition +void DDDBConditionsLoader::onRegisterCondition(Condition cond, void* param) { + // See if we got what we asked for: + if ( param ) { + CallArgs* arg = (CallArgs*)param; + Condition::Object* c = cond.ptr(); + RC& r = arg->rc; + if ( arg->cmd == REPLACE ) { + RC::iterator i=std::find_if(r.begin(),r.end(),byName(cond)); + if ( i != r.end() ) { + (*i) = cond; + printout(DEBUG,"DDDB","++ Got MATCH: %-40s [%08X] --> %s.", + c->name.c_str(), c->hash, c->address.c_str()); + arg->iov.iov_intersection(cond.iov()); + return; + } + printout(INFO,"DDDB","++ Got update: %-40s [%08X] --> %s.", + c->name.c_str(), c->hash, c->address.c_str()); } - const void* argv_dddb[] = {"conditions_only", 0}; - result = dddb_conditions_2_dd4hep(m_lcdd, 1, (char**)argv_dddb); - if ( 0 == result ) { - except("DDDB","++ Failed to process conditions from URI:%s",sys_id.c_str()); + else if ( arg->cmd == INSERT && arg->key == c->hash ) { + arg->iov.iov_intersection(cond.iov()); + r.insert(r.end(),cond); } } - m_mgr->callOnRegister(call,false); - - return 0; } diff --git a/DDDB/src/DDDBConditionsUpdate.cpp b/DDDB/src/DDDBConditionsUpdate.cpp deleted file mode 100644 index c6be64536593af75d8e54ac148fbf0fbb248b3cd..0000000000000000000000000000000000000000 --- a/DDDB/src/DDDBConditionsUpdate.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// \author Markus Frank -// \date 2016-02-02 -// \version 1.0 -// -//========================================================================== -// $Id$ - -// Framework include files -#include "DD4hep/Printout.h" -#include "DD4hep/DetFactoryHelper.h" -#include "DDCond/ConditionsInterna.h" - -using namespace DD4hep; -using namespace DD4hep::Conditions; - -/// Plugin entry point. -static long update_dddb_conditions(lcdd_t& /* lcdd */, int argc, char** argv) { - if ( argc > 0 ) { - time_t evt_time = *(long*)argv[0]; - char c_evt[64]; - struct tm evt; - ::gmtime_r(&evt_time, &evt); - ::strftime(c_evt,sizeof(c_evt),"%T %F",&evt); - printout(INFO,"DDDB","+++ ConditionsUpdate: Updating DDDB conditions... event time:%s", c_evt); - return 1; - } - except("DDDB","+++ Failed update DDDB conditions. No event time argument given!"); - return 0; -} -DECLARE_APPLY(DDDBConditionsUpdate,update_dddb_conditions) diff --git a/DDDB/src/DDDBConversion.cpp b/DDDB/src/DDDBConversion.cpp index fc0a21c9ada88b7f188614574180ec9f7d024880..c524306e3a6ac155ee3642aef2c6dafbbb226e71 100644 --- a/DDDB/src/DDDBConversion.cpp +++ b/DDDB/src/DDDBConversion.cpp @@ -64,6 +64,9 @@ namespace DD4hep { releaseObjects(placements)(); releaseObjects(placementPaths)(); + releaseObjects(tabproperties)(); + releaseObjects(tabpropertyPaths)(); + conditions.clear(); conditionPaths.clear(); //releaseObjects(conditions)(); @@ -222,6 +225,17 @@ namespace DD4hep { InstanceCount::decrement(this); } + + /// Default constructor + DDDB::TabProperty::TabProperty() { + InstanceCount::increment(this); + } + + /// Default destructor + DDDB::TabProperty::~TabProperty() { + InstanceCount::decrement(this); + } + pair<const DDDB::Catalog*,string> DDDB::Catalog::parent(const string& nam) const { const Catalog* cat = this; string rest = nam.substr(cat->path.length()+1); @@ -359,6 +373,15 @@ namespace DD4hep { "",obj->c_name(),obj->c_id()); } + template <> void dddb_print(const DDDB::TabProperty* obj) { + CHECK_OBJECT(obj); + printout(INFO,"Detector", "++ %-12s: [%s] xunit:%s xaxis:%s yunit:%s yaxis:%s siz:%d", + obj->path.c_str(), obj->type.c_str(), + obj->xunit.c_str(), obj->xaxis.c_str(), + obj->yunit.c_str(), obj->yaxis.c_str(), + int(obj->data.size())); + } + template <> void dddb_print(const DDDB::Catalog* obj) { CHECK_OBJECT(obj); printout(INFO,"Detector", "++ %-12s: [%s] %d children support:%s geo:%s", diff --git a/DDDB/src/DDDBDimension.cpp b/DDDB/src/DDDBDimension.cpp index efb3365a1b584b1eca39c74c332d6cf8fe2b57d7..26b2433e73cb3d2a679a10c5945787ef0e12f8ec 100644 --- a/DDDB/src/DDDBDimension.cpp +++ b/DDDB/src/DDDBDimension.cpp @@ -65,3 +65,9 @@ XML_ATTR_NS_ACCESSOR_STRING(DD4hep::DDDB::dddb_dim_t, symbol) XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, href) XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, state) XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, logvol) +XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, xunit) +XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, xaxis) +XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, yunit) +XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, yaxis) +XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, zunit) +XML_ATTR_NS_ACCESSOR(std::string,DD4hep::DDDB::dddb_dim_t, zaxis) diff --git a/DDDB/src/DDDBFileReader.cpp b/DDDB/src/DDDBFileReader.cpp index f0c97c427cb826b7ddac3c4b34cb5c699f1cca9e..87969a7bdce6b546bf213806c995c9aec9da51de 100644 --- a/DDDB/src/DDDBFileReader.cpp +++ b/DDDB/src/DDDBFileReader.cpp @@ -154,7 +154,7 @@ static long load_xml_dddb(Geometry::LCDD& lcdd, int argc, char** argv) { resolver.setDirectory(path.parent_path().c_str()); { /// Install helper char* arguments[] = {(char*)&resolver, 0}; - lcdd.apply("DDDBInstallHelper", 1, arguments); + lcdd.apply("DDDB_InstallHelper", 1, arguments); } if ( !params.empty() ) { /// Pre-Process Parameters XML::DocumentHolder doc(XML::DocumentHandler().load(params, &resolver)); diff --git a/DDDB/src/DDDBHelper.cpp b/DDDB/src/DDDBHelper.cpp index 0dfe8bc1f51cef7ec84324596445950400e963e8..146cc557fbfa4fde6c20c69f2d0d8514b6efc91d 100644 --- a/DDDB/src/DDDBHelper.cpp +++ b/DDDB/src/DDDBHelper.cpp @@ -85,4 +85,3 @@ void DDDBHelper::addVisAttr(const std::string& path, DD4hep::Geometry::VisAttr a } } } - diff --git a/DDDB/src/DDDBPlugins.cpp b/DDDB/src/DDDBPlugins.cpp new file mode 100644 index 0000000000000000000000000000000000000000..742b8c9ec9b4f84c48cdce5c7d08a7c66dc41b8a --- /dev/null +++ b/DDDB/src/DDDBPlugins.cpp @@ -0,0 +1,397 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== + +// Framework includes +#include "DD4hep/LCDD.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/DetConditions.h" +#include "DD4hep/ConditionsData.h" +#include "DD4hep/objects/DetectorInterna.h" + +#include "DDCond/ConditionsOperators.h" +#include "DDDB/DDDBConversion.h" +#include "DDDB/DDDBConditionPrinter.h" + +using namespace std; +using namespace DD4hep; + +using Geometry::LCDD; + +/// Anonymous namespace for plugins +namespace { + /// Plugin function + long dddb_dump_conditions(LCDD& lcdd, int , char** ) { + DDDB::ConditionPrinter prt; + const void* args[] = { &prt, 0}; + lcdd.apply("DD4hep_ConditionsDump", 1, (char**)args); + return 1; + } +} /* End anonymous namespace */ + +DECLARE_APPLY(DDDB_ConditionsDump,dddb_dump_conditions) +//========================================================================== + + +/// Anonymous namespace for plugins +namespace { + + /** Basic entry point to print out the detector element hierarchy + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + long dddb_map_condition_keys2detelements(LCDD& lcdd, int /* argc */, char** /* argv */) { + + typedef DDDB::Named::StringMap StringMap; + using DDDB::Catalog; + using Geometry::DetElement; + + /// Callback object to recursively register all conditions to detector elements. + /** Register all conditions to the corresponding detector elements + * in the geometry to the Conditons manager object. + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + struct Actor { + + /// Recursive callback + long operator()(DetElement de) { + const DetElement::Children& c = de.children(); + Conditions::DetConditions dc(de); + Conditions::Container::Object* conditions = dc.conditions().ptr(); + try { + Catalog* cat = de.extension<Catalog>(); + if ( !cat->condition.empty() ) { + conditions->addKey(cat->condition); + conditions->addKey("Alignment", cat->condition); + } + for(StringMap::const_iterator i=cat->conditioninfo.begin(); i!=cat->conditioninfo.end(); ++i) { + const string& cond_name = (*i).second; + conditions->addKey(cond_name); + conditions->addKey((*i).first, cond_name); + } + } + catch(...) { + } + for (DetElement::Children::const_iterator i=c.begin(); i != c.end(); ++i) + (*this)((*i).second); + return 1; + } + }; + return Actor()(lcdd.world()); + } +} /* End anonymous namespace */ + +DECLARE_APPLY(DDDB_AssignConditionsKeys,dddb_map_condition_keys2detelements) +//========================================================================== + +/// Anonymous namespace for plugins +namespace { + + /** Basic entry point to print out the detector element hierarchy + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + template <int flag> long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) { + + using Conditions::RangeConditions; + using Conditions::AbstractMap; + using Conditions::Condition; + using Conditions::IOV; + + using Geometry::DetElement; + + using DDDB::ConditionPrinter; + using DDDB::Catalog; + + struct Counters { + long totConditions; + long numConditions; + long numAlignments; + long numNoCatalogs; + void reset() { totConditions=numConditions=numAlignments=numNoCatalogs=0; } + }; + + /// Callback object to print selective information + /** + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + struct Actor { + /// Defintion of the container with all known conditions + typedef vector<pair<int,Condition> > _RC; + /// Container with all known conditions + _RC m_allConditions; + Counters m_counters; + bool m_sensitivesOnly; + bool m_dumpConditions; + string m_name; + LCDD& m_lcdd; + IOV m_iov; + + /// Standard constructor + Actor(LCDD& l, bool sens, bool dmp) : m_sensitivesOnly(sens), m_dumpConditions(dmp), m_lcdd(l), m_iov(0) {} + + /// Standard destructor + ~Actor() { + if ( flag > 1 ) { + printout(INFO,m_name,"++ Number of DetElements without catalog: %8ld",m_counters.numNoCatalogs); + printout(INFO,m_name,"++ Number of attached alignments: %8ld",m_counters.numAlignments); + if ( flag > 2 ) { + printout(INFO,m_name,"++ Number of attached conditions: %8ld",m_counters.numConditions); + printout(INFO,m_name,"++ Total number of conditions: %8ld",m_counters.totConditions); + } + } +#if 0 + printout(INFO,m_name,"**************** DDDB Detector dump: Conditions Usage ***************************"); + for(_RC::const_iterator ic=m_allConditions.begin(); ic!=m_allConditions.end(); ++ic) { + Condition cond = (*ic).second; + const AbstractMap& data = cond.get<AbstractMap>(); + const DDDB::Document* doc = data.option<DDDB::Document>(); + if ( doc ) + printout(INFO,m_name,"++ Usage: %d Cond: %s/%s -> %s [%08X]", + (*ic).first, doc->name.c_str(), cond->name.c_str(), cond->value.c_str(), cond->hash); + else + printout(INFO,m_name,"++ Usage: %d Cond: ---/%s -> %s [%08X]", + (*ic).first, cond->name.c_str(), cond->value.c_str(), cond->hash); + } +#endif + printout(INFO,m_name,"*********************************************************************************"); + } + + /// Initialization + Actor& init() { + m_counters.reset(); + m_allConditions.clear(); + + if ( flag >= 3 ) { + RangeConditions rc; + Conditions::Operators::collectAllConditions(m_lcdd, rc); + m_iov.reset().invert(); + m_iov.iovType = 0; + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) { + Condition cond = *ic; + m_allConditions.push_back(make_pair(0,cond)); + if ( !m_iov.iovType ) m_iov = cond.iov(); + else m_iov.iov_intersection(cond.iov()); + } + m_iov.set(m_iov.keyData.first); + if ( m_dumpConditions ) { + DDDB::ConditionPrinter prt; + printout(INFO,m_name,"**************** DDDB Detector dump: ALL Conditions *****************************"); + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) + prt(*ic); + printout(INFO,m_name,"*********************************************************************************"); + } + } + return *this; + } + + /// __________________________________________________________________________________ + RangeConditions findCond(const string& match) { + RangeConditions result; + if ( !match.empty() ) { + for(_RC::iterator ic=m_allConditions.begin(); ic!=m_allConditions.end(); ++ic) { + Condition cond = (*ic).second; + size_t idx = cond->value.find(match); + if ( idx == 0 ) { + if (cond->value.length() == match.length() ) { + (*ic).first++; + result.push_back(cond); + } + else if ( cond->value[match.length()] == '/' ) { + size_t idq = cond->value.find('/',match.length()+1); + if ( idq == string::npos ) { + (*ic).first++; + result.push_back(cond); + } + } + } + } + } + return result; + } + /// __________________________________________________________________________________ + void printDetElement(int level, DetElement de, ConditionPrinter& prt, bool with_placement=false, bool with_keys=false, bool with_values=false) { + typedef Conditions::Container::Object::Keys _K; + char fmt[128]; + const DetElement::Children& c = de.children(); + ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p Place:%%p",level+1,2*level+1); + printout(INFO, m_name, fmt, "", de.path().c_str(), int(c.size()), + (void*)de.volumeID(), (void*)de.placement().ptr()); + if ( with_placement ) { + ::sprintf(fmt,"%03d %%-%ds Placement: %%s",level+1,2*level+3); + printout(INFO,m_name,fmt,"",de.placementPath().c_str()); + } + if ( (with_keys || with_values) && de.hasConditions() ) { + Conditions::DetConditions dc(de); + Conditions::Container cont = dc.conditions(); + const _K& keys = cont->keys; + ::sprintf(fmt,"%03d %%-%ds Key: %%08X -> %%08X -> %%s",level+1,2*level+3); + for(_K::const_iterator i=keys.begin(); i!=keys.end(); ++i) { + if ( with_keys ) { + printout(INFO,m_name,fmt,"",(*i).first,(*i).second.first, (*i).second.second.c_str()); + } + if ( with_values ) { + Condition::key_type key = (*i).second.first; + Condition cond = dc.get(key, m_iov); + prt(cond); + } + } + } + } + /// __________________________________________________________________________________ + void printConditionInfo(int level, Catalog* cat, ConditionPrinter& prt, bool with_elements=false) { + if ( cat && !cat->conditioninfo.empty() ) { + char fmt[128]; + ::sprintf(fmt,"%03d %%-%ds Cond:%%-20s -> %%s",level+1,2*level+3); + for(DDDB::Named::StringMap::const_iterator i=cat->conditioninfo.begin(); i!=cat->conditioninfo.end(); ++i) { + const string& cond_name = (*i).second; + ++m_counters.numConditions; + if ( with_elements ) { + RangeConditions rc = findCond(cond_name); + printout(INFO,m_name,fmt,"",(*i).first.c_str(), + rc.empty() ? (cond_name+" !!!UNRESOLVED!!!").c_str() : cond_name.c_str()); + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) + prt(*ic); + continue; + } + printout(INFO,m_name,fmt,"",(*i).first.c_str(),cond_name.c_str()); + } + } + } + /// __________________________________________________________________________________ + void printAlignment(int level, Catalog* cat, ConditionPrinter& prt, bool with_values=false) { + if ( cat && !cat->condition.empty() ) { + char fmt[128]; + ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3); + ++m_counters.numAlignments; + if ( with_values ) { + RangeConditions rc = findCond(cat->condition); + printout(INFO,m_name,fmt,"","Alignment:", + rc.empty() ? (cat->condition+" !!!UNRESOLVED!!!").c_str() : cat->condition.c_str()); + for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) + prt(*ic); + return; + } + printout(INFO,m_name,fmt,"","Alignment:",cat->condition.c_str()); + } + } + /// __________________________________________________________________________________ + long dump(DetElement de, int level) { + char fmt[64], text[512]; + Catalog* cat = 0; + ConditionPrinter prt; + const DetElement::Children& c = de.children(); + ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5); + ::snprintf(text,sizeof(text),fmt,""); + prt.setPrefix(text); + try { + if ( !m_sensitivesOnly || 0 != de.volumeID() ) { + switch(flag) { + case 0: + printDetElement(level, de, prt, false, false); + break; + case 1: + printDetElement(level, de, prt, false, false); + cat = de.extension<Catalog>(); + printAlignment(level, cat, prt, false); + printConditionInfo(level, cat, prt, false); + break; + case 2: + printDetElement(level, de, prt, true, true); + cat = de.extension<Catalog>(); + printAlignment(level, cat, prt, false); + printConditionInfo(level, cat, prt, false); + break; + case 3: + printDetElement(level, de, prt, false, false); + cat = de.extension<Catalog>(); + printAlignment(level, cat, prt, true); + break; + case 4: + printDetElement(level, de, prt, true, true); + cat = de.extension<Catalog>(); + printAlignment(level, cat, prt, true); + printConditionInfo(level, cat, prt, true); + break; + case 5: + printDetElement(level, de, prt, true, true, true); + break; + default: + break; + } + } + } + catch(...) { + ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3); + printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", ""); + ++m_counters.numNoCatalogs; + } + for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) + dump((*i).second,level+1); + return 1; + } + }; + + bool dump_sensitive_only = false, dump_all_cond = false; + for(int i=0; i<argc; ++i) { + if ( ::strcmp(argv[i],"--sensitive")==0 ) { dump_sensitive_only = true; } + if ( ::strcmp(argv[i],"--dump")==0 ) { dump_all_cond = true; } + if ( ::strcmp(argv[i],"--help")==0 ) { + printout(INFO,"Plugin-Help","Usage: DDDBDetectorDump --opt [--opt]"); + printout(INFO,"Plugin-Help"," --sensitive Only use sensitive elements"); + printout(INFO,"Plugin-Help"," --dump Print conditions inventory"); + printout(INFO,"Plugin-Help"," --help Print this help message"); + return 0; + } + } + Actor actor(lcdd, dump_sensitive_only, dump_all_cond); + actor.m_name = "DDDBDetectorDump"; + if ( flag == 1 ) + actor.m_name = "DDDBDetVolumeDump"; + else if ( flag == 2 ) + actor.m_name = "DDDBDetConditionKeyDump"; + else if ( flag == 3 ) + actor.m_name = "DDDBDetConditionDump"; + else if ( flag == 4 ) + actor.m_name = "DDDBDetectorDump"; + else if ( flag == 5 ) + actor.m_name = "DetElementConditionDump"; + printout(INFO,actor.m_name,"**************** DDDB Detector dump *****************************"); + return actor.init().dump(lcdd.world(), 0); + } +} /* End anonymous namespace */ + +DECLARE_APPLY(DDDB_DetectorDump,dump_detelement_tree<0>) +DECLARE_APPLY(DDDB_DetectorVolumeDump,dump_detelement_tree<1>) +DECLARE_APPLY(DDDB_DetectorConditionKeysDump,dump_detelement_tree<2>) +DECLARE_APPLY(DDDB_DetectorAlignmentDump,dump_detelement_tree<3>) +DECLARE_APPLY(DDDB_DetectorConditionDump,dump_detelement_tree<4>) +DECLARE_APPLY(DDDB_DetElementConditionDump,dump_detelement_tree<5>) +//==========================================================================