From 4845de3248a68e96662b8116eb58d71393018d31 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Tue, 6 Sep 2016 15:10:24 +0000 Subject: [PATCH] Implemented alignment mechanism. Transformations untested. --- DDAlign/CMakeLists.txt | 9 +- DDAlign/include/DDAlign/AlignmentsManager.h | 88 +++++ DDAlign/src/AlignmentWriter.cpp | 34 +- DDAlign/src/AlignmentsManager.cpp | 304 +++++++++++++++++ DDAlign/src/{ => plugins}/AlignmentParser.cpp | 2 +- DDAlign/src/plugins/AlignmentPlugins.cpp | 53 +++ DDCond/CMakeLists.txt | 2 +- .../DDCond/ConditionsDependencyCollection.h | 2 +- .../DDCond/ConditionsDependencyHandler.h | 7 +- DDCond/include/DDCond/ConditionsManager.h | 2 + DDCond/include/DDCond/ConditionsPool.h | 2 +- DDCond/src/ConditionsDependencyCollection.cpp | 4 +- DDCond/src/ConditionsDependencyHandler.cpp | 7 +- DDCond/src/plugins/ConditionsUserPool.cpp | 6 +- DDCore/include/DD4hep/AlignmentData.h | 86 ++--- DDCore/include/DD4hep/AlignmentTools.h | 3 + DDCore/include/DD4hep/Alignments.h | 116 +++++-- DDCore/include/DD4hep/ConditionDerived.h | 136 ++++---- DDCore/include/DD4hep/Conditions.h | 15 +- DDCore/include/DD4hep/DetAlign.h | 2 + DDCore/include/DD4hep/MatrixHelpers.h | 27 +- .../DD4hep/objects/AlignmentsInterna.h | 22 +- DDCore/include/XML/UriReader.h | 8 + DDCore/src/AlignmentData.cpp | 16 +- DDCore/src/AlignmentTools.cpp | 21 ++ DDCore/src/Alignments.cpp | 82 ++++- DDCore/src/AlignmentsInterna.cpp | 22 +- DDCore/src/Detector.cpp | 5 +- DDCore/src/DetectorInterna.cpp | 2 + DDCore/src/IOV.cpp | 2 +- DDCore/src/MatrixHelpers.cpp | 75 +++-- DDCore/src/XML/DocumentHandler.cpp | 4 +- DDCore/src/XML/UriReader.cpp | 15 + DDDB/CMakeLists.txt | 5 +- DDDB/include/DDDB/DDDBConversion.h | 1 + DDDB/include/DDDB/DDDBReader.h | 4 + DDDB/src/CondDB2DDDB.cpp | 23 +- DDDB/src/DDDBAlignmentTest.cpp | 311 ++++++------------ DDDB/src/DDDBConditionsLoader.cpp | 2 + DDDB/src/DDDBDerivedCondTest.cpp | 10 +- DDDB/src/DDDBFileReader.cpp | 23 ++ DDDB/src/DDDBReader.cpp | 28 +- cmake/run_test_package.sh | 12 +- examples/DDDB/CMakeLists.txt | 11 +- examples/DDDB/scripts/run_dddb.sh | 6 +- 45 files changed, 1125 insertions(+), 492 deletions(-) create mode 100644 DDAlign/include/DDAlign/AlignmentsManager.h create mode 100644 DDAlign/src/AlignmentsManager.cpp rename DDAlign/src/{ => plugins}/AlignmentParser.cpp (99%) create mode 100644 DDAlign/src/plugins/AlignmentPlugins.cpp diff --git a/DDAlign/CMakeLists.txt b/DDAlign/CMakeLists.txt index e2e11e0d4..7d6c72fba 100644 --- a/DDAlign/CMakeLists.txt +++ b/DDAlign/CMakeLists.txt @@ -10,9 +10,12 @@ # #========================================================================== dd4hep_package( DDAlign - USES DDCore + USES DDCore DDCond INCLUDE_DIRS include INSTALL_INCLUDES include/DDAlign) -#---DDAlign library -------------------------------------------------------------- -dd4hep_add_plugin ( DDAlign SOURCES src/*.cpp ) +#---DDCond library -------------------------------------------------------------- +dd4hep_add_package_library(DDAlign SOURCES src/*.cpp ) + +#---DDAlign plugins ------------------------------------------------------------- +dd4hep_add_plugin(DDAlignPlugins SOURCES src/plugins/*.cpp ) diff --git a/DDAlign/include/DDAlign/AlignmentsManager.h b/DDAlign/include/DDAlign/AlignmentsManager.h new file mode 100644 index 000000000..4afc80f5c --- /dev/null +++ b/DDAlign/include/DDAlign/AlignmentsManager.h @@ -0,0 +1,88 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_DDALIGN_ALIGNMENTMANAGER_H +#define DD4HEP_DDALIGN_ALIGNMENTMANAGER_H + +// Framework include files +#include "DD4hep/Memory.h" +#include "DD4hep/Alignments.h" +#include "DD4hep/ConditionDerived.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + class UserPool; + class ConditionDependency; + class ConditionUpdateContext; + class ConditionsDependencyCollection; + } + + /// Namespace for the alignment part of the AIDA detector description toolkit + namespace Alignments { + + /// Forward declarations + class AlignmentsManagerObject; + + /// Alignment manager instance to handle alignment dependencies + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_ALIGN + */ + class AlignmentsManager : public Handle<AlignmentsManagerObject> { + public: + /// Standard object type + typedef AlignmentsManagerObject Object; + /// Conditions derivation context + typedef Conditions::ConditionUpdateContext Context; + /// Alignments re-use conditions dependency definition from the conditions manager + typedef Conditions::ConditionDependency Dependency; + /// Alignments re-use conditions dependency container def from the conditions manager + typedef Conditions::ConditionsDependencyCollection Dependencies; + + public: + /// Initializing constructor + AlignmentsManager(Object* p) : Handle<Object>(p) {} + /// Constructor to be used when reading the already parsed object + AlignmentsManager(const Handle<Object>& e) : Handle<Object>(e) {} + /// Constructor to be used when reading the already parsed object + template <typename Q> AlignmentsManager(const Handle<Q>& e) : Handle<Object>(e) {} + /// Initializing constructor. Creates the object! + AlignmentsManager(const std::string& name); + /// Initializing constructor. Creates the object! + AlignmentsManager(char const* name); + /// Default destructor + ~AlignmentsManager() {} + /// Delete the manager. Be careful: this affects all referencing handles! + void destroy(); + /// Adopy alignment dependency for later recalculation + void adoptDependency(Dependency* dependency) const; + /// Access all known dependencies + const Dependencies& knownDependencies() const; + /// Compute all alignment conditions of the internal dependency list + void compute(dd4hep_ptr<UserPool>& user_pool) const; + /// Compute all alignment conditions of the specified dependency list + void compute(dd4hep_ptr<UserPool>& user_pool, const Dependencies& deps) const; + /// Register new updated derived alignment during the computation step + static void newEntry(const Context& parameter, + DetElement& det, + const Dependency* dep, + AlignmentCondition& con); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDALIGN_ALIGNMENTMANAGER_H */ diff --git a/DDAlign/src/AlignmentWriter.cpp b/DDAlign/src/AlignmentWriter.cpp index 829590d7b..d6d9cb032 100644 --- a/DDAlign/src/AlignmentWriter.cpp +++ b/DDAlign/src/AlignmentWriter.cpp @@ -15,11 +15,10 @@ // Framework includes #include "DDAlign/AlignmentWriter.h" +#include "DD4hep/LCDD.h" #include "DD4hep/Printout.h" #include "DD4hep/MatrixHelpers.h" -#include "DD4hep/DetectorTools.h" #include "DD4hep/objects/DetectorInterna.h" -#include "DD4hep/DetFactoryHelper.h" #include "XML/DocumentHandler.h" #include "DDAlign/AlignmentTags.h" #include "DDAlign/AlignmentCache.h" @@ -30,7 +29,6 @@ // C/C++ include files #include <stdexcept> -namespace DetectorTools = DD4hep::Geometry::DetectorTools; using DD4hep::Geometry::Position; using DD4hep::Geometry::Translation3D; using namespace DD4hep::Alignments; @@ -153,33 +151,3 @@ long AlignmentWriter::write(XML::Document doc, const string& output) const { XML::DocumentHandler docH; return docH.output(doc, output); } - -static long create_alignment_file(LCDD& lcdd, int argc, char** argv) { - DetElement top; - string output, path = "/world"; - bool enable_transactions = false; - for(int i=1; i<argc;++i) { - if ( argv[i][0]=='-' || argv[i][0]=='/' ) { - const char* p = ::strchr(argv[i],'='); - if ( p && strncmp(argv[i]+1,"-output",7)==0 ) - output = p+1; - else if ( p && strncmp(argv[i]+1,"-path",5)==0 ) - path = p+1; - else if ( strncmp(argv[i]+1,"-transactions",5)==0 ) - enable_transactions = true; - else - throw runtime_error("AlignmentWriter: Invalid argument:"+string(argv[i])); - } - } - printout(ALWAYS,"AlignmentWriter", - "++++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"", - path.c_str(), output.c_str()); - top = DetectorTools::findDaughterElement(lcdd.world(),path); - if ( top.isValid() ) { - AlignmentWriter wr(lcdd); - return wr.write(wr.dump(top,enable_transactions), output); - } - throw runtime_error("AlignmentWriter: Invalid top level element name:"+path); -} - -DECLARE_APPLY(DDAlignmentWriter, create_alignment_file) diff --git a/DDAlign/src/AlignmentsManager.cpp b/DDAlign/src/AlignmentsManager.cpp new file mode 100644 index 000000000..8eddd84f1 --- /dev/null +++ b/DDAlign/src/AlignmentsManager.cpp @@ -0,0 +1,304 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/Handle.inl" +#include "DD4hep/Printout.h" +#include "DD4hep/MatrixHelpers.h" +#include "DDCond/ConditionsPool.h" +#include "DDAlign/AlignmentsManager.h" + +using namespace DD4hep; +using namespace DD4hep::Alignments; + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the alignment part of the AIDA detector description toolkit + namespace Alignments { + + typedef Conditions::ConditionDependency Dependency; + + struct AlignContext { + struct Entry { + const Dependency* dep; + DetElement::Object* det; + AlignmentCondition::Object* cond; + unsigned int key, top; + }; + 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; + unsigned long long int magic; + AlignContext() : magic(magic_word()) {} + void newEntry(DetElement det, const Dependency* dep, AlignmentCondition::Object* con) { + if ( det.isValid() ) { + Entry entry; + unsigned int key = det.key(); + entry.top = 0; + entry.cond = con; + entry.dep = dep; + entry.det = det.ptr(); + entry.key = key; + detectors.insert(std::make_pair(det, entries.size())); + keys.insert(std::make_pair(key, entries.size())); + entries.insert(entries.end(), entry); + } + } + }; + + /// Alignment manager. + /** + * Uses internally the conditions mechanism to manager the alignment conditions. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_ALIGNMENTS + */ + class AlignmentsManagerObject : public NamedObject { + public: + typedef AlignmentsManager::Dependencies Dependencies; + typedef Conditions::Condition Condition; + + /// Full list of alignment dependencies + Dependencies dependencies; + /// References to all alignment possibilities known + AlignContext all_alignments; + + /// Compute the transformation from the closest detector element of the alignment to the world system + void to_world(AlignContext& new_alignments, UserPool& pool, DetElement det, TGeoHMatrix& mat) const; + /// Compute all alignment conditions of the lower levels + void compute(AlignContext& new_alignments, UserPool& pool, DetElement child, int level) const; + + public: + /// Initializing constructor + AlignmentsManagerObject(); + /// Default destructor + virtual ~AlignmentsManagerObject(); + /// Compute all alignment conditions of the internal dependency list + void compute(UserPool& user_pool) const; + /// Compute all alignment conditions of the specified dependency list + void compute(UserPool& user_pool, const Dependencies& deps) const; + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + + +DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentsManagerObject); + +/// Initializing constructor +AlignmentsManagerObject::AlignmentsManagerObject() : NamedObject() { +} + +/// Default destructor +AlignmentsManagerObject::~AlignmentsManagerObject() { + dependencies.clear(); +} + +void AlignmentsManagerObject::to_world(AlignContext& new_alignments, UserPool& pool, DetElement det, TGeoHMatrix& mat) const { + DetElement par = det.parent(); + while( par.isValid() ) { + // If we find that the parent also got updated, directly take this transformation. + // Since we compute top-down, it is already valid! + AlignContext::Keys::const_iterator i = new_alignments.keys.find(par.key()); + if ( i != new_alignments.keys.end() ) { + const AlignContext::Entry& e = new_alignments.entries[(*i).second]; + AlignmentCondition cond(e.cond); + AlignmentData& align = cond.data(); + mat.MultiplyLeft(&align.worldTransformation()); + return; + } + // The parent did not get updated: We have to search the the conditions pool if + // there is a still valid condition, which we can use to build the world transformation + // The parent's alignment condition by defintiion must be present in the pool, + // since it got updated in the past! + i = all_alignments.keys.find(par.key()); + if ( i != all_alignments.keys.end() ) { + const AlignContext::Entry& e = all_alignments.entries[(*i).second]; + Condition::key_type key = e.dep->target.hash; + AlignmentCondition cond = pool.get(key); + AlignmentData& align = cond.data(); + mat.MultiplyLeft(&align.worldTransformation()); + return; + } + // There is no special alignment for this detector element. + // Hence to nominal (relative) transformation to the parent is valid + mat.MultiplyLeft(&par.nominal().detectorTransformation()); + par = par.parent(); + } +} + +/// Compute all alignment conditions of the internal dependency list +void AlignmentsManagerObject::compute(UserPool& user_pool) const { + compute(user_pool, dependencies); +} + +/// Compute all alignment conditions of the specified dependency list +void AlignmentsManagerObject::compute(UserPool& pool, const Dependencies& deps) const { + AlignContext::DetectorMap::const_iterator i; + AlignContext new_alignments; + new_alignments.entries.reserve(deps.size()); + pool.compute(deps, &new_alignments); + std::string prev = "-----"; + for(i=new_alignments.detectors.begin(); i!=new_alignments.detectors.end(); ++i) { + AlignContext::Entry& e = new_alignments.entries[(*i).second]; + DetElement det = e.det; + const std::string& p = det.path(); + size_t idx = p.find(prev); + if ( idx == 0 ) { + continue; + } + prev = p; + printout(DEBUG,"Alignment","Update top Node: Lvl:%d Key:%08X: %s", det.level(), det.key(), p.c_str()); + e.top = 1; + } + // We got now the top nodes of the new_alignments. From the top nodes we have to + // recursively calculate all changes downwards the lower levels! + // Note: The upper levels are already correct and do not need to be updated! + printout(INFO,"Alignment","Working down the tree...."); + for(i=new_alignments.detectors.begin(); i != new_alignments.detectors.end(); ++i) { + AlignContext::Entry& e = new_alignments.entries[(*i).second]; + if ( e.top ) { + compute(new_alignments, pool, e.det, 0); + } + } +} +/// Compute the alignment delta for one detector element and it's alignment condition +void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta) { + const AlignmentData& align = cond.data(); + const Delta& delta = align.delta; + const TGeoHMatrix& nom = align.detectorTransformation(); + 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: + Geometry::_transform(tr_delta, Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION: + Geometry::_transform(tr_delta, Transform3D(rot,pos)); + break; + case Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + Geometry::_transform(tr_delta, Transform3D(piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_ROTATION: + Geometry::_transform(tr_delta, rot); + break; + case Delta::HAVE_TRANSLATION: + Geometry::_transform(tr_delta, pos); + break; + default: + break; + } + tr_delta.MultiplyLeft(&nom); + align.detectorTrafo = tr_delta; + align.worldTrafo = tr_delta; +} +/// Compute all alignment conditions of the lower levels +void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det, int level) const { + AlignContext::Keys::const_iterator k=new_alignments.keys.find(det.key()); + bool has_cond = k != new_alignments.keys.end(); + const AlignContext::Entry* ent = has_cond ? &new_alignments.entries[(*k).second] : 0; + + if ( ent ) { + char fmt[128]; + TGeoHMatrix tr_delta; + AlignmentCondition cond(ent->cond); + AlignmentData& align = cond.data(); + computeDelta(cond, tr_delta); + to_world(new_alignments, pool, det, align.worldTrafo); + align.trToWorld = Geometry::_transform(&align.worldTrafo); + ::snprintf(fmt,sizeof(fmt),"%%d %%%ds %%s %%08X: %%s IOV:%%s",2*level); + printout(DEBUG,"ComputeAlignment",fmt, + det.level(), "", has_cond ? "NO " : "YES", + det.key(), det.path().c_str(), cond.iov().str().c_str()); + } + else { + // DetElement 'det' has no specific alignment. If any of the children has one + // and any of the parents, 'to_world' should pick up all the proper components + // to build the proper world-transformation of the child. + // Hence, we do not have to recompute it's value. + // We just continue to trickle down to the children. + // + // Alternatively we could inject 'special' alignment conditions, which would depend + // on the parent... + // Under circumstances, this might be cheaper to re-compute. + } + const DetElement::Children& children = det.children(); + for(auto c=children.begin(); c!=children.end(); ++c) { + DetElement child = (*c).second; + compute(new_alignments, pool, child, level+1); + } +} + +/// Initializing constructor +AlignmentsManager::AlignmentsManager(const std::string& nam) { + assign(new AlignmentsManagerObject(), nam, "alignmentmanager"); +} + +/// Initializing constructor +AlignmentsManager::AlignmentsManager(char const* nam) { + assign(new AlignmentsManagerObject(), nam ? nam : "", "alignmentmanager"); +} + +/// Delete the manager. +void AlignmentsManager::destroy() { + deletePtr(m_element); +} + +/// Adopy alignment dependency for later recalculation +void AlignmentsManager::adoptDependency(Dependency* dependency) const { + Object* o = access(); + o->dependencies.insert(dependency); + o->all_alignments.newEntry(dependency->detector, dependency, 0); +} + +/// Access all known dependencies +const AlignmentsManager::Dependencies& AlignmentsManager::knownDependencies() const { + return access()->dependencies; +} + +/// Compute all alignment conditions of the internal dependency list +void AlignmentsManager::compute(dd4hep_ptr<UserPool>& user_pool) const { + Object* o = access(); + o->compute(*(user_pool.get()), o->dependencies); +} + +/// Compute all alignment conditions of the specified dependency list +void AlignmentsManager::compute(dd4hep_ptr<UserPool>& user_pool, const Dependencies& deps) const { + access()->compute(*(user_pool.get()), deps); +} + +/// Register new updated derived alignment during the computation step +void AlignmentsManager::newEntry(const Context& context, + DetElement& det, + const Dependency* dep, + AlignmentCondition& con) { + // It must be ensured this is a valid object! Check magic word + AlignContext* o = static_cast<AlignContext*>(context.parameter); + if ( o && o->magic == magic_word() ) { + o->newEntry(det, dep, con.ptr()); + return; + } +} diff --git a/DDAlign/src/AlignmentParser.cpp b/DDAlign/src/plugins/AlignmentParser.cpp similarity index 99% rename from DDAlign/src/AlignmentParser.cpp rename to DDAlign/src/plugins/AlignmentParser.cpp index 9b0b9ba18..e0df8b57c 100644 --- a/DDAlign/src/AlignmentParser.cpp +++ b/DDAlign/src/plugins/AlignmentParser.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDAlign/src/plugins/AlignmentPlugins.cpp b/DDAlign/src/plugins/AlignmentPlugins.cpp new file mode 100644 index 000000000..14318c2e0 --- /dev/null +++ b/DDAlign/src/plugins/AlignmentPlugins.cpp @@ -0,0 +1,53 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework includes +#include "DD4hep/Printout.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DetectorTools.h" + +using namespace std; +using namespace DD4hep; + +#include "DDAlign/AlignmentWriter.h" + +namespace DetectorTools = DD4hep::Geometry::DetectorTools; +static long create_alignment_file(Geometry::LCDD& lcdd, int argc, char** argv) { + Geometry::DetElement top; + string output, path = "/world"; + bool enable_transactions = false; + for(int i=1; i<argc;++i) { + if ( argv[i][0]=='-' || argv[i][0]=='/' ) { + const char* p = ::strchr(argv[i],'='); + if ( p && strncmp(argv[i]+1,"-output",7)==0 ) + output = p+1; + else if ( p && strncmp(argv[i]+1,"-path",5)==0 ) + path = p+1; + else if ( strncmp(argv[i]+1,"-transactions",5)==0 ) + enable_transactions = true; + else + throw runtime_error("AlignmentWriter: Invalid argument:"+string(argv[i])); + } + } + printout(ALWAYS,"AlignmentWriter", + "++++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"", + path.c_str(), output.c_str()); + top = DetectorTools::findDaughterElement(lcdd.world(),path); + if ( top.isValid() ) { + Alignments::AlignmentWriter wr(lcdd); + return wr.write(wr.dump(top,enable_transactions), output); + } + throw runtime_error("AlignmentWriter: Invalid top level element name:"+path); +} +DECLARE_APPLY(DDAlignmentWriter, create_alignment_file) diff --git a/DDCond/CMakeLists.txt b/DDCond/CMakeLists.txt index 0b3c2e2de..c9f75c550 100644 --- a/DDCond/CMakeLists.txt +++ b/DDCond/CMakeLists.txt @@ -18,4 +18,4 @@ dd4hep_package( DDCond dd4hep_add_package_library(DDCond SOURCES src/*.cpp ) #---DDCond components ----------------------------------------------------------- -dd4hep_add_plugin ( DDCondPlugins SOURCES src/plugins/*.cpp ) +dd4hep_add_plugin(DDCondPlugins SOURCES src/plugins/*.cpp ) diff --git a/DDCond/include/DDCond/ConditionsDependencyCollection.h b/DDCond/include/DDCond/ConditionsDependencyCollection.h index 75a234594..79a678b27 100644 --- a/DDCond/include/DDCond/ConditionsDependencyCollection.h +++ b/DDCond/include/DDCond/ConditionsDependencyCollection.h @@ -107,7 +107,7 @@ namespace DD4hep { /// Mini-container interface: insert element by key std::pair<iterator,bool> insert(const Dependencies::value_type& entry); /// Insert new element by key - std::pair<iterator,bool> insert(Condition::key_type key, Dependency* dep); + std::pair<iterator,bool> insert(Dependency* dep); /// Create view by application of functor template <typename T> void for_each(const T& function) const { std::for_each(dependencies.begin(),dependencies.end(),function); } diff --git a/DDCond/include/DDCond/ConditionsDependencyHandler.h b/DDCond/include/DDCond/ConditionsDependencyHandler.h index fbbcd3b8c..c8ac20b3c 100644 --- a/DDCond/include/DDCond/ConditionsDependencyHandler.h +++ b/DDCond/include/DDCond/ConditionsDependencyHandler.h @@ -46,7 +46,9 @@ namespace DD4hep { UserPool& m_pool; /// Dependency container to be resolved. const Dependencies& m_dependencies; - + /// User defined optional processing parameter + void* m_userParam; + /// Internal call to trigger update callback Condition::Object* do_callback(const ConditionDependency& dep) const; @@ -54,7 +56,8 @@ namespace DD4hep { /// Initializing constructor ConditionsDependencyHandler(ConditionsManager::Object* mgr, UserPool& pool, - const Dependencies& dependencies); + const Dependencies& dependencies, + void* user_param); /// Default destructor ~ConditionsDependencyHandler(); /// ConditionResolver implementation: Access to the conditions manager diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h index 135409e62..336431d99 100644 --- a/DDCond/include/DDCond/ConditionsManager.h +++ b/DDCond/include/DDCond/ConditionsManager.h @@ -34,6 +34,7 @@ namespace DD4hep { class ConditionsIOVPool; class ConditionDependency; class ConditionsDataLoader; + class ConditionUpdateContext; class ConditionsManagerObject; /// Manager class for condition handles @@ -51,6 +52,7 @@ namespace DD4hep { typedef std::vector<IOVType> IOVTypes; typedef std::map<IOVType*,Container> TypeConditions; typedef std::map<DetElement,Container> DetectorConditions; + typedef ConditionDependency Dependency; typedef ConditionsDependencyCollection Dependencies; public: diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index dca41bc4e..332a5e4a0 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -177,7 +177,7 @@ namespace DD4hep { /// Prepare user pool for usage (load, fill etc.) according to required IOV virtual long prepare(const IOV& required) = 0; /// Evaluate and register all derived conditions from the dependency list - virtual long compute(const Dependencies& dependencies) = 0; + virtual long compute(const Dependencies& dependencies, void* user_param=0) = 0; }; } /* End namespace Conditions */ diff --git a/DDCond/src/ConditionsDependencyCollection.cpp b/DDCond/src/ConditionsDependencyCollection.cpp index 5b1c3fc24..32abd7bdb 100644 --- a/DDCond/src/ConditionsDependencyCollection.cpp +++ b/DDCond/src/ConditionsDependencyCollection.cpp @@ -52,7 +52,7 @@ ConditionsDependencyCollection::insert(const Dependencies::value_type& entry) /// Insert new element by key std::pair<ConditionsDependencyCollection::iterator,bool> -ConditionsDependencyCollection::insert(Condition::key_type key, Dependency* dep) { +ConditionsDependencyCollection::insert(Dependency* dep) { dep->addRef(); - return dependencies.insert(std::make_pair(key,Holder(dep))); + return dependencies.insert(std::make_pair(dep->key(),Holder(dep))); } diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp index 022f6b809..1be9b0b26 100644 --- a/DDCond/src/ConditionsDependencyHandler.cpp +++ b/DDCond/src/ConditionsDependencyHandler.cpp @@ -22,8 +22,9 @@ using namespace DD4hep::Conditions; /// Default constructor ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager::Object* mgr, UserPool& pool, - const Dependencies& dependencies) - : m_manager(mgr), m_pool(pool), m_dependencies(dependencies) + const Dependencies& dependencies, + void* user_param) + : m_manager(mgr), m_pool(pool), m_dependencies(dependencies), m_userParam(user_param) { } @@ -61,7 +62,7 @@ Condition::Object* ConditionsDependencyHandler::do_callback(const ConditionDependency& dep) const { try { Condition::iov_type iov(m_pool.validity().iovType); - ConditionUpdateCall::Context ctxt(*this, dep, iov.reset().invert()); + ConditionUpdateCall::Context ctxt(*this, dep, m_userParam, iov.reset().invert()); Condition cond = (*dep.callback)(dep.target, ctxt); Condition::Object* obj = cond.ptr(); if ( obj ) { diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp index 832de1ca5..8a53e6452 100644 --- a/DDCond/src/plugins/ConditionsUserPool.cpp +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -69,7 +69,7 @@ namespace DD4hep { /// Prepare user pool for usage (load, fill etc.) according to required IOV virtual long prepare(const IOV& required); /// Evaluate and register all derived conditions from the dependency list - virtual long compute(const Dependencies& dependencies); + virtual long compute(const Dependencies& dependencies, void* user_param); }; } /* End namespace Conditions */ @@ -237,11 +237,11 @@ long ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required) { /// Evaluate and register all derived conditions from the dependency list template<typename MAPPING> -long ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps) { +long ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps, void* user_param) { long num_updates = 0; if ( !deps.empty() ) { typedef Dependencies _D; - ConditionsDependencyHandler handler(m_manager.ptr(), *this, deps); + ConditionsDependencyHandler handler(m_manager.ptr(), *this, deps, user_param); ConditionsPool* pool = m_manager->registerIOV(*m_iov.iovType, m_iov.keyData); // Loop over the dependencies and check if they have to be upgraded for(_D::const_iterator i = deps.begin(); i!=deps.end(); ++i) { diff --git a/DDCore/include/DD4hep/AlignmentData.h b/DDCore/include/DD4hep/AlignmentData.h index b61d13eb8..691ef1bd4 100644 --- a/DDCore/include/DD4hep/AlignmentData.h +++ b/DDCore/include/DD4hep/AlignmentData.h @@ -32,6 +32,7 @@ namespace DD4hep { using Geometry::DetElement; using Geometry::RotationZYX; using Geometry::Transform3D; + using Geometry::Translation3D; using Geometry::Position; using Geometry::LCDD; @@ -47,12 +48,21 @@ namespace DD4hep { */ class Delta { public: - typedef Position Pivot; - Pivot pivot; - Position translation; - RotationZYX rotation; + typedef Translation3D Pivot; + Pivot pivot; + Position translation; + RotationZYX rotation; + unsigned int flags; + + enum AlignmentFlags { + HAVE_NONE = 0, + HAVE_TRANSLATION = 1<<2, + HAVE_ROTATION = 1<<3, + HAVE_PIVOT = 1<<4, + }; + /// Default constructor - Delta(); + Delta() : flags(0) {} /// Copy constructor Delta(const Delta& c); /// Default destructor @@ -61,6 +71,12 @@ namespace DD4hep { Delta& operator=(const Delta& c); /// Reset information to identity void clear(); + /// Access flags: Check if the delta operation contains a translation + bool hasTranslation() const { return (flags&HAVE_TRANSLATION) != 0; } + /// Access flags: Check if the delta operation contains a rotation + bool hasRotation() const { return (flags&HAVE_ROTATION) != 0; } + /// Access flags: Check if the delta operation contains a pivot + bool hasPivot() const { return (flags&HAVE_PIVOT) != 0; } }; /// Derived condition data-object definition @@ -125,19 +141,16 @@ namespace DD4hep { /// Assignment operator necessary due to copy constructor AlignmentData& operator=(const AlignmentData& copy); /// Data accessor for decorator - inline AlignmentData& alignmentData() { return *this; } + inline AlignmentData& data() { return *this; } /// Access the ideal/nominal alignment/placement matrix Alignment nominal() const; /// Create cached matrix to transform to world coordinates - const TGeoHMatrix& worldTransformation() const - { return worldTrafo; } + const TGeoHMatrix& worldTransformation() const { return worldTrafo; } /// Access the alignment/placement matrix with respect to the world - const TGeoHMatrix& detectorTransformation() const - { return detectorTrafo; } + const TGeoHMatrix& detectorTransformation() const { return detectorTrafo; } /// Access the currently applied alignment/placement matrix - const Transform3D& localToWorld() const - { return trToWorld; } + const Transform3D& localToWorld() const { return trToWorld; } /** Aliases for the transformation from local coordinates to the world system */ /// Transformation from local coordinates of the placed volume to the world system @@ -209,8 +222,7 @@ namespace DD4hep { ~AlignmentDecorator() { } /// Data accessor - const AlignmentData& data() const - { return T::alignmentData(); } + const AlignmentData& data() const { return T::data(); } /// Access to the DetElement node DetElement detector() const { return data().detector; } @@ -267,32 +279,47 @@ namespace DD4hep { { return data().delta; } /// Set the delta alignment information - void setDelta(const Delta& del) - { data().delta = del; } + void setDelta(const Delta& del) { + AlignmentData& d = data(); + d.delta = del; + } /// Set the delta alignment if only a single translation - void setDelta(const Position& translation) - { data().delta.translation = translation; } + void setDelta(const Position& translation) { + AlignmentData& d = data(); + d.delta.translation = translation; + d.delta.flags |= Delta::HAVE_TRANSLATION; + } /// Set the delta alignment if only a single rotation - void setDelta(const RotationZYX& rotation) - { data().delta.rotation = rotation; } + void setDelta(const RotationZYX& rotation) { + AlignmentData& d = data(); + d.delta.rotation = rotation; + d.delta.flags |= Delta::HAVE_ROTATION; + } /// Set the delta alignment as a composite of a translation and a rotation void setDelta(const Position& translation, RotationZYX& rotation) { AlignmentData& d = data(); d.delta.rotation = rotation; d.delta.translation = translation; + d.delta.flags |= Delta::HAVE_ROTATION; + d.delta.flags |= Delta::HAVE_TRANSLATION; } /// Set the delta alignment if only a single rotation around a pivot point - void setDeltaPivot(const Position& pivot, const RotationZYX& rotation) { + void setDeltaPivot(const Translation3D& pivot, const RotationZYX& rotation) { AlignmentData& d = data(); d.delta.pivot = pivot; d.delta.rotation = rotation; + d.delta.flags |= Delta::HAVE_PIVOT; + d.delta.flags |= Delta::HAVE_ROTATION; } /// Set the delta alignment if a translation and a rotation around pivot - void setDeltaPivot(const Position& translation, const Position& pivot, const RotationZYX& rotation) { + void setDeltaPivot(const Position& translation, const Translation3D& pivot, const RotationZYX& rotation) { AlignmentData& d = data(); d.delta.pivot = pivot; d.delta.rotation = rotation; d.delta.translation = translation; + d.delta.flags |= Delta::HAVE_PIVOT; + d.delta.flags |= Delta::HAVE_ROTATION; + d.delta.flags |= Delta::HAVE_TRANSLATION; } }; @@ -305,21 +332,6 @@ namespace DD4hep { AlignmentDecorator<T>::AlignmentDecorator(const AlignmentDecorator& c) : T(c) {} - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class NamedAlignmentObject : public NamedObject, public AlignmentData { - public: - /// Default constructor - NamedAlignmentObject(const std::string& nam, const std::string& tit="") - : NamedObject(nam,tit), AlignmentData() {} - /// Default destructor - virtual ~NamedAlignmentObject(); - }; - } /* End namespace Aligments */ } /* End namespace DD4hep */ #endif /* DD4HEP_ALIGMENTS_ALIGNMENTDATA_H */ diff --git a/DDCore/include/DD4hep/AlignmentTools.h b/DDCore/include/DD4hep/AlignmentTools.h index e5e4eebeb..84eb94a9b 100644 --- a/DDCore/include/DD4hep/AlignmentTools.h +++ b/DDCore/include/DD4hep/AlignmentTools.h @@ -25,6 +25,9 @@ namespace DD4hep { namespace AlignmentTools { + /// Copy alignment object from source object + void copy(Alignment from, Alignment to); + /// Compute the ideal/nominal to-world transformation from the detector element placement /** * Note: Detector information of the alignment data is filled by the caller! diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h index db96f00e6..20b39cc63 100644 --- a/DDCore/include/DD4hep/Alignments.h +++ b/DDCore/include/DD4hep/Alignments.h @@ -15,36 +15,47 @@ #define DD4HEP_ALIGMENTS_ALIGNMENTS_H // Framework include files +#include "DD4hep/IOV.h" #include "DD4hep/Volumes.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { + /// Forward declarations class IOV; + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + class UserPool; + /// Conditions internal namespace + namespace Interna { + class ConditionObject; + } + } + /// Namespace for the alignment part of the AIDA detector description toolkit namespace Alignments { using Geometry::LCDD; using Geometry::DetElement; using Geometry::PlacedVolume; - + using Conditions::UserPool; + /// Alignments internal namespace namespace Interna { /// Forward declarations class AlignmentContainer; + class AlignmentNamedObject; + class AlignmentConditionObject; } class AlignmentsManagerObject; class AlignmentsLoader; class AlignmentData; class Alignment; - class UserPool; class Delta; - /// Main handle class to hold a TGeo alignment object of type TGeoPhysicalNode + /// Main handle class to hold an alignment object /** - * See the ROOT documentation about the TGeoPhysicalNode for further details: - * @see http://root.cern.ch/root/html/TGeoPhysicalNode.html * * \author M.Frank * \version 1.0 @@ -55,6 +66,8 @@ namespace DD4hep { public: /// Forward definition of the base data object containing alignment data typedef AlignmentData Object; + /// Forward definition of the base data object containing alignment data + typedef AlignmentData Data; /// Forward definition of the geometry placement typedef Geometry::PlacedVolume PlacedVolume; /// Forward definition of the nodelist leading to the world @@ -68,43 +81,29 @@ namespace DD4hep { public: /// Default constructor - Alignment(); + Alignment() : Handle<Object>() {} /// Default constructor - Alignment(Object* p); - /// Copy constructor - Alignment(const Alignment& c); + Alignment(Object* p) : Handle<Object>(p) {} /// Constructor to be used when reading the already parsed object - template <typename Q> Alignment(const Handle<Q>& e) : Handle<Object>(e) {} + template <typename Q> Alignment(const Handle<Q>& e) : Handle<Object>(e) {} /// Object constructor for pure alignment objects - Alignment(const std::string& name); + template <typename Q=Interna::AlignmentNamedObject> Alignment(const std::string& name); /// Hash code generation from input string static key_type hashCode(const char* value); /// Hash code generation from input string static key_type hashCode(const std::string& value); - /// Assignment operator - Alignment& operator=(const Alignment& c); /// Data accessor for the use of decorators - AlignmentData& alignmentData() { return (*access()); } + Data& data() { return (*access()); } /// Data accessor for the use of decorators - const AlignmentData& alignmentData() const { return (*access()); } + const Data& data() const { return (*access()); } + /// Create cached matrix to transform to world coordinates + const TGeoHMatrix& worldTransformation() const; + /// Access the alignment/placement matrix with respect to the world + const TGeoHMatrix& detectorTransformation() const; }; - /// Default constructor - inline Alignment::Alignment(Object* p) : Handle<Object>(p) {} - - /// Copy constructor - inline Alignment::Alignment(const Alignment& c) : Handle<Object>(c.ptr()) {} - - /// Assignment operator - inline Alignment& Alignment::operator=(const Alignment& c) { - if ( &c != this ) { - m_element = c.ptr(); - } - return *this; - } - /// Hash code generation from input string inline Alignment::key_type Alignment::hashCode(const char* value) { return hash32(value); } @@ -113,6 +112,63 @@ namespace DD4hep { inline Alignment::key_type Alignment::hashCode(const std::string& value) { return hash32(value); } + /// Main handle class to hold an alignment conditions object + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_GEOMETRY + * \ingroup DD4HEP_ALIGN + */ + class AlignmentCondition : public Handle<Interna::AlignmentConditionObject> { + public: + /// Forward definition of the base data object containing alignment data + typedef Interna::AlignmentConditionObject Object; + /// Forward definition of the base data object containing alignment data + typedef AlignmentData Data; + /// Forward definition of the geometry placement + typedef Geometry::PlacedVolume PlacedVolume; + /// Forward definition of the nodelist leading to the world + typedef std::vector<PlacedVolume> NodeList; + /// Forward definition of the alignment delta data + typedef Alignments::Delta Delta; + /// Forward definition of the key type + typedef unsigned int key_type; + /// Forward definition of the iov type + typedef IOV iov_type; + + public: + /// Default constructor + AlignmentCondition() : Handle<Object>() {} + /// Default constructor + AlignmentCondition(Object* p) : Handle<Object>(p) {} + /// Assignment constructor from condition object + AlignmentCondition(Conditions::Interna::ConditionObject* p) : Handle<Object>(p) {} + /// Constructor to be used when reading the already parsed object + template <typename Q> AlignmentCondition(const Handle<Q>& e) : Handle<Object>(e) {} + /// Object constructor for pure alignment objects + template <typename Q=Object> AlignmentCondition(const std::string& name); + + /** Interval of validity */ + /// Access the IOV type + const IOVType& iovType() const; + /// Access the IOV block + const iov_type& iov() const; + + /** Data block (bound type) */ + /// Data accessor for the use of decorators + Data& data(); + /// Data accessor for the use of decorators + const Data& data() const; + /// Create cached matrix to transform to world coordinates + const TGeoHMatrix& worldTransformation() const; + /// Access the alignment/placement matrix with respect to the world + const TGeoHMatrix& detectorTransformation() const; + /// Check if object is already bound.... + bool is_bound() const; + }; + + /// Container class for alignment handles aggregated by a detector element /** * Note: The alignments container is owner by the detector element @@ -131,7 +187,7 @@ namespace DD4hep { typedef Alignment::key_type key_type; /// Forward definition of the iov type typedef Alignment::iov_type iov_type; - + public: /// Default constructor Container(); diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h index 66c4c8d73..fb47115a3 100644 --- a/DDCore/include/DD4hep/ConditionDerived.h +++ b/DDCore/include/DD4hep/ConditionDerived.h @@ -33,7 +33,7 @@ namespace DD4hep { class ConditionDependency; class ConditionUpdateCall; - /// + /// ConditionResolver class used by the derived conditions calculation mechanism /** * \author M.Frank * \version 1.0 @@ -55,6 +55,66 @@ namespace DD4hep { virtual const IOV& requiredValidity() const = 0; }; + /// ConditionUpdateContext class used by the derived conditions calculation mechanism + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + struct ConditionUpdateContext { + const ConditionResolver& resolver; + const ConditionDependency& dependency; + Condition::iov_type* iov; + void* parameter; + /// Initializing constructor + ConditionUpdateContext(const ConditionResolver& r, + const ConditionDependency& d, + void* parameter, + Condition::iov_type& iov); + /// Access to dependency keys + const ConditionKey& key(size_t which) const; + /// Access to condition object by dependency index + Condition condition(size_t which) const; + /// Access to condition object by dependency key + Condition condition(const ConditionKey& key_value) const; + /// Access user parameter + template<typename Q> Q* param() const { + return static_cast<Q*>(parameter); + } + /// Access of other conditions data from the resolver + template<typename T> T& get(const ConditionKey& key_value) { + Condition cond = resolver.get(key_value); + if ( cond.isValid() ) { + T& data = cond.get<T>(); /// Bind data to wanted type + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(cond.iov()); + return data; + } + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name); + } + /// Access of other conditions data from the resolver + template<typename T> const T& get(const ConditionKey& key_value) const { + Condition cond = resolver.get(key_value); + if ( cond.isValid() ) { + const T& data = cond.get<T>(); /// Bind data to wanted type + /// Update result IOV according by and'ing the new iov structure + iov->iov_intersection(cond.iov()); + return data; + } + throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name); + } + /// Access of other conditions data from the resolver + template<typename T> T& get(size_t key_id) { + const ConditionKey& key_value = this->key(key_id); + return this->get<T>(key_value); + } + /// Access of other conditions data from the resolver + template<typename T> const T& get(size_t key_id) const { + const ConditionKey& key_value = this->key(key_id); + return this->get<T>(key_value); + } + }; + /// Callback interface /** * \author M.Frank @@ -63,57 +123,7 @@ namespace DD4hep { */ class ConditionUpdateCall { public: - /** - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - struct Context { - const ConditionResolver& resolver; - const ConditionDependency& dependency; - Condition::iov_type* iov; - - /// Initializing constructor - Context(const ConditionResolver& r, const ConditionDependency& d, Condition::iov_type& iov); - /// Access to dependency keys - const ConditionKey& key(size_t which) const; - /// Access to condition object by dependency index - Condition condition(size_t which) const; - /// Access to condition object by dependency key - Condition condition(const ConditionKey& key_value) const; - /// Access of other conditions data from the resolver - template<typename T> T& get(const ConditionKey& key_value) { - Condition cond = resolver.get(key_value); - if ( cond.isValid() ) { - T& data = cond.get<T>(); /// Bind data to wanted type - /// Update result IOV according by and'ing the new iov structure - iov->iov_intersection(cond.iov()); - return data; - } - throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name); - } - /// Access of other conditions data from the resolver - template<typename T> const T& get(const ConditionKey& key_value) const { - Condition cond = resolver.get(key_value); - if ( cond.isValid() ) { - const T& data = cond.get<T>(); /// Bind data to wanted type - /// Update result IOV according by and'ing the new iov structure - iov->iov_intersection(cond.iov()); - return data; - } - throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name); - } - /// Access of other conditions data from the resolver - template<typename T> T& get(size_t key_id) { - const ConditionKey& key_value = this->key(key_id); - return this->get<T>(key_value); - } - /// Access of other conditions data from the resolver - template<typename T> const T& get(size_t key_id) const { - const ConditionKey& key_value = this->key(key_id); - return this->get<T>(key_value); - } - }; + typedef ConditionUpdateContext Context; protected: /// Reference count int m_refCount; @@ -148,6 +158,9 @@ namespace DD4hep { typedef Geometry::DetElement DetElement; /// Defintion of the depencency container typedef std::vector<ConditionKey> Dependencies; + /// Forward definition of the key type + typedef Condition::key_type key_type; + /// Reference to the target's detector element DetElement detector; /// Key to the condition to be updated @@ -172,10 +185,12 @@ namespace DD4hep { ConditionDependency(const ConditionKey& tar, ConditionUpdateCall* call); /// Default constructor ConditionDependency(); + /// Access the dependency key + key_type key() const { return target.hash; } /// Add use count to the object ConditionDependency* addRef() { ++m_refCount; return this; } /// Release object. May not be used any longer - void release() { if ( --m_refCount <= 0 ) delete this; } + void release() { if ( --m_refCount <= 0 ) delete this; } }; /// Condition dependency builder @@ -202,27 +217,28 @@ namespace DD4hep { }; /// Initializing constructor - inline ConditionUpdateCall::Context::Context(const ConditionResolver& resolv, - const ConditionDependency& dep, - Condition::iov_type& iov_ref) - : resolver(resolv), dependency(dep), iov(&iov_ref) + inline ConditionUpdateContext::ConditionUpdateContext(const ConditionResolver& resolv, + const ConditionDependency& dep, + void* user_param, + Condition::iov_type& iov_ref) + : resolver(resolv), dependency(dep), iov(&iov_ref), parameter(user_param) { } /// Access to dependency keys - inline const ConditionKey& ConditionUpdateCall::Context::key(size_t which) const { + inline const ConditionKey& ConditionUpdateContext::key(size_t which) const { return dependency.dependencies[which]; } /// Access to condition object by dependency key - inline Condition ConditionUpdateCall::Context::condition(const ConditionKey& key_value) const { + inline Condition ConditionUpdateContext::condition(const ConditionKey& key_value) const { Condition c = resolver.get(key_value); if ( c.isValid() ) return c; throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition:"+key_value.name); } /// Access to condition object by dependency index - inline Condition ConditionUpdateCall::Context::condition(size_t which) const { + inline Condition ConditionUpdateContext::condition(size_t which) const { const ConditionKey& key_value = this->key(which); return this->condition(key_value); } diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 9605a5839..7fa8ab3e6 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -61,7 +61,7 @@ namespace DD4hep { * * Note: * Conditions may be shared between several DetElement objects. - * Hence, the back-link to the DetElemetn structure cannot be + * Hence, the back-link to the DetElement structure cannot be * set - it would be ambiguous. * * \author M.Frank @@ -93,7 +93,12 @@ namespace DD4hep { ACTIVE = 1<<0, CHECKED = 1<<2, DERIVED = 1<<3, - USER_FLAGS_FIRST = 1<<10, + TEMPERATURE = 1<<4, + PRESSURE = 1<<5, + ALIGNMENT = 1<<6, + // Keep bit 7-15 for other generic types + // Bit 16-31 is reserved for user classifications + USER_FLAGS_FIRST = 1<<16, USER_FLAGS_LAST = 1<<31 }; @@ -115,9 +120,7 @@ namespace DD4hep { /// Initializing constructor Condition(Object* p); /// Constructor to be used when reading the already parsed object - template <typename Q> Condition(const Handle<Q>& e) - : Handle<Object>(e) { - } + template <typename Q> Condition(const Handle<Q>& e) : Handle<Object>(e) {} /// Initializing constructor for a pure, undecorated conditions object Condition(const std::string& name, const std::string& type); /// Assignment operator @@ -170,6 +173,8 @@ namespace DD4hep { template <typename T> T& get(); /// Generic getter (const version). Specify the exact type, not a polymorph type template <typename T> const T& get() const; + /// Check if object is already bound.... + bool is_bound() const { return isValid() ? data().is_bound() : false; } }; /// Initializing constructor diff --git a/DDCore/include/DD4hep/DetAlign.h b/DDCore/include/DD4hep/DetAlign.h index a07228023..3a3b6ccd7 100644 --- a/DDCore/include/DD4hep/DetAlign.h +++ b/DDCore/include/DD4hep/DetAlign.h @@ -46,6 +46,8 @@ namespace DD4hep { typedef Geometry::DetElementObject Object; /// Definition of the base handle type typedef Handle<Object> RefObject; + /// Pool definition + typedef Conditions::UserPool UserPool; public: diff --git a/DDCore/include/DD4hep/MatrixHelpers.h b/DDCore/include/DD4hep/MatrixHelpers.h index 66abdcfa0..d03d7a738 100644 --- a/DDCore/include/DD4hep/MatrixHelpers.h +++ b/DDCore/include/DD4hep/MatrixHelpers.h @@ -31,25 +31,36 @@ namespace DD4hep { typedef Position XYZAngles; - /// Access the TGeo identity transformation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Access the TGeo identity transformation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoIdentity* identityTransform(); - /// Convert a Position object to a TGeoTranslation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a Position object to a TGeoTranslation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoTranslation* _translation(const Geometry::Position& pos); - /// Convert a RotationZYX object to a TGeoRotation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a RotationZYX object to a TGeoRotation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoRotation* _rotationZYX(const Geometry::RotationZYX& rot); - /// Convert a Rotation3D object to a TGeoRotation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a Rotation3D object to a TGeoRotation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoRotation* _rotation3D(const Geometry::Rotation3D& rot); - /// Convert a Transform3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a Transform3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoHMatrix* _transform(const Geometry::Transform3D& trans); - /// Convert a Position object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a Position object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoHMatrix* _transform(const Geometry::Position& pos); - /// Convert a RotationZYX object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a RotationZYX object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoHMatrix* _transform(const Geometry::RotationZYX& rot); - /// Convert a Rotation3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + /// Convert a Rotation3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoHMatrix* _transform(const Geometry::Rotation3D& rot3D); /// Convert a Position followed by a RotationZYX to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoHMatrix* _transform(const Geometry::Position& pos, const Geometry::RotationZYX& rot); + /// Set a Transform3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + TGeoHMatrix& _transform(TGeoHMatrix& mat, const Geometry::Transform3D& trans); + /// Set a Position object (translation) to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + TGeoHMatrix& _transform(TGeoHMatrix& mat, const Geometry::Position& pos); + /// Set a RotationZYX object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + TGeoHMatrix& _transform(TGeoHMatrix& mat, const Geometry::RotationZYX& rot); + /// Set a Rotation3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + TGeoHMatrix& _transform(TGeoHMatrix& mat, const Geometry::Rotation3D& rot3D); + /// Set a Position followed by a RotationZYX to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY + TGeoHMatrix& _transform(TGeoHMatrix& mat, const Geometry::Position& pos, const Geometry::RotationZYX& rot); + /// Convert a TGeoMatrix object to a generic Transform3D \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY Geometry::Transform3D _transform(const TGeoMatrix* matrix); diff --git a/DDCore/include/DD4hep/objects/AlignmentsInterna.h b/DDCore/include/DD4hep/objects/AlignmentsInterna.h index f13a7afcb..64ec5eb98 100644 --- a/DDCore/include/DD4hep/objects/AlignmentsInterna.h +++ b/DDCore/include/DD4hep/objects/AlignmentsInterna.h @@ -89,12 +89,11 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGNMENTS */ - class AlignmentConditionObject - : public Conditions::Interna::ConditionObject, public AlignmentData + class AlignmentConditionObject : public Conditions::Interna::ConditionObject { public: - // Make the conditions object type local! - typedef Conditions::Interna::ConditionObject ConditionObject; + /// Cached pointer to the bound conditions data, since these may be accessed very frequently + AlignmentData* alignment_data; /// Standard constructor AlignmentConditionObject(const std::string& nam,const std::string& tit=""); /// Standard Destructor @@ -155,6 +154,21 @@ namespace DD4hep { void addKey(const std::string& key_value, const std::string& data_value); }; + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class AlignmentNamedObject : public NamedObject, public AlignmentData { + public: + /// Default constructor + AlignmentNamedObject(const std::string& nam, const std::string& tit="") + : NamedObject(nam,tit), AlignmentData() {} + /// Default destructor + virtual ~AlignmentNamedObject(); + }; + } /* End namespace Interna */ } /* End namespace Alignments */ diff --git a/DDCore/include/XML/UriReader.h b/DDCore/include/XML/UriReader.h index 072c677f5..a54fb33d7 100644 --- a/DDCore/include/XML/UriReader.h +++ b/DDCore/include/XML/UriReader.h @@ -51,6 +51,10 @@ namespace DD4hep { virtual bool load(const std::string& system_id, std::string& data); /// Resolve a given URI to a string containing the data with context virtual bool load(const std::string& system_id, UserContext* context, std::string& data) = 0; + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id, UserContext* ctxt) = 0; }; /// Class supporting to read data given a URI @@ -83,6 +87,10 @@ namespace DD4hep { virtual bool load(const std::string& system_id, std::string& data); /// Resolve a given URI to a string containing the data with context virtual bool load(const std::string& system_id, UserContext* context, std::string& data); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id, UserContext* ctxt); }; } /* End namespace XML */ diff --git a/DDCore/src/AlignmentData.cpp b/DDCore/src/AlignmentData.cpp index 36ed3d958..dc7c1b28d 100644 --- a/DDCore/src/AlignmentData.cpp +++ b/DDCore/src/AlignmentData.cpp @@ -25,13 +25,9 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; -/// Default constructor -Delta::Delta() { -} - /// Copy constructor Delta::Delta(const Delta& c) - : pivot(c.pivot), translation(c.translation), rotation(c.rotation) + : pivot(c.pivot), translation(c.translation), rotation(c.rotation), flags(c.flags) { } @@ -45,12 +41,14 @@ Delta& Delta::operator=(const Delta& c) { pivot = c.pivot; translation = c.translation; rotation = c.rotation; + flags = c.flags; } return *this; } /// Reset information to identity void Delta::clear() { + flags = 0; pivot = Pivot(); translation = Position(); rotation = RotationZYX(); @@ -202,14 +200,6 @@ Alignment AlignmentData::nominal() const { return detector.nominal(); } -/// Default destructor -NamedAlignmentObject::~NamedAlignmentObject() { -} - -#include "DD4hep/Handle.inl" -DD4HEP_INSTANTIATE_HANDLE_NAMED(NamedAlignmentObject); -DD4HEP_INSTANTIATE_HANDLE_UNNAMED(AlignmentData); - #include "DD4hep/ToStream.h" #include "DD4hep/objects/ConditionsInterna.h" DD4HEP_DEFINE_CONDITIONS_TYPE_DUMMY(Delta) diff --git a/DDCore/src/AlignmentTools.cpp b/DDCore/src/AlignmentTools.cpp index 548bbc037..f11bafc09 100644 --- a/DDCore/src/AlignmentTools.cpp +++ b/DDCore/src/AlignmentTools.cpp @@ -30,6 +30,23 @@ using DD4hep::Alignments::AlignmentData; namespace DetectorTools = DD4hep::Geometry::DetectorTools; typedef AlignmentData::MaskManipulator MaskManipulator; +/// Copy alignment object from source object +void DD4hep::Alignments::AlignmentTools::copy(Alignment from, Alignment to) { + Alignment::Object* f = from.ptr(); + Alignment::Object* t = to.ptr(); + if ( t != f ) { + t->flag = f->flag; + t->detectorTrafo = f->detectorTrafo; + t->worldTrafo = f->worldTrafo; + t->trToWorld = f->trToWorld; + t->detector = f->detector; + t->placement = f->placement; + t->nodes = f->nodes; + t->delta = f->delta; + t->magic = f->magic; + } +} + /// Compute the ideal/nominal to-world transformation from the detector element placement void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment) { Alignment::Object* a = alignment.ptr(); @@ -41,11 +58,15 @@ void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment) { for (size_t i = 0, n=path.size(); n>0 && i < n-1; ++i) { const PlacedVolume& p = path[i]; a->detectorTrafo.MultiplyLeft(p->GetMatrix()); + a->nodes.push_back(p); } a->worldTrafo = parent.nominal()->worldTrafo; a->worldTrafo.MultiplyLeft(&a->detectorTrafo); a->trToWorld = Geometry::_transform(&a->worldTrafo); a->placement = a->detector.placement(); + mask.clear(); + mask.set(AlignmentData::HAVE_PARENT_TRAFO); + mask.set(AlignmentData::HAVE_WORLD_TRAFO); mask.set(AlignmentData::IDEAL); } } diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp index 69288f595..0755d9ba6 100644 --- a/DDCore/src/Alignments.cpp +++ b/DDCore/src/Alignments.cpp @@ -15,6 +15,7 @@ // Framework include files #include "DD4hep/AlignmentData.h" #include "DD4hep/objects/AlignmentsInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" // C/C++ include files #include <sstream> @@ -22,13 +23,84 @@ using namespace std; using namespace DD4hep::Alignments; -/// Default constructor -Alignment::Alignment() : Handle<Object>() { + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the alignment part of the AIDA detector description toolkit + namespace Alignments { + + /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject) + template <> Alignment::Alignment<Alignment::Object>(const string& nam) { + assign(new Alignment::Object(), nam, "alignment"); + } + + /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject) + template <> Alignment::Alignment<Interna::AlignmentNamedObject>(const string& nam) { + assign(new Interna::AlignmentNamedObject(nam, "alignment"), nam, "alignment"); + } + + /// Initializing constructor to create a new object (Specialized for AlignmentConditionObject) + template <> AlignmentCondition::AlignmentCondition<AlignmentCondition::Object>(const string& nam) { + assign(new Object(nam, "alignment"), nam, "alignment"); + } + } /* End namespace Aligments */ +} /* End namespace DD4hep */ + + +/// Create cached matrix to transform to world coordinates +const TGeoHMatrix& Alignment::worldTransformation() const { + return data().worldTransformation(); +} + +/// Access the alignment/placement matrix with respect to the world +const TGeoHMatrix& Alignment::detectorTransformation() const { + return data().detectorTransformation(); +} + +/// Access the IOV type +const DD4hep::IOVType& AlignmentCondition::iovType() const { + return *(access()->iovType()); +} + +/// Access the IOV block +const DD4hep::IOV& AlignmentCondition::iov() const { + return *(access()->iovData()); +} + +/// Data accessor for the use of decorators +AlignmentCondition::Data& AlignmentCondition::data() { + Object* o = access(); + if ( o->alignment_data ) + return *(o->alignment_data); + Conditions::Condition c(*this); + o->alignment_data = c.is_bound() ? &c.get<Data>() : &c.bind<Data>(); + return *(o->alignment_data); +} + +/// Data accessor for the use of decorators +const AlignmentCondition::Data& AlignmentCondition::data() const { + Object* o = access(); + if ( o->alignment_data ) + return *(o->alignment_data); + Conditions::Condition c(*this); + o->alignment_data = c.is_bound() ? &c.get<Data>() : &c.bind<Data>(); + return *(o->alignment_data); +} + +/// Check if object is already bound.... +bool AlignmentCondition::is_bound() const { + return isValid() ? ptr()->data.is_bound() : false; +} + +/// Create cached matrix to transform to world coordinates +const TGeoHMatrix& AlignmentCondition::worldTransformation() const { + return data().worldTransformation(); } -/// Initializing constructor to create a new object -Alignment::Alignment(const string& nam) { - m_element = new NamedAlignmentObject(nam, "alignment"); +/// Access the alignment/placement matrix with respect to the world +const TGeoHMatrix& AlignmentCondition::detectorTransformation() const { + return data().detectorTransformation(); } /// Access the number of conditons keys available for this detector element diff --git a/DDCore/src/AlignmentsInterna.cpp b/DDCore/src/AlignmentsInterna.cpp index 8683623f3..70366e0a3 100644 --- a/DDCore/src/AlignmentsInterna.cpp +++ b/DDCore/src/AlignmentsInterna.cpp @@ -27,13 +27,16 @@ using namespace DD4hep::Alignments; using namespace DD4hep::Alignments::Interna; DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentConditionObject); +DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentNamedObject); DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentContainer); +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(AlignmentData); /// Standard constructor AlignmentConditionObject::AlignmentConditionObject(const string& nam, const string& tit) - : ConditionObject(nam, tit), AlignmentData() + : ConditionObject(nam, tit), alignment_data(0) { InstanceCount::increment(this); + flags = Conditions::Condition::ALIGNMENT; } /// Standard Destructor @@ -43,11 +46,13 @@ AlignmentConditionObject::~AlignmentConditionObject() { /// Clear data content on demand. void AlignmentConditionObject::clear() { - trToWorld = Transform3D(); - detectorTrafo.Clear(); - worldTrafo.Clear(); - nodes.clear(); - flags = 0; + AlignmentCondition a(this); + Alignment::Data& d = a.data(); + d.trToWorld = Transform3D(); + d.detectorTrafo.Clear(); + d.worldTrafo.Clear(); + d.nodes.clear(); + flags = Conditions::Condition::ALIGNMENT; } /// Standard constructor @@ -134,3 +139,8 @@ Alignment AlignmentContainer::get(key_type hash_key, const UserPool& pool) { /// Protected destructor AlignmentsLoader::~AlignmentsLoader() { } + +/// Default destructor +AlignmentNamedObject::~AlignmentNamedObject() { +} + diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index ec90438cd..49eb1ee15 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -188,7 +188,10 @@ Alignment DetElement::nominal() const { /// Access to the survey alignment information Alignment DetElement::survey() const { Object* o = access(); - if ( !o->survey.isValid() ) return nominal(); + if ( !o->survey.isValid() ) { + o->survey = Alignment("survey"); + DD4hep::Alignments::AlignmentTools::copy(nominal(), o->survey); + } return o->survey; } diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index a0ce8492b..83fad3846 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -89,6 +89,8 @@ DetElementObject::~DetElementObject() { deletePtr (referenceTrafo); destroyHandle (conditions); conditions = ConditionsContainer(); + destroyHandle (nominal); + destroyHandle (survey); destroyHandle (alignments); alignments = AlignmentsContainer(); placement.clear(); diff --git a/DDCore/src/IOV.cpp b/DDCore/src/IOV.cpp index d2b4504e9..ae14a00e0 100644 --- a/DDCore/src/IOV.cpp +++ b/DDCore/src/IOV.cpp @@ -142,7 +142,7 @@ string IOV::str() const { struct tm time_buff; ::strftime(c_since,sizeof(c_since),"%d-%m-%Y %H:%M:%S",::gmtime_r(&since,&time_buff)); ::strftime(c_until,sizeof(c_until),"%d-%m-%Y %H:%M:%S",::gmtime_r(&until,&time_buff)); - ::snprintf(text,sizeof(text),"%s(%d):[%s-%s]", + ::snprintf(text,sizeof(text),"%s(%d):[%s - %s]", iovType->name.c_str(),iovType->type, c_since, c_until); } diff --git a/DDCore/src/MatrixHelpers.cpp b/DDCore/src/MatrixHelpers.cpp index 64bf2d70d..bd3d18ffa 100644 --- a/DDCore/src/MatrixHelpers.cpp +++ b/DDCore/src/MatrixHelpers.cpp @@ -37,48 +37,70 @@ TGeoRotation* DD4hep::Geometry::_rotation3D(const Rotation3D& rot3D) { return new TGeoRotation("", rot.Phi() * RAD_2_DEGREE, rot.Theta() * RAD_2_DEGREE, rot.Psi() * RAD_2_DEGREE); } -TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos) { - double t[3]; - TGeoHMatrix *tr = new TGeoHMatrix(); - pos.GetCoordinates(t); - tr->SetDx(t[0]); - tr->SetDy(t[1]); - tr->SetDz(t[2]); +/// Set a RotationZYX object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const RotationZYX& rot) { + tr.RotateZ(rot.Phi() * RAD_2_DEGREE); + tr.RotateY(rot.Theta() * RAD_2_DEGREE); + tr.RotateX(rot.Psi() * RAD_2_DEGREE); return tr; } -TGeoHMatrix* DD4hep::Geometry::_transform(const RotationZYX& rot) { - TGeoHMatrix *tr = new TGeoHMatrix(); - tr->RotateZ(rot.Phi() * RAD_2_DEGREE); - tr->RotateY(rot.Theta() * RAD_2_DEGREE); - tr->RotateX(rot.Psi() * RAD_2_DEGREE); +/// Set a Position object (translation) to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Position& pos) { + double t[3]; + pos.GetCoordinates(t); + tr.SetDx(t[0]); + tr.SetDy(t[1]); + tr.SetDz(t[2]); return tr; } -TGeoHMatrix* DD4hep::Geometry::_transform(const Rotation3D& rot) { - TGeoHMatrix *tr = new TGeoHMatrix(); - Double_t* r = tr->GetRotationMatrix(); +/// Set a Rotation3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Rotation3D& rot) { + Double_t* r = tr.GetRotationMatrix(); rot.GetComponents(r); return tr; } -TGeoHMatrix* DD4hep::Geometry::_transform(const Transform3D& trans) { +/// Set a Transform3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Transform3D& trans) { Position pos; RotationZYX rot; trans.GetDecomposition(rot, pos); - return _transform(pos,rot); + return _transform(tr, pos, rot); +} + +/// Set a Position followed by a RotationZYX to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Position& pos, const RotationZYX& rot) { + return _transform(_transform(tr, rot), pos); +} + +/// Convert a Position object to a TGeoTranslation \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos) { + return &_transform(*(new TGeoHMatrix()), pos); } +/// Convert a RotationZYX object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix* DD4hep::Geometry::_transform(const RotationZYX& rot) { + return &_transform(*(new TGeoHMatrix()), rot); +} + +/// Convert a Rotation3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix* DD4hep::Geometry::_transform(const Rotation3D& rot) { + return &_transform(*(new TGeoHMatrix()), rot); +} + +/// Convert a Transform3D object to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY +TGeoHMatrix* DD4hep::Geometry::_transform(const Transform3D& trans) { + return &_transform(*(new TGeoHMatrix()), trans); +} + +/// Convert a Position followed by a RotationZYX to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos, const RotationZYX& rot) { - double t[3]; - TGeoHMatrix *tr = _transform(rot); - pos.GetCoordinates(t); - tr->SetDx(t[0]); - tr->SetDy(t[1]); - tr->SetDz(t[2]); - return tr; + return &_transform(*(new TGeoHMatrix()), pos, rot); } +/// Convert a TGeoMatrix object to a generic Transform3D \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY Transform3D DD4hep::Geometry::_transform(const TGeoMatrix* matrix) { const Double_t* t = matrix->GetTranslation(); if ( matrix->IsRotation() ) { @@ -86,11 +108,6 @@ Transform3D DD4hep::Geometry::_transform(const TGeoMatrix* matrix) { return Transform3D(r[0],r[1],r[2],t[0]*MM_2_CM, r[3],r[4],r[5],t[1]*MM_2_CM, r[6],r[7],r[8],t[2]*MM_2_CM); -#if 0 - return Transform3D(r[0],r[3],r[6],t[0]*MM_2_CM, - r[1],r[4],r[7],t[1]*MM_2_CM, - r[2],r[5],r[8],t[2]*MM_2_CM); -#endif } return Transform3D(0e0,0e0,0e0,t[0]*MM_2_CM, 0e0,0e0,0e0,t[1]*MM_2_CM, diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp index d959d9d8b..901b7d308 100644 --- a/DDCore/src/XML/DocumentHandler.cpp +++ b/DDCore/src/XML/DocumentHandler.cpp @@ -309,9 +309,10 @@ Document DocumentHandler::load(const string& fname, UriReader* reader) const { try { if ( !path.empty() ) { parser->parse(path.c_str()); + if ( reader ) reader->parserLoaded(path); } else { - if ( reader->load(fname, path) ) { + if ( reader && reader->load(fname, path) ) { MemBufInputSource src((const XMLByte*)path.c_str(), path.length(), fname.c_str(), false); parser->parse(src); return (XmlDocument*)parser->adoptDocument(); @@ -323,6 +324,7 @@ Document DocumentHandler::load(const string& fname, UriReader* reader) const { printout(ERROR,"DocumentHandler","+++ Exception(XercesC): parse(path):%s",e.what()); try { parser->parse(fname.c_str()); + if ( reader ) reader->parserLoaded(path); } catch (const exception& ex) { printout(FATAL,"DocumentHandler","+++ Exception(XercesC): parse(URI):%s",ex.what()); diff --git a/DDCore/src/XML/UriReader.cpp b/DDCore/src/XML/UriReader.cpp index e78a8ba4d..5454211cd 100644 --- a/DDCore/src/XML/UriReader.cpp +++ b/DDCore/src/XML/UriReader.cpp @@ -24,6 +24,11 @@ bool DD4hep::XML::UriReader::load(const std::string& system_id, std::string& dat return this->load(system_id, context(), data); } +/// Inform reader about a locally (e.g. by XercesC) handled source load +void DD4hep::XML::UriReader::parserLoaded(const std::string& system_id) { + this->parserLoaded(system_id, context()); +} + /// Default constructor DD4hep::XML::UriContextReader::UriContextReader(UriReader* reader, UriReader::UserContext* ctxt) : m_reader(reader), m_context(ctxt) @@ -49,3 +54,13 @@ bool DD4hep::XML::UriContextReader::load(const std::string& system_id, std::stri bool DD4hep::XML::UriContextReader::load(const std::string& system_id, UserContext* ctxt, std::string& data) { return m_reader->load(system_id, ctxt, data); } + +/// Inform reader about a locally (e.g. by XercesC) handled source load +void DD4hep::XML::UriContextReader::parserLoaded(const std::string& system_id) { + m_reader->parserLoaded(system_id, context()); +} + +/// Inform reader about a locally (e.g. by XercesC) handled source load +void DD4hep::XML::UriContextReader::parserLoaded(const std::string& system_id, UserContext* ctxt) { + m_reader->parserLoaded(system_id, ctxt); +} diff --git a/DDDB/CMakeLists.txt b/DDDB/CMakeLists.txt index bb3905e50..d1632c81d 100644 --- a/DDDB/CMakeLists.txt +++ b/DDDB/CMakeLists.txt @@ -18,9 +18,10 @@ #================================================================================= dd4hep_package( DDDB - USES DDCore DDCond + USES DDCore DDAlign DDCond INCLUDE_DIRS include INSTALL_INCLUDES include/DDDB) #---DDDB plugin library ------------------------------------------------------- -dd4hep_add_plugin ( DDDB SOURCES src/*.cpp ) +dd4hep_add_plugin ( DDDB SOURCES src/*.cpp + USES DDCore DDAlign DDCond ) diff --git a/DDDB/include/DDDB/DDDBConversion.h b/DDDB/include/DDDB/DDDBConversion.h index 6a4298440..ac98f68e7 100644 --- a/DDDB/include/DDDB/DDDBConversion.h +++ b/DDDB/include/DDDB/DDDBConversion.h @@ -47,6 +47,7 @@ namespace DD4hep { using Geometry::Rotation3D; using Geometry::RotationZYX; using Geometry::Transform3D; + using Geometry::Translation3D; using Geometry::Position; using Geometry::LCDD; diff --git a/DDDB/include/DDDB/DDDBReader.h b/DDDB/include/DDDB/DDDBReader.h index c6e7d7815..0acac4be9 100644 --- a/DDDB/include/DDDB/DDDBReader.h +++ b/DDDB/include/DDDB/DDDBReader.h @@ -61,6 +61,10 @@ namespace DD4hep { virtual bool load(const std::string& system_id, std::string& buffer); /// Resolve a given URI to a string containing the data virtual bool load(const std::string& system_id, UserContext* ctxt, std::string& buffer); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id); + /// Inform reader about a locally (e.g. by XercesC) handled source load + virtual void parserLoaded(const std::string& system_id, UserContext* ctxt); /// Read raw XML object from the database / file virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data); diff --git a/DDDB/src/CondDB2DDDB.cpp b/DDDB/src/CondDB2DDDB.cpp index e36196faf..a5f1fa788 100644 --- a/DDDB/src/CondDB2DDDB.cpp +++ b/DDDB/src/CondDB2DDDB.cpp @@ -735,14 +735,21 @@ namespace DD4hep { Position pos; const BasicGrammar& g = BasicGrammar::instance<Position>(); if ( !g.fromString(&pos,d) ) g.invalidConversion(d, g.type()); - if ( nam == "dPosXYZ" ) + if ( nam == "dPosXYZ" ) { a->translation = pos; - else if ( nam == "dRotXYZ" ) + a->flags |= AlignmentDelta::HAVE_TRANSLATION; + } + else if ( nam == "dRotXYZ" ) { a->rotation = RotationZYX(pos.z(),pos.y(),pos.x()); - else if ( nam == "pivotXYZ" ) - a->pivot = pos; - else - printout(ERROR,"AlignmentDelta","++ Unknown alignment conditions tag: %s",nam.c_str()); + a->flags |= AlignmentDelta::HAVE_ROTATION; + } + else if ( nam == "pivotXYZ" ) { + a->pivot = Translation3D(pos.x(),pos.y(),pos.z()); + a->flags |= AlignmentDelta::HAVE_PIVOT; + } + else { + printout(ERROR,"AlignmentDelta","++ Unknown alignment conditions tag: %s",nam.c_str()); + } } /// Specialized conversion of <condition/> entities @@ -1684,6 +1691,7 @@ namespace DD4hep { xml_coll_t(e, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); + // First handle the catalog. It may refer to local conditions! xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); } @@ -1697,8 +1705,9 @@ namespace DD4hep { xml_coll_t(e, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); { Context::PreservedLocals locals(context); - xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); + // First handle the catalog. It may refer to local conditions! xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); } } diff --git a/DDDB/src/DDDBAlignmentTest.cpp b/DDDB/src/DDDBAlignmentTest.cpp index 5be4047c5..0802eda14 100644 --- a/DDDB/src/DDDBAlignmentTest.cpp +++ b/DDDB/src/DDDBAlignmentTest.cpp @@ -24,15 +24,10 @@ #include "DD4hep/Printout.h" #include "DD4hep/Factories.h" #include "DD4hep/ConditionsData.h" -#include "DD4hep/ConditionDerived.h" -#include "DD4hep/Alignments.h" - -#include "DDCond/ConditionsAccess.h" +#include "DD4hep/InstanceCount.h" +#include "DDAlign/AlignmentsManager.h" #include "DDCond/ConditionsManager.h" -#include "DDCond/ConditionsIOVPool.h" #include "DDCond/ConditionsPool.h" -#include "DDCond/ConditionsInterna.h" -#include "DDCond/ConditionsOperators.h" #include "DDDB/DDDBReader.h" #include "DDDB/DDDBConversion.h" @@ -45,60 +40,16 @@ using namespace DD4hep::Conditions; using DDDB::Document; using Geometry::LCDD; using Geometry::DetElement; +using Geometry::Position; +using Geometry::RotationZYX; +using Geometry::Transform3D; +using Geometry::Translation3D; /// Anonymous namespace for plugins namespace { - class AlignmentTypes { - public: - typedef AbstractMap Map; - typedef Map::Params Params; - typedef Params::value_type::second_type Param; - typedef Alignments::AlignmentData Data; - typedef Alignments::Delta Delta; - typedef DDDB::ConditionPrinter _Printer; - }; + using Alignments::AlignmentsManager; - struct UserData; - struct Entry { - UserData* data; - DetElement::Object* det; - DetElement::Object* par; - ConditionDependency* dep; - int det_key, par_key, top; - }; - struct UserData { - struct det_lexical_ordering { - bool operator()(const DetElement& a, const DetElement& b) const { return a.path() == b.path(); } - }; - typedef std::map<DetElement,size_t,det_lexical_ordering> DetectorMap; - typedef std::map<unsigned int,size_t> DetectorKeys; - typedef std::vector<Entry> Entries; - DetectorMap detectors; - DetectorKeys keys; - Entries entries; - }; - struct _Oper : public ConditionsDependencyCollection::Functor { - void operator()(UserData& data, const Dependencies::value_type& e) const { - const Dependency* dep = e.second.get(); - DetElement det = dep->detector; - if ( det.isValid() ) { - Entry entry; - unsigned int key = det.key(); - entry.data = &data; - entry.top = 0; - entry.dep = e.second.get(); - entry.det = det.ptr(); - entry.par = det.parent().ptr(); - entry.det_key = key; - entry.par_key = det.parent().key(); - data.detectors.insert(make_pair(det,data.entries.size())); - data.keys.insert(make_pair(key,data.entries.size())); - data.entries.insert(data.entries.end(),entry); - } - } - }; - /// Specialized conditions update callback for alignments /** * Used by clients to update a condition. @@ -107,55 +58,42 @@ namespace { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - class AlignmentUpdate : public ConditionUpdateCall, public AlignmentTypes { + class AlignmentUpdate : public ConditionUpdateCall { + typedef AbstractMap::Params::value_type::second_type Param; + typedef Alignments::AlignmentData Data; public: - AlignmentUpdate() { } + AlignmentUpdate() { } virtual ~AlignmentUpdate() { } /// Interface to client Callback in order to update the condition virtual Condition operator()(const ConditionKey& key, const Context& context) { - Condition target(key.name,"Alignment"); - Data& data = target.bind<Data>(); - Condition cond0 = context.condition(0); - const Map& src0 = cond0.get<Map>(); - const Param& par0 = src0.firstParam().second; - DetElement det0 = context.dependency.detector; - printout(INFO,"AlignmentUpdate","++ Building dependent condition: %s Detector [%d]: %s ", - key.name.c_str(), det0.level(), det0.path().c_str()); - if ( par0.typeInfo() == typeid(Delta) ) { - const Delta& delta = src0.first<Delta>(); - data.delta = delta; - data.flag = Data::HAVE_NONE; + Alignments::AlignmentCondition target(key.name); + Data& data = target.data(); + Condition cond = context.condition(0); + AbstractMap& src = cond.get<AbstractMap>(); + const Param& par = src.firstParam().second; + DetElement det = context.dependency.detector; + printout(DEBUG,"AlignmentUpdate","++ Building dependent condition: %s Detector [%d]: %s ", + key.name.c_str(), det.level(), det.path().c_str()); + if ( par.typeInfo() == typeid(Data::Delta) ) { + const Data::Delta& delta = src.first<Data::Delta>(); + data.delta = delta; + data.flag = Data::HAVE_NONE; } else { printout(INFO,"AlignmentUpdate","++ Failed to access alignment-Delta from %s", - cond0->value.c_str()); - _Printer()(cond0); + cond->value.c_str()); + DDDB::ConditionPrinter()(cond); } - data.detector = context.dependency.detector; - //data.condition = target; + data.detector = det; + AlignmentsManager::newEntry(context, det, &context.dependency, target); + // A callback returning no condition is illegal! + // Need to crosscheck though if the alignment IOV interval of parents may be + // smaller then the daughter IOV interval. + // I though expect, that this is a purely academic case. return target; } }; - void __print(DetElement det, - UserData& data, - int level) - { - char fmt[128]; - auto i=data.keys.find(det.key()); - const char* has_alignment = i==data.keys.end() ? "NO " : "YES"; - size_t siz = i==data.keys.end() ? 0 : 1; - ::snprintf(fmt,sizeof(fmt),"%%d %%%ds %%p [%%d] %%s %%08X: %%s ",2*level); - printout(INFO,"Conditions",fmt, - det.level(), "", det.ptr(), siz, has_alignment, - det.key(), det.path().c_str()); - const DetElement::Children& children = det.children(); - for(auto c=children.begin(); c!=children.end(); ++c) { - DetElement child = (*c).second; - __print(child, data, level+1); - } - } - /// DDDB Conditions analyser to select alignments. /** * \author M.Frank @@ -166,153 +104,102 @@ namespace { class AlignmentSelector { public: typedef ConditionsManager::Dependencies Dependencies; + LCDD& lcdd; + AlignmentUpdate* updateCall; + long int time; string m_name; - RangeConditions m_allConditions; - Dependencies m_allDependencies; - ConditionsManager m_manager; - struct Counters { - size_t numAlignments; - size_t numNoCatalogs; - void reset() { numAlignments=numNoCatalogs=0; } - } m_counters; /// Initializing constructor - AlignmentSelector(ConditionsAccess mgr) : m_manager(mgr) { - Operators::collectAllConditions(mgr, m_allConditions); + AlignmentSelector(LCDD& l, long t) : lcdd(l), time(t), m_name("Selector") { + // The alignment update call can be re-used over and over. It has not state. + updateCall = new AlignmentUpdate(); } - + /// Default destructor virtual ~AlignmentSelector() { - m_allDependencies.clear(); - } - - void addDependency(ConditionDependency* dependency) { - m_allDependencies.insert(dependency->target.hash, dependency); - } - - RangeConditions findCond(const string& match) { - RangeConditions result; - if ( !match.empty() ) { - for(RangeConditions::iterator ic=m_allConditions.begin(); ic!=m_allConditions.end(); ++ic) { - Condition cond = (*ic); - size_t idx = cond->value.find(match); - if ( idx == 0 ) { - if (cond->value.length() == match.length() ) { - result.push_back(cond); - } - else if ( cond->value[match.length()] == '/' ) { - size_t idq = cond->value.find('/',match.length()+1); - if ( idq == string::npos ) { - result.push_back(cond); - } - } - } - } - } - return result; + releasePtr(updateCall); } - - AlignmentUpdate* m_update; - long collectDependencies(DetElement de, AlignmentUpdate* update, int level) { - char fmt[64], text[256]; - DDDB::Catalog* cat = 0; - DDDB::ConditionPrinter prt; - const DetElement::Children& c = de.children(); - - ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5); - ::snprintf(text,sizeof(text),fmt,""); - prt.setPrefix(text); - + /// Recursive alignment collector + long collect(DetElement de, dd4hep_ptr<UserPool>& user_pool, AlignmentsManager& am, int level) { + char fmt[64]; try { - ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1); - printout(INFO,m_name,fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID()); - cat = de.extension<DDDB::Catalog>(); - ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3); + DDDB::Catalog* cat = de.extension<DDDB::Catalog>(); if ( !cat->condition.empty() ) { - RangeConditions rc = findCond(cat->condition); - printout(INFO,m_name,fmt,"","Alignment: ", - rc.empty() ? (cat->condition+" !!!UNRESOLVED!!!").c_str() : cat->condition.c_str()); - if ( !rc.empty() ) { - ConditionKey target1(cat->condition+"/derived_1"); - DependencyBuilder build_1(target1, update->addRef()); - build_1->detector = de; - for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic) { - Condition cond = *ic; - ConditionKey key(cond->value); - build_1.add(key); - } - addDependency(build_1.release()); + ConditionKey key(cat->condition); + Condition cond = user_pool->get(key.hash); + if ( cond.isValid() ) { + DependencyBuilder b(ConditionKey(cat->condition+"/Tranformations"), updateCall->addRef()); + b->detector = de; + b.add(ConditionKey(cond->value)); + am.adoptDependency(b.release()); + } + else { + ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3); + printout(INFO,m_name,fmt,"","Alignment: ", + !cond.isValid() ? (cat->condition+" !!!UNRESOLVED!!!").c_str() : cat->condition.c_str()); } - ++m_counters.numAlignments; } } catch(...) { ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3); printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", ""); - ++m_counters.numNoCatalogs; } + const DetElement::Children& c = de.children(); for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) - collectDependencies((*i).second, update, level+1); + collect((*i).second, user_pool, am, level+1); return 1; } - - int computeDependencies(long time) { - dd4hep_ptr<UserPool> user_pool; - const Dependencies& dependencies = m_allDependencies; - const IOVType* iovType = m_manager.iovType("epoch"); + /// Initial collector call + long collect(ConditionsManager manager, AlignmentsManager& context) { + const IOVType* iovType = manager.iovType("epoch"); IOV iov(iovType, IOV::Key(time,time)); - long num_expired = m_manager.prepare(iov, user_pool, dependencies); - printout(INFO,"Conditions", - "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s", - num_expired, iov.str().c_str()); - - UserData data; - data.entries.reserve(dependencies.size()); - dependencies.for_each(DependencyCollector<UserData,_Oper>(data,_Oper())); - - string prev("-----"); - for(auto i=data.detectors.begin(); i!=data.detectors.end(); ++i) { - Entry& e = data.entries[(*i).second]; - DetElement det = e.det; - unsigned int key = det.key(); - const string& p = det.path(); - size_t idx = p.find(prev); - if ( idx == 0 ) { - //printout(INFO,"Conditions","***** %d %p %08X: %s ", - // det.level(), det.ptr(), key, det.path().c_str()); - continue; - } - prev = p; - printout(INFO,"Conditions","%d %p %08X: %s ", - det.level(), det.ptr(), key, det.path().c_str()); - e.top = 1; - } - - printout(INFO,"Conditions","Working down the tree...."); - for(auto i=data.detectors.begin(); i != data.detectors.end(); ++i) { - Entry& e = data.entries[(*i).second]; - if ( e.top ) { - DetElement det = e.det; - printout(INFO,"Conditions","%d %p %08X: %s ", - det.level(), det.ptr(), det.key(), det.path().c_str()); - __print(det, data, 0); + dd4hep_ptr<UserPool> user_pool; + manager.prepare(iov, user_pool); + return collect(lcdd.world(), user_pool, context, 0); + } + + int computeDependencies(ConditionsManager manager, AlignmentsManager& am) { + const IOVType* iovType = manager.iovType("epoch"); + for(int i=0; i<10; ++i) { { + int t = time + i*3600; + IOV iov(iovType, IOV::Key(t,t)); + dd4hep_ptr<UserPool> user_pool; + long num_expired = manager.prepare(iov, user_pool); + printout(INFO,"Conditions", + "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s", + num_expired, iov.str().c_str()); + am.compute(user_pool); + user_pool->clear(); } + DD4hep::InstanceCount::dump(); } - user_pool->clear(); return 1; } }; /// Plugin function long dddb_derived_alignments(LCDD& lcdd, int argc, char** argv) { - long int long init_time = argc>0 ? *(long*)argv[0] : 0;//DDDB::DDDBReader::makeTime(2016,4,1,12); - ConditionsManager manager = ConditionsManager::from(lcdd); - AlignmentSelector selector(manager); - AlignmentUpdate* update = new AlignmentUpdate(); - int ret = selector.collectDependencies(lcdd.world(), update, 0); - if ( ret == 1 ) { - ret = selector.computeDependencies(init_time); + long int long init_time = DDDB::DDDBReader::makeTime(2016,4,1,12); + if ( argc>0 ) { + struct tm tm; + char* c = ::strptime(argv[0],"%d-%m-%Y %H:%M:%S",&tm); + if ( 0 == c ) { + except("DerivedAlignmentsTest","Invalid time format given for update:%s " + " should be: %d-%m-%Y %H:%M:%S", argv[0]); + } + } + AlignmentSelector selector(lcdd, init_time); + AlignmentsManager alig_manager("Test"); + ConditionsManager cond_manager(ConditionsManager::from(lcdd)); + int ret = 0; + try { + ret = selector.collect(cond_manager,alig_manager); + if ( ret == 1 ) { + ret = selector.computeDependencies(cond_manager,alig_manager); + } + } + catch(...) { } - delete update; + alig_manager.destroy(); return ret; } } /* End anonymous namespace */ diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/DDDBConditionsLoader.cpp index b06f5d1d7..409e2c662 100644 --- a/DDDB/src/DDDBConditionsLoader.cpp +++ b/DDDB/src/DDDBConditionsLoader.cpp @@ -206,8 +206,10 @@ size_t DDDBConditionsLoader::update(const iov_type& req_validity, Condition::Object* c = (*i).ptr(); size_t idx = c->address.find('#'); string url = (idx == string::npos) ? c->address : c->address.substr(0,idx); +#if 0 printout(INFO,"DDDB","++ Need to update: %-40s [%08X] --> %s", c->name.c_str(), c->hash, url.c_str()); +#endif urls.insert(make_pair(url,c)); } /// Now load them. In the callbacks we can check if we got all required conditions diff --git a/DDDB/src/DDDBDerivedCondTest.cpp b/DDDB/src/DDDBDerivedCondTest.cpp index 2047ded71..13c518ad9 100644 --- a/DDDB/src/DDDBDerivedCondTest.cpp +++ b/DDDB/src/DDDBDerivedCondTest.cpp @@ -199,10 +199,6 @@ namespace { m_allDependencies.clear(); } - void addDependency(ConditionDependency* dependency) { - m_allDependencies.insert(dependency->target.hash, dependency); - } - RangeConditions findCond(const string& match) { RangeConditions result; if ( !match.empty() ) { @@ -266,9 +262,9 @@ namespace { build_3.add(target1); build_3.add(target2); } - addDependency(build_1.release()); - addDependency(build_2.release()); - addDependency(build_3.release()); + m_allDependencies.insert(build_1.release()); + m_allDependencies.insert(build_2.release()); + m_allDependencies.insert(build_3.release()); } ++m_counters.numAlignments; } diff --git a/DDDB/src/DDDBFileReader.cpp b/DDDB/src/DDDBFileReader.cpp index 847a348e5..db99db44b 100644 --- a/DDDB/src/DDDBFileReader.cpp +++ b/DDDB/src/DDDBFileReader.cpp @@ -42,6 +42,10 @@ namespace DD4hep { virtual ~DDDBFileReader() {} /// Read raw XML object from the database / file virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data); + /// Resolve a given URI to a string containing the data + virtual bool load(const std::string& system_id, std::string& buffer); + /// Resolve a given URI to a string containing the data + virtual bool load(const std::string& system_id, UserContext* ctxt, std::string& buffer); }; } /* End namespace DDDB */ @@ -85,6 +89,25 @@ int DD4hep::DDDB::DDDBFileReader::getObject(const std::string& system_id, return 0; } +/// Resolve a given URI to a string containing the data +bool DD4hep::DDDB::DDDBFileReader::load(const std::string& system_id, std::string& buffer) { + return XML::UriReader::load(system_id, buffer); +} + +/// Resolve a given URI to a string containing the data +bool DD4hep::DDDB::DDDBFileReader::load(const std::string& system_id, + UserContext* ctxt, + std::string& buffer) +{ + bool result = DDDBReader::load(system_id, ctxt, buffer); + if ( result ) { + DDDBReaderContext* context = (DDDBReaderContext*)ctxt; + context->valid_since = context->event_time; + context->valid_until = context->event_time; + } + return result; +} + namespace { void* create_dddb_xml_file_reader(const char* /* arg */) { return new DD4hep::DDDB::DDDBFileReader(); diff --git a/DDDB/src/DDDBReader.cpp b/DDDB/src/DDDBReader.cpp index 251b38b07..58077de48 100644 --- a/DDDB/src/DDDBReader.cpp +++ b/DDDB/src/DDDBReader.cpp @@ -21,9 +21,6 @@ // Framework includes #include "DDDB/DDDBReader.h" #include "DD4hep/Printout.h" -//#include "DD4hep/LCDD.h" -//#include "XML/DocumentHandler.h" -//#include "XML/XMLElements.h" // C/C++ include files #include <ctime> @@ -48,12 +45,13 @@ long long int DDDBReader::makeTime(int year, int month, int day, { struct tm tm_init; ::memset(&tm_init,0,sizeof(tm_init)); - tm_init.tm_year = year; - tm_init.tm_mon = month; - tm_init.tm_mday = day; - tm_init.tm_hour = hour; - tm_init.tm_min = minutes; - tm_init.tm_sec = seconds; + tm_init.tm_year = year > 1900 ? year-1900 : year; + tm_init.tm_mon = month; + tm_init.tm_mday = day; + tm_init.tm_hour = hour; + tm_init.tm_min = minutes; + tm_init.tm_sec = seconds; + tm_init.tm_isdst = -1; return ::mktime(&tm_init); } @@ -88,6 +86,18 @@ bool DDDBReader::load(const string& system_id, return false; } +/// Inform reader about a locally (e.g. by XercesC) handled source load +void DDDBReader::parserLoaded(const std::string& system_id) { + return XML::UriReader::parserLoaded(system_id); +} + +/// Inform reader about a locally (e.g. by XercesC) handled source load +void DDDBReader::parserLoaded(const std::string& system_id, UserContext* ctxt) { + DDDBReaderContext* context = (DDDBReaderContext*)ctxt; + context->valid_since = context->event_time; + context->valid_until = context->event_time; +} + int DDDBReader::getObject(const string& sys_id, UserContext* /* ctxt */, string& /* out */) { except("DDDBReader","DDDBReader::getObject is a virtual method, " diff --git a/cmake/run_test_package.sh b/cmake/run_test_package.sh index e730b666e..10b7e06c1 100755 --- a/cmake/run_test_package.sh +++ b/cmake/run_test_package.sh @@ -5,10 +5,16 @@ # calls the command (given as first argument) # with all following arguments # - +if [ ! ${DD4hep_DIR} ]; then + export DD4hep_DIR=@DD4hep_DIR@; +fi; +# +source ${DD4hep_DIR}/bin/thisdd4hep.sh; +dd4hep_parse_this ${BASH_ARGV[0]} @PackageName@; +# #----- initialize environment for this package - including DD4hep -source @CMAKE_INSTALL_PREFIX@/bin/this@PackageName@.sh - +source ${THIS}/bin/this@PackageName@.sh +# #----- parse command line - first argument is the # test to run command=$1 diff --git a/examples/DDDB/CMakeLists.txt b/examples/DDDB/CMakeLists.txt index 42b64f781..a986586bd 100644 --- a/examples/DDDB/CMakeLists.txt +++ b/examples/DDDB/CMakeLists.txt @@ -120,6 +120,16 @@ if (DD4HEP_USE_XERCESC) -config DD4hep_ConditionsManagerInstaller -exec DDDB_DerivedCondTest REGEX_PASS "Building dependent condition: /dd/Conditions/Alignment/TT/TTbVLayerR1Module3B/derived_3" ) + + # + #---Testing: Load the geometry + conditions + run basic derived alignments test + dd4hep_add_test_reg( test_DDDB_derived_alignments + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh" + EXEC_ARGS ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh + -config DD4hep_ConditionsManagerInstaller + -exec DDDB_DerivedAlignmentsTest + REGEX_PASS "| 24950| 24950| 0|DD4hep::Alignments::Interna::AlignmentConditionObject" ) + # #---Testing: Extract DDDB data from zip archive ------------------------------- dd4hep_add_test_reg( test_DDDB_clean @@ -127,5 +137,4 @@ if (DD4HEP_USE_XERCESC) EXEC_ARGS ${CMAKE_INSTALL_PREFIX}/bin/extract_dddb.sh -clean REGEX_PASS "DDDB Database successfully removed" ) - endif() diff --git a/examples/DDDB/scripts/run_dddb.sh b/examples/DDDB/scripts/run_dddb.sh index cf4779488..d58fbd171 100755 --- a/examples/DDDB/scripts/run_dddb.sh +++ b/examples/DDDB/scripts/run_dddb.sh @@ -83,4 +83,8 @@ done; export DD4HEP_TRACE=ON; ARGS=`echo -plugin DDDB_Executor ${loader} ${params} ${input} ${config} ${exec} ${vis}`; echo "Command: ${debug} `which geoPluginRun` -destroy $ARGS"; -${debug} `which geoPluginRun` -destroy ${ARGS}; +if test -z "${debug}";then + exec `which geoPluginRun` -destroy ${ARGS}; +else + ${debug} `which geoPluginRun` -destroy ${ARGS}; +fi; -- GitLab