diff --git a/DDAlign/include/DDAlign/AlignmentsForward.h b/DDAlign/include/DDAlign/AlignmentsForward.h index 7782d49a74fa99f561a8e58d114bdfb4363ead58..892293987dcbb776a57797b70ba9fcd2a12355c6 100644 --- a/DDAlign/include/DDAlign/AlignmentsForward.h +++ b/DDAlign/include/DDAlign/AlignmentsForward.h @@ -27,7 +27,7 @@ namespace DD4hep { namespace Alignments { // Forward declarations - class AlignmentUpdateCall; + class AlignmentsUpdateCall; /// Create alignment dependencies for child elements if a parent has re-alignments /** @@ -52,7 +52,7 @@ namespace DD4hep { /// Reference to the alignment manager object AlignmentsManager alignmentMgr; /// The callback to be registered for the update mechanism - AlignmentUpdateCall* updateCall; + AlignmentsUpdateCall* updateCall; /// Conditions pool used to access the basic conditions object Conditions::UserPool* user_pool; /// Extension property to construct the name of the alignment condition @@ -65,7 +65,7 @@ namespace DD4hep { PrintLevel printLevel; /// Initializing constructor - AlignmentsForward(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p); + AlignmentsForward(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p); /// Default destructor virtual ~AlignmentsForward(); /// Callback to output conditions information diff --git a/DDAlign/include/DDAlign/AlignmentsRegister.h b/DDAlign/include/DDAlign/AlignmentsRegister.h index 401d5e4b5330095b036394e60a24dd532e0e9bd2..51046caf9cb431e58100a389c10e13f25dff05e5 100644 --- a/DDAlign/include/DDAlign/AlignmentsRegister.h +++ b/DDAlign/include/DDAlign/AlignmentsRegister.h @@ -27,7 +27,7 @@ namespace DD4hep { namespace Alignments { // Forward declarations - class AlignmentUpdateCall; + class AlignmentsUpdateCall; /// Create lignment dependencies from conditions /** @@ -65,7 +65,7 @@ namespace DD4hep { /// Reference to the alignment manager object AlignmentsManager alignmentMgr; /// The callback to be registered for the update mechanism - AlignmentUpdateCall* updateCall; + AlignmentsUpdateCall* updateCall; /// Conditions pool used to access the basic conditions object Conditions::UserPool* user_pool; /// Extension property to construct the name of the alignment condition @@ -78,7 +78,7 @@ namespace DD4hep { PrintLevel printLevel; /// Initializing constructor - AlignmentsRegister(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p); + AlignmentsRegister(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p); /// Default destructor virtual ~AlignmentsRegister(); /// Callback to output conditions information diff --git a/DDAlign/include/DDAlign/AlignmentUpdateCall.h b/DDAlign/include/DDAlign/AlignmentsUpdateCall.h similarity index 96% rename from DDAlign/include/DDAlign/AlignmentUpdateCall.h rename to DDAlign/include/DDAlign/AlignmentsUpdateCall.h index 8f5bae5da42d999fed69e743f4e4ff7b77c96671..f0bed54e58f8141dddf4bb4907a577848c1cffd7 100644 --- a/DDAlign/include/DDAlign/AlignmentUpdateCall.h +++ b/DDAlign/include/DDAlign/AlignmentsUpdateCall.h @@ -43,7 +43,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - class AlignmentUpdateCall : public Conditions::ConditionUpdateCall { + class AlignmentsUpdateCall : public Conditions::ConditionUpdateCall { public: typedef Conditions::Condition Condition; typedef Conditions::ConditionKey ConditionKey; @@ -56,10 +56,10 @@ namespace DD4hep { public: /// Default constructor - AlignmentUpdateCall(); + AlignmentsUpdateCall(); /// Default destructor - virtual ~AlignmentUpdateCall(); + virtual ~AlignmentsUpdateCall(); /// Interface to client Callback in order to update the condition. To be overloaded by sub-class virtual Condition operator()(const ConditionKey& key, const UpdateContext& context) = 0; diff --git a/DDAlign/include/DDAlign/DDAlignForwardCall.h b/DDAlign/include/DDAlign/DDAlignForwardCall.h index ab95f1e4fe17f2a5127165f2f1c17ac01b3421e5..1440d77484ffdb785c245d3e1dc7f549ccfae219 100644 --- a/DDAlign/include/DDAlign/DDAlignForwardCall.h +++ b/DDAlign/include/DDAlign/DDAlignForwardCall.h @@ -14,7 +14,7 @@ #define DD4HEP_DDALIGN_DDALIGNFORWARDCALL_H // Framework includes -#include "DDAlign/AlignmentUpdateCall.h" +#include "DDAlign/AlignmentsUpdateCall.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -29,7 +29,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGNMENT */ - class DDAlignForwardCall : public AlignmentUpdateCall { + class DDAlignForwardCall : public AlignmentsUpdateCall { public: /// Default constructor DDAlignForwardCall() = default; diff --git a/DDAlign/include/DDAlign/DDAlignUpdateCall.h b/DDAlign/include/DDAlign/DDAlignUpdateCall.h index 37bdddad6292f278b7274009bbb7204da0430665..3aa72b2c0d273a3915eb501114bd6e3794b50d6a 100644 --- a/DDAlign/include/DDAlign/DDAlignUpdateCall.h +++ b/DDAlign/include/DDAlign/DDAlignUpdateCall.h @@ -14,7 +14,7 @@ #define DD4HEP_DDALIGN_DDALIGNUPDATECALL_H // Framework includes -#include "DDAlign/AlignmentUpdateCall.h" +#include "DDAlign/AlignmentsUpdateCall.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -29,7 +29,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGNMENT */ - class DDAlignUpdateCall : public AlignmentUpdateCall { + class DDAlignUpdateCall : public AlignmentsUpdateCall { public: /// Default constructor DDAlignUpdateCall() = default; diff --git a/DDAlign/include/DDAlign/GlobalAlignmentCache.h b/DDAlign/include/DDAlign/GlobalAlignmentCache.h index 17e3471c00b7b7ff6ce3c0cb7a8d800bc6c5588b..104c27c17497b83460fbe8a994247af9e06fad59 100644 --- a/DDAlign/include/DDAlign/GlobalAlignmentCache.h +++ b/DDAlign/include/DDAlign/GlobalAlignmentCache.h @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -16,7 +15,7 @@ // Framework include files #include "DD4hep/GlobalAlignment.h" -#include "DDAlign/AlignmentStack.h" +#include "DDAlign/GlobalAlignmentStack.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -25,9 +24,9 @@ namespace DD4hep { namespace Alignments { /// Forward declarations - class AlignmentOperator; + class GlobalAlignmentOperator; class GlobalAlignmentCache; - class AlignmentStack; + class GlobalAlignmentStack; /// Class caching all known alignment operations for one LCDD instance. /** @@ -40,12 +39,12 @@ namespace DD4hep { */ class GlobalAlignmentCache { friend class LCDD; - friend class AlignmentOperator; + friend class GlobalAlignmentOperator; public: - typedef AlignmentStack Stack; - typedef AlignmentStack::StackEntry Entry; - typedef std::map<unsigned int, TGeoPhysicalNode*> Cache; + typedef GlobalAlignmentStack Stack; + typedef Stack::StackEntry Entry; + typedef std::map<unsigned int, TGeoPhysicalNode*> Cache; typedef std::map<std::string,GlobalAlignmentCache*> SubdetectorAlignments; protected: @@ -74,7 +73,7 @@ namespace DD4hep { GlobalAlignmentCache* subdetectorAlignments(const std::string& name); /// Population entry: Apply a complete stack of ordered alignments to the geometry structure - void apply(AlignmentStack& stack); + void apply(GlobalAlignmentStack& stack); /// Apply a vector of SD entries of ordered alignments to the geometry structure void apply(const std::vector<Entry*> &changes); /// Add a new entry to the cache. The key is the placement path @@ -92,7 +91,7 @@ namespace DD4hep { /// Access the section name const std::string& name() const { return m_sdPath; } /// Close existing transaction stack and apply all alignments - void commit(AlignmentStack& stack); + void commit(GlobalAlignmentStack& stack); /// Retrieve the cache section corresponding to the path of an entry. GlobalAlignmentCache* section(const std::string& path_name) const; /// Retrieve an alignment entry by its lacement path diff --git a/DDAlign/include/DDAlign/AlignmentOperators.h b/DDAlign/include/DDAlign/GlobalAlignmentOperators.h similarity index 56% rename from DDAlign/include/DDAlign/AlignmentOperators.h rename to DDAlign/include/DDAlign/GlobalAlignmentOperators.h index ea4b9f817fc6972c5c2891e357e9a63719843fec..a2b0a60bc92369295ce566033b9aa105481e666b 100644 --- a/DDAlign/include/DDAlign/AlignmentOperators.h +++ b/DDAlign/include/DDAlign/GlobalAlignmentOperators.h @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -11,8 +10,8 @@ // Author : M.Frank // //========================================================================== -#ifndef DD4HEP_ALIGNMENT_ALIGNMENTOPERATORS_H -#define DD4HEP_ALIGNMENT_ALIGNMENTOPERATORS_H +#ifndef DD4HEP_ALIGNMENT_GLOBALALIGNMENTOPERATORS_H +#define DD4HEP_ALIGNMENT_GLOBALALIGNMENTOPERATORS_H // Framework include files #include "DD4hep/Alignments.h" @@ -31,17 +30,18 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGN */ - class AlignmentOperator { + class GlobalAlignmentOperator { public: - typedef AlignmentStack::StackEntry Entry; - typedef GlobalAlignmentCache::Cache Cache; - typedef std::vector<Entry*> Entries; + typedef GlobalAlignmentStack::StackEntry Entry; + typedef GlobalAlignmentCache::Cache Cache; + typedef std::vector<Entry*> Entries; typedef std::map<std::string,std::pair<TGeoPhysicalNode*,Entry*> > Nodes; GlobalAlignmentCache& cache; Nodes& nodes; + public: /// Initializing functor constructor - AlignmentOperator(GlobalAlignmentCache& c, Nodes& n) : cache(c), nodes(n) {} + GlobalAlignmentOperator(GlobalAlignmentCache& c, Nodes& n) : cache(c), nodes(n) {} /// Insert alignment entry void insert(GlobalAlignment alignment) const; }; @@ -52,12 +52,18 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGN */ - class AlignmentSelector : public AlignmentOperator { + class GlobalAlignmentSelector : public GlobalAlignmentOperator { public: const Entries& entries; /// Initializing functor constructor - AlignmentSelector(GlobalAlignmentCache& c, Nodes& n, const Entries& e) : AlignmentOperator(c,n), entries(e) {} - const AlignmentSelector& reset() const { nodes.clear(); return *this; } + GlobalAlignmentSelector(GlobalAlignmentCache& c, Nodes& n, const Entries& e) + : GlobalAlignmentOperator(c,n), entries(e) + { + } + const GlobalAlignmentSelector& reset() const { + nodes.clear(); + return *this; + } /// Function callback for cache entries void operator()(const GlobalAlignmentCache::Cache::value_type& e) const; /// Function callback for entries @@ -70,11 +76,16 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGN */ - template <typename T> class AlignmentActor : public AlignmentOperator { + template <typename T> class GlobalAlignmentActor : public GlobalAlignmentOperator { public: /// Initializing functor constructor - AlignmentActor(GlobalAlignmentCache& c, Nodes& n) : AlignmentOperator(c,n) { init(); } - void init() {} + GlobalAlignmentActor(GlobalAlignmentCache& c, Nodes& n) + : GlobalAlignmentOperator(c,n) + { + init(); + } + void init() { + } /// Function callback for entries void operator()(Nodes::value_type& e) const; }; @@ -88,11 +99,11 @@ namespace DD4hep { } // Specializations - template <> void AlignmentActor<DDAlign_standard_operations::node_print>::init(); - template <> void AlignmentActor<DDAlign_standard_operations::node_print>::operator() (Nodes::value_type& n) const; - template <> void AlignmentActor<DDAlign_standard_operations::node_delete>::operator()(Nodes::value_type& n) const; - template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operator() (Nodes::value_type& n) const; - template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operator() (Nodes::value_type& n) const; - } /* End namespace Alignments */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_ALIGNMENT_ALIGNMENTOPERATORS_H */ + template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_print>::init(); + template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_print>::operator() (Nodes::value_type& n) const; + template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_delete>::operator()(Nodes::value_type& n) const; + template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_reset>::operator() (Nodes::value_type& n) const; + template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_align>::operator() (Nodes::value_type& n) const; + } /* End namespace Alignments */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_ALIGNMENT_GLOBALALIGNMENTOPERATORS_H */ diff --git a/DDAlign/include/DDAlign/AlignmentStack.h b/DDAlign/include/DDAlign/GlobalAlignmentStack.h similarity index 91% rename from DDAlign/include/DDAlign/AlignmentStack.h rename to DDAlign/include/DDAlign/GlobalAlignmentStack.h index 95b7e345043100ebbc7d41a209b6e93769fb69fc..b55a7225134356f1f2a53a88efd22ff0e7d4a29d 100644 --- a/DDAlign/include/DDAlign/AlignmentStack.h +++ b/DDAlign/include/DDAlign/GlobalAlignmentStack.h @@ -10,8 +10,8 @@ // Author : M.Frank // //========================================================================== -#ifndef DD4HEP_ALIGNMENT_ALIGNMENTSTACK_H -#define DD4HEP_ALIGNMENT_ALIGNMENTSTACK_H +#ifndef DD4HEP_ALIGNMENT_GLOBALALIGNMENTSTACK_H +#define DD4HEP_ALIGNMENT_GLOBALALIGNMENTSTACK_H // Framework include files #include "DD4hep/Alignments.h" @@ -31,7 +31,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_ALIGN */ - class AlignmentStack { + class GlobalAlignmentStack { public: enum { OVERLAP_DEFINED = 1<<20, @@ -98,14 +98,14 @@ namespace DD4hep { Stack m_stack; /// Default constructor - AlignmentStack(); + GlobalAlignmentStack(); public: /// Default destructor. Careful with this one: - virtual ~AlignmentStack(); + virtual ~GlobalAlignmentStack(); /// Static client accessor - static AlignmentStack& get(); + static GlobalAlignmentStack& get(); /// Create an alignment stack instance. The creation of a second instance will be refused. static void create(); /// Check existence of alignment stack @@ -126,6 +126,6 @@ namespace DD4hep { std::vector<const StackEntry*> entries() const; }; - } /* End namespace Geometry */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_ALIGNMENT_ALIGNMENTSTACK_H */ + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_ALIGNMENT_GLOBALALIGNMENTSTACK_H */ diff --git a/DDAlign/include/DDAlign/GlobalAlignmentWriter.h b/DDAlign/include/DDAlign/GlobalAlignmentWriter.h index 632039de3bd7cc7a80faf37f13da3b8618ba9162..fc84731d523351cbe56377be03d569cd1d900682 100644 --- a/DDAlign/include/DDAlign/GlobalAlignmentWriter.h +++ b/DDAlign/include/DDAlign/GlobalAlignmentWriter.h @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDAlign/include/DDAlign/GlobalDetectorAlignment.h b/DDAlign/include/DDAlign/GlobalDetectorAlignment.h index 3ee1389f1c8b0b5c8a53599c73622ce4fff8e061..6bba746ef8dde9947d5a2ca529661c71f8a8bde6 100644 --- a/DDAlign/include/DDAlign/GlobalDetectorAlignment.h +++ b/DDAlign/include/DDAlign/GlobalDetectorAlignment.h @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDAlign/src/AlignmentsForward.cpp b/DDAlign/src/AlignmentsForward.cpp index a3f0aac3d654c323ace69cf80970239591609dd4..9b71e12f2939db933b1767c90adbe0548e8dbfaf 100644 --- a/DDAlign/src/AlignmentsForward.cpp +++ b/DDAlign/src/AlignmentsForward.cpp @@ -17,13 +17,13 @@ #include "DD4hep/DetConditions.h" #include "DDAlign/AlignmentsForward.h" -#include "DDAlign/AlignmentUpdateCall.h" +#include "DDAlign/AlignmentsUpdateCall.h" using namespace DD4hep; using namespace DD4hep::Alignments; /// Initializing constructor -AlignmentsForward::AlignmentsForward(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p) +AlignmentsForward::AlignmentsForward(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p) : alignmentMgr(m), updateCall(c), user_pool(p), extension("#alignment/Tranformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { diff --git a/DDAlign/src/AlignmentsRegister.cpp b/DDAlign/src/AlignmentsRegister.cpp index a3fc34b4119689e6a861ad2f29ae6cad546eab59..f3d47092a4fc3312878d56cd4518bc62c1241933 100644 --- a/DDAlign/src/AlignmentsRegister.cpp +++ b/DDAlign/src/AlignmentsRegister.cpp @@ -17,7 +17,7 @@ #include "DD4hep/DetConditions.h" #include "DDAlign/AlignmentsRegister.h" -#include "DDAlign/AlignmentUpdateCall.h" +#include "DDAlign/AlignmentsUpdateCall.h" using namespace DD4hep; using namespace DD4hep::Alignments; @@ -26,7 +26,7 @@ using Conditions::Condition; // ====================================================================================== /// Initializing constructor -AlignmentsRegister::AlignmentsRegister(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p) +AlignmentsRegister::AlignmentsRegister(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p) : alignmentMgr(m), updateCall(c), user_pool(p), extension("/Tranformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { diff --git a/DDAlign/src/AlignmentUpdateCall.cpp b/DDAlign/src/AlignmentsUpdateCall.cpp similarity index 87% rename from DDAlign/src/AlignmentUpdateCall.cpp rename to DDAlign/src/AlignmentsUpdateCall.cpp index 5e8dd378aeda2aa41b780b3fba5c9acb0bde8995..932c69760782a245b5563c0bb53e8f1b64407a7f 100644 --- a/DDAlign/src/AlignmentUpdateCall.cpp +++ b/DDAlign/src/AlignmentsUpdateCall.cpp @@ -12,7 +12,7 @@ //========================================================================== // Framework include files -#include "DDAlign/AlignmentUpdateCall.h" +#include "DDAlign/AlignmentsUpdateCall.h" #include "DDAlign/AlignmentsManager.h" #include "DD4hep/ConditionsPrinter.h" #include "DD4hep/InstanceCount.h" @@ -21,19 +21,19 @@ using namespace DD4hep::Alignments; /// Default constructor -AlignmentUpdateCall::AlignmentUpdateCall() +AlignmentsUpdateCall::AlignmentsUpdateCall() : DD4hep::Conditions::ConditionUpdateCall(), printLevel(DEBUG) { InstanceCount::increment(this); } /// Default destructor -AlignmentUpdateCall::~AlignmentUpdateCall() { +AlignmentsUpdateCall::~AlignmentsUpdateCall() { InstanceCount::decrement(this); } -AlignmentUpdateCall::Condition -AlignmentUpdateCall::handle(const ConditionKey& key, const UpdateContext& ctxt, const Delta& delta) { +AlignmentsUpdateCall::Condition +AlignmentsUpdateCall::handle(const ConditionKey& key, const UpdateContext& ctxt, const Delta& delta) { AlignmentCondition target(key.name); AlignmentData& data = target.data(); data.delta = delta; @@ -60,8 +60,8 @@ AlignmentUpdateCall::handle(const ConditionKey& key, const UpdateContext& ctxt, } /// Handler to be called if the Alignment cannot be created due to a bad underlying data type. -AlignmentUpdateCall::Condition -AlignmentUpdateCall::invalidDataType(const ConditionKey& key, const UpdateContext& context) { +AlignmentsUpdateCall::Condition +AlignmentsUpdateCall::invalidDataType(const ConditionKey& key, const UpdateContext& context) { // Here only print and return an empty alignment condition. // Otherwise the return is not accepted! // TODO: To be decided how to handle this error diff --git a/DDAlign/src/DDAlignForwardCall.cpp b/DDAlign/src/DDAlignForwardCall.cpp index 9e62660f7fea4d9caddedeb991c05443120a46c8..f346616d1fd04ca0614e1286802e0b82feb4ef95 100644 --- a/DDAlign/src/DDAlignForwardCall.cpp +++ b/DDAlign/src/DDAlignForwardCall.cpp @@ -25,7 +25,7 @@ Alignments::DDAlignForwardCall::operator()(const ConditionKey& key, const Update { Data::Delta delta; DetElement det = context.dependency.detector; - Condition c = AlignmentUpdateCall::handle(key, context, delta); + Condition c = AlignmentsUpdateCall::handle(key, context, delta); printout(INFO,"DDAlignForward","++ Building child alignment condition: %s Detector [%d]: %s [%p]", key.name.c_str(), det.level(), det.path().c_str(), c.ptr()); return c; diff --git a/DDAlign/src/DDAlignUpdateCall.cpp b/DDAlign/src/DDAlignUpdateCall.cpp index 75ddf5f0571de7ca492f27e051a202899812dbbe..735866e3c9dab0b64cec581792798f60a08b9d10 100644 --- a/DDAlign/src/DDAlignUpdateCall.cpp +++ b/DDAlign/src/DDAlignUpdateCall.cpp @@ -27,7 +27,7 @@ Alignments::DDAlignUpdateCall::operator()(const ConditionKey& key, const UpdateC DetElement det = context.dependency.detector; if ( cond.typeInfo() == typeid(Data::Delta) ) { const Data::Delta& delta = cond.get<Data::Delta>(); - Condition c = AlignmentUpdateCall::handle(key, context, delta); + Condition c = AlignmentsUpdateCall::handle(key, context, delta); printout(printLevel,"DDAlignUpdate","++ Building dependent condition: %s Detector [%d]: %s [%p]", key.name.c_str(), det.level(), det.path().c_str(), c.ptr()); return c; diff --git a/DDAlign/src/GlobalAlignmentCache.cpp b/DDAlign/src/GlobalAlignmentCache.cpp index a8ceb60addd258ebce2261231a3c68d0516c6c1a..8bae7d17dfe5b02888b321af52624f2174bb42e6 100644 --- a/DDAlign/src/GlobalAlignmentCache.cpp +++ b/DDAlign/src/GlobalAlignmentCache.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -16,7 +15,7 @@ #include "DD4hep/LCDD.h" #include "DD4hep/Printout.h" #include "DDAlign/GlobalAlignmentCache.h" -#include "DDAlign/AlignmentOperators.h" +#include "DDAlign/GlobalAlignmentOperators.h" #include "DD4hep/objects/DetectorInterna.h" // ROOT include files @@ -26,7 +25,7 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; using namespace DD4hep::Alignments::DDAlign_standard_operations; -typedef AlignmentStack::StackEntry Entry; +typedef GlobalAlignmentStack::StackEntry Entry; DetElement _detector(DetElement child) { if ( child.isValid() ) { @@ -164,7 +163,7 @@ vector<GlobalAlignment> GlobalAlignmentCache::matches(const string& match, bool } /// Close existing transaction stack and apply all alignments -void GlobalAlignmentCache::commit(AlignmentStack& stack) { +void GlobalAlignmentCache::commit(GlobalAlignmentStack& stack) { TGeoManager& mgr = m_lcdd.manager(); mgr.UnlockGeometry(); apply(stack); @@ -183,7 +182,7 @@ GlobalAlignmentCache* GlobalAlignmentCache::subdetectorAlignments(const string& } /// Apply a complete stack of ordered alignments to the geometry structure -void GlobalAlignmentCache::apply(AlignmentStack& stack) { +void GlobalAlignmentCache::apply(GlobalAlignmentStack& stack) { typedef map<string,DetElement> DetElementUpdates; typedef map<DetElement,vector<Entry*> > sd_entries_t; TGeoManager& mgr = m_lcdd.manager(); @@ -239,12 +238,12 @@ void GlobalAlignmentCache::apply(AlignmentStack& stack) { void GlobalAlignmentCache::apply(const vector<Entry*>& changes) { typedef map<string,pair<TGeoPhysicalNode*,Entry*> > Nodes; Nodes nodes; - AlignmentSelector selector(*this,nodes,changes); + GlobalAlignmentSelector selector(*this,nodes,changes); for_each(m_cache.begin(),m_cache.end(),selector.reset()); - for_each(nodes.begin(),nodes.end(),AlignmentActor<node_print>(*this,nodes)); - for_each(nodes.begin(),nodes.end(),AlignmentActor<node_reset>(*this,nodes)); + for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<node_print>(*this,nodes)); + for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<node_reset>(*this,nodes)); for_each(changes.begin(),changes.end(),selector.reset()); - for_each(nodes.begin(),nodes.end(),AlignmentActor<node_align>(*this,nodes)); - for_each(nodes.begin(),nodes.end(),AlignmentActor<node_delete>(*this,nodes)); + for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<node_align>(*this,nodes)); + for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<node_delete>(*this,nodes)); } diff --git a/DDAlign/src/AlignmentOperators.cpp b/DDAlign/src/GlobalAlignmentOperators.cpp similarity index 84% rename from DDAlign/src/AlignmentOperators.cpp rename to DDAlign/src/GlobalAlignmentOperators.cpp index 05a4aac789d463ee3ecbec65e769a4ecd9d038fa..38df2649f7d73920263a3a5fa4651feaf267ae11 100644 --- a/DDAlign/src/AlignmentOperators.cpp +++ b/DDAlign/src/GlobalAlignmentOperators.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -16,7 +15,7 @@ #include "DD4hep/LCDD.h" #include "DD4hep/Printout.h" #include "DD4hep/objects/DetectorInterna.h" -#include "DDAlign/AlignmentOperators.h" +#include "DDAlign/GlobalAlignmentOperators.h" #include "DDAlign/GlobalDetectorAlignment.h" // C/C++ include files @@ -26,18 +25,18 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; -void AlignmentOperator::insert(GlobalAlignment alignment) const { +void GlobalAlignmentOperator::insert(GlobalAlignment alignment) const { if ( !cache.insert(alignment) ) { // Error } } -void AlignmentSelector::operator()(Entries::value_type e) const { +void GlobalAlignmentSelector::operator()(Entries::value_type e) const { TGeoPhysicalNode* pn = 0; nodes.insert(make_pair(e->path,make_pair(pn,e))); } -void AlignmentSelector::operator()(const Cache::value_type& entry) const { +void GlobalAlignmentSelector::operator()(const Cache::value_type& entry) const { TGeoPhysicalNode* pn = entry.second; for(Entries::const_iterator j=entries.begin(); j != entries.end(); ++j) { Entries::value_type e = (*j); @@ -56,23 +55,23 @@ void AlignmentSelector::operator()(const Cache::value_type& entry) const { } } -template <> void AlignmentActor<DDAlign_standard_operations::node_print>::init() { +template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_print>::init() { printout(ALWAYS,"GlobalAlignmentCache","++++++++++++++++++++++++ Summary ++++++++++++++++++++++++"); } -template <> void AlignmentActor<DDAlign_standard_operations::node_print>::operator()(Nodes::value_type& n) const { +template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_print>::operator()(Nodes::value_type& n) const { TGeoPhysicalNode* p = n.second.first; Entry* e = n.second.second; printout(ALWAYS,"GlobalAlignmentCache","Need to reset entry:%s - %s [needsReset:%s, hasMatrix:%s]", p->GetName(),e->path.c_str(),yes_no(e->needsReset()),yes_no(e->hasMatrix())); } -template <> void AlignmentActor<DDAlign_standard_operations::node_delete>::operator()(Nodes::value_type& n) const { +template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_delete>::operator()(Nodes::value_type& n) const { delete n.second.second; n.second.second = 0; } -template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operator()(Nodes::value_type& n) const { +template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_reset>::operator()(Nodes::value_type& n) const { TGeoPhysicalNode* p = n.second.first; string np; if ( p->IsAligned() ) { @@ -83,7 +82,7 @@ template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operat if ( !mm->IsIdentity() && i > 0 ) { // Ignore the 'world', is identity anyhow GlobalAlignment a = cache.get(np); if ( a.isValid() ) { - printout(ALWAYS,"AlignmentActor<reset>","Correct path:%s leaf:%s",p->GetName(),np.c_str()); + printout(ALWAYS,"GlobalAlignmentActor<reset>","Correct path:%s leaf:%s",p->GetName(),np.c_str()); TGeoHMatrix* glob = p->GetMatrix(i-1); if ( a.isValid() && i!=nLvl ) { *mm = *(a->GetOriginalMatrix()); @@ -101,19 +100,19 @@ template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operat } } -template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operator()(Nodes::value_type& n) const { +template <> void GlobalAlignmentActor<DDAlign_standard_operations::node_align>::operator()(Nodes::value_type& n) const { Entry& e = *n.second.second; bool overlap = e.overlapDefined(); DetElement det = e.detector; if ( !det->global_alignment.isValid() && !e.hasMatrix() ) { - printout(WARNING,"AlignmentActor","++++ SKIP Alignment %s DE:%s Valid:%s Matrix:%s", + printout(WARNING,"GlobalAlignmentActor","++++ SKIP Alignment %s DE:%s Valid:%s Matrix:%s", e.path.c_str(),det.placementPath().c_str(), yes_no(det->global_alignment.isValid()), yes_no(e.hasMatrix())); return; } if ( GlobalDetectorAlignment::debug() ) { - printout(INFO,"AlignmentActor","++++ %s DE:%s Matrix:%s", + printout(INFO,"GlobalAlignmentActor","++++ %s DE:%s Matrix:%s", e.path.c_str(),det.placementPath().c_str(),yes_no(e.hasMatrix())); } // Need to care about optional arguments 'check_overlaps' and 'overlap' @@ -146,7 +145,7 @@ template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operat insert(align); return; } - except("AlignmentActor","Failed to apply alignment for "+e.path); + except("GlobalAlignmentActor","Failed to apply alignment for "+e.path); } #if 0 diff --git a/DDAlign/src/AlignmentStack.cpp b/DDAlign/src/GlobalAlignmentStack.cpp similarity index 59% rename from DDAlign/src/AlignmentStack.cpp rename to DDAlign/src/GlobalAlignmentStack.cpp index bc4974670368b4e32444ad5889d9a04b0ccb459d..146aeef007c2a0aed6da054e0dab7e1ceae6960e 100644 --- a/DDAlign/src/AlignmentStack.cpp +++ b/DDAlign/src/GlobalAlignmentStack.cpp @@ -16,43 +16,43 @@ #include "DD4hep/Objects.h" #include "DD4hep/Printout.h" #include "DD4hep/InstanceCount.h" -#include "DDAlign/AlignmentStack.h" +#include "DDAlign/GlobalAlignmentStack.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; -static dd4hep_ptr<AlignmentStack>& _stack() { - static dd4hep_ptr<AlignmentStack> s; +static dd4hep_ptr<GlobalAlignmentStack>& _stack() { + static dd4hep_ptr<GlobalAlignmentStack> s; return s; } -static dd4hep_ptr<AlignmentStack>& _stack(AlignmentStack* obj) { - dd4hep_ptr<AlignmentStack>& s = _stack(); +static dd4hep_ptr<GlobalAlignmentStack>& _stack(GlobalAlignmentStack* obj) { + dd4hep_ptr<GlobalAlignmentStack>& s = _stack(); s.adopt(obj); return s; } /// Constructor with partial initialization -AlignmentStack::StackEntry::StackEntry(DetElement element, const std::string& p, const Delta& del, double ov) +GlobalAlignmentStack::StackEntry::StackEntry(DetElement element, const std::string& p, const Delta& del, double ov) : detector(element), delta(del), path(p), overlap(ov) { InstanceCount::increment(this); } /// Copy constructor -AlignmentStack::StackEntry::StackEntry(const StackEntry& e) +GlobalAlignmentStack::StackEntry::StackEntry(const StackEntry& e) : detector(e.detector), delta(e.delta), path(e.path), overlap(e.overlap) { InstanceCount::increment(this); } /// Default destructor -AlignmentStack::StackEntry::~StackEntry() { +GlobalAlignmentStack::StackEntry::~StackEntry() { InstanceCount::decrement(this); } /// Assignment operator -AlignmentStack::StackEntry& AlignmentStack::StackEntry::operator=(const StackEntry& e) { +GlobalAlignmentStack::StackEntry& GlobalAlignmentStack::StackEntry::operator=(const StackEntry& e) { if ( this != &e ) { detector = e.detector; delta = e.delta; @@ -63,28 +63,28 @@ AlignmentStack::StackEntry& AlignmentStack::StackEntry::operator=(const StackEnt } /// Set flag to reset the entry to it's ideal geometrical position -AlignmentStack::StackEntry& AlignmentStack::StackEntry::setReset(bool new_value) { +GlobalAlignmentStack::StackEntry& GlobalAlignmentStack::StackEntry::setReset(bool new_value) { new_value ? (delta.flags |= RESET_VALUE) : (delta.flags &= ~RESET_VALUE); return *this; } /// Set flag to reset the entry's children to their ideal geometrical position -AlignmentStack::StackEntry& AlignmentStack::StackEntry::setResetChildren(bool new_value) { +GlobalAlignmentStack::StackEntry& GlobalAlignmentStack::StackEntry::setResetChildren(bool new_value) { new_value ? (delta.flags |= RESET_CHILDREN) : (delta.flags &= ~RESET_CHILDREN); return *this; } /// Set flag to check overlaps -AlignmentStack::StackEntry& AlignmentStack::StackEntry::setOverlapCheck(bool new_value) { +GlobalAlignmentStack::StackEntry& GlobalAlignmentStack::StackEntry::setOverlapCheck(bool new_value) { new_value ? (delta.flags |= CHECKOVL_DEFINED) : (delta.flags &= ~CHECKOVL_DEFINED); return *this; } /// Set the precision for the overlap check (otherwise the default is 0.001 cm) -AlignmentStack::StackEntry& AlignmentStack::StackEntry::setOverlapPrecision(double precision) { +GlobalAlignmentStack::StackEntry& GlobalAlignmentStack::StackEntry::setOverlapPrecision(double precision) { delta.flags |= CHECKOVL_DEFINED; delta.flags |= CHECKOVL_VALUE; overlap = precision; @@ -92,94 +92,94 @@ AlignmentStack::StackEntry& AlignmentStack::StackEntry::setOverlapPrecision(doub } /// Default constructor -AlignmentStack::AlignmentStack() +GlobalAlignmentStack::GlobalAlignmentStack() { InstanceCount::increment(this); } /// Default destructor -AlignmentStack::~AlignmentStack() { +GlobalAlignmentStack::~GlobalAlignmentStack() { destroyObjects(m_stack); InstanceCount::decrement(this); } /// Static client accessor -AlignmentStack& AlignmentStack::get() { +GlobalAlignmentStack& GlobalAlignmentStack::get() { if ( _stack().get() ) return *_stack(); - throw runtime_error("AlignmentStack> Stack not allocated -- may not be retrieved!"); + throw runtime_error("GlobalAlignmentStack> Stack not allocated -- may not be retrieved!"); } /// Create an alignment stack instance. The creation of a second instance will be refused. -void AlignmentStack::create() { +void GlobalAlignmentStack::create() { if ( _stack().get() ) { - throw runtime_error("AlignmentStack> Stack already allocated. Multiple copies are not allowed!"); + throw runtime_error("GlobalAlignmentStack> Stack already allocated. Multiple copies are not allowed!"); } - _stack(new AlignmentStack()); + _stack(new GlobalAlignmentStack()); } /// Check existence of alignment stack -bool AlignmentStack::exists() { +bool GlobalAlignmentStack::exists() { return _stack().get() != 0; } /// Clear data content and remove the slignment stack -void AlignmentStack::release() { +void GlobalAlignmentStack::release() { if ( _stack().get() ) { _stack(0); return; } - throw runtime_error("AlignmentStack> Attempt to delete non existing stack."); + throw runtime_error("GlobalAlignmentStack> Attempt to delete non existing stack."); } /// Add a new entry to the cache. The key is the placement path -bool AlignmentStack::insert(const string& full_path, dd4hep_ptr<StackEntry>& entry) { +bool GlobalAlignmentStack::insert(const string& full_path, dd4hep_ptr<StackEntry>& entry) { if ( entry.get() && !full_path.empty() ) { entry->path = full_path; return add(entry); } - throw runtime_error("AlignmentStack> Attempt to apply an invalid alignment entry."); + throw runtime_error("GlobalAlignmentStack> Attempt to apply an invalid alignment entry."); } /// Add a new entry to the cache. The key is the placement path -bool AlignmentStack::insert(dd4hep_ptr<StackEntry>& entry) { +bool GlobalAlignmentStack::insert(dd4hep_ptr<StackEntry>& entry) { return add(entry); } /// Add a new entry to the cache. The key is the placement path -bool AlignmentStack::add(dd4hep_ptr<StackEntry>& entry) { +bool GlobalAlignmentStack::add(dd4hep_ptr<StackEntry>& entry) { if ( entry.get() && !entry->path.empty() ) { Stack::const_iterator i = m_stack.find(entry->path); if ( i == m_stack.end() ) { // Need to make some checks BEFORE insertion if ( !entry->detector.isValid() ) { - throw runtime_error("AlignmentStack> Invalid alignment entry [No such detector]"); + throw runtime_error("GlobalAlignmentStack> Invalid alignment entry [No such detector]"); } - printout(INFO,"AlignmentStack","Add node:%s",entry->path.c_str()); + printout(INFO,"GlobalAlignmentStack","Add node:%s",entry->path.c_str()); m_stack.insert(make_pair(entry->path,entry.get())); entry.release(); return true; } - throw runtime_error("AlignmentStack> The entry with path "+entry->path+ + throw runtime_error("GlobalAlignmentStack> The entry with path "+entry->path+ " cannot be re-aligned twice in one transaction."); } - throw runtime_error("AlignmentStack> Attempt to apply an invalid alignment entry."); + throw runtime_error("GlobalAlignmentStack> Attempt to apply an invalid alignment entry."); } /// Retrieve an alignment entry of the current stack -dd4hep_ptr<AlignmentStack::StackEntry> AlignmentStack::pop() { +dd4hep_ptr<GlobalAlignmentStack::StackEntry> GlobalAlignmentStack::pop() { Stack::iterator i = m_stack.begin(); if ( i != m_stack.end() ) { dd4hep_ptr<StackEntry> e((*i).second); m_stack.erase(i); return e; } - throw runtime_error("AlignmentStack> Alignment stack is empty. " + throw runtime_error("GlobalAlignmentStack> Alignment stack is empty. " "Cannot pop entries - check size first!"); } /// Get all pathes to be aligned -vector<const AlignmentStack::StackEntry*> AlignmentStack::entries() const { +vector<const GlobalAlignmentStack::StackEntry*> GlobalAlignmentStack::entries() const { vector<const StackEntry*> result; result.reserve(m_stack.size()); for(Stack::const_iterator i=m_stack.begin(); i != m_stack.end(); ++i) diff --git a/DDAlign/src/GlobalAlignmentWriter.cpp b/DDAlign/src/GlobalAlignmentWriter.cpp index d6b921601f8da8a430a704ef02432a60f5f0df12..53061e1ba52d05d02a564f4367c2e1da17fed7a3 100644 --- a/DDAlign/src/GlobalAlignmentWriter.cpp +++ b/DDAlign/src/GlobalAlignmentWriter.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDAlign/src/GlobalDetectorAlignment.cpp b/DDAlign/src/GlobalDetectorAlignment.cpp index 3e88e366e4606343c59a83c56f690c343ba33eab..fb30c05454b9d7be1b72644b8acd9238eb187257 100644 --- a/DDAlign/src/GlobalDetectorAlignment.cpp +++ b/DDAlign/src/GlobalDetectorAlignment.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDAlign/src/plugins/AlignmentDependencyTest.cpp b/DDAlign/src/plugins/AlignmentsDependencyTest.cpp similarity index 100% rename from DDAlign/src/plugins/AlignmentDependencyTest.cpp rename to DDAlign/src/plugins/AlignmentsDependencyTest.cpp diff --git a/DDAlign/src/plugins/AlignmentPlugins.cpp b/DDAlign/src/plugins/AlignmentsPlugins.cpp similarity index 96% rename from DDAlign/src/plugins/AlignmentPlugins.cpp rename to DDAlign/src/plugins/AlignmentsPlugins.cpp index 136876a1dbb8ab72f56d413d3cf2a12d39492368..30bf03116402853d473305d1147e98de41c4f3b2 100644 --- a/DDAlign/src/plugins/AlignmentPlugins.cpp +++ b/DDAlign/src/plugins/AlignmentsPlugins.cpp @@ -96,14 +96,14 @@ DECLARE_APPLY(DD4hep_GlobalAlignmentWriter, create_global_alignment_file) // ====================================================================================== #include "DDAlign/DDAlignUpdateCall.h" static void* create_DDAlignUpdateCall(Geometry::LCDD& /* lcdd */, int /* argc */, char** /* argv */) { - return (AlignmentUpdateCall*)(new DDAlignUpdateCall()); + return (AlignmentsUpdateCall*)(new DDAlignUpdateCall()); } DECLARE_LCDD_CONSTRUCTOR(DDAlign_UpdateCall, create_DDAlignUpdateCall) // ====================================================================================== #include "DDAlign/DDAlignForwardCall.h" static void* create_DDAlignForwardCall(Geometry::LCDD& /* lcdd */, int /* argc */, char** /* argv */) { - return (AlignmentUpdateCall*)(new DDAlignForwardCall()); + return (AlignmentsUpdateCall*)(new DDAlignForwardCall()); } DECLARE_LCDD_CONSTRUCTOR(DDAlign_ForwardCall, create_DDAlignForwardCall) @@ -153,7 +153,7 @@ static void* ddalign_AlignmentsRegister(Geometry::LCDD& lcdd, int argc, char** a " Arguments to the 'prepare' plugin. \n" " -call ... args ... -call-end \n" " Arguments to the 'call' plugin, which \n" - " create the AlignmentUpdateCall callback. \n" + " create the AlignmentsUpdateCall callback. \n" "\tArguments given: " << arguments(argc,argv) << endl << flush; ::exit(EINVAL); } @@ -167,7 +167,7 @@ static void* ddalign_AlignmentsRegister(Geometry::LCDD& lcdd, int argc, char** a except("AlignRegister","++ Failed to prepare conditions user-pool!"); } test->addExtension<Conditions::UserPool>(pool,"ConditionsTestUserPool"); - AlignmentUpdateCall* call = (AlignmentUpdateCall*) + AlignmentsUpdateCall* call = (AlignmentsUpdateCall*) PluginService::Create<void*>((const char*)args_call[0],&lcdd, int(args_call.size())-1, (char**)&args_call[1]); @@ -207,14 +207,14 @@ static void* ddalign_AlignmentsForward(Geometry::LCDD& lcdd, int argc, char** ar " \n" " -call ... args ... -call-end \n" " Arguments to the 'call' plugin, which \n" - " create the AlignmentUpdateCall callback. \n" + " create the AlignmentsUpdateCall callback.\n" "\tArguments given: " << arguments(argc,argv) << endl << flush; ::exit(EINVAL); } PluginTester* test = lcdd.extension<PluginTester>(); Conditions::UserPool* pool = test->extension<Conditions::UserPool>("ConditionsTestUserPool"); - AlignmentUpdateCall* call = (AlignmentUpdateCall*) + AlignmentsUpdateCall* call = (AlignmentsUpdateCall*) PluginService::Create<void*>((const char*)args_call[0],&lcdd, int(args_call.size())-1, (char**)&args_call[1]); diff --git a/DDAlign/src/plugins/AlignmentParser.cpp b/DDAlign/src/plugins/GlobalAlignmentParser.cpp similarity index 87% rename from DDAlign/src/plugins/AlignmentParser.cpp rename to DDAlign/src/plugins/GlobalAlignmentParser.cpp index c9cd47bc9280e19bf26c4b97516031bf36ba6a0a..9f05c5eee0dc0873a9587befd4d2aee77cd3b6bf 100644 --- a/DDAlign/src/plugins/AlignmentParser.cpp +++ b/DDAlign/src/plugins/GlobalAlignmentParser.cpp @@ -23,7 +23,7 @@ #include "DD4hep/DetFactoryHelper.h" #include "DDAlign/AlignmentTags.h" -#include "DDAlign/AlignmentStack.h" +#include "DDAlign/GlobalAlignmentStack.h" #include "DDAlign/GlobalAlignmentCache.h" #include "DDAlign/GlobalDetectorAlignment.h" @@ -42,7 +42,7 @@ namespace DD4hep { class rotation; class position; class pivot; - class delta; + class alignment_delta; class debug; } @@ -51,7 +51,7 @@ namespace DD4hep { template <> void Converter<pivot>::operator()(xml_h seq) const; template <> void Converter<position>::operator()(xml_h seq) const; template <> void Converter<rotation>::operator()(xml_h seq) const; - template <> void Converter<delta>::operator()(xml_h seq) const; + template <> void Converter<alignment_delta>::operator()(xml_h seq) const; template <> void Converter<volume>::operator()(xml_h seq) const; template <> void Converter<alignment>::operator()(xml_h seq) const; @@ -148,7 +148,7 @@ template <> void Converter<pivot>::operator()(xml_h e) const { * @version 1.0 * @date 01/04/2014 */ -template <> void Converter<delta>::operator()(xml_h e) const { +template <> void Converter<alignment_delta>::operator()(xml_h e) const { Position pos; RotationZYX rot; Translation3D piv; @@ -174,7 +174,7 @@ template <> void Converter<delta>::operator()(xml_h e) const { delta->flags |= Delta::HAVE_TRANSLATION; } -typedef AlignmentStack::StackEntry StackEntry; +typedef GlobalAlignmentStack::StackEntry StackEntry; /** Convert volume objects * @@ -194,7 +194,7 @@ typedef AlignmentStack::StackEntry StackEntry; template <> void Converter<volume>::operator()(xml_h e) const { Delta val; pair<DetElement,string>* elt = (pair<DetElement,string>*)param; - AlignmentStack* stack = _option<AlignmentStack>(); + GlobalAlignmentStack* stack = _option<GlobalAlignmentStack>(); string subpath = e.attr<string>(_ALU(path)); bool reset = e.hasAttr(_ALU(reset)) ? e.attr<bool>(_ALU(reset)) : true; bool reset_dau = e.hasAttr(_ALU(reset_children)) ? e.attr<bool>(_ALU(reset_children)) : true; @@ -208,13 +208,13 @@ template <> void Converter<volume>::operator()(xml_h e) const { printout(INFO,"Alignment<vol>"," path:%s placement:%s reset:%s children:%s", subpath.c_str(), placement.c_str(), yes_no(reset), yes_no(reset_dau)); - Converter<delta>(lcdd,&val)(e); - if ( val.flags ) val.flags |= AlignmentStack::MATRIX_DEFINED; - if ( overlap ) val.flags |= AlignmentStack::OVERLAP_DEFINED; - if ( reset ) val.flags |= AlignmentStack::RESET_VALUE; - if ( reset_dau ) val.flags |= AlignmentStack::RESET_CHILDREN; - if ( check ) val.flags |= AlignmentStack::CHECKOVL_DEFINED; - if ( check_val ) val.flags |= AlignmentStack::CHECKOVL_VALUE; + Converter<alignment_delta>(lcdd,&val)(e); + if ( val.flags ) val.flags |= GlobalAlignmentStack::MATRIX_DEFINED; + if ( overlap ) val.flags |= GlobalAlignmentStack::OVERLAP_DEFINED; + if ( reset ) val.flags |= GlobalAlignmentStack::RESET_VALUE; + if ( reset_dau ) val.flags |= GlobalAlignmentStack::RESET_CHILDREN; + if ( check ) val.flags |= GlobalAlignmentStack::CHECKOVL_DEFINED; + if ( check_val ) val.flags |= GlobalAlignmentStack::CHECKOVL_VALUE; dd4hep_ptr<StackEntry> entry(new StackEntry(elt->first,placement,val,ovl)); stack->insert(entry); @@ -240,7 +240,7 @@ template <> void Converter<volume>::operator()(xml_h e) const { */ template <> void Converter<detelement>::operator()(xml_h e) const { DetElement det(_param<DetElement::Object>()); - AlignmentStack* stack = _option<AlignmentStack>(); + GlobalAlignmentStack* stack = _option<GlobalAlignmentStack>(); string path = e.attr<string>(_ALU(path)); bool check = e.hasAttr(_ALU(check_overlaps)); bool check_val = check ? e.attr<bool>(_ALU(check_overlaps)) : false; @@ -256,26 +256,26 @@ template <> void Converter<detelement>::operator()(xml_h e) const { throw runtime_error(err); } - Delta val; - Converter<delta>(lcdd,&val)(e); - if ( val.flags ) { - val.flags |= AlignmentStack::MATRIX_DEFINED; + Delta delta; + Converter<alignment_delta>(lcdd,&delta)(e); + if ( delta.flags ) { + delta.flags |= GlobalAlignmentStack::MATRIX_DEFINED; reset = reset_dau = true; } - if ( overlap ) val.flags |= AlignmentStack::OVERLAP_DEFINED; - if ( check ) val.flags |= AlignmentStack::CHECKOVL_DEFINED; - if ( reset ) val.flags |= AlignmentStack::RESET_VALUE; - if ( reset_dau ) val.flags |= AlignmentStack::RESET_CHILDREN; - if ( check_val ) val.flags |= AlignmentStack::CHECKOVL_VALUE; + if ( overlap ) delta.flags |= GlobalAlignmentStack::OVERLAP_DEFINED; + if ( check ) delta.flags |= GlobalAlignmentStack::CHECKOVL_DEFINED; + if ( reset ) delta.flags |= GlobalAlignmentStack::RESET_VALUE; + if ( reset_dau ) delta.flags |= GlobalAlignmentStack::RESET_CHILDREN; + if ( check_val ) delta.flags |= GlobalAlignmentStack::CHECKOVL_VALUE; printout(INFO,"Alignment<det>","path:%s [%s] placement:%s matrix:%s reset:%s children:%s", path.c_str(), elt.isValid() ? elt.path().c_str() : "-----", placement.c_str(), - yes_no(val.checkFlag(AlignmentStack::MATRIX_DEFINED)), + yes_no(delta.checkFlag(GlobalAlignmentStack::MATRIX_DEFINED)), yes_no(reset), yes_no(reset_dau)); - dd4hep_ptr<StackEntry> entry(new StackEntry(elt,placement,val,ovl)); + dd4hep_ptr<StackEntry> entry(new StackEntry(elt,placement,delta,ovl)); stack->insert(entry); pair<DetElement,string> vol_param(elt,""); @@ -346,16 +346,16 @@ static long setup_Alignment(lcdd_t& lcdd, const xml_h& e) { GlobalAlignmentCache* cache = GlobalAlignmentCache::install(lcdd); /// Check if transaction already present. If not, open, else issue an error if ( open_trans ) { - if ( AlignmentStack::exists() ) { + if ( GlobalAlignmentStack::exists() ) { except("GlobalAlignment","Request to open a second alignment transaction stack -- not allowed!"); } - AlignmentStack::create(); + GlobalAlignmentStack::create(); } - AlignmentStack& stack = AlignmentStack::get(); + GlobalAlignmentStack& stack = GlobalAlignmentStack::get(); (DD4hep::Converter<DD4hep::alignment>(lcdd,lcdd.world().ptr(),&stack))(e); if ( close_trans ) { cache->commit(stack); - AlignmentStack::get().release(); + GlobalAlignmentStack::get().release(); } if ( GlobalDetectorAlignment::debug() ) { xml_elt_t elt(e); diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h index 3bfb92aaf3fe472adff4a84988b4d5b16fbf3918..c86108732ce8bb196eba92646b89527726ccf22f 100644 --- a/DDCore/include/DD4hep/Alignments.h +++ b/DDCore/include/DD4hep/Alignments.h @@ -37,6 +37,7 @@ namespace DD4hep { namespace Alignments { using Geometry::LCDD; + using Geometry::Position; using Geometry::DetElement; using Geometry::PlacedVolume; using Conditions::UserPool; @@ -121,6 +122,50 @@ namespace DD4hep { const TGeoHMatrix& worldTransformation() const; /// Access the alignment/placement matrix with respect to the world const TGeoHMatrix& detectorTransformation() const; + + /** Aliases for the transformation from local coordinates to the world system */ + /// Transformation from local coordinates of the placed volume to the world system + void localToWorld(const Position& local, Position& global) const; + /// Transformation from local coordinates of the placed volume to the world system + void localToWorld(const Double_t local[3], Double_t global[3]) const; + /// Transformation from local coordinates of the placed volume to the world system + Position localToWorld(const Position& local) const; + /// Transformation from local coordinates of the placed volume to the world system + Position localToWorld(const Double_t local[3]) const + { return localToWorld(Position(local[0],local[1],local[2])); } + + /** Aliases for the transformation from world coordinates to the local volume */ + /// Transformation from world coordinates of the local placed volume coordinates + void worldToLocal(const Position& global, Position& local) const; + /// Transformation from world coordinates of the local placed volume coordinates + void worldToLocal(const Double_t global[3], Double_t local[3]) const; + /// Transformation from local coordinates of the placed volume to the world system + Position worldToLocal(const Position& global) const; + /// Transformation from local coordinates of the placed volume to the world system + Position worldToLocal(const Double_t global[3]) const + { return worldToLocal(Position(global[0],global[1],global[2])); } + + /** Aliases for the transformation from local coordinates to the next DetElement system */ + /// Transformation from local coordinates of the placed volume to the detector system + void localToDetector(const Position& local, Position& detector) const; + /// Transformation from local coordinates of the placed volume to the detector system + void localToDetector(const Double_t local[3], Double_t detector[3]) const; + /// Transformation from local coordinates of the placed volume to the world system + Position localToDetector(const Position& local) const; + /// Transformation from local coordinates of the placed volume to the world system + Position localToDetector(const Double_t local[3]) const + { return localToDetector(Position(local[0],local[1],local[2])); } + + /** Aliases for the transformation from the next DetElement to local coordinates */ + /// Transformation from detector element coordinates to the local placed volume coordinates + void detectorToLocal(const Position& detector, Position& local) const; + /// Transformation from detector element coordinates to the local placed volume coordinates + void detectorToLocal(const Double_t detector[3], Double_t local[3]) const; + /// Transformation from detector element coordinates to the local placed volume coordinates + Position detectorToLocal(const Position& detector) const; + /// Transformation from detector element coordinates to the local placed volume coordinates + Position detectorToLocal(const Double_t det[3]) const + { return detectorToLocal(Position(det[0],det[1],det[2])); } }; /// Hash code generation from input string diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index 10d37719fb728889bc189ed9136a445e08152b54..f3dd69049d4b8d035594121c4cb173d58468c08b 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -10,7 +10,6 @@ // Author : M.Frank // //========================================================================== - #ifndef DD4HEP_DETECTOR_H #define DD4HEP_DETECTOR_H @@ -401,14 +400,14 @@ namespace DD4hep { /// Transformation from local coordinates of the placed volume to the parent system bool localToParent(const Position& local, Position& parent) const; /// Transformation from local coordinates of the placed volume to arbitrary parent system set as reference - //bool localToReference(const Position& local, Position& reference) const; + bool localToReference(const Position& local, Position& reference) const; /// Transformation from world coordinates of the local placed volume coordinates bool worldToLocal(const Position& global, Position& local) const; /// Transformation from world coordinates of the local placed volume coordinates bool parentToLocal(const Position& parent, Position& local) const; /// Transformation from world coordinates of the local placed volume coordinates - //bool referenceToLocal(const Position& reference, Position& local) const; + bool referenceToLocal(const Position& reference, Position& local) const; }; } /* End namespace Geometry */ diff --git a/DDCore/include/DD4hep/GlobalAlignment.h b/DDCore/include/DD4hep/GlobalAlignment.h index 7bbf7fb801ec847e3e7e502aa321ba05cdea17a8..59d51ade532b86ef2a0edf6272e4bd53844b8522 100644 --- a/DDCore/include/DD4hep/GlobalAlignment.h +++ b/DDCore/include/DD4hep/GlobalAlignment.h @@ -87,9 +87,9 @@ namespace DD4hep { Transform3D delta() const; /// Access the inverse of the currently applied correction matrix (delta) (mother to daughter) Transform3D invDelta() const; - }; - } /* End namespace Alignments */ -} /* End namespace DD4hep */ + } /* End namespace Alignments */ +} /* End namespace DD4hep */ #endif /* DD4HEP_ALIGNMENT_GLOBALALIGNMENT_H */ + diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index b757b92481a971d813a75bca47ada2450b594a4f..3736ac69379aac178815e00e341f525c69b310a2 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -78,6 +78,15 @@ namespace DD4hep { virtual ~invalid_handle_exception() = default; }; + /// Macro for deprecated functions. Prints once only. useage: deprecatedCall(__PRETTY_FUNCTION__); +#define DD4HEP_DEPRECATED_CALL(tag,replacement,func) \ + { static bool __dd4hep_first=true; \ + if ( __dd4hep_first ) { __dd4hep_first=false; \ + DD4hep::printout(DD4hep::WARNING,tag, \ + "Deprecated function: '%s' use '%s' instead.", \ + func,replacement); \ + }} + /// ABI information about type names std::string typeName(const std::type_info& type); /// Check type infos for equivalence (dynamic casts) using ABI information diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h index c5ca4c79313c7d2a47cce8b723f48ed10e449812..bbe5c3128a404bf990b7d72ad5533243ec191f4b 100644 --- a/DDCore/include/DD4hep/objects/DetectorInterna.h +++ b/DDCore/include/DD4hep/objects/DetectorInterna.h @@ -158,20 +158,23 @@ namespace DD4hep { /// Global alignment data Ref_t global_alignment; + //@} +#if 0 // To be removed! /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements std::vector<Alignment> volume_alignments; /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements std::vector<Alignment> volume_surveys; - //@} +#endif + //@{ Cached information of the detector element /// Intermediate buffer to store the transformation to the world coordination system TGeoHMatrix worldTrafo; /// Intermediate buffer to store the transformation to the parent detector element - TGeoHMatrix parentTrafo; + //TGeoHMatrix parentTrafo; /// Intermediate buffer for the transformation to an arbitrary DetElement - TGeoHMatrix* referenceTrafo; + //TGeoHMatrix* referenceTrafo; //@} private: @@ -199,7 +202,7 @@ namespace DD4hep { /// Create cached matrix to transform to parent coordinates const TGeoHMatrix& parentTransformation(); /// Create cached matrix to transform to reference coordinates - const TGeoHMatrix& referenceTransformation(); + //const TGeoHMatrix& referenceTransformation(); /// Remove callback from object void removeAtUpdate(unsigned int type, void* pointer); /// Trigger update callbacks diff --git a/DDCore/src/AlignmentData.cpp b/DDCore/src/AlignmentData.cpp index 0e212b0a811977406a6aaa51c47491f7fd3a196b..d4fa54bd2d291cab20ac11aaa7990260dee97ab4 100644 --- a/DDCore/src/AlignmentData.cpp +++ b/DDCore/src/AlignmentData.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/AlignmentTools.cpp b/DDCore/src/AlignmentTools.cpp index f11bafc09afc526176380295b3436464eef1d2b1..2e5f83d45ea9502815ec24ad9eee920673181cef 100644 --- a/DDCore/src/AlignmentTools.cpp +++ b/DDCore/src/AlignmentTools.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -30,6 +29,18 @@ using DD4hep::Alignments::AlignmentData; namespace DetectorTools = DD4hep::Geometry::DetectorTools; typedef AlignmentData::MaskManipulator MaskManipulator; +namespace { + void reset_matrix(TGeoHMatrix* m) { + double tr[3] = {0e0,0e0,0e0}; + double rot[9] = {1e0,0e0,0e0, + 0e0,1e0,0e0, + 0e0,0e0,1e0}; + m->SetTranslation(tr); + m->SetRotation(rot); + } + +} + /// Copy alignment object from source object void DD4hep::Alignments::AlignmentTools::copy(Alignment from, Alignment to) { Alignment::Object* f = from.ptr(); @@ -52,6 +63,7 @@ void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment) { Alignment::Object* a = alignment.ptr(); MaskManipulator mask(a->flag); DetElement parent = a->detector.parent(); + reset_matrix(&a->detectorTrafo); if ( parent.isValid() ) { DetectorTools::PlacementPath path; DetectorTools::placementPath(parent, a->detector, path); @@ -69,6 +81,9 @@ void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment) { mask.set(AlignmentData::HAVE_WORLD_TRAFO); mask.set(AlignmentData::IDEAL); } + else { + reset_matrix(&a->worldTrafo); + } } /// Compute the ideal/nominal to-world transformation from the detector element placement diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp index 5417522cb23a9f7e6c814aaf9120b267dd62cf32..933df8547fc6052abdf4f8234f9ac6f020103973 100644 --- a/DDCore/src/Alignments.cpp +++ b/DDCore/src/Alignments.cpp @@ -67,6 +67,65 @@ const TGeoHMatrix& Alignment::detectorTransformation() const { return data().detectorTransformation(); } +/// Transformation from local coordinates of the placed volume to the world system +void Alignment::localToWorld(const Position& local, Position& global) const { + return access()->localToWorld(local,global); +} + +/// Transformation from local coordinates of the placed volume to the world system +void Alignment::localToWorld(const Double_t local[3], Double_t global[3]) const { + return access()->localToWorld(local,global); +} +/// Transformation from local coordinates of the placed volume to the world system +Position Alignment::localToWorld(const Position& local) const { + return access()->localToWorld(local); +} + +/// Transformation from world coordinates of the local placed volume coordinates +void Alignment::worldToLocal(const Position& global, Position& local) const { + return access()->worldToLocal(global,local); +} + +/// Transformation from world coordinates of the local placed volume coordinates +void Alignment::worldToLocal(const Double_t global[3], Double_t local[3]) const { + return access()->worldToLocal(global,local); +} + +/// Transformation from local coordinates of the placed volume to the world system +Position Alignment::worldToLocal(const Position& global) const { + return access()->worldToLocal(global); +} + +/// Transformation from local coordinates of the placed volume to the detector system +void Alignment::localToDetector(const Position& local, Position& detector) const { + return access()->localToDetector(local,detector); +} + +/// Transformation from local coordinates of the placed volume to the detector system +void Alignment::localToDetector(const Double_t local[3], Double_t detector[3]) const { + return access()->localToDetector(local,detector); +} + +/// Transformation from local coordinates of the placed volume to the world system +Position Alignment::localToDetector(const Position& local) const { + return access()->localToDetector(local); +} + +/// Transformation from detector element coordinates to the local placed volume coordinates +void Alignment::detectorToLocal(const Position& detector, Position& local) const { + return access()->detectorToLocal(detector,local); +} + +/// Transformation from detector element coordinates to the local placed volume coordinates +void Alignment::detectorToLocal(const Double_t detector[3], Double_t local[3]) const { + return access()->detectorToLocal(detector,local); +} + +/// Transformation from detector element coordinates to the local placed volume coordinates +Position Alignment::detectorToLocal(const Position& detector) const { + return access()->detectorToLocal(detector); +} + /// Access the IOV type const DD4hep::IOVType& AlignmentCondition::iovType() const { return *(access()->iovType()); diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 3712736cc7a3c882ef1415bc66327ad6f805d200..10281113c47943bc638729c9456c58f5a2af760c 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -17,13 +17,14 @@ #include "DD4hep/objects/AlignmentsInterna.h" #include "DD4hep/AlignmentTools.h" #include "DD4hep/DetectorTools.h" +#include "DD4hep/Printout.h" #include "DD4hep/World.h" #include "DD4hep/LCDD.h" using namespace std; using namespace DD4hep::Geometry; using DD4hep::Alignments::Alignment; - + namespace { static string s_empty_string; } @@ -189,6 +190,8 @@ Alignment DetElement::nominal() const { if ( !o->nominal.isValid() ) { o->nominal = Alignment("nominal"); o->nominal->detector = *this; + //o->flag |= Object::HAVE_WORLD_TRAFO; + //o->flag |= Object::HAVE_PARENT_TRAFO; DD4hep::Alignments::AlignmentTools::computeIdeal(o->nominal); } return o->nominal; @@ -373,16 +376,19 @@ bool DetElement::referenceToLocal(const Position& global, Position& local) const /// Create cached matrix to transform to world coordinates const TGeoHMatrix& DetElement::worldTransformation() const { - return access()->worldTransformation(); + DD4HEP_DEPRECATED_CALL("DetElement","DetElement::nominal()",__PRETTY_FUNCTION__); + return nominal().worldTransformation(); } /// Create cached matrix to transform to parent coordinates const TGeoHMatrix& DetElement::parentTransformation() const { - return access()->parentTransformation(); + DD4HEP_DEPRECATED_CALL("DetElement","DetElement::nominal()",__PRETTY_FUNCTION__); + return nominal().detectorTransformation(); } /// Transformation from local coordinates of the placed volume to the world system bool DetElement::localToWorld(const Position& local, Position& global) const { + DD4HEP_DEPRECATED_CALL("DetElement","DetElement::nominal()",__PRETTY_FUNCTION__); Double_t master_point[3] = { 0, 0, 0 }, local_point[3] = { local.X(), local.Y(), local.Z() }; // If the path is unknown an exception will be thrown inside worldTransformation() ! worldTransformation().LocalToMaster(local_point, master_point); @@ -392,6 +398,7 @@ bool DetElement::localToWorld(const Position& local, Position& global) const { /// Transformation from local coordinates of the placed volume to the parent system bool DetElement::localToParent(const Position& local, Position& global) const { + DD4HEP_DEPRECATED_CALL("DetElement","DetElement::nominal()",__PRETTY_FUNCTION__); // If the path is unknown an exception will be thrown inside parentTransformation() ! Double_t master_point[3] = { 0, 0, 0 }, local_point[3] = { local.X(), local.Y(), local.Z() }; parentTransformation().LocalToMaster(local_point, master_point); @@ -401,6 +408,7 @@ bool DetElement::localToParent(const Position& local, Position& global) const { /// Transformation from world coordinates of the local placed volume coordinates bool DetElement::worldToLocal(const Position& global, Position& local) const { + DD4HEP_DEPRECATED_CALL("DetElement","DetElement::nominal()",__PRETTY_FUNCTION__); // If the path is unknown an exception will be thrown inside worldTransformation() ! Double_t master_point[3] = { global.X(), global.Y(), global.Z() }, local_point[3] = { 0, 0, 0 }; worldTransformation().MasterToLocal(master_point, local_point); @@ -410,6 +418,7 @@ bool DetElement::worldToLocal(const Position& global, Position& local) const { /// Transformation from parent coordinates of the local placed volume coordinates bool DetElement::parentToLocal(const Position& global, Position& local) const { + DD4HEP_DEPRECATED_CALL("DetElement","DetElement::nominal()",__PRETTY_FUNCTION__); // If the path is unknown an exception will be thrown inside parentTransformation() ! Double_t master_point[3] = { global.X(), global.Y(), global.Z() }, local_point[3] = { 0, 0, 0 }; parentTransformation().MasterToLocal(master_point, local_point); diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index 845f92a0b2f12c80b113ea405216349ea41380e3..1de83fb834d1a6c4ea5cebd425e4a6897858c1b7 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -64,8 +64,8 @@ DetElementObject::DetElementObject() : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), flag(0), id(0), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(), idealPlace(), placement(), volumeID(0), parent(), reference(), children(), - nominal(), survey(), alignments(), conditions(), - worldTrafo(), parentTrafo(), referenceTrafo(0) { + nominal(), survey(), alignments(), conditions(), worldTrafo() +{ printout(VERBOSE,"DetElementObject","+++ Created new anonymous DetElementObject()"); InstanceCount::increment(this); } @@ -75,8 +75,8 @@ DetElementObject::DetElementObject(const std::string& nam, int ident) : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), flag(0), id(ident), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(), idealPlace(), placement(), volumeID(0), parent(), reference(), children(), - nominal(), survey(), alignments(), conditions(), - worldTrafo(), parentTrafo(), referenceTrafo(0) { + nominal(), survey(), alignments(), conditions(), worldTrafo() +{ SetName(nam.c_str()); printout(VERBOSE,"DetElementObject","+++ Created new DetElementObject('%s', %d)",nam.c_str(),id); InstanceCount::increment(this); @@ -85,7 +85,7 @@ DetElementObject::DetElementObject(const std::string& nam, int ident) /// Internal object destructor: release extension object(s) DetElementObject::~DetElementObject() { destroyHandles(children); - deletePtr (referenceTrafo); + //deletePtr (referenceTrafo); destroyHandle (conditions); conditions = ConditionsContainer(); destroyHandle (nominal); @@ -154,6 +154,7 @@ World DetElementObject::i_access_world() { /// Create cached matrix to transform to world coordinates const TGeoHMatrix& DetElementObject::worldTransformation() { + DD4HEP_DEPRECATED_CALL("DetElementObject","DetElement::nominal()",__PRETTY_FUNCTION__); if ( (flag&HAVE_WORLD_TRAFO) == 0 ) { PlacementPath nodes; flag |= HAVE_WORLD_TRAFO; @@ -165,6 +166,8 @@ const TGeoHMatrix& DetElementObject::worldTransformation() { /// Create cached matrix to transform to parent coordinates const TGeoHMatrix& DetElementObject::parentTransformation() { + DD4HEP_DEPRECATED_CALL("DetElementObject","DetElement::nominal()",__PRETTY_FUNCTION__); +#if 0 if ( (flag&HAVE_PARENT_TRAFO) == 0 ) { PlacementPath nodes; flag |= HAVE_PARENT_TRAFO; @@ -172,8 +175,11 @@ const TGeoHMatrix& DetElementObject::parentTransformation() { DetectorTools::placementTrafo(nodes,false,parentTrafo); } return parentTrafo; +#endif + return DetElement(this).nominal().detectorTransformation(); } +#if 0 /// Create cached matrix to transform to reference coordinates const TGeoHMatrix& DetElementObject::referenceTransformation() { if (!referenceTrafo) { @@ -199,6 +205,7 @@ const TGeoHMatrix& DetElementObject::referenceTransformation() { } return *referenceTrafo; } +#endif /// Revalidate the caches void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { @@ -222,34 +229,34 @@ void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { placement.ptr(), node.ptr(), (placement.ptr() == node.ptr()) ? "" : "[UPDATE]"); placement = node; - - if ( have_trafo && print ) worldTrafo.Print(); + Alignments::Alignment::Data& data = det.nominal().data(); + if ( have_trafo && print ) data.worldTransformation().Print(); if ( (flag&HAVE_PARENT_TRAFO) ) { - DetectorTools::placementTrafo(par_path,false,parentTrafo); + DetectorTools::placementTrafo(par_path,false,data.detectorTrafo); } /// Compute world transformations if ( parent_world_trafo ) { // If possible use the pre-computed values from the parent worldTrafo = *parent_world_trafo; - worldTrafo.Multiply(&parentTransformation()); + worldTrafo.Multiply(&data.detectorTransformation()); flag |= HAVE_WORLD_TRAFO; } else if ( have_trafo ) { // Else re-compute the transformation to the world. PlacementPath world_nodes; DetectorTools::placementPath(this, world_nodes); - DetectorTools::placementTrafo(world_nodes,false,worldTrafo); + DetectorTools::placementTrafo(world_nodes,false,data.worldTrafo); flag |= HAVE_WORLD_TRAFO; } - if ( (flag&HAVE_PARENT_TRAFO) && print ) worldTrafo.Print(); - deletePtr (referenceTrafo); + if ( (flag&HAVE_PARENT_TRAFO) && print ) data.worldTrafo.Print(); + //deletePtr (referenceTrafo); /// Now iterate down the children.... for(const auto& i : children ) - i.second->revalidate(&worldTrafo); + i.second->revalidate(&data.worldTrafo); } /// Remove callback from object diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp index 748a43ad174acb9ddbcbcde52bbd3320ea9dc6b6..c2dcb5da32ca5d25f0bcf66f31f249eabd0b6073 100644 --- a/DDCore/src/VolumeManager.cpp +++ b/DDCore/src/VolumeManager.cpp @@ -305,12 +305,41 @@ namespace { //context->volID = ids; context->path = nodes; for (size_t i = nodes.size(); i > 1; --i) { // Omit the placement of the parent DetElement - TGeoMatrix* m = nodes[i - 1]->GetMatrix(); + TGeoMatrix* m = nodes[i-1]->GetMatrix(); context->toWorld.MultiplyLeft(m); } context->toDetector = context->toWorld; context->toDetector.MultiplyLeft(nodes[0]->GetMatrix()); - context->toWorld.MultiplyLeft(&parent.worldTransformation()); + //context->toWorld.MultiplyLeft(&parent->worldTransformation()); + context->toWorld.MultiplyLeft(&parent.nominal().worldTransformation()); + + // We HAVE to check at least once if the matrices from the original DetElement + // and from the nominal alignment are identical.... + string p = ""; + for (size_t i = 0; i<nodes.size(); ++i) { // Omit the placement of the parent DetElement + p += "/"; + p += nodes[i]->GetName(); + } + const Double_t* t1 = parent->worldTransformation().GetTranslation(); + const Double_t* t2 = parent.nominal().worldTransformation().GetTranslation(); + for(int i=0; i<3; ++i) { + if ( std::fabs(t1[i]-t2[i]) > numeric_limits<double>::epsilon() ) { + printout(WARNING,"Volumes", + "+++ World matrix of %s // %s is NOT equal (translation) [diff[%d]=%f]!", + e.placementPath().c_str(),p.c_str(),i,std::fabs(t1[i]-t2[i])); + break; + } + } + const Double_t* r1 = parent->worldTransformation().GetRotationMatrix(); + const Double_t* r2 = parent.nominal().worldTransformation().GetRotationMatrix(); + for(int i=0; i<9; ++i) { + if ( std::fabs(r1[i]-r2[i]) > numeric_limits<double>::epsilon() ) { + printout(WARNING,"Volumes", + "+++ World matrix of %s // %s is NOT equal (rotation) [diff[%d]=%f]!", + e.placementPath().c_str(),p.c_str(),i,std::fabs(r1[i]-r2[i])); + break; + } + } if (!section.adoptPlacement(context)) { print_node(sd, parent, e, n, code, nodes); } @@ -346,7 +375,8 @@ namespace { } context->toDetector = context->toWorld; context->toDetector.MultiplyLeft(nodes[0]->GetMatrix()); - context->toWorld.MultiplyLeft(&parent.worldTransformation()); + context->toWorld.MultiplyLeft(&parent->worldTransformation()); + //context->toWorld.MultiplyLeft(&parent.nominal().worldTransformation()); if (!section.adoptPlacement(context)) { print_node(sd, parent, e, n, ids, nodes); } diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp index 43d7edfe2da649002f3a18edced5b5b4d3ba1626..5b0fdd0b63d724b87baa603f7dae7b17a669ef20 100644 --- a/DDCore/src/XML/DocumentHandler.cpp +++ b/DDCore/src/XML/DocumentHandler.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -451,7 +450,8 @@ Document DocumentHandler::load(const std::string& fname, UriReader* reader) cons fname.c_str(),"[URI Resolution is not supported by TiXML]"); } else { - printout(INFO,"DocumentHandler","+++ Loading document URI: %s",fname.c_str()); + printout(INFO,"DocumentHandler","+++ Loading document URI: %s [Resolved:'%s']", + fname.c_str(),clean.c_str()); } TiXmlDocument* doc = new TiXmlDocument(clean.c_str()); bool result = false; @@ -459,19 +459,23 @@ Document DocumentHandler::load(const std::string& fname, UriReader* reader) cons result = doc->LoadFile(); if ( !result ) { if ( doc->Error() ) { - printout(FATAL,"DocumentHandler","+++ Error (TinyXML) while parsing XML document:%s",doc->ErrorDesc()); + printout(FATAL,"DocumentHandler","+++ Error (TinyXML) parsing XML document:%s [%s]", + fname.c_str(), clean.c_str()); + printout(FATAL,"DocumentHandler","+++ Error (TinyXML) XML parsing error:%s", + doc->ErrorDesc()); printout(FATAL,"DocumentHandler","+++ Document:%s Location Line:%d Column:%d", doc->Value(), doc->ErrorRow(), doc->ErrorCol()); - throw runtime_error(string("DD4hep: ")+doc->ErrorDesc()); + throw runtime_error("DD4hep: file:"+clean+" error:"+doc->ErrorDesc()); } - throw runtime_error("DD4hep: Unknown error whaile parsing XML document with TinyXML."); + throw runtime_error("DD4hep: Unknown error (TinyXML) while parsing:%s",fname.c_str()); } } catch(exception& e) { printout(ERROR,"DocumentHandler","+++ Exception (TinyXML): parse(path):%s",e.what()); } if ( result ) { - printout(INFO,"DocumentHandler","+++ Document %s succesfully parsed with TinyXML .....",fname.c_str()); + printout(INFO,"DocumentHandler","+++ Document %s succesfully parsed with TinyXML .....", + fname.c_str()); return (XmlDocument*)doc; } delete doc; @@ -496,12 +500,15 @@ Document DocumentHandler::parse(const char* bytes, size_t /* length */, const ch return (XmlDocument*)doc; } if ( doc->Error() ) { - printout(FATAL,"DocumentHandler","+++ Error (TinyXML) while parsing XML document:%s",doc->ErrorDesc()); - printout(FATAL,"DocumentHandler","+++ Document:%s Location Line:%d Column:%d", + printout(FATAL,"DocumentHandler", + "+++ Error (TinyXML) while parsing XML string [%s]", + doc->ErrorDesc()); + printout(FATAL,"DocumentHandler", + "+++ XML Document error: %s Location Line:%d Column:%d", doc->Value(), doc->ErrorRow(), doc->ErrorCol()); throw runtime_error(string("DD4hep: ")+doc->ErrorDesc()); } - throw runtime_error("DD4hep: Unknown error whaile parsing XML document with TiXml."); + throw runtime_error("DD4hep: Unknown error while parsing XML document with TiXml."); } catch(exception& e) { printout(ERROR,"DocumentHandler","+++ Exception (TinyXML): parse(string):%s",e.what()); diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index fae3f7b7b6c5744697de1a23eb2b2c16d4731079..69c0020d730926c975f616eeeb19129ead87cb48 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -17,7 +17,6 @@ #include "DD4hep/DD4hepUnits.h" #include "DD4hep/FieldTypes.h" #include "DD4hep/Printout.h" -//#include "DD4hep/Mixture.h" #include "DD4hep/Plugins.h" #include "DD4hep/objects/SegmentationsInterna.h" #include "DD4hep/objects/DetectorInterna.h" @@ -329,7 +328,6 @@ template <> void Converter<Material>::operator()(xml_h e) const { #endif //throw 1; mat = mix = new TGeoMixture(matname, composites.size(), dens_val); - //mat = mix = new Mixture(matname, composites.size(), dens_val); size_t ifrac = 0; vector<double> composite_fractions; double composite_fractions_total = 0.0; diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index ec4128563d96dce90efda30889c029c9e32e6398..8d23343a7f54a37063f9af0870b55dae89c567bc 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -736,8 +736,8 @@ static long detelement_cache(LCDD& lcdd, int , char** ) { struct Actor { static long cache(DetElement de) { const DetElement::Children& c = de.children(); - de.worldTransformation(); - de.parentTransformation(); + de.nominal().worldTransformation(); + de.nominal().detectorTransformation(); de.placementPath(); de.path(); for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) diff --git a/DDDB/include/DDDB/DDDBAlignmentUpdateCall.h b/DDDB/include/DDDB/DDDBAlignmentUpdateCall.h index 729a538b4b5641e0812fb2e97621d2cca29c6a1e..96c7d9fc9ae4dbbe350c21af001917647224ea21 100644 --- a/DDDB/include/DDDB/DDDBAlignmentUpdateCall.h +++ b/DDDB/include/DDDB/DDDBAlignmentUpdateCall.h @@ -20,7 +20,7 @@ #define DD4HEP_DDDB_DDDBALIGNMENTUPDATECALL_H // Framework includes -#include "DDAlign/AlignmentUpdateCall.h" +#include "DDAlign/AlignmentsUpdateCall.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -46,7 +46,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_CONDITIONS */ - class DDDBAlignmentUpdateCall : public Alignments::AlignmentUpdateCall { + class DDDBAlignmentUpdateCall : public Alignments::AlignmentsUpdateCall { public: /// Default constructor DDDBAlignmentUpdateCall() = default; diff --git a/DDDB/src/DDDBAlignmentTestEx.cpp b/DDDB/src/DDDBAlignmentTestEx.cpp index 872346777a546c344a5830028041ca504dff1aca..d17f772b68a77dcdbb3968883655b718b65495da 100644 --- a/DDDB/src/DDDBAlignmentTestEx.cpp +++ b/DDDB/src/DDDBAlignmentTestEx.cpp @@ -61,7 +61,7 @@ namespace { long m_accessCount = 0; TStatistic acc_stat, comp_stat; - struct UCall : public Alignments::AlignmentUpdateCall { + struct UCall : public Alignments::AlignmentsUpdateCall { AlignmentsManager manager; UCall(AlignmentsManager m) : manager(m) {} virtual ~UCall() = default; @@ -75,7 +75,7 @@ namespace { key.name.c_str(), det.level(), det.path().c_str()); if ( par.typeInfo() == typeid(Data::Delta) ) { const Data::Delta& delta = src.first<Data::Delta>(); - return AlignmentUpdateCall::handle(key, context, delta); + return AlignmentsUpdateCall::handle(key, context, delta); } // Somehow the condition is not of type Data::Delta. This is an ERROR. // Here only print and return an empty alignment condition. diff --git a/DDDB/src/DDDBAlignmentUpdateCall.cpp b/DDDB/src/DDDBAlignmentUpdateCall.cpp index e69fbc425c36f44af6131e9a051ad4f0005c2649..2fc87f0c37beb7a1da0ed2f94bea3c9ad7f9fada 100644 --- a/DDDB/src/DDDBAlignmentUpdateCall.cpp +++ b/DDDB/src/DDDBAlignmentUpdateCall.cpp @@ -38,7 +38,7 @@ DDDB::DDDBAlignmentUpdateCall::operator()(const ConditionKey& key, const UpdateC key.name.c_str(), det.level(), det.path().c_str()); if ( par.typeInfo() == typeid(Data::Delta) ) { const Data::Delta& delta = src.first<Data::Delta>(); - return AlignmentUpdateCall::handle(key, context, delta); + return AlignmentsUpdateCall::handle(key, context, delta); } // Somehow the condition is not of type Data::Delta. This is an ERROR. // Here only print and return an empty alignment condition. diff --git a/DDDetectors/src/MultiLayerTracker_geo.cpp b/DDDetectors/src/MultiLayerTracker_geo.cpp index b361197936e5294800e9694ff31caad82978aae9..206cf55c62a44616ebfa456783fd6543a559196f 100644 --- a/DDDetectors/src/MultiLayerTracker_geo.cpp +++ b/DDDetectors/src/MultiLayerTracker_geo.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDDetectors/src/PolyconeSupport_geo.cpp b/DDDetectors/src/PolyconeSupport_geo.cpp index 2cf3b5f9423878a3337bdfc50c5446bc24a7d4cf..7030df9e898ca42bcf542e25fa260373e10c67e9 100644 --- a/DDDetectors/src/PolyconeSupport_geo.cpp +++ b/DDDetectors/src/PolyconeSupport_geo.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp b/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp index 5fb587b8da2e0bb60af98ac1719a87723ba4a8ad..96a7186f219abbb125435e7712e0cb9ea438aee6 100644 --- a/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp +++ b/DDDetectors/src/PolyhedraBarrelCalorimeter2_geo.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp b/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp index 1c942ceb62bf616168271b7480885db43fa16ba4..f8875eb3b686389a73d4ac3452dd24fcb2163d13 100644 --- a/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp +++ b/DDDetectors/src/PolyhedraEndcapCalorimeter2_geo.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDDetectors/src/PolyhedraEndcapCalorimeter2_surfaces.cpp b/DDDetectors/src/PolyhedraEndcapCalorimeter2_surfaces.cpp index f7351c2a10f0b7d366feeb8c1d6e7970b4f7daf0..19080db7ba2246b7bec9c722e5eb9039ba313f62 100644 --- a/DDDetectors/src/PolyhedraEndcapCalorimeter2_surfaces.cpp +++ b/DDDetectors/src/PolyhedraEndcapCalorimeter2_surfaces.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -32,7 +31,7 @@ void Installer<UserData>::install(DetElement component, PlacedVolume pv) { } else if ( !handleUsingCache(component,comp_vol) ) { DetElement par = component.parent(); - const TGeoHMatrix& m = par.worldTransformation(); + const TGeoHMatrix& m = par.nominal().worldTransformation(); double dz = m.GetTranslation()[2]; const double* trans = placementTranslation(component); double half_mod_thickness = (mod_shape->GetZ(1)-mod_shape->GetZ(0))/2.0; diff --git a/DDEve/src/Utilities.cpp b/DDEve/src/Utilities.cpp index 594ad13aa65d3d62b1c06e1ea7bc57e5f136150c..9d9ca5e759f1d324443f1dd0e26bde7948bda791 100644 --- a/DDEve/src/Utilities.cpp +++ b/DDEve/src/Utilities.cpp @@ -141,9 +141,6 @@ Utilities::createEveShape(int level, int max_level, TEveElement* p, TGeoNode* n, shape->SetUserData(n); element = shape; } - else { - printout(INFO,"createEveShape","Weird!! %s",n->GetName()); - } Daughters: for (Int_t idau = 0, ndau = n->GetNdaughters(); idau < ndau; ++idau) { diff --git a/DDRec/src/IDDecoder.cpp b/DDRec/src/IDDecoder.cpp index afe888b1e2239d4812e340b3e63d0da509e80210..07165a4b3ba2a7abf58de6531bf76e777444979f 100644 --- a/DDRec/src/IDDecoder.cpp +++ b/DDRec/src/IDDecoder.cpp @@ -50,7 +50,7 @@ CellID IDDecoder::cellIDFromLocal(const Position& local, const VolumeID volID) c // FIXME: direct lookup of transformations seems to be broken //const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volID); DetElement det = this->detectorElement(volID); - const TGeoMatrix& localToGlobal = det.worldTransformation(); + const TGeoMatrix& localToGlobal = det.nominal().worldTransformation(); localToGlobal.LocalToMaster(l, g); Position global(g[0], g[1], g[2]); return this->findReadout(det).segmentation().cellID(local, global, volID); @@ -67,7 +67,7 @@ CellID IDDecoder::cellID(const Position& global) const { // FIXME: direct lookup of transformations seems to be broken //const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volID); DetElement det = this->detectorElement(volID); - const TGeoMatrix& localToGlobal = det.worldTransformation(); + const TGeoMatrix& localToGlobal = det.nominal().worldTransformation(); localToGlobal.MasterToLocal(g, l); Position local(l[0], l[1], l[2]); return this->findReadout(det).segmentation().cellID(local, global, volID); @@ -84,7 +84,7 @@ Position IDDecoder::position(const CellID& cell) const { local.GetCoordinates(l); // FIXME: direct lookup of transformations seems to be broken //const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(cell); - const TGeoMatrix& localToGlobal = det.worldTransformation(); + const TGeoMatrix& localToGlobal = det.nominal().worldTransformation(); localToGlobal.LocalToMaster(l, g); return Position(g[0], g[1], g[2]); } @@ -243,7 +243,7 @@ DetElement IDDecoder::getClosestDaughter(const DetElement& det, const Position& if (det.volume().isValid() and det.volume().solid().isValid()) { double globalPosition[3] = { position.x(), position.y(), position.z() }; double localPosition[3] = { 0., 0., 0. }; - det.worldTransformation().MasterToLocal(globalPosition, localPosition); + det.nominal().worldTransformation().MasterToLocal(globalPosition, localPosition); if (det.volume().solid()->Contains(localPosition)) { result = det; } else { diff --git a/DDRec/src/SubdetectorExtensionImpl.cpp b/DDRec/src/SubdetectorExtensionImpl.cpp index a1983da6287ed41c701095db2a9966d45a7cd1df..1be6ad2874ef7e683457419b0935f1cfab8c3a43 100644 --- a/DDRec/src/SubdetectorExtensionImpl.cpp +++ b/DDRec/src/SubdetectorExtensionImpl.cpp @@ -132,7 +132,7 @@ double SubdetectorExtensionImpl::getZMin() const { if (box.isValid()) { Position local(0.,0.,-box->GetDZ()/2.); Position global; - det.localToWorld(local, global); + det.nominal().localToWorld(local, global); return global.z(); } } @@ -150,7 +150,7 @@ double SubdetectorExtensionImpl::getZMax() const { if (box.isValid()) { Position local(0.,0.,box->GetDZ()/2.); Position global; - det.localToWorld(local, global); + det.nominal().localToWorld(local, global); return global.z(); } } diff --git a/DDRec/src/Surface.cpp b/DDRec/src/Surface.cpp index 57f2408de0352b45df8773eb5eab16855d47caef..7ea093753af97ebb09859355a93ed220ba6323f7 100644 --- a/DDRec/src/Surface.cpp +++ b/DDRec/src/Surface.cpp @@ -723,7 +723,7 @@ namespace DD4hep { //=========== compute and cache world transform for surface ========== - const TGeoHMatrix& wm = _det.worldTransformation() ; + const TGeoHMatrix& wm = _det.nominal().worldTransformation() ; #if 0 // debug wm.Print() ; diff --git a/doc/LaTex/DDAlignManual.V2.pdf b/doc/LaTex/DDAlignManual.V2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..81bb564f997077851750b8eb33ec0f5167675515 Binary files /dev/null and b/doc/LaTex/DDAlignManual.V2.pdf differ diff --git a/doc/LaTex/DDAlignManual.V2.tex b/doc/LaTex/DDAlignManual.V2.tex new file mode 100644 index 0000000000000000000000000000000000000000..a963f4821b3686fd894a6d21d7c98672985c1fd8 --- /dev/null +++ b/doc/LaTex/DDAlignManual.V2.tex @@ -0,0 +1,1064 @@ +%============================================================================= +\documentclass[10pt,a4paper]{article} +% +\input{DD4hep-setup.tex} +% +\pagestyle{fancyplain}{\fancyfoot[C]{\sffamily{DDAlign User Manual}}} +% +\usepackage{amsmath} +\begin{document} +% +\mytitle{ +DDAlign +}{ +Alignment Support for the \\ +\vspace{0.5cm} +DD4hep Geometry Description \\ +\vspace{0.5cm} +Toolkit +\vspace{2cm} +} +{M. Frank \\ +{CERN, 1211 Geneva 23, Switzerland}} + +% +% +%== Abstract =============================================================== +\pagestyle{plain} +\pagenumbering{Roman} +\setcounter{page}{1} +\begin{abstract} +%============================================================================= + +\noindent +\normalsize +Experimental setups in High Energy Physics are highly complex assemblies +consisting of various detector devices typically called {\it{subdetectors}}. +Contrary to the ideal world, where all these components are of perfect shape +and at exact positions, existing devices have imperfections both in their +shape and their relative and absolute positions. These are described by the +alignment parameters.\\ +To still measure the detector response from particle collisions with the highest +possible precision, these imperfections are taken into account when converting +measured signals to space-points in the measurement devices. This procedure +is called {\it{detector alignment}}. \DDhep does not want to solve the exact +problem of the detector alignment itself, but rather support firstly algorithms +determining the alignment parameters and secondly support the application which +apply the measured alignment parameters and apply them to the ideal geometry +for further event data processing.\\ +We will present the tools to support the detector alignment procedures using +the \DDhep detector description toolkit. +The \DDA toolkit implements a modular and flexible approach to introduce and +access the alignment parameters.\\ +The design is strongly driven by easy of use; +developers of detector descriptions and applications using +them should provide minimal information and minimal specific +code to achieve the desired result. + +\end{abstract} + +\vspace{8cm} + +\begin{center} +{\large{\bf{ +\begin{tabular} {| l | l | l |} +\hline +\multicolumn{3}{| c |}{} \\[0.2cm] +\multicolumn{3}{| c |}{Document History} \\[0.2cm] +\multicolumn{3}{| c |}{} \\[0.2cm] +\hline + & & \\ +Document & & \\ +version & Date & Author \\[0.2cm] \hline + & & \\ +1.0 & 01/04/2014 & Markus Frank CERN/LHCb \\ +1.1 & 30/04/2014 & Markus Frank CERN/LHCb \\ +1.2 & 28/02/2017 & Markus Frank CERN/LHCb \\ + & & \\ \hline +\end{tabular} +}}} +\end{center} + +\clearpage +% +% +%== TOC ==================================================================== +\tableofcontents +\clearpage +% +% +%============================================================================= +% Manual +%============================================================================= +\pagenumbering{arabic} +\setcounter{page}{1} + +%============================================================================= +\section{Introduction} +\label{sec:ddalign-user-manual-introduction} +%============================================================================= +\noindent +This manual should introduce to the \DDA framework. +One goal of \DDA is to easily model geometrical imperfections applied to +the ideal geometry of detection devices as they are typically used in +high energy physics experiments. + +\noindent +To avoid confusion within this document, a few terms need to be defined +with respect to detector alignment: +\begin{itemize}\itemcompact +\item The {\it{ideal geometry}} describes the detector as it was designed. + Such a detector is an utopic object, which can never be realized in terms + of the placement of the individual components as such. +\item The {\it{actual geometry}} describes the real detector + in the configuration at + a given time. This includes all the changes i.e. {\it{deltas}} to the + {\it{ideal}} geometry. These changes are also called the + {\it{alignment parameters}}. These parameters typically are only valid + for a defined time interval. +\item {\it{Realignment}} defines the procedure to apply a new set of + temporary {\it{misalignment parameters}} to the ideal geometry. + Such a procedure + is applied, if a previously applied set of parameters is no longer valid with + respect to the event data to be processed. In short {\it{realignment}} + is necessary if the {\it{actual geometry}} of the detector is time dependent. +\end{itemize} + +\noindent +\DDA formalizes both the access and the application of alignment parameters +to the ideal geometry. The possibility to properly describe actual geometries +with respect to ideal geometries is essential to understand the detector response +to particle collisions and to connect response of geometrical independent +areas of the experiment e.g. to one single track. + +\noindent +In this manual we will shortly describe the model used +to describe an experiments detector description and then in more detail +document the support for alignment with its programming interfaces. + +%============================================================================= +\begin{figure}[h] + \begin{center} + \includegraphics[height=90mm] {DD4hep_classes.png} + \caption{Class diagram with the main classes and their relations + for the Generic Detector Description Model. The implementing + ROOT classes are shown in brackets.} + \label{fig:dd4hep-detector-model} + \end{center} +\end{figure} +\vspace{-0.1cm} +%============================================================================= +\subsection{Generic Detector Description Model} +\label{subsec:generic-model} +%============================================================================= + +\noindent +This is the heart of the DD4hep detector description toolkit. Its purpose is +to build in memory a model of the detector including its geometrical aspects +as well as structural and functional aspects. The design reuses the elements +from the ROOT geometry package and extends them in case required functionality +is not available. Figure~\ref{fig:dd4hep-detector-model} illustrates the main +players and their relationships~\cite{bib:DD4hep}. +Any detector is modeled as a tree of $Detector$ $Elements$, the entity +central to this design, which is represented in the implementation by +the $DetElement$ class~\cite{bib:LHCb-geometry}. It offers all +applications a natural entry point to any detector part of the experiment +and represents a complete sub-detector (e.g. TPC), a part of a +sub-detector (e.g. TPC-Endcap), a detector module or any other convenient +detector device. +The main purpose is to give access to the data associated +to the detector device. For example, if the user writes some TPC reconstruction +code, accessing the TPC detector element from this code will provide access +the all TPC geometrical dimensions, the alignment and calibration constants +and other slow varying conditions such as the gas pressure, end-plate +temperatures etc. The $Detector$ $Element$ acts as a data concentrator. +Applications may access the full experiment geometry and all connected data +through a singleton object called $LCDD$, which provides +management, bookkeeping and ownership to the model instances. + +\noindent +The geometry is implemented using the ROOT geometry classes, which are used +directly without unnecessary interfaces to isolate the end-user from the +actual ROOT based implementation. +\DDA allows client to access, manage and apply alignment parameters or +smallish changes to the ideal geometry. The mechanism to achieve this +is described in the following. + + +%============================================================================= +\begin{figure}[h] + \begin{center} + \includegraphics[height=75mm] {DD4hep_detelement_tree.png} + \caption{The object diagram of a hypothetical TPC detector showing in + parallel the $Detector$ $Element$ and the $Geometry$ hierarchy and the + relationships between the objects.} + \label{fig:dd4hep-hierarchies} + \end{center} + \vspace{-0.5cm} +\end{figure} + + +%============================================================================= +\subsection{Detector Element Tree and the Geometry Hierarchy} +\label{subsect:detelement-hierarchy} +%============================================================================= +\noindent +The geometry part of the detector description is delegated to the ROOT classes. +$Logical$ $Volumes$ are the basic objects used in building the geometrical hierarchy. +A $Logical$ $Volume$ is a shape with its dimensions and consist of a given material. +They represent unpositioned objects which store all information about +the placement of possibly embedded volumes. The same +volume can be replicated several times in the geometry. The $Logical$ $Volume$ +also represents a system of reference with respect to its containing volumes. +The reuse of instances of $Logical$ $Volumes$ for different placements +optimizes the memory consumption and detailed geometries for complex setups +consisting of millions of volumes may be realized with reasonable amount of memory. +The difficulty is to identify a given positioned volume +in space and e.g. apply alignment parameters to one of these volumes. +The relationship between the Detector Element and the placements +is not defined by a single reference to the placement, but the full path +from the top of the detector geometry model to resolve existing +ambiguities due to the reuse of $Logical$ $Volumes$. +Hence, individual volumes must be identified by their full path from mother +to daughter starting from the top-level volume. + +\noindent +The tree structure of +$Detector$ $Elements$ is a parallel structure to the geometrical hierarchy. +This structure will probably not be as deep as the geometrical one since +there would not need to associate detector information at very fine-grain +level - it is unlikely that every little metallic screw +needs associated detector information such as alignment, conditions, etc. +Though this screw and many other replicas must be described in the geometry +description since it may be important e.g. for its material contribution +in the simulation application. Thus, the tree of Detector Elements is +fully degenerate and each detector element object will be placed only +once in the detector element tree as illustrated for a hypothetical +Time Projection Chamber (TPC) detector in +Figure~\ref{fig:dd4hep-hierarchies} with an ideal geometry, +where no positioning corrections are applied to neither child. +It is essential to realize that the geometry tree in an ideal geometry is +degenerate contrary to the tree of detector elements. + +\noindent +It should be noted, that alignment parameters may be applied to any volume +of the ideal geometry. The alignment only affects the actual position of +a volume it is e.g. irrelevant if the volume is sensitive or not. + +%============================================================================= +\begin{figure}[h] + \begin{center} + \includegraphics[width=160mm] {DDAlign_detelement_aligned_tree.png} + \caption{The object diagram of a hypothetical TPC detector showing in + parallel the $Detector$ $Element$ and the $Geometry$ hierarchy and examples + of mispositioned detector parts: (a) mispositioned entire subdetector + (translation), (b) mispositioned end-cap (tilt) and (c) mispositioned + individual sectors within one endcap.} + \label{fig:dd4hep-aligned-hierarchies} + \end{center} +\end{figure} + + + +%============================================================================= +\subsection{Alignment Parameters of Detector Components} +\label{subsect:ddalign-intro-aligments} +%============================================================================= +\noindent +Alignment parameters never apply in the same way to {\it{all}} placements of the +same volume in this hierarchy. Hence, to (re-)align a volume in the hierarchy +means to logically lift a full branch of placements from the top volume down to +the element to be (re-)aligned out of this shared hierarchy and apply +a correction matrix to the last node. This procedure is illustrated in +Figure~\ref{fig:dd4hep-aligned-hierarchies}. Re-alignment of volumes may occur +at any level. In the above example of a TPC this results in the following effects: + +\noindent +\begin{itemize}\itemcompact +\item A realignment of the entire subdetector, i.e. the TPC as a whole, + would affect consequently move all contained children with respect to the + top level coordinate system. An example is shown in + Figure~\ref{fig:dd4hep-aligned-hierarchies} (a). A movement of the subdetector + would affect all transformation between local coordinates of any part of the + subdetector to the top level coordinate system. Such effects would be visible + at all stages of the data processing e.g. when translating signals from + particles into global coordinates. +\item A realignment of parts of a subdetector affects only the partial subdetector + itself and child volumes at lower levels. As in the example, where the entire + subdetector is moved, here only the sectors on one + side of the TPC would be affected + as shown in Figure~\ref{fig:dd4hep-aligned-hierarchies} (b). +\item In Figure~\ref{fig:dd4hep-aligned-hierarchies} (c) within one + end-cap of the TPC + individual sectors may not be positioned at the ideal location + (Figure~\ref{fig:dd4hep-aligned-hierarchies} (c) exaggerates: + ''flying sectors'' are a rather rare case in reality). + Finally also the sectors itself could be fragmented and be assemblies of other + shapes, which are not ideally placed and may need correction. +\end{itemize} +The origin of the volume misplacements may be many-fold: +\begin{itemize}\itemcompact +\item Elements may be weak and assembled parts move due to weak support + structures. + This is a common problem e.g. for tracking detectors, where heavy and solid + structures dramatically influence the measurement result. + Misplaced sectors could e.g. be the consequence of a deforming + end-cap frame due to the weight of the sectors. +\item Environmental conditions such as the temperature may influence the + position or the shape of a volume. +\item Some of the measurement equipment may be moved from a parking position into + a data taking position such as the two halves of the LHCb vertex detector. + Whereas the position of the sensors on each half are known to a very high + precision, the position of the absolute position of the two halves with + respect to the full experiment may change after each movement. +\end{itemize} +Changes to the volume placement do not only affect sensitive material +i.e. detector components with an active readout, but also passive material. +The placement of any volume, passive or active, may be corrected using \DDA. +The determination of the alignment parameters of passive components however may +be more difficult in the absence of located signals resulting +e.g. from the traversal of a track. + +\noindent +All effects resulting from such causes obviously need to be corrected in order to +fully explore the capabilities of the detection devices and to minimize +measurement errors. In general any deviation from the ideal position of a volume +can be described by two elementary transformations: +\begin{itemize}\itemcompact +\item a translation +\item a rotation around a pivot point. +\end{itemize} +giving a full transformation matrix of the form: +\begin{equation} +T = L * P * R * P^{-1} +\end{equation} +where +\begin{itemize}\itemcompact +\item $T$ is the full transformation in 3D space containing the change to the +exiting placement transformation. The existing placement is the placement +transformation of the volume with respect to the mother volume. +\item $L$ is a translation specifying the position change with respect to the + mother volume. +\item $P * R * P^{-1}$ describes a rotation around a pivot point specified + int he mother volume's coordinate system. +\item $P$ is the translation vector from the mother volumes origin to the + pivot point. The concept of a pivot point does not introduce a new + set of parameters. Pivot points only help to increase the numerical + precision. +\end{itemize} +Most of the changes do not require the full set of parameters. Very often +the changes only require the application of only a translation, only a +rotation or both with a pivot point in the origin. These simplifications +are supported in the user interface described in +Section~\ref{sec:ddalign-user-manual-ddalign-interface}. + +\noindent +Generally such a behavior can be achieved in two ways. The usage strongly depends +on the use-case required by the client: +\begin{enumerate} +\item either the ideal geometry in memory is changed directly to + reflect the measured geometry. This approach has the + disadvantage, that all measurement points on a daughter + volume can only be transformed to the global coordinate + system using one single transformation. Time-dependent changes of + these transformations cannot be modeled. Hence, for multi-threaded + systems this approach is of limited use. However, this is the + perfect approach to simulate distorted geometries. This approach + is naturally supported by the ROOT geometry toolkit. +\item The second possibility is to not modify the ideal geometry in memory, + but to provide instead transformations to move measured coordinates + to their correct place in space. This approach allows to keep + several - also time-dependent - transformations in memory. + Ideal to support multi-threaded data processing frameworks, + which become more and more popular. +\end{enumerate} + +\noindent +\DDA supports both possibilities as will be described in the following sections. + +%============================================================================= +\begin{figure}[t] + \begin{center} + \includegraphics[width=160mm] {DDAlign-iterative-misalignment.png} + \caption{The iterative application of alignment parameters as described + in Section~\ref{subsect:ddalign-intro-iterative-alignments}. + For each interval of validity + ($[T_0,T_1]$, $[T_2,T_3]$, $[T_4,T_5]$, ...) + a seperate set of alignment constants is applied to the ideal geometry. + The two steps to reset the misaligned geometry back to the ideal + geometry and + to re-apply a new set of alignment constants may be executed as + often as necessary when processing data from particle collisions.} + \label{fig:ddalign-aligned-iterative} + \end{center} +\end{figure} + +%============================================================================= +\subsection{Iterative Application of Alignments} +\label{subsect:ddalign-intro-iterative-alignments} +%============================================================================= +\noindent +In the general case a given set of alignment parameters is not static and +may very well change with time. For this reason it is highly important to +support not only one single realignment step. +Hence, the following scenario is an important use case: +\begin{enumerate}\itemcompact +\item Create the ideal detector using an ideal geometry. +\item Apply a set of alignment parameters for a given time + interval corresponding to the + time a set of particle collisions were collected in the experiment. +\item Process the set of collected particle collisions. +\item Reset the misaligned detector to the ideal. +\item Choose new event data input corresponding to another time interval + and restart at item 2. +\end{enumerate} +Graphically this use case is illustrated in +Figure~\ref{fig:ddalign-aligned-iterative}. In +Section~\ref{sec:ddalign-user-manual-ddalign-interface} the implementation +to realize this use case is described. + +%============================================================================= +\subsection{Procedures to Determine Alignment Parameters} +\label{subsect:ddalign-intro-determine-alignment-params} +%============================================================================= +\noindent +Typically the determination of alignment parameters requires a starting point +which is not necessarily identical to the ideal position of a +volume~\cite{bib:chris-parkes-priv-comm}. These volume positions are the result +of a survey measurement or the result of internal position measurements +of a sub-volume within a sub-detector e.g. on a measurement bench. +In the following we call these parameters {\it{survey parameters}}. +{\it{Survey parameters}} default to the ideal volume position if not supplied, +alternatively, if set, to the provided position. {\it{Survey parameters}} +are, like the alignment parameters, provided in terms of {\it{changes}} with +respect to the ideal position and hence may be treated in a similar way. + +\noindent +The survey parameters are - like alignment parameters - accessible to users +through the interface offered by the $DetElement$ objects. + + +%============================================================================= +\subsection{Simulation of Non-Ideal, Real Detector Geometries} +\label{subsect:ddalign-intro-simulate-misaligned-geometries} +%============================================================================= +\noindent +It is a standard procedure in high energy physics to at least verify +the measured detector response of a given physics process in particle +collisions with the expected simulated detector response. +For most purposes the simulation of an ideal detector is certainly is +sufficient - though not describing the full truth. Sometimes however, the +detector geometry must be simulated with a geometry as close to the +known geometry as possible. + +\noindent +The simulation of such a geometry with applied alignment parameters can +rather easily be realized using using the \DDhep, \DDA and the \DDG frameworks: +\begin{itemize}\itemcompact +\item The ideal geometry is constructed using the standard procedures + of \DDhep~\cite{bib:DD4hep}. +\item Then the alignment parameters are applied and finally +\item the corrected geometry is translated to $Geant4$~\cite{bib:geant4} + using the \DDG~\cite{bib:DDG4} package. + All particle collisions simulated with this translated geometry + correspond to the modified geometry including the geometry + modifications. +\end{itemize} +There is a caveat though: The application of alignment parameters can +easily create volume overlaps, which are highly disliked by the $Geant4$ +runtime. If the above described procedure is applied, it is highly advised +to check the resulting geometry for overlaps. Both, +$ROOT$~\cite{bib:ROOT-tgeo} and $Geant4$~\cite{bib:geant4} offer tools +to perform such tests. + +\noindent +To simulate distorted geometries clients should use the +$Global$ $Alignment$ interface described in +section~\ref{sec:ddalign-user-manual-ddalign-global-interface}. + +\newpage +%============================================================================= +\section{The Global Alignment Interface} +\label{sec:ddalign-user-manual-ddalign-global-interface} +%============================================================================= + +\noindent +In this chapter will be documented how to use the $Global$ $Alignment$ +interface of \DDA. As already mentioned in +section~\ref{}, this interface allows to alter the layout of the +geometry in memory. Use cases are e.g. the simulation of +non-ideal geometries. + +\noindent +Global alignment can be applied to detector elements using a specialized +interface $GlobalDetectorAlignment$~\footnote{See the header file +$DDAlign/GlobalDetectorAlignment.h$ for details.}. This interface +provides the API to apply global changes to the geometry provided +the presence of alignment parameters as shown in the following +code snippet: + +\begin{code} + /// First install the global alignment cache to build proper transactions + GlobalAlignmentCache* cache = GlobalAlignmentCache::install(lcdd); + + /// Now create the tranaction context. There may only be one context present + GlobalAlignmentStack::create(); + GlobalAlignmentStack& stack = GlobalAlignmentStack::get(); + + /// Now we can push any number of global alignment entries to the stack: + DetElement elt = ...detector element containing the volume to be re-aligned ...; + string placement = "/full/path/to/the/volume/to/be/realigned"; + Alignments::Delta delta = ...; + double ovl = allowed_overlap_in cm; // e.g. 0.001; + + // Create the new stack entry and insert it to the stack + dd4hep_ptr<StackEntry> entry(new StackEntry(elt,placement,delta,ovl)); + stack->insert(entry); + + /// Finally we commit the stacked entries and release the stack. + cache->commit(stack); + GlobalAlignmentStack::get().release(); +\end{code} + +\noindent +{\bf{Explanation:}} \\ +\begin{tabular} {l||p{0cm}} +\docline{Line}{} +\docline{2}{Install the $GlobalAlignmentCache$. Required to be done +once. The object is registered to the LCDD instance and kept there.} +\docline{2-7}{The fact that the classes $GlobalAlignmentCache$ and +$GlobalAlignmentStack$ are singletons is not a fundamental issue. +However, we want to call the XML parser (or other database sources) +iteratively and currently cannot chain a context (stack).} +\docline{15-19}{The created stacked entries are automatically released +once the transaction is committed.} +\end{tabular} + +\noindent +%============================================================================= +\subsubsection{Loading Global Geometrical Imperfections from XML} +\label{sec:ddalign-user-manual-global-misalignment-manip-xml} +%============================================================================= +\noindent +In this section we describe how to load geometry imperfections and to apply them +to an existing geometry. Loading the XML file is done automatically using the +standard XML loader plugin provided by \DDhep. This plugin is interfaced to +the {\tt LCDD} instance and invoked from code as follows: +\begin{code} + LCDD& lcdd = ....; + lcdd.fromXML("file:AlepTPC_alignment.xml"); +\end{code} +To fully exploit the capabilities it is important to understand the interpreted +structure of the XML file being processed. At the top level of the primary +input file (i.e. the file given to the XML processor) the following structure +is expected: +\begin{code} +<global_alignment> + <!-- Open the alignment transaction --> + <open_transaction/> + <subdetectors> <!-- Container with the list of subdetectors to be processed. --> + <detelement path="TPC" reset="true" reset_children="true"> + <!-- Move the entire TPC in the world volume --> + <position="" x="30" y="30" z="80"/> + + <!-- Now add daughter detector elements --> + + <!-- Twist a bit the entire endcap by rotating it around the x and the y axis --> + <detelement path="/world/TPC/TPC_SideA" check_overlaps="false"> + <position x="0" y="0" z="0"/> + <rotation x="-0.2" y="-0.2" z="0"/> + <!-- Apply corrections of type Translation*Rotation to a single sector + <detelement path="TPC_SideA_sector02" check_overlaps="true"> + <position x="0" y="0" z="0"/> + <rotation x="0.5" y="0.1" z="0.2"/> + </detelement> + </detelement> + + <!-- And the full shooting match of transformations for this sector --> + <detelement path="TPC_SideA/TPC_SideA_sector03" check_overlaps="true"> + <position x="0" y="0" z="290.0*mm"/> + <rotation x="0" y="pi/2" z="0"/> + <pivot x="0" y="0" z="100"/> + </detelement> + + .... + + <!-- Include alignment files to be processed in the context of the "TPC" DetElement + <include ref="file-name"/> + + </detElement> + </subdetectors> + + <!-- Include alignment files to be processed at the top level context --> + <include ref="file-name"/> + + <!-- Close the alignment transaction --> + <close_transaction/> +</global_alignment> +\end{code} + +\noindent +The structure of the alignment file explained quickly: + +\begin{tabular} {l||p{0cm}} +\docline{Line}{} +\docline{1}{The {\tt root} tag for the primary alignment file is {\tt <alignment/>}. + The primary tag name is mandatory and actually is used to invoke the correct interpreter.} +\docline{2,41}{Trigger the alignment transaction by specifying the transaction tags in + the main XML file.} +\docline{4}{Defintion of the set of {\tt subdetectors} to be processed. A valid alias for this + directove is {\tt detelements}.} +\docline{5}{The first subdetector: {\tt TPC}. The subdetector tag is {\tt detelement} + Each {\tt detelement} may recursively contain other {\tt detelement} tags. + as they were defined in the {\tt DetElement} hierarchy. + Internal {\tt detelement} elements are processed in the context of the outer + element i.e. pathes may be specified relative to the parent or as absolute pathes + with respect to the world (starting with a '/').} +\docline{7}{Global movement of the TPC} +\docline{12-20}{Realignment entry for the TPC endcap A named {\tt TPC\_SideA}} +\docline{16-19}{Realignment entry for sector named {\tt TPC\_SideA\_sector02} of the TPC endcap A. + Here the sector is specified directly as a daughter of the endcap. The name + of the {\tt DetElement} is relative to the parent.} +\docline{23-27}{Realignment entry for sector named {\tt TPC\_SideA\_sector03} of the TPC endcap A + containing a full transformation: $Translation * Pivot * Rotation * Pivot^{-1}$} +\docline{32}{Optionally {\tt detelement} elements may include other alignment files specifying + lower volume levels. These files are interpreted in the context of the calling + detector element. } +\docline{38}{Optionally the subdetector alignment constants may be fragmented + into several files, which can be loaded using the {\tt include} + directive. Each file could for example describe one single detector.} +\end{tabular} + +\vspace{0.5cm} +\noindent +The specification of any transformation element is optional: +\begin{itemize}\itemcompact +\item The absence of a translation implies the origin (0,0,0) +\item The absence of a pivot point implies the origin (0,0,0) +\item The absence of a rotation implies the identity rotation. + Any supplied pivot point in this case is ignored. +\end{itemize} +The absence of a transformation element is absolutely legal and does not +issue any warning or error. + +\noindent +All transformations describe the change of placement with respect to the +coordinate system of the closest mother-volume in the volume hierarchy, +i.e. translations, rotations and pivot points are local to the +mother coordinate system. + +\newpage +\noindent +Included files may directly start with the {\tt root} tags {\tt subdetectors}, +{\tt detelements} or {\tt detelement} and may recursively include other +files. Except for the top level these files are processed in the calling context. + +\vspace{1cm} +\noindent +And finally, the result: +%============================================================================= +\begin{figure}[h] + \begin{center} + \includegraphics[width=160mm] {DDAlign-misaligned-TPC.png} + \caption{The ALEPH TPC after the import of the alignment file. + Note, that the geometry in $memory$ changed. The original + geometry desciption is no longer present. + } + \label{fig:dd4hep-aligned-hierarchies} + \end{center} +\end{figure} + + +\noindent +%============================================================================= +\subsubsection{Export Geometrical Imperfections to XML} +\label{sec:ddalign-user-misalignment-expotr-xml} +%============================================================================= +\noindent +In this section we describe how to export geometry imperfections to an XML file. +A small helper class {\tt AlignmentWriter} achieves this task as shown in +the snippet: +\begin{code} + LCDD& lcdd = ....; + DetElement top = ....; + if ( top.isValid() ) { + AlignmentWriter wr(lcdd); + return wr.write(top,output,enable\_transactions); + } +\end{code} +This code will dump all alignment constants contained in the {\tt DetElement} +hierarchy of {\tt top} to the output file {\tt output}. The optional argument +{\tt enable\_transactions} (default: true) will add the tags +{\tt <open\_transaction/>} and {\tt <close\_transaction/>} to the output +file. The output file conforms to the specifications described in +Section~\ref{sec:ddalign-user-manual-misalignment-manip-xml} and may later +be imported by another process. + + + + +\vspace{3cm} +\noindent +FIXME: This chapter sort of still has to be written!!!! + +%%%% Here we are now. +\vspace{3cm} + +\newpage +%============================================================================= +\section{The Local Alignment Interface} +\label{sec:ddalign-user-manual-ddalign-interface} +%============================================================================= + +\noindent +\DDA implements a machinery to apply and access the alignment parameters +describing the difference between an ideal detector given by an ideal geometry +and the geometry of the actually built assembly in real life. +To ease its usage for the clients and to shield clients from the +internals when actually dealing with realigned geometries, a set of +helper classes was designed. The access to the alignment parameters +in read-only mode was separated from the import or export thereof. + +\noindent +As a basic concept within \DDhep any {\it{sizable}} detector component +can be realigned. {\it{Sizable}} as a rule of thumb is anything, which +is manufactured as an individual piece and which you may ''hold in your hands''. +Such objects are also described by a $detector$ $element$ of type {\tt DetElement}. +An example is e.g. a single silicon wafer of a tracking device or the entire +tracking detector itself. +The access to the alignment parameters is possible from each {\tt DetElement} +instance as described in Section~\ref{sec:ddalign-user-manual-misalignment-access}. +The interface assumes ''planar'' alignment parameters i.e. the shape of +a given volume does not change~\footnote{This is a restriction to the +possibilities provided by the ROOT implemetation~\cite{bib:ROOT-tgeo} +based on experience~\cite{bib:chris-parkes-priv-comm}. +If at a later time the need arises the provided alignment interface may +be extended to support shape changes.}. + +\noindent +As mentioned earlier, in the local alignment \DDA allowed to retrieve +time dependent alignment parameters and transformations. This time +dependency was relatively easy achieved by re-using the conditions +mechanism from \DDC. In this spirit Alignment transformations are +practically no different from conditions like temperatures, pressures etc. +To access the $alignment$ $conditions$ clearly not only some +identifier must be provided, but also a $interval$ $of$ $validity$, +which defines from which point in the past to which point in the future +the required alignment constants may be applied. + +\noindent +Please be aware that the extensive use of misalignments is highly memory +consuming. + +\noindent +%============================================================================= +\subsection{Access to Alignment Parameters from the Detector Element} +\label{sec:ddalign-user-manual-misalignment-access} +%============================================================================= + +\noindent +The $DetAlign$ class as shown in Figure~\ref{fig:dd4hep-detector-model} +gives the user access to the alignment structure of type $Alignment$ as +illustrated in the following example: +\begin{code} + ConditionsSlice slice = ... // Prepared slice containing all condiitons + DetElement wafer_det = ... // Valid handle to a detector element + DetAlign wafer = wafer_det; + Alignment wafer_alignment = wafer.get(); + if ( wafer_alignment.isValid() ) { + // This wafer's placement differs from the ideal geometry when + // alignment parameters are present. + + // Access the misalignment transformation with respect to the parent volume: + Transform3D tr = wafer_alignment.toMotherDelta(); + } +\end{code} +The access to details of an invalid alignment object results in a runtime +exception. The following calls allow clients to access alignment information +from the $DetElement$ structure: +\begin{code} + /// Access to the actual alignment information + Alignment alignment() const; + + /// Access to the survey alignment information + Alignment surveyAlignment() const; +\end{code} +The call to $alignment()$ return the parameters $applied$ to the the existing +ideal geometry. The call $surveyAlignment()$ returns optional constants used +to perform numerical calculations as described in +section~\ref{subsect:ddalign-intro-determine-alignment-params}. + +\noindent +All functionality of the DetElement, which depends on applied alignment parameters +are automatically updated in the event of changes. These are typically the geometry +transformations with respect to the mother- and the world volume: +\begin{code} + /// Create cached matrix to transform to world coordinates + const TGeoHMatrix& worldTransformation() const; + + /// Create cached matrix to transform to parent coordinates + const TGeoHMatrix& parentTransformation() const; + + /// Transformation from local coordinates of the placed volume to the world system + bool localToWorld(const Position& local, Position& global) const; + + /// Transformation from local coordinates of the placed volume to the parent system + bool localToParent(const Position& local, Position& parent) const; + + /// Transformation from world coordinates of the local placed volume coordinates + bool worldToLocal(const Position& global, Position& local) const; + + /// Transformation from world coordinates of the local placed volume coordinates + bool parentToLocal(const Position& parent, Position& local) const; +\end{code} +it is worth noting that the update of cached information is performed by the $DetElement$ +objects, other user defined cached information is {\bf{not}} updated. To update +user caches it is mandatory to provide a user defined update callback to the $DetElement$: +\begin{code} + template <typename Q, typename T> + void callAtUpdate(unsigned int type, Q* pointer, + void (T::*pmf)(unsigned long typ, DetElement& det, void* opt_par)) const; +\end{code} + +\noindent +The interface of the $Alignment$ structure to access detector +alignment parameters is as follows (see also the corresponding header file DD4hep/Alignment.h): +\begin{code} + /// Number of nodes in this branch (=depth of the placement hierarchy from the top level volume) + int numNodes() const; + + /// Access the placement of this node + PlacedVolume placement() const; + + /// Access the placement of the mother of this node + PlacedVolume motherPlacement(int level_up = 1) const; + + /// Access the placement of a node in the chain of placements for this branch + PlacedVolume nodePlacement(int level=-1) const; + + /// Access the currently applied alignment/placement matrix with respect to the world + Transform3D toGlobal(int level=-1) const; + + /// Transform a point from local coordinates of a given level to global coordinates + Position toGlobal(const Position& localPoint, int level=-1) const; + + /// Transform a point from global coordinates to local coordinates of a given level + Position globalToLocal(const Position& globalPoint, int level=-1) const; + + /// Access the currently applied alignment/placement matrix with respect to mother volume + Transform3D toMother(int level=-1) const; + + /// Access the currently applied alignment/placement matrix (mother to daughter) + Transform3D nominal() const; + + /// Access the currently applied correction matrix (delta) (mother to daughter) + Transform3D delta() const; + + /// Access the inverse of the currently applied correction matrix (delta) (mother to daughter) + Transform3D invDelta() const; +\end{code} +\begin{itemize}\itemcompact +\item The calls in line 3-8 allow access to the relative position of the $nth.$ element + in the alignment stack with respect to its next level parent. + Element $numNodes()-1$ denotes the lowest level and element $0$ is the world + volume. The default argument $(-1)$ addresses the lowest placement in the hierarchy. +\item Calls in line 9-12 allow to access/execute transformations from a given level + in the placement hierarchy to coordinates in the top level volume (world). +\item The call in line 14 allows to transform a global coordinate to the local coordinate + system in a given level of the hierarchy. +\item The call $toMother$ in line 16 returns the local transformation of the node at + a given level to the mother's coordinate system. +\item The calls in line 17-20 give access to the nominal placement matrix of the realigned + node with respect to the parent volume and the changes thereof. +\end{itemize} +Besides these convenience calls the full interface to the class {\tt TGeoPhysicalNode}, +which implements in the ROOT geometry package alignment changes, is accessible +from the $Alignment$ handle using the overloaded $operator->()$. +Further documentation is available directly from the \tgeo{TGeoPhysicalNode}{ROOT site}. + +\noindent +%============================================================================= +\subsection{Manipulation of Alignment Parameters} +\label{sec:ddalign-user-manual-misalignment-manip} +%============================================================================= +There are multiple possibilities to apply alignment parameters: +\begin{itemize}\itemcompact +\item The pedestrian way ''by hand'' using C++ as described in + Subsection~\ref{sec:ddalign-user-manual-misalignment-manip-cxx} +\item Loading a whole set of misalignment constants from XML, the ''poor man's'' database. + This mechanism is described in + Subsection~\ref{sec:ddalign-user-manual-misalignment-manip-xml} +\item Loading a whole set of misalignment constants from a database. + This possibility depends heavily on the database and its schema used. + A typical use case is to load misalignment constants depending on the + experiment conditions at the time the event data were collected. + \DDA does not provide an implementation. + This possibility here is only mentioned for completeness and will be subject + to further developments to support conditions in \DDhep. +\end{itemize} + +\noindent +%============================================================================= +\subsubsection{Manipulation of Alignment Parameters for Pedestrians using C++} +\label{sec:ddalign-user-manual-misalignment-manip-cxx} +%============================================================================= +\noindent +In this section we describe how to apply geometry imperfections to an existing +detector geometry in memory using {\tt C++}. To apply misalignment to an existing +geometry two classes are collaborating, the {\tt AlignmentCache} attached to +the geometry container {\tt LCDD} and a temporary structure the {\tt AlignmentStack}. +The {\tt AlignmentCache} allows to access all existing alignment entries +based on their subdetector. +The {\tt AlignmentStack} may exist in exactly one instance and is used to +insert a consistent set of alignment entries. Consistency is important because +changes may occur at any hierarchical level and internal transformation caches +of the ROOT geometry package must be revalidated for all branches containing +a higher level node. +{\bf For this reason it is highly advisable to apply realignment constants +for a complete subdetector.} +Note that this restriction is not imposed, in principle a consistent set +of misalignments may be applied at any level of the geometry hierarchy. + +\noindent +Though the application of alignment is much simpler using XML files, the following +description should give an insight on the mechanisms used behind the scene and +to understand the concept. + +\noindent +Any manipulations are transaction based must be embraced by the following two calls +opening and closing a transaction: +\begin{code} +// Required include file(s) +#include "DDAlign/AlignmentCache.h" + + LCDD& lcdd = ....; + AlignmentCache* cache = lcdd.extension<Geometry::AlignmentCache>(); + + // First things first: open the transaction. + cache->openTransaction(); + + // Prepare the entry containing the alignment data + AlignmentStack::StackEntry* entry = .....; + //.... and add the element to the AlignmentStack ..... + AlignmentStack::insert(entry); + + // Finally close the transaction. At this moment the changes are applied. + cache->closeTransaction(); +\end{code} +In the following we describe the mechanism to create and prepare the +{\tt StackEntry} instances of the above code snippet. The calls to open and close +the alignment transaction do not have to be in the same code fragment where also +the alignment entries are prepared. However, all changes are only applied when +the transaction is closed. The alignment entries do not necessarily have to +be prepared in the sequence of the hierarchy they should be applied, internally +the entries are re-ordered and follow the geometry hierarchy top to bottom +i.e. mother volumes are always re-aligned {\it\bf before} the daughters +are re-aligned. + +\noindent +The {\tt StackEntry} instances carry all information to apply the re-alignment +of a given volume. This information contains: +\begin{itemize}\itemcompact +\item The transformation matrix describing the positional change of the volume + with respect to its mother volume. +\item The placement path of the volume to be realigned. +\item A flag to reset the volume to its ideal position {\it\bf before} the + change is applied. +\item A flag to also reset all daughter volumes to their + ideal position {\it\bf before} the change is applied. +\item A flag to check for overlaps after the application of the change and +\item the actual precision used to perform this check. +\end{itemize} + +\noindent +The {\tt ROOT::Math} library provides several ways to construct the required +3D transformation as described in Section~\ref{subsect:ddalign-intro-aligments}: +\begin{code} +// Required include file(s) +#include "DD4hep/Objects.h" + + Position trans(x_translation, y_translation, z_translation); + RotationZYX rot (z_angle, y_angle, x_angle); + Translation3D pivot(x_pivot, y_pivot, z_pivot); + + Transform3D trafo; + /// Construct a 3D transformation for a translation and a rotation around a pivot point: + trafo = Transform3D(Translation3D(trans)*pivot*rot*(pivot.Inverse())); + + /// Construct a 3D transformation for a translation and a rotation around the origin + trafo = Transform3D(rot,pos); + + /// Construct a 3D transformation for a rotation around a pivot point + trafo = Transform3D(piv*rot*(piv.Inverse())); + + /// Construct a 3D transformation for a rotation around the origin + trafo = Transform3D(rot); + + /// Construct a 3D transformation for simple translation + trafo = Transform3D(pos); + +\end{code} + +\noindent +The following code snippet shows how to extract this information from the +{\tt DetElement} and prepare such a {\tt StackEntry} instance: +\begin{code} +// Required include file(s) +#include "DDAlign/AlignmentStack.h" + + // Prepare the entry containing the alignment data + typedef AlignmentStack::StackEntry Entry; + /// Detector element to be realigned + DetElement element = ...; + /// The transformation describing the relative change with respect to the mother volume + Transform3D trafo = ...; + /// Instantiate a new alignment entry + Entry* entry = new Entry(element); + entry->setTransformation(trafo) // Apply the transformation matrix + .applyReset(/* argument default: true */) // Set the reset flag + .applyResetChildren(/* argument default: true */) // Set the daughter reset flag + .checkOverlaps(/* argument default: true */) // Set flag to check overlaps + .overlapPrecision(0.001/mm); // With this precision in mm + + /// Now add the entry to the alignment stack: + AlignmentStack::insert(entry); +\end{code} +The constructor will automatically determine the volumes placement path +from the {\tt DetElement}. Then the transformation is applied and the flags +to reset the volume, its children and to trigger the overlap checks with +the given precision. + +\noindent +When passing the entry to the {\tt AlignmentStack} the {\tt AlignmentStack} +takes ownership and subsequently the entry is deleted after being applied to +the geometry. For further shortcuts in the calling sequence please consult the +{\tt AlignmentStack} header file. + + + +\newpage +%============================================================================= +\begin{thebibliography}{9} +\bibitem{bib:DD4hep} M. Frank et al, "DD4hep: A Detector Description Toolkit + for High Energy Physics Experiments", + International Conference on Computing in High Energy and Nuclear Physics + (CHEP 2013), \\ + Amsterdam, Netherlands, 2013, proceedings. + +\bibitem{bib:LHCb-geometry} S. Ponce et al., + "Detector Description Framework in LHCb", + International Conference on Computing in High Energy and Nuclear Physics (CHEP 2003), + La Jolla, CA, 2003, proceedings. +\bibitem{bib:chris-parkes-priv-comm} C. Parkes, private communications. +\bibitem{bib:DDG4} M.Frank, "DDG4 - A Simulation Toolkit for High Energy + Physics Experiments using Geant4 \\ + and the DD4hep Geometry Description". +\bibitem{bib:ROOT-tgeo} R.Brun, A.Gheata, M.Gheata, "The ROOT geometry package",\\ + Nuclear Instruments and Methods {\bf{A}} 502 (2003) 676-680. +\bibitem{bib:geant4} S. Agostinelli et al., + "Geant4 - A Simulation Toolkit", \\ + Nuclear Instruments and Methods {\bf{A}} 506 (2003) 250-303. + +\end{thebibliography} +%============================================================================= +\end{document} diff --git a/doc/LaTex/DDConditionsManual.tex b/doc/LaTex/DDConditionsManual.tex index bcf205a663a5103d20afba07b1d142de0f88029a..c6cfc36ed8c3080831a15e2e45df6191f6b0145c 100644 --- a/doc/LaTex/DDConditionsManual.tex +++ b/doc/LaTex/DDConditionsManual.tex @@ -93,7 +93,19 @@ version & Date & Author \\[0.2cm] \hline \label{sec:ddalign-user-manual-introduction} %============================================================================= \noindent -This manual should introduce to the \DDA framework. +In a high energy physics experiment the data originating from particle collisions +(so called $Event$-$data$) in most cases require supplementary, mostly +environmental, calibration- or alignment data to extract the physics content +from the recorded event data. These supplementary data are time-dependent and +typically called $conditons$. The ability of an experiment to produce correct +and timely results depends on the complete and efficient availability of +needed conditions for each stage of data handling. +This manual should introduce to the \DDC toolkit, which provides access +to conditions data within the \DDH data structures. + + + + One goal of \DDA is to easily model geometrical imperfections applied to the ideal geometry of detection devices as they are typically used in high energy physics experiments. diff --git a/examples/AlignDet/src/AlignmentExample_read_xml.cpp b/examples/AlignDet/src/AlignmentExample_read_xml.cpp index 607a2b407a66ad5f3f501041ba04a1d9a451a2e5..fa882a6f309aa2ce2ae03a9fa9dd4dfc993004d3 100644 --- a/examples/AlignDet/src/AlignmentExample_read_xml.cpp +++ b/examples/AlignDet/src/AlignmentExample_read_xml.cpp @@ -53,7 +53,7 @@ static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { /// Help printout describing the basic command line interface cout << "Usage: -plugin <name> -arg [-arg] \n" - " name: factory name DD4hep_AlignmentExample2 \n" + " name: factory name DD4hep_AlignmentExample_read_xml \n" " -input <string> Geometry file \n" " -deltas <string> Alignment deltas (Conditions \n" "\tArguments given: " << arguments(argc,argv) << endl << flush;