From 00065e6667a2e8368b1aa633d5674b75b305227c Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 4 Apr 2018 20:30:48 +0200 Subject: [PATCH] Fix bug in DDDB conditions loading. Add Gaudi-like conditions service to DDDB --- DDCond/include/DDCond/ConditionsCleanup.h | 69 ++++ DDCond/include/DDCond/ConditionsContent.h | 19 +- .../DDCond/ConditionsDependencyHandler.h | 42 ++- DDCond/include/DDCond/ConditionsManager.h | 5 +- DDCond/include/DDCond/ConditionsPool.h | 4 +- DDCond/include/DDCond/ConditionsSlice.h | 4 + DDCond/src/ConditionsCleanup.cpp | 22 ++ DDCond/src/ConditionsDependencyHandler.cpp | 106 +++--- DDCond/src/ConditionsManager.cpp | 5 + DDCond/src/ConditionsPool.cpp | 20 +- DDCond/src/ConditionsSlice.cpp | 8 + DDCond/src/Type1/Manager_Type1.cpp | 14 +- DDCond/src/plugins/ConditionsLinearPool.cpp | 28 +- DDCond/src/plugins/ConditionsMappedPool.cpp | 4 +- DDCond/src/plugins/ConditionsUserPool.cpp | 9 +- DDCore/include/DD4hep/AlignmentsCalculator.h | 71 +++- DDCore/include/DD4hep/ComponentProperties.h | 27 +- DDCore/include/DD4hep/ConditionDerived.h | 206 ++++++++---- DDCore/include/DD4hep/Conditions.h | 19 +- DDCore/include/DD4hep/ConditionsMap.h | 8 +- DDCore/include/DD4hep/IOV.h | 9 +- DDCore/include/DD4hep/Plugins.h | 6 +- DDCore/include/XML/UriReader.h | 10 +- DDCore/src/AlignmentsCalculator.cpp | 83 ++++- DDCore/src/ConditionDerived.cpp | 47 +++ DDCore/src/ConditionsPrinter.cpp | 5 +- DDCore/src/IOV.cpp | 6 +- DDCore/src/XML/UriReader.cpp | 14 +- DDDB/include/DDDB/DDDBHelper.h | 11 +- DDDB/include/DDDB/DDDBReader.h | 27 +- DDDB/include/DDDB/DDDBReaderContext.h | 6 +- DDDB/include/Detector/DeAlignmentCall.h | 2 +- DDDB/include/Detector/DeVPConditionCalls.h | 18 +- DDDB/include/Detector/DeVeloConditionCalls.h | 14 +- DDDB/include/Detector/IDetService.h | 110 ++++++ DDDB/src/DDDBReader.cpp | 16 +- DDDB/src/Detector/DeAlignmentCall.cpp | 14 +- DDDB/src/Detector/DeVPConditionCalls.cpp | 54 +-- DDDB/src/Detector/DeVeloConditionCalls.cpp | 44 +-- DDDB/src/plugins/CondDB2DDDB.cpp | 28 +- DDDB/src/plugins/DDDBConditionsLoader.cpp | 25 +- DDDB/src/plugins/DDDBDerivedCondTest.cpp | 14 +- DDDB/src/plugins/DDDBExecutor.cpp | 26 +- DDDB/src/plugins/DDDBFileReader.cpp | 70 +++- DDDB/src/plugins/DeVeloServiceTest.cpp | 228 +++++++++++++ DDDB/src/plugins/DeVeloTest.cpp | 114 ++++--- DDDB/src/plugins/DetService.cpp | 318 ++++++++++++++++++ DDDB/src/plugins/DetService.h | 162 +++++++++ DDG4/include/DDG4/Geant4Output2ROOT.h | 5 + DDG4/src/Geant4Output2ROOT.cpp | 31 +- .../src/ConditionExampleObjects.cpp | 46 ++- .../Conditions/src/ConditionExampleObjects.h | 12 +- .../Conditions/src/ConditionExample_load.cpp | 1 - 53 files changed, 1854 insertions(+), 412 deletions(-) create mode 100644 DDCond/include/DDCond/ConditionsCleanup.h create mode 100644 DDCond/src/ConditionsCleanup.cpp create mode 100644 DDDB/include/Detector/IDetService.h create mode 100644 DDDB/src/plugins/DeVeloServiceTest.cpp create mode 100644 DDDB/src/plugins/DetService.cpp create mode 100644 DDDB/src/plugins/DetService.h diff --git a/DDCond/include/DDCond/ConditionsCleanup.h b/DDCond/include/DDCond/ConditionsCleanup.h new file mode 100644 index 000000000..b3439319a --- /dev/null +++ b/DDCond/include/DDCond/ConditionsCleanup.h @@ -0,0 +1,69 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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_CONDITIONSCLEANUP_H +#define DDCOND_CONDITIONSCLEANUP_H + +// Framework include files +#include "DDCond/ConditionsManager.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for implementation details of the AIDA detector description toolkit + namespace cond { + + /// Base class to handle conditions cleanups + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsCleanup { + public: + /// Default constructor + ConditionsCleanup() = default; + /// Copy constructor + ConditionsCleanup(const ConditionsCleanup& c) = default; + /// Default destructor + virtual ~ConditionsCleanup() = default; + /// Assignment operator + ConditionsCleanup& operator=(const ConditionsCleanup& c) = default; + /// Cleanup operation + virtual void operator()(ConditionsManager mgr) const = 0; + }; + + /// Base class to handle conditions cleanups + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsFullCleanup : public ConditionsCleanup { + public: + /// Default constructor + ConditionsFullCleanup() = default; + /// Copy constructor + ConditionsFullCleanup(const ConditionsFullCleanup& c) = default; + /// Default destructor + virtual ~ConditionsFullCleanup() = default; + /// Assignment operator + ConditionsFullCleanup& operator=(const ConditionsFullCleanup& c) = default; + /// Cleanup operation + virtual void operator()(ConditionsManager mgr) const override; + }; + } /* End namespace cond */ +} /* End namespace dd4hep */ + +#endif /* DDCOND_CONDITIONSCLEANUP_H */ diff --git a/DDCond/include/DDCond/ConditionsContent.h b/DDCond/include/DDCond/ConditionsContent.h index cae73ad69..a28b861e0 100644 --- a/DDCond/include/DDCond/ConditionsContent.h +++ b/DDCond/include/DDCond/ConditionsContent.h @@ -45,6 +45,7 @@ namespace dd4hep { virtual const std::type_info& type() const = 0; virtual const void* ptr() const = 0; + virtual ConditionsLoadInfo* clone() const = 0; template<typename T> T* data() const { return (T*)ptr(); } }; @@ -75,8 +76,9 @@ namespace dd4hep { LoadInfo(const LoadInfo& c) = default; virtual ~LoadInfo() = default; LoadInfo& operator=(const LoadInfo& copy) = default; - virtual const std::type_info& type() const { return typeid(T); } - virtual const void* ptr() const { return &info; } + virtual const std::type_info& type() const { return typeid(T); } + virtual const void* ptr() const { return &info; } + virtual ConditionsLoadInfo* clone() const { return new LoadInfo<T>(info); } }; typedef std::map<Condition::key_type,ConditionDependency* > Dependencies; @@ -112,12 +114,17 @@ namespace dd4hep { return m_conditions.insert(std::make_pair(hash,(ConditionsLoadInfo*)0)).second; } /// Add a new conditions key. T must inherit from class ConditionsContent::Info - template <typename T> bool insertKey(Condition::key_type hash, const T& info) { - ConditionsLoadInfo* i = new LoadInfo<T>(info); - bool ret = m_conditions.insert(std::make_pair(hash,i)).second; - if ( !ret ) delete i; + bool insertKey(Condition::key_type hash, std::unique_ptr<ConditionsLoadInfo>& info) { + bool ret = m_conditions.insert(std::make_pair(hash,info.get())).second; + if ( ret ) info.release(); + else info.reset(); return ret; } + /// Add a new conditions key. T must inherit from class ConditionsContent::Info + template <typename T> bool insertKey(Condition::key_type hash, const T& info) { + std::unique_ptr<ConditionsLoadInfo> ptr(new LoadInfo<T>(info)); + return insertKey(hash, ptr); + } /// Add a new shared conditions dependency bool insertDependency(ConditionDependency* dep) { bool ret = m_derived.insert(std::make_pair(dep->key(),dep)).second; diff --git a/DDCond/include/DDCond/ConditionsDependencyHandler.h b/DDCond/include/DDCond/ConditionsDependencyHandler.h index 17f651d67..163769e50 100644 --- a/DDCond/include/DDCond/ConditionsDependencyHandler.h +++ b/DDCond/include/DDCond/ConditionsDependencyHandler.h @@ -38,18 +38,24 @@ namespace dd4hep { */ class ConditionsDependencyHandler : public ConditionResolver { public: - enum State { CREATED, RESOLVED }; - struct Created { - const ConditionDependency* dependency; - Condition::Object* condition; - State state; - Created() = default; - Created(const Created&) = default; - Created& operator=(const Created&) = default; - Created(const ConditionDependency* d, Condition::Object* o) : dependency(d), condition(o), state(CREATED) {} + enum State { INVALID, CREATED, RESOLVED }; + struct Work { + IOV iov; + ConditionUpdateContext context; + Condition::Object* condition = 0; + State state = INVALID; + Work() = delete; + Work(ConditionResolver* r, + const ConditionDependency* d, + ConditionUpdateUserContext* u, + const IOV& i) + : iov(i), context(r,d,&iov,u) {} + Work(const Work&) = default; + Work& operator=(const Work&) = default; }; typedef std::map<Condition::key_type, const ConditionDependency*> Dependencies; - typedef std::map<Condition::key_type, Created> CreatedConditions; + typedef std::map<Condition::key_type, Work*> WorkConditions; + protected: /// Reference to conditions manager ConditionsManagerObject* m_manager; @@ -62,17 +68,18 @@ namespace dd4hep { /// User defined optional processing parameter ConditionUpdateUserContext* m_userParam; /// The objects created during processing - CreatedConditions m_created; + WorkConditions m_created, m_todo; /// Handler's state State m_state = CREATED; - + Work* m_block; + public: /// Number of callbacks to the handler for monitoring mutable size_t num_callback; protected: /// Internal call to trigger update callback - Condition::Object* do_callback(const ConditionDependency* dep); + Condition::Object* do_callback(Work* dep); public: /// Initializing constructor @@ -84,7 +91,7 @@ namespace dd4hep { ~ConditionsDependencyHandler(); /// Access the conditions created during processing - const CreatedConditions& created() const { return m_created; } + //const CreatedConditions& created() const { return m_created; } /// 1rst pass: Compute/create the missing conditions void compute(); /// 2nd pass: Handler callback for the second turn to resolve missing dependencies @@ -101,8 +108,13 @@ namespace dd4hep { virtual ConditionsMap& conditionsMap() const override { return m_pool; } /// ConditionResolver implementation: Interface to access conditions. virtual Condition get(const ConditionKey& key) override { return get(key.hash); } + /// Interface to access conditions by conditions key + virtual Condition get(const ConditionKey& key, bool throw_if_not) override + { return get(key.hash, throw_if_not); } /// ConditionResolver implementation: Interface to access conditions - virtual Condition get(Condition::key_type key) override; + virtual Condition get(Condition::key_type key) override { return get(key, true); } + /// Interface to access conditions by hash value + virtual Condition get(Condition::key_type key, bool throw_if_not) override; /// Interface to access conditions by hash value of the DetElement (only valid at resolve!) virtual std::vector<Condition> get(DetElement de) override; /// Interface to access conditions by hash value of the DetElement (only valid at resolve!) diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h index 63ade841e..7c57dc1b0 100644 --- a/DDCond/include/DDCond/ConditionsManager.h +++ b/DDCond/include/DDCond/ConditionsManager.h @@ -94,7 +94,7 @@ namespace dd4hep { ConditionsManager(Object* p) : Handle<Object>(p) {} /// Constructor to assing handle of the same type - ConditionsManager(const ConditionsManager& c) : Handle<Object>(c) {} + ConditionsManager(const ConditionsManager& c) = default; /// Constructor to be used assigning from different type template <typename Q> ConditionsManager(const Handle<Q>& e) : Handle<Object>(e) {} @@ -108,6 +108,9 @@ namespace dd4hep { /// Initialize the object after having set the properties ConditionsManager& initialize(); + /// Access the detector description + Detector& detectorDescription() const; + /// Access to properties Property& operator[](const std::string& property_name) const; diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index c3cb35e9d..9752abe85 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -74,7 +74,7 @@ namespace dd4hep { public: /// Default constructor - ConditionsPool(ConditionsManager mgr); + ConditionsPool(ConditionsManager mgr, IOV* iov); /// Default destructor. Note: pool must be cleared by the subclass! virtual ~ConditionsPool(); /// Print pool basics @@ -115,7 +115,7 @@ namespace dd4hep { public: /// Default constructor - UpdatePool(ConditionsManager mgr); + UpdatePool(ConditionsManager mgr, IOV* iov); /// Default destructor. virtual ~UpdatePool(); /// Adopt all entries sorted by IOV. Entries will be removed from the pool diff --git a/DDCond/include/DDCond/ConditionsSlice.h b/DDCond/include/DDCond/ConditionsSlice.h index 943ad7083..6e795b47e 100644 --- a/DDCond/include/DDCond/ConditionsSlice.h +++ b/DDCond/include/DDCond/ConditionsSlice.h @@ -131,6 +131,8 @@ namespace dd4hep { ConditionsSlice(const ConditionsSlice& copy); /// Default destructor. virtual ~ConditionsSlice(); + + /// Total size of all conditions contained in the slice size_t size() const { return content->conditions().size()+content->derived().size(); } /// Access the map of conditions from the desired content const ConditionsContent::Conditions& conditions() const { return content->conditions();} @@ -140,6 +142,8 @@ namespace dd4hep { ConditionsContent::Conditions& missingConditions() { return m_missingConditions; } /// Access the map of missing computational conditions (only valid after preparation) ConditionsContent::Dependencies& missingDerivations() { return m_missingDerivations; } + /// Access the combined IOV of the slice from the pool + const IOV& iov() const; /// Clear the conditions content and the user pool. void reset(); /// Insert a set of conditions to the slice AND register them to the conditions manager. diff --git a/DDCond/src/ConditionsCleanup.cpp b/DDCond/src/ConditionsCleanup.cpp new file mode 100644 index 000000000..5deffdec7 --- /dev/null +++ b/DDCond/src/ConditionsCleanup.cpp @@ -0,0 +1,22 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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/ConditionsCleanup.h" + +using namespace dd4hep::cond; + +/// Cleanup operation +void ConditionsFullCleanup::operator()(ConditionsManager mgr) const { + mgr.clear(); +} diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp index 3d800d86d..2f39731fc 100644 --- a/DDCond/src/ConditionsDependencyHandler.cpp +++ b/DDCond/src/ConditionsDependencyHandler.cpp @@ -28,11 +28,24 @@ ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager mgr, m_userParam(user_param), num_callback(0) { const IOV& iov = m_pool.validity(); + //IOV full_iov(iov.iovType,IOV::Key(IOV::MIN_KEY,IOV::MAX_KEY)); + IOV full_iov(iov.iovType,IOV::Key(0,detail::makeTime(2099,12,31))); m_iovPool = m_manager->registerIOV(*iov.iovType, iov.keyData); + unsigned char* p = new unsigned char[dependencies.size()*sizeof(Work)]; + Dependencies::const_iterator idep = dependencies.begin(); + m_block = (Work*)p; + for(size_t i=0; i<dependencies.size(); ++i, ++idep, p+=sizeof(Work)) { + Work* w = new(p) Work(this,(*idep).second,user_param,full_iov); + m_todo.insert(std::make_pair((*idep).first,w)); + } } /// Default destructor ConditionsDependencyHandler::~ConditionsDependencyHandler() { + m_todo.clear(); + m_created.clear(); + if ( m_block ) delete [] m_block; + m_block = 0; } /// ConditionResolver implementation: Access to the detector description instance @@ -43,12 +56,9 @@ Detector& ConditionsDependencyHandler::detectorDescription() const { /// 1rst pass: Compute/create the missing conditions void ConditionsDependencyHandler::compute() { m_state = CREATED; - for( const auto& i : m_dependencies ) { - const ConditionDependency* dep = i.second; - Condition c = m_pool.get(dep->key()); - // If we would know, that dependencies are only ONE level, we could skip this search.... - if ( !c.isValid() ) { - do_callback(dep); + for( const auto& i : m_todo ) { + if ( !i.second->condition ) { + do_callback(i.second); continue; } // printout(INFO,"UserPool","Already calcluated: %s",d->name()); @@ -58,11 +68,28 @@ void ConditionsDependencyHandler::compute() { /// 2nd pass: Handler callback for the second turn to resolve missing dependencies void ConditionsDependencyHandler::resolve() { + size_t num_resolved = 0; + std::map<IOV::Key,ConditionsPool*> pools; m_state = RESOLVED; for( auto& c : m_created ) { - if ( c.second.state == RESOLVED ) continue; - c.second.state = RESOLVED; - c.second.dependency->callback->resolve(c.second.condition, *this); + Work* w = c.second; + if ( w->state == RESOLVED ) continue; + w->state = RESOLVED; + w->context.dependency->callback->resolve(w->condition, w->context); + ++num_resolved; + } + // Optimize pool interactions: Cache pool in map assuming there are only few pools created + for( auto& c : m_created ) { + Work* w = c.second; + ConditionsPool* p = 0; + auto res = pools.insert(make_pair(w->iov.keyData,p)); + if ( res.second ) { + p = m_manager->registerIOV(*w->iov.iovType, w->iov.keyData); + (*res.first).second = p; + } + p = (*res.first).second; + w->condition->iov = p->iov; + m_manager->registerUnlocked(*p, w->condition); } } @@ -84,38 +111,31 @@ std::vector<Condition> ConditionsDependencyHandler::get(Condition::detkey_type d } /// ConditionResolver implementation: Interface to access conditions -Condition ConditionsDependencyHandler::get(Condition::key_type key) { +Condition ConditionsDependencyHandler::get(Condition::key_type key, bool throw_if_not) { /// Check if the required condition is one of the newly created ones: auto e = m_created.find(key); if ( e != m_created.end() ) { - Created& c = (*e).second; - if ( c.state == CREATED ) { - c.state = RESOLVED; - c.dependency->callback->resolve(c.condition, *this); - return c.condition; + Work* w = (*e).second; + if ( w->state == CREATED ) { + w->state = RESOLVED; + w->context.dependency->callback->resolve(w->condition, w->context); + return w->condition; } } /// If we are not already resolving here, we follow the normal procedure Condition c = m_pool.get(key); if ( c.isValid() ) { - Condition::Object* obj = c.ptr(); - const IOV& required = m_pool.validity(); - if ( obj && obj->iov && IOV::key_is_contained(required.keyData,obj->iov->keyData) ) + return c; + } + auto i = m_todo.find(key); + if ( i != m_todo.end() ) { + c = do_callback((*i).second); + if ( c.isValid() ) { return c; - /// We should with normal pools never end up here, because the existing conditions - /// in a reasonable pool are valid for the IOV and we should have returned above. - 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. - const ConditionDependency* dep = (*i).second; - m_pool.remove(key); - return do_callback(dep); } } - Dependencies::const_iterator i = m_dependencies.find(key); - if ( i != m_dependencies.end() ) { - const ConditionDependency* dep = (*i).second; - return do_callback(dep); + if ( throw_if_not ) { + except("ConditionsDependencyHandler","Failed to resolve conditon:%16lX",key); } return Condition(); } @@ -123,23 +143,23 @@ Condition ConditionsDependencyHandler::get(Condition::key_type key) { /// Internal call to trigger update callback Condition::Object* -ConditionsDependencyHandler::do_callback(const ConditionDependency* dep) { +ConditionsDependencyHandler::do_callback(Work* work) { + const ConditionDependency* dep = work->context.dependency; try { - IOV iov(m_pool.validity().iovType); - ConditionUpdateContext ctxt(this, dep, m_userParam, &iov.reset().invert()); - Condition cond = (*dep->callback)(dep->target, ctxt); - Condition::Object* obj = cond.ptr(); - if ( obj ) { - obj->hash = dep->target.hash; - cond->setFlag(Condition::DERIVED); - cond->iov = m_pool.validityPtr(); + work->condition = (*dep->callback)(dep->target, work->context).ptr(); + if ( work->condition ) { + work->condition->iov = &work->iov; + work->condition->hash = dep->target.hash; + work->condition->setFlag(Condition::DERIVED); + work->state = CREATED; + //TEST cond->iov = m_pool.validityPtr(); // Must IMMEDIATELY insert to handle inter-dependencies. ++num_callback; - m_created[dep->target.hash] = Created(dep, obj); - m_pool.insert(cond); - m_manager->registerUnlocked(*m_iovPool, cond); + m_created[dep->target.hash] = work; + //TEST m_manager->registerUnlocked(*m_iovPool, work.condition); + m_pool.insert(work->condition); } - return obj; + return work->condition; } catch(const std::exception& e) { printout(ERROR,"ConditionDependency", diff --git a/DDCond/src/ConditionsManager.cpp b/DDCond/src/ConditionsManager.cpp index 69e548ac2..cf33735e0 100644 --- a/DDCond/src/ConditionsManager.cpp +++ b/DDCond/src/ConditionsManager.cpp @@ -161,6 +161,11 @@ PropertyManager& ConditionsManager::properties() const { return access()->properties(); } +/// Access the detector description +Detector& ConditionsManager::detectorDescription() const { + return access()->detectorDescription(); +} + /// Access to properties Property& ConditionsManager::operator[](const std::string& property_name) const { return access()->properties().property(property_name); diff --git a/DDCond/src/ConditionsPool.cpp b/DDCond/src/ConditionsPool.cpp index f35f3d0b3..039c33392 100644 --- a/DDCond/src/ConditionsPool.cpp +++ b/DDCond/src/ConditionsPool.cpp @@ -17,6 +17,7 @@ #include "DD4hep/Printout.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/detail/Handle.inl" +#include "DD4hep/ConditionsPrinter.h" #include "DD4hep/detail/ConditionsInterna.h" using std::string; @@ -27,8 +28,8 @@ DD4HEP_INSTANTIATE_HANDLE_NAMED(UpdatePool); DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsPool); /// Default constructor -ConditionsPool::ConditionsPool(ConditionsManager mgr) - : NamedObject(), m_manager(mgr), iov(0), age_value(AGE_NONE) +ConditionsPool::ConditionsPool(ConditionsManager mgr, IOV* i) + : NamedObject(), m_manager(mgr), iov(i), age_value(AGE_NONE) { InstanceCount::increment(this); } @@ -42,13 +43,22 @@ ConditionsPool::~ConditionsPool() { /// Print pool basics void ConditionsPool::print() const { printout(INFO,"ConditionsPool","+++ Conditions for pool with IOV: %-32s age:%3d [%4d entries]", - iov->str().c_str(), age_value, size()); + GetName(), age_value, size()); } /// Print pool basics void ConditionsPool::print(const string& opt) const { printout(INFO,"ConditionsPool","+++ %s Conditions for pool with IOV: %-32s age:%3d [%4d entries]", - opt.c_str(), iov->str().c_str(), age_value, size()); + opt.c_str(), GetName(), age_value, size()); + if ( opt == "*" || opt == "ALL" ) { + ConditionsPrinter printer(0); + RangeConditions range; + printer.summary = false; + printer.lineLength = 132; + const_cast<ConditionsPool*>(this)->select_all(range); + for( auto c : range ) + printer(c); + } } /// Listener invocation when a condition is registered to the cache @@ -62,7 +72,7 @@ void ConditionsPool::onRemove(Condition condition) { } /// Default constructor -UpdatePool::UpdatePool(ConditionsManager mgr) : ConditionsPool(mgr) +UpdatePool::UpdatePool(ConditionsManager mgr, IOV* i) : ConditionsPool(mgr, i) { } diff --git a/DDCond/src/ConditionsSlice.cpp b/DDCond/src/ConditionsSlice.cpp index fbf390a64..c65ef2062 100644 --- a/DDCond/src/ConditionsSlice.cpp +++ b/DDCond/src/ConditionsSlice.cpp @@ -46,6 +46,14 @@ ConditionsSlice::~ConditionsSlice() { InstanceCount::decrement(this); } +/// Access the combined IOV of the slice from the pool +const IOV& ConditionsSlice::iov() const { + if ( pool.get() ) return pool->validity(); + dd4hep::except("ConditionsSlice", + "pool-iov: Failed to access validity of non-existing pool."); + return pool->validity(); +} + /// Clear the conditions access and the user pool. void ConditionsSlice::reset() { if ( pool.get() ) pool->clear(); diff --git a/DDCond/src/Type1/Manager_Type1.cpp b/DDCond/src/Type1/Manager_Type1.cpp index ead797202..4ee6c0ab4 100644 --- a/DDCond/src/Type1/Manager_Type1.cpp +++ b/DDCond/src/Type1/Manager_Type1.cpp @@ -158,9 +158,9 @@ void Manager_Type1::initialize() { if ( !m_updatePool.get() ) { string typ = "DD4hep_Conditions_"+m_loaderType+"_Loader"; const void* argv_loader[] = {"ConditionsDataLoader", this, 0}; - const void* argv_pool[] = {this, 0}; + const void* argv_pool[] = {this, 0, 0}; m_loader.reset(createPlugin<ConditionsDataLoader>(typ,m_detDesc,2,argv_loader)); - m_updatePool.reset(createPlugin<UpdatePool>(m_updateType,m_detDesc,1,argv_pool)); + m_updatePool.reset(createPlugin<UpdatePool>(m_updateType,m_detDesc,2,argv_pool)); if ( !m_updatePool.get() ) { except("ConditionsManager","+++ The update pool of type %s cannot be created. [%s]", m_updateType.c_str(),Errors::noSys().c_str()); @@ -224,13 +224,13 @@ ConditionsPool* Manager_Type1::registerIOV(const IOVType& typ, IOV::Key key) { if ( i != pool->elements.end() ) { return (*i).second.get(); } - const void* argv_pool[] = {this, 0}; - shared_ptr<ConditionsPool> cond_pool(createPlugin<ConditionsPool>(m_poolType,m_detDesc,1,argv_pool)); IOV* iov = new IOV(&typ); iov->type = typ.type; iov->keyData = key; - cond_pool->iov = iov; + const void* argv_pool[] = {this, iov, 0}; + shared_ptr<ConditionsPool> cond_pool(createPlugin<ConditionsPool>(m_poolType,m_detDesc,2,argv_pool)); pool->elements.insert(make_pair(key,cond_pool)); + printout(INFO,"ConditionsManager","Created IOV Pool for:%s",iov->str().c_str()); return cond_pool.get(); } @@ -245,6 +245,10 @@ bool Manager_Type1::registerUnlocked(ConditionsPool& pool, Condition cond) { cond->iov = pool.iov; cond->setFlag(Condition::ACTIVE); pool.insert(cond); +#if 0 + printout(INFO,"ConditionsManager","Register condition %016lX %s [%s] IOV:%s", + cond->hash, cond.name(), cond->address.c_str(), pool.iov->str().c_str()); +#endif __callListeners(m_onRegister, &ConditionsListener::onRegisterCondition, cond); return true; } diff --git a/DDCond/src/plugins/ConditionsLinearPool.cpp b/DDCond/src/plugins/ConditionsLinearPool.cpp index bcc0951ca..15aa9e927 100644 --- a/DDCond/src/plugins/ConditionsLinearPool.cpp +++ b/DDCond/src/plugins/ConditionsLinearPool.cpp @@ -54,7 +54,7 @@ namespace dd4hep { } public: /// Default constructor - ConditionsLinearPool(ConditionsManager mgr); + ConditionsLinearPool(ConditionsManager mgr, IOV* iov); /// Default destructor virtual ~ConditionsLinearPool(); @@ -113,13 +113,15 @@ namespace dd4hep { { public: /// Default constructor - ConditionsLinearUpdatePool(ConditionsManager mgr) - : ConditionsLinearPool<MAPPING,BASE>(mgr) + ConditionsLinearUpdatePool(ConditionsManager mgr, IOV*) + : ConditionsLinearPool<MAPPING,BASE>(mgr,0) { + this->BASE::SetTitle("ConditionsLinearUpdatePool"); } /// Default destructor - virtual ~ConditionsLinearUpdatePool() {} + virtual ~ConditionsLinearUpdatePool() { + } /// Adopt all entries sorted by IOV. Entries will be removed from the pool virtual size_t popEntries(UpdatePool::UpdateEntries& entries) final { @@ -193,7 +195,12 @@ using namespace dd4hep::cond; /// Default constructor template<typename MAPPING, typename BASE> -ConditionsLinearPool<MAPPING,BASE>::ConditionsLinearPool(ConditionsManager mgr) : BASE(mgr) { +ConditionsLinearPool<MAPPING,BASE>::ConditionsLinearPool(ConditionsManager mgr, IOV* i) + : BASE(mgr, i) +{ + + this->BASE::SetName(i ? i->str().c_str() : "Unknown IOV"); + this->BASE::SetTitle("ConditionsLinearPool"); InstanceCount::increment(this); } @@ -201,6 +208,7 @@ ConditionsLinearPool<MAPPING,BASE>::ConditionsLinearPool(ConditionsManager mgr) template<typename MAPPING, typename BASE> ConditionsLinearPool<MAPPING,BASE>::~ConditionsLinearPool() { clear(); + detail::deletePtr(this->BASE::iov); InstanceCount::decrement(this); } @@ -225,9 +233,17 @@ namespace { dd4hep::except("ConditionsLinearPool","++ Insufficient arguments: arg[0] = ConditionManager!"); return ConditionsManager(0); } + IOV* _iov(int argc, char** argv) { + if ( argc > 1 ) { + IOV* i = (IOV*)argv[1]; + return i; + } + dd4hep::except("ConditionsLinearPool","++ Insufficient arguments: arg[1] = IOV!"); + return nullptr; + } #define _CR(fun,x,b,y) void* fun(dd4hep::Detector&, int argc, char** argv) \ - { return new b<x<Condition::Object*>,y>(_mgr(argc,argv)); } + { return new b<x<Condition::Object*>,y>(_mgr(argc,argv), _iov(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 diff --git a/DDCond/src/plugins/ConditionsMappedPool.cpp b/DDCond/src/plugins/ConditionsMappedPool.cpp index ec5322e69..d09a3b211 100644 --- a/DDCond/src/plugins/ConditionsMappedPool.cpp +++ b/DDCond/src/plugins/ConditionsMappedPool.cpp @@ -207,7 +207,9 @@ using namespace dd4hep::cond; /// Default constructor template<typename MAPPING, typename BASE> -ConditionsMappedPool<MAPPING,BASE>::ConditionsMappedPool(ConditionsManager mgr) : BASE(mgr) { +ConditionsMappedPool<MAPPING,BASE>::ConditionsMappedPool(ConditionsManager mgr) : BASE(mgr,0) { + this->BASE::SetName(""); + this->BASE::SetTitle("ConditionsMappedPool"); InstanceCount::increment(this); } diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp index ecf150488..4cf732546 100644 --- a/DDCond/src/plugins/ConditionsUserPool.cpp +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -487,15 +487,17 @@ ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required, begin(m_conditions), end(m_conditions), begin(cond_missing), COMP()); long num_cond_miss = last_cond-begin(cond_missing); + cond_missing.resize(num_cond_miss); printout(num_cond_miss==0 ? DEBUG : INFO,"UserPool", - "Found %ld missing conditions out of %ld conditions.", + "%ld conditions out of %ld conditions are MISSING.", num_cond_miss, slice_cond.size()); CalcMissing::iterator last_calc = set_difference(begin(slice_calc), end(slice_calc), begin(m_conditions), end(m_conditions), begin(calc_missing), COMP()); long num_calc_miss = last_calc-begin(calc_missing); + calc_missing.resize(num_calc_miss); printout(num_calc_miss==0 ? DEBUG : INFO,"UserPool", - "Found %ld missing derived conditions out of %ld conditions.", + "%ld derived conditions out of %ld conditions are MISSING.", num_calc_miss, slice_calc.size()); #if 0 auto iter = begin(calc_missing); @@ -513,6 +515,7 @@ ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required, if ( num_cond_miss > 0 ) { if ( do_load ) { ConditionsDataLoader::LoadedItems loaded; + //size_t updates = m_loader->load_many(required, cond_missing, loaded, pool_iov); size_t updates = m_loader->load_many(required, cond_missing, loaded, pool_iov); if ( updates > 0 ) { // Need to compute the intersection: All missing entries are required.... @@ -523,7 +526,7 @@ ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required, begin(load_missing), COMP()); long num_load_miss = load_last-begin(load_missing); printout(num_load_miss==0 ? DEBUG : ERROR,"UserPool", - "Found %ld out of %ld conditions, which CANNOT be loaded...", + "%ld out of %ld conditions CANNOT be loaded...", num_load_miss, loaded.size()); if ( do_output_miss ) { copy(begin(load_missing), load_last, inserter(slice_miss_cond, slice_miss_cond.begin())); diff --git a/DDCore/include/DD4hep/AlignmentsCalculator.h b/DDCore/include/DD4hep/AlignmentsCalculator.h index cb10ca9ff..c7741ac94 100644 --- a/DDCore/include/DD4hep/AlignmentsCalculator.h +++ b/DDCore/include/DD4hep/AlignmentsCalculator.h @@ -21,6 +21,9 @@ /// Namespace for the AIDA detector description toolkit namespace dd4hep { + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace cond { class ConditionUpdateContext; } + /// Namespace for the alignment part of the AIDA detector description toolkit namespace align { @@ -33,8 +36,6 @@ namespace dd4hep { class AlignmentsCalculator { public: - typedef std::map<DetElement, Delta> Deltas; - /// Object encapsulating the result of a computation call to the alignments calculator /** * \author M.Frank @@ -58,6 +59,64 @@ namespace dd4hep { size_t total() const { return computed+missing; } }; + /// Functor for path ordered maps as they are needed for the calculator + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class PathOrdering { + public: + bool operator()(const DetElement& a, const DetElement& b) const + { return a.path() < b.path(); } + }; + + typedef std::map<DetElement,const Delta*,PathOrdering> OrderedDeltas; + + + /// Scanner to find all alignment deltas in the detector hierarchy + /** + * The deltas are collected in the appropriate container suited for the + * calculator object, so that no re-ordering is necessary. + * + * Usage: + * + * /// Interface to client Callback in order to update the condition + * Condition AlignmentCall::operator()(const ConditionKey& key, + * ConditionUpdateContext& ctxt) { + * .... + * DetectorScanner().scan(AlignmentsCalculator::Scanner(ctxt,deltas),top); + * .... + * } + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class Scanner { + public: + /// Reference to the user pool taking into account IOV intersections + cond::ConditionUpdateContext& context; + /// Collection container + OrderedDeltas& deltas; + public: + /// Default constructor + Scanner() = delete; + /// Initializing constructor + Scanner(cond::ConditionUpdateContext& m, OrderedDeltas& d) : context(m), deltas(d) {} + /// Default move constructor is disabled + Scanner(cond::ConditionUpdateContext& m, OrderedDeltas&& p) = delete; + /// R-value copy from a temporary + Scanner(Scanner&& copy) = default; + /// Copy constructor + Scanner(const Scanner& copy) = default; + /// Default destructor + ~Scanner() = default; + /// Assignment operator + Scanner& operator=(const Scanner& copy) = default; + /// Callback to output alignments information + virtual int operator()(DetElement de, int) const final; + }; public: /// Default constructor @@ -67,7 +126,13 @@ namespace dd4hep { /// Assignment operator AlignmentsCalculator& operator=(const AlignmentsCalculator& mgr) = delete; /// Compute all alignment conditions of the internal dependency list - Result compute(const Deltas& deltas, ConditionsMap& alignments) const; + Result compute(const std::map<DetElement, Delta>& deltas, + ConditionsMap& alignments) const; + /// Compute all alignment conditions of the internal dependency list + Result compute(const std::map<DetElement, const Delta*>& deltas, + ConditionsMap& alignments) const; + /// Optimized call using already properly ordered Deltas + Result compute(const OrderedDeltas& deltas, ConditionsMap& alignments) const; }; /// Add results diff --git a/DDCore/include/DD4hep/ComponentProperties.h b/DDCore/include/DD4hep/ComponentProperties.h index 797f23b10..2bb40d9e6 100644 --- a/DDCore/include/DD4hep/ComponentProperties.h +++ b/DDCore/include/DD4hep/ComponentProperties.h @@ -247,7 +247,26 @@ namespace dd4hep { * \author M.Frank * \version 1.0 */ - class PropertyConfigurable { + class PropertyInterface { + public: + /// Default destructor + virtual ~PropertyInterface() = default; + /// Access to the properties of the object + virtual PropertyManager& properties() = 0; + /// Check property for existence + virtual bool hasProperty(const std::string& name) const = 0; + /// Access single property + virtual Property& property(const std::string& name) = 0; + }; + + /// Property object as base class for all objects supporting properties + /** + * Note: This class cannot be saved to a ROOT file! + * + * \author M.Frank + * \version 1.0 + */ + class PropertyConfigurable : virtual public PropertyInterface { protected: /// Property pool PropertyManager m_properties; @@ -258,13 +277,13 @@ namespace dd4hep { /// Default destructor virtual ~PropertyConfigurable(); /// Access to the properties of the object - PropertyManager& properties() { + virtual PropertyManager& properties() override { return m_properties; } /// Check property for existence - bool hasProperty(const std::string& name) const; + virtual bool hasProperty(const std::string& name) const override; /// Access single property - Property& property(const std::string& name); + virtual Property& property(const std::string& name) override; /// Declare property template <typename T> void declareProperty(const std::string& nam, T& val); /// Declare property diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h index 2d0da5c45..8f19a8b2e 100644 --- a/DDCore/include/DD4hep/ConditionDerived.h +++ b/DDCore/include/DD4hep/ConditionDerived.h @@ -28,9 +28,12 @@ namespace dd4hep { namespace cond { /// Forward declarations + class DependencyBuilder; class ConditionResolver; class ConditionDependency; class ConditionUpdateCall; + class ConditionUpdateContext; + class ConditionUpdateUserContext; /// ConditionUpdateUserContext class used by the derived conditions calculation mechanism /** @@ -66,8 +69,12 @@ namespace dd4hep { virtual ConditionsMap& conditionsMap() const = 0; /// Interface to access conditions by conditions key virtual Condition get(const ConditionKey& key) = 0; + /// Interface to access conditions by conditions key + virtual Condition get(const ConditionKey& key, bool throw_if_not) = 0; /// Interface to access conditions by hash value virtual Condition get(Condition::key_type key) = 0; + /// Interface to access conditions by hash value + virtual Condition get(Condition::key_type key, bool throw_if_not) = 0; /// Interface to access conditions by hash value of the DetElement (only valid at resolve!) virtual std::vector<Condition> get(DetElement de) = 0; /// Interface to access conditions by hash value of the DetElement (only valid at resolve!) @@ -76,69 +83,119 @@ namespace dd4hep { /// ConditionUpdateContext class used by the derived conditions calculation mechanism /** + * This is the central object used by the functional callbacks to + * build derived conditions. All optionally necessary information + * can and must be accessed by this object. + * + * Please node: + * 1) Be careful when resolving other conditions + * These calls are IN GENERAL ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + * 2) Only accessing the conditions using the context ensure that the + * IOV of the resulting derived condition is correct. + * The conditions resolver does not affect the resulting IOV. + * 3) Though the access to the resolver under certain circumstances + * is useful, you should always be aware that to IOV intersection + * shall be wrong, since these accessed conditions are not taken + * into account. + * * \author M.Frank * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - class ConditionUpdateContext { + class ConditionUpdateContext final { public: + /// Internal reference to the resolver to access other conditions (Be careful) ConditionResolver* resolver; + /// The dependency to be handled within this context const ConditionDependency* dependency; - ConditionUpdateUserContext* parameter; + /// The reference to the combined IOV resulting from the cumputation IOV* iov; + /// A refernce to the user parameter + ConditionUpdateUserContext* parameter; + + public: /// Initializing constructor ConditionUpdateContext(ConditionResolver* r, const ConditionDependency* d, - ConditionUpdateUserContext* parameter, - IOV* iov); + IOV* iov, + ConditionUpdateUserContext* parameter); + /// Throw exception on conditions access failure void accessFailure(const ConditionKey& key_value) const; + /// 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 to condition object by dependency key - Condition conditionByHash(Condition::key_type key_value) const; + const ConditionKey& key(size_t which) const ; + /// Access user parameter template<typename Q> Q* param() const { return static_cast<Q*>(parameter); } - /// 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; - } - accessFailure(key_value); - throw std::runtime_error("ConditionUpdateCall"); + + /// Access to all conditions of a detector element. + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + std::vector<Condition> conditions(DetElement det) const { + return conditions(det.key()); } + + /// Access to all conditions of a detector element. + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + std::vector<Condition> conditions(Condition::detkey_type det_key) const; + + /// Access to condition object by dependency key + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + Condition condition(const ConditionKey& key_value) const; + + /// Access to condition object by dependency key + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + Condition condition(Condition::key_type key_value) const; + + /// Access to condition object by dependency key + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + Condition condition(Condition::key_type key_value, bool throw_if_not) const; + /// 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; - } - accessFailure(key_value); - throw std::runtime_error("ConditionUpdateCall"); - } + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + template<typename T> T& get(const ConditionKey& key_value); + /// 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); - } + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + template<typename T> const T& get(const ConditionKey& key_value) const; + /// 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); - } + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + template<typename T> T& get(Condition::key_type key_value); + + /// Access of other conditions data from the resolver + /** Careful: This limits the validity! + * ONLY VALID AT RESOLVE ! + * Otherwise the resulting IOV shall be wrong ! + */ + template<typename T> const T& get(Condition::key_type key_value) const; }; /// Callback interface @@ -173,9 +230,9 @@ namespace dd4hep { } /// Interface to client callback in order to update/create the condition virtual Condition operator()(const ConditionKey& target, - const ConditionUpdateContext& ctxt) = 0; + ConditionUpdateContext& ctxt) = 0; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition /* c */, ConditionResolver& /* resolver */) {} + virtual void resolve(Condition /* c */, ConditionUpdateContext& /* ctxt */) {} }; /// Condition dependency definition @@ -216,13 +273,13 @@ namespace dd4hep { /// Default constructor ConditionDependency(); /// Access the dependency key - Condition::key_type key() const { return target.hash; } + Condition::key_type key() const { return target.hash; } /// Access the dependency key - const char* name() const { return target.name.c_str(); } + const char* name() const { return target.name.c_str(); } /// Add use count to the object - ConditionDependency* addRef() { ++m_refCount; return this; } + ConditionDependency* addRef() { ++m_refCount; return this; } /// Release object. May not be used any longer - void release() { if ( --m_refCount <= 0 ) delete this; } + void release() { if ( --m_refCount <= 0 ) delete this; } }; /// Condition dependency builder @@ -253,37 +310,52 @@ namespace dd4hep { /// Initializing constructor inline ConditionUpdateContext::ConditionUpdateContext(ConditionResolver* resolv, const ConditionDependency* dep, - ConditionUpdateUserContext* user_param, - IOV* i) - : resolver(resolv), dependency(dep), parameter(user_param), iov(i) + IOV* i, + ConditionUpdateUserContext* user_param) + : resolver(resolv), dependency(dep), iov(i), parameter(user_param) { } /// Access to dependency keys - inline const ConditionKey& ConditionUpdateContext::key(size_t which) const { + inline const ConditionKey& + ConditionUpdateContext::key(size_t which) const { return dependency->dependencies[which]; } - /// Access to condition object by dependency key - inline Condition ConditionUpdateContext::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 of other conditions data from the resolver + template<typename T> inline T& + ConditionUpdateContext::get(const ConditionKey& key_value) { + Condition cond = condition(key_value); + if ( cond.isValid() ) { + return cond.get<T>(); /// return already bound data to wanted type + } + accessFailure(key_value); + throw std::runtime_error("ConditionUpdateCall"); } - - /// Access to condition object by dependency index - inline Condition ConditionUpdateContext::condition(size_t which) const { - const ConditionKey& key_value = this->key(which); - return this->condition(key_value); + + /// Access of other conditions data from the resolver + template<typename T> inline const T& + ConditionUpdateContext::get(const ConditionKey& key_value) const { + Condition cond = condition(key_value); + if ( cond.isValid() ) { + return cond.get<T>(); /// return already bound data to wanted type + } + accessFailure(key_value); + throw std::runtime_error("ConditionUpdateCall"); + } + + /// Access of other conditions data from the resolver + template<typename T> inline T& + ConditionUpdateContext::get(Condition::key_type key_value) { + return condition(key_value).get<T>(); } - /// Access to condition object by dependency key - inline Condition ConditionUpdateContext::conditionByHash(Condition::key_type 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."); + /// Access of other conditions data from the resolver + template<typename T> inline const T& + ConditionUpdateContext::get(Condition::key_type key_value) const { + return condition(key_value).get<T>(); } - + } /* End namespace cond */ } /* End namespace dd4hep */ #endif /* DD4HEP_DDCORE_CONDITIONDERIVED_H */ diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 76a95b779..3379b6730 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -62,6 +62,7 @@ namespace dd4hep { typedef unsigned int mask_type; public: + /// Flags to steer the conditions conversion to string enum StringFlags { WITH_IOV = 1<<0, WITH_ADDRESS = 1<<1, @@ -72,6 +73,7 @@ namespace dd4hep { NO_NAME = 1<<20, NONE }; + /// Flags to indicate the conditions type ans state enum ConditionState { INACTIVE = 0, ACTIVE = 1<<0, @@ -85,11 +87,26 @@ namespace dd4hep { PRESSURE_DERIVED = 1<<8|DERIVED, ALIGNMENT_DELTA = 1<<9, ALIGNMENT_DERIVED = 1<<10|DERIVED, - // Keep bit 8-15 for other generic types + // Keep bit 10-15 for other generic types // Bit 16-31 is reserved for user classifications USER_FLAGS_FIRST = 1<<16, USER_FLAGS_LAST = 1<<31 }; + /// Flags to indicate conditions item ranges (low word of the conditions key) + enum ConditionItemRangeKeys { + FIRST_ITEM_KEY = 0x0U, + LAST_ITEM_KEY = ~0x0U + }; + /// Flags to indicate conditions detector ranges (high word of the conditions key) + enum ConditionDetectorRangeKeys { + FIRST_DET_KEY = 0x0U, + LAST_DET_KEY = ~0x0U + }; + /// Flags to indicate global conditions ranges + enum { + FIRST_KEY = 0x0ULL, + LAST_KEY = ~0x0ULL + }; /// Abstract base for processing callbacks to conditions objects /** diff --git a/DDCore/include/DD4hep/ConditionsMap.h b/DDCore/include/DD4hep/ConditionsMap.h index 47d949df3..16019c9d2 100644 --- a/DDCore/include/DD4hep/ConditionsMap.h +++ b/DDCore/include/DD4hep/ConditionsMap.h @@ -59,12 +59,12 @@ namespace dd4hep { class ConditionsMap { public: enum { - FIRST_ITEM = 0x0, - LAST_ITEM = ~0x0 + FIRST_ITEM = Condition::FIRST_ITEM_KEY, + LAST_ITEM = Condition::LAST_ITEM_KEY }; enum { - FIRST_KEY = 0x0ULL, - LAST_KEY = ~0x0ULL + FIRST_KEY = Condition::FIRST_KEY, + LAST_KEY = Condition::LAST_KEY }; public: diff --git a/DDCore/include/DD4hep/IOV.h b/DDCore/include/DD4hep/IOV.h index e27c6cea4..7490a1d97 100644 --- a/DDCore/include/DD4hep/IOV.h +++ b/DDCore/include/DD4hep/IOV.h @@ -15,6 +15,7 @@ // C/C++ include files #include <string> +#include <limits> #include <algorithm> /// Namespace for the AIDA detector description toolkit @@ -71,8 +72,12 @@ namespace dd4hep { typedef long Key_second_type; typedef std::pair<Key_first_type,Key_second_type> Key; - enum { INVALID_KEY = 0 }; - + enum { + INVALID_KEY = 0, + MIN_KEY = std::numeric_limits<long>::min(), + MAX_KEY = std::numeric_limits<long>::max() + }; + /// Reference to IOV type const IOVType* iovType = 0; /// IOV key (if second==first, discrete, otherwise range) diff --git a/DDCore/include/DD4hep/Plugins.h b/DDCore/include/DD4hep/Plugins.h index 5c7acba74..cd17f528a 100644 --- a/DDCore/include/DD4hep/Plugins.h +++ b/DDCore/include/DD4hep/Plugins.h @@ -167,8 +167,10 @@ namespace dd4hep { #define DD4HEP_PLUGINSVC_FACTORY(type,name,signature,serial) \ namespace { \ struct DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) { \ - DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial)() { DD4HEP_FACTORY_CALL(type,#name,signature); } \ - } DD4HEP_PLUGINSVC_CNAME(s____typeFactory__,serial); \ + DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial)() { \ + DD4HEP_FACTORY_CALL(type,#name,signature); }}; \ + static const DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) \ + DD4HEP_PLUGINSVC_CNAME(s____typeFactory__,serial); \ } diff --git a/DDCore/include/XML/UriReader.h b/DDCore/include/XML/UriReader.h index 55bde5705..1e5d169f1 100644 --- a/DDCore/include/XML/UriReader.h +++ b/DDCore/include/XML/UriReader.h @@ -43,17 +43,17 @@ namespace dd4hep { * \ingroup DD4HEP_XML */ struct UserContext { - UserContext() {} - UserContext(const UserContext&) {} - virtual ~UserContext() {} + UserContext() = default; + UserContext(const UserContext&) = default; + virtual ~UserContext() = default; }; public: /// Default constructor - UriReader() {} + UriReader() = default; /// Default destructor virtual ~UriReader(); /// Access to local context - virtual UserContext* context() { return 0; } + virtual UserContext* context() = 0; /// Resolve a given URI to a string containing the data virtual bool load(const std::string& system_id, std::string& data); /// Resolve a given URI to a string containing the data with context diff --git a/DDCore/src/AlignmentsCalculator.cpp b/DDCore/src/AlignmentsCalculator.cpp index 88cfede65..d60e3a3c5 100644 --- a/DDCore/src/AlignmentsCalculator.cpp +++ b/DDCore/src/AlignmentsCalculator.cpp @@ -18,6 +18,7 @@ #include "DD4hep/ConditionsMap.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/MatrixHelpers.h" +#include "DD4hep/ConditionDerived.h" #include "DD4hep/detail/AlignmentsInterna.h" using namespace dd4hep; @@ -69,11 +70,7 @@ namespace dd4hep { class Calculator::Context { public: - struct PathOrdering { - bool operator()(const DetElement& a, const DetElement& b) const - { return a.path() < b.path(); } - }; - typedef std::map<DetElement,size_t,PathOrdering> DetectorMap; + typedef std::map<DetElement,size_t,AlignmentsCalculator::PathOrdering> DetectorMap; typedef std::map<unsigned int,size_t> Keys; typedef std::vector<Entry> Entries; @@ -103,8 +100,22 @@ namespace dd4hep { } /* End namespace dd4hep */ //static PrintLevel s_PRINT = DEBUG; -static PrintLevel s_PRINT = INFO; +//static PrintLevel s_PRINT = INFO; +static PrintLevel s_PRINT = WARNING; +/// Callback to output alignments information +int AlignmentsCalculator::Scanner::operator()(DetElement de, int) const { + if ( de.isValid() ) { + Condition::key_type key(ConditionKey::KeyMaker(de.key(),align::Keys::deltaKey).hash); + Condition c = context.condition(key, false); + if ( c.isValid() ) { + const Delta& d = c.get<Delta>(); + deltas.insert(std::make_pair(de,&d)); + } + return 1; + } + return 0; +} /// Compute all alignment conditions of the lower levels Result Calculator::compute(Context& context, Entry& e) const { @@ -181,6 +192,22 @@ void Calculator::resolve(Context& context, DetElement detector) const { resolve(context, c.second); } +/// Optimized call using already properly ordered Deltas +Result AlignmentsCalculator::compute(const OrderedDeltas& deltas, + ConditionsMap& alignments) const +{ + Result result; + Calculator obj; + Calculator::Context context(alignments); + for( const auto& i : deltas ) + context.insert(i.first, i.second); + for( const auto& i : deltas ) + obj.resolve(context,i.first); + for( auto& i : context.entries ) + result += obj.compute(context, i); + return result; +} + /// Compute all alignment conditions of the internal dependency list Result AlignmentsCalculator::compute(const std::map<DetElement, Delta>& deltas, ConditionsMap& alignments) const @@ -197,16 +224,42 @@ Result AlignmentsCalculator::compute(const std::map<DetElement, Delta>& deltas, // corrections are calculated in the wrong order ie. not top -> down the // hierarchy, but in "some" order depending on the pointer values! // - std::map<DetElement,Delta,Calculator::Context::PathOrdering> ordered_deltas; + OrderedDeltas ordered_deltas; + for( const auto& i : deltas ) + ordered_deltas.insert(std::make_pair(i.first, &i.second)); + return compute(ordered_deltas, alignments); +} +/// Compute all alignment conditions of the internal dependency list +Result AlignmentsCalculator::compute(const std::map<DetElement, const Delta*>& deltas, + ConditionsMap& alignments) const +{ + Result result; + Calculator obj; + Calculator::Context context(alignments); + // This is a tricky one. We absolutely need the detector elements ordered + // by their depth aka. the distance to /world. + // Unfortunately one cannot use the raw pointer of the DetElement here, + // But has to insert them in a map which is ordered by the DetElement path. + // + // Otherwise memory randomization gives us the wrong order and the + // corrections are calculated in the wrong order ie. not top -> down the + // hierarchy, but in "some" order depending on the pointer values! + // + OrderedDeltas ordered_deltas; for( const auto& i : deltas ) ordered_deltas.insert(i); - - for( const auto& i : ordered_deltas ) - context.insert(i.first, &(i.second)); - for( const auto& i : ordered_deltas ) - obj.resolve(context,i.first); - for( auto& i : context.entries ) - result += obj.compute(context, i); - return result; + return compute(ordered_deltas, alignments); } + +// The map is used by the Alignments calculator +typedef AlignmentsCalculator::OrderedDeltas OrderedMap; +// Have only a weak reference here! +inline std::ostream& operator << (std::ostream& s, const DetElement& ) { return s; } + +#include "Parsers/Parsers.h" +DD4HEP_DEFINE_PARSER_DUMMY(OrderedMap) +#include "DD4hep/detail/BasicGrammar_inl.h" +#include "DD4hep/detail/ConditionsInterna.h" +DD4HEP_DEFINE_PARSER_GRAMMAR(OrderedMap,eval_none<OrderedMap>) +DD4HEP_DEFINE_CONDITIONS_TYPE(OrderedMap) diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp index 54e060451..041f6d84c 100644 --- a/DDCore/src/ConditionDerived.cpp +++ b/DDCore/src/ConditionDerived.cpp @@ -25,6 +25,53 @@ using namespace dd4hep::cond; ConditionUpdateUserContext::~ConditionUpdateUserContext() { } +/// Access to condition object by dependency key +Condition ConditionUpdateContext::condition(const ConditionKey& key_value) const { + Condition c = resolver->get(key_value); + if ( c.isValid() ) { + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(c.iov()); + return c; + } + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition:"+key_value.name); +} + +/// Access to all conditions of a detector element. Careful: This limits the validity! +std::vector<Condition> ConditionUpdateContext::conditions(Condition::detkey_type det_key) const { + std::vector<Condition> v = resolver->get(det_key); + for(Condition c : v) { + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(c.iov()); + } + return v; +} + +/// Access to condition object by dependency key +Condition ConditionUpdateContext::condition(Condition::key_type key_value) const { + Condition c = resolver->get(key_value); + if ( c.isValid() ) { + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(c.iov()); + return c; + } + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition."); +} + +/// Access to condition object by dependency key +Condition ConditionUpdateContext::condition(Condition::key_type key_value, + bool throw_if_not) const { + Condition c = resolver->get(key_value, throw_if_not); + if ( c.isValid() ) { + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(c.iov()); + return c; + } + else if ( throw_if_not ) { + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition."); + } + return Condition(); +} + /// Standard destructor ConditionUpdateCall::ConditionUpdateCall() : m_refCount(1) { InstanceCount::increment(this); diff --git a/DDCore/src/ConditionsPrinter.cpp b/DDCore/src/ConditionsPrinter.cpp index 91e200784..7386d9f58 100644 --- a/DDCore/src/ConditionsPrinter.cpp +++ b/DDCore/src/ConditionsPrinter.cpp @@ -142,8 +142,9 @@ int ConditionsPrinter::operator()(Condition cond) const { string new_prefix = prefix; new_prefix.assign(prefix.length(),' '); if ( !cond.is_bound() ) { - printout(this->printLevel,name,"++ %s \tPath:%s Key:%16llX Type:%s", - new_prefix.c_str(), cond.name(), cond.key(), "<Unbound-Condition>"); + printout(this->printLevel,name,"++ %s \tPath:%s Key:%16llX Type:%s (%s)", + new_prefix.c_str(), cond.name(), cond.key(), "<Unbound-Condition>", + typeName(typeid(*ptr)).c_str()); return 1; } const type_info& type = cond.typeInfo(); diff --git a/DDCore/src/IOV.cpp b/DDCore/src/IOV.cpp index f52c1a9ec..c9ab9166f 100644 --- a/DDCore/src/IOV.cpp +++ b/DDCore/src/IOV.cpp @@ -13,6 +13,7 @@ // Framework includes #include "DD4hep/IOV.h" +#include "DD4hep/Primitives.h" // C/C++ include files #include <climits> @@ -139,8 +140,9 @@ string IOV::str() const { iovType->name.c_str(),int(iovType->type),keyData.first, keyData.second); } else if ( iovType->name == "epoch" ) { - time_t since = keyData.first; - time_t until = keyData.second; + static long int max_time = detail::makeTime(2099,12,31,24,59,59); + time_t since = std::min(std::max(long(0),keyData.first), max_time); + time_t until = std::min(std::max(long(0),keyData.second), max_time); 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)); diff --git a/DDCore/src/XML/UriReader.cpp b/DDCore/src/XML/UriReader.cpp index fc9054647..efd54db09 100644 --- a/DDCore/src/XML/UriReader.cpp +++ b/DDCore/src/XML/UriReader.cpp @@ -14,17 +14,19 @@ // Framework include files #include "XML/UriReader.h" +using namespace std; + /// Default destructor dd4hep::xml::UriReader::~UriReader() { } /// Resolve a given URI to a string containing the data -bool dd4hep::xml::UriReader::load(const std::string& system_id, std::string& data) { +bool dd4hep::xml::UriReader::load(const string& system_id, string& data) { return this->load(system_id, context(), data); } /// Inform reader about a locally (e.g. by XercesC) handled source load -void dd4hep::xml::UriReader::parserLoaded(const std::string& system_id) { +void dd4hep::xml::UriReader::parserLoaded(const string& system_id) { this->parserLoaded(system_id, context()); } @@ -45,21 +47,21 @@ dd4hep::xml::UriContextReader::~UriContextReader() { } /// Resolve a given URI to a string containing the data -bool dd4hep::xml::UriContextReader::load(const std::string& system_id, std::string& data) { +bool dd4hep::xml::UriContextReader::load(const string& system_id, string& data) { return m_reader->load(system_id, context(), data); } /// Resolve a given URI to a string containing the data -bool dd4hep::xml::UriContextReader::load(const std::string& system_id, UserContext* ctxt, std::string& data) { +bool dd4hep::xml::UriContextReader::load(const string& system_id, UserContext* ctxt, string& data) { return m_reader->load(system_id, ctxt, data); } /// Inform reader about a locally (e.g. by XercesC) handled source load -void dd4hep::xml::UriContextReader::parserLoaded(const std::string& system_id) { +void dd4hep::xml::UriContextReader::parserLoaded(const string& system_id) { m_reader->parserLoaded(system_id, context()); } /// Inform reader about a locally (e.g. by XercesC) handled source load -void dd4hep::xml::UriContextReader::parserLoaded(const std::string& system_id, UserContext* ctxt) { +void dd4hep::xml::UriContextReader::parserLoaded(const string& system_id, UserContext* ctxt) { m_reader->parserLoaded(system_id, ctxt); } diff --git a/DDDB/include/DDDB/DDDBHelper.h b/DDDB/include/DDDB/DDDBHelper.h index 78011d088..1c50a756e 100644 --- a/DDDB/include/DDDB/DDDBHelper.h +++ b/DDDB/include/DDDB/DDDBHelper.h @@ -20,6 +20,7 @@ #define DD4HEP_DDDB_DDDBHELPER_H // Framework includes +#include "DD4hep/ComponentProperties.h" #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/DD4hepUnits.h" #include "DD4hep/FieldTypes.h" @@ -49,7 +50,7 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_XML */ - class DDDBHelper { + class DDDBHelper : public PropertyConfigurable { public: typedef std::vector<std::pair<std::string, VisAttr> > VisAttrs; typedef std::map<std::string,std::pair<DetElement,std::string> > Det_Conditions; @@ -61,11 +62,13 @@ namespace dd4hep { virtual ~DDDBHelper(); /// Access XML reader object - xml::UriReader* xmlReader() const { return m_xmlReader; } + xml::UriReader* xmlReader() const { return m_xmlReader; } + /// Access XML reader object + template<typename T> T* reader() const { return dynamic_cast<T*>(m_xmlReader); } /// Set XML reader object - void setXmlReader(xml::UriReader* rdr) { m_xmlReader = rdr; } + void setXmlReader(xml::UriReader* rdr) { m_xmlReader = rdr; } /// Access local database representation - dddb* detectorDescription() const { return m_detDesc; } + dddb* detectorDescription() const { return m_detDesc; } /// Set XML reader object void setDetectorDescription(dddb* geo); /// Access visualization attribute for a given volume by path diff --git a/DDDB/include/DDDB/DDDBReader.h b/DDDB/include/DDDB/DDDBReader.h index cc42c6f2d..45e693ef6 100644 --- a/DDDB/include/DDDB/DDDBReader.h +++ b/DDDB/include/DDDB/DDDBReader.h @@ -22,6 +22,7 @@ // Framework includes #include "XML/UriReader.h" #include "DDDB/DDDBReaderContext.h" +#include "DD4hep/ComponentProperties.h" /// Namespace for the AIDA detector description toolkit @@ -37,7 +38,9 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_XML */ - class DDDBReader : public dd4hep::xml::UriReader { + class DDDBReader : public dd4hep::xml::UriReader, + public PropertyConfigurable + { public: /// Standard constructor DDDBReader(const std::string& dir=""); @@ -48,27 +51,35 @@ namespace dd4hep { /// Access data directory const std::string& directory() const { return m_directory; } /// Set data match - void setMatch(const std::string& dir) { m_match = dir; } + void setMatch(const std::string& dir) { m_match = dir; } /// Access data match - const std::string& match() const { return m_match; } + const std::string& match() const { return m_match; } /// Access to local context - virtual UserContext* context() { return &m_context; } + virtual UserContext* context(); + + /// Process load request. Calls getObject at the end. */ /// Resolve a given URI to a string containing the data virtual bool load(const std::string& system_id, std::string& buffer); /// Resolve a given URI to a string containing the data virtual bool load(const std::string& system_id, UserContext* ctxt, std::string& buffer); + /** If you have to modify intervals of validity, do it in here. + * Only this routine is called by EVERY parsing request + */ /// Inform reader about a locally (e.g. by XercesC) handled source load virtual void parserLoaded(const std::string& system_id); /// Inform reader about a locally (e.g. by XercesC) handled source load virtual void parserLoaded(const std::string& system_id, UserContext* ctxt); + + /** Main object reader routine */ /// Read raw XML object from the database / file - virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data); + virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data) = 0; - protected: + protected: std::string m_directory; std::string m_match; + /// Reader context DDDBReaderContext m_context; }; - } /* End namespace DDDB */ -} /* End namespace dd4hep */ + } /* End namespace DDDB */ + } /* End namespace dd4hep */ #endif /* DD4HEP_DDDB_DDDBFILEREADER_H */ diff --git a/DDDB/include/DDDB/DDDBReaderContext.h b/DDDB/include/DDDB/DDDBReaderContext.h index 3698dec9d..3a0aa0481 100644 --- a/DDDB/include/DDDB/DDDBReaderContext.h +++ b/DDDB/include/DDDB/DDDBReaderContext.h @@ -38,9 +38,9 @@ namespace dd4hep { */ class DDDBReaderContext : public xml::UriReader::UserContext { public: - long long int event_time = 0; - long long int valid_since = 0; - long long int valid_until = 0; + long event_time = 0; + long valid_since = 0; + long valid_until = 0; std::string doc, channel, match; /// Standard constructor DDDBReaderContext() = default; diff --git a/DDDB/include/Detector/DeAlignmentCall.h b/DDDB/include/Detector/DeAlignmentCall.h index c3ecc2d9e..15aeac8a1 100644 --- a/DDDB/include/Detector/DeAlignmentCall.h +++ b/DDDB/include/Detector/DeAlignmentCall.h @@ -38,7 +38,7 @@ namespace gaudi { virtual ~DeAlignmentCall() = default; /// Interface to client Callback in order to update the condition virtual dd4hep::Condition operator()(const dd4hep::ConditionKey& /* key */, - const dd4hep::cond::ConditionUpdateContext& ctxt) override final; + dd4hep::cond::ConditionUpdateContext& ctxt) override final; }; } // End namespace gaudi diff --git a/DDDB/include/Detector/DeVPConditionCalls.h b/DDDB/include/Detector/DeVPConditionCalls.h index a49d1667d..3c411227f 100644 --- a/DDDB/include/Detector/DeVPConditionCalls.h +++ b/DDDB/include/Detector/DeVPConditionCalls.h @@ -67,9 +67,9 @@ namespace gaudi { /// Default destructor virtual ~DeVPStaticConditionCall() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const Context& context) override final; + virtual Condition operator()(const ConditionKey& key, Context& context) override final; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition c, Resolver& resolver) override final; + virtual void resolve(Condition c, Context& context) override final; }; /// Condition derivation call to build the dynamic Velo-pixel DetElement condition information @@ -83,16 +83,16 @@ namespace gaudi { public: DetElement detector; Catalog* catalog = 0; - VPUpdateContext* context = 0; + VPUpdateContext* velo_context = 0; /// Initializing constructor DeVPIOVConditionCall(DetElement de, Catalog* cat, VPUpdateContext* ctx) - : detector(de), catalog(cat), context(ctx) {} + : detector(de), catalog(cat), velo_context(ctx) {} /// Default destructor virtual ~DeVPIOVConditionCall() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const Context& context) override final; + virtual Condition operator()(const ConditionKey& key, Context& context) override final; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition c, Resolver& resolver) override; + virtual void resolve(Condition c, Context& context) override; }; /// Condition derivation call to build the dynamic Velo-pixel DetElement condition information @@ -110,11 +110,7 @@ namespace gaudi { /// Default destructor virtual ~DeVPConditionCall() = default; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition c, Resolver& resolver) override final; - void add_generic(detail::DeVPObject* vp, - std::vector<DeVPGeneric>& cont, - const std::vector<DeVPGenericStatic>& src, - Resolver& resolver) const; + virtual void resolve(Condition c, Context& context) override final; }; } // End namespace gaudi diff --git a/DDDB/include/Detector/DeVeloConditionCalls.h b/DDDB/include/Detector/DeVeloConditionCalls.h index 58c89049b..f9dd6c163 100644 --- a/DDDB/include/Detector/DeVeloConditionCalls.h +++ b/DDDB/include/Detector/DeVeloConditionCalls.h @@ -67,9 +67,9 @@ namespace gaudi { /// Default destructor virtual ~DeVeloStaticConditionCall() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const Context& context) override final; + virtual Condition operator()(const ConditionKey& key, Context& context) override final; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition c, Resolver& resolver) override final; + virtual void resolve(Condition c, Context& context) override final; }; /// Condition derivation call to build the dynamic Velo-pixel DetElement condition information @@ -83,16 +83,16 @@ namespace gaudi { public: DetElement detector; Catalog* catalog = 0; - VeloUpdateContext* context = 0; + VeloUpdateContext* velo_context = 0; /// Initializing constructor DeVeloIOVConditionCall(DetElement de, Catalog* cat, VeloUpdateContext* ctx) - : detector(de), catalog(cat), context(ctx) {} + : detector(de), catalog(cat), velo_context(ctx) {} /// Default destructor virtual ~DeVeloIOVConditionCall() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const Context& context) override final; + virtual Condition operator()(const ConditionKey& key, Context& context) override final; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition c, Resolver& resolver) override; + virtual void resolve(Condition c, Context& context) override; }; /// Condition derivation call to build the dynamic Velo-pixel DetElement condition information @@ -110,7 +110,7 @@ namespace gaudi { /// Default destructor virtual ~DeVeloConditionCall() = default; /// Interface to client callback for resolving references or to use data from other conditions - virtual void resolve(Condition c, Resolver& resolver) override final; + virtual void resolve(Condition c, Context& context) override final; }; } // End namespace gaudi diff --git a/DDDB/include/Detector/IDetService.h b/DDDB/include/Detector/IDetService.h new file mode 100644 index 000000000..3954e1b06 --- /dev/null +++ b/DDDB/include/Detector/IDetService.h @@ -0,0 +1,110 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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_IDETSERVICE_H +#define DD4HEP_IDETSERVICE_H + +// Framework includes +#include "DDCond/ConditionsSlice.h" +#include "DDCond/ConditionsCleanup.h" + + +/// Gaudi namespace declaration +namespace gaudi { + + /// Example gaudi-like service to access dd4hep conditions + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + class IDetService { + public: + /// Short-cut to the ConditionsManager + typedef dd4hep::cond::ConditionsManager ConditionsManager; + /// Other useful type definitions and type short-cuts + typedef dd4hep::cond::ConditionUpdateUserContext Context; + typedef dd4hep::cond::ConditionDependency Dependency; + typedef dd4hep::cond::ConditionsCleanup Cleanup; + typedef dd4hep::DetElement DetElement; + typedef dd4hep::Condition Condition; + typedef dd4hep::IOV::Key_first_type EventStamp; + typedef dd4hep::IOVType IOVType; + typedef std::shared_ptr<dd4hep::cond::ConditionsContent> Content; + typedef std::shared_ptr<dd4hep::cond::ConditionsSlice> Slice; + + /// Default destructor + virtual ~IDetService() = default; + + /** General accessors to manipulate the conditions */ + /// Accessor: get refernece to the conditions manager + virtual ConditionsManager manager() const = 0; + + /// Accessor: Access IOV Type from conditions manager + virtual const IOVType* iovType(const std::string& identifier) const = 0; + + /** Content management interface routines */ + /// Open content creation context + virtual Content openContent(const std::string& name) = 0; + + /// Retrive existing and registered conditions content object by name + virtual Content getContent(const std::string& name) = 0; + + /// Add a condition address to the content. Condition is identified by it's global key + virtual void addContent(Content& content, + Condition::key_type key, + const std::string& address) = 0; + + /// Add a condition address to the content. Condition is identified by the detector and item name + virtual void addContent(Content& content, + DetElement det, + const std::string& item, + const std::string& address) = 0; + + /// Add a condition functor for a derived condition to the content + virtual void addContent(Content& content, + Dependency* call) = 0; + + /// Open content creation context + virtual void closeContent(Content& content) = 0; + + /// Remove content object from cache. + virtual bool removeContent(Content& content) = 0; + + /** Slice management interface routines */ + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + virtual Slice project(Content &content, + Context *ctx, + const IOVType *typ, + EventStamp stamp) = 0; + + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + virtual Slice project(Content &content, + Context *ctx, + const std::string &typ, + EventStamp stamp) = 0; + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + virtual Slice project(const std::string &content, + Context *ctx, + const std::string &typ, + EventStamp stamp) = 0; + /// Invoke slice cleanup + virtual void cleanup(const Cleanup& cleaner) = 0; + }; +} // End namespace gaudi +#endif // DD4HEP_IDETSERVICE_H diff --git a/DDDB/src/DDDBReader.cpp b/DDDB/src/DDDBReader.cpp index a7858f1be..d89eb3251 100644 --- a/DDDB/src/DDDBReader.cpp +++ b/DDDB/src/DDDBReader.cpp @@ -19,6 +19,7 @@ // Framework includes #include "DDDB/DDDBReader.h" +#include "DDDB/DDDBReaderContext.h" #include "DD4hep/Printout.h" #include "DD4hep/Primitives.h" @@ -39,6 +40,11 @@ DDDBReader::DDDBReader(const std::string& dir) m_context.match = m_match; } +/// Access to local context +xml::UriReader::UserContext* DDDBReader::context() { + return &m_context; +} + /// Resolve a given URI to a string containing the data bool DDDBReader::load(const string& system_id, string& buffer) { return xml::UriReader::load(system_id, buffer); @@ -73,7 +79,7 @@ bool DDDBReader::load(const string& system_id, /// Inform reader about a locally (e.g. by XercesC) handled source load void DDDBReader::parserLoaded(const std::string& system_id) { - return xml::UriReader::parserLoaded(system_id); + xml::UriReader::parserLoaded(system_id); } /// Inform reader about a locally (e.g. by XercesC) handled source load @@ -82,11 +88,3 @@ void DDDBReader::parserLoaded(const std::string& /* system_id */, UserContext* c c->valid_since = c->event_time; c->valid_until = c->event_time; } - -int DDDBReader::getObject(const string& sys_id, UserContext* /* ctxt */, string& /* out */) -{ - except("DDDBReader","DDDBReader::getObject is a virtual method, " - "which must be overloaded by the concrete instance!! sys_id:%s", sys_id.c_str()); - return 0; -} - diff --git a/DDDB/src/Detector/DeAlignmentCall.cpp b/DDDB/src/Detector/DeAlignmentCall.cpp index ac441a420..68e3ed1f7 100644 --- a/DDDB/src/Detector/DeAlignmentCall.cpp +++ b/DDDB/src/Detector/DeAlignmentCall.cpp @@ -29,19 +29,22 @@ using namespace dd4hep::align; /// Interface to client Callback in order to update the condition Condition gaudi::DeAlignmentCall::operator()(const ConditionKey& /* key */, - const ConditionUpdateContext& ctxt) { + ConditionUpdateContext& ctxt) { + namespace tools = dd4hep::detail::tools; Condition cond; UserPool* conditions = dynamic_cast<UserPool*>(&ctxt.resolver->conditionsMap()); if ( conditions ) { + typedef AlignmentsCalculator::OrderedDeltas Deltas; ConditionsHashMap slice; AlignmentsCalculator calc; const IOV& iov = conditions->validity(); ConditionsManager mgr = ctxt.resolver->manager(); cond = Condition(gaudi::Keys::alignmentsComputedKeyName,"Calculator"); - AlignmentsCalculator::Deltas& deltas = cond.bind<AlignmentsCalculator::Deltas>(); - DetectorScanner(deltaCollector(*conditions, deltas), top); - //slice->pool->flags |= cond::UserPool::PRINT_INSERT; + Deltas& deltas = cond.bind<Deltas>(); + conditions->print(""); + // Test. Need to be replaced by a special scanner + DetectorScanner().scan(AlignmentsCalculator::Scanner(ctxt,deltas),top); AlignmentsCalculator::Result ares = calc.compute(deltas, slice); ConditionsPool* iov_pool = mgr.registerIOV(*iov.iovType,iov.key()); for(auto i=std::begin(slice.data); i != std::end(slice.data); ++i) { @@ -49,7 +52,8 @@ Condition gaudi::DeAlignmentCall::operator()(const ConditionKey& /* key */, mgr.registerUnlocked(*iov_pool,c); conditions->insert(c); } - printout(INFO,"Align","Alignments:(C:%ld,M:%ld)", ares.computed, ares.missing); + printout(INFO,"Align","Alignments:(C:%ld,M:%ld) IOV:%s", + ares.computed, ares.missing, ctxt.iov->str().c_str()); return cond; } except("DeAlignmentCall","No conditions slice present!"); diff --git a/DDDB/src/Detector/DeVPConditionCalls.cpp b/DDDB/src/Detector/DeVPConditionCalls.cpp index 76722b6f2..516a7ad02 100644 --- a/DDDB/src/Detector/DeVPConditionCalls.cpp +++ b/DDDB/src/Detector/DeVPConditionCalls.cpp @@ -21,7 +21,7 @@ using namespace gaudi; /// Interface to client Callback in order to update the condition -dd4hep::Condition DeVPStaticConditionCall::operator()(const ConditionKey& key, const Context& context) { +dd4hep::Condition DeVPStaticConditionCall::operator()(const ConditionKey& key, Context& context) { VPUpdateContext* ctxt = dynamic_cast<VPUpdateContext*>(context.parameter); KeyMaker km(key.hash); auto ide = ctxt->detectors.find(km.values.det_key); @@ -38,7 +38,7 @@ dd4hep::Condition DeVPStaticConditionCall::operator()(const ConditionKey& key, c } /// Interface to client callback for resolving references or to use data from other conditions -void DeVPStaticConditionCall::resolve(Condition c, Resolver& resolver) { +void DeVPStaticConditionCall::resolve(Condition c, Context& context) { DeStatic s(c); if ( s->clsID == DeVP::classID() ) { // Velo main element DeVPStatic vp = s; @@ -52,7 +52,7 @@ void DeVPStaticConditionCall::resolve(Condition c, Resolver& resolver) { for ( const auto& i : elts ) { DetElement de = i.first; KeyMaker key(de.key(), Keys::staticKey); - DeStatic cond = resolver.get(key.hash); + DeStatic cond = context.condition(key.hash); const std::string& path = de.path(); if ( path.find("/VPLeft") != std::string::npos || path.find("/VPRight") != std::string::npos ) { switch( i.second ) { @@ -60,28 +60,28 @@ void DeVPStaticConditionCall::resolve(Condition c, Resolver& resolver) { break; case 1: side = cond; - side->parent = vp.access(); + side->parent = vp.access(); side->de_user |= VP::SIDE; vp->sides.push_back(side); printout(INFO,"DeVPStatic","Add Side[%03ld]: %s",vp->sides.size()-1,path.c_str()); break; case 2: support = cond; - support->parent = side.access(); + support->parent = side.access(); support->de_user |= VP::SUPPORT; vp->supports.push_back(support); printout(INFO,"DeVPStatic","Add Support[%03ld]: %s",vp->supports.size()-1,path.c_str()); break; case 3: module = cond; - module->parent = support.access(); + module->parent = support.access(); module->de_user |= VP::MODULE; vp->modules.push_back(module); printout(INFO,"DeVPStatic","Add Module[%03ld]: %s",vp->modules.size()-1,path.c_str()); break; case 4: ladder = cond; - ladder->parent = module.access(); + ladder->parent = module.access(); ladder->de_user |= VP::LADDER; vp->ladders.push_back(ladder); printout(INFO,"DeVPStatic","Add Ladder[%03ld]: %s",vp->ladders.size()-1,path.c_str()); @@ -111,7 +111,7 @@ void DeVPStaticConditionCall::resolve(Condition c, Resolver& resolver) { } /// Interface to client Callback in order to update the condition -dd4hep::Condition DeVPIOVConditionCall::operator()(const ConditionKey&, const Context&) { +dd4hep::Condition DeVPIOVConditionCall::operator()(const ConditionKey&, Context&) { DeIOV iov; if ( catalog->classID == DeVPSensor::classID() ) // DeVPSensor iov = DeIOV(new detail::DeVPSensorObject()); @@ -123,33 +123,33 @@ dd4hep::Condition DeVPIOVConditionCall::operator()(const ConditionKey&, const Co } /// Interface to client callback for resolving references or to use data from other conditions -void DeVPIOVConditionCall::resolve(Condition cond, Resolver& resolver) { +void DeVPIOVConditionCall::resolve(Condition cond, Context& context) { DeIOV iov(cond); Condition::detkey_type det_key = iov->detector.key(); KeyMaker kalign(det_key,dd4hep::align::Keys::alignmentKey); KeyMaker kstatic(det_key,Keys::staticKey); /// Check that the alignments are computed. We need them here! - if ( !context->alignments_done.isValid() ) { - context->alignments_done = resolver.get(Keys::alignmentsComputedKey); + if ( !velo_context->alignments_done.isValid() ) { + velo_context->alignments_done = context.condition(Keys::alignmentsComputedKey); } - std::vector<Condition> conds = resolver.get(det_key); - iov->de_static = resolver.get(kstatic.hash); - iov->detectorAlignment = resolver.get(kalign.hash); + std::vector<Condition> conds = context.conditions(det_key); + iov->de_static = context.condition(kstatic.hash); + iov->detectorAlignment = context.condition(kalign.hash); for ( Condition c : conds ) iov->conditions.insert(std::make_pair(c.item_key(),c)); iov->initialize(); } -void DeVPConditionCall::add_generic( detail::DeVPObject* vp, - std::vector<DeVPGeneric>& cont, - const std::vector<DeVPGenericStatic>& src, - Resolver& resolver) const +static void add_generic( detail::DeVPObject* vp, + std::vector<DeVPGeneric>& cont, + const std::vector<DeVPGenericStatic>& src, + dd4hep::cond::ConditionUpdateContext& context) { for ( const auto& i : src ) { - KeyMaker key(i->detector.key(), Keys::deKey); - DeVPGeneric gen = resolver.get(key.hash); + dd4hep::ConditionKey::KeyMaker key(i->detector.key(), Keys::deKey); + DeVPGeneric gen = context.condition(key.hash); cont.push_back(gen); for ( const auto& j : i->sensors ) gen->sensors.push_back(vp->sensors[j->sensorNumber]); @@ -158,23 +158,23 @@ void DeVPConditionCall::add_generic( detail::DeVPObject* vp, } /// Interface to client callback for resolving references or to use data from other conditions -void DeVPConditionCall::resolve(Condition cond, Resolver& resolver) { +void DeVPConditionCall::resolve(Condition cond, Context& context) { DeIOV iov(cond); DeVP vp(cond); - DeVPIOVConditionCall::resolve(cond, resolver); + DeVPIOVConditionCall::resolve(cond, context); DeVPStatic s = vp.access()->vp_static; vp->sensors.resize(s->sensors.size()); for ( const auto& i : s->sensors ) { if ( i.isValid() ) { KeyMaker key(i->detector.key(), Keys::deKey); - DeVPSensor sens = resolver.get(key.hash); + DeVPSensor sens = context.condition(key.hash); vp->sensors[i->sensorNumber] = sens; printout(INFO,"DeVP","Add Sensor[%03ld]: %s",long(i->sensorNumber),i->detector.path().c_str()); } } - add_generic(vp.ptr(), vp->sides, s->sides, resolver); - add_generic(vp.ptr(), vp->supports, s->supports, resolver); - add_generic(vp.ptr(), vp->modules, s->modules, resolver); - add_generic(vp.ptr(), vp->ladders, s->ladders, resolver); + add_generic(vp.ptr(), vp->sides, s->sides, context); + add_generic(vp.ptr(), vp->supports, s->supports, context); + add_generic(vp.ptr(), vp->modules, s->modules, context); + add_generic(vp.ptr(), vp->ladders, s->ladders, context); } diff --git a/DDDB/src/Detector/DeVeloConditionCalls.cpp b/DDDB/src/Detector/DeVeloConditionCalls.cpp index 8d1f18635..67093009a 100644 --- a/DDDB/src/Detector/DeVeloConditionCalls.cpp +++ b/DDDB/src/Detector/DeVeloConditionCalls.cpp @@ -22,7 +22,7 @@ using namespace std; using namespace gaudi; /// Interface to client Callback in order to update the condition -dd4hep::Condition DeVeloStaticConditionCall::operator()(const ConditionKey& key, const Context& context) { +dd4hep::Condition DeVeloStaticConditionCall::operator()(const ConditionKey& key, Context& context) { VeloUpdateContext* ctxt = dynamic_cast<VeloUpdateContext*>(context.parameter); KeyMaker km(key.hash); auto ide = ctxt->detectors.find(km.values.det_key); @@ -39,7 +39,7 @@ dd4hep::Condition DeVeloStaticConditionCall::operator()(const ConditionKey& key, } /// Interface to client callback for resolving references or to use data from other conditions -void DeVeloStaticConditionCall::resolve(Condition c, Resolver& resolver) { +void DeVeloStaticConditionCall::resolve(Condition c, Context& context) { DeStatic s(c); if ( s->clsID == DeVelo::classID() ) { // Velo main element DeVeloStatic vp = s; @@ -54,7 +54,7 @@ void DeVeloStaticConditionCall::resolve(Condition c, Resolver& resolver) { for ( const auto& i : elts ) { DetElement de = i.first; KeyMaker key(de.key(), Keys::staticKey); - DeStatic cond = resolver.get(key.hash); + DeStatic cond = context.condition(key.hash); const string& path = de.path(); bool left = path.find("/VeloLeft/Module") != string::npos || path.find("/VeloLeft") == path.length()-9; bool right = path.find("/VeloRight/Module") != string::npos || path.find("/VeloRight") == path.length()-10; @@ -119,7 +119,7 @@ void DeVeloStaticConditionCall::resolve(Condition c, Resolver& resolver) { } /// Interface to client Callback in order to update the condition -dd4hep::Condition DeVeloIOVConditionCall::operator()(const ConditionKey&, const Context&) { +dd4hep::Condition DeVeloIOVConditionCall::operator()(const ConditionKey&, Context&) { DeIOV iov; if ( catalog->classID == DeVeloSensor::classID() || catalog->classID == 1008102 || catalog->classID == 1008103 ) // DeVeloSensor iov = DeIOV(new detail::DeVeloSensorObject()); @@ -131,20 +131,20 @@ dd4hep::Condition DeVeloIOVConditionCall::operator()(const ConditionKey&, const } /// Interface to client callback for resolving references or to use data from other conditions -void DeVeloIOVConditionCall::resolve(Condition cond, Resolver& resolver) { +void DeVeloIOVConditionCall::resolve(Condition cond, Context& context) { DeIOV iov(cond); Condition::detkey_type det_key = iov->detector.key(); KeyMaker kalign(det_key,dd4hep::align::Keys::alignmentKey); KeyMaker kstatic(det_key,Keys::staticKey); /// Check that the alignments are computed. We need them here! - if ( !context->alignments_done.isValid() ) { - context->alignments_done = resolver.get(Keys::alignmentsComputedKey); + if ( !velo_context->alignments_done.isValid() ) { + velo_context->alignments_done = context.condition(Keys::alignmentsComputedKey); } - vector<Condition> conds = resolver.get(det_key); - iov->de_static = resolver.get(kstatic.hash); - iov->detectorAlignment = resolver.get(kalign.hash); + vector<Condition> conds = context.conditions(det_key); + iov->de_static = context.condition(kstatic.hash); + iov->detectorAlignment = context.condition(kalign.hash); for ( Condition c : conds ) iov->conditions.insert(make_pair(c.item_key(),c)); iov->initialize(); @@ -164,7 +164,7 @@ namespace { void add_sensors( DeVeloGeneric gen, DeVeloGenericStatic src, map<DeVeloSensorStatic,DeVeloSensor>& mapping, - dd4hep::cond::ConditionResolver& resolver) + dd4hep::cond::ConditionUpdateContext& context) { gen->sensors.reserve(src->sensors.size()); for (DeVeloSensorStatic i : src->sensors) { @@ -176,18 +176,18 @@ namespace { } for (detail::DeVeloGenericStaticObject* i : src->children) { dd4hep::ConditionKey::KeyMaker key(i->detector.key(), Keys::deKey); - DeVeloGeneric child = resolver.get(key.hash); + DeVeloGeneric child = context.condition(key.hash); gen->children.push_back(child.ptr()); - add_sensors(child, DeVeloGenericStatic(i), mapping, resolver); + add_sensors(child, DeVeloGenericStatic(i), mapping, context); } } } /// Interface to client callback for resolving references or to use data from other conditions -void DeVeloConditionCall::resolve(Condition cond, Resolver& resolver) { +void DeVeloConditionCall::resolve(Condition cond, Context& context) { DeIOV iov(cond); DeVelo vp(cond); - DeVeloIOVConditionCall::resolve(cond, resolver); + DeVeloIOVConditionCall::resolve(cond, context); DeVeloStatic s = vp.access()->vp_static; map<DeVeloSensorStatic,DeVeloSensor> sensorMapping; @@ -195,7 +195,7 @@ void DeVeloConditionCall::resolve(Condition cond, Resolver& resolver) { for ( const auto& i : s->sensors[DeVeloFlags::ALL] ) { if ( i.isValid() ) { KeyMaker key(i->detector.key(), Keys::deKey); - DeVeloSensor sens = resolver.get(key.hash); + DeVeloSensor sens = context.condition(key.hash); if ( !sens.isValid() ) { cout << "Problem Mapping " << (void*)i.ptr() << " ---> " << (void*)sens.ptr() << " " << i->detector.path() @@ -207,16 +207,16 @@ void DeVeloConditionCall::resolve(Condition cond, Resolver& resolver) { } for(size_t iside = 0; iside<3; ++iside) { - add_sensors(vp->sensors[iside], s->sensors[iside], sensorMapping); - add_sensors(vp->rSensors[iside], s->rSensors[iside], sensorMapping); - add_sensors(vp->phiSensors[iside], s->phiSensors[iside], sensorMapping); + add_sensors(vp->sensors[iside], s->sensors[iside], sensorMapping); + add_sensors(vp->rSensors[iside], s->rSensors[iside], sensorMapping); + add_sensors(vp->phiSensors[iside], s->phiSensors[iside], sensorMapping); add_sensors(vp->rphiSensors[iside], s->rphiSensors[iside], sensorMapping); - add_sensors(vp->puSensors[iside], s->puSensors[iside], sensorMapping); + add_sensors(vp->puSensors[iside], s->puSensors[iside], sensorMapping); } for ( auto side : s->sides ) { dd4hep::ConditionKey::KeyMaker key(side->detector.key(), Keys::deKey); - DeVeloGeneric child = resolver.get(key.hash); + DeVeloGeneric child = context.condition(key.hash); vp->sides.push_back(child); - add_sensors(child, side, sensorMapping, resolver); + add_sensors(child, side, sensorMapping, context); } } diff --git a/DDDB/src/plugins/CondDB2DDDB.cpp b/DDDB/src/plugins/CondDB2DDDB.cpp index 6430693d4..4638760ef 100644 --- a/DDDB/src/plugins/CondDB2DDDB.cpp +++ b/DDDB/src/plugins/CondDB2DDDB.cpp @@ -1762,18 +1762,21 @@ namespace dd4hep { xml_doc->name = context->locals.obj_path; xml_doc->context.doc = xml_doc->id; xml_doc->context.event_time = ctx->event_time; - xml_doc->context.valid_since = 0; - xml_doc->context.valid_until = 0; + xml_doc->context.valid_since = 0;//ctx->valid_since; + xml_doc->context.valid_until = 0;//ctx->valid_until; docs.insert(make_pair(doc_path,xml_doc->addRef())); - //if ( str_upper(doc_path).find("/VP/") != string::npos ) { - // printout(ALWAYS,"load_dddb","Loading document: %s",doc_path.c_str()); - //} - xml::UriContextReader reader(rdr, &xml_doc->context); xml_doc_holder_t doc(xml_handler_t().load(fp, &reader)); xml_h e = doc.root(); context->print(xml_doc); + //if ( str_upper(doc_path).find("/VP/") != string::npos ) + printout(DEBUG,"load_dddb","Loading document: %s IOV: %ld [%ld,%ld]", + xml_doc->id.c_str(), + xml_doc->context.event_time, + xml_doc->context.valid_since, + xml_doc->context.valid_until); + if ( e ) { if ( !key.empty() ) { stringstream str; @@ -1859,9 +1862,16 @@ namespace dd4hep { if ( argc >= 3 && argv[2] != 0 ) { obj_path = argv[2]; } - if ( argc >= 4 && argv[3] != 0 ) { - long evt_time = *(long*)argv[3]; - ctx->event_time = evt_time; + if ( argc == 4 && argv[3] != 0 ) { + long long int evt_time = *(long long int*)argv[3]; + ctx->event_time = evt_time; + } + if ( argc == 5 && argv[3] != 0 && argv[4] != 0) { + long long int iov_start = *(long long int*)argv[3]; + long long int iov_end = *(long long int*)argv[4]; + ctx->event_time = (iov_start+iov_end)/2; + ctx->valid_since = iov_start; + ctx->valid_until = iov_end; } config_context(ctxt, rdr, sys_id, obj_path); load_dddb_entity<ACTION>(&ctxt,0,0,ctxt.locals.xml_doc->id); diff --git a/DDDB/src/plugins/DDDBConditionsLoader.cpp b/DDDB/src/plugins/DDDBConditionsLoader.cpp index cb2830f08..dbed5c8d9 100644 --- a/DDDB/src/plugins/DDDBConditionsLoader.cpp +++ b/DDDB/src/plugins/DDDBConditionsLoader.cpp @@ -107,22 +107,29 @@ namespace { private: Loaded& loaded; const IOV& req_iov; - public: - IOV iov; - + /// Resulting IOV + IOV iov; public: /// Initializing constructor GroupCollector(const IOV& i, Loaded& l) - : loaded(l), req_iov(i), iov(req_iov.iovType) {} + : loaded(l), req_iov(i), iov(req_iov.iovType) + { + iov.reset().invert(); + } /// ConditionsListener overload: onRegister new condition virtual void onRegisterCondition(Condition cond, void* param) { Condition::Object* c = cond.ptr(); if ( c && param == this && req_iov.iovType == c->iov->iovType && - IOV::key_is_contained(c->iov->keyData,req_iov.keyData) ) + IOV::key_is_contained(req_iov.keyData,c->iov->keyData) ) { loaded.insert(make_pair(c->hash,cond)); + /// This is not entirely correct: + /// There may be more conditions loaded than required + /// and hence the interval of the pool bigger. + /// But we do not want to make another map-lookup! + iov.iov_intersection(c->iov->keyData); } } }; @@ -296,25 +303,25 @@ size_t DDDBConditionsLoader::load_many(const IOV& req_iov, bool print_results = isActivePrintLevel(DEBUG); m_mgr->callOnRegister(make_pair(&listener,&listener),true); listener.iov.reset().invert(); - for(const auto& url : urls ) { + for( const auto& url : urls ) { loadDocument(local_reader, url.first, url.second); if ( !print_results ) continue; printout(DEBUG,"DDDBLoader","++ Loaded %3ld conditions from %s.",loaded.size()-loaded_len,url.first.c_str()); loaded_len = loaded.size(); } if ( print_results ) { - for(const auto& e : loaded ) { + for( const auto& e : loaded ) { const Condition& cond = e.second; printout(INFO,"DDDBLoader","++ %16llX: %s -> %s",cond.key(),cond->value.c_str(),cond.name()); } } conditions_validity = listener.iov; } - catch(const exception& e) { + catch( const exception& e ) { printout(ERROR,"DDDBLoader","+++ Load exception: %s",e.what()); throw; } - catch(...) { + catch( ... ) { printout(ERROR,"DDDBLoader","+++ UNKNWON Load exception."); throw; } diff --git a/DDDB/src/plugins/DDDBDerivedCondTest.cpp b/DDDB/src/plugins/DDDBDerivedCondTest.cpp index 9d07ab421..57daa06ee 100644 --- a/DDDB/src/plugins/DDDBDerivedCondTest.cpp +++ b/DDDB/src/plugins/DDDBDerivedCondTest.cpp @@ -80,12 +80,12 @@ namespace { } virtual ~ConditionUpdate1() { } /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const ConditionUpdateContext& ctxt) { + virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& ctxt) override final { printout(context.level,"ConditionUpdate1","++ Building dependent condition: %s",key.name.c_str()); Condition target(key.name,"Alignment"); try { AlignmentData& data = target.bind<AlignmentData>(); - Condition cond0 = ctxt.condition(0); + Condition cond0 = ctxt.condition(ctxt.key(0)); const Delta& delta = cond0.get<Delta>(); data.delta = delta; data.flag = AlignmentData::HAVE_NONE; @@ -115,14 +115,14 @@ namespace { } virtual ~ConditionUpdate2() { } /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const ConditionUpdateContext& ctxt) { + virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& ctxt) override final { printout(context.level,"ConditionUpdate2","++ Building dependent condition: %s",key.name.c_str()); Condition target(key.name,"Alignment"); try { AlignmentData& data = target.bind<AlignmentData>(); - Condition cond0 = ctxt.condition(0); + Condition cond0 = ctxt.condition(ctxt.key(0)); const Delta& delta0 = cond0.get<Delta>(); - const AlignmentData& data1 = ctxt.get<AlignmentData>(1); // Equivalent to ctxt.condition(1).get<AlignmentData>() + const AlignmentData& data1 = ctxt.get<AlignmentData>(ctxt.key(1)); data.delta = delta0; data.delta = data1.delta; data.flag = AlignmentData::HAVE_NONE; @@ -152,12 +152,12 @@ namespace { } virtual ~ConditionUpdate3() { } /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const ConditionUpdateContext& ctxt) { + virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& ctxt) override final { printout(context.level,"ConditionUpdate3","++ Building dependent condition: %s",key.name.c_str()); Condition target(key.name,"Alignment"); try { AlignmentData& data = target.bind<AlignmentData>(); - Condition cond0 = ctxt.condition(0); + Condition cond0 = ctxt.condition(ctxt.key(0)); const Delta& delta0 = cond0.get<Delta>(); const AlignmentData& data1 = ctxt.get<AlignmentData>(1); const AlignmentData& data2 = ctxt.get<AlignmentData>(2); diff --git a/DDDB/src/plugins/DDDBExecutor.cpp b/DDDB/src/plugins/DDDBExecutor.cpp index c22cffef4..bcbba46c6 100644 --- a/DDDB/src/plugins/DDDBExecutor.cpp +++ b/DDDB/src/plugins/DDDBExecutor.cpp @@ -80,11 +80,16 @@ static long load_xml_dddb(Detector& description, int argc, char** argv) { std::vector<string> setup, xmlFiles, executors, config; std::map<std::string, std::vector<char*> > e_args, s_args, c_args; long result = 0, visualize = 0, dump = 0; + long event_time = detail::makeTime(2016,4,1,12); + long iov_start = -1; + long iov_end = -1; char last = 0, c; + for(int i=0; i<argc;++i) { + const char* arg = argv[i]; c = 0; - if ( argv[i][0] == '-' ) { - c = ::toupper(argv[i][1]); + if ( arg[0] == '-' ) { + c = ::toupper(arg[1]); switch(c) { case 'A': attr = argv[++i]; @@ -105,7 +110,12 @@ static long load_xml_dddb(Detector& description, int argc, char** argv) { last = c; break; case 'I': - sys_id = argv[++i]; + if ( ::strncasecmp(arg+1,"IOV_START",5)==0 ) + iov_start = detail::makeTime(argv[++i]); + else if ( ::strncasecmp(arg+1,"IOV_END",5)==0 ) + iov_end = detail::makeTime(argv[++i]); + else + sys_id = argv[++i]; last = 0; break; case 'L': @@ -161,8 +171,9 @@ static long load_xml_dddb(Detector& description, int argc, char** argv) { } DDDBHelper* helper = description.extension<DDDBHelper>(); + DDDBReader* resolver = 0; if ( !loader_name.empty() ) { - DDDBReader* resolver = (DDDBReader*)dd4hep::PluginService::Create<void*>(loader_name,(const char*)0); + resolver = (DDDBReader*)dd4hep::PluginService::Create<void*>(loader_name,(const char*)0); resolver->setMatch(match); resolver->setDirectory(path.parent_path().c_str()); helper->setXmlReader(resolver); @@ -190,9 +201,12 @@ static long load_xml_dddb(Detector& description, int argc, char** argv) { /// Process XML if ( !sys_id.empty() ) { - long long int init_time = detail::makeTime(2016,4,1,12); - const void* args[] = {0, sys_id.c_str(), "/", &init_time, 0}; printout(INFO,"DDDBExecutor","+++ Processing DDDB: %s", sys_id.c_str()); + if ( iov_start >= 0 && iov_end >= 0 ) { + resolver->property("ValidityLower").set(iov_start); + resolver->property("ValidityUpper").set(iov_end); + } + const void* args[] = {0, sys_id.c_str(), "/", &event_time, 0}; result = description.apply("DDDB_Loader", 4, (char**)args); check_result(result); printout(INFO,"DDDBExecutor"," .... done"); diff --git a/DDDB/src/plugins/DDDBFileReader.cpp b/DDDB/src/plugins/DDDBFileReader.cpp index c2184e414..80c56677d 100644 --- a/DDDB/src/plugins/DDDBFileReader.cpp +++ b/DDDB/src/plugins/DDDBFileReader.cpp @@ -19,6 +19,7 @@ // Framework includes #include "DDDB/DDDBReader.h" +#include "DD4hep/IOV.h" /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -34,13 +35,20 @@ namespace dd4hep { * \ingroup DD4HEP_XML */ class DDDBFileReader : public DDDBReader { + long m_validityLowerLimit = 0; + long m_validityUpperLimit = IOV::MAX_KEY; + public: /// Standard constructor - DDDBFileReader() : DDDBReader() {} + DDDBFileReader(); /// Default destructor virtual ~DDDBFileReader() {} /// Read raw XML object from the database / file virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id, UserContext* ctxt); /// Resolve a given URI to a string containing the data virtual bool load(const std::string& system_id, std::string& buffer); /// Resolve a given URI to a string containing the data @@ -63,16 +71,30 @@ namespace dd4hep { #include <unistd.h> #include <fcntl.h> +/// Standard constructor +dd4hep::DDDB::DDDBFileReader::DDDBFileReader() + : DDDBReader() +{ + declareProperty("ValidityLower", m_context.valid_since); + declareProperty("ValidityUpper", m_context.valid_until); + declareProperty("ValidityLowerLimit",m_validityLowerLimit); + declareProperty("ValidityUpperLimit",m_validityUpperLimit); +} + int dd4hep::DDDB::DDDBFileReader::getObject(const std::string& system_id, - UserContext* /* ctxt */, - std::string& buffer) + UserContext* /* ctxt */, + std::string& buffer) { - std::string path; - std::string p = m_directory+system_id; - if ( p.substr(0,7) == "file://" ) path = p.substr(6); - else if ( p.substr(0,5) == "file:" ) path = p.substr(5); - else path = p; + std::string path = system_id; int fid = ::open(path.c_str(), O_RDONLY); + + if ( fid == -1 ) { + std::string p = m_directory+system_id; + if ( p.substr(0,7) == "file://" ) path = p.substr(6); + else if ( p.substr(0,5) == "file:" ) path = p.substr(5); + else path = p; + fid = ::open(path.c_str(), O_RDONLY); + } if ( fid != -1 ) { struct stat buff; if ( 0 == ::fstat(fid, &buff) ) { @@ -108,13 +130,31 @@ bool dd4hep::DDDB::DDDBFileReader::load(const std::string& system_id, UserContext* ctxt, std::string& buffer) { - bool result = DDDBReader::load(system_id, ctxt, buffer); - if ( result ) { - DDDBReaderContext* c = (DDDBReaderContext*)ctxt; - c->valid_since = c->event_time; - c->valid_until = c->event_time; - } - return result; + return DDDBReader::load(system_id, ctxt, buffer); +} + +/// Inform reader about a locally (e.g. by XercesC) handled source load +void dd4hep::DDDB::DDDBFileReader::parserLoaded(const std::string& system_id) { + DDDBReader::parserLoaded(system_id); +} + +/// Inform reader about a locally (e.g. by XercesC) handled source load +void dd4hep::DDDB::DDDBFileReader::parserLoaded(const std::string& /* system_id */, UserContext* ctxt) { + DDDBReaderContext *ct = (DDDBReaderContext *)ctxt; + // Adjust IOV period according to setup (files have no IOV) + ct->valid_since = m_context.valid_since; + ct->valid_until = m_context.valid_until; + // Check lower bound + if (ct->valid_since < m_validityLowerLimit) + ct->valid_since = m_validityLowerLimit; + else if (ct->valid_since > m_validityUpperLimit) + ct->valid_since = m_validityUpperLimit; + // Check upper bound + if (ct->valid_until < m_validityLowerLimit) + ct->valid_until = m_validityLowerLimit; + else if (ct->valid_until > m_validityUpperLimit) + ct->valid_until = m_validityUpperLimit; + //DDDBReader::parserLoaded(system_id, ctxt); } namespace { diff --git a/DDDB/src/plugins/DeVeloServiceTest.cpp b/DDDB/src/plugins/DeVeloServiceTest.cpp new file mode 100644 index 000000000..1c7dee4d5 --- /dev/null +++ b/DDDB/src/plugins/DeVeloServiceTest.cpp @@ -0,0 +1,228 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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/Plugins.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/DetectorTools.h" +#include "DD4hep/ConditionsPrinter.h" +#include "DD4hep/DetectorProcessor.h" + +#include "DDCond/ConditionsSlice.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsIOVPool.h" + +#include "DDDB/DDDBHelper.h" +#include "DDDB/DDDBReader.h" +#include "DDDB/DDDBConversion.h" + +#include "DetService.h" +#include "Detector/DeVelo.h" +#include "Detector/DeAlignmentCall.h" +#include "Detector/DeVeloConditionCalls.h" + +using namespace std; +using namespace gaudi; + + +// C/C++ include files + + +/// Anonymous namespace for plugins +namespace { + dd4hep::PrintLevel s_PrintLevel = INFO; +} + +//========================================================================== +/// 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 dump_det(dd4hep::Detector& description, int argc, char** argv) { + + /// Callback object to print selective information + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + struct DumpActor { + dd4hep::DetElement m_de; + unique_ptr<VeloUpdateContext> m_context; + + dd4hep::DDDB::DDDBReader* m_reader = 0; + shared_ptr<IDetService> m_service; + + /// Configure file based reader + void configReader(long iov_start, long iov_end) { + try { + const DetService::IOVType* iov_typ = m_service->iovType("epoch"); + dd4hep::IOV iov_range(iov_typ); + iov_range.keyData.first = iov_start; + iov_range.keyData.second = iov_end; + m_reader->property("ValidityLower").set(iov_range.keyData.first); + m_reader->property("ValidityUpper").set(iov_range.keyData.second); + printout(INFO,"ConditionsManager","+++ Configure file based reader for IOV:%s", + iov_range.str().c_str()); + } + catch(...) { + } + } + + /// Standard constructor + DumpActor(dd4hep::Detector& dsc, const string& path) { + IDetService::Slice slice; + IDetService::Content cont; + vector<pair<dd4hep::DetElement, int> > elts; + dd4hep::DDDB::DDDBHelper* helper = dsc.extension<dd4hep::DDDB::DDDBHelper>(false); + dd4hep::cond::ConditionsManager manager = dd4hep::cond::ConditionsManager(dsc); + + m_de = dd4hep::detail::tools::findElement(dsc, path); + m_reader = helper->reader<dd4hep::DDDB::DDDBReader>(); + m_service.reset(new DetService(manager)); + const DetService::IOVType* iov_typ = m_service->iovType("epoch"); + dd4hep::IOV iov(iov_typ,dd4hep::detail::makeTime(2018,1,1)); + IDetService::Content content = m_service->openContent("DDDB"); + configReader(dd4hep::detail::makeTime(2008,1,1), dd4hep::detail::makeTime(2018,12,31)); + + cont.reset(new dd4hep::cond::ConditionsContent()); + slice.reset(new dd4hep::cond::ConditionsSlice(manager,cont)); + dd4hep::cond::fill_content(manager, *cont, *iov_typ); + dd4hep::cond::ConditionsManager::Result res = manager.prepare(iov, *slice); + printout(dd4hep::ALWAYS,"Prepare","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of IOV %s", + res.total(), res.selected, res.loaded, res.computed, res.missing, iov.str().c_str()); + + m_context.reset(new VeloUpdateContext()); + dd4hep::DetectorScanner(dd4hep::detElementsCollector(elts), m_de); + dd4hep::cond::DependencyBuilder align_builder(dsc.world(), + Keys::alignmentsComputedKey, + new DeAlignmentCall(m_de)); + auto* dep = align_builder.release(); + dep->target.hash = Keys::alignmentsComputedKey; + m_service->addContent(content, dep); + + std::unique_ptr<DeVeloStaticConditionCall> static_update(new DeVeloStaticConditionCall()); + for(const auto& e : elts) { + dd4hep::DetElement de = e.first; + dd4hep::DDDB::DDDBCatalog* cat = de.extension<dd4hep::DDDB::DDDBCatalog>(); + dd4hep::Condition::detkey_type det_key = de.key(); + dd4hep::ConditionKey::KeyMaker lower(det_key, dd4hep::Condition::FIRST_ITEM_KEY); + dd4hep::ConditionKey::KeyMaker upper(det_key, dd4hep::Condition::LAST_ITEM_KEY); + cout << "Processing " << e.second << " class " << cat->classID << " -> " << de.path() << endl; + m_context->detectors.insert(make_pair(det_key,make_pair(de,cat))); + { + auto first = cont->conditions().lower_bound(lower.hash); + for(; first != cont->conditions().end() && (*first).first <= upper.hash; ++first) { + std::unique_ptr<dd4hep::cond::ConditionsLoadInfo> ptr((*first).second->clone()); + m_service->addContent(content, (*first).first, *ptr->data<string>()); + } + } + { + auto first = cont->derived().lower_bound(lower.hash); + for(; first != cont->derived().end() && (*first).first <= upper.hash; ++first) { + m_service->addContent(content, (*first).second); + } + } + + dd4hep::cond::DependencyBuilder static_builder(de, Keys::staticKey, static_update->addRef()); + m_service->addContent(content, static_builder.release()); + + dd4hep::cond::ConditionUpdateCall* call = (e.first == m_de) + ? new DeVeloConditionCall(de, cat, m_context.get()) + : new DeVeloIOVConditionCall(de, cat, m_context.get()); + dd4hep::cond::DependencyBuilder iov_builder(de, Keys::deKey, call); + m_service->addContent(content, iov_builder.release()); + } + static_update.release()->release(); + m_service->closeContent(content); + manager.clear(); + } + + /// Standard destructor + ~DumpActor() { + } + + /// __________________________________________________________________________________ + long dump() { + shared_ptr<dd4hep::cond::ConditionsSlice> slice; + IDetService::ConditionsManager manager = m_service->manager(); + const IDetService::IOVType* iov_typ = m_service->iovType("epoch"); + + printout(INFO,"ConditionsManager","+++ Starting conditions dump loop"); + for(size_t i=0; i<10; ++i) { + long stamp = dd4hep::detail::makeTime(2016,5,20,i,30,0); + dd4hep::IOV iov(iov_typ, stamp); + configReader(stamp-1800, stamp+1799); // Run duration 1 hour - 1 second + // Reset context. Need at some point a better mechanism + m_context->alignments_done = dd4hep::Condition(); + /// The next line is what would show up in the client code: + slice = m_service->project("DDDB", m_context.get(), "epoch", stamp); + printout(INFO,"ConditionsManager","+++ Prepared slice Round: %ld for IOV:%s", + i, slice->iov().str().c_str()); + + DeVelo devp = slice->get(m_de,Keys::deKey); + //devp.print(0,DePrint::ALL); + DetectorElement<DeVelo> detVP = devp; + cout << "TEST: Got detector element:" + << " " << detVP.conditions().size() + << " " << detVP.detector().path() + << " " << detVP.detectorAlignment().name() + << " " << detVP.conditions().size() + << endl; + try { + DeVeloGeneric deGEN = devp; + cout << " " << deGEN.conditions().size() + << " " << deGEN.children().size() + << endl; + } + catch(const exception& e) { + cout << "Exception(This is GOOD!): " << e.what() << endl; + } + } + m_service->cleanup(dd4hep::cond::ConditionsFullCleanup()); + return 1; + } + }; + + for(int i=0; i<argc; ++i) { + if ( ::strcmp(argv[i],"-print")==0 ) { + s_PrintLevel = dd4hep::printLevel(argv[++i]); + printout(INFO,"DDDB","Setting print level for %s to %s [%d]",__FILE__,argv[i-1],s_PrintLevel); + } + else if ( ::strcmp(argv[i],"--help")==0 ) { + printout(INFO,"Plugin-Help","Usage: DDDBDetectorDump --opt [--opt] "); + printout(INFO,"Plugin-Help"," -print <value> Printlevel for output "); + printout(INFO,"Plugin-Help"," -help Print this help message "); + return 0; + } + } + DumpActor actor(description, "/world/LHCb/BeforeMagnetRegion/Velo"); + return actor.dump(); + } +} /* End anonymous namespace */ + +using namespace dd4hep; +DECLARE_APPLY(DDDB_DeVeloServiceTest,dump_det) +//========================================================================== diff --git a/DDDB/src/plugins/DeVeloTest.cpp b/DDDB/src/plugins/DeVeloTest.cpp index 96e9e54ed..b86668bf9 100644 --- a/DDDB/src/plugins/DeVeloTest.cpp +++ b/DDDB/src/plugins/DeVeloTest.cpp @@ -18,7 +18,6 @@ //========================================================================== // Framework includes -#include "DD4hep/Detector.h" #include "DD4hep/Plugins.h" #include "DD4hep/Printout.h" #include "DD4hep/Factories.h" @@ -26,12 +25,13 @@ #include "DD4hep/ConditionsPrinter.h" #include "DD4hep/DetectorProcessor.h" -#include "DDCond/ConditionsManager.h" #include "DDCond/ConditionsSlice.h" -#include "DDDB/DDDBConversion.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsManager.h" -// C/C++ include files -//#include <memory> +#include "DDDB/DDDBHelper.h" +#include "DDDB/DDDBReader.h" +#include "DDDB/DDDBConversion.h" #include "Detector/DeVelo.h" #include "Detector/DeAlignmentCall.h" @@ -71,22 +71,44 @@ namespace { dd4hep::cond::ConditionsManager m_manager; shared_ptr<dd4hep::cond::ConditionsContent> m_content; const dd4hep::IOVType* m_iovtype = 0; + dd4hep::DDDB::DDDBReader* m_reader = 0; + + /// Configure file based reader + void configReader(long iov_start, long iov_end) { + try { + dd4hep::IOV iov_range(m_iovtype); + iov_range.keyData.first = iov_start; + iov_range.keyData.second = iov_end; + m_reader->property("ValidityLower").set(iov_range.keyData.first); + m_reader->property("ValidityUpper").set(iov_range.keyData.second); + printout(INFO,"ConditionsManager","+++ Configure file based reader for IOV:%s", + iov_range.str().c_str()); + } + catch(...) { + } + } + /// Standard constructor - DumpActor(dd4hep::Detector& l, const string& path) : m_detDesc(l) { + DumpActor(dd4hep::Detector& dsc, const string& path) : m_detDesc(dsc) { + dd4hep::DDDB::DDDBHelper* helper = dsc.extension<dd4hep::DDDB::DDDBHelper>(false); shared_ptr<dd4hep::cond::ConditionsSlice> slice; shared_ptr<dd4hep::cond::ConditionsContent> cont; vector<pair<dd4hep::DetElement, int> > elts; + + m_de = dd4hep::detail::tools::findElement(m_detDesc, path); m_manager = dd4hep::cond::ConditionsManager::from(m_detDesc); - m_de = dd4hep::detail::tools::findElement(m_detDesc, path); m_iovtype = m_manager.iovType("epoch"); + m_reader = helper->reader<dd4hep::DDDB::DDDBReader>(); + configReader(dd4hep::detail::makeTime(2008,1,1), dd4hep::detail::makeTime(2018,12,31)); dd4hep::IOV iov(m_iovtype, 0); - cont.reset(new dd4hep::cond::ConditionsContent()); slice.reset(new dd4hep::cond::ConditionsSlice(m_manager,cont)); dd4hep::cond::fill_content(m_manager, *cont, *m_iovtype); - m_manager.prepare(iov, *slice); + dd4hep::cond::ConditionsManager::Result res = m_manager.prepare(iov, *slice); + printout(dd4hep::ALWAYS,"ConditionsManager","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of IOV %s", + res.total(), res.selected, res.loaded, res.computed, res.missing, iov.str().c_str()); m_context.reset(new VeloUpdateContext()); m_content.reset(new dd4hep::cond::ConditionsContent()); @@ -103,14 +125,16 @@ namespace { dd4hep::DetElement de = e.first; dd4hep::DDDB::DDDBCatalog* cat = de.extension<dd4hep::DDDB::DDDBCatalog>(); dd4hep::Condition::detkey_type det_key = de.key(); - dd4hep::ConditionKey::KeyMaker lower(det_key, 0); - dd4hep::ConditionKey::KeyMaker upper(det_key, ~0x0); + dd4hep::ConditionKey::KeyMaker lower(det_key, dd4hep::Condition::FIRST_ITEM_KEY); + dd4hep::ConditionKey::KeyMaker upper(det_key, dd4hep::Condition::LAST_ITEM_KEY); cout << "Processing " << e.second << " class " << cat->classID << " -> " << de.path() << endl; m_context->detectors.insert(make_pair(det_key,make_pair(de,cat))); { auto first = cont->conditions().lower_bound(lower.hash); - for(; first != cont->conditions().end() && (*first).first <= upper.hash; ++first) - m_content->insertKey((*first).first); + for(; first != cont->conditions().end() && (*first).first <= upper.hash; ++first) { + std::unique_ptr<dd4hep::cond::ConditionsLoadInfo> ptr((*first).second->clone()); + m_content->insertKey((*first).first, ptr); + } } { auto first = cont->derived().lower_bound(lower.hash); @@ -128,6 +152,7 @@ namespace { m_content->insertDependency(iov_builder.release()); } static_update.release()->release(); + m_manager.clear(); } /// Standard destructor @@ -137,34 +162,45 @@ namespace { /// __________________________________________________________________________________ long dump() { shared_ptr<dd4hep::cond::ConditionsSlice> slice; - dd4hep::IOV iov(m_iovtype, 0); - - slice.reset(new dd4hep::cond::ConditionsSlice(m_manager, m_content)); - m_manager.prepare(iov, *slice, m_context.get()); - /* - dd4hep::cond::ConditionsPrinter printer(slice.get()); - printer.lineLength = 180; - dd4hep::DetectorScanner(printer, m_de); - */ - DeVelo devp = slice->get(m_de,Keys::deKey); - devp.print(0,DePrint::ALL); - - DetectorElement<DeVelo> detVP = devp; - cout << "TEST: Got detector element:" - << " " << detVP.conditions().size() - << " " << detVP.detector().path() - << " " << detVP.detectorAlignment().name() - << " " << detVP.conditions().size() - << endl; - try { - DeVeloGeneric deGEN = devp; - cout << " " << deGEN.conditions().size() - << " " << deGEN.children().size() + dd4hep::cond::ConditionsIOVPool* iovp = m_manager.iovPool(*m_iovtype); + + printout(INFO,"ConditionsManager","+++ Dump pools at dump:"); + for(const auto& e : iovp->elements) + e.second->print(); + printout(INFO,"ConditionsManager","+++ Starting conditions dump loop"); + long start_time = dd4hep::detail::makeTime(2016,5,20,0,0,0); + for(size_t i=0; i<10; ++i) { + long stamp = start_time + i*3600 + 1800; // Middle of 1 hour run + dd4hep::IOV iov(m_iovtype, stamp); + configReader(stamp-1800, stamp+1799); // Run duration 1 hour - 1 second + slice.reset(new dd4hep::cond::ConditionsSlice(m_manager, m_content)); + m_context->alignments_done = dd4hep::Condition(); + dd4hep::cond::ConditionsManager::Result res = m_manager.prepare(iov, *slice, m_context.get()); + printout(dd4hep::ALWAYS,"ConditionsManager","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of IOV %s", + res.total(), res.selected, res.loaded, res.computed, res.missing, iov.str().c_str()); + for(const auto& e : iovp->elements) + e.second->print(); + DeVelo devp = slice->get(m_de,Keys::deKey); + devp.print(0,DePrint::ALL); + + DetectorElement<DeVelo> detVP = devp; + cout << "TEST: Got detector element:" + << " " << detVP.conditions().size() + << " " << detVP.detector().path() + << " " << detVP.detectorAlignment().name() + << " " << detVP.conditions().size() << endl; + try { + DeVeloGeneric deGEN = devp; + cout << " " << deGEN.conditions().size() + << " " << deGEN.children().size() + << endl; + } + catch(const exception& e) { + cout << "Exception(This is GOOD!): " << e.what() << endl; + } } - catch(const exception& e) { - cout << "Exception(This is GOOD!): " << e.what() << endl; - } + m_manager.clear(); return 1; } }; diff --git a/DDDB/src/plugins/DetService.cpp b/DDDB/src/plugins/DetService.cpp new file mode 100644 index 000000000..9c08f6755 --- /dev/null +++ b/DDDB/src/plugins/DetService.cpp @@ -0,0 +1,318 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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 "DetService.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" + +using namespace std; +using namespace gaudi; + +using dd4hep::except; +using dd4hep::printout; +using dd4hep::PrintLevel; + +typedef lock_guard<mutex> Lock; + +/// Initializing constructor +DetService::DetService(ConditionsManager m) : m_manager(m) +{ + declareProperty("AgeLimit", m_ageLimit=3); +} + +/// Initialize the service +int DetService::initialize() { + return 1; +} + +/// Finalize the service +int DetService::finalize() { + return 1; +} + +/// Accessor: get refernece to the conditions manager +DetService::ConditionsManager DetService::manager() const { + return m_manager; +} + +/// Accessor: Access IOV Type from conditions manager +const DetService::IOVType* DetService::iovType(const std::string& identifier) const { + return m_manager.iovType(identifier); +} + +/// Open content creation context and copy items from registered object +DetService::Content DetService::getContent(const string& nam) { + Lock lock(m_contentLock); + for(const auto& c : m_activeContents) { + if ( c.first == nam ) + return c.second; + } + for(const auto& c : m_openContents) { + if ( c.first == nam ) + return c.second; + } + return Content(); +} + +/// Open content creation context and copy items from registered object +DetService::Content DetService::openContent(const string& nam) { + Content ptr = getContent(nam); + if ( !ptr ) { + Lock lock(m_contentLock); + ptr.reset(new dd4hep::cond::ConditionsContent()); + m_openContents.insert(m_openContents.end(),make_pair(nam,ptr)); + return ptr; + } + except("DetService", + "openContent FAILED. ConditionsContent object with name %s exists already.", + nam.c_str()); + return Content(); +} + +/// Add a condition address to the content. Condition is identified by it's global key +bool DetService::_addContent(Content& content, + Condition::key_type key, + const std::string& address) { + if ( content ) { + for(auto& c : m_openContents) { + if ( content == c.second ) { + if ( c.second->insertKey(key, address) ) { + return true; + } + } + } + } + return false; +} + +/// Add a condition address to the content. Condition is identified by it's global key +void DetService::addContent(Content& content, + Condition::key_type key, + const std::string& address) { + /// Fast return if all fine: + if ( _addContent(content, key, address) ) + return; + /// Handle errors: + if ( content ) { + for(auto& c : m_openContents) { + if ( content == c.second ) { + except("DetService","Attempt to insert item with duplicate key: %016lX", key); + } + } + except("DetService","This content object is not availible for manipulation. Key:%016X", key); + } + except("DetService","This content object is INVALID and cannot be manipulated. Key:%016X", key); +} + +/// Add a condition address to the content +void DetService::addContent(Content& content, + DetElement det, + const string& item, + const string& address) { + dd4hep::ConditionKey key(det.key(), item); + if ( _addContent(content, key.hash, address) ) + return; + if ( content ) { + for(auto& c : m_openContents) { + if ( content == c.second ) { + except("DetService","Attempt to insert item with duplicate key:%s -> %s", + det.path().c_str(), item.c_str()); + } + } + except("DetService","This content object is not availible for manipulation. %s -> %s", + det.path().c_str(), item.c_str()); + } + except("DetService","This content object is INVALID and cannot be manipulated. %s -> %s", + det.path().c_str(), item.c_str()); +} + +/// Add a condition functor for a derived condition to the content +void DetService::addContent(Content& content, Dependency* dep) +{ + if ( content && dep ) { + for(auto& c : m_openContents) { + if ( content == c.second && c.second->insertDependency(dep) ) { + return; + } + except("DetService","Attempt to insert dependency with duplicate key."); + } + except("DetService","This content object is not availible for manipulation."); + } + except("DetService","This content object is INVALID and cannot be manipulated."); +} + +/// Open content creation context +void DetService::closeContent(Content& content) { + if ( content ) { + for(auto c=m_openContents.begin(); c!=m_openContents.end(); ++c) { + if ( content == (*c).second ) { + Lock lock(m_contentLock); + m_activeContents.insert(m_activeContents.end(),*c); + m_openContents.erase(c); + return; + } + } + except("DetService","This content object is not availible for manipulation."); + } + except("DetService","This content object is INVALID and cannot be manipulated."); +} + +/// Remove content from cache container +bool DetService::_remove(CachedContents& cache, Content& content) { + for(auto c=cache.begin(); c!=cache.end(); ++c) { + if ( content == (*c).second ) { + cache.erase(c); + return true; + } + } + return false; +} + +/// Close content creation context +bool DetService::removeContent(Content& cont) { + Lock lock(m_contentLock); + if ( cont ) { + bool ret = _remove(m_activeContents,cont) ? true : _remove(m_openContents,cont); + if ( ret ) cont.reset(); + return ret; + } + return false; +} + +/// Age all slices and check for slices which have expired. +void DetService::_age() { + CachedSlices tmp = m_cache; + m_cache.clear(); + m_cache.reserve(tmp.size()); + for( size_t i=0; i<tmp.size(); ++i ) { + if ( ++tmp[i]->age > m_ageLimit && tmp[i]->slice.unique() ) continue; + m_cache.push_back(tmp[i]); + tmp[i] = 0; + } + for(auto* cc : tmp) { + if ( cc ) delete cc; + } +} + +/// Find an existing cached slice +DetService::Slice DetService::_find(Content& content, + const IOVType* typ, + EventStamp stamp) +{ + // When we are here we know that all arguments make sense. + // No need here for any further checks + dd4hep::IOV req_iov(typ,stamp); + // First scan the cache: maybe we do not have to do anything..... + for(CacheEntry* c : m_cache) { + if ( c->iov.iovType != typ ) continue; + if ( content != c->slice->content ) continue; + if ( dd4hep::IOV::key_is_contained(req_iov.keyData,c->iov.keyData) ) { + c->age = 0; + _age(); + c->age = 0; + return c->slice; + } + } + return Slice(); +} + +/// Project a newly created conditions slice. +DetService::Slice DetService::_create(Content& content, + Context *ctx, + const IOVType* typ, + EventStamp stamp) +{ + dd4hep::IOV req_iov(typ, stamp); + unique_ptr<CacheEntry> e(new CacheEntry()); + e->slice.reset(new dd4hep::cond::ConditionsSlice(m_manager,content)); + m_manager.prepare(req_iov, *e->slice, ctx); + m_cache.push_back(e.release()); + return m_cache.back()->slice; +} + +/// Project a new conditions slice. If a free cached slice is availible, it shall be re-used +DetService::Slice DetService::_project(Content& content, + Context *ctx, + const IOVType* typ, + EventStamp stamp) { + Slice ptr; + if ( content ) { + Lock lock(m_sliceLock); + if ( !(ptr=_find(content, typ, stamp)) ) { + return _create(content, ctx, typ, stamp); + } + except("DetService","Invalid conditions content give. Cannot create slice."); + } + return ptr; +} + +/// Project a new conditions slice. If a free cached slice is availible, it shall be re-used +DetService::Slice DetService::project(Content& content, + Context *ctx, + const IOVType* typ, + EventStamp stamp) { + /// Check if the givem IOV type is correct + auto used_types = m_manager.iovTypesUsed(); + for(const auto* i : used_types) { + if ( i == typ ) { + return _project(content, ctx, i, stamp); + } + } + dd4hep::except("DetService", + "Request to project a conditions slice for an unknown IOV type."); + return Slice(); +} + +/// Project a new conditions slice. If a free cached slice is availible, it shall be re-used +DetService::Slice DetService::project(Content& content, + Context *ctx, + const string& typ, + EventStamp stamp) { + /// Check if the givem IOV type is correct + const IOVType* iovType = m_manager.iovType(typ); + if ( iovType ) { + return _project(content, ctx, iovType, stamp); + } + dd4hep::except("DetService", + "Request to project a conditions slice for an unknown IOV type: %s", + typ.c_str()); + return Slice(); +} + +/// Project a new conditions slice. If a free cached slice is availible, it shall be re-used +DetService::Slice DetService::project(const string& content, + Context *ctx, + const string& typ, + EventStamp stamp) { + Content cont(getContent(content)); + if ( cont ) { + return project(cont, ctx, typ, stamp); + } + dd4hep::except("DetService", + "Request to project a conditions slice for unknown content: %s", + content.c_str()); + return Slice(); +} + +/// Invoke slice cleanup +void DetService::cleanup(const Cleanup &cleaner) { + cleaner(m_manager); +} diff --git a/DDDB/src/plugins/DetService.h b/DDDB/src/plugins/DetService.h new file mode 100644 index 000000000..e2cc70fbb --- /dev/null +++ b/DDDB/src/plugins/DetService.h @@ -0,0 +1,162 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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_DETSERVICE_H +#define DD4HEP_DETSERVICE_H + +// Framework includes +#include "Detector/IDetService.h" +#include "DD4hep/ComponentProperties.h" + +// C/C++ includes +#include <mutex> + +/// Gaudi namespace declaration +namespace gaudi { + + /// Example gaudi-like service to access dd4hep conditions + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + class DetService : virtual public IDetService, + public dd4hep::PropertyConfigurable + { + /// Cache entry definition + class CacheEntry + { + public: + Slice slice; + dd4hep::IOV iov{0}; + int age = 0; + CacheEntry() = default; + CacheEntry(CacheEntry &&) = delete; + CacheEntry(const CacheEntry &) = delete; + CacheEntry &operator=(const CacheEntry &) = delete; + }; + + /// Short-cut to the ConditionsManager + typedef dd4hep::cond::ConditionsManager ConditionsManager; + /// Short-cut to the cache slices + typedef std::vector<CacheEntry *> CachedSlices; + /// Short-cut to the content cache + typedef std::pair<std::string, Content> ContentEntry; + /// Cached content container + typedef std::vector<ContentEntry> CachedContents; + + /// Main object lock for content manipulation + std::mutex m_contentLock; + /// Main object lock for slice manipulation + std::mutex m_sliceLock; + /// Reference to the conditions manager object + ConditionsManager m_manager; + /// Container of active content objects + CachedContents m_activeContents; + /// Container of content objects being edited + CachedContents m_openContents; + /// The slice cache of re-usable slices + CachedSlices m_cache; + /// The maximum age limit + int m_ageLimit; + + protected: + /// Age all slices and check for slices which have expired. + void _age(); + /// Find a conditions slice in the cache + Slice _find(Content &content, const IOVType *typ, EventStamp stamp); + /// Project a newly created conditions slice. + Slice _create(Content &content, Context *ctx, const IOVType *typ, EventStamp stamp); + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + Slice _project(Content &content, Context *ctx, const IOVType *typ, EventStamp stamp); + /// Remove content from cache + bool _remove(CachedContents &cache, Content &content); + /// Add a condition address to the content. Condition is identified by it's global key + bool _addContent(Content &content, Condition::key_type key, const std::string &address); + + public: + /// Default constructor + DetService() = delete; + /// Initializing constructor + DetService(ConditionsManager m); + /// Initializing constructor + DetService(const DetService ©) = delete; + /// Default destructor + virtual ~DetService() = default; + /// Assignment operator + DetService &operator=(const DetService ©) = delete; + + /// Initialize the service + virtual int initialize(); + /// Finalize the service + virtual int finalize(); + + /** General accessors to manipulate the conditions */ + /// Accessor: get refernece to the conditions manager + virtual ConditionsManager manager() const override; + + /// Accessor: Access IOV Type from conditions manager + virtual const IOVType *iovType(const std::string &identifier) const override; + + /// Open content creation context + virtual Content openContent(const std::string &name) override; + + /// Open content creation context and copy items from registered object + virtual Content getContent(const std::string &name) override; + + /// Add a condition address to the content. Condition is identified by it's global key + virtual void addContent(Content &content, + Condition::key_type key, + const std::string &address) override; + + /// Add a condition address to the content + virtual void addContent(Content &content, + DetElement det, + const std::string &item, + const std::string &address) override; + + /// Add a condition functor for a derived condition to the content + virtual void addContent(Content &content, + Dependency *call); + + /// Close content creation context + virtual void closeContent(Content &content) override; + + /// Remove content object from cache. + virtual bool removeContent(Content &content) override; + + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + virtual Slice project(Content &content, + Context *ctx, + const IOVType *typ, + EventStamp stamp) override; + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + virtual Slice project(Content &content, + Context *ctx, + const std::string &typ, + EventStamp stamp) override; + /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used + virtual Slice project(const std::string &content, + Context *ctx, + const std::string &typ, + EventStamp stamp) override; + /// Invoke slice cleanup + virtual void cleanup(const Cleanup &cleaner) override; + }; +} +#endif // DD4HEP_DETSERVICE_H diff --git a/DDG4/include/DDG4/Geant4Output2ROOT.h b/DDG4/include/DDG4/Geant4Output2ROOT.h index 206a98550..d0faf357a 100644 --- a/DDG4/include/DDG4/Geant4Output2ROOT.h +++ b/DDG4/include/DDG4/Geant4Output2ROOT.h @@ -50,6 +50,11 @@ namespace dd4hep { TTree* m_tree; /// Flag if Monte-Carlo truth should be followed and checked bool m_handleMCTruth; + /// Property: vector with disabled collections + std::vector<std::string> m_disabledCollections; + /// Property: vector with disabled collections + bool m_disableParticles = false; + public: /// Standard constructor Geant4Output2ROOT(Geant4Context* context, const std::string& nam); diff --git a/DDG4/src/Geant4Output2ROOT.cpp b/DDG4/src/Geant4Output2ROOT.cpp index b6eef4212..af5cef884 100644 --- a/DDG4/src/Geant4Output2ROOT.cpp +++ b/DDG4/src/Geant4Output2ROOT.cpp @@ -36,6 +36,8 @@ Geant4Output2ROOT::Geant4Output2ROOT(Geant4Context* ctxt, const string& nam) : Geant4OutputAction(ctxt, nam), m_file(0), m_tree(0) { declareProperty("Section", m_section = "EVENT"); declareProperty("HandleMCTruth", m_handleMCTruth = true); + declareProperty("DisabledCollections", m_disabledCollections); + declareProperty("DisableParticles", m_disableParticles); InstanceCount::increment(this); } @@ -140,17 +142,19 @@ void Geant4Output2ROOT::commit(OutputContext<G4Event>& ctxt) { /// Callback to store the Geant4 event void Geant4Output2ROOT::saveEvent(OutputContext<G4Event>& /* ctxt */) { - Geant4ParticleMap* parts = context()->event().extension<Geant4ParticleMap>(); - if ( parts ) { - typedef Geant4HitWrapper::HitManipulator Manip; - typedef Geant4ParticleMap::ParticleMap ParticleMap; - Manip* manipulator = Geant4HitWrapper::manipulator<Geant4Particle>(); - const ParticleMap& pm = parts->particles(); - vector<void*> particles; - for(ParticleMap::const_iterator i=pm.begin(); i!=pm.end(); ++i) { - particles.push_back((ParticleMap::mapped_type*)(*i).second); + if ( !m_disableParticles ) { + Geant4ParticleMap* parts = context()->event().extension<Geant4ParticleMap>(); + if ( parts ) { + typedef Geant4HitWrapper::HitManipulator Manip; + typedef Geant4ParticleMap::ParticleMap ParticleMap; + Manip* manipulator = Geant4HitWrapper::manipulator<Geant4Particle>(); + const ParticleMap& pm = parts->particles(); + vector<void*> particles; + for(ParticleMap::const_iterator i=pm.begin(); i!=pm.end(); ++i) { + particles.push_back((ParticleMap::mapped_type*)(*i).second); + } + fill("MCParticles",manipulator->vec_type,&particles); } - fill("MCParticles",manipulator->vec_type,&particles); } } @@ -158,8 +162,13 @@ void Geant4Output2ROOT::saveEvent(OutputContext<G4Event>& /* ctxt */) { void Geant4Output2ROOT::saveCollection(OutputContext<G4Event>& /* ctxt */, G4VHitsCollection* collection) { Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(collection); string hc_nam = collection->GetName(); - vector<void*> hits; + for(const auto& n : m_disabledCollections) { + if ( n == hc_nam ) { + return; + } + } if (coll) { + vector<void*> hits; coll->getHitsUnchecked(hits); size_t nhits = coll->GetSize(); if ( m_handleMCTruth && m_truth && nhits > 0 ) { diff --git a/examples/Conditions/src/ConditionExampleObjects.cpp b/examples/Conditions/src/ConditionExampleObjects.cpp index e140dd678..e06ec6b21 100644 --- a/examples/Conditions/src/ConditionExampleObjects.cpp +++ b/examples/Conditions/src/ConditionExampleObjects.cpp @@ -35,51 +35,68 @@ ConditionsManager dd4hep::ConditionExamples::installManager(Detector& descriptio } /// Interface to client Callback in order to update the condition -Condition ConditionUpdate1::operator()(const ConditionKey& key, const ConditionUpdateContext& context) { +Condition ConditionUpdate1::operator()(const ConditionKey& key, ConditionUpdateContext&) { #ifdef DD4HEP_CONDITIONKEY_HAVE_NAME printout(printLevel,"ConditionUpdate1","++ Building dependent condition: %016llX [%s]",key.hash, key.name.c_str()); #else printout(printLevel,"ConditionUpdate1","++ Building dependent condition: %016llX",key.hash); #endif Condition target(key.name,"derived"); - vector<int>& data = target.bind<vector<int> >(); - Condition cond0 = context.condition(0); + target.bind<vector<int> >(); + return target; +} + +/// Interface to client Callback in order to update the condition +void ConditionUpdate1::resolve(Condition target, ConditionUpdateContext& context) { + vector<int>& data = target.get<vector<int> >(); + Condition cond0 = context.condition(context.key(0)); data.push_back(cond0.get<int>()); data.push_back(cond0.get<int>()*2); - return target; } /// Interface to client Callback in order to update the condition -Condition ConditionUpdate2::operator()(const ConditionKey& key, const ConditionUpdateContext& context) { +Condition ConditionUpdate2::operator()(const ConditionKey& key, ConditionUpdateContext&) { #ifdef DD4HEP_CONDITIONKEY_HAVE_NAME printout(printLevel,"ConditionUpdate2","++ Building dependent condition: %016llX [%s]",key.hash, key.name.c_str()); #else printout(printLevel,"ConditionUpdate2","++ Building dependent condition: %016llX",key.hash); #endif Condition target(key.name,"derived"); - vector<int>& data = target.bind<vector<int> >(); - Condition cond0 = context.condition(0); - Condition cond1 = context.condition(1); + target.bind<vector<int> >(); + return target; +} + +/// Interface to client Callback in order to update the condition +void ConditionUpdate2::resolve(Condition target, ConditionUpdateContext& context) { + vector<int>& data = target.get<vector<int> >(); + Condition cond0 = context.condition(context.key(0)); + Condition cond1 = context.condition(context.key(1)); data.push_back(cond0.get<int>()); data.push_back(cond0.get<int>()*2); vector<int>& c1 = cond1.get<vector<int> >(); data.insert(data.end(), c1.begin(), c1.end()); - return target; } + /// Interface to client Callback in order to update the condition -Condition ConditionUpdate3::operator()(const ConditionKey& key, const ConditionUpdateContext& context) { +Condition ConditionUpdate3::operator()(const ConditionKey& key, ConditionUpdateContext&) { #ifdef DD4HEP_CONDITIONKEY_HAVE_NAME printout(printLevel,"ConditionUpdate3","++ Building dependent condition: %016llX [%s]",key.hash, key.name.c_str()); #else printout(printLevel,"ConditionUpdate3","++ Building dependent condition: %016llX",key.hash); #endif Condition target(key.name,"derived"); - vector<int>& data = target.bind<vector<int> >(); - Condition cond0 = context.condition(0); - Condition cond1 = context.condition(1); - Condition cond2 = context.condition(2); + target.bind<vector<int> >(); + return target; +} + +/// Interface to client Callback in order to update the condition +void ConditionUpdate3::resolve(Condition target, ConditionUpdateContext& context) { + vector<int>& data = target.get<vector<int> >(); + Condition cond0 = context.condition(context.key(0)); + Condition cond1 = context.condition(context.key(1)); + Condition cond2 = context.condition(context.key(2)); data.push_back(cond0.get<int>()); data.push_back(cond0.get<int>()*2); @@ -88,7 +105,6 @@ Condition ConditionUpdate3::operator()(const ConditionKey& key, const ConditionU vector<int>& c2 = cond2.get<vector<int> >(); data.insert(data.end(), c2.begin(), c2.end()); - return target; } /// Initializing constructor diff --git a/examples/Conditions/src/ConditionExampleObjects.h b/examples/Conditions/src/ConditionExampleObjects.h index 3ffc48f8b..87cab0a7b 100644 --- a/examples/Conditions/src/ConditionExampleObjects.h +++ b/examples/Conditions/src/ConditionExampleObjects.h @@ -75,7 +75,9 @@ namespace dd4hep { /// Default destructor virtual ~ConditionUpdate1() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const ConditionUpdateContext& context) final; + virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& context) override final; + /// Interface to client Callback in order to update the condition + virtual void resolve(Condition condition, ConditionUpdateContext& context) override final; }; /// Specialized conditions update callback @@ -93,7 +95,9 @@ namespace dd4hep { /// Default destructor virtual ~ConditionUpdate2() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const ConditionUpdateContext& context) final; + virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& context) override final; + /// Interface to client Callback in order to update the condition + virtual void resolve(Condition condition, ConditionUpdateContext& context) override final; }; /// Specialized conditions update callback @@ -111,7 +115,9 @@ namespace dd4hep { /// Default destructor virtual ~ConditionUpdate3() = default; /// Interface to client Callback in order to update the condition - virtual Condition operator()(const ConditionKey& key, const ConditionUpdateContext& context) final; + virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& context) override final; + /// Interface to client Callback in order to update the condition + virtual void resolve(Condition condition, ConditionUpdateContext& context) override final; }; /// This is important, otherwise the register and forward calls won't find them! diff --git a/examples/Conditions/src/ConditionExample_load.cpp b/examples/Conditions/src/ConditionExample_load.cpp index 618d6ab2e..4adebf84b 100644 --- a/examples/Conditions/src/ConditionExample_load.cpp +++ b/examples/Conditions/src/ConditionExample_load.cpp @@ -126,7 +126,6 @@ static int condition_example (Detector& description, int argc, char** argv) { if ( 0 == i ) { // First one we print... Scanner(ConditionsPrinter(slice.get(),"Example"),description.world()); } - // Now compute the tranformation matrices printout(ALWAYS,"Prepare","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of IOV %s", r.total(), r.selected, r.loaded, r.computed, r.missing, req_iov.str().c_str()); } -- GitLab