File indexing completed on 2025-01-30 09:16:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Detector.h>
0016 #include <DD4hep/Printout.h>
0017 #include <DDAlign/GlobalAlignmentCache.h>
0018 #include <DDAlign/GlobalAlignmentOperators.h>
0019 #include <DD4hep/detail/DetectorInterna.h>
0020
0021
0022 #include <TGeoManager.h>
0023
0024 using namespace dd4hep::align;
0025 using Entry = GlobalAlignmentStack::StackEntry;
0026
0027 dd4hep::DetElement _detector(dd4hep::DetElement child) {
0028 if ( child.isValid() ) {
0029 dd4hep::DetElement p(child.parent());
0030 if ( p.isValid() && !p.parent().isValid() )
0031 return child;
0032 else if ( !p.isValid() )
0033 return child;
0034 return _detector(p);
0035 }
0036 dd4hep::except("GlobalAlignmentCache", "DetElement cannot determine detector parent [Invalid handle]");
0037 return {};
0038 }
0039
0040
0041 GlobalAlignmentCache::GlobalAlignmentCache(Detector& description, const std::string& sdPath, bool top)
0042 : m_detDesc(description), m_sdPath(sdPath), m_sdPathLen(sdPath.length()), m_refCount(1), m_top(top)
0043 {
0044 }
0045
0046
0047 GlobalAlignmentCache::~GlobalAlignmentCache() {
0048 int nentries = (int)m_cache.size();
0049 int nsect = (int)m_detectors.size();
0050 detail::releaseObjects(m_detectors);
0051 m_cache.clear();
0052 printout(INFO,"GlobalAlignmentCache",
0053 "Destroy cache for subdetector %s [%d section(s), %d entrie(s)]",
0054 m_sdPath.c_str(),nsect,nentries);
0055 }
0056
0057
0058 int GlobalAlignmentCache::addRef() {
0059 return ++m_refCount;
0060 }
0061
0062
0063 int GlobalAlignmentCache::release() {
0064 int value = --m_refCount;
0065 if ( value == 0 ) {
0066 delete this;
0067 }
0068 return value;
0069 }
0070
0071
0072 GlobalAlignmentCache* GlobalAlignmentCache::install(Detector& description) {
0073 GlobalAlignmentCache* cache = description.extension<GlobalAlignmentCache>(false);
0074 if ( !cache ) {
0075 cache = new GlobalAlignmentCache(description,"world",true);
0076 ExtensionEntry* e = new detail::DeleteExtension<GlobalAlignmentCache,GlobalAlignmentCache>(cache);
0077 description.addUserExtension(detail::typeHash64<GlobalAlignmentCache>(),e);
0078 }
0079 return cache;
0080 }
0081
0082
0083 void GlobalAlignmentCache::uninstall(Detector& description) {
0084 if ( description.extension<GlobalAlignmentCache>(false) ) {
0085 description.removeExtension<GlobalAlignmentCache>(true);
0086 }
0087 }
0088
0089
0090 bool GlobalAlignmentCache::insert(GlobalAlignment alignment) {
0091 TGeoPhysicalNode* pn = alignment.ptr();
0092 unsigned int index = detail::hash32(pn->GetName()+m_sdPathLen);
0093 Cache::const_iterator i = m_cache.find(index);
0094 printout(ALWAYS,"GlobalAlignmentCache","Section: %s adding entry: %s",
0095 name().c_str(),alignment->GetName());
0096 if ( i == m_cache.end() ) {
0097 m_cache[index] = pn;
0098 return true;
0099 }
0100 return false;
0101 }
0102
0103
0104 GlobalAlignmentCache* GlobalAlignmentCache::section(const std::string& path_name) const {
0105 std::size_t idx, idq;
0106 if ( path_name[0] != '/' ) {
0107 return section(m_detDesc.world().placementPath()+'/'+path_name);
0108 }
0109 else if ( (idx=path_name.find('/',1)) == std::string::npos ) {
0110 return (m_sdPath == path_name.c_str()+1) ? (GlobalAlignmentCache*)this : 0;
0111 }
0112 else if ( m_detectors.empty() ) {
0113 return 0;
0114 }
0115 if ( (idq=path_name.find('/',idx+1)) != std::string::npos ) --idq;
0116 std::string path = path_name.substr(idx+1,idq-idx);
0117 SubdetectorAlignments::const_iterator j = m_detectors.find(path);
0118 return (j==m_detectors.end()) ? 0 : (*j).second;
0119 }
0120
0121
0122 GlobalAlignment GlobalAlignmentCache::get(const std::string& path_name) const {
0123 std::size_t idx, idq;
0124 unsigned int index = detail::hash32(path_name.c_str()+m_sdPathLen);
0125 Cache::const_iterator i = m_cache.find(index);
0126 if ( i != m_cache.end() ) {
0127 return GlobalAlignment((*i).second);
0128 }
0129 else if ( m_detectors.empty() ) {
0130 return GlobalAlignment(0);
0131 }
0132 else if ( path_name[0] != '/' ) {
0133 return get(m_detDesc.world().placementPath()+'/'+path_name);
0134 }
0135 else if ( (idx=path_name.find('/',1)) == std::string::npos ) {
0136
0137 return GlobalAlignment(0);
0138 }
0139 if ( (idq=path_name.find('/',idx+1)) != std::string::npos ) --idq;
0140 std::string path = path_name.substr(idx+1, idq-idx);
0141 SubdetectorAlignments::const_iterator j = m_detectors.find(path);
0142 if ( j != m_detectors.end() ) return (*j).second->get(path_name);
0143 return GlobalAlignment(0);
0144 }
0145
0146
0147 std::vector<GlobalAlignment>
0148 GlobalAlignmentCache::matches(const std::string& match, bool exclude_exact) const {
0149 std::vector<GlobalAlignment> result;
0150 GlobalAlignmentCache* c = section(match);
0151 if ( c ) {
0152 std::size_t len = match.length();
0153 result.reserve(c->m_cache.size());
0154 for(Cache::const_iterator i=c->m_cache.begin(); i!=c->m_cache.end();++i) {
0155 const Cache::value_type& v = *i;
0156 const char* n = v.second->GetName();
0157 if ( 0 == ::strncmp(n,match.c_str(),len) ) {
0158 if ( exclude_exact && len == ::strlen(n) ) continue;
0159 result.emplace_back(GlobalAlignment(v.second));
0160 }
0161 }
0162 }
0163 return result;
0164 }
0165
0166
0167 void GlobalAlignmentCache::commit(GlobalAlignmentStack& stack) {
0168 TGeoManager& mgr = m_detDesc.manager();
0169 mgr.UnlockGeometry();
0170 apply(stack);
0171 mgr.LockGeometry();
0172 }
0173
0174
0175 GlobalAlignmentCache* GlobalAlignmentCache::subdetectorAlignments(const std::string& nam) {
0176 SubdetectorAlignments::const_iterator i = m_detectors.find(nam);
0177 if ( i == m_detectors.end() ) {
0178 GlobalAlignmentCache* ptr = new GlobalAlignmentCache(m_detDesc,nam,false);
0179 m_detectors.emplace(nam,ptr);
0180 return ptr;
0181 }
0182 return (*i).second;
0183 }
0184
0185
0186 void GlobalAlignmentCache::apply(GlobalAlignmentStack& stack) {
0187 typedef std::map<std::string,DetElement> DetElementUpdates;
0188 typedef std::map<DetElement,std::vector<Entry*> > sd_entries_t;
0189 TGeoManager& mgr = m_detDesc.manager();
0190 DetElementUpdates detelt_updates;
0191 sd_entries_t all;
0192
0193 while(stack.size() > 0) {
0194 Entry* e = stack.pop().release();
0195 DetElement det = _detector(e->detector);
0196 all[det].emplace_back(e);
0197 if ( stack.hasMatrix(*e) || stack.needsReset(*e) || stack.resetChildren(*e) ) {
0198 detelt_updates.emplace(e->detector.path(),e->detector);
0199 }
0200 }
0201 for(sd_entries_t::iterator i=all.begin(); i!=all.end(); ++i) {
0202 DetElement det((*i).first);
0203 GlobalAlignmentCache* sd_cache = subdetectorAlignments(det.placement().name());
0204 sd_cache->apply( (*i).second );
0205 (*i).second.clear();
0206 }
0207
0208 printout(INFO,"GlobalAlignmentCache","Alignments were applied. Refreshing physical nodes....");
0209 mgr.GetCurrentNavigator()->ResetAll();
0210 mgr.GetCurrentNavigator()->BuildCache();
0211 mgr.RefreshPhysicalNodes();
0212
0213
0214 for(DetElementUpdates::iterator i=detelt_updates.begin(); i!=detelt_updates.end(); ++i) {
0215 DetElement elt((*i).second);
0216 printout(DEBUG,"GlobalAlignmentCache","+++ Trigger placement update for %s [2]",elt.path().c_str());
0217 elt->update(DetElement::PLACEMENT_CHANGED|DetElement::PLACEMENT_ELEMENT,elt.ptr());
0218 }
0219
0220 std::string last_path = "?????";
0221 for(DetElementUpdates::iterator i=detelt_updates.begin(); i!=detelt_updates.end(); ++i) {
0222 const std::string& path = (*i).first;
0223 if ( path.find(last_path) == std::string::npos ) {
0224 DetElement elt((*i).second);
0225 printout(DEBUG,"GlobalAlignmentCache","+++ Trigger placement update for %s [1]",elt.path().c_str());
0226 elt->update(DetElement::PLACEMENT_CHANGED|DetElement::PLACEMENT_HIGHEST,elt.ptr());
0227 last_path = (*i).first;
0228 }
0229 }
0230
0231 for(sd_entries_t::iterator i=all.begin(); i!=all.end(); ++i) {
0232 DetElement elt((*i).first);
0233 printout(DEBUG,"GlobalAlignmentCache","+++ Trigger placement update for %s [0]",elt.path().c_str());
0234 elt->update(DetElement::PLACEMENT_CHANGED|DetElement::PLACEMENT_DETECTOR,elt.ptr());
0235 }
0236 }
0237
0238
0239 void GlobalAlignmentCache::apply(const std::vector<Entry*>& changes) {
0240 std::map<std::string,std::pair<TGeoPhysicalNode*,Entry*> > nodes;
0241 namespace ops = dd4hep::align::DDAlign_standard_operations;
0242 GlobalAlignmentSelector selector(*this,nodes,changes);
0243
0244 for_each(m_cache.begin(),m_cache.end(),selector.reset());
0245 for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<ops::node_print>(*this,nodes));
0246 for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<ops::node_reset>(*this,nodes));
0247
0248 for_each(changes.begin(),changes.end(),selector.reset());
0249 for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<ops::node_align>(*this,nodes));
0250 for_each(nodes.begin(),nodes.end(),GlobalAlignmentActor<ops::node_delete>(*this,nodes));
0251 }