ATLAS Offline Software
Loading...
Searching...
No Matches
InDetDetectorManager.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 ATH_MSG_DEBUG("align() called ");
98
99 if (!getIdHelper()) return StatusCode::SUCCESS;
100
101 bool alignmentChange = false;
102 const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype);
103
104 // New global aligment folders should be processed first
105 for (const auto & globalFolder : m_globalFolders) {
106
107 try {
108 bool status = processGlobalAlignmentContainer(globalFolder);
109 alignmentChange = (alignmentChange || status);
110 } catch(std::runtime_error& err) {
111 // keys are empty when running simualtion. It is normal for detector specific aligments not to exist.
112 ATH_MSG_FATAL(err.what());
113 return StatusCode::FAILURE;
114 }
115 }
116
117 // Regular alignments. Loop through folder keys. Normally only one.
118 for (const auto & folder : m_folders) {
119
120 try {
121 bool status = processAlignmentContainer(folder);
122 alignmentChange = (alignmentChange || status);
123 }
124 catch(std::runtime_error& err) {
125 // alignments should always exist so we return fatal if we could not process the alignment for this key
126 ATH_MSG_FATAL(err.what());
127 return StatusCode::FAILURE;
128 }
129 }
130 // Detector specific aligments
131 for (const auto & specialFolder : m_specialFolders) {
132 try {
133 bool status = processSpecialAlignment(specialFolder, aligninfo.AlignFolder());
134 alignmentChange = (alignmentChange || status);
135 } catch(std::runtime_error& err) {
136 // keys are empty when running simualtion. It is normal for detector specific aligments not to exist.
137 ATH_MSG_INFO(err.what());
138 // We continue as detector specific aligments don't always exist.
139 }
140 }
141
142 // We invalidate all the elements if at least one alignment changed.
143 if (alignmentChange) {
144 //this is non-const as it invalidate the elements we hold
146 }
147
148 return StatusCode::SUCCESS;
149 }
150
151 StatusCode InDetDetectorManager::align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const
152 {
153
154 ATH_MSG_DEBUG("align() called from an alignment CondAlg");
155 if (!getIdHelper()) return StatusCode::SUCCESS; // To Do: is it really a success?
156
157 bool alignmentChange = false;
158 // const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype);
159
160 for(const auto& alignObj : alignObjects) {
161 const std::string& key = alignObj.first;
162
163 ATH_MSG_DEBUG(" Processing folder " << key);
164
165 if(m_globalFolders.find(key)!=m_globalFolders.end()) {
166 try {
167 // New global alignemnts
168 const CondAttrListCollection* obj = static_cast<const CondAttrListCollection*>(alignObj.second);
169 bool status = processGlobalAlignmentContainer(key,obj,alignStore);
170 alignmentChange = (alignmentChange || status);
171 } catch(std::runtime_error& err) {
172 // alignments should always exist so we return fatal if we could not process the alignment for this key
173 ATH_MSG_FATAL(err.what());
174 return StatusCode::FAILURE;
175 }
176 }
177 else if(m_folders.find(key)!=m_folders.end()) {
178 try {
179 // Regular alignemnts
180 const AlignableTransformContainer* container = static_cast<const AlignableTransformContainer*>(alignObj.second);
181 bool status = processAlignmentContainer(container,alignStore);
182 alignmentChange = (alignmentChange || status);
183 } catch(std::runtime_error& err) {
184 // alignments should always exist so we return fatal if we could not process the alignment for this key
185 ATH_MSG_FATAL(err.what());
186 return StatusCode::FAILURE;
187 }
188 }
189 else if(m_specialFolders.find(key)!=m_specialFolders.end()) {
190 try {
191 // Detector specific alignments
192 const CondAttrListCollection *obj =
193 static_cast<const CondAttrListCollection*>(alignObj.second);
194 bool status = processSpecialAlignment(key, obj, alignStore);
195 alignmentChange = (alignmentChange || status);
196 }
197 catch(std::runtime_error& err) {
198 // Should always exist if the folder was requested so we return fatal if
199 // we could not process the alignment for this key
200 ATH_MSG_FATAL(err.what());
201 return StatusCode::FAILURE;
202 }
203 }
204 else {
205 // Should not be any other keys specified in raw alignment object.
206 ATH_MSG_ERROR("Unrecognized folder name "<<key<<". Expected names are:");
207 for (const std::string& out:m_globalFolders) ATH_MSG_ERROR("--"<<out);
208 for (const std::string& out:m_folders) ATH_MSG_ERROR("--"<<out);
209 for (const std::string& out:m_specialFolders) ATH_MSG_ERROR("--"<<out);
210
211 return StatusCode::RECOVERABLE;
212 }
213 }
214 return StatusCode::SUCCESS;
215 }
216
217 bool InDetDetectorManager::processAlignmentContainer(const std::string & key) const
218 {
219 bool alignmentChange = false;
220
221 ATH_MSG_DEBUG("Dealing with key as container");
223 if (StatusCode::SUCCESS!=m_detStore->retrieve(container, key)) {
224 ATH_MSG_ERROR("Cannot find AlignableTransformContainer for key "
225 << key << " - no misalignment");
226 // This should not occur in normal situations so we force job to abort.
227 throw std::runtime_error("Unable to apply Inner Detector alignments");
228 }
229 // Check if container is empty - this can occur if it is an invalid IOV.
230 if (container->empty()) {
231 ATH_MSG_ERROR("AlignableTransformContainer for key "
232 << key << " is empty. Probably due to out of range IOV");
233 // This should not occur in normal situations so we force job to abort.
234 throw std::runtime_error("Unable to apply Inner Detector alignments.");
235 }
236 // loop over all the AlignableTransform objects in the collection
237 for (const auto *pat : *container) {
238
239 bool status = processKey(pat->tag(),pat);
240 alignmentChange = (alignmentChange || status);
241 }
242 return alignmentChange;
243 }
244
246 {
247 bool alignmentChange = false;
248
249 // Check if container is empty - this can occur if it is an invalid IOV.
250 if (container->empty()) {
251 ATH_MSG_ERROR("AlignableTransformContainer "
252 << " is empty. Probably due to out of range IOV"); // To Do: add key to this printout for making it more informative
253 // This should not occur in normal situations so we force job to abort.
254 throw std::runtime_error("Unable to apply Inner Detector alignments.");
255 }
256 // loop over all the AlignableTransform objects in the collection
257 // use only the last ones.
258 // /Indet/AlignL3/SCTEA9 appear repeatedly in tags of the /Indet/AlignL3 folder
259 std::map<const std::string, const AlignableTransform*> stringToTransform;
260 for (const auto *pat : *container) {
261 stringToTransform[pat->tag()] = pat;
262 }
263 for (const std::pair<const std::string, const AlignableTransform*>& value: stringToTransform) {
264 bool status = processKey(value.first, value.second, alignStore);
265 alignmentChange = (alignmentChange || status);
266 }
267 return alignmentChange;
268 }
269
270 bool InDetDetectorManager::processKey(const std::string& key,
271 const AlignableTransform* transformCollection,
272 GeoVAlignmentStore* alignStore) const
273 {
274 bool alignmentChange = false;
275
276 // From the key determine what level in hierarchy we are dealing with.
277 // returns -1 if unrecognized.
278 const LevelInfo & levelInfo = getLevel(key);
279 if (levelInfo.isValid()) {
280 ATH_MSG_VERBOSE("Processing channel: " << key);
281 } else {
282 ATH_MSG_DEBUG("Channel " << key << " not registered in this manager");
283 }
284 // return silently if unrecognised - this can happen in container mode
285 // when a single container holds transforms for both pixel and SCT
286 if (!levelInfo.isValid() ) return false;
287
288 //Loop over the effected nodes.
289 for (AlignableTransform::AlignTransMem_citr trans_iter = transformCollection->begin();
290 trans_iter != transformCollection->end();
291 ++trans_iter) {
292 ATH_MSG_DEBUG( "Get alignment for identifier "
293 << getIdHelper()->show_to_string(trans_iter->identify())
294 << " at level " << levelInfo.level());
295
296 // The delta in the conditions DB is not necessarily the same as what is needed in the
297 // alignable transform. At the moment we support global frame, local frame or an alternative frame
298 // The setAlignableTransformDelta method takes care of this correction - this is CLHEP <--> Amg interfaced
299 bool status = setAlignableTransformDelta(levelInfo.level(),
300 trans_iter->identify(),
301 Amg::CLHEPTransformToEigen(trans_iter->transform()),
302 levelInfo.frame(),
303 alignStore);
304
305 alignmentChange = (alignmentChange || status);
306
307 if (!status) {
308 if (!identifierBelongs(trans_iter->identify())) {
309 // Its probably OK. Eg /Indet/Align/ID contains alse pixel and sct ids.
310 ATH_MSG_DEBUG("Cannot set AlignableTransform for identifier."
311 << " Probably OK if its /Indet/Align/ID folder. "
312 << getIdHelper()->show_to_string(trans_iter->identify())
313 << " at level " << levelInfo.level());
314 } else {
315 if (m_suppressWarnings) {
316 ATH_MSG_DEBUG("WARNING: Cannot set AlignableTransform for identifier "
317 << getIdHelper()->show_to_string(trans_iter->identify())
318 << " at level " << levelInfo.level());
319 } else {
320 ATH_MSG_WARNING("Cannot set AlignableTransform for identifier "
321 << getIdHelper()->show_to_string(trans_iter->identify())
322 << " at level " << levelInfo.level());
323 ATH_MSG_WARNING("Subsequent WARNINGS will be printed at DEBUG level.");
324 m_suppressWarnings = true;
325 }
326 }
327 }
328 }
329 return alignmentChange;
330 }
331
332 // We provide a default implementation of any detector specific alignment.
334 const CondAttrListCollection* obj,
335 GeoVAlignmentStore* alignStore) const
336 {
337 bool alignmentChange = false;
338
339 ATH_MSG_DEBUG("processing GlobalAlignmentContainer with key: " << key);
340 // From the key determine what level in hierarchy we are dealing with.
341 // returns -1 if unrecognized.
342 const LevelInfo & levelInfo = getLevel(key);
343 if (levelInfo.isValid()) {
344 ATH_MSG_VERBOSE("Processing channel: " << key);
345 } else {
346 ATH_MSG_DEBUG("Channel " << key << " not registered in this manager");
347 }
348 // return silently if unrecognised - this can happen in container mode
349 // when a single container holds transforms for both pixel and SCT
350 if (!levelInfo.isValid() ) return false;
351
352 // Within detector specific code
353 bool status = processGlobalAlignment(key, levelInfo.level(), levelInfo.frame(), obj, alignStore);
354
355 alignmentChange = (alignmentChange || status);
356
357 return alignmentChange;
358
359 }
360
361 // We provide a default implementation of any detector specific alignment.
362 bool InDetDetectorManager::processGlobalAlignment(const std::string &, int /*level*/, FrameType /*frame*/,
363 const CondAttrListCollection* /*obj*/, GeoVAlignmentStore* /*alignStore*/) const
364 {
365 return false;
366 }
367
368
369 // We provide a default implementation of any detector specific alignment.
371 {
372 return false;
373 }
374
376
377} // 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...
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)
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