From 74f0dc8b97a2bc9440d9fa86433837029b669699 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 21 Sep 2016 19:13:04 +0200 Subject: [PATCH] Add global alignment example --- DDAlign/include/DDAlign/AlignmentOperators.h | 2 +- DDAlign/include/DDAlign/AlignmentStack.h | 56 +++---- DDAlign/include/DDAlign/AlignmentTags.h | 1 + DDAlign/include/DDAlign/DetectorAlignment.h | 77 ---------- DDAlign/src/AlignmentOperators.cpp | 85 ++++++----- DDAlign/src/AlignmentStack.cpp | 95 ++---------- DDAlign/src/AlignmentWriter.cpp | 4 +- ...gnment.cpp => GlobalDetectorAlignment.cpp} | 98 +++++++----- DDAlign/src/plugins/AlignmentParser.cpp | 142 ++++++++++-------- DDCore/include/DD4hep/AlignmentData.h | 27 +++- DDCore/include/DD4hep/GlobalAlignment.h | 2 +- DDCore/include/XML/XMLElements.h | 2 + DDCore/src/AlignmentData.cpp | 2 +- DDCore/src/XML/XMLElements.cpp | 10 ++ DDCore/src/plugins/StandardPlugins.cpp | 4 +- UtilityApps/src/run_plugin.h | 18 ++- examples/AlignDet/CMakeLists.txt | 32 +++- .../AlignDet/compact/AlephTPC_alignment.xml | 5 +- examples/AlignDet/compact/AlephTPC_reset.xml | 4 +- 19 files changed, 298 insertions(+), 368 deletions(-) delete mode 100644 DDAlign/include/DDAlign/DetectorAlignment.h rename DDAlign/src/{DetectorAlignment.cpp => GlobalDetectorAlignment.cpp} (69%) diff --git a/DDAlign/include/DDAlign/AlignmentOperators.h b/DDAlign/include/DDAlign/AlignmentOperators.h index 596e108ab..9d6276c8a 100644 --- a/DDAlign/include/DDAlign/AlignmentOperators.h +++ b/DDAlign/include/DDAlign/AlignmentOperators.h @@ -43,7 +43,7 @@ namespace DD4hep { /// Initializing functor constructor AlignmentOperator(AlignmentCache& c, Nodes& n) : cache(c), nodes(n) {} /// Insert alignment entry - void insert(Alignment alignment) const; + void insert(GlobalAlignment alignment) const; }; /// Select alignment operations according to certain criteria diff --git a/DDAlign/include/DDAlign/AlignmentStack.h b/DDAlign/include/DDAlign/AlignmentStack.h index 87be8a206..052d77960 100644 --- a/DDAlign/include/DDAlign/AlignmentStack.h +++ b/DDAlign/include/DDAlign/AlignmentStack.h @@ -15,7 +15,7 @@ #define DD4HEP_ALIGNMENT_ALIGNMENTSTACK_H // Framework include files -#include "DD4hep/Detector.h" +#include "DD4hep/Alignments.h" #include "DD4hep/Objects.h" #include "DD4hep/Memory.h" @@ -35,12 +35,12 @@ namespace DD4hep { class AlignmentStack { public: enum { - OVERLAP_DEFINED = 1<<0, - MATRIX_DEFINED = 1<<1, - CHECKOVL_DEFINED = 1<<2, - CHECKOVL_VALUE = 1<<3, - RESET_VALUE = 1<<4, - RESET_CHILDREN = 1<<5, + OVERLAP_DEFINED = 1<<20, + MATRIX_DEFINED = 1<<21, + CHECKOVL_DEFINED = 1<<22, + CHECKOVL_VALUE = 1<<23, + RESET_VALUE = 1<<24, + RESET_CHILDREN = 1<<25, ____LLLAST = 1<<31 } Flags; @@ -52,28 +52,16 @@ namespace DD4hep { */ struct StackEntry { /// Reference to the detector element - DetElement detector; - /// 3-D Transformation matrix for the volume - Transform3D transform; + DetElement detector; + /// Delta transformation to be applied + Delta delta; /// Path to the misaligned volume - std::string path; + std::string path; /// Parameter for overlap checking - double overlap; - /// Flag containing various encodings - int flag; + double overlap; /// Fully initializing constructor - StackEntry(const DetElement& p, const std::string& placement, const Transform3D& t, double ov, int flg); - /// Constructor with partial initialization - StackEntry(DetElement element, bool rst=true, bool rst_children=true); - /// Constructor with partial initialization - StackEntry(DetElement element, const Transform3D& trafo, bool rst=true, bool rst_children=true); - /// Constructor with partial initialization - StackEntry(DetElement element, const Position& translation, bool rst=true, bool rst_children=true); - /// Constructor with partial initialization - StackEntry(DetElement element, const RotationZYX& rot, bool rst=true, bool rst_children=true); - /// Constructor with partial initialization - StackEntry(DetElement element, const Position& translation, const RotationZYX& rot, bool rst=true, bool rst_children=true); + StackEntry(DetElement p, const std::string& placement, const Delta& t, double ov); /// Copy constructor StackEntry(const StackEntry& e); /// Default destructor @@ -82,25 +70,19 @@ namespace DD4hep { /// Assignment operator StackEntry& operator=(const StackEntry& e); - /// Check a given flag - bool checkFlag(int mask) const { return (flag&mask) == mask; } /// Check if the overlap flag checking is enabled - bool overlapDefined() const { return checkFlag(OVERLAP_DEFINED); } + bool overlapDefined() const { return delta.checkFlag(OVERLAP_DEFINED); } /// Check if the overlap flag checking is enabled - bool checkOverlap() const { return checkFlag(CHECKOVL_DEFINED); } + bool checkOverlap() const { return delta.checkFlag(CHECKOVL_DEFINED); } /// Check if the overalp value is present - bool overlapValue() const { return checkFlag(CHECKOVL_VALUE); } + bool overlapValue() const { return delta.checkFlag(CHECKOVL_VALUE); } /// Check if this alignment entry has a non unitary transformation matrix - bool hasMatrix() const { return checkFlag(MATRIX_DEFINED); } + bool hasMatrix() const { return delta.checkFlag(MATRIX_DEFINED); } /// Check flag if the node location should be reset - bool needsReset() const { return checkFlag(RESET_VALUE); } + bool needsReset() const { return delta.checkFlag(RESET_VALUE); } /// Check flag if the node location and all children should be reset - bool resetChildren() const { return checkFlag(RESET_CHILDREN); } + bool resetChildren() const { return delta.checkFlag(RESET_CHILDREN); } - /// Attach transformation object - StackEntry& setTransformation(const Transform3D& trafo); - /// Instruct entry to ignore the transformation - StackEntry& clearTransformation(); /// Set flag to reset the entry to it's ideal geometrical position StackEntry& setReset(bool new_value=true); /// Set flag to reset the entry's children to their ideal geometrical position diff --git a/DDAlign/include/DDAlign/AlignmentTags.h b/DDAlign/include/DDAlign/AlignmentTags.h index 44d295b8e..7287c19e9 100644 --- a/DDAlign/include/DDAlign/AlignmentTags.h +++ b/DDAlign/include/DDAlign/AlignmentTags.h @@ -42,6 +42,7 @@ namespace DD4hep { UNICODE(open_transaction); UNICODE(close_transaction); UNICODE(check_overlaps); + UNICODE(debug); } } diff --git a/DDAlign/include/DDAlign/DetectorAlignment.h b/DDAlign/include/DDAlign/DetectorAlignment.h deleted file mode 100644 index dad90f60a..000000000 --- a/DDAlign/include/DDAlign/DetectorAlignment.h +++ /dev/null @@ -1,77 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -#ifndef DD4HEP_GEOMETRY_DETECTORALIGNMENT_H -#define DD4HEP_GEOMETRY_DETECTORALIGNMENT_H - -// Framework include files -#include "DD4hep/Detector.h" -#include "DD4hep/GlobalAlignment.h" - -// Forward declarations -class TGeoHMatrix; - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Alignments { - - /// DetectorAlignment. DetElement Handle supporting alignment operations. - /** - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_ALIGN - */ - class DetectorAlignment : public DetElement { - protected: - public: - /// Initializing constructor - DetectorAlignment(DetElement e); - /// Collect all placements from the detector element up to the world volume - void collectNodes(std::vector<PlacedVolume>& nodes); - /// Access to the alignment block - GlobalAlignment alignment() const; - /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements - std::vector<GlobalAlignment>& volumeAlignments(); - /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements - const std::vector<GlobalAlignment>& volumeAlignments() const; - - /** @DetElement alignment: Calls to align the detector element itself */ - /// Align the PhysicalNode of the placement of the detector element (translation only) - GlobalAlignment align(const Position& pos, bool check = false, double overlap = 0.001); - /// Align the PhysicalNode of the placement of the detector element (rotation only) - GlobalAlignment align(const RotationZYX& rot, bool check = false, double overlap = 0.001); - /// Align the PhysicalNode of the placement of the detector element (translation + rotation) - GlobalAlignment align(const Position& pos, const RotationZYX& rot, bool check = false, double overlap = 0.001); - /// Align the physical node according to a generic Transform3D - GlobalAlignment align(const Transform3D& tr, bool check = false, double overlap = 0.001); - /// Align the physical node according to a generic TGeo matrix - GlobalAlignment align(TGeoHMatrix* matrix, bool check = false, double overlap = 0.001); - - /** @Volume alignment: Calls to align the volumes within on detector element */ - /// Align the PhysicalNode of the placement of the detector element (translation only) - GlobalAlignment align(const std::string& volume_path, const Position& pos, bool check = false, double overlap = 0.001); - /// Align the PhysicalNode of the placement of the detector element (rotation only) - GlobalAlignment align(const std::string& volume_path, const RotationZYX& rot, bool check = false, double overlap = 0.001); - /// Align the PhysicalNode of the placement of the detector element (translation + rotation) - GlobalAlignment align(const std::string& volume_path, const Position& pos, const RotationZYX& rot, bool check = false, double overlap = 0.001); - /// Align the physical node according to a generic Transform3D - GlobalAlignment align(const std::string& volume_path, const Transform3D& tr, bool check = false, double overlap = 0.001); - /// Align the physical node according to a generic TGeo matrix - GlobalAlignment align(const std::string& volume_path, TGeoHMatrix* matrix, bool check = false, double overlap = 0.001); - }; - - } /* End namespace Alignments */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_GEOMETRY_DETECTORALIGNMENT_H */ diff --git a/DDAlign/src/AlignmentOperators.cpp b/DDAlign/src/AlignmentOperators.cpp index a331152eb..f4fefaa3c 100644 --- a/DDAlign/src/AlignmentOperators.cpp +++ b/DDAlign/src/AlignmentOperators.cpp @@ -17,7 +17,7 @@ #include "DD4hep/Printout.h" #include "DD4hep/objects/DetectorInterna.h" #include "DDAlign/AlignmentOperators.h" -#include "DDAlign/DetectorAlignment.h" +#include "DDAlign/GlobalDetectorAlignment.h" // C/C++ include files #include <stdexcept> @@ -26,7 +26,7 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; -void AlignmentOperator::insert(Alignment alignment) const { +void AlignmentOperator::insert(GlobalAlignment alignment) const { if ( !cache.insert(alignment) ) { // Error } @@ -74,7 +74,6 @@ template <> void AlignmentActor<DDAlign_standard_operations::node_delete>::opera template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operator()(Nodes::value_type& n) const { TGeoPhysicalNode* p = n.second.first; - //Entry* e = n.second.second; string np; if ( p->IsAligned() ) { for (Int_t i=0, nLvl=p->GetLevel(); i<=nLvl; i++) { @@ -103,55 +102,55 @@ template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operat } template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operator()(Nodes::value_type& n) const { - Entry& e = *n.second.second; - bool check = e.checkOverlap(); + Entry& e = *n.second.second; bool overlap = e.overlapDefined(); - bool has_matrix = e.hasMatrix(); - DetElement det = e.detector; - bool valid = det->global_alignment.isValid(); - string det_placement = det.placementPath(); - - if ( !valid && !has_matrix ) { - cout << "++++ SKIP ALIGNMENT: ++++ " << e.path - << " DE:" << det_placement - << " Valid:" << yes_no(valid) - << " Matrix:" << yes_no(has_matrix) << endl; - /* */ - return; - } + DetElement det = e.detector; - cout << "++++ " << e.path - << " DE:" << det_placement - << " Valid:" << yes_no(valid) - << " Matrix:" << yes_no(has_matrix) - << endl; - /* */ - // Need to care about optional arguments 'check_overlaps' and 'overlap' - DetectorAlignment ad(det); - Alignment alignment; - bool is_not_volume = e.path == det_placement; - if ( check && overlap ) { - alignment = is_not_volume - ? ad.align(e.transform, e.overlapValue(), e.overlap) - : ad.align(e.path, e.transform, e.overlapValue(), e.overlap); - } - else if ( check ) { - alignment = is_not_volume - ? ad.align(e.transform, e.overlapValue()) - : ad.align(e.path, e.transform, e.overlapValue()); + if ( !det->global_alignment.isValid() && !e.hasMatrix() ) { + printout(WARNING,"AlignmentActor","++++ 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; } - else { - alignment = is_not_volume ? ad.align(e.transform) : ad.align(e.path, e.transform); + if ( GlobalDetectorAlignment::debug() ) { + printout(INFO,"AlignmentActor","++++ %s DE:%s Matrix:%s", + e.path.c_str(),det.placementPath().c_str(),yes_no(e.hasMatrix())); } - if ( alignment.isValid() ) { - insert(alignment); + // Need to care about optional arguments 'check_overlaps' and 'overlap' + GlobalDetectorAlignment ad(det); + GlobalAlignment align; + Transform3D trafo; + bool no_vol = e.path == det.placementPath(); + double ovl_val = e.overlapValue(); + const Delta& delta = e.delta; + + if ( delta.checkFlag(Delta::HAVE_ROTATION|Delta::HAVE_PIVOT|Delta::HAVE_TRANSLATION) ) + trafo = Transform3D(Translation3D(delta.translation)*delta.pivot*delta.rotation*(delta.pivot.Inverse())); + else if ( delta.checkFlag(Delta::HAVE_ROTATION|Delta::HAVE_TRANSLATION) ) + trafo = Transform3D(delta.rotation,delta.translation); + else if ( delta.checkFlag(Delta::HAVE_ROTATION|Delta::HAVE_PIVOT) ) + trafo = Transform3D(delta.pivot*delta.rotation*(delta.pivot.Inverse())); + else if ( delta.checkFlag(Delta::HAVE_ROTATION) ) + trafo = Transform3D(delta.rotation); + else if ( delta.checkFlag(Delta::HAVE_TRANSLATION) ) + trafo = Transform3D(delta.translation); + + if ( e.checkOverlap() && overlap ) + align = no_vol ? ad.align(trafo,ovl_val,e.overlap) : ad.align(e.path,trafo,ovl_val,e.overlap); + else if ( e.checkOverlap() ) + align = no_vol ? ad.align(trafo,ovl_val) : ad.align(e.path,trafo,ovl_val); + else + align = no_vol ? ad.align(trafo) : ad.align(e.path,trafo); + + if ( align.isValid() ) { + insert(align); return; } - throw runtime_error("Failed to apply alignment for "+e.path); + except("AlignmentActor","Failed to apply alignment for "+e.path); } #if 0 -void alignment_reset_dbg(const string& path, const Alignment& a) { +void alignment_reset_dbg(const string& path, const GlobalAlignment& a) { TGeoPhysicalNode* n = a.ptr(); cout << " +++++++++++++++++++++++++++++++ " << path << endl; cout << " +++++ Misaligned physical node: " << endl; diff --git a/DDAlign/src/AlignmentStack.cpp b/DDAlign/src/AlignmentStack.cpp index 74f3176de..ba51135fc 100644 --- a/DDAlign/src/AlignmentStack.cpp +++ b/DDAlign/src/AlignmentStack.cpp @@ -33,74 +33,16 @@ static dd4hep_ptr<AlignmentStack>& _stack(AlignmentStack* obj) { return s; } -/// Fully initializing constructor -AlignmentStack::StackEntry::StackEntry(const DetElement& p, const string& placement, const Transform3D& t, double ov, int f) - : detector(p), transform(t), path(placement), overlap(ov), flag(f) -{ - InstanceCount::increment(this); -} - -/// Constructor with partial initialization -AlignmentStack::StackEntry::StackEntry(DetElement element, bool rst, bool rst_children) - : detector(element), transform(), overlap(0.001), flag(0) -{ - InstanceCount::increment(this); - if ( rst ) flag |= RESET_VALUE; - if ( rst_children ) flag |= RESET_CHILDREN; - if ( detector.isValid() ) path = detector.placementPath(); -} - -/// Constructor with partial initialization -AlignmentStack::StackEntry::StackEntry(DetElement element, const Transform3D& trafo, bool rst, bool rst_children) - : detector(element), transform(trafo), overlap(0.001), flag(0) -{ - InstanceCount::increment(this); - flag |= MATRIX_DEFINED; - if ( rst ) flag |= RESET_VALUE; - if ( rst_children ) flag |= RESET_CHILDREN; - if ( detector.isValid() ) path = detector.placementPath(); -} - -/// Constructor with partial initialization -AlignmentStack::StackEntry::StackEntry(DetElement element, const Position& translation, bool rst, bool rst_children) - : detector(element), transform(translation), overlap(0.001), flag(0) -{ - InstanceCount::increment(this); - flag |= MATRIX_DEFINED; - if ( rst ) flag |= RESET_VALUE; - if ( rst_children ) flag |= RESET_CHILDREN; - if ( detector.isValid() ) path = detector.placementPath(); -} - /// Constructor with partial initialization -AlignmentStack::StackEntry::StackEntry(DetElement element, const RotationZYX& rot, bool rst, bool rst_children) - : detector(element), transform(rot), overlap(0.001), flag(0) +AlignmentStack::StackEntry::StackEntry(DetElement element, const std::string& p, const Delta& del, double ov) + : detector(element), delta(del), path(p), overlap(ov) { InstanceCount::increment(this); - flag |= MATRIX_DEFINED; - if ( rst ) flag |= RESET_VALUE; - if ( rst_children ) flag |= RESET_CHILDREN; - if ( detector.isValid() ) path = detector.placementPath(); -} - -/// Constructor with partial initialization -AlignmentStack::StackEntry::StackEntry(DetElement element, - const Position& translation, - const RotationZYX& rot, - bool rst, - bool rst_children) - : detector(element), transform(rot,translation), overlap(0.001), flag(0) -{ - InstanceCount::increment(this); - flag |= MATRIX_DEFINED; - if ( rst ) flag |= RESET_VALUE; - if ( rst_children ) flag |= RESET_CHILDREN; - if ( detector.isValid() ) path = detector.placementPath(); } /// Copy constructor AlignmentStack::StackEntry::StackEntry(const StackEntry& e) - : detector(e.detector), transform(e.transform), path(e.path), overlap(e.overlap), flag(e.flag) + : detector(e.detector), delta(e.delta), path(e.path), overlap(e.overlap) { InstanceCount::increment(this); } @@ -114,53 +56,38 @@ AlignmentStack::StackEntry::~StackEntry() { AlignmentStack::StackEntry& AlignmentStack::StackEntry::operator=(const StackEntry& e) { if ( this != &e ) { detector = e.detector; - transform = e.transform; - overlap = e.overlap; - path = e.path; - flag = e.flag; + delta = e.delta; + overlap = e.overlap; + path = e.path; } return *this; } -/// Attach transformation object -AlignmentStack::StackEntry& AlignmentStack::StackEntry::setTransformation(const Transform3D& trafo) { - flag |= MATRIX_DEFINED; - transform = trafo; - return *this; -} - -/// Instruct entry to ignore the transformation -AlignmentStack::StackEntry& AlignmentStack::StackEntry::clearTransformation() { - flag &= ~MATRIX_DEFINED; - transform = Transform3D(); - return *this; -} - /// Set flag to reset the entry to it's ideal geometrical position AlignmentStack::StackEntry& AlignmentStack::StackEntry::setReset(bool new_value) { - new_value ? (flag |= RESET_VALUE) : (flag &= ~RESET_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) { - new_value ? (flag |= RESET_CHILDREN) : (flag &= ~RESET_CHILDREN); + 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) { - new_value ? (flag |= CHECKOVL_DEFINED) : (flag &= ~CHECKOVL_DEFINED); + 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) { - flag |= CHECKOVL_DEFINED; - flag |= CHECKOVL_VALUE; + delta.flags |= CHECKOVL_DEFINED; + delta.flags |= CHECKOVL_VALUE; overlap = precision; return *this; } diff --git a/DDAlign/src/AlignmentWriter.cpp b/DDAlign/src/AlignmentWriter.cpp index d6d9cb032..e568a7f85 100644 --- a/DDAlign/src/AlignmentWriter.cpp +++ b/DDAlign/src/AlignmentWriter.cpp @@ -22,7 +22,7 @@ #include "XML/DocumentHandler.h" #include "DDAlign/AlignmentTags.h" #include "DDAlign/AlignmentCache.h" -#include "DDAlign/DetectorAlignment.h" +#include "DDAlign/GlobalDetectorAlignment.h" #include "TGeoMatrix.h" @@ -52,7 +52,7 @@ XML::Element AlignmentWriter::createElement(XML::Document doc, DetElement elemen XML::Element e(0), placement(0), elt = XML::Element(doc,_ALU(detelement)); string path = element.placementPath(); GlobalAlignment a = element->global_alignment; - DetectorAlignment det(element); + GlobalDetectorAlignment det(element); const vector<GlobalAlignment>& va = det.volumeAlignments(); elt.setAttr(_ALU(path),element.path()); diff --git a/DDAlign/src/DetectorAlignment.cpp b/DDAlign/src/GlobalDetectorAlignment.cpp similarity index 69% rename from DDAlign/src/DetectorAlignment.cpp rename to DDAlign/src/GlobalDetectorAlignment.cpp index 7f0e60515..3e88e366e 100644 --- a/DDAlign/src/DetectorAlignment.cpp +++ b/DDAlign/src/GlobalDetectorAlignment.cpp @@ -13,7 +13,7 @@ //========================================================================== // Framework include files -#include "DDAlign/DetectorAlignment.h" +#include "DDAlign/GlobalDetectorAlignment.h" #include "DD4hep/DetectorTools.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/MatrixHelpers.h" @@ -36,13 +36,16 @@ namespace DD4hep { GlobalAlignment global; std::vector<GlobalAlignment> volume_alignments; public: - GlobalAlignmentData() : NamedObject("","global-alignment") {} - virtual ~GlobalAlignmentData() {} + GlobalAlignmentData(const std::string& path) : NamedObject(path,"global-alignment") { + global = GlobalAlignment(path); + } + virtual ~GlobalAlignmentData() { + destroyHandle (global); + } }; } /* End namespace Aligments */ } /* End namespace DD4hep */ - using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; @@ -50,20 +53,30 @@ using namespace DD4hep::Alignments; namespace DetectorTools = DD4hep::Geometry::DetectorTools; typedef vector<pair<int,DetElement> > LevelElements; +DD4HEP_INSTANTIATE_HANDLE_NAMED(GlobalAlignmentData); + + namespace { + static bool s_GlobalDetectorAlignment_debug = false; + GlobalAlignment _align(const GlobalAlignment& a, TGeoHMatrix* transform, bool check, double overlap) { TGeoPhysicalNode* n = a.ptr(); if ( n ) { TGeoMatrix* mm = n->GetNode()->GetMatrix(); - printout(INFO,"Alignment","DELTA matrix of %s",n->GetName()); - transform->Print(); - /* + bool dbg = GlobalDetectorAlignment::debug(); + if ( dbg ) { + printout(INFO,"Alignment","DELTA matrix of %s",n->GetName()); + transform->Print(); printout(INFO,"Alignment","OLD matrix of %s",n->GetName()); mm->Print(); - */ + } transform->MultiplyLeft(mm); // orig * delta n->Align(transform, 0, check, overlap); + if ( dbg ) { + printout(INFO,"Alignment","NEW matrix of %s",n->GetName()); + n->GetNode()->GetMatrix()->Print(); + } /* printout(INFO,"Alignment","Apply new relative matrix mother to daughter:"); transform->Print(); @@ -71,8 +84,6 @@ namespace { printout(INFO,"Alignment","With deltas %s ....",n->GetName()); transform->Print(); n->Align(transform, 0, check, overlap); - printout(INFO,"Alignment","NEW matrix of %s",n->GetName()); - n->GetNode()->GetMatrix()->Print(); Position local, global = a.toGlobal(local); cout << "Local:" << local << " Global: " << global @@ -83,25 +94,20 @@ namespace { throw runtime_error("DD4hep: Cannot align non existing physical node. [Invalid Handle]"); } - GlobalAlignment _alignment(const DetectorAlignment& det) { - Ref_t gbl = det._data().global_alignment; - if ( gbl.isValid() ) { - Handle<GlobalAlignmentData> h(gbl); - return h->global; - } - throw runtime_error("DD4hep: Cannot access global alignment data. [Invalid Handle]"); -#if 0 + GlobalAlignment _alignment(const GlobalDetectorAlignment& det) { DetElement::Object& e = det._data(); - if ( !e.alignment.isValid() ) { + if ( !e.global_alignment.isValid() ) { string path = DetectorTools::placementPath(det); - //cout << "Align path:" << path << endl; - e.alignment = GlobalAlignment(path); + e.global_alignment = Ref_t(new GlobalAlignmentData(path)); } - return e.alignment; -#endif + Handle<GlobalAlignmentData> h(e.global_alignment); + if ( h.isValid() && h->global.isValid() ) { + return h->global; + } + throw runtime_error("DD4hep: Cannot access global alignment data. [Invalid Handle]"); } - void _dumpParentElements(DetectorAlignment& det, LevelElements& elements) { + void _dumpParentElements(GlobalDetectorAlignment& det, LevelElements& elements) { int level = 0; DetectorTools::PlacementPath nodes; DetectorTools::ElementPath det_nodes; @@ -127,84 +133,94 @@ namespace { } } -DD4HEP_INSTANTIATE_HANDLE_NAMED(GlobalAlignmentData); - /// Initializing constructor -DetectorAlignment::DetectorAlignment(DetElement e) +GlobalDetectorAlignment::GlobalDetectorAlignment(DetElement e) : DetElement(e) { } +/// Access debugging flag +bool GlobalDetectorAlignment::debug() { + return s_GlobalDetectorAlignment_debug; +} + +/// Set debugging flag +bool GlobalDetectorAlignment::debug(bool value) { + bool tmp = s_GlobalDetectorAlignment_debug; + s_GlobalDetectorAlignment_debug = value; + return tmp; +} + /// Collect all placements from the detector element up to the world volume -void DetectorAlignment::collectNodes(vector<PlacedVolume>& nodes) { +void GlobalDetectorAlignment::collectNodes(vector<PlacedVolume>& nodes) { DetectorTools::placementPath(*this,nodes); } /// Access to the alignment block -GlobalAlignment DetectorAlignment::alignment() const { +GlobalAlignment GlobalDetectorAlignment::alignment() const { return _alignment(*this); } /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements -vector<GlobalAlignment>& DetectorAlignment::volumeAlignments() { +vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() { Handle<GlobalAlignmentData> h(_data().global_alignment); return h->volume_alignments; } /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements -const vector<GlobalAlignment>& DetectorAlignment::volumeAlignments() const { +const vector<GlobalAlignment>& GlobalDetectorAlignment::volumeAlignments() const { Handle<GlobalAlignmentData> h(_data().global_alignment); return h->volume_alignments; } /// Align the PhysicalNode of the placement of the detector element (translation only) -GlobalAlignment DetectorAlignment::align(const Position& pos, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, bool chk, double overlap) { return align(Geometry::_transform(pos),chk,overlap); } /// Align the PhysicalNode of the placement of the detector element (rotation only) -GlobalAlignment DetectorAlignment::align(const RotationZYX& rot, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const RotationZYX& rot, bool chk, double overlap) { return align(Geometry::_transform(rot),chk,overlap); } /// Align the PhysicalNode of the placement of the detector element (translation + rotation) -GlobalAlignment DetectorAlignment::align(const Position& pos, const RotationZYX& rot, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const Position& pos, const RotationZYX& rot, bool chk, double overlap) { return align(Geometry::_transform(pos,rot),chk,overlap); } /// Align the physical node according to a generic Transform3D -GlobalAlignment DetectorAlignment::align(const Transform3D& transform, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const Transform3D& transform, bool chk, double overlap) { return align(Geometry::_transform(transform),chk,overlap); } /// Align the physical node according to a generic TGeo matrix -GlobalAlignment DetectorAlignment::align(TGeoHMatrix* matrix, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(TGeoHMatrix* matrix, bool chk, double overlap) { return _align(_alignment(*this),matrix,chk,overlap); } /// Align the PhysicalNode of the placement of the detector element (translation only) -GlobalAlignment DetectorAlignment::align(const string& elt_path, const Position& pos, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const string& elt_path, const Position& pos, bool chk, double overlap) { return align(elt_path,Geometry::_transform(pos),chk,overlap); } /// Align the PhysicalNode of the placement of the detector element (rotation only) -GlobalAlignment DetectorAlignment::align(const string& elt_path, const RotationZYX& rot, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const string& elt_path, const RotationZYX& rot, bool chk, double overlap) { return align(elt_path,Geometry::_transform(rot),chk,overlap); } /// Align the PhysicalNode of the placement of the detector element (translation + rotation) GlobalAlignment -DetectorAlignment::align(const string& elt_path, const Position& pos, const RotationZYX& rot, bool chk, double overlap) { +GlobalDetectorAlignment::align(const string& elt_path, const Position& pos, const RotationZYX& rot, bool chk, double overlap) { return align(elt_path,Geometry::_transform(pos,rot),chk,overlap); } /// Align the physical node according to a generic Transform3D -GlobalAlignment DetectorAlignment::align(const string& elt_path, const Transform3D& transform, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const string& elt_path, const Transform3D& transform, bool chk, double overlap) { return align(elt_path,Geometry::_transform(transform),chk,overlap); } /// Align the physical node according to a generic TGeo matrix -GlobalAlignment DetectorAlignment::align(const string& elt_path, TGeoHMatrix* matrix, bool chk, double overlap) { +GlobalAlignment GlobalDetectorAlignment::align(const string& elt_path, TGeoHMatrix* matrix, bool chk, double overlap) { if ( elt_path.empty() ) return _align(_alignment(*this),matrix,chk,overlap); else if ( elt_path == placementPath() ) diff --git a/DDAlign/src/plugins/AlignmentParser.cpp b/DDAlign/src/plugins/AlignmentParser.cpp index e0df8b57c..2bef0931d 100644 --- a/DDAlign/src/plugins/AlignmentParser.cpp +++ b/DDAlign/src/plugins/AlignmentParser.cpp @@ -14,6 +14,8 @@ // Framework include files #include "DD4hep/LCDD.h" +#include "DD4hep/Path.h" +#include "DD4hep/Mutex.h" #include "DD4hep/Printout.h" #include "XML/Conversions.h" #include "XML/XMLElements.h" @@ -25,6 +27,7 @@ #include "DDAlign/AlignmentStack.h" #include "DDAlign/AlignmentCache.h" #include "DDAlign/AlignmentTransaction.h" +#include "DDAlign/GlobalDetectorAlignment.h" // C/C++ include files #include <stdexcept> @@ -41,14 +44,16 @@ namespace DD4hep { class rotation; class position; class pivot; - class transform3d; + class delta; + class debug; } /// Forward declarations for all specialized converters + template <> void Converter<debug>::operator()(xml_h seq) const; 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<transform3d>::operator()(xml_h seq) const; + template <> void Converter<delta>::operator()(xml_h seq) const; template <> void Converter<volume>::operator()(xml_h seq) const; template <> void Converter<alignment>::operator()(xml_h seq) const; @@ -62,6 +67,11 @@ using namespace DD4hep::Alignments; using DD4hep::Geometry::Position; using DD4hep::Geometry::Translation3D; +template <> void Converter<debug>::operator()(xml_h e) const { + bool value = e.attr<bool>(_U(value)); + GlobalDetectorAlignment::debug(value); +} + /** Convert rotation objects * * <rotation x="0.5" y="0" z="0"/> @@ -74,7 +84,7 @@ template <> void Converter<rotation>::operator()(xml_h e) const { xml_comp_t r(e); RotationZYX* v = (RotationZYX*)param; v->SetComponents(r.z(), r.y(), r.x()); - printout(INFO,"Alignment<rotation>", + printout(INFO,"Alignment<rot>", " Rotation: x=%9.3f y=%9.3f z=%9.3f phi=%7.4f psi=%7.4f theta=%7.4f", r.x(), r.y(), r.z(), v->Phi(), v->Psi(), v->Theta()); } @@ -91,7 +101,7 @@ template <> void Converter<position>::operator()(xml_h e) const { xml_comp_t p(e); Position* v = (Position*)param; v->SetXYZ(p.x(), p.y(), p.z()); - printout(INFO,"Alignment<position>"," Position: x=%9.3f y=%9.3f z=%9.3f", + printout(INFO,"Alignment<pos>"," Position: x=%9.3f y=%9.3f z=%9.3f", v->X(), v->Y(), v->Z()); } @@ -108,10 +118,10 @@ template <> void Converter<pivot>::operator()(xml_h e) const { double x,y,z; Translation3D* v = (Translation3D*)param; v->SetXYZ(x=p.x(), y=p.y(), z=p.z()); - printout(INFO,"Alignment<pivot>"," Pivot: x=%9.3f y=%9.3f z=%9.3f",x,y,z); + printout(INFO,"Alignment<piv>"," Pivot: x=%9.3f y=%9.3f z=%9.3f",x,y,z); } -/** Convert transform3d objects +/** Convert delta objects * * A generic alignment transformation is defined by * - a translation in 3D space identified in XML as a @@ -134,35 +144,30 @@ template <> void Converter<pivot>::operator()(xml_h e) const { * @version 1.0 * @date 01/04/2014 */ -template <> void Converter<transform3d>::operator()(xml_h e) const { - typedef pair<bool,Transform3D> Data; +template <> void Converter<delta>::operator()(xml_h e) const { Position pos; RotationZYX rot; Translation3D piv; - xml_h child_rot, child_pos, child_piv; - Data* tr = (Data*)param; + xml_h child_rot, child_pos, child_piv; + Delta* delta = (Delta*)param; if ( (child_pos=e.child(_U(position),false)) ) - Converter<position>(lcdd,&pos)(child_pos); + Converter<position>(lcdd,&delta->translation)(child_pos); if ( (child_rot=e.child(_U(rotation),false)) ) { - Converter<rotation>(lcdd,&rot)(child_rot); + Converter<rotation>(lcdd,&delta->rotation)(child_rot); if ( (child_piv=e.child(_U(pivot),false)) ) - Converter<pivot>(lcdd,&piv)(child_piv); + Converter<pivot>(lcdd,&delta->pivot)(child_piv); } - tr->first = true; if ( child_rot && child_pos && child_piv ) - tr->second = Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse())); + delta->flags |= Delta::HAVE_ROTATION|Delta::HAVE_PIVOT|Delta::HAVE_TRANSLATION; else if ( child_rot && child_pos ) - tr->second = Transform3D(rot,pos); + delta->flags |= Delta::HAVE_ROTATION|Delta::HAVE_TRANSLATION; else if ( child_rot && child_piv ) - tr->second = Transform3D(piv*rot*(piv.Inverse())); + delta->flags |= Delta::HAVE_ROTATION|Delta::HAVE_PIVOT; else if ( child_rot ) - tr->second = Transform3D(rot); + delta->flags |= Delta::HAVE_ROTATION; else if ( child_pos ) - tr->second = Transform3D(pos); - else { - tr->first = false; - } + delta->flags |= Delta::HAVE_TRANSLATION; } typedef AlignmentStack::StackEntry StackEntry; @@ -183,31 +188,30 @@ typedef AlignmentStack::StackEntry StackEntry; * @date 01/04/2014 */ template <> void Converter<volume>::operator()(xml_h e) const { - pair<bool,Transform3D> trafo; + Delta val; pair<DetElement,string>* elt = (pair<DetElement,string>*)param; - 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; - bool check = e.hasAttr(_ALU(check_overlaps)); - bool check_val = check ? e.attr<bool>(_ALU(check_overlaps)) : false; - bool overlap = e.hasAttr(_ALU(overlap)); - double ovl = overlap ? e.attr<double>(_ALU(overlap)) : 0.001; - string eltPlacement = elt->first.placementPath(); - string placementPath = subpath[0]=='/' ? subpath : eltPlacement + "/" + subpath; + 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; + bool check = e.hasAttr(_ALU(check_overlaps)); + bool check_val = check ? e.attr<bool>(_ALU(check_overlaps)) : false; + bool overlap = e.hasAttr(_ALU(overlap)); + double ovl = overlap ? e.attr<double>(_ALU(overlap)) : 0.001; + string elt_place = elt->first.placementPath(); + string placement = subpath[0]=='/' ? subpath : elt_place + "/" + subpath; - printout(INFO,"Alignment<volume>"," path:%s placement:%s reset:%s children:%s", - subpath.c_str(), placementPath.c_str(), yes_no(reset), yes_no(reset_dau)); + 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<transform3d>(lcdd,&trafo)(e); - int flags = 0; - if ( overlap ) flags |= AlignmentStack::OVERLAP_DEFINED; - if ( trafo.first ) flags |= AlignmentStack::MATRIX_DEFINED; - if ( reset ) flags |= AlignmentStack::RESET_VALUE; - if ( reset_dau ) flags |= AlignmentStack::RESET_CHILDREN; - if ( check ) flags |= AlignmentStack::CHECKOVL_DEFINED; - if ( check_val ) flags |= AlignmentStack::CHECKOVL_VALUE; + 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; - dd4hep_ptr<StackEntry> entry(new StackEntry(elt->first,placementPath,trafo.second,ovl,flags)); + dd4hep_ptr<StackEntry> entry(new StackEntry(elt->first,placement,val,ovl)); AlignmentStack::insert(entry); pair<DetElement,string> vol_param(elt->first,subpath); xml_coll_t(e,_U(volume)).for_each(Converter<volume>(lcdd,&vol_param)); @@ -239,33 +243,33 @@ template <> void Converter<detelement>::operator()(xml_h e) const { bool overlap = e.hasAttr(_ALU(overlap)); double ovl = overlap ? e.attr<double>(_ALU(overlap)) : 0.001; DetElement elt = Geometry::DetectorTools::findDaughterElement(det,path); - string placementPath = elt.isValid() ? elt.placementPath() : string("-----"); + string placement = elt.isValid() ? elt.placementPath() : string("-----"); if ( !elt.isValid() ) { string err = "DD4hep: DetElement "+det.path()+" has no child:"+path+" [No such child]"; throw runtime_error(err); } - pair<bool,Transform3D> trafo; - Converter<transform3d>(lcdd,&trafo)(e); - int flags = 0; - if ( trafo.first ) { - flags |= AlignmentStack::MATRIX_DEFINED; + Delta val; + Converter<delta>(lcdd,&val)(e); + if ( val.flags ) { + val.flags |= AlignmentStack::MATRIX_DEFINED; reset = reset_dau = true; } - if ( overlap ) flags |= AlignmentStack::OVERLAP_DEFINED; - if ( check ) flags |= AlignmentStack::CHECKOVL_DEFINED; - if ( reset ) flags |= AlignmentStack::RESET_VALUE; - if ( reset_dau ) flags |= AlignmentStack::RESET_CHILDREN; - if ( check_val ) flags |= AlignmentStack::CHECKOVL_VALUE; + 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; - printout(INFO,"Alignment<detelement>","path:%s [%s] placement:%s matrix:%s reset:%s children:%s", + printout(INFO,"Alignment<det>","path:%s [%s] placement:%s matrix:%s reset:%s children:%s", path.c_str(), elt.isValid() ? elt.path().c_str() : "-----", - placementPath.c_str(), - yes_no(trafo.first), yes_no(reset), yes_no(reset_dau)); + placement.c_str(), + yes_no(val.checkFlag(AlignmentStack::MATRIX_DEFINED)), + yes_no(reset), yes_no(reset_dau)); - dd4hep_ptr<StackEntry> entry(new StackEntry(elt,placementPath,trafo.second,ovl,flags)); + dd4hep_ptr<StackEntry> entry(new StackEntry(elt,placement,val,ovl)); AlignmentStack::insert(entry); pair<DetElement,string> vol_param(elt,""); @@ -316,6 +320,7 @@ template <> void Converter<alignment>::operator()(xml_h e) const { /// Now we process all allowed elements within the alignment tag: /// <detelement/>, <detelements/>, <subdetectors/> and <include/> + xml_coll_t(e,_ALU(debug)).for_each(Converter<debug>(lcdd,&top)); xml_coll_t(e,_ALU(detelement)).for_each(Converter<detelement>(lcdd,&top)); xml_coll_t(e,_ALU(detelements)).for_each(_ALU(detelement),Converter<detelement>(lcdd,&top)); xml_coll_t(e,_ALU(subdetectors)).for_each(_ALU(detelement),Converter<detelement>(lcdd,&top)); @@ -328,13 +333,22 @@ template <> void Converter<alignment>::operator()(xml_h e) const { * @version 1.0 * @date 01/04/2014 */ -static long setup_Alignment(lcdd_t& lcdd, const xml_h& e) { - AlignmentCache::install(lcdd); - AlignmentTransaction tr(lcdd, e); - (DD4hep::Converter<DD4hep::alignment>(lcdd))(e); +static long setup_Alignment(lcdd_t& lcdd, const xml_h& e) {{ + static dd4hep_mutex_t s_mutex; + dd4hep_lock_t lock(s_mutex); + AlignmentCache::install(lcdd); + AlignmentTransaction tr(lcdd, e); + (DD4hep::Converter<DD4hep::alignment>(lcdd))(e); + } + if ( GlobalDetectorAlignment::debug() ) { + xml_elt_t elt(e); + Path uri = elt.document().uri(); + printout(INFO,"GlobalAlignment","+++ Successfully parsed XML: %s", + uri.filename().c_str()); + } return 1; } -DECLARE_XML_DOC_READER(alignment,setup_Alignment) +DECLARE_XML_DOC_READER(global_alignment,setup_Alignment) /** Basic entry point to install the alignment cache in a LCDD instance * @@ -346,4 +360,4 @@ static long install_Alignment(lcdd_t& lcdd, int, char**) { AlignmentCache::install(lcdd); return 1; } -DECLARE_APPLY(DD4hepAlignmentInstall,install_Alignment) +DECLARE_APPLY(DD4hep_GlobalAlignmentInstall,install_Alignment) diff --git a/DDCore/include/DD4hep/AlignmentData.h b/DDCore/include/DD4hep/AlignmentData.h index 35af9d8ac..a8e762fce 100644 --- a/DDCore/include/DD4hep/AlignmentData.h +++ b/DDCore/include/DD4hep/AlignmentData.h @@ -50,8 +50,8 @@ namespace DD4hep { class Delta { public: typedef Translation3D Pivot; - Pivot pivot; Position translation; + Pivot pivot; RotationZYX rotation; unsigned int flags; @@ -64,6 +64,21 @@ namespace DD4hep { /// Default constructor Delta() : flags(0) {} + /// Initializing constructor + Delta(const Position& tr) + : translation(tr), flags(HAVE_TRANSLATION) {} + /// Initializing constructor + Delta(const RotationZYX& rot) + : translation(), rotation(rot), flags(HAVE_ROTATION) {} + /// Initializing constructor + Delta(const Position& tr, const RotationZYX& rot) + : translation(tr), rotation(rot), flags(HAVE_ROTATION|HAVE_TRANSLATION) {} + /// Initializing constructor + Delta(const Translation3D& piv, const RotationZYX& rot) + : pivot(piv), rotation(rot), flags(HAVE_ROTATION|HAVE_PIVOT) {} + /// Initializing constructor + Delta(const Position& tr, const Translation3D& piv, const RotationZYX& rot) + : translation(tr), pivot(piv), rotation(rot), flags(HAVE_ROTATION|HAVE_PIVOT|HAVE_TRANSLATION) {} /// Copy constructor Delta(const Delta& c); /// Default destructor @@ -72,12 +87,16 @@ namespace DD4hep { Delta& operator=(const Delta& c); /// Reset information to identity void clear(); + /// Check a given flag + bool checkFlag(unsigned int mask) const { return (flags&mask) == mask; } + /// Check a given flag + void setFlag(unsigned int mask) { flags |= mask; } /// Access flags: Check if the delta operation contains a translation - bool hasTranslation() const { return (flags&HAVE_TRANSLATION) != 0; } + bool hasTranslation() const { return checkFlag(HAVE_TRANSLATION); } /// Access flags: Check if the delta operation contains a rotation - bool hasRotation() const { return (flags&HAVE_ROTATION) != 0; } + bool hasRotation() const { return checkFlag(HAVE_ROTATION); } /// Access flags: Check if the delta operation contains a pivot - bool hasPivot() const { return (flags&HAVE_PIVOT) != 0; } + bool hasPivot() const { return checkFlag(HAVE_PIVOT); } }; /// Derived condition data-object definition diff --git a/DDCore/include/DD4hep/GlobalAlignment.h b/DDCore/include/DD4hep/GlobalAlignment.h index 75cc59b90..95f065ca8 100644 --- a/DDCore/include/DD4hep/GlobalAlignment.h +++ b/DDCore/include/DD4hep/GlobalAlignment.h @@ -36,7 +36,7 @@ namespace DD4hep { * \ingroup DD4HEP_GEOMETRY * \ingroup DD4HEP_ALIGN */ - class GlobalAlignment: public Handle<TGeoPhysicalNode> { + class GlobalAlignment : public Handle<TGeoPhysicalNode> { typedef Geometry::RotationZYX RotationZYX; typedef Geometry::Transform3D Transform3D; diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index 979fbd825..5bd36037c 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -637,6 +637,8 @@ namespace DD4hep { Handle_t createElt(const XmlChar* tag) const; /// Clone a DOM element / sub-tree Handle_t clone(Handle_t source) const; + /// Acces the document URI + std::string uri() const; }; /// Class supporting the basic functionality of an XML document including ownership diff --git a/DDCore/src/AlignmentData.cpp b/DDCore/src/AlignmentData.cpp index dc7c1b28d..6319fece5 100644 --- a/DDCore/src/AlignmentData.cpp +++ b/DDCore/src/AlignmentData.cpp @@ -27,7 +27,7 @@ using namespace DD4hep::Alignments; /// Copy constructor Delta::Delta(const Delta& c) - : pivot(c.pivot), translation(c.translation), rotation(c.rotation), flags(c.flags) + : translation(c.translation), pivot(c.pivot), rotation(c.rotation), flags(c.flags) { } diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp index efccaf202..d2ed4bd35 100644 --- a/DDCore/src/XML/XMLElements.cpp +++ b/DDCore/src/XML/XMLElements.cpp @@ -63,6 +63,7 @@ namespace { #define appendChild LinkEndChild #define getOwnerDocument GetDocument #define getDocumentElement RootElement +#define getDocumentURI Value /// Union to ease castless object access in TinyXML union Xml { @@ -1034,6 +1035,15 @@ Handle_t Document::root() const { throw runtime_error("Document::root: Invalid handle!"); } +/// Acces the document URI +std::string Document::uri() const { + if (m_doc) { + Tag_t val(_D(m_doc)->getDocumentURI()); + return val; + } + throw runtime_error("Document::uri: Invalid handle!"); +} + /// Assign new document. Old document is dropped. DocumentHolder& DocumentHolder::assign(DOC d) { if (m_doc) { diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index ab71e35c5..ea1b822b7 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -35,7 +35,9 @@ using namespace DD4hep; using namespace DD4hep::Geometry; static LCDDBuildType build_type(const char* value) { - if ( strcmp(value,"BUILD_DEFAULT")==0 ) + if ( !value ) + return BUILD_DEFAULT; + else if ( strcmp(value,"BUILD_DEFAULT")==0 ) return BUILD_DEFAULT; else if ( strcmp(value,"BUILD_SIMU")==0 ) return BUILD_SIMU; diff --git a/UtilityApps/src/run_plugin.h b/UtilityApps/src/run_plugin.h index c7582adab..f276af34e 100644 --- a/UtilityApps/src/run_plugin.h +++ b/UtilityApps/src/run_plugin.h @@ -91,8 +91,7 @@ namespace { " The lower the level, the more printout... \n" " -plugin <name> <args> Execute plugin <name> after loading geometry. \n" " All arguments following until the next '-' \n" - " are considered as arguments to the plugin. \n" - " "; + " are considered as arguments to the plugin. \n"; return cout; } @@ -138,6 +137,8 @@ namespace { } else if ( strncmp(argv[i],"-load_only",5)==0 ) dry_run = true; + else if ( strncmp(argv[i],"-dry-run",5)==0 ) + dry_run = true; else if ( strncmp(argv[i],"-print",4)==0 ) DD4hep::setPrintLevel(DD4hep::PrintLevel(print = decodePrintLevel(argv[++i]))); else if ( strncmp(argv[i],"-destroy",5)==0 ) @@ -174,20 +175,23 @@ namespace { long result; for(size_t i=0; i<plugins.size(); ++i) { std::vector<const char*>& plug=plugins[i]; - result = run_plugin(lcdd,plug[0],plug.size()-1,(char**)(plug.size()>1 ? &plug[1] : 0)); + // Remove plugin name and trailing 0x0 from args. + size_t num_args = plug.size()>2 ? plug.size()-2 : 0; + + result = run_plugin(lcdd,plug[0],plug.size()-1,(char**)(num_args>0 ? &plug[1] : 0)); if ( result == EINVAL ) { cout << "FAILED to execute DD4hep plugin: '" << plug[0] - << "' with args (" << (plug.size()-1) << ") :[ "; + << "' with args (" << num_args << ") :[ "; for(size_t j=1; j<plug.size(); ++j) { - cout << plug[j] << " "; + if ( plug[j] ) cout << plug[j] << " "; } cout << "]" << endl; usage_default(name); } cout << "Executed DD4hep plugin: '" << plug[0] - << "' with args (" << (plug.size()-1) << ") :[ "; + << "' with args (" << num_args << ") :[ "; for(size_t j=1; j<plug.size(); ++j) { - cout << plug[j] << " "; + if ( plug[j] ) cout << plug[j] << " "; } cout << "]" << endl; } diff --git a/examples/AlignDet/CMakeLists.txt b/examples/AlignDet/CMakeLists.txt index b83229baa..d07c95a26 100644 --- a/examples/AlignDet/CMakeLists.txt +++ b/examples/AlignDet/CMakeLists.txt @@ -12,7 +12,7 @@ cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) include ( ${DD4hep_DIR}/cmake/DD4hep.cmake ) -#----------------------------------------------------------------------------------- +#-------------------------------------------------------------------------- dd4hep_configure_output() dd4hep_package ( AlignDet MAJOR 0 MINOR 0 PATCH 1 USES [ROOT REQUIRED COMPONENTS Geom GenVector MathCore] @@ -24,3 +24,33 @@ dd4hep_package ( AlignDet MAJOR 0 MINOR 0 PATCH 1 dd4hep_add_plugin( AlignDet SOURCES src/*.cpp ) dd4hep_install_dir( compact DESTINATION examples/AlignDet ) dd4hep_configure_scripts( AlignDet DEFAULT_SETUP WITH_TESTS) + +# +#---Testing: Load ALEPH TPC geometry -------------------------------------- +dd4hep_add_test_reg( test_DetAlign_AlephTPC_load + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" + EXEC_ARGS geoPluginRun + -input file:${CMAKE_CURRENT_SOURCE_DIR}/compact/AlephTPC.xml + -destroy -no-interpreter -plugin DD4hep_GlobalAlignmentInstall + REGEX_PASS "189 nodes/ 23 volume UID's in LCDD Geometry" ) +# +#---Testing: Load and misalign ALEPH TPC geometry ------------------------- +dd4hep_add_test_reg( test_DetAlign_Global_AlephTPC_align + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" + EXEC_ARGS geoPluginRun + -input file:${CMAKE_CURRENT_SOURCE_DIR}/compact/AlephTPC.xml + -destroy -no-interpreter + -plugin DD4hep_GlobalAlignmentInstall + -plugin DD4hepXMLLoader file:${CMAKE_CURRENT_SOURCE_DIR}/compact/AlephTPC_alignment.xml BUILD_DEFAULT + REGEX_PASS "Successfully parsed XML: AlephTPC_alignment.xml") +# +#---Testing: Load and misalign ALEPH TPC geometry ------------------------- +dd4hep_add_test_reg( test_DetAlign_Global_AlephTPC_reset + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" + EXEC_ARGS geoPluginRun + -input file:${CMAKE_CURRENT_SOURCE_DIR}/compact/AlephTPC.xml + -destroy -no-interpreter + -plugin DD4hep_GlobalAlignmentInstall + -plugin DD4hepXMLLoader file:${CMAKE_CURRENT_SOURCE_DIR}/compact/AlephTPC_alignment.xml + -plugin DD4hepXMLLoader file:${CMAKE_CURRENT_SOURCE_DIR}/compact/AlephTPC_reset.xml + REGEX_PASS "Successfully parsed XML: AlephTPC_reset.xml" ) diff --git a/examples/AlignDet/compact/AlephTPC_alignment.xml b/examples/AlignDet/compact/AlephTPC_alignment.xml index c7181f69d..d8bff42d4 100644 --- a/examples/AlignDet/compact/AlephTPC_alignment.xml +++ b/examples/AlignDet/compact/AlephTPC_alignment.xml @@ -1,5 +1,6 @@ -<alignment> +<global_alignment> + <debug value="true"/> <open_transaction/> <subdetectors> <!-- @@ -76,4 +77,4 @@ Any supplied pivot point in this case is ignored. </subdetectors> <close_transaction/> -</alignment> +</global_alignment> diff --git a/examples/AlignDet/compact/AlephTPC_reset.xml b/examples/AlignDet/compact/AlephTPC_reset.xml index ed5d594c0..98ea4111b 100644 --- a/examples/AlignDet/compact/AlephTPC_reset.xml +++ b/examples/AlignDet/compact/AlephTPC_reset.xml @@ -1,4 +1,4 @@ -<alignment print="true"> +<global_alignment print="true"> <open_transaction/> <subdetectors> <!-- @@ -23,4 +23,4 @@ </detelement> </subdetectors> <close_transaction/> -</alignment> +</global_alignment> -- GitLab