From 350e27b99ca6b1a2c7cd70e93005a830f4747027 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Fri, 25 Apr 2014 08:15:20 +0000 Subject: [PATCH] Please see doc/release.notes for changes --- DDAlign/CMakeLists.txt | 6 +- DDAlign/include/DDAlign/AlignmentStack.h | 37 ++++++-- .../include/DDAlign/AlignmentTransaction.h | 55 ++++++++++++ DDAlign/src/AlignmentCache.cpp | 84 +++++++++++-------- DDAlign/src/AlignmentOperators.cpp | 12 +-- DDAlign/src/AlignmentParser.cpp | 68 +++++---------- DDAlign/src/AlignmentStack.cpp | 72 ++++++++++++---- DDAlign/src/AlignmentTransaction.cpp | 36 ++++++++ DDAlign/src/AlignmentWriter.cpp | 2 +- DDAlign/src/DetectorAlignment.cpp | 5 +- 10 files changed, 256 insertions(+), 121 deletions(-) create mode 100644 DDAlign/include/DDAlign/AlignmentTransaction.h create mode 100644 DDAlign/src/AlignmentTransaction.cpp diff --git a/DDAlign/CMakeLists.txt b/DDAlign/CMakeLists.txt index 2313286bb..1d5b10ae6 100644 --- a/DDAlign/CMakeLists.txt +++ b/DDAlign/CMakeLists.txt @@ -9,14 +9,16 @@ include( DD4hep ) find_package( ROOT REQUIRED ) #---Includedirs ------------------------------------------------------------------ -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include +include_directories(${CMAKE_SOURCE_DIR}/DDCore/include + ${CMAKE_SOURCE_DIR}/DDSegmentation/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ${DD4hep_INCLUDE_DIRS} ${ROOT_INCLUDE_DIR} ) #---DD4hepAlign library -------------------------------------------------------------- file(GLOB sources src/*.cpp) add_library(DD4hepAlign SHARED ${sources}) -target_link_libraries(DD4hepAlign ${DD4hep_LIBRARIES} DD4hepCore ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES}) +target_link_libraries(DD4hepAlign DD4hepCore ${ROOT_LIBRARIES}) SET( CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Wno-long-long") if(DD4HEP_USE_XERCESC) add_definitions(-DDD4HEP_USE_XERCESC) diff --git a/DDAlign/include/DDAlign/AlignmentStack.h b/DDAlign/include/DDAlign/AlignmentStack.h index 87bb31011..e90486983 100644 --- a/DDAlign/include/DDAlign/AlignmentStack.h +++ b/DDAlign/include/DDAlign/AlignmentStack.h @@ -34,6 +34,9 @@ namespace DD4hep { */ class AlignmentStack { public: + + friend class std::auto_ptr<AlignmentStack>; + enum { OVERLAP_DEFINED = 1<<0, MATRIX_DEFINED = 1<<1, @@ -45,10 +48,15 @@ namespace DD4hep { } Flags; struct StackEntry { + /// Reference to the detector element DetElement detector; + /// 3-D Transformation matrix for the volume Transform3D transform; + /// Path to the misaligned volume std::string path; + /// Parameter for overlap checking double overlap; + /// Flag containing various encodings int flag; /// Fully initializing constructor @@ -66,13 +74,24 @@ namespace DD4hep { /// Copy constructor StackEntry(const StackEntry& e); /// Default destructor - ~StackEntry() {} + virtual ~StackEntry(); + + /// Assignment operator + StackEntry& operator=(const StackEntry& e); + + /// Check a given flag bool checkFlag(int mask) const { return (flag&mask) == mask; } - bool checkOverflow() const { return checkFlag(CHECKOVL_DEFINED); } - bool overflowValue() const { return checkFlag(CHECKOVL_VALUE); } - bool checkOverlap() const { return checkFlag(OVERLAP_DEFINED); } + /// Check if the overlap flag checking is enabled + bool overlapDefined() const { return checkFlag(OVERLAP_DEFINED); } + /// Check if the overlap flag checking is enabled + bool checkOverlap() const { return checkFlag(CHECKOVL_DEFINED); } + /// Check if the overalp value is present + bool overlapValue() const { return checkFlag(CHECKOVL_VALUE); } + /// Check if this alignment entry has a non unitary transformation matrix bool hasMatrix() const { return checkFlag(MATRIX_DEFINED); } + /// Check flag if the node location should be reset bool needsReset() const { return checkFlag(RESET_VALUE); } + /// Check flag if the node location and all children should be reset bool resetChildren() const { return checkFlag(RESET_CHILDREN); } /// Attach transformation object @@ -96,11 +115,11 @@ namespace DD4hep { /// Default constructor AlignmentStack(); + /// Default destructor. Careful with this one: + virtual ~AlignmentStack(); public: - /// Default destructor. Careful with this one: - virtual ~AlignmentStack(); /// Static client accessor static AlignmentStack& get(); /// Create an alignment stack instance. The creation of a second instance will be refused. @@ -108,15 +127,15 @@ namespace DD4hep { /// Check existence of alignment stack static bool exists(); /// Add a new entry to the cache. The key is the placement path - static bool insert(const std::string& full_path, StackEntry* new_entry); + static bool insert(const std::string& full_path, std::auto_ptr<StackEntry>& new_entry); /// Add a new entry to the cache. The key is the placement path. The placement path must be set in the entry - static bool insert(StackEntry* new_entry); + static bool insert(std::auto_ptr<StackEntry>& new_entry); /// Clear data content and remove the slignment stack void release(); /// Access size of the alignment stack size_t size() const { return m_stack.size(); } /// Add a new entry to the cache. The key is the placement path - bool add(StackEntry* new_entry); + bool add(std::auto_ptr<StackEntry>& new_entry); /// Retrieve an alignment entry of the current stack std::auto_ptr<StackEntry> pop(); /// Get all path entries to be aligned. Note: transient! diff --git a/DDAlign/include/DDAlign/AlignmentTransaction.h b/DDAlign/include/DDAlign/AlignmentTransaction.h new file mode 100644 index 000000000..2be31da31 --- /dev/null +++ b/DDAlign/include/DDAlign/AlignmentTransaction.h @@ -0,0 +1,55 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_ALIGNMENT_ALIGNMENTTRANSACTION_H +#define DD4HEP_ALIGNMENT_ALIGNMENTTRANSACTION_H + +// Framework include files +#include "DD4hep/Primitives.h" + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + namespace XML { class Handle_t; } + + /* + * Alignment namespace declaration + */ + namespace Geometry { + + // Forward declarations + class LCDD; + class AlignmentCache; + + /** @class AlignmentTransaction + * + * Manage alignment transaction to the cache for a given LCDD instance + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + struct AlignmentTransaction { + /// Internal flag to remember transaction contexts + bool flag; + /// Reference to the current LCDD instance + LCDD& lcdd; + /// Reference to the alignment cache + AlignmentCache* m_cache; + + /// Default constructor + AlignmentTransaction(LCDD& l, const XML::Handle_t& e); + /// Default destructor + ~AlignmentTransaction(); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_ALIGNMENT_ALIGNMENTTRANSACTION_H */ diff --git a/DDAlign/src/AlignmentCache.cpp b/DDAlign/src/AlignmentCache.cpp index 49b39b5cd..7c6933f27 100644 --- a/DDAlign/src/AlignmentCache.cpp +++ b/DDAlign/src/AlignmentCache.cpp @@ -12,37 +12,18 @@ #include "DD4hep/DetectorTools.h" #include "DDAlign/AlignmentCache.h" #include "DDAlign/AlignmentOperators.h" +#include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" // ROOT include files #include "TGeoManager.h" -// C/C++ include files -#include <stdexcept> - using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; using namespace DD4hep::Geometry::DDAlign_standard_operations; - typedef AlignmentStack::StackEntry Entry; -namespace { - /// one-at-time hash function - inline unsigned int hash32(const char* key) { - unsigned int hash = 0; - const char* k = key; - for (; *k; k++) { - hash += *k; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); hash += (hash << 15); - return hash; - } - -} - DetElement _detector(DetElement child) { if ( child.isValid() ) { DetElement p(child.parent()); @@ -56,7 +37,7 @@ DetElement _detector(DetElement child) { } /// Default constructor -AlignmentCache::AlignmentCache(LCDD& lcdd, const std::string& sdPath, bool top) +AlignmentCache::AlignmentCache(LCDD& lcdd, const string& sdPath, bool top) : m_lcdd(lcdd), m_sdPath(sdPath), m_sdPathLen(sdPath.length()), m_refCount(1), m_top(top) { } @@ -101,7 +82,7 @@ bool AlignmentCache::insert(Alignment alignment) { } /// Retrieve the cache section corresponding to the path of an entry. -AlignmentCache* AlignmentCache::section(const std::string& path_name) const { +AlignmentCache* AlignmentCache::section(const string& path_name) const { size_t idx, idq; if ( path_name[0] != '/' ) { return section(m_lcdd.world().placementPath()+'/'+path_name); @@ -118,8 +99,8 @@ AlignmentCache* AlignmentCache::section(const std::string& path_name) const { return (j==m_detectors.end()) ? 0 : (*j).second; } -/// Retrieve an alignment entry by its lacement path -Alignment AlignmentCache::get(const std::string& path_name) const { +/// Retrieve an alignment entry by its placement path +Alignment AlignmentCache::get(const string& path_name) const { size_t idx, idq; unsigned int index = hash32(path_name.c_str()+m_sdPathLen); Cache::const_iterator i = m_cache.find(index); @@ -184,11 +165,7 @@ void AlignmentCache::closeTransaction() { mgr.UnlockGeometry(); apply(AlignmentStack::get()); AlignmentStack::get().release(); - printout(INFO,"AlignmentCache","Alignments were applied. Refreshing physical nodes...."); mgr.LockGeometry(); - mgr.GetCurrentNavigator()->ResetAll(); - mgr.GetCurrentNavigator()->BuildCache(); - mgr.RefreshPhysicalNodes(); return; } printout(WARNING,"Alignment<alignment>", @@ -211,7 +188,7 @@ void AlignmentCache::uninstall(LCDD& lcdd) { } /// Retrieve branch cache by name. If not present it will be created -AlignmentCache* AlignmentCache::subdetectorAlignments(const std::string& name) { +AlignmentCache* AlignmentCache::subdetectorAlignments(const string& name) { SubdetectorAlignments::const_iterator i = m_detectors.find(name); if ( i == m_detectors.end() ) { AlignmentCache* ptr = new AlignmentCache(m_lcdd,name,false); @@ -223,25 +200,60 @@ AlignmentCache* AlignmentCache::subdetectorAlignments(const std::string& name) /// Apply a complete stack of ordered alignments to the geometry structure void AlignmentCache::apply(AlignmentStack& stack) { - typedef map<TNamed*,vector<Entry*> > sd_entries_t; - sd_entries_t all; + typedef map<string,DetElement> DetElementUpdates; + typedef map<DetElement,vector<Entry*> > sd_entries_t; + TGeoManager& mgr = m_lcdd.manager(); + DetElementUpdates detelt_updates; + sd_entries_t all, highest; + while(stack.size() > 0) { Entry* e = stack.pop().release(); DetElement det = _detector(e->detector); - all[det.ptr()].push_back(e); + all[det].push_back(e); + if ( e->hasMatrix() || e->needsReset() || e->resetChildren() ) { + detelt_updates.insert(make_pair(e->detector.path(),e->detector)); + } } for(sd_entries_t::iterator i=all.begin(); i!=all.end(); ++i) { - DetElement det(Ref_t((*i).first)); + DetElement det((*i).first); AlignmentCache* sd_cache = subdetectorAlignments(det.placement().name()); sd_cache->apply( (*i).second ); (*i).second.clear(); } -} + printout(INFO,"AlignmentCache","Alignments were applied. Refreshing physical nodes...."); + mgr.GetCurrentNavigator()->ResetAll(); + mgr.GetCurrentNavigator()->BuildCache(); + mgr.RefreshPhysicalNodes(); + + // Provide update callback for every detector element with a changed placement + for(DetElementUpdates::iterator i=detelt_updates.begin(); i!=detelt_updates.end(); ++i) { + DetElement elt((*i).second); + printout(DEBUG,"AlignmentCache","+++ Trigger placement update for %s [2]",elt.path().c_str()); + elt->update(DetElement::PLACEMENT_CHANGED|DetElement::PLACEMENT_ELEMENT,elt.ptr()); + } + // Provide update callback for the highest detector element + string last_path = "?????"; + for(DetElementUpdates::iterator i=detelt_updates.begin(); i!=detelt_updates.end(); ++i) { + const string& path = (*i).first; + if ( path.find(last_path) == string::npos ) { + DetElement elt((*i).second); + printout(DEBUG,"AlignmentCache","+++ Trigger placement update for %s [1]",elt.path().c_str()); + elt->update(DetElement::PLACEMENT_CHANGED|DetElement::PLACEMENT_HIGHEST,elt.ptr()); + last_path = (*i).first; + } + } + // Provide update callback at the detector level + for(sd_entries_t::iterator i=all.begin(); i!=all.end(); ++i) { + DetElement elt((*i).first); + printout(DEBUG,"AlignmentCache","+++ Trigger placement update for %s [0]",elt.path().c_str()); + elt->update(DetElement::PLACEMENT_CHANGED|DetElement::PLACEMENT_DETECTOR,elt.ptr()); + } +} /// Apply a vector of SD entries of ordered alignments to the geometry structure void AlignmentCache::apply(const vector<Entry*>& changes) { - typedef std::map<std::string,std::pair<TGeoPhysicalNode*,Entry*> > Nodes; + typedef map<string,pair<TGeoPhysicalNode*,Entry*> > Nodes; typedef vector<Entry*> Changes; Nodes nodes; diff --git a/DDAlign/src/AlignmentOperators.cpp b/DDAlign/src/AlignmentOperators.cpp index fe73c627d..4c6a818e4 100644 --- a/DDAlign/src/AlignmentOperators.cpp +++ b/DDAlign/src/AlignmentOperators.cpp @@ -97,8 +97,8 @@ 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.checkOverflow(); - bool overlap = e.checkOverlap(); + bool check = e.checkOverlap(); + bool overlap = e.overlapDefined(); bool has_matrix = e.hasMatrix(); DetElement det = e.detector; bool valid = det.alignment().isValid(); @@ -125,13 +125,13 @@ template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operat bool is_not_volume = e.path == det_placement; if ( check && overlap ) { alignment = is_not_volume - ? ad.align(e.transform, e.overflowValue(), e.overlap) - : ad.align(e.path, e.transform, e.overflowValue(), e.overlap); + ? 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.overflowValue()) - : ad.align(e.path, e.transform, e.overflowValue()); + ? ad.align(e.transform, e.overlapValue()) + : ad.align(e.path, e.transform, e.overlapValue()); } else { alignment = is_not_volume ? ad.align(e.transform) : ad.align(e.path, e.transform); diff --git a/DDAlign/src/AlignmentParser.cpp b/DDAlign/src/AlignmentParser.cpp index 9de3872c4..c17ab8f59 100644 --- a/DDAlign/src/AlignmentParser.cpp +++ b/DDAlign/src/AlignmentParser.cpp @@ -19,6 +19,7 @@ #include "DDAlign/AlignmentTags.h" #include "DDAlign/AlignmentStack.h" #include "DDAlign/AlignmentCache.h" +#include "DDAlign/AlignmentTransaction.h" // C/C++ include files #include <stdexcept> @@ -27,41 +28,6 @@ namespace DD4hep { namespace { - /** @class AlignmentTransaction - * - * Manage alignment transaction to the cache for a given LCDD instance - * - * @author M.Frank - * @version 1.0 - * @date 01/04/2014 - */ - struct AlignmentTransaction { - /// Internal flag to remember transaction contexts - bool flag; - /// Reference to the current LCDD instance - lcdd_t& lcdd; - /// Reference to the alignment cache - Geometry::AlignmentCache* m_cache; - - /// Default constructor - AlignmentTransaction(lcdd_t& l, xml_h e) : lcdd(l) { - flag = e.hasChild(_U(close_transaction)); - /// First check if a transaction is to be opened - m_cache = lcdd.extension<Geometry::AlignmentCache>(); - m_cache->addRef(); - if ( e.hasChild(_U(open_transaction)) ) { - m_cache->openTransaction(); - } - } - /// Default destructor - ~AlignmentTransaction() { - /// Last check if a transaction is to be closed - if ( flag ) { - lcdd.extension<Geometry::AlignmentCache>()->closeTransaction(); - } - m_cache->release(); - } - }; /// Some utility class to specialize the convetrers: class alignment; class detelement; @@ -234,7 +200,7 @@ template <> void Converter<volume>::operator()(xml_h e) const { if ( check ) flags |= AlignmentStack::CHECKOVL_DEFINED; if ( check_val ) flags |= AlignmentStack::CHECKOVL_VALUE; - StackEntry* entry = new StackEntry(elt->first,placementPath,trafo.second,ovl,flags); + auto_ptr<StackEntry> entry(new StackEntry(elt->first,placementPath,trafo.second,ovl,flags)); AlignmentStack::insert(entry); pair<DetElement,string> vol_param(elt->first,subpath); xml_coll_t(e,_U(volume)).for_each(Converter<volume>(lcdd,&vol_param)); @@ -261,19 +227,13 @@ template <> void Converter<detelement>::operator()(xml_h e) const { string path = e.attr<string>(_U(path)); bool check = e.hasAttr(_U(check_overlaps)); bool check_val = check ? e.attr<bool>(_U(check_overlaps)) : false; - bool reset = e.hasAttr(_U(reset)) ? e.attr<bool>(_U(reset)) : true; - bool reset_dau = e.hasAttr(_U(reset_children)) ? e.attr<bool>(_U(reset_children)) : true; + bool reset = e.hasAttr(_U(reset)) ? e.attr<bool>(_U(reset)) : false; + bool reset_dau = e.hasAttr(_U(reset_children)) ? e.attr<bool>(_U(reset_children)) : false; bool overlap = e.hasAttr(_U(overlap)); double ovl = overlap ? e.attr<double>(_U(overlap)) : 0.001; - DetElement elt = Geometry::DetectorTools::findElement(det,path); + DetElement elt = Geometry::DetectorTools::findDaughterElement(det,path); string placementPath = elt.isValid() ? elt.placementPath() : string("-----"); - printout(INFO,"Alignment<detelement>","path:%s [%s] placement:%s reset:%s children:%s", - path.c_str(), - elt.isValid() ? elt.path().c_str() : "-----", - placementPath.c_str(), - yes_no(reset), yes_no(reset_dau)); - if ( !elt.isValid() ) { string err = "DD4hep: DetElement "+det.path()+" has no child:"+path+" [No such child]"; throw runtime_error(err); @@ -282,14 +242,23 @@ template <> void Converter<detelement>::operator()(xml_h e) const { pair<bool,Transform3D> trafo; Converter<transform3d>(lcdd,&trafo)(e); int flags = 0; + if ( trafo.first ) { + flags |= AlignmentStack::MATRIX_DEFINED; + reset = reset_dau = true; + } if ( overlap ) flags |= AlignmentStack::OVERLAP_DEFINED; if ( check ) flags |= AlignmentStack::CHECKOVL_DEFINED; - if ( trafo.first ) flags |= AlignmentStack::MATRIX_DEFINED; if ( reset ) flags |= AlignmentStack::RESET_VALUE; if ( reset_dau ) flags |= AlignmentStack::RESET_CHILDREN; if ( check_val ) flags |= AlignmentStack::CHECKOVL_VALUE; - StackEntry* entry = new StackEntry(elt,placementPath,trafo.second,ovl,flags); + printout(INFO,"Alignment<detelement>","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)); + + auto_ptr<StackEntry> entry(new StackEntry(elt,placementPath,trafo.second,ovl,flags)); AlignmentStack::insert(entry); pair<DetElement,string> vol_param(elt,""); @@ -310,7 +279,8 @@ template <> void Converter<detelement>::operator()(xml_h e) const { * @date 01/04/2014 */ template <> void Converter<include_file>::operator()(xml_h element) const { - xml_h node = XML::DocumentHandler().load(element, element.attr_value(_U(ref))).root(); + XML::DocumentHolder doc(XML::DocumentHandler().load(element, element.attr_value(_U(ref)))); + xml_h node = doc.root(); string tag = node.tag(); if ( tag == "alignment" ) Converter<alignment>(lcdd,param)(node); @@ -335,7 +305,6 @@ template <> void Converter<include_file>::operator()(xml_h element) const { * @date 01/04/2014 */ template <> void Converter<alignment>::operator()(xml_h e) const { - AlignmentTransaction tr(lcdd, e); DetElement top = param ? *(DetElement*)param : lcdd.world(); /// Now we process all allowed elements within the alignment tag: @@ -354,6 +323,7 @@ template <> void Converter<alignment>::operator()(xml_h e) const { */ static long setup_Alignment(lcdd_t& lcdd, const xml_h& e) { AlignmentCache::install(lcdd); + AlignmentTransaction tr(lcdd, e); (DD4hep::Converter<DD4hep::alignment>(lcdd))(e); return 1; } diff --git a/DDAlign/src/AlignmentStack.cpp b/DDAlign/src/AlignmentStack.cpp index db5f3656c..8f60b62fe 100644 --- a/DDAlign/src/AlignmentStack.cpp +++ b/DDAlign/src/AlignmentStack.cpp @@ -10,25 +10,35 @@ #include "DD4hep/LCDD.h" #include "DD4hep/Objects.h" #include "DD4hep/Printout.h" +#include "DD4hep/InstanceCount.h" #include "DDAlign/AlignmentStack.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -static AlignmentStack* s_alignStack = 0; - +static auto_ptr<AlignmentStack>& _stack() { + static auto_ptr<AlignmentStack> s; + return s; +} +static auto_ptr<AlignmentStack>& _stack(AlignmentStack* obj) { + auto_ptr<AlignmentStack>& s = _stack(); + s = auto_ptr<AlignmentStack>(obj); + return s; +} /// Fully initializing constructor -AlignmentStack::StackEntry::StackEntry(const DetElement& p, const std::string& placement, const Transform3D& t, double ov, int f) +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(); @@ -38,6 +48,7 @@ AlignmentStack::StackEntry::StackEntry(DetElement element, bool rst, bool rst_ch 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; @@ -48,6 +59,7 @@ AlignmentStack::StackEntry::StackEntry(DetElement element, const Transform3D& tr 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; @@ -58,6 +70,7 @@ AlignmentStack::StackEntry::StackEntry(DetElement element, const Position& trans AlignmentStack::StackEntry::StackEntry(DetElement element, const RotationZYX& rot, bool rst, bool rst_children) : detector(element), transform(rot), overlap(0.001), flag(0) { + InstanceCount::increment(this); flag |= MATRIX_DEFINED; if ( rst ) flag |= RESET_VALUE; if ( rst_children ) flag |= RESET_CHILDREN; @@ -68,6 +81,7 @@ AlignmentStack::StackEntry::StackEntry(DetElement element, const RotationZYX& ro 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; @@ -78,6 +92,24 @@ AlignmentStack::StackEntry::StackEntry(DetElement element, const Position& trans AlignmentStack::StackEntry::StackEntry(const StackEntry& e) : detector(e.detector), transform(e.transform), path(e.path), overlap(e.overlap), flag(e.flag) { + InstanceCount::increment(this); +} + +/// Default destructor +AlignmentStack::StackEntry::~StackEntry() { + InstanceCount::decrement(this); +} + +/// Assignment operator +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; + } + return *this; } /// Attach transformation object @@ -126,45 +158,46 @@ AlignmentStack::StackEntry& AlignmentStack::StackEntry::setOverlapPrecision(doub /// Default constructor AlignmentStack::AlignmentStack() { + InstanceCount::increment(this); } /// Default destructor AlignmentStack::~AlignmentStack() { destroyObjects(m_stack)(); + InstanceCount::decrement(this); } /// Static client accessor AlignmentStack& AlignmentStack::get() { - if ( s_alignStack ) return *s_alignStack; + if ( _stack().get() ) return *_stack(); throw runtime_error("AlignmentStack> Stack not allocated -- may not be retrieved!"); } /// Create an alignment stack instance. The creation of a second instance will be refused. void AlignmentStack::create() { - if ( s_alignStack ) { + if ( _stack().get() ) { throw runtime_error("AlignmentStack> Stack already allocated. Multiple copies are not allowed!"); } - s_alignStack = new AlignmentStack(); + _stack(new AlignmentStack()); } /// Check existence of alignment stack bool AlignmentStack::exists() { - return s_alignStack != 0; + return _stack().get() != 0; } /// Clear data content and remove the slignment stack void AlignmentStack::release() { - if ( s_alignStack ) { - delete s_alignStack; - s_alignStack = 0; + if ( _stack().get() ) { + _stack(0); return; } throw runtime_error("AlignmentStack> Attempt to delete non existing stack."); } /// Add a new entry to the cache. The key is the placement path -bool AlignmentStack::insert(const std::string& full_path, StackEntry* entry) { - if ( entry && !full_path.empty() ) { +bool AlignmentStack::insert(const string& full_path, auto_ptr<StackEntry>& entry) { + if ( entry.get() && !full_path.empty() ) { entry->path = full_path; return get().add(entry); } @@ -172,16 +205,23 @@ bool AlignmentStack::insert(const std::string& full_path, StackEntry* entry) { } /// Add a new entry to the cache. The key is the placement path -bool AlignmentStack::insert(StackEntry* entry) { +bool AlignmentStack::insert(auto_ptr<StackEntry>& entry) { return get().add(entry); } /// Add a new entry to the cache. The key is the placement path -bool AlignmentStack::add(StackEntry* entry) { - if ( entry && !entry->path.empty() ) { +bool AlignmentStack::add(auto_ptr<StackEntry>& entry) { + if ( entry.get() && !entry->path.empty() ) { Stack::const_iterator i = m_stack.find(entry->path); if ( i == m_stack.end() ) { - m_stack.insert(make_pair(entry->path,entry)); + + // Need to make some checks BEFORE insertion + if ( !entry->detector.isValid() ) { + throw runtime_error("AlignmentStack> Invalid alignment entry [No such detector]"); + } + printout(INFO,"AlignmentStack","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+ diff --git a/DDAlign/src/AlignmentTransaction.cpp b/DDAlign/src/AlignmentTransaction.cpp new file mode 100644 index 000000000..8796af6d0 --- /dev/null +++ b/DDAlign/src/AlignmentTransaction.cpp @@ -0,0 +1,36 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DDAlign/AlignmentTags.h" +#include "DDAlign/AlignmentCache.h" +#include "DDAlign/AlignmentTransaction.h" + +using namespace DD4hep; +using namespace DD4hep::Geometry; + +/// Default constructor +AlignmentTransaction::AlignmentTransaction(LCDD& l, const XML::Handle_t& e) : lcdd(l) { + flag = e.hasChild(_U(close_transaction)); + /// First check if a transaction is to be opened + m_cache = lcdd.extension<Geometry::AlignmentCache>(); + m_cache->addRef(); + if ( e.hasChild(_U(open_transaction)) ) { + m_cache->openTransaction(); + } +} +/// Default destructor +AlignmentTransaction::~AlignmentTransaction() { + /// Last check if a transaction is to be closed + if ( flag ) { + lcdd.extension<Geometry::AlignmentCache>()->closeTransaction(); + } + m_cache->release(); +} diff --git a/DDAlign/src/AlignmentWriter.cpp b/DDAlign/src/AlignmentWriter.cpp index a87c54894..e11cf63db 100644 --- a/DDAlign/src/AlignmentWriter.cpp +++ b/DDAlign/src/AlignmentWriter.cpp @@ -165,7 +165,7 @@ static long create_alignment_file(LCDD& lcdd, int argc, char** argv) { printout(ALWAYS,"AlignmentWriter", "++++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"", path.c_str(), output.c_str()); - top = DetectorTools::findElement(lcdd.world(),path); + top = DetectorTools::findDaughterElement(lcdd.world(),path); if ( top.isValid() ) { AlignmentWriter wr(lcdd); return wr.write(wr.dump(top,enable_transactions), output); diff --git a/DDAlign/src/DetectorAlignment.cpp b/DDAlign/src/DetectorAlignment.cpp index 000a73072..bd1d1d071 100644 --- a/DDAlign/src/DetectorAlignment.cpp +++ b/DDAlign/src/DetectorAlignment.cpp @@ -11,6 +11,7 @@ #include "DD4hep/InstanceCount.h" #include "DD4hep/MatrixHelpers.h" #include "DD4hep/Printout.h" +#include "DD4hep/objects/DetectorInterna.h" // ROOT include files #include "TGeoMatrix.h" @@ -109,12 +110,12 @@ Alignment DetectorAlignment::alignment() const { } /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements -std::vector<Alignment>& DetectorAlignment::volumeAlignments() { +vector<Alignment>& DetectorAlignment::volumeAlignments() { return _data().volume_alignments; } /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements -const std::vector<Alignment>& DetectorAlignment::volumeAlignments() const { +const vector<Alignment>& DetectorAlignment::volumeAlignments() const { return _data().volume_alignments; } -- GitLab