diff --git a/DDCond/include/DDCond/ConditionsDependencyHandler.h b/DDCond/include/DDCond/ConditionsDependencyHandler.h index 984cae234349089b2b28bac721c11105a9c3bebf..c535a3b783f55442f86ce2c118653d1dd983c870 100644 --- a/DDCond/include/DDCond/ConditionsDependencyHandler.h +++ b/DDCond/include/DDCond/ConditionsDependencyHandler.h @@ -38,48 +38,75 @@ namespace dd4hep { */ class ConditionsDependencyHandler : public ConditionResolver { public: - typedef std::map<Condition::key_type,const ConditionDependency*> Dependencies; - + 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) {} + }; + typedef std::map<Condition::key_type, const ConditionDependency*> Dependencies; + typedef std::map<Condition::key_type, Created> CreatedConditions; protected: /// Reference to conditions manager - ConditionsManagerObject* m_manager; + ConditionsManagerObject* m_manager; /// Reference to the user pool object - UserPool& m_pool; + UserPool& m_pool; /// Dependency container to be resolved. - const Dependencies& m_dependencies; + const Dependencies& m_dependencies; /// IOV target pool for this handler - ConditionsPool* m_iovPool; + ConditionsPool* m_iovPool; /// User defined optional processing parameter - void* m_userParam; + ConditionUpdateUserContext* m_userParam; + /// The objects created during processing + CreatedConditions m_created; + /// Handler's state + State m_state = CREATED; public: /// Number of callbacks to the handler for monitoring - mutable size_t num_callback; + mutable size_t num_callback; protected: /// Internal call to trigger update callback - Condition::Object* do_callback(const ConditionDependency& dep) const; + Condition::Object* do_callback(const ConditionDependency* dep); public: /// Initializing constructor ConditionsDependencyHandler(ConditionsManager mgr, UserPool& pool, const Dependencies& dependencies, - void* user_param); + ConditionUpdateUserContext* user_param); /// Default destructor ~ConditionsDependencyHandler(); /// ConditionResolver implementation: Access to the detector description instance Detector& detectorDescription() const; + + /// Access the conditions created during processing + 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 + void resolve(); + + /** ConditionResolver interface implementation */ /// ConditionResolver implementation: Access to the conditions manager - virtual Ref_t manager() const { return m_manager; } + virtual Ref_t manager() const override { return m_manager; } /// Access to pool IOV - virtual const IOV& requiredValidity() const { return m_pool.validity(); } + virtual const IOV& requiredValidity() const override { return m_pool.validity(); } + /// Accessor for the current conditons mapping + virtual ConditionsMap& conditionsMap() const override { return m_pool; } /// ConditionResolver implementation: Interface to access conditions. - virtual Condition get(const ConditionKey& key) const { return get(key.hash); } + virtual Condition get(const ConditionKey& key) override { return get(key.hash); } /// ConditionResolver implementation: Interface to access conditions - virtual Condition get(Condition::key_type key) const; - /// Handler callback to process multiple derived conditions - Condition::Object* operator()(const ConditionDependency* dep) const; + virtual Condition get(Condition::key_type key) 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!) + virtual std::vector<Condition> get(Condition::detkey_type key) override; }; } /* End namespace cond */ diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h index 3dfb77fe2a4bf92b63128f5991a66f2d25a972eb..63ade841e1ff4e393a85fbac7892b85012557a36 100644 --- a/DDCond/include/DDCond/ConditionsManager.h +++ b/DDCond/include/DDCond/ConditionsManager.h @@ -34,6 +34,7 @@ namespace dd4hep { class ConditionsIOVPool; class ConditionsDataLoader; class ConditionsManagerObject; + class ConditionUpdateUserContext; /// Manager class for condition handles /** @@ -162,8 +163,9 @@ namespace dd4hep { std::unique_ptr<UserPool> createUserPool(const IOVType* iovT) const; /// Prepare all updates to the clients with the defined IOV - Result prepare(const IOV& required_validity, - ConditionsSlice& slice) const; + Result prepare(const IOV& required_validity, + ConditionsSlice& slice, + ConditionUpdateUserContext* ctxt=0) const; }; /// Add results diff --git a/DDCond/include/DDCond/ConditionsManagerObject.h b/DDCond/include/DDCond/ConditionsManagerObject.h index 3f0655ea0f9bc283806110733b8d860dfde9bdd8..769d0e0670693aa5e81c201456c9603ff89ae61c 100644 --- a/DDCond/include/DDCond/ConditionsManagerObject.h +++ b/DDCond/include/DDCond/ConditionsManagerObject.h @@ -162,7 +162,7 @@ namespace dd4hep { virtual std::unique_ptr<UserPool> createUserPool(const IOVType* iovT) const = 0; /// Prepare all updates to the clients with the defined IOV - virtual Result prepare(const IOV& req_iov, ConditionsSlice& slice) = 0; + virtual Result prepare(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx=0) = 0; /// Clean conditions, which are above the age limit. /** @return Number of conditions cleaned/removed from the IOV pool of the given type */ diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index e2d5854d796beac14dd0f3bd4775a23d4914eb04..c3cb35e9d368feb9d681f5d905ff8bafcab457fb 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -208,13 +208,13 @@ namespace dd4hep { const Condition::Processor& processor) const = 0; /// Prepare user pool for usage (load, fill etc.) according to required IOV - virtual ConditionsManager::Result prepare(const IOV& required, - ConditionsSlice& slice, - void* user_param = 0) = 0; + virtual ConditionsManager::Result prepare(const IOV& required, + ConditionsSlice& slice, + ConditionUpdateUserContext* user_param = 0) = 0; /// Evaluate and register all derived conditions from the dependency list virtual size_t compute(const Dependencies& dependencies, - void* user_param, + ConditionUpdateUserContext* user_param, bool force) = 0; }; } /* End namespace cond */ diff --git a/DDCond/include/DDCond/Type1/Manager_Type1.h b/DDCond/include/DDCond/Type1/Manager_Type1.h index d45bab2bca18233b5587afad2d2731bbd152eed9..015f72b4d44f236cced835acb9db1b93ceb15690 100644 --- a/DDCond/include/DDCond/Type1/Manager_Type1.h +++ b/DDCond/include/DDCond/Type1/Manager_Type1.h @@ -167,7 +167,7 @@ namespace dd4hep { * * @return */ - Result prepare(const IOV& req_iov, ConditionsSlice& slice) final; + Result prepare(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctxt) final; }; } /* End namespace cond */ diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp index d73d86885def67cb12ec58e781bb74b9e5e198fb..3d800d86d4e311fc31ed8aad3337fa0917bf4c46 100644 --- a/DDCond/src/ConditionsDependencyHandler.cpp +++ b/DDCond/src/ConditionsDependencyHandler.cpp @@ -23,7 +23,7 @@ using namespace dd4hep::cond; ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager mgr, UserPool& pool, const Dependencies& dependencies, - void* user_param) + ConditionUpdateUserContext* user_param) : m_manager(mgr.access()), m_pool(pool), m_dependencies(dependencies), m_userParam(user_param), num_callback(0) { @@ -40,26 +40,82 @@ Detector& ConditionsDependencyHandler::detectorDescription() const { return m_manager->detectorDescription(); } +/// 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); + continue; + } + // printout(INFO,"UserPool","Already calcluated: %s",d->name()); + continue; + } +} + +/// 2nd pass: Handler callback for the second turn to resolve missing dependencies +void ConditionsDependencyHandler::resolve() { + 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); + } +} + +/// Interface to access conditions by hash value of the DetElement (only valid at resolve!) +std::vector<Condition> ConditionsDependencyHandler::get(DetElement de) { + return this->get(de.key()); +} + +/// Interface to access conditions by hash value of the DetElement (only valid at resolve!) +std::vector<Condition> ConditionsDependencyHandler::get(Condition::detkey_type det_key) { + if ( m_state == RESOLVED ) { + ConditionKey::KeyMaker lower(det_key, 0); + ConditionKey::KeyMaker upper(det_key, ~0x0); + return m_pool.get(lower.hash, upper.hash); + } + except("ConditionsDependencyHandler", + "Conditions bulk accesses are only possible during conditions resolution!"); + return std::vector<Condition>(); +} + /// ConditionResolver implementation: Interface to access conditions -Condition ConditionsDependencyHandler::get(Condition::key_type key) const { +Condition ConditionsDependencyHandler::get(Condition::key_type key) { + /// 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; + } + } + /// 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; + /// 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); + 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); + return do_callback(dep); } return Condition(); } @@ -67,20 +123,20 @@ Condition ConditionsDependencyHandler::get(Condition::key_type key) const { /// Internal call to trigger update callback Condition::Object* -ConditionsDependencyHandler::do_callback(const ConditionDependency& dep) const { +ConditionsDependencyHandler::do_callback(const ConditionDependency* dep) { try { IOV iov(m_pool.validity().iovType); - ConditionUpdateContext ctxt(*this, dep, m_userParam, iov.reset().invert()); - Condition cond = (*dep.callback)(dep.target, ctxt); + 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; + obj->hash = dep->target.hash; cond->setFlag(Condition::DERIVED); - //cond->validate(); cond->iov = m_pool.validityPtr(); // Must IMMEDIATELY insert to handle inter-dependencies. ++num_callback; - m_pool.insert(dep.detector, dep.target.item_key(), cond); + m_created[dep->target.hash] = Created(dep, obj); + m_pool.insert(cond); m_manager->registerUnlocked(*m_iovPool, cond); } return obj; @@ -88,22 +144,17 @@ ConditionsDependencyHandler::do_callback(const ConditionDependency& dep) const catch(const std::exception& e) { printout(ERROR,"ConditionDependency", "+++ Exception while creating dependent Condition %s:", - dep.name()); + dep->name()); printout(ERROR,"ConditionDependency","\t\t%s", e.what()); } catch(...) { printout(ERROR,"ConditionDependency", "+++ UNKNOWN exception while creating dependent Condition %s.", - dep.name()); + dep->name()); } m_pool.print("*"); except("ConditionDependency", "++ Exception while creating dependent Condition %s.", - dep.name()); + dep->name()); return 0; } - -/// Handler callback to process multiple derived conditions -Condition::Object* ConditionsDependencyHandler::operator()(const ConditionDependency* dep) const { - return do_callback(*dep); -} diff --git a/DDCond/src/ConditionsManager.cpp b/DDCond/src/ConditionsManager.cpp index 68d7d579bae3be2b8d7a50a1da2c188f41748326..69e548ac27b4c9a0913736d33032b105aab594c7 100644 --- a/DDCond/src/ConditionsManager.cpp +++ b/DDCond/src/ConditionsManager.cpp @@ -252,6 +252,6 @@ std::unique_ptr<UserPool> ConditionsManager::createUserPool(const IOVType* iovT) /// Prepare all updates to the clients with the defined IOV ConditionsManager::Result -ConditionsManager::prepare(const IOV& req_iov, ConditionsSlice& slice) const { - return access()->prepare(req_iov, slice); +ConditionsManager::prepare(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx) const { + return access()->prepare(req_iov, slice, ctx); } diff --git a/DDCond/src/ConditionsRepository.cpp b/DDCond/src/ConditionsRepository.cpp index b092b9311828ae2ef3dfdca1e536c62895cd65c2..c78def29cb5555d19e47dbc25fe2293f1417fff3 100644 --- a/DDCond/src/ConditionsRepository.cpp +++ b/DDCond/src/ConditionsRepository.cpp @@ -67,7 +67,9 @@ namespace { root.append(cond = xml_elt_t(doc, _U(ref))); cond.setAttr(_U(key), text); cond.setAttr(_U(name), c.name()); +#if !defined(DD4HEP_MINIMAL_CONDITIONS) cond.setAttr(_U(ref), c.address()); +#endif } printout(ALWAYS,"ConditionsRepository","++ Handled %ld conditions.",all.size()); if ( !output.empty() ) { @@ -102,9 +104,10 @@ namespace { } int createText(const string& output, const AllConditions& all, char sep) { + ofstream out(output); +#if !defined(DD4HEP_MINIMAL_CONDITIONS) size_t siz_nam=0, siz_add=0, siz_tot=0; char fmt[64], text[2*PATH_MAX+64]; - ofstream out(output); if ( !out.good() ) { except("ConditionsRepository", "++ Failed to open output file:%s [errno:%d %s]", @@ -134,6 +137,7 @@ namespace { ::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str()); out << text << endl; } +#endif out.close(); return 1; } diff --git a/DDCond/src/ConditionsTextRepository.cpp b/DDCond/src/ConditionsTextRepository.cpp index 299dcc662afcf34063feed8159c6cc60a2ecc943..3be4589ea3e265c08d1aeb68c093e4a0698dde19 100644 --- a/DDCond/src/ConditionsTextRepository.cpp +++ b/DDCond/src/ConditionsTextRepository.cpp @@ -65,7 +65,9 @@ namespace { root.append(cond = xml_elt_t(doc, _U(ref))); cond.setAttr(_U(key), text); cond.setAttr(_U(name), c.second.name()); +#if !defined(DD4HEP_MINIMAL_CONDITIONS) cond.setAttr(_U(ref), c.second.address()); +#endif } printout(ALWAYS,"ConditionsRepository","++ Handled %ld conditions.",all.size()); if ( !output.empty() ) { @@ -100,9 +102,10 @@ namespace { } int createText(const string& output, const AllConditions& all, char sep) { + ofstream out(output); +#if !defined(DD4HEP_MINIMAL_CONDITIONS) size_t siz_nam=0, siz_add=0, siz_tot=0; char fmt[64], text[2*PATH_MAX+64]; - ofstream out(output); if ( !out.good() ) { except("ConditionsTextRepository", "++ Failed to open output file:%s [errno:%d %s]", @@ -116,8 +119,8 @@ namespace { Condition::Object* c = i.second.ptr(); size_t siz_n = c->name.length(); size_t siz_a = c->address.length(); - if ( siz_nam < siz_n ) siz_nam = siz_n; if ( siz_add < siz_a ) siz_add = siz_a; + if ( siz_nam < siz_n ) siz_nam = siz_n; if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a; } siz_tot += 8+2+1; @@ -132,6 +135,7 @@ namespace { ::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str()); out << text << endl; } +#endif out.close(); return 1; } diff --git a/DDCond/src/Type1/Manager_Type1.cpp b/DDCond/src/Type1/Manager_Type1.cpp index d05fa62586dcb701abb8a970be4e0bea7f89b54e..ead7972026fef539bd4fa42f6cfc99a62f015a24 100644 --- a/DDCond/src/Type1/Manager_Type1.cpp +++ b/DDCond/src/Type1/Manager_Type1.cpp @@ -442,13 +442,13 @@ Manager_Type1::getRange(Condition::key_type key, const IOV& iov) /// Prepare all updates for the given keys to the clients with the defined IOV ConditionsManager::Result -Manager_Type1::prepare(const IOV& req_iov, ConditionsSlice& slice) +Manager_Type1::prepare(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx) { __get_checked_pool(req_iov, slice.pool); /// First push any pending updates and register them to pending pools... pushUpdates(); /// Now update/fill the user pool - return slice.pool->prepare(req_iov, slice); + return slice.pool->prepare(req_iov, slice, ctx); } /// Create empty user pool object diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp index 1acc6e17bb79c937570dd7cea9d69fcaf34fc7da..ecf1504884cca759c0a83fdf90e0b1480674ec34 100644 --- a/DDCond/src/plugins/ConditionsUserPool.cpp +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -110,22 +110,22 @@ namespace dd4hep { const Condition::Processor& processor) const override; /// Prepare user pool for usage (load, fill etc.) according to required IOV - virtual ConditionsManager::Result prepare(const IOV& required, - ConditionsSlice& slice, - void* user_param) override; + virtual ConditionsManager::Result prepare(const IOV& required, + ConditionsSlice& slice, + ConditionUpdateUserContext* user_param) override; /// Evaluate and register all derived conditions from the dependency list - virtual size_t compute(const Dependencies& dependencies, - void* user_param, - bool force) override; + virtual size_t compute(const Dependencies& dependencies, + ConditionUpdateUserContext* user_param, + bool force) override; /// Prepare user pool for usage (load, fill etc.) according to required IOV virtual ConditionsManager::Result load (const IOV& required, ConditionsSlice& slice); /// Prepare user pool for usage (load, fill etc.) according to required IOV - virtual ConditionsManager::Result compute(const IOV& required, - ConditionsSlice& slice, - void* user_param); + virtual ConditionsManager::Result compute(const IOV& required, + ConditionsSlice& slice, + ConditionUpdateUserContext* user_param); }; } /* End namespace cond */ @@ -320,7 +320,7 @@ bool ConditionsMappedUserPool<MAPPING>::insert(DetElement detector, /// ConditionsMap overload: Access a condition template<typename MAPPING> Condition ConditionsMappedUserPool<MAPPING>::get(DetElement detector, unsigned int item_key) const { - ConditionKey::KeyMaker m(detector.key(),item_key); + ConditionKey::KeyMaker m(detector.key(), item_key); return get(m.hash); } @@ -395,25 +395,23 @@ bool ConditionsMappedUserPool<MAPPING>::remove(Condition::key_type hash_key) /// Evaluate and register all derived conditions from the dependency list template<typename MAPPING> size_t ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps, - void* user_param, + ConditionUpdateUserContext* user_param, bool force) { - size_t num_updates = 0; if ( !deps.empty() ) { - vector<const ConditionDependency*> missing; + Dependencies missing; // Loop over the dependencies and check if they have to be upgraded - missing.reserve(deps.size()); for ( const auto& i : deps ) { typename MAPPING::iterator j = m_conditions.find(i.first); if ( j != m_conditions.end() ) { if ( !force ) { Condition::Object* c = (*j).second; // Remeber: key ist first, test is second! - if ( IOV::key_is_contained(m_iov.keyData,c->iov->keyData) ) { + if ( !IOV::key_is_contained(m_iov.keyData,c->iov->keyData) ) { /// This condition is no longer valid. remove it! - /// This condition will be added again by the handler. + /// It will be added again by the handler. m_conditions.erase(j); - missing.push_back(i.second); + missing.insert(i); } continue; } @@ -421,18 +419,19 @@ size_t ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps, m_conditions.erase(j); } } - missing.push_back(i.second); + missing.insert(i); } if ( !missing.empty() ) { ConditionsManagerObject* m(m_manager.access()); - ConditionsDependencyHandler h(m, *this, deps, user_param); - for ( const ConditionDependency* d : missing ) { - Condition::Object* c = h(d); - if ( c ) ++num_updates; - } + ConditionsDependencyHandler handler(m, *this, missing, user_param); + /// 1rst pass: Compute/create the missing condiions + handler.compute(); + /// 2nd pass: Resolve missing dependencies + handler.resolve(); + return handler.num_callback; } } - return num_updates; + return 0; } namespace { @@ -454,9 +453,9 @@ namespace { } template<typename MAPPING> ConditionsManager::Result -ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required, - ConditionsSlice& slice, - void* user_param) +ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required, + ConditionsSlice& slice, + ConditionUpdateUserContext* user_param) { typedef vector<pair<Condition::key_type,ConditionDependency*> > CalcMissing; typedef vector<pair<Condition::key_type,ConditionsLoadInfo*> > CondMissing; @@ -550,22 +549,16 @@ ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required, if ( do_load ) { map<Condition::key_type,const ConditionDependency*> deps(calc_missing.begin(),last_calc); ConditionsDependencyHandler handler(m_manager, *this, deps, user_param); - for( const auto& i : deps ) { - const ConditionDependency* d = i.second; - typename MAPPING::iterator j = m_conditions.find(d->key()); - // If we would know, that dependencies are only ONE level, we could skip this search.... - if ( j == m_conditions.end() ) { - handler(d); - continue; - } - // printout(INFO,"UserPool","Already calcluated: %s",d->name()); - continue; - } + /// 1rst pass: Compute/create the missing condiions + handler.compute(); + /// 2nd pass: Resolve missing dependencies + handler.resolve(); + result.computed = handler.num_callback; result.missing -= handler.num_callback; if ( do_output_miss && result.computed < deps.size() ) { // Is this cheaper than an intersection ? - for( auto i = calc_missing.begin(); i != last_calc; ++i) { + for( auto i = calc_missing.begin(); i != last_calc; ++i ) { typename MAPPING::iterator j = m_conditions.find((*i).first); if ( j == m_conditions.end() ) slice_miss_calc.insert(*i); @@ -651,9 +644,9 @@ ConditionsMappedUserPool<MAPPING>::load(const IOV& required, } template<typename MAPPING> ConditionsManager::Result -ConditionsMappedUserPool<MAPPING>::compute(const IOV& required, - ConditionsSlice& slice, - void* user_param) +ConditionsMappedUserPool<MAPPING>::compute(const IOV& required, + ConditionsSlice& slice, + ConditionUpdateUserContext* user_param) { typedef vector<pair<Condition::key_type,ConditionDependency*> > CalcMissing; const auto& slice_calc = slice.content->derived(); @@ -690,17 +683,12 @@ ConditionsMappedUserPool<MAPPING>::compute(const IOV& required, if ( do_load ) { map<Condition::key_type,const ConditionDependency*> deps(calc_missing.begin(),last_calc); ConditionsDependencyHandler handler(m_manager, *this, deps, user_param); - for( const auto& i : deps ) { - const ConditionDependency* d = i.second; - typename MAPPING::iterator j = m_conditions.find(d->key()); - // If we would know, that dependencies are only ONE level, we could skip this search.... - if ( j == m_conditions.end() ) { - handler(d); - continue; - } - // printout(INFO,"UserPool","Already calcluated: %s",d->name()); - continue; - } + + /// 1rst pass: Compute/create the missing condiions + handler.compute(); + /// 2nd pass: Resolve missing dependencies + handler.resolve(); + result.computed = handler.num_callback; result.missing -= handler.num_callback; if ( do_output && result.computed < deps.size() ) { diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt index 0f322b2613c629332a7634e33f93c31dae7168de..1bf5fa1c34b9bd727b04fae0916241d9efb4d6c8 100644 --- a/DDCore/CMakeLists.txt +++ b/DDCore/CMakeLists.txt @@ -12,17 +12,21 @@ dd4hep_package( DDCore USES [ROOT REQUIRED COMPONENTS Geom GenVector] DDParsers - #OPTIONAL XERCESC + OPTIONAL XERCESC INCLUDE_DIRS include - INSTALL_INCLUDES include/DDSegmentation include/DD4hep include/Parsers include/XML include/JSON) + INSTALL_INCLUDES include/DDSegmentation + include/DD4hep + include/XML + include/JSON + include/Parsers + include/ROOT) #---Generate ROOT dictionary------------------------------------------------------ dd4hep_add_dictionary( G__DD4hep SOURCES include/ROOT/Warnings.h - include/XML/Helper.h -# include/JSON/Helper.h include/DD4hep/*.h include/DD4hep/detail/*.h + include/XML/*.h src/DetectorImp.h src/RootDictionary.h EXCLUDE include/DD4hep/DetFactoryHelper.h diff --git a/DDCore/include/DD4hep/AlignmentData.h b/DDCore/include/DD4hep/AlignmentData.h index 6b83e0906b593a8eb1f4a404ccbf6141be479ab0..f4f5fa51e9bb959d92c6f94fc04b367f2c8ce11a 100644 --- a/DDCore/include/DD4hep/AlignmentData.h +++ b/DDCore/include/DD4hep/AlignmentData.h @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -27,7 +27,7 @@ namespace dd4hep { // Forward declarations class Alignment; class AlignmentCondition; - + /// Class describing an condition to re-adjust an alignment /** * @@ -85,6 +85,8 @@ namespace dd4hep { bool hasRotation() const { return checkFlag(HAVE_ROTATION); } /// Access flags: Check if the delta operation contains a pivot bool hasPivot() const { return checkFlag(HAVE_PIVOT); } + /// Compute the alignment delta for one detector element and it's alignment condition + void computeMatrix(TGeoHMatrix& tr_delta) const; }; /// Derived condition data-object definition @@ -114,8 +116,6 @@ namespace dd4hep { Delta delta; /// Intermediate buffer to store the transformation to the world coordination system mutable TGeoHMatrix worldTrafo; - /// Delta transformation to the world coordination system - mutable TGeoHMatrix worldDelta; /// Intermediate buffer to store the transformation to the parent detector element mutable TGeoHMatrix detectorTrafo; /// The list of TGeoNodes (physical placements) diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h index 85cac14000df96a24b4116e7d33fef1caa5de29e..68b988c972531fc504c5239c7e72ecba0cac8228 100644 --- a/DDCore/include/DD4hep/Alignments.h +++ b/DDCore/include/DD4hep/Alignments.h @@ -56,6 +56,7 @@ namespace dd4hep { static const Condition::itemkey_type alignmentKey; }; } + /// Main handle class to hold an alignment conditions object /** diff --git a/DDCore/include/DD4hep/AlignmentsCalculator.h b/DDCore/include/DD4hep/AlignmentsCalculator.h index 2598effd381f388374f23b3e03ebd0d59c0b6dc9..cb10ca9ff2f44a765429525280c16f3220bb798b 100644 --- a/DDCore/include/DD4hep/AlignmentsCalculator.h +++ b/DDCore/include/DD4hep/AlignmentsCalculator.h @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -32,6 +32,8 @@ namespace dd4hep { */ class AlignmentsCalculator { public: + + typedef std::map<DetElement, Delta> Deltas; /// Object encapsulating the result of a computation call to the alignments calculator /** @@ -65,7 +67,7 @@ namespace dd4hep { /// Assignment operator AlignmentsCalculator& operator=(const AlignmentsCalculator& mgr) = delete; /// Compute all alignment conditions of the internal dependency list - Result compute(const std::map<DetElement, Delta>& deltas, ConditionsMap& alignments) const; + Result compute(const Deltas& deltas, ConditionsMap& alignments) const; }; /// Add results diff --git a/DDCore/include/DD4hep/AlignmentsPrinter.h b/DDCore/include/DD4hep/AlignmentsPrinter.h index c5256673091e048a68a7265469b37211f0b41c0e..7e52413bd38b981da2ed2e145ad99da3ea59eb43 100644 --- a/DDCore/include/DD4hep/AlignmentsPrinter.h +++ b/DDCore/include/DD4hep/AlignmentsPrinter.h @@ -93,6 +93,7 @@ namespace dd4hep { virtual int operator()(Alignment cond) const override; }; + /// Default printout of an alignment entry void printAlignment(PrintLevel prt_level, const std::string& prefix, Alignment alignment); diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h index 0a73dd03ec792554c939e6d96e5502db24026ad8..2d0da5c45c81cf714ffa5c6e90406ff7306b7d50 100644 --- a/DDCore/include/DD4hep/ConditionDerived.h +++ b/DDCore/include/DD4hep/ConditionDerived.h @@ -32,6 +32,20 @@ namespace dd4hep { class ConditionDependency; class ConditionUpdateCall; + /// ConditionUpdateUserContext class used by the derived conditions calculation mechanism + /** + * Used to pass user data to the update calls during ConditionsManager::prepare + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionUpdateUserContext { + public: + /// Default destructor + virtual ~ConditionUpdateUserContext(); + }; + /// ConditionResolver class used by the derived conditions calculation mechanism /** * \author M.Frank @@ -42,16 +56,22 @@ namespace dd4hep { public: /// Standard destructor virtual ~ConditionResolver(); - /// Interface to access conditions by conditions key - virtual Condition get(const ConditionKey& key) const = 0; - /// Interface to access conditions by hash value - virtual Condition get(Condition::key_type key) const = 0; /// Access to the conditions manager virtual Handle<NamedObject> manager() const = 0; /// Access to the detector description instance virtual Detector& detectorDescription() const = 0; /// Required IOV value for update cycle virtual const IOV& requiredValidity() const = 0; + /// Accessor for the current conditons mapping + virtual ConditionsMap& conditionsMap() const = 0; + /// Interface to access conditions by conditions key + virtual Condition get(const ConditionKey& key) = 0; + /// Interface to access conditions by hash value + virtual Condition get(Condition::key_type key) = 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!) + virtual std::vector<Condition> get(Condition::detkey_type key) = 0; }; /// ConditionUpdateContext class used by the derived conditions calculation mechanism @@ -62,15 +82,15 @@ namespace dd4hep { */ class ConditionUpdateContext { public: - const ConditionResolver& resolver; - const ConditionDependency& dependency; - IOV* iov; - void* parameter; + ConditionResolver* resolver; + const ConditionDependency* dependency; + ConditionUpdateUserContext* parameter; + IOV* iov; /// Initializing constructor - ConditionUpdateContext(const ConditionResolver& r, - const ConditionDependency& d, - void* parameter, - IOV& iov); + ConditionUpdateContext(ConditionResolver* r, + const ConditionDependency* d, + ConditionUpdateUserContext* parameter, + IOV* iov); /// Throw exception on conditions access failure void accessFailure(const ConditionKey& key_value) const; /// Access to dependency keys @@ -79,13 +99,15 @@ namespace dd4hep { 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; /// 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); + 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 @@ -97,7 +119,7 @@ namespace dd4hep { } /// 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); + 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 @@ -137,6 +159,7 @@ namespace dd4hep { virtual ~ConditionUpdateCall(); /// No assignment operator ConditionUpdateCall& operator=(const ConditionUpdateCall& copy) = delete; + public: /// Add use count to the object ConditionUpdateCall* addRef() { @@ -148,9 +171,11 @@ namespace dd4hep { if ( --m_refCount <= 0 ) delete this; } - /// Interface to client Callback in order to update the condition + /// Interface to client callback in order to update/create the condition virtual Condition operator()(const ConditionKey& target, const ConditionUpdateContext& ctxt) = 0; + /// Interface to client callback for resolving references or to use data from other conditions + virtual void resolve(Condition /* c */, ConditionResolver& /* resolver */) {} }; /// Condition dependency definition @@ -226,32 +251,39 @@ namespace dd4hep { }; /// Initializing constructor - inline ConditionUpdateContext::ConditionUpdateContext(const ConditionResolver& resolv, - const ConditionDependency& dep, - void* user_param, - IOV& iov_ref) - : resolver(resolv), dependency(dep), iov(&iov_ref), parameter(user_param) + inline ConditionUpdateContext::ConditionUpdateContext(ConditionResolver* resolv, + const ConditionDependency* dep, + ConditionUpdateUserContext* user_param, + IOV* i) + : resolver(resolv), dependency(dep), parameter(user_param), iov(i) { } /// Access to dependency keys inline const ConditionKey& ConditionUpdateContext::key(size_t which) const { - return dependency.dependencies[which]; + 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); + Condition c = resolver->get(key_value); if ( c.isValid() ) return c; throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition:"+key_value.name); } - + /// Access to condition object by dependency index inline Condition ConditionUpdateContext::condition(size_t which) const { const ConditionKey& key_value = this->key(which); return this->condition(key_value); } + /// 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."); + } + } /* 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 b48f0c2f071b2b8fafc9a4e57046b65f7eee5901..76a95b7797387cf47b52b4a3a4ab4b797414112e 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -80,11 +80,11 @@ namespace dd4hep { ONSTACK = 1<<4, // Flags for specific conditions TEMPERATURE = 1<<5, - TEMPERATURE_DERIVED = TEMPERATURE|DERIVED, - PRESSURE = 1<<6, - PRESSURE_DERIVED = PRESSURE|DERIVED, - ALIGNMENT_DELTA = 1<<7, - ALIGNMENT_DERIVED = ALIGNMENT_DELTA|DERIVED, + TEMPERATURE_DERIVED = 1<<6|DERIVED, + PRESSURE = 1<<7, + PRESSURE_DERIVED = 1<<8|DERIVED, + ALIGNMENT_DELTA = 1<<9, + ALIGNMENT_DERIVED = 1<<10|DERIVED, // Keep bit 8-15 for other generic types // Bit 16-31 is reserved for user classifications USER_FLAGS_FIRST = 1<<16, @@ -148,18 +148,21 @@ namespace dd4hep { detkey_type detector_key() const; /// Item part of the identifier itemkey_type item_key() const; - - + /** Direct data items in string form */ /// Access the type field of the condition const std::string& type() const; - /// Access the comment field of the condition - const std::string& comment() const; + +#if !defined(DD4HEP_MINIMAL_CONDITIONS) /// Access the value field of the condition as a string const std::string& value() const; + /// Access the comment field of the condition + const std::string& comment() const; /// Access the address string [e.g. database identifier] const std::string& address() const; - +#endif + /// Flag operations: Get condition flags + mask_type flags() const; /// Flag operations: Set a conditons flag void setFlag(mask_type option); /// Flag operations: UN-Set a conditons flag @@ -246,7 +249,14 @@ namespace dd4hep { this->values.det_key = det; this->values.item_key = item; } + /// Constructor from string + KeyMaker(Condition::detkey_type det, const std::string& value); + /// Constructor from string + KeyMaker(DetElement detector, const std::string& value); + /// Constructor from detector element and item sub-key + KeyMaker(DetElement detector, Condition::itemkey_type item_key); }; + /// Compare keys by the hash value /** * \author M.Frank diff --git a/DDCore/include/DD4hep/ConditionsPrinter.h b/DDCore/include/DD4hep/ConditionsPrinter.h index 0063f119881d28d4c603304156a91d7558d61768..5733a4f6597e6e3a35c6026f5d7548ccbf0ca4a7 100644 --- a/DDCore/include/DD4hep/ConditionsPrinter.h +++ b/DDCore/include/DD4hep/ConditionsPrinter.h @@ -66,7 +66,8 @@ namespace dd4hep { mutable size_t numCondition = 0; /// Counter: number of empty conditions mutable size_t numEmptyCondition = 0; - + /// Flag to print summary + bool summary = true; public: /// Initializing constructor ConditionsPrinter(ConditionsMap* m, @@ -83,6 +84,7 @@ namespace dd4hep { /// Callback to output conditions information virtual int operator()(Condition condition) const; }; + } /* End namespace cond */ } /* End namespace dd4hep */ #endif /* DD4HEP_DDCORE_CONDITIONSPRINTER_H */ diff --git a/DDCore/include/DD4hep/ConditionsProcessor.h b/DDCore/include/DD4hep/ConditionsProcessor.h index 41d71c22d5a770014468a97be9543921c8ca3e45..7fbf7311cc763cd13839549a76073d76e29d785e 100644 --- a/DDCore/include/DD4hep/ConditionsProcessor.h +++ b/DDCore/include/DD4hep/ConditionsProcessor.h @@ -149,6 +149,7 @@ namespace dd4hep { template <typename T> inline ConditionsCollector<typename std::remove_reference<T>::type> conditionsCollector(ConditionsMap& m, T&& conditions) { return ConditionsCollector<typename std::remove_reference<T>::type>(m, conditions); } + } /* End namespace cond */ } /* End namespace dd4hep */ diff --git a/DDCore/include/DD4hep/DetectorProcessor.h b/DDCore/include/DD4hep/DetectorProcessor.h index f9a42bc0d37859e0cd8e7c69319fdde0a187e0f9..a4dfa1ccc402f637ef44b4aa5b6a7e6778506aa8 100644 --- a/DDCore/include/DD4hep/DetectorProcessor.h +++ b/DDCore/include/DD4hep/DetectorProcessor.h @@ -117,6 +117,46 @@ namespace dd4hep { { return (*processor)(de, level); } }; + /// Generic detector element collector of a sub-tree + /** + * To be used with utilities like DetElementProcessor etc. + * + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + template <typename T> class DetElementsCollector { + public: + /// Collection container + T& elements; + public: + /// Default constructor + DetElementsCollector(T& d) : elements(d) {} + /// Default move constructor is disabled + DetElementsCollector(T&& p) = delete; + /// R-value copy from a temporary + DetElementsCollector(DetElementsCollector&& copy) = default; + /// Copy constructor + DetElementsCollector(const DetElementsCollector& copy) = default; + /// Default destructor + ~DetElementsCollector() = default; + /// Assignment operator + DetElementsCollector& operator=(const DetElementsCollector& copy) = default; + /// Callback to output elements information + /** Note: Valid implementations exist for the container types: + * std::set<DetElement> + * std::list<DetElement> + * std::vector<DetElement> + */ + virtual int operator()(DetElement de, int level) const final; + }; + + /// Creator utility function for DetElementsCollector objects + template <typename T> inline + DetElementsCollector<typename std::remove_reference<T>::type> detElementsCollector(T&& container) + { return DetElementsCollector<typename std::remove_reference<T>::type>(container); } + /// Helper to run DetElement scans /** * This wrapper converts any object, which has the signature diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index 81e85b58a019bff54f4a3eb85b1fe75413b71d2f..d1c9d71fce9c5044429794e05c1a1e1a95d09ac3 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -88,7 +88,9 @@ namespace dd4hep { /** Type definitions and class specific abbreviations and forward declarations */ /// Extern accessible definition of the contained element type typedef T Object; - + /// Self type: used by sub-classes + typedef Handle<T> Base; + /// Single and only data member: Reference to the actual element. T* m_element = 0; diff --git a/DDCore/include/DD4hep/config.h b/DDCore/include/DD4hep/config.h index 6939acabf62a1f84753e29f8c144cf3cb86391c6..7b9009430cd9ca8ce3bfa1a1ef12c0234cf39be7 100644 --- a/DDCore/include/DD4hep/config.h +++ b/DDCore/include/DD4hep/config.h @@ -10,16 +10,13 @@ // Author : M.Frank // //========================================================================== -// -// Setup XML parsing for the use of Apache Xerces-C and TiXml -// -//========================================================================== -#ifndef DD4HEP_DDCORE_CONFIG_H -#define DD4HEP_DDCORE_CONFIG_H +#ifndef DD4HEP_CONFIG_H +#define DD4HEP_CONFIG_H -#include "Parsers/config.h" #define DD4HEP_INSTANCE_COUNTS 1 #define DD4HEP_USE_SAFE_CAST 1 +/// Enable this if you want to minimize the footprint of conditions +///#define DD4HEP_MINIMAL_CONDITIONS 1 #ifdef DD4HEP_INSTANCE_COUNTS #define INCREMENT_COUNTER InstanceCount::increment(this) @@ -29,4 +26,12 @@ #define DECREMENT_COUNTER #endif -#endif // DD4HEP_DDCORE_CONFIG_H +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for implementation details of the AIDA detector description toolkit + namespace detail { + + } /* End namespace detail */ +} /* End namespace dd4hep */ +#endif /* DD4HEP_CONFIG_H */ diff --git a/DDCore/include/DD4hep/detail/ConditionsInterna.h b/DDCore/include/DD4hep/detail/ConditionsInterna.h index 2aebdf9083bbfc83546e01d0be91e10ff812a235..846a6e00961f4b58c8d281ef56d7ef7b1cf09197 100644 --- a/DDCore/include/DD4hep/detail/ConditionsInterna.h +++ b/DDCore/include/DD4hep/detail/ConditionsInterna.h @@ -31,6 +31,7 @@ // C/C++ include files #include <map> + /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -59,12 +60,14 @@ namespace dd4hep { public: /// Condition value (in string form) std::string value; +#if !defined(DD4HEP_MINIMAL_CONDITIONS) /// Condition validity (in string form) std::string validity; /// Condition address std::string address; /// Comment string std::string comment; +#endif /// Data block OpaqueDataBlock data; /// Interval of validity diff --git a/DDCore/include/DD4hep/detail/ContainerHelpers.h b/DDCore/include/DD4hep/detail/ContainerHelpers.h index 1bd3491df9c43c60fa29bf41b91304e5f5f3df42..148bb47473b4344b62620e0a00ddb5daa3a11e5e 100644 --- a/DDCore/include/DD4hep/detail/ContainerHelpers.h +++ b/DDCore/include/DD4hep/detail/ContainerHelpers.h @@ -18,25 +18,57 @@ // C/C++ include files #include <map> +#include <set> #include <list> #include <vector> #include <string> /// Namespace for the AIDA detector description toolkit +/** Functions useful to make projections into various containers + * when using Conditions/Alignment/DetElement processors. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ namespace dd4hep { template <typename Q, typename T> void insert_item(std::vector<T>& c, Q, const T& d) { c.push_back(d); } + template <typename Q, typename T> + void insert_item(std::vector<Q>& c, Q de, const T&) { + c.push_back(de); + } + template <typename Q, typename T> void insert_item(std::list<T>& c, Q, const T& d) { c.push_back(d); } template <typename Q, typename T> - void insert_item(std::map<Q,T>& c, Q de, const T& d) { + void insert_item(std::list<Q>& c, Q de, const T&) { + c.push_back(de); + } + + template <typename Q, typename T> + void insert_item(std::set<T>& c, Q, const T& d) { + c.insert(d); + } + template <typename Q, typename T> + void insert_item(std::set<Q>& c, Q de, const T&) { + c.insert(de); + } + + template <typename Q, typename T> + void insert_item(std::map<Q,T>& c, Q de, const T& d) { c.insert(std::make_pair(de,d)); } + template <typename Q, typename T> + void insert_item(std::map<T,Q>& c, Q de, const T& d) { + c.insert(std::make_pair(d,de)); + } + template <typename Q, typename T> void insert_item(std::vector<std::pair<Q,T> >& c, Q de, const T& d) { c.push_back(std::make_pair(de,d)); @@ -45,7 +77,25 @@ namespace dd4hep { void insert_item(std::vector<std::pair<std::string,T> >& c, Q de, const T& d) { c.push_back(std::make_pair(de.path(),d)); } - + + template <typename Q, typename T> + void insert_item(std::list<std::pair<Q,T> >& c, Q de, const T& d) { + c.push_back(std::make_pair(de,d)); + } + template <typename Q, typename T> + void insert_item(std::list<std::pair<std::string,T> >& c, Q de, const T& d) { + c.push_back(std::make_pair(de.path(),d)); + } + + template <typename Q, typename T> + void insert_item(std::set<std::pair<Q,T> >& c, Q de, const T& d) { + c.insert(std::make_pair(de,d)); + } + template <typename Q, typename T> + void insert_item(std::set<std::pair<std::string,T> >& c, Q de, const T& d) { + c.insert(std::make_pair(de.path(),d)); + } + template <typename Q, typename T> void insert_item(std::multimap<Q,T>& c, Q de, const T& d) { c.insert(std::make_pair(de,d)); diff --git a/DDCore/include/DD4hep/detail/Handle.inl b/DDCore/include/DD4hep/detail/Handle.inl index f33e7370fcdac4a05892e113fd164d2dea06cc12..6591f7b50125519e9d6b4d6e872be7857f784529 100644 --- a/DDCore/include/DD4hep/detail/Handle.inl +++ b/DDCore/include/DD4hep/detail/Handle.inl @@ -83,7 +83,7 @@ namespace dd4hep { #define DD4HEP_SAFE_CAST_IMPLEMENTATION(FROM, TO) \ namespace dd4hep { namespace detail { \ - template <> FROM* safe_cast<FROM>::cast(FROM* p) \ + template <> template <> FROM* safe_cast<FROM>::cast(FROM* p) \ { return dynamic_cast<FROM*>(p); } \ template <> template <> FROM* safe_cast<FROM>::cast_non_null(FROM* p) { \ FROM* ptr = const_cast<FROM*>(dynamic_cast<const FROM*>(p)); \ diff --git a/DDCore/src/AlignmentData.cpp b/DDCore/src/AlignmentData.cpp index 1a8fdff951287c602cf172fce0d80a133f0d96e0..6ab67070cc86d390b7f511d7f1286c3f38caf7ed 100644 --- a/DDCore/src/AlignmentData.cpp +++ b/DDCore/src/AlignmentData.cpp @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -15,6 +15,7 @@ #include "DD4hep/AlignmentData.h" #include "DD4hep/MatrixHelpers.h" #include "DD4hep/InstanceCount.h" +#include "DD4hep/DetElement.h" #include "DD4hep/OpaqueData.h" #include "DD4hep/Primitives.h" @@ -54,6 +55,34 @@ void Delta::clear() { rotation = RotationZYX(); } +/// Compute the alignment delta for one detector element and it's alignment condition +void Delta::computeMatrix(TGeoHMatrix& tr_delta) const { + const Delta& delta = *this; + const Position& pos = delta.translation; + const Translation3D& piv = delta.pivot; + const RotationZYX& rot = delta.rotation; + + switch(delta.flags) { + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + detail::matrix::_transform(tr_delta, Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION: + detail::matrix::_transform(tr_delta, Transform3D(rot,pos)); + break; + case Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + detail::matrix::_transform(tr_delta, Transform3D(piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_ROTATION: + detail::matrix::_transform(tr_delta, rot); + break; + case Delta::HAVE_TRANSLATION: + detail::matrix::_transform(tr_delta, pos); + break; + default: + break; + } +} + /// print alignment delta object ostream& operator << (ostream& s, const Delta& data) { string res; @@ -74,7 +103,7 @@ AlignmentData::AlignmentData() /// Copy constructor AlignmentData::AlignmentData(const AlignmentData& copy) - : delta(copy.delta), worldTrafo(copy.worldTrafo), worldDelta(copy.worldDelta), + : delta(copy.delta), worldTrafo(copy.worldTrafo), detectorTrafo(copy.detectorTrafo), nodes(copy.nodes), trToWorld(copy.trToWorld), detector(copy.detector), placement(copy.placement), flag(copy.flag), magic(magic_word()) @@ -91,7 +120,6 @@ AlignmentData::~AlignmentData() { AlignmentData& AlignmentData::operator=(const AlignmentData& copy) { if ( this != © ) { delta = copy.delta; - worldTrafo = copy.worldTrafo; detectorTrafo = copy.detectorTrafo; nodes = copy.nodes; trToWorld = copy.trToWorld; @@ -201,15 +229,22 @@ Alignment AlignmentData::nominal() const { return detector.nominal(); } +// The map is used by the Alignments calculator +typedef std::map<DetElement, Delta> DeltaMap; + #include "Parsers/Parsers.h" +DD4HEP_DEFINE_OSTREAM_DUMMY(DetElement) DD4HEP_DEFINE_PARSER_DUMMY(Delta) +DD4HEP_DEFINE_PARSER_DUMMY(DeltaMap) DD4HEP_DEFINE_PARSER_DUMMY(AlignmentData) #include "DD4hep/detail/BasicGrammar_inl.h" #include "DD4hep/detail/ConditionsInterna.h" DD4HEP_DEFINE_PARSER_GRAMMAR(Delta,eval_none<Delta>) +DD4HEP_DEFINE_PARSER_GRAMMAR(DeltaMap,eval_none<DeltaMap>) DD4HEP_DEFINE_PARSER_GRAMMAR(AlignmentData,eval_none<AlignmentData>) DD4HEP_DEFINE_CONDITIONS_TYPE(Delta) +DD4HEP_DEFINE_CONDITIONS_TYPE(DeltaMap) DD4HEP_DEFINE_CONDITIONS_TYPE(AlignmentData) diff --git a/DDCore/src/AlignmentsCalculator.cpp b/DDCore/src/AlignmentsCalculator.cpp index 682f1345954b25ec0173b025457a1e3e4ee415f2..71e2afa58649935af7aeda90eda12bd8029b9d02 100644 --- a/DDCore/src/AlignmentsCalculator.cpp +++ b/DDCore/src/AlignmentsCalculator.cpp @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -39,7 +39,7 @@ namespace dd4hep { * Uses internally the conditions mechanism to calculator the alignment conditions. * * \author M.Frank - * \version 1.0 + * \version 2.0 * \ingroup DD4HEP_ALIGNMENTS */ class Calculator { @@ -52,10 +52,6 @@ namespace dd4hep { Calculator() = default; /// Default destructor ~Calculator() = default; - /// Compute the alignment delta for one detector element and it's alignment condition - void computeDelta(const Delta& delta, TGeoHMatrix& tr_delta) const; - /// Compute the transformation from the closest detector element of the alignment to the world system - Result to_world(Context& context, DetElement det, TGeoHMatrix& mat) const; /// Compute all alignment conditions of the lower levels Result compute(Context& context, Entry& entry) const; /// Resolve child dependencies for a given context @@ -106,102 +102,9 @@ namespace dd4hep { } /* End namespace align */ } /* End namespace dd4hep */ -static PrintLevel s_PRINT = WARNING; -//static PrintLevel s_PRINT = INFO; +//static PrintLevel s_PRINT = DEBUG; +static PrintLevel s_PRINT = INFO; -Result Calculator::to_world(Context& context, - DetElement det, - TGeoHMatrix& delta_to_world) const -{ - Result result; - DetElement par = det.parent(); - - while( par.isValid() ) { - // Mapping creation mode: - // If we find that the parent also got updated, directly take this transformation. - // Since we compute top-down, it is already valid! - Context::Keys::const_iterator i = context.keys.find(par.key()); - if ( i != context.keys.end() ) { - Entry& e = context.entries[(*i).second]; - // The parent entry is (not yet) valid. need to compute it first - if ( 0 == e.valid ) { - result += compute(context, e); - } - AlignmentCondition cond(e.cond); - AlignmentData& align(cond.data()); - if ( s_PRINT <= INFO ) { - ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); - ::printf(" with ALIGN(world) %s :", par.path().c_str()); align.worldDelta.Print(); - } - delta_to_world.MultiplyLeft(&align.worldDelta); - if ( s_PRINT <= INFO ) { - ::printf(" Result :"); delta_to_world.Print(); - } - ++result.computed; - return result; - } - // Mapping update mode: - // Check if there is already a transformation in the cache. If yes, take it. - // We assume it is a good one, because higher level changes are already processed. - AlignmentCondition cond = context.mapping.get(par,Keys::alignmentKey); - if ( cond.isValid() ) { - AlignmentData& align(cond.data()); - if ( s_PRINT <= INFO ) { - ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); - ::printf(" with ALIGN(world) %s :", par.path().c_str()); align.worldDelta.Print(); - } - delta_to_world.MultiplyLeft(&align.worldDelta); - if ( s_PRINT <= INFO ) { - ::printf(" Result :"); delta_to_world.Print(); - } - ++result.computed; - return result; - } - // There is no special alignment for this detector element. - // Hence to nominal (relative) transformation to the parent is valid - if ( s_PRINT <= INFO ) { - ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); - ::printf(" with NOMINAL(det) %s :", par.path().c_str()); - par.nominal().detectorTransformation().Print(); - } - delta_to_world.MultiplyLeft(&par.nominal().detectorTransformation()); - if ( s_PRINT <= INFO ) { - ::printf(" Result :"); delta_to_world.Print(); - } - par = par.parent(); - } - ++result.computed; - return result; -} - -/// Compute the alignment delta for one detector element and it's alignment condition -void Calculator::computeDelta(const Delta& delta, - TGeoHMatrix& tr_delta) const -{ - const Position& pos = delta.translation; - const Translation3D& piv = delta.pivot; - const RotationZYX& rot = delta.rotation; - - switch(delta.flags) { - case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: - detail::matrix::_transform(tr_delta, Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse()))); - break; - case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION: - detail::matrix::_transform(tr_delta, Transform3D(rot,pos)); - break; - case Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: - detail::matrix::_transform(tr_delta, Transform3D(piv*rot*(piv.Inverse()))); - break; - case Delta::HAVE_ROTATION: - detail::matrix::_transform(tr_delta, rot); - break; - case Delta::HAVE_TRANSLATION: - detail::matrix::_transform(tr_delta, pos); - break; - default: - break; - } -} /// Compute all alignment conditions of the lower levels Result Calculator::compute(Context& context, Entry& e) const { @@ -212,23 +115,37 @@ Result Calculator::compute(Context& context, Entry& e) const { printout(DEBUG,"ComputeAlignment","================ IGNORE %s (already valid)",det.path().c_str()); return result; } - AlignmentCondition c = context.mapping.get(e.det, Keys::alignmentKey); + AlignmentCondition c = context.mapping.get(det, Keys::alignmentKey); AlignmentCondition cond = c.isValid() ? c : AlignmentCondition("alignment"); AlignmentData& align = cond.data(); const Delta* delta = e.delta ? e.delta : &identity_delta; - TGeoHMatrix tr_delta; + TGeoHMatrix transform_for_delta; printout(DEBUG,"ComputeAlignment", "============================== Compute transformation of %s",det.path().c_str()); e.valid = 1; e.cond = cond.ptr(); - computeDelta(*delta, tr_delta); align.delta = *delta; - align.worldDelta = tr_delta; - result += to_world(context, det, align.worldDelta); - align.worldTrafo = det.nominal().worldTransformation()*align.worldDelta; - align.detectorTrafo = det.nominal().detectorTransformation()*tr_delta; - align.trToWorld = detail::matrix::_transform(&align.worldDelta); + delta->computeMatrix(transform_for_delta); + + DetElement parent_det = det.parent(); + AlignmentCondition parent_cond = context.mapping.get(parent_det, Keys::alignmentKey); + TGeoHMatrix parent_transform; + if (parent_cond.isValid()) { + AlignmentData& parent_align = parent_cond.data(); + parent_transform = parent_align.worldTrafo; + } + else if ( det.parent().isValid() ) { + parent_transform = parent_det.nominal().worldTransformation(); + } + else { + // The tranformation from the "world" to its parent is non-existing i.e. unity + } + + align.detectorTrafo = det.nominal().detectorTransformation() * transform_for_delta; + align.worldTrafo = parent_transform * align.detectorTrafo; + align.trToWorld = detail::matrix::_transform(&align.worldTrafo); + ++result.computed; // Update mapping if the condition is freshly created if ( !c.isValid() ) { e.created = 1; @@ -239,13 +156,17 @@ Result Calculator::compute(Context& context, Entry& e) const { printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%16llX", det.level(), det.path().c_str(), det.key(), yes_no(e.delta != 0), (long long int)cond.key()); - if ( s_PRINT <= DEBUG ) { - ::printf("DetectorTrafo: '%s' -> '%s' ",det.path().c_str(), det.parent().path().c_str()); + if ( s_PRINT <= DEBUG ) { + ::printf("Nominal: '%s' ", det.path().c_str()); + det.nominal().worldTransformation().Print(); + ::printf("Parent: '%s' -> '%s' ", det.path().c_str(), parent_det.path().c_str()); + parent_transform.Print(); + ::printf("DetectorTrafo: '%s' -> '%s' ", det.path().c_str(), det.parent().path().c_str()); det.nominal().detectorTransformation().Print(); - ::printf("Delta: '%s' ",det.path().c_str()); tr_delta.Print(); - ::printf("World-Delta: '%s' ",det.path().c_str()); align.worldDelta.Print(); - ::printf("Nominal: '%s' ",det.path().c_str()); det.nominal().worldTransformation().Print(); - ::printf("Result: '%s' ",det.path().c_str()); align.worldTrafo.Print(); + ::printf("Delta: '%s' ", det.path().c_str()); + transform_for_delta.Print(); + ::printf("Result: '%s' ", det.path().c_str()); + align.worldTrafo.Print(); } } return result; @@ -267,23 +188,9 @@ Result AlignmentsCalculator::compute(const std::map<DetElement, Delta>& deltas, 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! - // - std::map<DetElement,Delta,Calculator::Context::PathOrdering> 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 ) + for( const auto& i : deltas ) obj.resolve(context,i.first); for( auto& i : context.entries ) result += obj.compute(context, i); diff --git a/DDCore/src/AlignmentsCalculator.cpp.old b/DDCore/src/AlignmentsCalculator.cpp.old new file mode 100644 index 0000000000000000000000000000000000000000..682f1345954b25ec0173b025457a1e3e4ee415f2 --- /dev/null +++ b/DDCore/src/AlignmentsCalculator.cpp.old @@ -0,0 +1,291 @@ +//========================================================================== +// 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 "DD4hep/AlignmentsCalculator.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/ConditionsMap.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/MatrixHelpers.h" +#include "DD4hep/detail/AlignmentsInterna.h" + +using namespace dd4hep; +using namespace dd4hep::align; +typedef AlignmentsCalculator::Result Result; + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the alignment part of the AIDA detector description toolkit + namespace align { + + /// Anonymous implementation classes + namespace { + static Delta identity_delta; + + /// Alignment calculator. + /** + * Uses internally the conditions mechanism to calculator the alignment conditions. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_ALIGNMENTS + */ + class Calculator { + public: + class Entry; + class Context; + + public: + /// Initializing constructor + Calculator() = default; + /// Default destructor + ~Calculator() = default; + /// Compute the alignment delta for one detector element and it's alignment condition + void computeDelta(const Delta& delta, TGeoHMatrix& tr_delta) const; + /// Compute the transformation from the closest detector element of the alignment to the world system + Result to_world(Context& context, DetElement det, TGeoHMatrix& mat) const; + /// Compute all alignment conditions of the lower levels + Result compute(Context& context, Entry& entry) const; + /// Resolve child dependencies for a given context + void resolve(Context& context, DetElement child) const; + }; + + class Calculator::Entry { + public: + DetElement::Object* det = 0; + const Delta* delta = 0; + AlignmentCondition::Object* cond = 0; + unsigned char key = 0, valid = 0, created = 0, _pad[1]; + Entry(DetElement d, const Delta* del) : det(d.ptr()), delta(del), key(d.key()) {} + }; + + 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<unsigned int,size_t> Keys; + typedef std::vector<Entry> Entries; + + DetectorMap detectors; + Keys keys; + Entries entries; + ConditionsMap& mapping; + Context(ConditionsMap& m) : mapping(m) { + InstanceCount::increment(this); + } + ~Context() { + InstanceCount::decrement(this); + } + void insert(DetElement det, const Delta* delta) { + if ( det.isValid() ) { + Entry entry(det,delta); + detectors.insert(std::make_pair(det, entries.size())); + keys.insert(std::make_pair(entry.key, entries.size())); + entries.insert(entries.end(), entry); + return; + } + except("AlignContext","Failed to add entry: invalid detector handle!"); + } + }; + } + } /* End namespace align */ +} /* End namespace dd4hep */ + +static PrintLevel s_PRINT = WARNING; +//static PrintLevel s_PRINT = INFO; + +Result Calculator::to_world(Context& context, + DetElement det, + TGeoHMatrix& delta_to_world) const +{ + Result result; + DetElement par = det.parent(); + + while( par.isValid() ) { + // Mapping creation mode: + // If we find that the parent also got updated, directly take this transformation. + // Since we compute top-down, it is already valid! + Context::Keys::const_iterator i = context.keys.find(par.key()); + if ( i != context.keys.end() ) { + Entry& e = context.entries[(*i).second]; + // The parent entry is (not yet) valid. need to compute it first + if ( 0 == e.valid ) { + result += compute(context, e); + } + AlignmentCondition cond(e.cond); + AlignmentData& align(cond.data()); + if ( s_PRINT <= INFO ) { + ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); + ::printf(" with ALIGN(world) %s :", par.path().c_str()); align.worldDelta.Print(); + } + delta_to_world.MultiplyLeft(&align.worldDelta); + if ( s_PRINT <= INFO ) { + ::printf(" Result :"); delta_to_world.Print(); + } + ++result.computed; + return result; + } + // Mapping update mode: + // Check if there is already a transformation in the cache. If yes, take it. + // We assume it is a good one, because higher level changes are already processed. + AlignmentCondition cond = context.mapping.get(par,Keys::alignmentKey); + if ( cond.isValid() ) { + AlignmentData& align(cond.data()); + if ( s_PRINT <= INFO ) { + ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); + ::printf(" with ALIGN(world) %s :", par.path().c_str()); align.worldDelta.Print(); + } + delta_to_world.MultiplyLeft(&align.worldDelta); + if ( s_PRINT <= INFO ) { + ::printf(" Result :"); delta_to_world.Print(); + } + ++result.computed; + return result; + } + // There is no special alignment for this detector element. + // Hence to nominal (relative) transformation to the parent is valid + if ( s_PRINT <= INFO ) { + ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); + ::printf(" with NOMINAL(det) %s :", par.path().c_str()); + par.nominal().detectorTransformation().Print(); + } + delta_to_world.MultiplyLeft(&par.nominal().detectorTransformation()); + if ( s_PRINT <= INFO ) { + ::printf(" Result :"); delta_to_world.Print(); + } + par = par.parent(); + } + ++result.computed; + return result; +} + +/// Compute the alignment delta for one detector element and it's alignment condition +void Calculator::computeDelta(const Delta& delta, + TGeoHMatrix& tr_delta) const +{ + const Position& pos = delta.translation; + const Translation3D& piv = delta.pivot; + const RotationZYX& rot = delta.rotation; + + switch(delta.flags) { + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + detail::matrix::_transform(tr_delta, Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION: + detail::matrix::_transform(tr_delta, Transform3D(rot,pos)); + break; + case Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + detail::matrix::_transform(tr_delta, Transform3D(piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_ROTATION: + detail::matrix::_transform(tr_delta, rot); + break; + case Delta::HAVE_TRANSLATION: + detail::matrix::_transform(tr_delta, pos); + break; + default: + break; + } +} + +/// Compute all alignment conditions of the lower levels +Result Calculator::compute(Context& context, Entry& e) const { + Result result; + DetElement det = e.det; + + if ( e.valid == 1 ) { + printout(DEBUG,"ComputeAlignment","================ IGNORE %s (already valid)",det.path().c_str()); + return result; + } + AlignmentCondition c = context.mapping.get(e.det, Keys::alignmentKey); + AlignmentCondition cond = c.isValid() ? c : AlignmentCondition("alignment"); + AlignmentData& align = cond.data(); + const Delta* delta = e.delta ? e.delta : &identity_delta; + TGeoHMatrix tr_delta; + + printout(DEBUG,"ComputeAlignment", + "============================== Compute transformation of %s",det.path().c_str()); + e.valid = 1; + e.cond = cond.ptr(); + computeDelta(*delta, tr_delta); + align.delta = *delta; + align.worldDelta = tr_delta; + result += to_world(context, det, align.worldDelta); + align.worldTrafo = det.nominal().worldTransformation()*align.worldDelta; + align.detectorTrafo = det.nominal().detectorTransformation()*tr_delta; + align.trToWorld = detail::matrix::_transform(&align.worldDelta); + // Update mapping if the condition is freshly created + if ( !c.isValid() ) { + e.created = 1; + cond->hash = ConditionKey(e.det,Keys::alignmentKey).hash; + context.mapping.insert(e.det, Keys::alignmentKey, cond); + } + if ( s_PRINT <= INFO ) { + printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%16llX", + det.level(), det.path().c_str(), det.key(), + yes_no(e.delta != 0), (long long int)cond.key()); + if ( s_PRINT <= DEBUG ) { + ::printf("DetectorTrafo: '%s' -> '%s' ",det.path().c_str(), det.parent().path().c_str()); + det.nominal().detectorTransformation().Print(); + ::printf("Delta: '%s' ",det.path().c_str()); tr_delta.Print(); + ::printf("World-Delta: '%s' ",det.path().c_str()); align.worldDelta.Print(); + ::printf("Nominal: '%s' ",det.path().c_str()); det.nominal().worldTransformation().Print(); + ::printf("Result: '%s' ",det.path().c_str()); align.worldTrafo.Print(); + } + } + return result; +} + +/// Resolve child dependencies for a given context +void Calculator::resolve(Context& context, DetElement detector) const { + auto children = detector.children(); + auto item = context.detectors.find(detector); + if ( item == context.detectors.end() ) context.insert(detector,0); + for(const auto& c : children ) + resolve(context, c.second); +} + +/// Compute all alignment conditions of the internal dependency list +Result AlignmentsCalculator::compute(const std::map<DetElement, 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! + // + std::map<DetElement,Delta,Calculator::Context::PathOrdering> 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; +} diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp index a6314d1817c1798bd5a9edfaf18a26973e297b0a..54e060451567f42fce64d2f84cf1168d098227f1 100644 --- a/DDCore/src/ConditionDerived.cpp +++ b/DDCore/src/ConditionDerived.cpp @@ -21,6 +21,10 @@ using namespace dd4hep; using namespace dd4hep::cond; +/// Default destructor +ConditionUpdateUserContext::~ConditionUpdateUserContext() { +} + /// Standard destructor ConditionUpdateCall::ConditionUpdateCall() : m_refCount(1) { InstanceCount::increment(this); @@ -39,12 +43,12 @@ ConditionResolver::~ConditionResolver() { void ConditionUpdateContext::accessFailure(const ConditionKey& key_value) const { except("ConditionUpdateCall", "%s [%016llX]: FAILED to access non-existing item:%s [%016llX]", - dependency.target.name.c_str(), dependency.target.hash, + dependency->target.name.c_str(), dependency->target.hash, key_value.name.c_str(), key_value.hash); } /// Initializing constructor -ConditionDependency::ConditionDependency(DetElement de, +ConditionDependency::ConditionDependency(DetElement de, unsigned int item_key, ConditionUpdateCall* call) : m_refCount(0), detector(de), target(de, item_key), callback(call) @@ -75,7 +79,7 @@ ConditionDependency::~ConditionDependency() { } /// Initializing constructor -DependencyBuilder::DependencyBuilder(DetElement de, +DependencyBuilder::DependencyBuilder(DetElement de, unsigned int item_key, ConditionUpdateCall* call) : m_dependency(new ConditionDependency(de,item_key,call)) @@ -83,7 +87,7 @@ DependencyBuilder::DependencyBuilder(DetElement de, } /// Initializing constructor -DependencyBuilder::DependencyBuilder(DetElement de, +DependencyBuilder::DependencyBuilder(DetElement de, const std::string& item, ConditionUpdateCall* call) : m_dependency(new ConditionDependency(de,item,call)) diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp index 59317706dca925624a845704396772ce2351bf97..8eaec85ff4e67eb98c360bddd643c286d6a83c99 100644 --- a/DDCore/src/Conditions.cpp +++ b/DDCore/src/Conditions.cpp @@ -49,21 +49,24 @@ Condition::Condition(const string& nam,const string& typ, size_t memory) string Condition::str(int flags) const { stringstream output; Object* o = access(); - const IOV* ptr_iov = o->iovData(); if ( 0 == (flags&NO_NAME) ) output << setw(16) << left << o->name; - if ( flags&WITH_IOV ) + if ( flags&WITH_IOV ) { + const IOV* ptr_iov = o->iovData(); output << " " << (ptr_iov ? ptr_iov->str().c_str() : "IOV:[UNKNOWN]"); + } if ( flags&WITH_TYPE ) output << " (" << o->type << ")"; - if ( flags&WITH_ADDRESS ) - output << " " << o->address; if ( flags&WITH_DATATYPE ) output << " -> " << o->data.dataType(); if ( flags&WITH_DATA ) output << " Data:" << o->data.str(); +#if !defined(DD4HEP_MINIMAL_CONDITIONS) + if ( flags&WITH_ADDRESS ) + output << " " << o->address; if ( flags&WITH_COMMENT ) output << " \"" << o->comment << "\""; +#endif return output.str(); } @@ -92,6 +95,7 @@ const string& Condition::type() const { return access()->type; } +#if !defined(DD4HEP_MINIMAL_CONDITIONS) /// Access the value field of the condition as a string const string& Condition::value() const { return access()->value; @@ -106,6 +110,7 @@ const string& Condition::comment() const { const string& Condition::address() const { return access()->address; } +#endif /// Access to the type information const type_info& Condition::typeInfo() const { @@ -127,6 +132,11 @@ Condition::itemkey_type Condition::item_key() const { return ConditionKey::KeyMaker(access()->hash).values.item_key; } +/// Flag operations: Get flags +Condition::mask_type Condition::flags() const { + return access()->flags; +} + /// Flag operations: Set a conditons flag void Condition::setFlag(mask_type option) { access()->setFlag(option); @@ -177,9 +187,26 @@ ConditionsSelect::~ConditionsSelect() { } /// Constructor from string -ConditionKey::ConditionKey(DetElement detector, const string& value) { +ConditionKey::KeyMaker::KeyMaker(DetElement detector, const std::string& value) { KeyMaker m(detector.key(), detail::hash32(value)); hash = m.hash; +} + +/// Constructor from detector element and item sub-key +ConditionKey::KeyMaker::KeyMaker(DetElement detector, Condition::itemkey_type item_key) { + KeyMaker m(detector.key(), item_key); + hash = m.hash; +} + +/// Constructor from string +ConditionKey::KeyMaker::KeyMaker(Condition::detkey_type det, const std::string& value) { + KeyMaker m(det, detail::hash32(value)); + hash = m.hash; +} + +/// Constructor from string +ConditionKey::ConditionKey(DetElement detector, const string& value) { + hash = KeyMaker(detector,value).hash; #ifdef DD4HEP_CONDITIONKEY_HAVE_NAME name = detector.path()+"#"+value; #endif @@ -187,8 +214,7 @@ ConditionKey::ConditionKey(DetElement detector, const string& value) { /// Constructor from detector element key and item sub-key ConditionKey::ConditionKey(Condition::detkey_type det_key, const string& value) { - KeyMaker m(det_key, detail::hash32(value)); - hash = m.hash; + hash = KeyMaker(det_key,value).hash; #ifdef DD4HEP_CONDITIONKEY_HAVE_NAME char text[32]; ::snprintf(text,sizeof(text),"%08X#",det_key); @@ -208,12 +234,12 @@ ConditionKey::ConditionKey(DetElement detector, Condition::itemkey_type item_key /// Hash code generation from input string Condition::key_type ConditionKey::hashCode(DetElement detector, const char* value) { - return KeyMaker(detector.key(), detail::hash32(value)).hash; + return KeyMaker(detector.key(), value).hash; } /// Hash code generation from input string Condition::key_type ConditionKey::hashCode(DetElement detector, const string& value) { - return KeyMaker(detector.key(), detail::hash32(value)).hash; + return KeyMaker(detector, value).hash; } /// 32 bit hashcode of the item diff --git a/DDCore/src/ConditionsInterna.cpp b/DDCore/src/ConditionsInterna.cpp index c760e8922f084a9c56cb2563ac998004f977df32..4d3c1264f74a683948e6be9135b97d3ec754172c 100644 --- a/DDCore/src/ConditionsInterna.cpp +++ b/DDCore/src/ConditionsInterna.cpp @@ -35,14 +35,13 @@ namespace { /// Default constructor detail::ConditionObject::ConditionObject() - : NamedObject(), value(), validity(), address(), comment(), data() { InstanceCount::increment(this); } /// Standard constructor detail::ConditionObject::ConditionObject(const string& nam,const string& tit) - : NamedObject(nam, tit), value(), validity(), address(), comment(), data() + : NamedObject(nam, tit), data() { InstanceCount::increment(this); } diff --git a/DDCore/src/ConditionsPrinter.cpp b/DDCore/src/ConditionsPrinter.cpp index 42a729fd2d4d868de0e6df5b0f1c6e4b8ea66031..91e20078467be2ffcd7238d39919b841c93ee705 100644 --- a/DDCore/src/ConditionsPrinter.cpp +++ b/DDCore/src/ConditionsPrinter.cpp @@ -119,11 +119,13 @@ ConditionsPrinter::ConditionsPrinter(ConditionsMap* m, const string& pref, int f /// Default destructor ConditionsPrinter::~ConditionsPrinter() { - printout(INFO,name,"++ %s +++++++++++++ Printout summary:", prefix.c_str()); - printout(INFO,name,"++ %s Number of conditions: %8ld [ dto. empty:%ld]", - prefix.c_str(), numCondition, numEmptyCondition); - printout(INFO,name,"++ %s Total Number of parameters: %8ld [%7.3f Parameters/Condition]", - prefix.c_str(), numParam, double(numParam)/std::max(double(numCondition),1e0)); + if ( summary ) { + printout(INFO,name,"++ %s +++++++++++++ Printout summary:", prefix.c_str()); + printout(INFO,name,"++ %s Number of conditions: %8ld [ dto. empty:%ld]", + prefix.c_str(), numCondition, numEmptyCondition); + printout(INFO,name,"++ %s Total Number of parameters: %8ld [%7.3f Parameters/Condition]", + prefix.c_str(), numParam, double(numParam)/std::max(double(numCondition),1e0)); + } detail::deletePtr(m_print); } @@ -133,15 +135,19 @@ int ConditionsPrinter::operator()(Condition cond) const { if ( cond.isValid() ) { string repr = cond.str(m_flag); Condition::Object* ptr = cond.ptr(); - const type_info& type = cond.typeInfo(); - const OpaqueData& opaque = cond.data(); if ( repr.length() > lineLength ) repr = repr.substr(0,lineLength)+"..."; printout(this->printLevel,name, "++ %s%s", prefix.c_str(), repr.c_str()); - 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>"); + return 1; + } + const type_info& type = cond.typeInfo(); + const OpaqueData& opaque = cond.data(); printout(this->printLevel,name,"++ %s \tPath:%s Key:%16llX Type:%s", new_prefix.c_str(), cond.name(), cond.key(), opaque.dataType().c_str()); //string values = opaque.str(); diff --git a/DDCore/src/ConditionsProcessor.cpp b/DDCore/src/ConditionsProcessor.cpp index 208efc0a50cf335cf604ce19f0b4b4f72b3e660f..9a3514e6e4f8fcd9b138ec7582e3f55e3b9152cb 100644 --- a/DDCore/src/ConditionsProcessor.cpp +++ b/DDCore/src/ConditionsProcessor.cpp @@ -20,6 +20,7 @@ using namespace std; using namespace dd4hep; using namespace dd4hep::cond; + /// Callback to output conditions information template <typename T> int ConditionsCollector<T>::operator()(DetElement de, int) const { diff --git a/DDCore/src/DetectorProcessor.cpp b/DDCore/src/DetectorProcessor.cpp index 7189dfbf9c5834cd0171df786ea9e8ec41b2e8b9..a08741f43713537bf9dd2b3f57ed431060a2deab 100644 --- a/DDCore/src/DetectorProcessor.cpp +++ b/DDCore/src/DetectorProcessor.cpp @@ -14,6 +14,7 @@ // Framework includes #include "DD4hep/Printout.h" #include "DD4hep/DetectorProcessor.h" +#include "DD4hep/detail/ContainerHelpers.h" using namespace dd4hep; @@ -34,3 +35,23 @@ int DetectorProcessor::process(DetElement de, int level, bool recursive) const except("Detector","Cannot process an invalid detector element"); return 0; } + +/// Callback to output conditions information +template <typename T> +int DetElementsCollector<T>::operator()(DetElement de, int level) const { + insert_item(elements, de, level); + return 1; +} + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + //template class DetElementsCollector<T>; + template class DetElementsCollector<std::set<DetElement> >; + template class DetElementsCollector<std::list<DetElement> >; + template class DetElementsCollector<std::vector<DetElement> >; + + template class DetElementsCollector<std::set<std::pair<DetElement, int> > >; + template class DetElementsCollector<std::list<std::pair<DetElement, int> > >; + template class DetElementsCollector<std::vector<std::pair<DetElement, int> > >; +} /* End namespace dd4hep */ + diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index aeb582861754e00d73aed9a219f6d914072a6082..4f23bbfd2ae6d27f3b6067ecfb35a9700dba48b4 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -164,6 +164,11 @@ namespace dd4hep { return _toDouble(value); } + /// Generic type conversion from string to primitive value + template <> string _toType<string>(const string& value) { + return value; + } + template <> char _multiply<char>(const string& left, const string& right) { double val = _toDouble(left + "*" + right); if ( val >= double(SCHAR_MIN) && val <= double(SCHAR_MAX) ) diff --git a/DDDB/CMakeLists.txt b/DDDB/CMakeLists.txt index 7a40a15e9a91ad59075a6f1e70cac5e60d9fd02d..b078ba9fa698e0fdefc1ce5456a2d18f5c4d84ab 100644 --- a/DDDB/CMakeLists.txt +++ b/DDDB/CMakeLists.txt @@ -19,15 +19,12 @@ dd4hep_package( DDDB USES DDCore DDAlign DDCond INCLUDE_DIRS include - INSTALL_INCLUDES include/DDDB) - -# -# We only create only library for DDDB. The whole package is a single component -# library. A priory there is no need to seperate the implementation from the -# plugins.... + INSTALL_INCLUDES include/DDDB include/Detector include/Kernel) # -# If need arises, this can be changed easily. +#---DDCond library -------------------------------------------------------------- +dd4hep_add_package_library(DDDB + SOURCES src/*.cpp src/Detector/*.cpp ) # #---DDDB plugin library ------------------------------------------------------- -dd4hep_add_plugin ( DDDB SOURCES src/*.cpp src/plugins/*.cpp src/Detector/*.cpp +dd4hep_add_plugin(DDDBPlugins SOURCES src/plugins/*.cpp USES DDCore DDAlign DDCond ) diff --git a/DDDB/include/Detector/DeAlignmentCall.h b/DDDB/include/Detector/DeAlignmentCall.h new file mode 100644 index 0000000000000000000000000000000000000000..c3ecc2d9ef0f9cd20b45ea8b435e98873fffed63 --- /dev/null +++ b/DDDB/include/Detector/DeAlignmentCall.h @@ -0,0 +1,45 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DEALIGNMENTCALLS_H +#define DETECTOR_DEALIGNMENTCALLS_H 1 + +// Framework include files +#include "DD4hep/Conditions.h" +#include "DD4hep/ConditionDerived.h" + +/// Gaudi namespace declaration +namespace gaudi { + + /// Callback, which triggers the alignment computation once the delta-parameters are loaded + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeAlignmentCall : public dd4hep::cond::ConditionUpdateCall { + public: + dd4hep::DetElement top; + /// Initializing constructor + DeAlignmentCall(dd4hep::DetElement t) : top(t) {} + /// Default destructor + 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; + }; + +} // End namespace gaudi +#endif // DETECTOR_DEALIGNMENTCALLS_H diff --git a/DDDB/include/Detector/DeIOV.h b/DDDB/include/Detector/DeIOV.h new file mode 100644 index 0000000000000000000000000000000000000000..80946aa071a0588e26b4d069a82023d731a0aadc --- /dev/null +++ b/DDDB/include/Detector/DeIOV.h @@ -0,0 +1,203 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DE_CTORS_DEFAULT +#pragma error("This header should never be included directly. Inlcude Detector/DetectorElement.h instead!") +#endif + +#ifndef DETECTOR_DEIOV_H +#define DETECTOR_DEIOV_H + +/// Gaudi namespace declaration +namespace gaudi { + + // Forward declarations + class DeIOV; + + /// Gaudi::detail namespace declaration + namespace detail { + + // Forward declarations + class DeIOVObject; + + /// Base class for intervall of validity dependent DetectorElement data + /** + * Need to store pointers in the child chache - + * Handles are only defined below and cannot be used here. + * Though: The pointer can directly be assigned to handles. + * + * Note: + * 1) When populating the child chache it is the USER's responsibility + * To use ConditionsMaps with appropriate IOVs! + * 2) The child chache may ONLY be populated while the condition is not + * active ie. during creation/initialization time. Otherwise + * MT races occur! + * + * Concurrentcy notice: + * Except during filling, which is performed by the framework code, + * instances of this class are assumed to the read-only! + * Thread safety hence is no issue. + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeIOVObject : public detail::ConditionObject { + DE_CONDITIONS_TYPEDEFS; + + public: + /// Helper to initialize the basic information + DeIOVObject* fill_info(DetElement de, Catalog* cat); + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeIOVObject); + + /// Initialization of sub-classes. May only be called while the condition is NOT active + virtual void initialize(); + /// Fill the child cache. May only be called while the condition is NOT active + void fillCache(ConditionsMap& m); + + /// Printout method to stdout + virtual void print(int indent, int flags) const; + /// Check (enforce) the validity of the alignment object if required + void checkAlignment() const; + /// Access daughter elements: IOV dependent part + DeIOVObject* child(DetElement de) const; + + public: + /// The static part of the detector element + DeStatic de_static; + /// Cache of static information of the children. + std::map<DetElement,DeIOVObject*> childCache; + /// The dd4hep detector element reference of this gaudi detector element + DetElement detector; + /// All the time dependent conditions + Conditions conditions; + /// The alignment object, which belongs to THIS detectoreleemnt + Alignment detectorAlignment; + /// Alignments for daughter volumes not directly identified by a DetElement + VolumeAlignments volumeAlignments; + + /// We want to cache here the matrix from world to local (=inverse world2local) + TGeoHMatrix toLocalMatrix; + /// We want to cache here the delta matrix + TGeoHMatrix deltaMatrix; + /// Initialization flags to steer actions + int de_flags = 0; + /// Item key + itemkey_type key = 0; + }; + } // End namespace detail + + + /// Geometry access + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class TransformationInfo : public dd4hep::Handle<detail::DeIOVObject> { + DE_CONDITIONS_TYPEDEFS; + + public: + /// Standard handle assignments and constructors + DE_CTORS_HANDLE(TransformationInfo,Base); + + /* + /// Initialization from detector element base + template<typename s, typename i> + TransformationInfo(const DetectorElementBase<s,i>& base); + */ + /// Access to the alignmant object to transformideal coordinates + Alignment detectorAlignment() const + { return ptr()->detectorAlignment; } + + /// Access to transformation matrices + const TGeoHMatrix& toLocalMatrix() const + { return ptr()->toLocalMatrix; } + const TGeoHMatrix& toGlobalMatrix() const + { return detectorAlignment().worldTransformation(); } + const TGeoHMatrix& toLocalMatrixNominal() const + { return ptr()->deltaMatrix; } + + /// Local -> Global and Global -> Local transformations + XYZPoint toLocal( const XYZPoint& global ) const + { return XYZPoint(detectorAlignment().worldToLocal(XYZVector(global))); } + XYZPoint toGlobal( const XYZPoint& local ) const + { return XYZPoint(detectorAlignment().localToWorld(XYZVector(local))); } + XYZVector toLocal( const XYZVector& globalDirection ) const + { return detectorAlignment().worldToLocal(globalDirection); } + XYZVector toGlobal( const XYZVector& localDirection ) const + { return detectorAlignment().localToWorld(localDirection); } + }; + + /// Geometry access + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeIOV : public TransformationInfo { + DE_CONDITIONS_TYPEDEFS; + + /// Forward definition of the static type for facades + typedef detail::DeStaticObject static_t; + + public: + /// Standard handle assignments and constructors + DE_CTORS_HANDLE(DeIOV,TransformationInfo); + DeIOV(const TransformationInfo& c) : TransformationInfo(c) {} + + /// Printout method to stdout + void print(int indent, int flags) const; + /// Access to the static data + static_t& staticData() const + { return access()->de_static; } + + /// Compute key value for caching + static itemkey_type key(const std::string& value) + { return dd4hep::ConditionKey::itemCode(value); } + /// Compute key value for caching + static itemkey_type key(const char* value) + { return dd4hep::ConditionKey::itemCode(value); } + + /// Access all conditions which belong to this detector element + const Conditions& conditions() const; + + /// Check if the condition identified by 'key' is in the list of conditionrefs. + bool hasCondition(itemkey_type key) const + { return this->condition(key, false).isValid(); } + /// Access condition by hash-key (fast) + Condition condition(itemkey_type key) const; + /// Access condition by hash-key (fast) + Condition condition(itemkey_type key, bool throw_if) const; + + /// Check if the condition called 'name' is in the list of conditionrefs. + bool hasCondition(const std::string& nam) const + { return this->condition(nam, false).isValid(); } + /// Access condition by name (slow) + Condition condition(const std::string& name) const; + /// Access condition by name (slow) + Condition condition(const std::string& name, bool throw_if) const; + + /// Access the volume alignments + const VolumeAlignments& volumeAlignments() const; + + }; +} // End namespace gaudi + +#endif // DETECTOR_DEIOV_H diff --git a/DDDB/include/Detector/DeStatic.h b/DDDB/include/Detector/DeStatic.h new file mode 100644 index 0000000000000000000000000000000000000000..27abbee12cfaaf9c495b4faefcccac197349cf6f --- /dev/null +++ b/DDDB/include/Detector/DeStatic.h @@ -0,0 +1,127 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DE_CTORS_DEFAULT +#pragma error("This header should never be included directly. Inlcude Detector/DetectorElement.h instead!") +#endif + +#ifndef DETECTOR_DESTATIC_H +#define DETECTOR_DESTATIC_H + +/// gaudi namespace declaration +namespace gaudi { + + /// gaudi::detail namespace declaration + namespace detail { + + /// Forward declarations + class DeStaticObject; + + /// Base class for static DetectorElement data + /** + * The static data support all requests to a generic detector element + * if no time-dependent information is required. The time dependent + * information is stored in the IOV dependent part of the detector element. + * + * Note: + * 1) When populating the child chache it is the USER's responsibility + * To use ConditionsMaps with appropriate IOVs! + * 2) The child chache may ONLY be populated while the condition is not + * active ie. during creation/initialization time. Otherwise + * MT races occur! + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeStaticObject : public detail::ConditionObject { + DE_CONDITIONS_TYPEDEFS; + + public: + /// Helper to initialize the basic information + DeStaticObject* fill_info(DetElement de, Catalog* cat); + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeStaticObject); + + /// Initialization of sub-classes. May only be called while the condition is NOT active + virtual void initialize(); + + /// Printout method to stdout + virtual void print(int indent, int flags) const; + + /// Fill the child cache. May only be called while the condition is NOT active + void fillCache(ConditionsMap& m); + + /// Type dependent accessor to a named parameter + template <typename T> T param(const std::string& nam, bool throw_if_not_present=true) const + { return parameters.param(nam,throw_if_not_present).get<T>(); } + + /// Access daughter elements: Static part + DeStaticObject* child(DetElement de) const; + + public: + /// Cache of static information of the children. + std::map<DetElement,DeStaticObject*> childCache; + /// Pointer to parent + DeStaticObject* parent = 0; + /// The dd4hep detector element reference of this gaudi detector element + DetElement detector; + /// Reference to the geometry information of this gaudi detector element + PlacedVolume geometry; + /// The parameter map of this detector element + ParameterMap parameters; + /// Detector element Class ID + int classID = 0; + /// Initialization flags to steer actions + int de_flags = 0; + /// Item key + itemkey_type key = 0; + + /// Not really necessary and no code should depend on it, but helps for debugging! + Catalog* catalog = 0; + }; + } // End namespace detail + + /// Base class for static DetectorElement data + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeStatic : public dd4hep::Handle<detail::DeStaticObject> { + DE_CONDITIONS_TYPEDEFS; + + public: + /// Standard handle assignments and constructors + DE_CTORS_HANDLE(DeStatic,Base); + + /// Printout method to stdout + void print(int indent, int flags) const; + + /** Simplification accessors. Do not check validity here */ + /// Access parameters directory + const ParameterMap::Parameters& params() const; + + /// Access single parameter + const ParameterMap::Parameter& param(const std::string& nam, bool throw_if_not_present=true) const; + + /// Type dependent accessor to a named parameter + template <typename T> T param(const std::string& nam, bool throw_if_not_present=true) const + { return param(nam,throw_if_not_present).get<T>(); } + }; +} // End namespace gaudi +#endif // DETECTOR_DESTATIC_H diff --git a/DDDB/include/Detector/DeVP.h b/DDDB/include/Detector/DeVP.h new file mode 100644 index 0000000000000000000000000000000000000000..bda06044b0e474b91883e1f6386fffade709c151 --- /dev/null +++ b/DDDB/include/Detector/DeVP.h @@ -0,0 +1,146 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DEVP_H +#define DETECTOR_DEVP_H 1 + +// Framework include files +#include "Detector/DeVPSensor.h" +#include "Detector/DeVPGeneric.h" + +/// Gaudi namespace declaration +namespace gaudi { + + /// Gaudi::detail namespace declaration + namespace detail { + + /// VP detector element data + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPStaticObject : public DeVPGenericStaticObject { + DE_CONDITIONS_TYPEDEFS; + typedef std::vector<DeVPGenericStatic> Sides; + typedef std::vector<DeVPGenericStatic> ModuleSupports; + typedef std::vector<DeVPGenericStatic> Modules; + typedef std::vector<DeVPGenericStatic> Ladders; + + public: + Sides sides; + ModuleSupports supports; + Modules modules; + Ladders ladders; + + double sensitiveVolumeCut = 0e0; + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeVPStaticObject); + /// Initialization of sub-classes + virtual void initialize(); + /// Printout method to stdout + virtual void print(int indent, int flags) const override; + }; + } // End namespace detail + + + /// Handle defintiion to an instance of VP detector element data + /** + * This object defines the behaviour of the objects's data + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPStatic : public dd4hep::Handle<detail::DeVPStaticObject> { + DE_CONDITIONS_TYPEDEFS; + + public: + /// Standard constructors and assignment + DE_CTORS_HANDLE(DeVPStatic,Base); + /// Printout method to stdout + void print(int indent, int flags) const; + /// Return the number of sensors. + unsigned int numberSensors() const + { return ptr()->sensors.size(); } + /// Return vector of sensors. + const std::vector<DeVPSensorStatic>& sensors() const + { return ptr()->sensors; } + }; + + /// Gaudi::detail namespace declaration + namespace detail { + + /// VP detector element data + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPObject : public DeVPGenericObject { + DE_CONDITIONS_TYPEDEFS; + typedef std::vector<DeVPGeneric> Sides; + typedef std::vector<DeVPGeneric> ModuleSupports; + typedef std::vector<DeVPGeneric> Modules; + typedef std::vector<DeVPGeneric> Ladders; + + public: + DeVPStatic vp_static; + Sides sides; + ModuleSupports supports; + Modules modules; + Ladders ladders; + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeVPObject); + /// Initialization of sub-classes + virtual void initialize(); + /// Printout method to stdout + void print(int indent, int flags) const; + }; + } // End namespace detail + + /// Handle defintiion to an instance of VP detector element data + /** + * This object defines the behaviour of the objects's data + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVP : public dd4hep::Handle<detail::DeVPObject> { + DE_CONDITIONS_TYPEDEFS; + typedef detail::DeVPStaticObject static_t; + + public: + /// Standard constructors and assignment + DE_CTORS_HANDLE(DeVP,Base); + /// Printout method to stdout + void print(int indent, int flags) const; + /// Access to the static data + static_t& staticData() const + { return access()->vp_static; } + /// Return the number of sensors. + unsigned int numberSensors() const + { return ptr()->sensors.size(); } + /// Return vector of sensors. + const std::vector<DeVPSensor>& sensors() const + { return ptr()->sensors; } + }; +} // End namespace gaudi +#endif // DETECTOR_DEVP_H diff --git a/DDDB/include/Detector/DeVPConditionCalls.h b/DDDB/include/Detector/DeVPConditionCalls.h new file mode 100644 index 0000000000000000000000000000000000000000..a712191f9bf457a4b00c21d671aa71c5105590c6 --- /dev/null +++ b/DDDB/include/Detector/DeVPConditionCalls.h @@ -0,0 +1,121 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DEVPCONDITIONCALLS_H +#define DETECTOR_DEVPCONDITIONCALLS_H 1 + +// Framework include files +#include "Detector/DeVP.h" +#include "DD4hep/ConditionDerived.h" + +/// Gaudi namespace declaration +namespace gaudi { + + /// Context information used when computing the Velo-pixel derived conditions + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class VeloUpdateContext : public dd4hep::cond::ConditionUpdateUserContext { + public: + std::map<dd4hep::Condition::detkey_type,std::pair<dd4hep::DetElement,dd4hep::DDDB::DDDBCatalog*> > detectors; + dd4hep::Condition alignments_done; + }; + + /// Base class to share common type definitions + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeConditionCallDefs { + public: + typedef dd4hep::DetElement DetElement; + typedef dd4hep::Condition Condition; + typedef dd4hep::ConditionKey ConditionKey; + typedef dd4hep::ConditionKey::KeyMaker KeyMaker; + typedef dd4hep::cond::ConditionResolver Resolver; + typedef dd4hep::cond::ConditionUpdateContext Context; + typedef dd4hep::DDDB::DDDBCatalog Catalog; + }; + + /// Condition derivation call to build the static Velo-pixel DetElement condition information + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPStaticConditionCall : public dd4hep::cond::ConditionUpdateCall, public DeConditionCallDefs { + public: + /// Initializing constructor + DeVPStaticConditionCall() = default; + /// 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; + /// Interface to client callback for resolving references or to use data from other conditions + virtual void resolve(Condition c, Resolver& resolver) override final; + }; + + /// Condition derivation call to build the dynamic Velo-pixel DetElement condition information + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPIOVConditionCall : public dd4hep::cond::ConditionUpdateCall, public DeConditionCallDefs { + public: + DetElement detector; + Catalog* catalog = 0; + VeloUpdateContext* context = 0; + /// Initializing constructor + DeVPIOVConditionCall(DetElement de, Catalog* cat, VeloUpdateContext* ctx) + : detector(de), catalog(cat), 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; + /// Interface to client callback for resolving references or to use data from other conditions + virtual void resolve(Condition c, Resolver& resolver) override; + }; + + /// Condition derivation call to build the dynamic Velo-pixel DetElement condition information + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPConditionCall : public DeVPIOVConditionCall { + public: + /// Initializing constructor + DeVPConditionCall(DetElement de, Catalog* cat, VeloUpdateContext* ctx) + : DeVPIOVConditionCall(de,cat,ctx) {} + /// 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; + }; + +} // End namespace gaudi +#endif // DETECTOR_DEVPCONDITIONCALLS_H diff --git a/DDDB/include/Detector/DeVPGeneric.h b/DDDB/include/Detector/DeVPGeneric.h new file mode 100644 index 0000000000000000000000000000000000000000..6adf91ab32a128353f2c336253200bc8b55ac70d --- /dev/null +++ b/DDDB/include/Detector/DeVPGeneric.h @@ -0,0 +1,140 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DEVPGENERIC_H +#define DETECTOR_DEVPGENERIC_H 1 + +// Framework include files +#include "Detector/DeVPSensor.h" +#include "Detector/DeStatic.h" +#include "Detector/DeIOV.h" + +/// Gaudi namespace declaration +namespace gaudi { + + /// Gaudi::detail namespace declaration + namespace detail { + + /// VP detector element data + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPGenericStaticObject : public DeStaticObject { + DE_CONDITIONS_TYPEDEFS; + + public: + typedef std::vector<DeVPSensorStatic> Sensors; + int vp_flags = 0; + Sensors sensors; + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeVPGenericStaticObject); + /// Initialization of sub-classes + virtual void initialize(); + /// Printout method to stdout + void print(int indent, int flg) const; + }; + } // End namespace detail + + /// Handle defintiion to an instance of VP detector element data + /** + * This object defines the behaviour of the objects's data + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPGenericStatic : public dd4hep::Handle<detail::DeVPGenericStaticObject> { + DE_CONDITIONS_TYPEDEFS; + + enum { MAIN = 1<<0, + SIDE = 1<<1, + SUPPORT = 1<<2, + MODULE = 1<<3, + LADDER = 1<<4, + SENSOR = 1<<5 + }; + public: + /// Standard constructors and assignment + DE_CTORS_HANDLE(DeVPGenericStatic,Base); + /// Printout method to stdout + void print(int indent, int flags) const; + }; + + /// Gaudi::detail namespace declaration + namespace detail { + + /// VP detector element data + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPGenericObject : public DeIOVObject { + DE_CONDITIONS_TYPEDEFS; + + public: + typedef std::vector<DeVPSensor> Sensors; + int vp_flags = 0; + Sensors sensors; + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeVPGenericObject); + /// Initialization of sub-classes + virtual void initialize(); + /// Printout method to stdout + void print(int indent, int flg) const; + }; + } // End namespace detail + + /// Handle defintiion to an instance of VP detector element data + /** + * This object defines the behaviour of the objects's data + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPGeneric : public dd4hep::Handle<detail::DeVPGenericObject> { + DE_CONDITIONS_TYPEDEFS; + + /// Forward definition of the static type for facades + typedef detail::DeStaticObject static_t; + + typedef std::vector<DeVPSensor> Sensors; + enum { MAIN = 1<<0, + SIDE = 1<<1, + SUPPORT = 1<<2, + MODULE = 1<<3, + LADDER = 1<<4, + SENSOR = 1<<5 + }; + + public: + /// Standard constructors and assignment + DE_CTORS_HANDLE(DeVPGeneric,Base); + /// Printout method to stdout + void print(int indent, int flags) const; + /// Access to the static data + static_t& staticData() const { return access()->de_static; } + }; + +} // End namespace gaudi +#endif // DETECTOR_DEVPGENERIC_H diff --git a/DDDB/include/Detector/DeVPSensor.h b/DDDB/include/Detector/DeVPSensor.h new file mode 100644 index 0000000000000000000000000000000000000000..5eb792ffa15eacdf72bbd27ea0d2fc5ff0a9ed01 --- /dev/null +++ b/DDDB/include/Detector/DeVPSensor.h @@ -0,0 +1,157 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DEVPSENSOR_H +#define DETECTOR_DEVPSENSOR_H 1 + +// Framework include files +#include "Detector/DetectorElement.h" +#include "Detector/DeStatic.h" +#include "Detector/DeIOV.h" +#include "Kernel/VPConstants.h" + +/// Gaudi namespace declaration +namespace gaudi { + + + /// Gaudi::detail namespace declaration + namespace detail { + + /// Generic VP static detector element + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPSensorStaticObject : public detail::DeStaticObject { + public: + /// Cache of local x-cooordinates + std::array<double,VP::NSensorColumns> local_x; + /// Cache of x-pitch + std::array<double,VP::NSensorColumns> x_pitch; + + /// Dimensions of the sensor active area + double sizeX = 0e0; + double sizeY = 0e0; + double thickness = 0e0; + /// Length of chip active area + double chipSize = 0e0; + /// Distance between two chips + double interChipDist = 0e0; + /// Cell size of pixels + double pixelSize = 0e0; + /// Cell size in column direction of elongated pixels + double interChipPixelSize = 0e0; + /// Global Z position + double zpos = 0e0; + + /// Number of chips per ladder + unsigned int nChips = 0; + /// Number of columns and rows + unsigned int nCols = 0; + unsigned int nRows = 0; + /// Sensor ans module number + unsigned int sensorNumber = 0; + unsigned int module = 0; + bool isLeft = false; + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeVPSensorStaticObject); + + /// Initialization of sub-classes + virtual void initialize() override; + /// Printout method to stdout + virtual void print(int indent, int flags) const override; + }; + } // End namespace detail + + /// Handle defintiion to an instance of VP static detector element data + /** + * This object defines the behaviour of the objects's data + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPSensorStatic : public dd4hep::Handle<detail::DeVPSensorStaticObject> { + DE_CONDITIONS_TYPEDEFS; + public: + /// Standard constructors and assignment + DE_CTORS_HANDLE(DeVPSensorStatic,Base); + /// Printout method to stdout + void print(int indent, int flags) const; + }; + + /// Gaudi::detail namespace declaration + namespace detail { + + /// Generic VP iov dependent detector element + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPSensorObject : public DeIOVObject { + DE_CONDITIONS_TYPEDEFS; + + /// The static part of the detector element + DeVPSensorStatic sensor_static; + + /** For ref only: values are taken from the RUN-II conditions information */ + /// Reference to time-dependent sensor information + Condition info; + /// Reference to time-dependent noise + Condition noise; + /// Reference to time-dependent readout configuration parameters + Condition readout; + + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeVPSensorObject); + + /// Initialization of sub-classes + virtual void initialize() override; + /// Printout method to stdout + virtual void print(int indent, int flags) const override; + }; + } // End namespace detail + + + /// Handle defintiion to an instance of VP IOV dependent data + /** + * This object defines the behaviour of the objects's data + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class DeVPSensor : public dd4hep::Handle<detail::DeVPSensorObject> { + DE_CONDITIONS_TYPEDEFS; + typedef detail::DeVPSensorStaticObject static_t; + + public: + /** Define conditions access keys for optimization */ + static const itemkey_type key_info; + static const itemkey_type key_noise; + static const itemkey_type key_readout; + /// Standard constructors and assignment + DE_CTORS_HANDLE(DeVPSensor,Base); + /// Printout method to stdout + void print(int indent, int flags) const; + }; +} // End namespace gaudi +#endif // DETECTOR_DEVPSENSORIOV_H diff --git a/DDDB/include/Detector/DetectorElement.h b/DDDB/include/Detector/DetectorElement.h new file mode 100644 index 0000000000000000000000000000000000000000..e27e729e4b00e76ae49c2157f9b7d722f1dfc6ef --- /dev/null +++ b/DDDB/include/Detector/DetectorElement.h @@ -0,0 +1,290 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DETECTORELEMENT_H +#define DETECTOR_DETECTORELEMENT_H 1 + +// Framework include files +#include "DD4hep/Objects.h" +#include "DD4hep/Printout.h" +#include "DD4hep/DetElement.h" +#include "DD4hep/detail/ConditionsInterna.h" +#include "Math/Vector3D.h" +#include "Math/Point3D.h" +#include "Detector/ParameterMap.h" + +// C/C++ include files + + +namespace dd4hep { namespace DDDB { class DDDBCatalog; }} + + +/// Gaudi namespace declaration +namespace gaudi { + + typedef ROOT::Math::XYZPoint XYZPoint; + typedef ROOT::Math::XYZVector XYZVector; + typedef ROOT::Math::Translation3D Translation3D; + +#define DE_CONDITIONS_TYPEDEFS \ + public: \ + typedef dd4hep::DDDB::DDDBCatalog Catalog; \ + typedef ParameterMap::Parameter Parameter; \ + typedef dd4hep::DetElement DetElement; \ + typedef dd4hep::Condition Condition; \ + typedef dd4hep::ConditionsMap ConditionsMap; \ + typedef dd4hep::PlacedVolume PlacedVolume; \ + typedef dd4hep::Alignment Alignment; \ + typedef Condition::itemkey_type itemkey_type; \ + typedef std::map<itemkey_type,Condition> Conditions; \ + typedef std::map<PlacedVolume,Alignment> VolumeAlignments + + using dd4hep::yes_no; + using dd4hep::except; + using dd4hep::printout; + using dd4hep::DEBUG; + using dd4hep::INFO; + using dd4hep::ERROR; + +#define DE_CTORS_DEFAULT(X) \ + X() = default; \ + X(const X& c) = default; \ + virtual ~X() = default; \ + X& operator=(const X& c) = default + +#define DE_CTORS_HANDLE(X,B) \ + X() = default; \ + X(const X& c) = default; \ + explicit X(Object* p) : B(p) {} \ + template <typename Q> X(const dd4hep::Handle<Q>& e) : B(e) {} \ + X& operator=(const X& c) = default; \ + X& operator=(Object* p) { return (*this = X(p)); } \ + ~X() = default + + namespace DE { + std::string indent(int level); + } + namespace DePrint { + enum PrintFlags { BASICS = 1, + PARAMS = 2, + DETAIL = 4, + SPECIFIC = 5, + STATIC = 6, + ALIGNMENTS = 7, + ALL = BASICS|PARAMS|DETAIL|SPECIFIC|STATIC + }; + } + namespace DeInit { + enum InitFlags { FILLCACHE = 1, + INITIALIZED = 1<<31 + }; + } + struct DeHelpers { + DE_CONDITIONS_TYPEDEFS; + enum { ALL = 1<<31 }; + template<typename T> static std::map<DetElement, T*> + getChildConditions(ConditionsMap& m, DetElement de, itemkey_type key, int flags); + }; + + /// Gaudi::detail namespace declaration + namespace detail { + + /// We want to have the base in the local namespace + typedef dd4hep::detail::ConditionObject ConditionObject; + + /// Generic Detector element data object combining static and iov data + /** + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + template <typename STATIC, typename IOV> + class DeObject : public ConditionObject { + DE_CONDITIONS_TYPEDEFS; + typedef STATIC static_t; + typedef IOV iov_t; + static_t de_static; + iov_t de_iov; + public: + /// Standard constructors and assignment + DE_CTORS_DEFAULT(DeObject); + }; + } + + /// Static identifiers computed once. Use the hash code whenever possible! + struct Keys { + typedef dd4hep::Condition::key_type key_type; + typedef dd4hep::Condition::itemkey_type itemkey_type; + + /// Static key name: "DetElement-Info-Static" + static const std::string staticKeyName; + /// Static key: 32 bit hash of "DetElement-Info-Static". Must be unique for one DetElement + static const itemkey_type staticKey; + + /// Static key name: "DetElement-Info-IOV" + static const std::string deKeyName; + /// Static key: 32 bit hash of "DetElement-Info-IOV". Must be unique for one DetElement + static const itemkey_type deKey; + + /// Static key name: "Alignments-Computed" + static const std::string alignmentsComputedKeyName; + /// Static key: 32 bit hash of "Alignments-Computed". Must be unique for the world + static const key_type alignmentsComputedKey; + }; +} // End namespace gaudi + +#include "Detector/DeStatic.h" +#include "Detector/DeIOV.h" + +/// Gaudi::detail namespace declaration +namespace gaudi { + + /// Main detector element class + /** + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + * + */ + template<typename TYPE> + class DetectorElement : public TYPE { + DE_CONDITIONS_TYPEDEFS; + typedef DetectorElement<TYPE> self_t; + typedef TYPE base_t; + typedef typename TYPE::Object iov_t; + typedef typename TYPE::static_t static_t; + typedef typename DetElement::Children children_t; + + private: + /// Static detelement accessor. Used internally - may be specialized for optimization + const static_t& static_data() const; + /// Access the time dependent data block. Used internally - may be specialized for optimization + const iov_t& iovData() const; + + base_t& base() { return *this; } + public: + /// Standard constructor + DetectorElement() = default; + /// Copy constructoe + DetectorElement(const DetectorElement&) = default; + /// Copy assignment + DetectorElement& operator=(const DetectorElement&) = default; + /// Constructor from base class pointer + DetectorElement(const typename base_t::Object* p) : base_t(p) {} + /// Constructor from other polymorph pointers + template <typename Q> DetectorElement(Q* p) : base_t(dd4hep::Handle<Q>(p)) {} + /// Constructor from other polymorph handle + template <typename Q> DetectorElement(const dd4hep::Handle<Q>& p) : base_t() { + base() = p; + if ( p.ptr() && !this->ptr() ) { this->bad_assignment(typeid(p),typeid(self_t)); } + } + /// Copy assignment from polymorph handle + template <typename Q> DetectorElement& operator=(const dd4hep::Handle<Q>& p) { + base() = p; + if ( p.ptr() && !this->ptr() ) { this->bad_assignment(typeid(p),typeid(self_t)); } + return *this; + } + + /** Access to static detector element data */ + /// Detector element Class ID + int classID() const + { return static_data().classID; } + /// Accessor to detector structure + DetElement detector() const + { return static_data().detector; } + /// Accessor to the geometry structure of this detector element + PlacedVolume geometry() const + { return static_data().geometry; } + /// Accessor to the parameter map + const ParameterMap& params() const + { return static_data().parameters; } + /// Access single parameter + const Parameter& param(const std::string& nam, bool throw_if_not_present=true) const + { return static_data().parameters.param(nam, throw_if_not_present); } + /// Type dependent accessor to a named parameter + template <typename T> T param(const std::string& nam, bool throw_if_not_present=true) const + { return static_data().parameters.param<T>(nam, throw_if_not_present); } + /// Access the parent detector element + DetElement parent() const + { return static_data().detector.parent(); } + /// Access the children detector elements + children_t children() const + { return static_data().detector.children(); } + + /** Access to IOV dependent data */ + /// Check if the condition called 'name' is in the list of conditionrefs. + bool hasCondition(const std::string& nam) const + { return iovData().condition(nam).isValid(); } + /// Access all conditions which belong to this detector element + const Conditions& conditions() const + { return iovData().conditions; } + /// Return the SmartRef for the condition called 'name'. Throw exception on failure + Condition condition(const std::string& nam) const + { return iovData().condition(nam, true); } + /// Return the SmartRef for the condition called 'name'. Throw exception if requested. + Condition condition(const std::string& nam, bool throw_if) const + { return iovData().condition(nam, throw_if); } + /// Access to the alignmant object to transformideal coordinates + Alignment detectorAlignment() const + { return iovData().detectorAlignment; } + /// Access the volume alignments + const VolumeAlignments& volumeAlignments() const + { return iovData().volumeAlignments(); } + + /// helper member using IGeometryInfo::isInside + bool isInside(const XYZPoint& globalPoint) const + { return iovData().isInside(static_data(), globalPoint); } + + /** Access to more sophisticated geometry information */ + /// Check if the geometry is connected to a logical volume + bool hasLVolume() const + { return geometry().volume().isValid(); } + /// Check if the geometry is connected to a supporting parent detector element + bool hasSupport() const + { return detector().parent().isValid(); } + + /// Access to transformation matrices + const TGeoHMatrix& toLocalMatrix() const + { return iovData().toLocalMatrix(); } + const TGeoHMatrix& toGlobalMatrix() const + { return iovData().toGlobalMatrix(); } + const TGeoHMatrix& toLocalMatrixNominal() const + { return iovData().toLocalMatrixNominal(); } + + /// Local -> Global and Global -> Local transformations + XYZPoint toLocal( const XYZPoint& global ) const + { return iovData().toLocal(global); } + XYZPoint toGlobal( const XYZPoint& local ) const + { return iovData().toGlobal(local); } + XYZVector toLocal( const XYZVector& globalDirection ) const + { return iovData().toLocal(globalDirection); } + XYZVector toGlobal( const XYZVector& localDirection ) const + { return iovData().toGlobal(localDirection); } + }; + + /// Static detelement accessor. Used internally - may be specialized for optimization + template <typename TYPE> inline + const typename DetectorElement<TYPE>::static_t& + DetectorElement<TYPE>::static_data() const + { return this->TYPE::staticData(); } + + /// Access the time dependent data block. Used internally - may be specialized for optimization + template <typename TYPE> inline + const typename DetectorElement<TYPE>::iov_t& + DetectorElement<TYPE>::iovData() const + { return *(this->TYPE::access()); } + +} // End namespace gaudi +#endif diff --git a/DDDB/include/Detector/DetectorElement_inl.h b/DDDB/include/Detector/DetectorElement_inl.h new file mode 100644 index 0000000000000000000000000000000000000000..da0d17af7dcc801f1ec6575fb3492f4b27ca08f9 --- /dev/null +++ b/DDDB/include/Detector/DetectorElement_inl.h @@ -0,0 +1,41 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_DETECTORELEMENT_INL_H +#define DETECTOR_DETECTORELEMENT_INL_H 1 + +// Framework include files +#include "Detector/DetectorElement.h" +#include "DD4hep/ConditionsMap.h" +#include "DD4hep/Printout.h" + +template<typename T> std::map<dd4hep::DetElement, T*> +gaudi::DeHelpers::getChildConditions(ConditionsMap& m, DetElement de, itemkey_type key, int flags) { + std::map<dd4hep::DetElement, T*> cache; + auto children = de.children(); + for(const auto& c : children) { + T* p = dynamic_cast<T*>(m.get(c.second, Keys::deKey).ptr()); + if ( p ) { + cache.insert(std::make_pair(c.second,p)); + continue; + } + if ( 0 != (flags&ALL) ) { + except("DeStatic","fillCache> No such condition:%d for detector element:%s", + key, de.path().c_str()); + } + } + return cache; +} + +#endif // #ifndef DETECTOR_DETECTORELEMENT_INL_H diff --git a/DDDB/include/Detector/ParameterMap.h b/DDDB/include/Detector/ParameterMap.h new file mode 100644 index 0000000000000000000000000000000000000000..aae11d91a00bf933207dbc827c15308a39777fb6 --- /dev/null +++ b/DDDB/include/Detector/ParameterMap.h @@ -0,0 +1,93 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== +#ifndef DETECTOR_PARAMETERMAP_H +#define DETECTOR_PARAMETERMAP_H 1 + +// Framework include files + +// C/C++ include files +#include <string> +#include <map> + +/// Gaudi namespace declaration +namespace gaudi { + + /// Generic detector element parameter map to specialize detector elements + /** + * Concurrentcy notice: + * Except during filling, which is performed by the framework code, + * instances of this class are assumed to the read-only! + * Thread safety hence is no issue. + * + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class ParameterMap final { + public: + /// Defintiion of a single parameter + /** + * \author Markus Frank + * \date 2018-03-08 + * \version 1.0 + */ + class Parameter final { + public: + std::string value; + std::string type; + public: + Parameter() = default; + Parameter(Parameter&& copy) = default; + Parameter(const Parameter& copy) = default; + Parameter(const std::string& v, const std::string& t) + : value(v), type(t) {} + Parameter& operator=(const Parameter& copy) = default; + bool operator==(const Parameter& copy) const + { return value == copy.value && type == copy.type; } + /// Type dependent accessor to a named parameter + template <typename T> T get() const; + }; + + typedef std::map<std::string,Parameter> Parameters; + + protected: + /// The parameter map + Parameters m_params; + + /// Access single parameter + const Parameter& _param(const std::string& nam) const; + public: + /// Defautl constructor + ParameterMap() = default; + /// Copy constructor + ParameterMap(const ParameterMap& copy) = default; + /// Default destructor + ~ParameterMap() = default; + /// Assignment opererator + ParameterMap& operator=(const ParameterMap& copy) = default; + /// Check the parameter existence + bool exists(const std::string& nam) const + { return m_params.find(nam) != m_params.end(); } + /// Add/update a parameter value + bool set(const std::string& nam, const std::string& val, const std::string& type); + /// Access parameters set + const Parameters& params() const { return m_params; } + /// Access single parameter + const Parameter& param(const std::string& nam, bool throw_if_not_present=true) const; + /// Type dependent accessor to a named parameter + template <typename T> T param(const std::string& nam, bool throw_if_not_present=true) const; + }; +} // End namespace gaudi +#endif // DETECTOR_PARAMETERMAP_H diff --git a/DDDB/include/Kernel/VPConstants.h b/DDDB/include/Kernel/VPConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..45e19202ffa1fbeb5237d41eb2a0d57cfb733eb5 --- /dev/null +++ b/DDDB/include/Kernel/VPConstants.h @@ -0,0 +1,18 @@ +#ifndef KERNEL_VPCONSTANTS_H +#define KERNEL_VPCONSTANTS_H 1 +namespace VP { + +static const unsigned int NModules = 52; +static const unsigned int NSensorsPerModule = 4; +static const unsigned int NSensors = NModules * NSensorsPerModule; +static const unsigned int NChipsPerSensor = 3; +static const unsigned int NRows = 256; +static const unsigned int NColumns = 256; +static const unsigned int NSensorColumns = NColumns * NChipsPerSensor; +static const unsigned int NPixelsPerSensor = NSensorColumns * NRows; + +static const double Pitch = 0.055; + +} + +#endif diff --git a/DDDB/src/Detector/DeAlignmentCall.cpp b/DDDB/src/Detector/DeAlignmentCall.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac441a42011231158f41a21c12d9d51a9951f0a6 --- /dev/null +++ b/DDDB/src/Detector/DeAlignmentCall.cpp @@ -0,0 +1,57 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DeAlignmentCall.h" +#include "Detector/DetectorElement.h" +#include "DD4hep/DetectorTools.h" +#include "DD4hep/DetectorProcessor.h" +#include "DD4hep/AlignmentsProcessor.h" +#include "DD4hep/AlignmentsCalculator.h" +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsManager.h" + +using namespace dd4hep; +using namespace dd4hep::cond; +using namespace dd4hep::align; + +/// Interface to client Callback in order to update the condition +Condition gaudi::DeAlignmentCall::operator()(const ConditionKey& /* key */, + const ConditionUpdateContext& ctxt) { + namespace tools = dd4hep::detail::tools; + Condition cond; + UserPool* conditions = dynamic_cast<UserPool*>(&ctxt.resolver->conditionsMap()); + if ( conditions ) { + 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; + 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) { + Condition c = (*i).second; + mgr.registerUnlocked(*iov_pool,c); + conditions->insert(c); + } + printout(INFO,"Align","Alignments:(C:%ld,M:%ld)", ares.computed, ares.missing); + return cond; + } + except("DeAlignmentCall","No conditions slice present!"); + return cond; +} diff --git a/DDDB/src/Detector/DeHandles.cpp b/DDDB/src/Detector/DeHandles.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cfed91afeb64cfa06cd46e3be10e9f380338585d --- /dev/null +++ b/DDDB/src/Detector/DeHandles.cpp @@ -0,0 +1,66 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// A bit of magic + +// Framework include files +#include "Detector/DeVP.h" +#include "DD4hep/detail/Handle.inl" + +// This is some magic you do not really want to know about.... + +using namespace gaudi::detail; + +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeStaticObject,ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeVPSensorStaticObject,DeStaticObject,ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeVPGenericStaticObject,DeStaticObject,ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeVPStaticObject,DeVPGenericStaticObject,DeStaticObject,ConditionObject); + +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeIOVObject,ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeVPSensorObject,DeIOVObject,ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeVPGenericObject,DeIOVObject,ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(DeVPObject,DeVPGenericObject,DeIOVObject,ConditionObject); + + +#include "Parsers/Parsers.h" +DD4HEP_DEFINE_OSTREAM_DUMMY(DeVPStaticObject) +DD4HEP_DEFINE_OSTREAM_DUMMY(DeVPSensorStaticObject) +DD4HEP_DEFINE_OSTREAM_DUMMY(DeVPGenericStaticObject) +DD4HEP_DEFINE_OSTREAM_DUMMY(DeVPObject) +DD4HEP_DEFINE_OSTREAM_DUMMY(DeVPSensorObject) +DD4HEP_DEFINE_OSTREAM_DUMMY(DeVPGenericObject) + +DD4HEP_DEFINE_PARSER_DUMMY(DeVPStaticObject) +DD4HEP_DEFINE_PARSER_DUMMY(DeVPSensorStaticObject) +DD4HEP_DEFINE_PARSER_DUMMY(DeVPGenericStaticObject) +DD4HEP_DEFINE_PARSER_DUMMY(DeVPObject) +DD4HEP_DEFINE_PARSER_DUMMY(DeVPSensorObject) +DD4HEP_DEFINE_PARSER_DUMMY(DeVPGenericObject) + +#include "DD4hep/detail/BasicGrammar_inl.h" +#include "DD4hep/detail/ConditionsInterna.h" +DD4HEP_DEFINE_PARSER_GRAMMAR(DeVPStaticObject,eval_none<DeVPStaticObject>) +DD4HEP_DEFINE_PARSER_GRAMMAR(DeVPSensorStaticObject,eval_none<DeVPSensorStaticObject>) +DD4HEP_DEFINE_PARSER_GRAMMAR(DeVPGenericStaticObject,eval_none<DeVPGenericStaticObject>) +DD4HEP_DEFINE_PARSER_GRAMMAR(DeVPObject,eval_none<DeVPObject>) +DD4HEP_DEFINE_PARSER_GRAMMAR(DeVPSensorObject,eval_none<DeVPSensorObject>) +DD4HEP_DEFINE_PARSER_GRAMMAR(DeVPGenericObject,eval_none<DeVPGenericObject>) + +DD4HEP_DEFINE_CONDITIONS_TYPE(DeVPStaticObject) +DD4HEP_DEFINE_CONDITIONS_TYPE(DeVPSensorStaticObject) +DD4HEP_DEFINE_CONDITIONS_TYPE(DeVPGenericStaticObject) +DD4HEP_DEFINE_CONDITIONS_TYPE(DeVPObject) +DD4HEP_DEFINE_CONDITIONS_TYPE(DeVPSensorObject) +DD4HEP_DEFINE_CONDITIONS_TYPE(DeVPGenericObject) diff --git a/DDDB/src/Detector/DeIOV.cpp b/DDDB/src/Detector/DeIOV.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39236bfbbc8cf9901f88de0b588c004cc92400c3 --- /dev/null +++ b/DDDB/src/Detector/DeIOV.cpp @@ -0,0 +1,189 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DetectorElement.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Alignments.h" +#include "DD4hep/ConditionsMap.h" +#include "DD4hep/AlignmentsPrinter.h" +#include "DD4hep/detail/AlignmentsInterna.h" + +#include "Detector/DetectorElement_inl.h" +namespace gaudi { + template std::map<dd4hep::DetElement, gaudi::detail::DeIOVObject*> + DeHelpers::getChildConditions<gaudi::detail::DeIOVObject>(ConditionsMap& m, DetElement de, itemkey_type key, int flags); +} + +#include <sstream> + +using namespace gaudi; +using namespace gaudi::detail; + +/// Helper to initialize the basic information +DeIOVObject* DeIOVObject::fill_info(DetElement de, Catalog* /* cat */) { + name = Keys::deKeyName; + key = Keys::deKey; + detector = de; + return this; +} + +/// Initialization of sub-classes +void DeIOVObject::initialize() { + if ( (de_flags&DeInit::INITIALIZED) == 0 ) { + auto i = conditions.find(dd4hep::align::Keys::alignmentKey); + de_flags |= DeInit::INITIALIZED; + detectorAlignment = (i==conditions.end()) ? Condition() : (*i).second; + if ( detectorAlignment.isValid() ) { + toLocalMatrix = detectorAlignment.worldTransformation().Inverse(); + detectorAlignment.delta().computeMatrix(deltaMatrix); + } + return; + } + except("DeIov","initialize> Modifying a condition after initialization is not allowed!"); +} + +/// Printout method to stdout +void DeIOVObject::print(int indent, int flg) const { + std::string prefix = DE::indent(indent); + printout(INFO, "DeIOVObject", + "%s+ Name:%s Hash:%016lX Type:%s Flags:%08X IOV:%s", + prefix.c_str(), name.c_str(), hash, + is_bound() ? data.dataType().c_str() : "<UNBOUND>", + flags, iov ? iov->str().c_str() : "--"); + if ( flg&DePrint::STATIC) { + de_static.print(indent, flg); + } + if ( flg&DePrint::DETAIL) { + printout(INFO, "DeIOVObject","%s+ >> Conditions:%ld Alignment:%s VolAlign:%ld", + prefix.c_str(), conditions.size(), + yes_no(detectorAlignment.isValid()), + volumeAlignments.size()); + for(const auto& cc : conditions) { + Condition c = cc.second; + printout(INFO, "DeIOVObject","%s+ >> Condition [%08X] %s Hash:%016X Flags:%08X Type:%s", + prefix.c_str(), cc.first, c.name(), c.key(), c.flags(), + c.is_bound() ? c.data().dataType().c_str() : "<UNBOUND>"); + if ( c->iov ) { + printout(INFO, "DeIOVObject","%s+ >> + IOV:%s", + prefix.c_str(), c->iov ? c.iov().str().c_str() : "--"); + } + } + if ( detectorAlignment.isValid() ) { + char txt1[64], txt2[64], txt3[64]; + std::stringstream str; + dd4hep::Alignment::Object* ptr = detectorAlignment.ptr(); + const dd4hep::AlignmentData& alignment_data = detectorAlignment.data(); + const dd4hep::Delta& D = alignment_data.delta; + + if ( D.hasTranslation() ) + ::snprintf(txt1,sizeof(txt1),"Tr: x:%g y:%g z:%g ",D.translation.x(), D.translation.Y(), D.translation.Z()); + else + ::snprintf(txt1,sizeof(txt1),"Tr: ------- "); + if ( D.hasRotation() ) + ::snprintf(txt2,sizeof(txt2),"Rot: phi:%g psi:%g theta:%g ",D.rotation.Phi(), D.rotation.Psi(), D.rotation.Theta()); + else + ::snprintf(txt2,sizeof(txt2),"Rot: ------- "); + if ( D.hasPivot() ) + ::snprintf(txt3,sizeof(txt3),"Rot: x:%g y:%g z:%g ",D.pivot.Vect().X(), D.pivot.Vect().Y(), D.pivot.Vect().Z()); + else + ::snprintf(txt3,sizeof(txt3),"Pivot: ------- "); + + printout(INFO,"DeIOVObject","%s+ >> Aligment [%p] Typ:%s \tData:(%11s-%8s-%5s)", + prefix.c_str(), detectorAlignment.ptr(), + dd4hep::typeName(typeid(*ptr)).c_str(), + D.hasTranslation() ? "Translation" : "", + D.hasRotation() ? "Rotation" : "", + D.hasPivot() ? "Pivot" : ""); + if ( D.hasTranslation() || D.hasRotation() || D.hasPivot() ) { + printout(INFO,"DeIOVObject","%s+ >> Aligment-Delta %s %s %s",prefix.c_str(), txt1,txt2,txt3); + } + } + } +} + +/// Check (enforce) the validity of the alignment object if required +void DeIOVObject::checkAlignment() const { + if ( !detectorAlignment.isValid() ) { + dd4hep::except("DeIOVObject", + "Invalid alignment object! Cannot compute derived quantities."); + } +} + +/// Fill the child cache. May only be called while the condition is NOT active +void DeIOVObject::fillCache(ConditionsMap& m) { + if ( (de_flags&DeInit::INITIALIZED) == 0 ) { + childCache = DeHelpers::getChildConditions<DeIOVObject>(m, detector, Keys::deKey, DeHelpers::ALL); + return; + } + except("DeIov","fillCache> Modifying %d (%s) after initialization is not allowed!", + Keys::deKeyName.c_str(), detector.path().c_str()); +} + +/// Access daughter elements: IOV dependent part +DeIOVObject* DeIOVObject::child(DetElement de) const { + auto i = childCache.find(de); + if ( i == childCache.end() ) { + except("DeIOV","No such condition:%s for detector element:%s", + Keys::deKeyName.c_str(), de.path().c_str()); + } + return (*i).second; +} + +/// Printout method to stdout +void DeIOV::print(int indent, int flags) const { + return access()->print(indent, flags); +} + +/// Access condition by name +DeIOV::Condition DeIOV::condition(const std::string& nam) const { + return this->condition(dd4hep::ConditionKey::itemCode(nam)); +} + +/// Access condition by name +DeIOV::Condition DeIOV::condition(const std::string& nam, bool throw_if) const { + return this->condition(dd4hep::ConditionKey::itemCode(nam), throw_if); +} + +/// Access condition by name +DeIOV::Condition DeIOV::condition(itemkey_type key) const { + const auto* o = access(); + auto i = o->conditions.find(key); + return (i == o->conditions.end()) ? (*i).second : Condition(); +} + +/// Access condition by name +DeIOV::Condition DeIOV::condition(itemkey_type key, bool throw_if) const { + const auto* o = access(); + auto i = o->conditions.find(key); + if (i != o->conditions.end()) { + return (*i).second; + } + if ( throw_if ) { + except("DeIOV","Attempt to access non-existing condition."); + } + return Condition(); +} + +/// Access all conditions which belong to this detector element +const DeIOV::Conditions& DeIOV::conditions() const { + return access()->conditions; +} + +/// Access the volume alignments +const DeIOV::VolumeAlignments& DeIOV::volumeAlignments() const { + return access()->volumeAlignments; +} + diff --git a/DDDB/src/Detector/DeStatic.cpp b/DDDB/src/Detector/DeStatic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a3fb6ec937cb4ce1b8f98440c235169dc2fc911 --- /dev/null +++ b/DDDB/src/Detector/DeStatic.cpp @@ -0,0 +1,110 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DetectorElement_inl.h" +#include "DD4hep/Printout.h" +#include "DDDB/DDDBConversion.h" + +namespace gaudi { + template std::map<dd4hep::DetElement, gaudi::detail::DeStaticObject*> + DeHelpers::getChildConditions<gaudi::detail::DeStaticObject>(ConditionsMap& m, DetElement de, itemkey_type key, int flags); +} + +using namespace gaudi; +using namespace gaudi::detail; + +/// Helper to initialize the basic information +DeStaticObject* DeStaticObject::fill_info(DetElement de, Catalog* cat) { + detector = de; + geometry = de.placement(); + name = Keys::staticKeyName; + key = Keys::staticKey; + classID = cat->classID; + catalog = cat; + for( const auto& p : cat->params ) + parameters.set(p.first, p.second.second, p.second.first); + return this; +} + +/// Initialization of sub-classes +void DeStaticObject::initialize() { + if ( (de_flags&DeInit::INITIALIZED) == 0 ) { + de_flags |= DeInit::INITIALIZED; + return; + } + except("DeStatic","initialize> Modifying a condition after initialization is not allowed!"); +} + + +/// Printout method to stdout +void DeStaticObject::print(int indent, int flg) const { + std::string prefix = DE::indent(indent); + printout(INFO, "DeStatic", "%s+ Detector:%s", + prefix.c_str(), detector.path().c_str()); + printout(INFO, "DeStatic", + "%s+ Name:%s Hash:%016lX Type:%s Flags:%08X IOV:%s", + prefix.c_str(), name.c_str(), hash, + is_bound() ? data.dataType().c_str() : "<UNBOUND>", + flags, iov ? iov->str().c_str() : "--"); + if ( flg & DePrint::BASICS ) { + const DetElement::Children& c = detector.children(); + printout(INFO, "DeStatic", "%s+ Detector:%s Class:%d key:%08X #Dau:%d", + prefix.c_str(), detector.name(), classID, key, int(c.size())); + } + if ( flg & DePrint::PARAMS ) { + for( const auto& p : parameters.params() ) { + printout(INFO, "DeStatic", "%s+ Param: %s -> %s [%s]", + prefix.c_str(), p.first.c_str(), + p.second.value.c_str(), p.second.type.c_str()); + } + } +} + +/// Access daughter elements: Static part +DeStaticObject* DeStaticObject::child(DetElement de) const { + auto i = childCache.find(de); + if ( i == childCache.end() ) { + except("DeStatic","child> No such condition:%s for detector element:%s", + Keys::staticKeyName.c_str(), de.path().c_str()); + } + return (*i).second; +} + +/// Fill the child cache. May only be called while the condition is NOT active +void DeStaticObject::fillCache(ConditionsMap& m) { + if ( (de_flags&DeInit::INITIALIZED) == 0 ) { + childCache = DeHelpers::getChildConditions<DeStaticObject>(m, detector,Keys::deKey, DeHelpers::ALL); + return; + } + except("DeIov","fillCache> Modifying % (%s) after initialization is not allowed!", + Keys::staticKeyName.c_str(), detector.path().c_str()); +} + +/// Printout method to stdout +void DeStatic::print(int indent, int flags) const { + return access()->print(indent, flags); +} + +/// Access parameters directory +const ParameterMap::Parameters& DeStatic::params() const { + return access()->parameters.params(); +} + +/// Access single parameter +const ParameterMap::Parameter& +DeStatic::param(const std::string& nam, bool throw_if_not_present) const { + return access()->parameters.param(nam, throw_if_not_present); +} diff --git a/DDDB/src/Detector/DeVP.cpp b/DDDB/src/Detector/DeVP.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9ac3a5beccdd1f17ec543ae711bf24050526591 --- /dev/null +++ b/DDDB/src/Detector/DeVP.cpp @@ -0,0 +1,79 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DeVP.h" +#include "DD4hep/Printout.h" + +using namespace gaudi::detail; + + +/// Printout method to stdout +void DeVPStaticObject::print(int indent, int flg) const { + std::string prefix = DE::indent(indent); + printout(INFO, "DeVPStatic", + "%s*+++++ VP detector element for %s Sides:%ld Supports:%ld Modules:%ld Ladders:%ld Sensors:%ld Cut:%g", + prefix.c_str(), detector.path().c_str(), + sides.size(), supports.size(), modules.size(), ladders.size(), sensors.size(), + sensitiveVolumeCut); + this->DeVPGenericStaticObject::print(indent,flg); + std::for_each(sensors.begin(), sensors.end(), [indent,flg](const DeVPSensorStatic& s) { s.print(indent+1,flg); }); +} + +/// Initialization of sub-classes +void DeVPStaticObject::initialize() { + this->DeVPGenericStaticObject::initialize(); + sensitiveVolumeCut = param<double>("sensitiveVolumeCut"); +} + +/// Printout method to stdout +void gaudi::DeVPStatic::print(int indent, int flg) const { + access()->print(indent, flg); +} + +/// Printout method to stdout +void DeVPObject::print(int indent, int flg) const { + std::string prefix = DE::indent(indent); + printout(INFO, "DeVP", + "%s*+++++ VP detector element for %s Sides:%ld Supports:%ld Modules:%ld Ladders:%ld Sensors:%ld", + prefix.c_str(), detector.path().c_str(), + sides.size(), supports.size(), modules.size(), ladders.size(), sensors.size()); + this->DeVPGenericObject::print(indent,flg); + std::for_each(sensors.begin(), sensors.end(), [indent,flg](const DeVPSensor& s) { + if ( s.isValid() ) s.print(indent+1,flg); }); +} + +/// Initialization of sub-classes +void DeVPObject::initialize() { + this->DeVPGenericObject::initialize(); + vp_static = de_static; +} + + +/// Printout method to stdout +void gaudi::DeVP::print(int indent, int flg) const { + access()->print(indent,flg); +} + +#if 0 +static void test() { + using namespace gaudi; + DeVP devp; + DetectorElement<DeVP> detElem(devp); + std::cout << "TEST: Got detector element:" << detElem.detector().path() + << detElem.detectorAlignment().name() + << std::endl; +} +#endif diff --git a/DDDB/src/Detector/DeVPConditionCalls.cpp b/DDDB/src/Detector/DeVPConditionCalls.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b05d112a604a25dd1c988840bb7ac907dfc438a2 --- /dev/null +++ b/DDDB/src/Detector/DeVPConditionCalls.cpp @@ -0,0 +1,180 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DeVPConditionCalls.h" +#include "DD4hep/DetectorProcessor.h" +#include "DDDB/DDDBConversion.h" + +using namespace gaudi; + +/// Interface to client Callback in order to update the condition +dd4hep::Condition DeVPStaticConditionCall::operator()(const ConditionKey& key, const Context& context) { + VeloUpdateContext* ctxt = dynamic_cast<VeloUpdateContext*>(context.parameter); + KeyMaker km(key.hash); + auto ide = ctxt->detectors.find(km.values.det_key); + auto* cat = (*ide).second.second; + DetElement det = (*ide).second.first; + DeStatic s; + if ( cat->classID == 1008205 ) // DeVPSensor + s = DeStatic(new detail::DeVPSensorStaticObject()); + else if ( cat->classID == 8200 ) // DeVP Velo main element + s = DeStatic(new detail::DeVPStaticObject()); + else // All other in the hierarchy + s = DeStatic(new detail::DeVPGenericStaticObject()); + return s->fill_info(det, cat); +} + +/// Interface to client callback for resolving references or to use data from other conditions +void DeVPStaticConditionCall::resolve(Condition c, Resolver& resolver) { + DeStatic s(c); + if ( s->classID == 8200 ) { // Velo main element + DeVPStatic vp = s; + DeVPSensorStatic sens; + DeVPGenericStatic side, support, module, ladder; + std::vector<std::pair<DetElement, int> > elts; + dd4hep::DetectorScanner(dd4hep::detElementsCollector(elts), s->detector); + + vp->vp_flags |= DeVPGenericStatic::MAIN; + vp->sensors.resize(200); + for ( const auto& i : elts ) { + DetElement de = i.first; + KeyMaker key(de.key(), Keys::staticKey); + DeStatic cond = resolver.get(key.hash); + const std::string& path = de.path(); + if ( path.find("/VPLeft") != std::string::npos || path.find("/VPRight") != std::string::npos ) { + switch( i.second ) { + case 0: // Self! + break; + case 1: + side = cond; + side->parent = vp.access(); + side->vp_flags |= DeVPGeneric::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->vp_flags |= DeVPGeneric::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->vp_flags |= DeVPGeneric::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->vp_flags |= DeVPGeneric::LADDER; + vp->ladders.push_back(ladder); + printout(INFO,"DeVPStatic","Add Ladder[%03ld]: %s",vp->ladders.size()-1,path.c_str()); + break; + case 5: + sens = cond; + sens->parent = ladder.access(); + if ( sens->sensorNumber >= vp->sensors.size() ) + vp->sensors.resize(sens->sensorNumber+1); + vp->sensors[sens->sensorNumber] = sens; + ladder->sensors.push_back(sens); + module->sensors.push_back(sens); + support->sensors.push_back(sens); + side->sensors.push_back(sens); + printout(INFO,"DeVPStatic","Add Sensor[%03ld]: %s",long(sens->sensorNumber),path.c_str()); + break; + default: + break; + } + } + else { + printout(INFO,"DeVPStatic","Aux.DetElmenet: %s",path.c_str()); + } + } + } + s->initialize(); +} + +/// Interface to client Callback in order to update the condition +dd4hep::Condition DeVPIOVConditionCall::operator()(const ConditionKey&, const Context&) { + DeIOV iov((catalog->classID == 1008205) ? new detail::DeVPSensorObject() : new detail::DeIOVObject()); + if ( catalog->classID == 1008205 ) // DeVPSensor + iov = DeIOV(new detail::DeVPSensorObject()); + else if ( catalog->classID == 8200 ) // DeVP Velo main element + iov = DeIOV(new detail::DeVPObject()); + else // All other in the hierarchy + iov = DeIOV(new detail::DeVPGenericObject()); + return iov->fill_info(detector, catalog); +} + +/// Interface to client callback for resolving references or to use data from other conditions +void DeVPIOVConditionCall::resolve(Condition cond, Resolver& resolver) { + 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); + } + + std::vector<Condition> conds = resolver.get(det_key); + iov->de_static = resolver.get(kstatic.hash); + iov->detectorAlignment = resolver.get(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 +{ + for ( const auto& i : src ) { + KeyMaker key(i->detector.key(), Keys::deKey); + DeVPGeneric gen = resolver.get(key.hash); + cont.push_back(gen); + for ( const auto& j : i->sensors ) + gen->sensors.push_back(vp->sensors[j->sensorNumber]); + printout(INFO,"DeVP","Add [%03ld]: %s",cont.size()-1,gen->detector.path().c_str()); + } +} + +/// Interface to client callback for resolving references or to use data from other conditions +void DeVPConditionCall::resolve(Condition cond, Resolver& resolver) { + DeIOV iov(cond); + DeVP vp(cond); + DeVPIOVConditionCall::resolve(cond, resolver); + 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); + 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); +} diff --git a/DDDB/src/Detector/DeVPGeneric.cpp b/DDDB/src/Detector/DeVPGeneric.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a856f7359af1ff24cb72042697eb2f528f344070 --- /dev/null +++ b/DDDB/src/Detector/DeVPGeneric.cpp @@ -0,0 +1,49 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DeVP.h" +#include "DD4hep/Printout.h" + +using namespace gaudi::detail; + +/// Initialization of sub-classes +void DeVPGenericStaticObject::initialize() { + this->DeStaticObject::initialize(); +} + +/// Printout method to stdout +void DeVPGenericStaticObject::print(int indent, int flg) const { + if ( flg & DePrint::SPECIFIC ) { + printout(INFO,"DeVPGenStatic", "%s*========== %ld Sensors %s", + DE::indent(indent).c_str(), sensors.size(), detector.path().c_str()); + } + DeStaticObject::print(indent, flg); +} + + +/// Initialization of sub-classes +void DeVPGenericObject::initialize() { + this->DeIOVObject::initialize(); +} + +/// Printout method to stdout +void DeVPGenericObject::print(int indent, int flg) const { + if ( flg & DePrint::SPECIFIC ) { + printout(INFO,"DeVPGen", "%s*========== %ld Sensors %s", + DE::indent(indent).c_str(), sensors.size(), detector.path().c_str()); + } + DeIOVObject::print(indent, flg); +} diff --git a/DDDB/src/Detector/DeVPSensor.cpp b/DDDB/src/Detector/DeVPSensor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c819c02fdc010e3a3dae3b60ce3b223e28a9b81 --- /dev/null +++ b/DDDB/src/Detector/DeVPSensor.cpp @@ -0,0 +1,144 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DeVPSensor.h" +#include "DD4hep/Primitives.h" +#include "DD4hep/Printout.h" + +namespace gaudi { + const DeVPSensor::itemkey_type DeVPSensor::key_info = dd4hep::ConditionKey::itemCode("StripInfo"); + const DeVPSensor::itemkey_type DeVPSensor::key_noise = dd4hep::ConditionKey::itemCode("StripNoise"); + const DeVPSensor::itemkey_type DeVPSensor::key_readout = dd4hep::ConditionKey::itemCode("StripReadout"); +} + +/// Printout method to stdout +void gaudi::detail::DeVPSensorStaticObject::print(int indent, int flg) const { + + if ( flg & DePrint::SPECIFIC ) { + printout(INFO,"DeVPSensorStatic", "%s*==========%s", + DE::indent(indent).c_str(), detector.path().c_str()); + printout(INFO,"DeVPSensorStatic", + "%s%s >> Module:%d Sensor:%d %s %d Chips Rows:%d Cols:%d", + DE::indent(indent).c_str(),"+ ", + module, sensorNumber, isLeft ? "Left" : "Right", nChips, nCols, nRows); + } + if ( flg & DePrint::DETAIL ) { + printout(INFO,"DeVPSensorStatic", + "%s%s >> Thickness:%g ChipSize:%g Dist:%g Pix-Size:%g Dist:%g", + DE::indent(indent).c_str(),"+ ", + thickness, chipSize, interChipDist, pixelSize, interChipPixelSize); + printout(INFO,"DeVPSensorStatic", + "%s%s >> SizeX: %g SizeY: %g local:%ld pitch:%ld", + DE::indent(indent).c_str(), "+ ", sizeX, sizeY, local_x.size(), x_pitch.size()); + } + this->DeStaticObject::print(indent, flg); +} + +/// Initialization of sub-classes +void gaudi::detail::DeVPSensorStaticObject::initialize() { + std::string side = param<std::string>("Side"); + + sensorNumber = param<int>("SensorNumber"); + module = param<int>("Module"); + isLeft = side.find("Left") == 0; + + thickness = param<double>("Thickness"); + nChips = param<int>("NChips"); + chipSize = param<double>("ChipSize"); + interChipDist = param<double>("InterChipDist"); + nCols = param<int>("NColumns"); + nRows = param<int>("NRows"); + pixelSize = param<double>("PixelSize"); + interChipPixelSize = param<double>("InterChipPixelSize"); + + sizeX = nChips * chipSize + (nChips - 1) * interChipDist; + sizeY = chipSize; + for (unsigned int col = 0; col < VP::NSensorColumns; ++col) { + // Calculate the x-coordinate of the pixel centre and the pitch. + const double x0 = + (col / VP::NColumns) * (chipSize + interChipDist); + double x = x0 + (col % VP::NColumns + 0.5) * pixelSize; + double pitch = pixelSize; + switch (col) { + case 256: + case 512: + // right of chip border + x -= 0.5 * (interChipPixelSize - pixelSize); + pitch = + 0.5 * (interChipPixelSize + pixelSize); + break; + case 255: + case 511: + // left of chip border + x += 0.5 * (interChipPixelSize - pixelSize); + pitch = interChipPixelSize; + break; + case 254: + case 510: + // two left of chip border + pitch = + 0.5 * (interChipPixelSize + pixelSize); + break; + } + local_x[col] = x; + x_pitch[col] = pitch; + } +} + +/// Printout method to stdout +void gaudi::DeVPSensorStatic::print(int indent, int flg) const { + access()->print(indent,flg); +} + + +/// Printout method to stdout +void gaudi::detail::DeVPSensorObject::print(int indent, int flg) const { + printout(INFO,"DeVPSensor", "%s+ Info: %s Noise:%s Readout:%s", + DE::indent(indent).c_str(), + yes_no(info.isValid()), + yes_no(noise.isValid()), + yes_no(readout.isValid())); + DeIOVObject::print(indent, flg); +} + +/// Initialization of sub-classes +void gaudi::detail::DeVPSensorObject::initialize() { + DeIOVObject::initialize(); + + sensor_static = de_static; + // We require a valid alignment object for sensors! + checkAlignment(); + for(const auto& c : conditions) { + if ( c.first == DeVPSensor::key_info ) info = c.second; + else if ( c.first == DeVPSensor::key_noise ) noise = c.second; + else if ( c.first == DeVPSensor::key_readout ) readout = c.second; + } + // Check here if values must be valid ? + if ( !info.isValid() ) { + // except(DeVPSensor", "Invalid IOV dependent sensor info!"); + } + if ( !noise.isValid() ) { + // except(DeVPSensor", "Invalid IOV dependent sensor noise!"); + } + if ( !readout.isValid() ) { + // except(DeVPSensor", "Invalid IOV dependent sensor readout!"); + } +} + +/// Printout method to stdout +void gaudi::DeVPSensor::print(int indent, int flg) const { + access()->print(indent, flg); +} diff --git a/DDDB/src/Detector/DetectorElement.cpp b/DDDB/src/Detector/DetectorElement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f4d4bb2a9dfb2ee8a46b23ef52f8b2edd128de5 --- /dev/null +++ b/DDDB/src/Detector/DetectorElement.cpp @@ -0,0 +1,38 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/DetectorElement.h" +#include "DD4hep/Printout.h" + + +namespace gaudi { + typedef dd4hep::ConditionKey _K; + const std::string Keys::staticKeyName ("DetElement-Info-Static"); + const Keys::itemkey_type Keys::staticKey = _K::itemCode(Keys::staticKeyName); + const std::string Keys::deKeyName ("DetElement-Info-IOV"); + const Keys::itemkey_type Keys::deKey = _K::itemCode(Keys::deKeyName); + + const std::string Keys::alignmentsComputedKeyName("Alignments-Computed"); + const Keys::key_type Keys::alignmentsComputedKey = _K::KeyMaker(0,Keys::alignmentsComputedKeyName).hash; +} + +std::string gaudi::DE::indent(int level) { + char fmt[128], text[1024]; + ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds",level+1,2*level+1); + ::snprintf(text,sizeof(text),fmt,""); + return text; +} + diff --git a/DDDB/src/Detector/ParameterMap.cpp b/DDDB/src/Detector/ParameterMap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6559fd5598ae0ef478baf9278738ff4a89e0b43d --- /dev/null +++ b/DDDB/src/Detector/ParameterMap.cpp @@ -0,0 +1,73 @@ +//============================================================================== +// AIDA Detector description implementation for LHCb +//------------------------------------------------------------------------------ +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2018-03-08 +// \version 1.0 +// +//============================================================================== + +// Framework include files +#include "Detector/ParameterMap.h" +#include "DD4hep/Handle.h" + +namespace { + static gaudi::ParameterMap::Parameter s_empty; +} + +/// Gaudi namespace declaration +namespace gaudi { + + /// Type dependent accessor to a named parameter + template <typename T> T ParameterMap::Parameter::get() const { + if ( this == &s_empty ) return 0; + return dd4hep::_toType<T>(value); + } + + /// Add/update a parameter value + bool ParameterMap::set(const std::string& nam, const std::string& val, const std::string& type) { + const auto i = m_params.find(nam); + if ( i == m_params.end() ) { + return m_params.insert(make_pair(nam,Parameter(val,type))).second; + } + (*i).second.value = val; + (*i).second.type = type; + return false; + } + + /// Access single parameter + const ParameterMap::Parameter& ParameterMap::param(const std::string& nam, bool throw_if) const { + const auto i = m_params.find(nam); + if ( i != m_params.end() ) + return (*i).second; + else if ( throw_if ) { + throw std::runtime_error("ParameterMap: Attempt to access non-existng parameter: "+nam); + } + return s_empty; + } + + /// Type dependent accessor to a named parameter + template <typename T> T ParameterMap::param(const std::string& nam, bool throw_if) const { + return param(nam, throw_if).get<T>(); + } + +#define INST(x) template x ParameterMap::Parameter::get() const; \ + template x ParameterMap::param(const std::string& nam, bool throw_if_not_present) const + + INST(bool); + INST(int); + INST(short); + INST(long); + INST(double); + INST(float); + INST(std::string); +} + + + diff --git a/DDDB/src/plugins/CondDB2DDDB.cpp b/DDDB/src/plugins/CondDB2DDDB.cpp index 53a8d318614aca741e659dfa8be59336ca859440..6430693d4f70b2a16ce40901775693b787bea127 100644 --- a/DDDB/src/plugins/CondDB2DDDB.cpp +++ b/DDDB/src/plugins/CondDB2DDDB.cpp @@ -65,7 +65,6 @@ namespace dd4hep { struct DDDBConditionParamVector {}; struct DDDBConditionParamSpecific {}; - /// C++ version to convert a string to lower case std::string str_lower(const std::string& str) { std::string res = str.c_str(); @@ -588,7 +587,7 @@ namespace dd4hep { if ( !g.fromString(&pos,data) ) g.invalidConversion(data, g.type()); if ( nam == "dPosXYZ" ) { - a->translation = pos; + a->translation = pos/10.0; a->flags |= Delta::HAVE_TRANSLATION; } else if ( nam == "dRotXYZ" ) { @@ -622,7 +621,12 @@ namespace dd4hep { if ( element.hasAttr(_U(comment)) ) { cond->comment = element.attr<string>(_U(comment)); } - +#if 0 + if ( str_upper(path).find("/VP/") != string::npos ) { + printout(ALWAYS,"Conditions","Loading condition: %s", path.c_str()); + } +#endif + int cls_id = -1; if ( element.hasAttr(_LBU(classID)) ) { cls_id = element.attr<int>(_LBU(classID)); @@ -635,7 +639,7 @@ namespace dd4hep { ++num_align; } #endif - if ( cls_id == AbstractMap::ALIGNMENT ) { + if ( cls_id == AbstractMap::ALIGNMENT || cls_id == 1008106 ) { AbstractMap& d = cond.bind<AbstractMap>(); pair<string,OpaqueDataBlock> block; Delta& align = block.second.bind<Delta>(); @@ -1439,9 +1443,10 @@ namespace dd4hep { det->name.c_str() ); } + if ( x_det.hasAttr(_LBU(classID)) ) { + det->classID = element.attr<int>(_LBU(classID)); + } // Now extract all availible information from the xml - if ( x_det.hasAttr(_LBU(classID)) ) - det->classID = x_det.attr<int>(_LBU(classID)); if ( (elt=x_det.child(_U(author),false)) ) Conv<DDDBAuthor>(description,context,&det->author)(elt); if ( (elt=x_det.child(_U(version),false)) ) @@ -1760,9 +1765,11 @@ namespace dd4hep { xml_doc->context.valid_since = 0; xml_doc->context.valid_until = 0; docs.insert(make_pair(doc_path,xml_doc->addRef())); - //if ( str_upper(doc_path).find("VELO") != string::npos ) { - //printout(ALWAYS,"load_dddb","Loading document: %s",doc_path.c_str()); + + //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(); @@ -1835,9 +1842,9 @@ namespace dd4hep { long load_dddb_objects(Detector& description, int argc, char** argv) { DDDBHelper* hlp = description.extension<DDDBHelper>(false); if ( hlp ) { - DDDBContext ctxt(description); - xml::UriReader* rdr = hlp->xmlReader(); + xml::UriReader* rdr = hlp->xmlReader(); DDDBReaderContext* ctx = (DDDBReaderContext*)rdr->context(); + DDDBContext ctxt(description); string sys_id = ctx->match+"//lhcb.xml"; string obj_path = "/"; if ( argc == 0 ) { diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/plugins/DDDBConditionsLoader.cpp similarity index 100% rename from DDDB/src/DDDBConditionsLoader.cpp rename to DDDB/src/plugins/DDDBConditionsLoader.cpp diff --git a/DDDB/src/plugins/DetectorElementTest.cpp b/DDDB/src/plugins/DetectorElementTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fa06570237171d6d69979900dc2b7462ef5f975 --- /dev/null +++ b/DDDB/src/plugins/DetectorElementTest.cpp @@ -0,0 +1,136 @@ +//========================================================================== +// 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/Detector.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/ConditionsData.h" +#include "DD4hep/ConditionsPrinter.h" +#include "DD4hep/AlignmentsProcessor.h" +#include "DD4hep/ConditionsProcessor.h" +#include "DD4hep/detail/DetectorInterna.h" + +#include "DDCond/ConditionsOperators.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsSlice.h" + +// C/C++ include files +#include <memory> + +using namespace std; +using namespace dd4hep; + +#include "Kernel/VPConstants.h" +#include "Detector/DeVP.h" + +/// Anonymous namespace for plugins +namespace { + PrintLevel s_PrintLevel = INFO; +} + +//========================================================================== +/// Anonymous namespace for plugins +namespace { + + using namespace dd4hep::cond; + + /// Basic entry point to print out the detector element hierarchy + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + long dump_det_tree(Detector& description, int argc, char** argv) { + + using DDDB::DDDBCatalog; + + /// Callback object to print selective information + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + struct DumpActor { + /// Container with all known conditions + vector<pair<int,Condition> > m_allConditions; + shared_ptr<ConditionsSlice> m_slice; + ConditionsManager m_manager; + string m_name; + Detector& m_detDesc; + + /// Standard constructor + DumpActor(Detector& l) + : m_detDesc(l) + { + m_manager = ConditionsManager::from(m_detDesc); + m_slice.reset(new ConditionsSlice(m_manager,shared_ptr<ConditionsContent>(new ConditionsContent()))); + } + + /// Standard destructor + ~DumpActor() { + } + + /// __________________________________________________________________________________ + void printDetElement(int , DetElement ) { + } + long dump(DetElement de, int level) { + char fmt[64], text[512]; + const DetElement::Children& c = de.children(); + ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5); + ::snprintf(text,sizeof(text),fmt,""); + try { + printDetElement(level, de); + } + catch(const exception& e) { + ::sprintf(fmt,"%03d %%-%ds WARNING from: %%s %%-20s %%s",level+1,2*level+3); + printout(INFO, m_name, fmt, "", de.path().c_str(), "[NO CATALOG availible]",e.what()); + } + catch(...) { + ::sprintf(fmt,"%03d %%-%ds WARNING from: %%s %%-20s",level+1,2*level+3); + printout(INFO, m_name, fmt, "", de.path().c_str(), "[NO CATALOG availible]"); + } + for (const auto& i : c) + dump(i.second,level+1); + 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); + return actor.dump(description.world(), 0); + } + + template <int flag> long dump_detelement_tree(Detector& description, int argc, char** argv) + { return dump_det_tree(description,argc,argv); } +} /* End anonymous namespace */ + +DECLARE_APPLY(DDDB_DeVeloTest,dump_detelement_tree<0>) +//========================================================================== diff --git a/DDParsers/include/Parsers/spirit/Parsers.h b/DDParsers/include/Parsers/spirit/Parsers.h index 82b453403fad56718a78107ebcd9ae50f9e1a077..b8779e04eaf4baacf6bcc02382f621a9e7e34089 100755 --- a/DDParsers/include/Parsers/spirit/Parsers.h +++ b/DDParsers/include/Parsers/spirit/Parsers.h @@ -24,6 +24,7 @@ #include <set> #include <map> #include <deque> +#include <iostream> // ============================================================================ #define PARSERS_DECL_FOR_SINGLE(Type) \ @@ -31,6 +32,12 @@ int parse(Type& result, const std::string& input); \ }} +/// Macro to define dummy (local) ostreams +#define DD4HEP_DEFINE_OSTREAM_DUMMY(x) \ + namespace { \ + std::ostream& operator<<(std::ostream& s,const x&) { return s; } \ + } + #define DD4HEP_DEFINE_PARSER_DUMMY(Type) \ PARSERS_DECL_FOR_SINGLE(Type) \ namespace dd4hep { namespace Parsers { \ diff --git a/examples/Conditions/src/ConditionsTest.cpp b/examples/Conditions/src/ConditionsTest.cpp index 5ddc22315ab156c1e040f99a7c3f9987e40e00cf..96a5d43d834850af8c91ef28d8f7e9afd307af47 100644 --- a/examples/Conditions/src/ConditionsTest.cpp +++ b/examples/Conditions/src/ConditionsTest.cpp @@ -111,7 +111,12 @@ namespace dd4hep { string type = c.type(); printout(INFO,"Cond_Value","%-32s [%16s] : %s [%s] ", c.name(), c.type().c_str(), - c.value().c_str(), c->validity.c_str()); +#if !defined(DD4HEP_MINIMAL_CONDITIONS) + c.value().c_str(), c->validity.c_str() +#else + "", "" +#endif + ); if ( type == "alignment" ) print_bound_value<string>(c); else if ( type == "temperature" )