ATLAS Offline Software
Loading...
Searching...
No Matches
InDetDetectorManager.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7
14
15#include <map>
16
17namespace InDetDD
18{
19
20 InDetDetectorManager::InDetDetectorManager(StoreGateSvc * detStore, const std::string & name)
21 : AthMessaging(name+"DetectorManager"),
24 {
25 setName(name);
26 }
27
28 // Destructor
30 = default;
31
32
34 {
35 return m_version;
36 }
37
38 const std::string& InDetDetectorManager::getLayout() const
39 {
40 return m_version.layout();
41 }
42
44 {
45 m_version = version;
46
47 // Since default alignments are for final layout, Pixel Rome-Initial
48 // layout will result in several (harmless) WARNING message. We suppress these.
49 // Also the SR1 layout produce warnings due to missing parts. We suppress these also.
50 m_suppressWarnings = ( (getName() == "Pixel" &&
51 (version.tag() == "Pixel-01" || version.tag() == "Pixel-DC2-Initial-00"))
52 || version.layout() == "SR1" || version.layout() == "SR1-EndcapC");
53
54 }
55
56 void InDetDetectorManager::addChannel(const std::string & key, int level, FrameType frame)
57 {
58 std::string frameStr = "other";
59 if (frame == InDetDD::global) frameStr = "global";
60 if (frame == InDetDD::local) frameStr = "local";
61 ATH_MSG_INFO("Registering alignment channel with key " << key << ", level " << level
62 << ", with frame " << frameStr << ".");
63 m_keys[key] = LevelInfo(level, frame);
64 }
65
66 void InDetDetectorManager::addFolder(const std::string & key)
67 {
68 m_folders.insert(key);
69 }
70
71 void InDetDetectorManager::addSpecialFolder(const std::string & key)
72 {
73 m_specialFolders.insert(key);
74 }
75
76 void InDetDetectorManager::addGlobalFolder(const std::string & key)
77 {
78 m_globalFolders.insert(key);
79 }
80
82 {
83 m_alignfoldertype = alignfolder;
84 }
85
86 // Return the level in the hierarchy (user defined) corresponding to the key.
88 {
89 std::map<std::string, LevelInfo>::const_iterator iter;
90 iter = m_keys.find(key);
91 if (iter == m_keys.end()) return s_invalidLevel;
92 return iter->second;
93 }
94
96 {
97
98 (void) I; // avoid warning about unused parameter
99
100 ATH_MSG_DEBUG("AlignmentCallback called ");
101
102 if (!getIdHelper()) return StatusCode::SUCCESS;
103
104 bool alignmentChange = false;
105 const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype);
106
107 // If dummy arguments
108 if (keys.empty()) {
109
110
111 // New global aligment folders should be processed first
112 for (const auto & globalFolder : m_globalFolders) {
113
114 try {
115 bool status = processGlobalAlignmentContainer(globalFolder);
116 alignmentChange = (alignmentChange || status);
117 } catch(std::runtime_error& err) {
118 // keys are empty when running simualtion. It is normal for detector specific aligments not to exist.
119 ATH_MSG_FATAL(err.what());
120 return StatusCode::FAILURE;
121 }
122 }
123
124 // Regular alignments. Loop through folder keys. Normally only one.
125 for (const auto & folder : m_folders) {
126
127 try {
128 bool status = processAlignmentContainer(folder);
129 alignmentChange = (alignmentChange || status);
130 }
131 catch(std::runtime_error& err) {
132 // alignments should always exist so we return fatal if we could not process the alignment for this key
133 ATH_MSG_FATAL(err.what());
134 return StatusCode::FAILURE;
135 }
136 }
137 // Detector specific aligments
138 for (const auto & specialFolder : m_specialFolders) {
139 try {
140 bool status = processSpecialAlignment(specialFolder, aligninfo.AlignFolder());
141 alignmentChange = (alignmentChange || status);
142 } catch(std::runtime_error& err) {
143 // keys are empty when running simualtion. It is normal for detector specific aligments not to exist.
144 ATH_MSG_INFO(err.what());
145 // We continue as detector specific aligments don't always exist.
146 }
147 }
148
149 } else {
150 // Loop over all the keys.
151 for (std::list<std::string>::const_iterator itr=keys.begin(); itr!=keys.end(); ++itr) {
152
153 const std::string & key = *itr;
154
155 ATH_MSG_DEBUG(" Processing call back key " << key);
156
157 if ( m_globalFolders.find(key) != m_globalFolders.end() ) {
158
159 try {
160 // New global alignemnts
162 alignmentChange = (alignmentChange || status);
163 } catch(std::runtime_error& err) {
164 // alignments should always exist so we return fatal if we could not process the alignment for this key
165 ATH_MSG_FATAL(err.what());
166 return StatusCode::FAILURE;
167 }
168
169 } else if ( m_folders.find(key) != m_folders.end() ) {
170
171 try {
172 // Regular alignemnts
174 alignmentChange = (alignmentChange || status);
175 } catch(std::runtime_error& err) {
176 // alignments should always exist so we return fatal if we could not process the alignment for this key
177 ATH_MSG_FATAL(err.what());
178 return StatusCode::FAILURE;
179 }
180
181 } else if ( m_specialFolders.find(key) != m_specialFolders.end() ) {
182 try {
183 // Detector specific alignments
184 bool status = processSpecialAlignment(key, aligninfo.AlignFolder());
185 alignmentChange = (alignmentChange || status);
186 }
187 catch(std::runtime_error& err) {
188 // Should always exist if the folder was requested so we return fatal if we could not process the alignment for this key
189 ATH_MSG_FATAL(err.what());
190 return StatusCode::FAILURE;
191 }
192 } else {
193 // Should not be any other keys specified in call back.
194 ATH_MSG_ERROR("Unrecognized key in call back.");
195 return StatusCode::RECOVERABLE;
196 }
197 }
198 }
199
200 // We invalidate all the elements if at least one alignment changed.
201 if (alignmentChange) {
202 //this is non-const as it invalidate the elements we hold
204 }
205
206 return StatusCode::SUCCESS;
207 }
208
209 StatusCode InDetDetectorManager::align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const
210 {
211
212 ATH_MSG_DEBUG("align() called from an alignment CondAlg");
213 if (!getIdHelper()) return StatusCode::SUCCESS; // To Do: is it really a success?
214
215 bool alignmentChange = false;
216 // const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype);
217
218 for(const auto& alignObj : alignObjects) {
219 const std::string& key = alignObj.first;
220
221 ATH_MSG_DEBUG(" Processing folder " << key);
222
223 if(m_globalFolders.find(key)!=m_globalFolders.end()) {
224 try {
225 // New global alignemnts
226 const CondAttrListCollection* obj = static_cast<const CondAttrListCollection*>(alignObj.second);
227 bool status = processGlobalAlignmentContainer(key,obj,alignStore);
228 alignmentChange = (alignmentChange || status);
229 } catch(std::runtime_error& err) {
230 // alignments should always exist so we return fatal if we could not process the alignment for this key
231 ATH_MSG_FATAL(err.what());
232 return StatusCode::FAILURE;
233 }
234 }
235 else if(m_folders.find(key)!=m_folders.end()) {
236 try {
237 // Regular alignemnts
238 const AlignableTransformContainer* container = static_cast<const AlignableTransformContainer*>(alignObj.second);
239 bool status = processAlignmentContainer(container,alignStore);
240 alignmentChange = (alignmentChange || status);
241 } catch(std::runtime_error& err) {
242 // alignments should always exist so we return fatal if we could not process the alignment for this key
243 ATH_MSG_FATAL(err.what());
244 return StatusCode::FAILURE;
245 }
246 }
247 else if(m_specialFolders.find(key)!=m_specialFolders.end()) {
248 try {
249 // Detector specific alignments
250 const CondAttrListCollection *obj =
251 static_cast<const CondAttrListCollection*>(alignObj.second);
252 bool status = processSpecialAlignment(key, obj, alignStore);
253 alignmentChange = (alignmentChange || status);
254 }
255 catch(std::runtime_error& err) {
256 // Should always exist if the folder was requested so we return fatal if
257 // we could not process the alignment for this key
258 ATH_MSG_FATAL(err.what());
259 return StatusCode::FAILURE;
260 }
261 }
262 else {
263 // Should not be any other keys specified in raw alignment object.
264 ATH_MSG_ERROR("Unrecognized folder name "<<key<<". Expected names are:");
265 for (const std::string& out:m_globalFolders) ATH_MSG_ERROR("--"<<out);
266 for (const std::string& out:m_folders) ATH_MSG_ERROR("--"<<out);
267 for (const std::string& out:m_specialFolders) ATH_MSG_ERROR("--"<<out);
268
269 return StatusCode::RECOVERABLE;
270 }
271 }
272 return StatusCode::SUCCESS;
273 }
274
275 bool InDetDetectorManager::processAlignmentContainer(const std::string & key) const
276 {
277 bool alignmentChange = false;
278
279 ATH_MSG_DEBUG("Dealing with key as container");
281 if (StatusCode::SUCCESS!=m_detStore->retrieve(container, key)) {
282 ATH_MSG_ERROR("Cannot find AlignableTransformContainer for key "
283 << key << " - no misalignment");
284 // This should not occur in normal situations so we force job to abort.
285 throw std::runtime_error("Unable to apply Inner Detector alignments");
286 }
287 // Check if container is empty - this can occur if it is an invalid IOV.
288 if (container->empty()) {
289 ATH_MSG_ERROR("AlignableTransformContainer for key "
290 << key << " is empty. Probably due to out of range IOV");
291 // This should not occur in normal situations so we force job to abort.
292 throw std::runtime_error("Unable to apply Inner Detector alignments.");
293 }
294 // loop over all the AlignableTransform objects in the collection
295 for (const auto *pat : *container) {
296
297 bool status = processKey(pat->tag(),pat);
298 alignmentChange = (alignmentChange || status);
299 }
300 return alignmentChange;
301 }
302
304 {
305 bool alignmentChange = false;
306
307 // Check if container is empty - this can occur if it is an invalid IOV.
308 if (container->empty()) {
309 ATH_MSG_ERROR("AlignableTransformContainer "
310 << " is empty. Probably due to out of range IOV"); // To Do: add key to this printout for making it more informative
311 // This should not occur in normal situations so we force job to abort.
312 throw std::runtime_error("Unable to apply Inner Detector alignments.");
313 }
314 // loop over all the AlignableTransform objects in the collection
315 // use only the last ones.
316 // /Indet/AlignL3/SCTEA9 appear repeatedly in tags of the /Indet/AlignL3 folder
317 std::map<const std::string, const AlignableTransform*> stringToTransform;
318 for (const auto *pat : *container) {
319 stringToTransform[pat->tag()] = pat;
320 }
321 for (const std::pair<const std::string, const AlignableTransform*>& value: stringToTransform) {
322 bool status = processKey(value.first, value.second, alignStore);
323 alignmentChange = (alignmentChange || status);
324 }
325 return alignmentChange;
326 }
327
328 bool InDetDetectorManager::processKey(const std::string& key,
329 const AlignableTransform* transformCollection,
330 GeoVAlignmentStore* alignStore) const
331 {
332 bool alignmentChange = false;
333
334 // From the key determine what level in hierarchy we are dealing with.
335 // returns -1 if unrecognized.
336 const LevelInfo & levelInfo = getLevel(key);
337 if (levelInfo.isValid()) {
338 ATH_MSG_VERBOSE("Processing channel: " << key);
339 } else {
340 ATH_MSG_DEBUG("Channel " << key << " not registered in this manager");
341 }
342 // return silently if unrecognised - this can happen in container mode
343 // when a single container holds transforms for both pixel and SCT
344 if (!levelInfo.isValid() ) return false;
345
346 //Loop over the effected nodes.
347 for (AlignableTransform::AlignTransMem_citr trans_iter = transformCollection->begin();
348 trans_iter != transformCollection->end();
349 ++trans_iter) {
350 ATH_MSG_DEBUG( "Get alignment for identifier "
351 << getIdHelper()->show_to_string(trans_iter->identify())
352 << " at level " << levelInfo.level());
353
354 // The delta in the conditions DB is not necessarily the same as what is needed in the
355 // alignable transform. At the moment we support global frame, local frame or an alternative frame
356 // The setAlignableTransformDelta method takes care of this correction - this is CLHEP <--> Amg interfaced
357 bool status = setAlignableTransformDelta(levelInfo.level(),
358 trans_iter->identify(),
359 Amg::CLHEPTransformToEigen(trans_iter->transform()),
360 levelInfo.frame(),
361 alignStore);
362
363 alignmentChange = (alignmentChange || status);
364
365 if (!status) {
366 if (!identifierBelongs(trans_iter->identify())) {
367 // Its probably OK. Eg /Indet/Align/ID contains alse pixel and sct ids.
368 ATH_MSG_DEBUG("Cannot set AlignableTransform for identifier."
369 << " Probably OK if its /Indet/Align/ID folder. "
370 << getIdHelper()->show_to_string(trans_iter->identify())
371 << " at level " << levelInfo.level());
372 } else {
373 if (m_suppressWarnings) {
374 ATH_MSG_DEBUG("WARNING: Cannot set AlignableTransform for identifier "
375 << getIdHelper()->show_to_string(trans_iter->identify())
376 << " at level " << levelInfo.level());
377 } else {
378 ATH_MSG_WARNING("Cannot set AlignableTransform for identifier "
379 << getIdHelper()->show_to_string(trans_iter->identify())
380 << " at level " << levelInfo.level());
381 ATH_MSG_WARNING("Subsequent WARNINGS will be printed at DEBUG level.");
382 m_suppressWarnings = true;
383 }
384 }
385 }
386 }
387 return alignmentChange;
388 }
389
390 // We provide a default implementation of any detector specific alignment.
392 const CondAttrListCollection* obj,
393 GeoVAlignmentStore* alignStore) const
394 {
395 bool alignmentChange = false;
396
397 ATH_MSG_DEBUG("processing GlobalAlignmentContainer with key: " << key);
398 // From the key determine what level in hierarchy we are dealing with.
399 // returns -1 if unrecognized.
400 const LevelInfo & levelInfo = getLevel(key);
401 if (levelInfo.isValid()) {
402 ATH_MSG_VERBOSE("Processing channel: " << key);
403 } else {
404 ATH_MSG_DEBUG("Channel " << key << " not registered in this manager");
405 }
406 // return silently if unrecognised - this can happen in container mode
407 // when a single container holds transforms for both pixel and SCT
408 if (!levelInfo.isValid() ) return false;
409
410 // Within detector specific code
411 bool status = processGlobalAlignment(key, levelInfo.level(), levelInfo.frame(), obj, alignStore);
412
413 alignmentChange = (alignmentChange || status);
414
415 return alignmentChange;
416
417 }
418
419 // We provide a default implementation of any detector specific alignment.
420 bool InDetDetectorManager::processGlobalAlignment(const std::string &, int /*level*/, FrameType /*frame*/,
421 const CondAttrListCollection* /*obj*/, GeoVAlignmentStore* /*alignStore*/) const
422 {
423 return false;
424 }
425
426
427 // We provide a default implementation of any detector specific alignment.
429 {
430 return false;
431 }
432
434
435} // namespace InDetDD
CondMultChanCollection< AlignableTransform > AlignableTransformContainer
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
#define IOVSVC_CALLBACK_ARGS_P(I, K)
short hand for IOVSvc call back argument list, to be used when access to formal arguments is needed,...
Definition IOVSvcDefs.h:42
#define I(x, y, z)
Definition MD5.cxx:116
std::vector< AlignTransMember >::const_iterator AlignTransMem_citr
AlignTransMem_citr end() const
AlignTransMem_citr begin() const
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
This class is a collection of AttributeLists where each one is associated with a channel number.
virtual bool identifierBelongs(const Identifier &id) const =0
Check identifier is for this detector.
void addGlobalFolder(const std::string &key)
void addAlignFolderType(const AlignFolderType alignfolder)
bool processKey(const std::string &key, const AlignableTransform *transformCollection, GeoVAlignmentStore *alignStore=nullptr) const
Called by processAlignmentContainer, applies only one key on the transform Collections.
InDetDetectorManager(StoreGateSvc *detStore, const std::string &name)
std::set< std::string > m_specialFolders
const std::string & getLayout() const
virtual bool processSpecialAlignment(const std::string &key, InDetDD::AlignFolderType alignfolder)=0
static const LevelInfo s_invalidLevel
void addChannel(const std::string &key, int level, FrameType frame)
Alignment access.
void addFolder(const std::string &key)
virtual bool processGlobalAlignment(const std::string &key, int level, FrameType frame, const CondAttrListCollection *obj=nullptr, GeoVAlignmentStore *alignStore=nullptr) const
const LevelInfo & getLevel(const std::string &key) const
Retrieve level information.
bool processGlobalAlignmentContainer(const std::string &key, const CondAttrListCollection *obj=nullptr, GeoVAlignmentStore *alignStore=nullptr) const
virtual const AtlasDetectorID * getIdHelper() const =0
void addSpecialFolder(const std::string &key)
std::set< std::string > m_folders
virtual bool setAlignableTransformDelta(int level, const Identifier &id, const Amg::Transform3D &delta, FrameType frame, GeoVAlignmentStore *alignStore=nullptr) const =0
Set method applying the delta transform (in global or local frame) onto the geoModel transform : CLHE...
virtual void invalidateAll()=0
Invalidate cache for all detector elements.
std::set< std::string > m_globalFolders
void setVersion(const Version &version)
StatusCode align(IOVSVC_CALLBACK_ARGS)
const Version & getVersion() const
Get version information.
bool processAlignmentContainer(const std::string &key) const
return align folder string to use
std::map< std::string, LevelInfo > m_keys
Class to hold version information consisting of tag, name layout and description as strings,...
Definition Version.h:24
The Athena Transient Store API.
Amg::Transform3D CLHEPTransformToEigen(const HepGeom::Transform3D &CLHEPtransf)
Converts a CLHEP-based HepGeom::Transform3D into an Eigen Amg::Transform3D.
Message Stream Member.
std::map< std::string, const void * > RawAlignmentObjects
status
Definition merge.py:16