ATLAS Offline Software
Loading...
Searching...
No Matches
HGTDAlignDBTool.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// HGTDAlignDBTool.cxx
6// AlgTool for creating and managing HGTD alignment payloads.
7// This is the first implementation of the HGTD alignment database tool.
8// The alignment constants are stored at detector-module level.
9// Each HGTD module owns one AlignableTransform entry identified by
10// its Identifier.
11// Tool responsibilities:
12// * create an empty HGTD alignment payload
13// * update module transforms
14// * retrieve module transforms
15// * print payload contents
16// * stream payload objects
17// * register payload in the conditions database
18// Higher-level alignment strategies may still be performed externally,
19// but the final payload stored in SQLite is represented at module level.
20// Fatima Bendebba, started 2026
21
22#include "HGTDAlignDBTool.h"
23
31
33
35HGTDAlignDBTool(const std::string& type,
36 const std::string& name,
37 const IInterface* parent)
38 :
39 AthAlgTool(type,name,parent)
40{
41 declareInterface<IHGTDAlignDBTool>(this);
42}
43
45
47{
48 ATH_MSG_DEBUG("========================================");
49 ATH_MSG_DEBUG("LOCAL HGTDAlignDBTool initialize()");
50 ATH_MSG_DEBUG("========================================");
51
52 ATH_CHECK(detStore().retrieve());
53 ATH_CHECK(m_condStream.retrieve());
54 ATH_CHECK(detStore()->retrieve(m_detManager));
55 ATH_CHECK(detStore()->retrieve(m_hgtdId));
56
57 ATH_MSG_INFO("Alignment folder = " << m_dbRoot);
58 ATH_MSG_DEBUG("HGTD modules = " << m_hgtdId->wafer_hash_max());
59
60 return StatusCode::SUCCESS;
61}
62
64
65std::string
67{
68 IdentifierHash hash;
69 IdContext waferContext = m_hgtdId->wafer_context();
70
71 if (m_hgtdId->get_hash(id,
72 hash,
73 &waferContext))
74 {
75 ATH_MSG_WARNING("Failed to obtain wafer hash for " << m_hgtdId->show_to_string(id));
76 return {};
77 }
78
79 return "HGTDModule_" + std::to_string(hash.value());
80}
81
83
85{
86 ATH_MSG_INFO("Creating HGTD alignment payload");
87
89 {
90 ATH_MSG_ERROR("Alignment container already exists.");
91 return StatusCode::FAILURE;
92 }
93
94 auto* container = new AlignableTransformContainer;
95
96 unsigned int nModules = 0;
97 for(const auto* element : *m_detManager->getDetectorElementCollection())
98 {
99 if(!element)
100 continue;
101
102 Identifier id = element->identify();
103 IdentifierHash hash;
104 IdContext waferContext = m_hgtdId->wafer_context();
105
106 if(m_hgtdId->get_hash(id,
107 hash,
108 &waferContext))
109 {
110 ATH_MSG_WARNING("Cannot obtain wafer hash for " << m_hgtdId->show_to_string(id));
111 continue;
112 }
113
114 auto* transform = new AlignableTransform(moduleTag(id));
115
116 transform->add(
117 id,
118 Amg::EigenTransformToCLHEP(Amg::Transform3D::Identity()));
119
120 container->push_back(transform);
121 container->add(hash);
122 ATH_MSG_DEBUG("hash = " << hash.value()
123 << " tag = " << transform->tag());
124
125 ++nModules;
126 }
127
128 SG::DataProxy* proxy = detStore()->proxy(
130 m_dbRoot.value());
131
132 ATH_MSG_DEBUG("Proxy before record = " << proxy);
133
134 ATH_CHECK(detStore()->record(container, m_dbRoot.value()));
135
136 ATH_MSG_DEBUG("After record:");
137
138 const AlignableTransformContainer* test = nullptr;
139 StatusCode sc = detStore()->retrieve(test, m_dbRoot.value());
140
141 ATH_MSG_DEBUG("retrieve after record = " << sc);
142
143 if (test) {
144 ATH_MSG_DEBUG("retrieve pointer = " << test);
145 }
146 //sortTrans();
147
148 ATH_MSG_INFO("Created alignment payload for "
149 << nModules
150 << " HGTD modules.");
151
152 return StatusCode::SUCCESS;
153}
154
156
159{
160 const AlignableTransformContainer* container = nullptr;
161
162 if (detStore()->retrieve(container, m_dbRoot.value()).isFailure())
163 return nullptr;
164
165 const std::string tag = moduleTag(id);
166
167 for (const auto* transform : *container) {
168 if (transform->tag() == tag) {
169 return const_cast<AlignableTransform*>(transform);
170 }
171 }
172
173 return nullptr;
174}
175
177
180{
181 const AlignableTransformContainer* container = nullptr;
182
183 if (detStore()->retrieve(container, m_dbRoot.value()).isFailure())
184 return nullptr;
185
186 const std::string tag = moduleTag(id);
187
188 for (const auto* transform : *container) {
189 if (transform->tag() == tag) {
190 return transform;
191 }
192 }
193
194 return nullptr;
195}
196
198
199bool
201 unsigned int level,
202 const Amg::Transform3D& trans) const
203{
206 (void)level;
207
208 AlignableTransform* transform = getTransPtr(id);
209
210 if(!transform)
211 {
212 ATH_MSG_ERROR("Cannot retrieve AlignableTransform for " << m_hgtdId->show_to_string(id));
213 return false;
214 }
215
216 return transform->update(
217 id,
219}
220
222
223bool
225 const Identifier& id,
226 unsigned int level,
227 const Amg::Vector3D& translation,
228 double alpha,
229 double beta,
230 double gamma) const
231{
232 Amg::Translation3D t(translation);
233
235 t * Amg::RotationMatrix3D::Identity();
236
237 tr *= Amg::AngleAxis3D(
238 gamma,
239 Amg::Vector3D(0.,0.,1.));
240
241 tr *= Amg::AngleAxis3D(
242 beta,
243 Amg::Vector3D(0.,1.,0.));
244
245 tr *= Amg::AngleAxis3D(
246 alpha,
247 Amg::Vector3D(1.,0.,0.));
248
249 return setTrans(id, level, tr);
250}
251
253
254bool
256 unsigned int level,
257 const Amg::Transform3D& trans) const
258{
259 (void)level;
260
261 AlignableTransform* transform = getTransPtr(id);
262
263 if(!transform)
264 {
265 ATH_MSG_ERROR("Cannot retrieve AlignableTransform for " << m_hgtdId->show_to_string(id));
266 return false;
267 }
268
269 return transform->tweak(
270 id,
272}
273
275
276bool
278 const Identifier& id,
279 unsigned int level,
280 const Amg::Vector3D& translation,
281 double alpha,
282 double beta,
283 double gamma) const
284{
285 Amg::Translation3D t(translation);
286
288 t * Amg::RotationMatrix3D::Identity();
289
290 tr *= Amg::AngleAxis3D(
291 gamma,
292 Amg::Vector3D(0.,0.,1.));
293
294 tr *= Amg::AngleAxis3D(
295 beta,
296 Amg::Vector3D(0.,1.,0.));
297
298 tr *= Amg::AngleAxis3D(
299 alpha,
300 Amg::Vector3D(1.,0.,0.));
301
302 return tweakTrans(id, level, tr);
303}
304
306
309 unsigned int level) const
310{
311 (void)level;
312 const AlignableTransform* transform = cgetTransPtr(id);
313
314 if(!transform)
315 return Amg::Transform3D::Identity();
316
317 AlignableTransform::AlignTransMem_citr itr = transform->findIdent(id);
318
319 if (itr != transform->end()) {
321 itr->transform());
322 }
323
324 return Amg::Transform3D::Identity();
325}
326
328
330{
331 ATH_MSG_INFO("Writing HGTD alignment payload");
332
333 if (m_condStream->connectOutput().isFailure()) {
334 ATH_MSG_ERROR("Cannot connect output stream");
335 return StatusCode::FAILURE;
336 }
337
338 ATH_MSG_DEBUG("Output stream connected");
339
341 ATH_MSG_ERROR("Cannot find AlignableTransformContainer "
342 << m_dbRoot.value());
343 return StatusCode::FAILURE;
344 }
345
346 ATH_MSG_DEBUG("Container exists in DetectorStore");
347
349
350 objects.emplace_back("AlignableTransformContainer", m_dbRoot.value());
351
352 ATH_MSG_DEBUG("Streaming "
353 << objects.size()
354 << " object(s)");
355
356 if (m_condStream->streamObjects(objects).isFailure()) {
357
358 const AlignableTransformContainer* c = nullptr;
359 ATH_CHECK(detStore()->retrieve(c, m_dbRoot.value()));
360 ATH_MSG_INFO("Container key = " << m_dbRoot.value());
361 ATH_MSG_INFO("Container size = " << c->size());
362 ATH_MSG_INFO("Container pointer = " << c);
363
364 ATH_MSG_ERROR("streamObjects failed");
365 return StatusCode::FAILURE;
366 }
367
368 ATH_MSG_DEBUG("Objects streamed");
369
370 if (m_condStream->commitOutput().isFailure()) {
371 ATH_MSG_ERROR("commitOutput failed");
372 return StatusCode::FAILURE;
373 }
374
375 ATH_MSG_INFO("POOL payload committed");
376
377 const AlignableTransformContainer* c = nullptr;
378
379 ATH_CHECK(detStore()->retrieve(c, m_dbRoot.value()));
380
381 if (c) {
382 ATH_MSG_DEBUG("container ptr = " << c);
383 ATH_MSG_DEBUG("container size = " << c->size());
384 } else {
385 ATH_MSG_DEBUG("container is nullptr");
386 }
387
388 SG::DataProxy* proxy =
390 m_dbRoot.value());
391
392 if (!proxy) {
393 ATH_MSG_WARNING("NO PROXY FOUND");
394 }
395 else {
396 ATH_MSG_DEBUG("Proxy = " << proxy);
397 ATH_MSG_DEBUG("Proxy name = " << proxy->name());
398 ATH_MSG_DEBUG("Proxy CLID = " << proxy->clID());
399 const auto* address = proxy->address();
400 ATH_MSG_DEBUG("Proxy address = " << address);
401
402 if (address) {
403 ATH_MSG_DEBUG("Storage type = " << address->svcType());
404 ATH_MSG_DEBUG("Address class = " << typeid(*address).name());
405 }
406 }
407
408 return StatusCode::SUCCESS;
409}
410
412
413StatusCode
414HGTDAlignDBTool::fillDB(const std::string& tag,
415 unsigned int run1,
416 unsigned int event1,
417 unsigned int run2,
418 unsigned int event2) const
419{
420 SmartIF<IIOVRegistrationSvc> regSvc{
421 Gaudi::svcLocator()->service("IOVRegistrationSvc")
422 };
423
424 if(!regSvc.isValid())
425 {
426 ATH_MSG_FATAL("Cannot retrieve IOVRegistrationSvc");
427 return StatusCode::FAILURE;
428 }
429
430 ATH_MSG_INFO("Registering folder " << m_dbRoot);
431 ATH_MSG_INFO("Tag = " << tag);
432
433 ATH_CHECK(
434 regSvc->registerIOV(
435 "AlignableTransformContainer",
436 m_dbRoot.value(),
437 tag,
438 run1,
439 run2,
440 event1,
441 event2));
442
443 ATH_MSG_INFO("IOV registration successful");
444
445 return StatusCode::SUCCESS;
446}
447
449
451{
452 const AlignableTransformContainer* container = nullptr;
453
454 if (detStore()->retrieve(container, m_dbRoot.value()).isFailure())
455 return;
456
457 ATH_MSG_INFO("HGTD alignment payload:");
458
459 unsigned int n = 0;
460
461 for (const auto* transform : *container) {
462
463 for (auto itr = transform->begin();
464 itr != transform->end();
465 ++itr)
466 {
467 const Amg::Transform3D trans = Amg::CLHEPTransformToEigen(itr->transform());
468 const Amg::Vector3D shift = trans.translation();
469
470 ATH_MSG_INFO("Identifier : "
471 << itr->identify()
472 << " Shift = ("
473 << shift.x() << ", "
474 << shift.y() << ", "
475 << shift.z() << ")");
476
477 ++n;
478 }
479 }
480
481 ATH_MSG_INFO("Total aligned modules : " << n);
482}
483
485
487{
488 const AlignableTransformContainer* container = nullptr;
489
490 if (detStore()->retrieve(container, m_dbRoot.value()).isFailure())
491 return;
492
493 for (const auto* transform : *container) {
494 const_cast<AlignableTransform*>(transform)->sortv();
495 }
496}
CondMultChanCollection< AlignableTransform > AlignableTransformContainer
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This is an interface to a tool used to register conditions objects in the Interval of Validity (IOV) ...
static Double_t sc
std::vector< AlignTransMember >::const_iterator AlignTransMem_citr
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
Gaudi::Property< std::string > m_dbRoot
Alignment folder.
ToolHandle< IAthenaOutputStreamTool > m_condStream
Output stream.
StatusCode fillDB(const std::string &tag, unsigned int run1, unsigned int event1, unsigned int run2, unsigned int event2) const override
Register payload in the Conditions DB.
const HGTD_ID * m_hgtdId
HGTD Identifier helper.
const AlignableTransform * cgetTransPtr(const Identifier &id) const
Retrieve read-only AlignableTransform.
void printDB() const override
Print payload.
const HGTD_DetectorManager * m_detManager
HGTD detector manager.
virtual Amg::Transform3D getTrans(const Identifier &, unsigned int level) const override
Retrieve transform.
StatusCode createDB() override
Create an empty alignment payload.
std::string moduleTag(const Identifier &id) const
Build the AlignableTransform tag corresponding to one HGTD module.
StatusCode initialize() override
bool setTrans(const Identifier &, unsigned int level, const Amg::Transform3D &) const override
Replace the transform of one module.
bool tweakTrans(const Identifier &, unsigned int level, const Amg::Transform3D &) const override
Apply an incremental transform.
AlignableTransform * getTransPtr(const Identifier &id) const
Retrieve writable AlignableTransform.
StatusCode outputObjs() override
Stream payload to POOL.
HGTDAlignDBTool(const std::string &type, const std::string &name, const IInterface *parent)
void sortTrans() const override
Sort AlignableTransform entries.
std::vector< TypeKeyPair > TypeKeyPairs
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
Eigen::AngleAxisd AngleAxis3D
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.
Amg::Transform3D CLHEPTransformToEigen(const HepGeom::Transform3D &CLHEPtransf)
Converts a CLHEP-based HepGeom::Transform3D into an Eigen Amg::Transform3D.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D