ATLAS Offline Software
Loading...
Searching...
No Matches
CreateMisalignAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// ================================================
7// CreateMisalignAlg
8// ================================================
9//
10// CreateMisalignAlg.cxx
11// Source file for CreateMisalignAlg
12//
13// Namespace LocalChi2Align
14// Header include
15
16// Gaudi & StoreGate
17#include "GaudiKernel/ITHistSvc.h"
18#include "GaudiKernel/SmartDataPtr.h" //NTupleFilePtr
19#include "GaudiKernel/RndmGenerators.h"
20#include "GaudiKernel/IRndmGenSvc.h"
21
22// Geometry Stuff
23#include "Identifier/Identifier.h"
33
34// Alignment DB Stuff
38#include "CreateMisalignAlg.h"
41#include <cmath>
42#include <tuple> //for tuple decomposition and std::ignore
43#include <sstream>
44
45
46
47
50
51
52namespace{
53 std::string commonAlignmentOutput(const HepGeom::Transform3D & initialAlignment){
54 std::ostringstream os;
55 os << "\nAlignment x = (" << initialAlignment.getTranslation().x() / CLHEP::micrometer << ") micron\n";
56 os << "Alignment y = (" << initialAlignment.getTranslation().y() / CLHEP::micrometer << ") micron\n";
57 os << "Alignment z = (" << initialAlignment.getTranslation().z() / CLHEP::micrometer << ") micron\n";
58 os << "Alignment x phi = (" << initialAlignment.getRotation().phiX() / CLHEP::deg << ") degree\n";
59 os << "Alignment x Theta = (" << initialAlignment.getRotation().thetaX() / CLHEP::deg << ") degree\n";
60 os << "Alignment y phi = (" << initialAlignment.getRotation().phiY() / CLHEP::deg << ") degree\n";
61 os << "Alignment y Theta = (" << initialAlignment.getRotation().thetaY() / CLHEP::deg << ") degree\n";
62 os << "Alignment z phi = (" << initialAlignment.getRotation().phiZ() / CLHEP::deg << ") degree\n";
63 os << "Alignment z Theta = (" << initialAlignment.getRotation().thetaZ() / CLHEP::deg << ") degree\n";
64 return os.str();
65 }
66}
67
69{
70
71 // Constructor
72 CreateMisalignAlg::CreateMisalignAlg(const std::string& name, ISvcLocator* pSvcLocator):
73 AthAlgorithm(name,pSvcLocator),
74 m_idHelper(nullptr),
75 m_pixelIdHelper(nullptr),
76 m_sctIdHelper(nullptr),
77 m_trtIdHelper(nullptr),
78 m_IDAlignDBTool("InDetAlignDBTool",this),
79 m_trtaligndbservice("TRT_AlignDbSvc",name),
80 m_asciiFileNameBase("MisalignmentSet"),
81 m_SQLiteTag("test_tag"),
82 m_firstEvent(true),
83 m_createFreshDB(true),
85 m_nEvents(0),
86 m_translation{0.1, 0.1, 0.1},
87 m_rotation{0.1, 0.1, 0.1},
88 m_local_translation{0., 0., 0.},
89 m_local_rotation{0., 0., 0.},
90 m_index(""),
92 m_Misalign_maxShift_Inner(50*CLHEP::micrometer),
105 m_doPix(true),
106 m_doStrip(true),
107 m_doTRT(true)
108 {
109 declareProperty("ASCIIFilenameBase" , m_asciiFileNameBase);
110 declareProperty("SQLiteTag" , m_SQLiteTag);
111 declareProperty("MisalignMode" , m_MisalignmentMode);
112 declareProperty("Translation_Scale" , m_translation);
113 declareProperty("Rotation_Scale" , m_rotation);
114 declareProperty("Local_Translation" , m_local_translation);
115 declareProperty("Local_Rotation" , m_local_rotation);
116 declareProperty("Index" , m_index);
119 declareProperty("CreateFreshDB" , m_createFreshDB);
120 declareProperty("IDAlignDBTool" , m_IDAlignDBTool);
121 declareProperty("TRTAlignDBService" , m_trtaligndbservice);
122 declareProperty("ScalePixelIBL" , m_ScalePixelIBL);
123 declareProperty("ScalePixelDBM" , m_ScalePixelDBM);
124 declareProperty("IBLBowingTshift" , m_IBLBowingTshift);
125 declareProperty("ScalePixelBarrel" , m_ScalePixelBarrel);
126 declareProperty("ScalePixelEndcap" , m_ScalePixelEndcap);
127 declareProperty("ScaleSCTBarrel" , m_ScaleSCTBarrel);
128 declareProperty("ScaleSCTEndcap" , m_ScaleSCTEndcap);
129 declareProperty("ScaleTRTBarrel" , m_ScaleTRTBarrel);
130 declareProperty("ScaleTRTEndcap" , m_ScaleTRTEndcap);
131 }
132
133 //__________________________________________________________________________
134 // Destructor
136 {
137 ATH_MSG_DEBUG( "CreateMisalignAlg destructor called" );
138 }
139
140 //__________________________________________________________________________
142 {
143 ATH_MSG_DEBUG("CreateMisalignAlg initialize()");
144 if(m_pixelDetEleCollKey.empty()) {m_doPix=false;ATH_MSG_INFO("Not creating misalignment for Pixel");}
145 if(m_SCTDetEleCollKey.empty()) {m_doStrip=false;ATH_MSG_INFO("Not creating misalignment for Strip/SCT");}
146 if(m_trtDetEleCollKey.empty()) {m_doTRT=false;ATH_MSG_INFO("Not creating misalignment for TRT");}
147
151
152 if (m_doPix || m_doStrip) ATH_CHECK(m_IDAlignDBTool.retrieve());
153 if(m_doTRT) ATH_CHECK(m_trtaligndbservice.retrieve());
154 //ID helpers
155 // Pixel
156 if(m_doPix){
157 ATH_CHECK(detStore()->retrieve(m_pixelIdHelper, "PixelID"));
158 }
159 // SCT
160 if(m_doStrip){
161 ATH_CHECK(detStore()->retrieve(m_sctIdHelper, "SCT_ID"));
162 }
163 // TRT
164 if(m_doTRT){
165 ATH_CHECK(detStore()->retrieve(m_trtIdHelper, "TRT_ID"));
166 }
167 ATH_CHECK(detStore()->retrieve(m_idHelper, "AtlasID"));
168
169 // Retrieve the Histo Service
170 SmartIF<ITHistSvc> hist_svc{Gaudi::svcLocator()->service("THistSvc")};
171 ATH_CHECK(hist_svc.isValid());
172 //Registering TTree for Visualization Lookup
173 m_VisualizationLookupTree = new TTree("IdentifierTree", "Visualization Identifier Lookup Tree");
174 ATH_CHECK(hist_svc->regTree("/IDENTIFIERTREE/IdentifierTree", m_VisualizationLookupTree));
175 m_VisualizationLookupTree->Branch ("AthenaHashedID", &m_AthenaHashedID, "AthenaID/i");
176 m_VisualizationLookupTree->Branch ("HumanReadableID", &m_HumanReadableID, "HumanID/I");
177
178 // initialize generated Initial Alignment NTuple
179 NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/CREATEMISALIGN");
180
181 NTuplePtr nt(ntupleSvc(), "/NTUPLES/CREATEMISALIGN/InitialAlignment");
182 if ( !nt ) { // Check if already booked
183 nt = ntupleSvc()->book("/NTUPLES/CREATEMISALIGN/InitialAlignment", CLID_ColumnWiseTuple, "InitialAlignment");
184 if ( nt ) {
185 ATH_MSG_INFO( "InitialAlignment ntuple booked." );
186 ATH_CHECK( nt->addItem("x" ,m_AlignResults_x) );
187 ATH_CHECK( nt->addItem("y" ,m_AlignResults_y) );
188 ATH_CHECK( nt->addItem("z" ,m_AlignResults_z) );
189 ATH_CHECK( nt->addItem("alpha" ,m_AlignResults_alpha) );
190 ATH_CHECK( nt->addItem("beta" ,m_AlignResults_beta) );
191 ATH_CHECK( nt->addItem("gamma" ,m_AlignResults_gamma) );
192 ATH_CHECK( nt->addItem("ID" ,m_AlignResults_Identifier_ID) );
193 ATH_CHECK( nt->addItem("PixelSCT" ,m_AlignResults_Identifier_PixelSCT) );
194 ATH_CHECK( nt->addItem("BarrelEC" ,m_AlignResults_Identifier_BarrelEC) );
195 ATH_CHECK( nt->addItem("LayerDisc" ,m_AlignResults_Identifier_LayerDisc) );
196 ATH_CHECK( nt->addItem("Phi" ,m_AlignResults_Identifier_Phi) );
197 ATH_CHECK( nt->addItem("Eta" ,m_AlignResults_Identifier_Eta) );
198 ATH_CHECK( nt->addItem("center_x" ,m_Initial_center_x ) );
199 ATH_CHECK( nt->addItem("center_y" ,m_Initial_center_y ) );
200 ATH_CHECK( nt->addItem("center_z" ,m_Initial_center_z ) );
201 ATH_CHECK( nt->addItem("misaligned_global_x" ,m_Global_center_x ) );
202 ATH_CHECK( nt->addItem("misaligned_global_y" ,m_Global_center_y ) );
203 ATH_CHECK( nt->addItem("misaligned_global_z" ,m_Global_center_z ) );
204 } else { // did not manage to book the N tuple....
205 msg(MSG::ERROR) << "Failed to book InitialAlignment ntuple." << endmsg;
206 }
207 }
208
209 if (m_MisalignmentMode) {
210 ATH_MSG_INFO( "Misalignment mode chosen: " << m_MisalignmentMode );
211 if (m_MisalignmentMode == 1) {
212 ATH_MSG_INFO( "MisalignmentX : " << m_Misalign_x / CLHEP::micrometer << " micrometer" );
213 ATH_MSG_INFO( "MisalignmentY : " << m_Misalign_y / CLHEP::micrometer << " micrometer" );
214 ATH_MSG_INFO( "MisalignmentZ : " << m_Misalign_z / CLHEP::micrometer << " micrometer" );
215 ATH_MSG_INFO( "MisalignmentAlpha : " << m_Misalign_alpha / CLHEP::mrad << " mrad" );
216 ATH_MSG_INFO( "MisalignmentBeta : " << m_Misalign_beta / CLHEP::mrad << " mrad" );
217 ATH_MSG_INFO( "MisalignmentGamma : " << m_Misalign_gamma / CLHEP::mrad << " mrad" );
218 } else {
219 ATH_MSG_INFO( "with maximum shift of " << m_Misalign_maxShift / CLHEP::micrometer << " micrometer" );
220 }
221 } else {
222 ATH_MSG_INFO( "Dry run, no misalignment will be generated." );
223 }
224
225 return StatusCode::SUCCESS;
226 }
227
228 //__________________________________________________________________________
230 {
231 ATH_MSG_DEBUG( "AlignAlg execute()" );
232 ++m_nEvents;
233
234 if (m_firstEvent) {
235 int nSCT = 0;
236 int nPixel = 0;
237 int nTRT = 0;
238
239 if (m_createFreshDB) {
240 m_IDAlignDBTool->createDB();
241 //m_trtaligndbservice->createAlignObjects(); //create DB for TRT? should be ok... //TODO
242 }
243
247
248 ATH_MSG_INFO( "Back from AlignModuleObject Setup. " );
249 ATH_MSG_INFO( nPixel << " Pixel modules found." );
250 ATH_MSG_INFO( nSCT << " SCT modules found," );
251 ATH_MSG_INFO( nTRT << " TRT modules found." );
252
253 ATH_MSG_INFO( m_ModuleList.size() << " entries in identifier list" );
254
255 if (StatusCode::SUCCESS!=GenerateMisaligment()) {
256 ATH_MSG_ERROR( "GenerateMisalignment failed!" );
257 return StatusCode::FAILURE;
258 };
259
260 m_firstEvent = false;
261 }
262
263 return StatusCode::SUCCESS;
264 }
265
266 //__________________________________________________________________________
268 {
269 ATH_MSG_DEBUG("CreateMisalignAlg finalize()" );
270
271 m_ModuleList.clear();
272
273 return StatusCode::SUCCESS;
274 }
275
276 //__________________________________________________________________________
278 {
279 // SiDetectorElementCollection for SCT
281 const InDetDD::SiDetectorElementCollection* elements(*sctDetEleHandle);
282 if (not sctDetEleHandle.isValid() or elements==nullptr) {
283 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " is not available.");
284 return;
285 }
286 for (const InDetDD::SiDetectorElement *element: *elements) {
287 const Identifier SCT_ModuleID = m_sctIdHelper->module_id(element->identify()); //from wafer id to module id
288 const IdentifierHash SCT_ModuleHash = m_sctIdHelper->wafer_hash(SCT_ModuleID);
289
290 if (m_ModuleList.find(SCT_ModuleID) == m_ModuleList.end())
291 {
292 const InDetDD::SiDetectorElement *module = elements->getDetectorElement(SCT_ModuleHash);
293 m_ModuleList[SCT_ModuleID][0] = module->center()[0];
294 m_ModuleList[SCT_ModuleID][1] = module->center()[1];
295 m_ModuleList[SCT_ModuleID][2] = module->center()[2];
296 ++nSCT;
297 ATH_MSG_VERBOSE( "SCT module " << nSCT );
298 }
299
300 if (m_sctIdHelper->side(element->identify()) == 0) { // inner side case
301 // Write out Visualization Lookup Tree
303 m_HumanReadableID = 1000000*2 /*2 = SCT*/
304 + 100000*m_sctIdHelper->layer_disk(SCT_ModuleID)
305 + 1000*(10+m_sctIdHelper->eta_module(SCT_ModuleID))
306 + m_sctIdHelper->phi_module(SCT_ModuleID);
307 if ( m_sctIdHelper->barrel_ec(SCT_ModuleID) != 0 ) {
308 m_HumanReadableID = m_sctIdHelper->barrel_ec(SCT_ModuleID)*(m_HumanReadableID + 10000000);
309 }
310
311 ATH_MSG_VERBOSE( "Human Readable ID: " << m_HumanReadableID );
312
314
315 // Syntax is (ID, Level) where Level is from 1 to 3 (3 is single module level)
316 if (msgLvl(MSG::VERBOSE)) {
317 HepGeom::Transform3D InitialAlignment = Amg::EigenTransformToCLHEP(m_IDAlignDBTool->getTrans(SCT_ModuleID,3));
318 msg() << "Initial Alignment of module " << m_idHelper->show_to_string(SCT_ModuleID,nullptr,'/') << endmsg;
319 msg() << commonAlignmentOutput(InitialAlignment);
320 msg() << endmsg;
321 }
322 } // end inner side case
323 } //end loop over SCT elements
324 }
325
326 //__________________________________________________________________________
328 {
329 // SiDetectorElementCollection for Pixel
331 const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
332 if (not pixelDetEleHandle.isValid() or elements==nullptr) {
333 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
334 return;
335 }
336 for (const InDetDD::SiDetectorElement *element: *elements) {
337 // get the ID
338 const Identifier Pixel_ModuleID = element->identify();
339 const IdentifierHash Pixel_ModuleHash = m_pixelIdHelper->wafer_hash(Pixel_ModuleID);
340 // check the validity
341 if (Pixel_ModuleID.is_valid()) {
342 if (m_ModuleList.find(Pixel_ModuleID) == m_ModuleList.end()) {
343 const InDetDD::SiDetectorElement *module = elements->getDetectorElement(Pixel_ModuleHash);
344 m_ModuleList[Pixel_ModuleID][0] = module->center()[0];
345 m_ModuleList[Pixel_ModuleID][1] = module->center()[1];
346 m_ModuleList[Pixel_ModuleID][2] = module->center()[2];
347
348 ++nPixel;
349 ATH_MSG_VERBOSE( "Pixel module " << nPixel );
350
351 // Write out Visualization Lookup Tree
352 m_AthenaHashedID = Pixel_ModuleID.get_identifier32().get_compact();
353 m_HumanReadableID = 1000000*1 /*1 = Pixel*/
354 + 100000*m_pixelIdHelper->layer_disk(Pixel_ModuleID)
355 + 1000*(10+m_pixelIdHelper->eta_module(Pixel_ModuleID))
356 + m_pixelIdHelper->phi_module(Pixel_ModuleID);
357 if ( m_pixelIdHelper->barrel_ec(Pixel_ModuleID) != 0 ) {
358 m_HumanReadableID = m_pixelIdHelper->barrel_ec(Pixel_ModuleID)*(m_HumanReadableID + 10000000);
359 }
360
361 ATH_MSG_VERBOSE( "Human Readable ID: " << m_HumanReadableID );
362
364
365 if (msgLvl(MSG::VERBOSE)) {
366 HepGeom::Transform3D InitialAlignment = Amg::EigenTransformToCLHEP(m_IDAlignDBTool->getTrans(Pixel_ModuleID,3));
367 msg() << "Initial Alignment of module " << m_idHelper->show_to_string(Pixel_ModuleID,nullptr,'/') << endmsg;
368 msg() << commonAlignmentOutput(InitialAlignment);
369 msg() << endmsg;
370 }
371 }
372 } else {
373 ATH_MSG_INFO( "not a valid PIXEL Module ID (setup)" );
374 }
375 }
376 }
377
378 //__________________________________________________________________________
380 {
381 //TODO: writing into the Identifier tree is undone for TRT (AthenaHashedID and HumanReadableID)
382
383 std::map< Identifier, std::vector<double> > trtModulesWithCOG;
384
385 // TRT_DetElementContainer->TRT_DetElementCollection for TRT
387 const InDetDD::TRT_DetElementCollection* elements(trtDetEleHandle->getElements());
388 if (not trtDetEleHandle.isValid() or elements==nullptr) {
389 ATH_MSG_FATAL(m_trtDetEleCollKey.fullKey() << " is not available.");
390 return;
391 }
392
393 //step through all detector elements (=strawlayers) and accumulate strawcenters per
394 // element (with DB granularity, i.e. phi sectors in endcap, bi-modules in barrel)
395 for (const InDetDD::TRT_BaseElement *element: *elements) {
396 const Identifier TRTID_orig = element->identify();
397 const Identifier TRTID = reduceTRTID(TRTID_orig);
398 bool insertSuccess{};
399 std::tie(std::ignore, insertSuccess) = trtModulesWithCOG.insert({TRTID,std::vector<double>(4,0.)}); //create fresh vector for module center
400 if (not insertSuccess){
401 ATH_MSG_VERBOSE("No insert was performed, identifier was already in the trtModulesWithCOG map");
402 }
403
404 unsigned int nStraws = element->nStraws();
405 for (unsigned int l = 0; l<nStraws; l++) {
406 const Amg::Vector3D strawcenter = element->strawCenter(l);
407 trtModulesWithCOG[TRTID].at(0) += strawcenter.x(); /*sumx*/
408 trtModulesWithCOG[TRTID].at(1) += strawcenter.y(); /*sumy*/
409 trtModulesWithCOG[TRTID].at(2) += strawcenter.z(); /*sumz*/
410 trtModulesWithCOG[TRTID].at(3) += 1.; /*nStraws*/
411
412 }
413
414 ATH_MSG_DEBUG( "this strawlayer has " << nStraws << " straws." );
415 ATH_MSG_DEBUG( "strawcount of this module: " << trtModulesWithCOG[TRTID].at(3) );
416
417 }
418
419 //go through cog list and create one COG per TRT module (at DB granularity)
420 std::map< Identifier, std::vector<double> >::const_iterator iter2;
421 for (iter2 = trtModulesWithCOG.begin(); iter2!=trtModulesWithCOG.end(); ++iter2) {
422 const Identifier TRTID = iter2->first;
423 double nStraws = iter2->second.at(3);
424 nTRT++;
425 ATH_MSG_VERBOSE( "TRT module " << nTRT );
426 m_ModuleList[TRTID] = HepGeom::Point3D<double>(iter2->second.at(0)/nStraws, iter2->second.at(1)/nStraws,iter2->second.at(2)/nStraws);
427
428 HepGeom::Transform3D InitialAlignment ;
429
430 const Amg::Transform3D* p = m_trtaligndbservice->getAlignmentTransformPtr(TRTID,2) ;
431 if ( p ) {
432 if (msgLvl(MSG::VERBOSE)) {
433 InitialAlignment = Amg::EigenTransformToCLHEP(*p) ;
434 msg() << "Initial Alignment of module " << m_idHelper->show_to_string(TRTID,nullptr,'/') << endmsg;
435 msg() << commonAlignmentOutput(InitialAlignment);
436 msg() << endmsg;
437 }
438 } else {
439
440 ATH_MSG_VERBOSE("No initial alignment for TRT module " << m_idHelper->show_to_string(TRTID,nullptr,'/') );
441 }
442
443
444 }
445 }
446
447 //__________________________________________________________________________
449 {
450
451 SmartIF<IRndmGenSvc> randsvc{Gaudi::svcLocator()->service("RndmGenSvc")};
452 ATH_CHECK(randsvc.isValid());
453 ATH_MSG_DEBUG( "Got RndmGenSvc" );
454
455 int i = 0;
456
457 /*
458 ===================================
459 Documentation of misalignment modes
460 ===================================
461
462 MisalignMode =
463 0: nothing, no misalignments are generated
464 1: Misalignment of whole InDet by 6 parameters
465 2: random misalignment
466 3: IBL-stave temperature dependent bowing
467
468 ====================================================
469 Global Distortions according to David Brown (LHC Detector Alignment Workshop 2006-09-04, slides page 11)
470 ====================================================
471 11: R delta R: Radial expansion linearly with r
472 12: Phi delta R: radial expansion sinuisoidally with phi
473 13: Z delta R: radial expansion linearly with z
474 21: R delta Phi: rotation linearly with r
475 22: Phi delta Phi: rotation sinusoidally with phi
476 23: Z delta Phi: rotation linearly with z
477 31: R delta Z: z-shift linearly with r
478 32: Phi delta Z: z-shift sinusoidally with phi
479 33: Z delta Z: z-shift linearly with z
480 */
481
482 const double maxRadius=51.4*CLHEP::cm; // maximum radius of Silicon Detector (=outermost SCT radius)
483 const double minRadius=50.5*CLHEP::mm; // minimum radius of Silicon Detector (=innermost PIX radius)
484 const double maxLength=158.*CLHEP::cm; // maximum length of Silicon Detector barrel (=length of SCT barrel)
485
486 const double maxDeltaR = m_Misalign_maxShift;
487 const double maxAngle = 2 * asin( m_Misalign_maxShift / (2*maxRadius));
488 const double maxAngleInner = 2 * asin ( m_Misalign_maxShift_Inner / (2*minRadius));
489 const double maxDeltaZ = m_Misalign_maxShift;
490 ATH_MSG_DEBUG( "maximum deltaPhi = " << maxAngle/CLHEP::mrad << " mrad" );
491 ATH_MSG_DEBUG( "maximum deltaPhi for 1/r term = " << maxAngleInner/CLHEP::mrad << " mrad" );
492 const InDetDD::SiDetectorElementCollection* pixelElements=nullptr;
493 const InDetDD::SiDetectorElementCollection* sctElements=nullptr;
494 if(m_doPix){
495 // SiDetectorElementCollection for Pixel
497 pixelElements = *pixelDetEleHandle;
498 if (not pixelDetEleHandle.isValid() or pixelElements==nullptr) {
499 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
500 return StatusCode::FAILURE;
501 }
502 }
503 if(m_doStrip){
504 // SiDetectorElementCollection for SCT
506 sctElements = *sctDetEleHandle;
507 if (not sctDetEleHandle.isValid() or sctElements==nullptr) {
508 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " is not available.");
509 return StatusCode::FAILURE;
510 }
511 }
512
513 for (std::map<Identifier, HepGeom::Point3D<double> >::const_iterator iter = m_ModuleList.begin(); iter != m_ModuleList.end(); ++iter) {
514 ++i;
515 const Identifier& ModuleID = iter->first;
516
517 const InDetDD::SiDetectorElement * SiModule = nullptr; //dummy to get moduleTransform() for silicon
518
519 if (m_idHelper->is_pixel(ModuleID)) {
520 const IdentifierHash Pixel_ModuleHash = m_pixelIdHelper->wafer_hash(ModuleID);
521 if(pixelElements) SiModule = pixelElements->getDetectorElement(Pixel_ModuleHash);
522 else ATH_MSG_WARNING("Trying to access a Pixel module when running with no Pixel!");
523 //module = SiModule;
524 } else if (m_idHelper->is_sct(ModuleID)) {
525 const IdentifierHash SCT_ModuleHash = m_sctIdHelper->wafer_hash(ModuleID);
526 if(sctElements) SiModule = sctElements->getDetectorElement(SCT_ModuleHash);
527 else ATH_MSG_WARNING("Trying to access an SCT/Strop module when running with no SCT/Strip!");
528 //module = SiModule;OB
529 } else if (m_idHelper->is_trt(ModuleID)) {
530 //module = m_TRT_Manager->getElement(ModuleID);
531 //const InDetDD::TRT_BaseElement *p_TRT_Module = m_TRT_Manager->getElement(iter->second.moduleID());
532 } else {
533 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
534 }
535
536 //TRT alignment transformations are given in global frame in DB,
537 // that's not fully correct, since the level2 transform can rotate the system in which level1 transforms
538 // are applied ...
539
540 //Si have a local coordinate system
541 // Take care: For SCT we have to ensure that module's
542 // system is taken, not the system of one of the wafers!
543 HepGeom::Transform3D localToGlobal = HepGeom::Transform3D();
544 if ((not m_idHelper->is_trt(ModuleID))){
545 if (SiModule){
546 localToGlobal=Amg::EigenTransformToCLHEP(SiModule->moduleTransform());
547 } else {
548 ATH_MSG_WARNING("Apparently in a silicon detector, but SiModule is a null pointer");
549 }
550 }
551 const HepGeom::Point3D<double> center = iter->second;
552
553 //center of module in global coordinates
554 double r = center.rho(); //distance from beampipe
555 double phi = center.phi();
556 double z = center.z();
557
558 HepGeom::Transform3D parameterizedTrafo;
559 HepGeom::Transform3D alignmentTrafo;
560
561
562 // prepare scale factor for different subsystems:
563 double ScaleFactor = 1.;
564
565 if (m_idHelper->is_pixel(ModuleID))
566 {
567 if (m_pixelIdHelper->is_barrel(ModuleID)) {
568 ScaleFactor=m_ScalePixelBarrel;
569 }
570 else {
571 ScaleFactor=m_ScalePixelEndcap;
572 }
573 if (m_pixelIdHelper->is_blayer(ModuleID)) { // IBL
574 ScaleFactor=m_ScalePixelIBL;
575 }
576 if (m_pixelIdHelper->is_dbm(ModuleID)) { // DBM
577 ScaleFactor=m_ScalePixelDBM;
578 }
579
580 } else if (m_idHelper->is_sct(ModuleID))
581 {
582 if (m_sctIdHelper->is_barrel(ModuleID)) {
583 ScaleFactor=m_ScaleSCTBarrel;
584 }
585 else {
586 ScaleFactor=m_ScaleSCTEndcap;
587 }
588
589 } else if (m_idHelper->is_trt(ModuleID))
590 {
591 if (m_trtIdHelper->is_barrel(ModuleID)) {
592 ScaleFactor=m_ScaleTRTBarrel;
593 }
594 else {
595 ScaleFactor=m_ScaleTRTEndcap;
596 }
597 } else {
598 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
599 }
600
601
602
603 ATH_MSG_INFO( "ID Module " << i << " with ID " << m_idHelper->show_to_string(ModuleID,nullptr,'/') );
604 if (msgLvl(MSG::DEBUG)) {
605 msg() << "radius " << r / CLHEP::cm << " centimeter" << endmsg;
606 msg() << "phi " << phi << endmsg;
607 msg() << "z " << z / CLHEP::cm << " centimeter" << endmsg;
608 if (msgLvl(MSG::VERBOSE)) {
609 msg() << "localToGlobal transformation:" << endmsg;
610 msg() << "translation: " << localToGlobal.dx() / CLHEP::cm << ";" << localToGlobal.dy() / CLHEP::cm << ";" << localToGlobal.dz() / CLHEP::cm << endmsg;
611 msg() << "rotation: " << endmsg;
612 msg() << localToGlobal.xx() << " " << localToGlobal.xy() << " " << localToGlobal.xz() << endmsg;
613 msg() << localToGlobal.yx() << " " << localToGlobal.yy() << " " << localToGlobal.yz() << endmsg;
614 msg() << localToGlobal.zx() << " " << localToGlobal.zy() << " " << localToGlobal.zz() << endmsg;
615 }
616 }
617
618 if (!m_MisalignmentMode) {
619 //no misalignment mode set
620 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
621 }
622
623 else if (m_MisalignmentMode==1) {
624 //shift whole detector
625 HepGeom::Vector3D<double> shift(ScaleFactor*m_Misalign_x, ScaleFactor*m_Misalign_y, ScaleFactor*m_Misalign_z);
626
627 CLHEP::HepRotation rot;
628 rot = CLHEP::HepRotationX(ScaleFactor*m_Misalign_alpha) * CLHEP::HepRotationY(ScaleFactor*m_Misalign_beta) * CLHEP::HepRotationZ(ScaleFactor*m_Misalign_gamma);
629
630 if (ScaleFactor == 0.0) {
631 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
632 } else {
633 parameterizedTrafo = HepGeom::Transform3D(rot, shift);
634 }
635
636 }
637
638 else if (m_MisalignmentMode == 2) {
639
640 // randomly misalign modules at L3
647 Rndm::Numbers RandMisX(randsvc, Rndm::Gauss(m_Misalign_x,m_RndmMisalignWidth_x*ScaleFactor));
648 Rndm::Numbers RandMisY(randsvc, Rndm::Gauss(m_Misalign_y,m_RndmMisalignWidth_y*ScaleFactor));
649 Rndm::Numbers RandMisZ(randsvc, Rndm::Gauss(m_Misalign_z,m_RndmMisalignWidth_z*ScaleFactor));
650 Rndm::Numbers RandMisalpha(randsvc, Rndm::Gauss(m_Misalign_alpha,m_RndmMisalignWidth_alpha*ScaleFactor));
651 Rndm::Numbers RandMisbeta(randsvc, Rndm::Gauss(m_Misalign_beta,m_RndmMisalignWidth_beta*ScaleFactor));
652 Rndm::Numbers RandMisgamma(randsvc, Rndm::Gauss(m_Misalign_gamma,m_RndmMisalignWidth_gamma*ScaleFactor));
653
654 double randMisX = RandMisX(); //assign to variables to allow the values to be queried
655 double randMisY = RandMisY();
656 double randMisZ = RandMisZ();
657
658 double randMisaplha = RandMisalpha();
659 double randMisbeta = RandMisbeta();
660 double randMisgamma = RandMisgamma();
661
662 CLHEP::HepRotation rot;
663 HepGeom::Vector3D<double> shift;
664
665
666 if (ScaleFactor == 0.0) {
667 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
668 } else {
669 shift = HepGeom::Vector3D<double>(randMisX, randMisY, randMisZ);
670 rot = CLHEP::HepRotationX(randMisaplha) * CLHEP::HepRotationY(randMisbeta) * CLHEP::HepRotationZ(randMisgamma);
671 parameterizedTrafo = HepGeom::Transform3D(rot, shift);}
672
673 }
674
675 else if (m_MisalignmentMode==3) {
676 //shift whole detector
677 double deltaX;
678 if ( m_idHelper->is_pixel(ModuleID) && m_pixelIdHelper->is_blayer(ModuleID) ) {
679 //function is parameterized in global z
681
682 } else {
683 //IBL-stave temperature distortion not applied to anything but IBL
684 deltaX = 0.;
685 ATH_MSG_DEBUG( "will not move this module for IBL temp distortion " );
686 }
687
688 ATH_MSG_DEBUG( "deltaX for this module: " << deltaX/CLHEP::micrometer << " um" );
689 parameterizedTrafo = HepGeom::Translate3D(deltaX,0,0); // translation in x direction
690 }
691
692 else if (m_MisalignmentMode == 7) {
693
694
695 std::string module_str = m_idHelper->show_to_string(ModuleID, nullptr, '/');
696
697 if (module_str.substr(0, m_index.size()) == m_index) {
698
699 // Handle translation
700 HepGeom::Vector3D<double> shift(0, 0, 0);
701 if (!m_local_translation.empty()) {
702 shift = HepGeom::Vector3D<double>(m_local_translation[0], m_local_translation[1], m_local_translation[2]);
703 }
704
705 // Handle rotation
706 CLHEP::HepRotation rot = CLHEP::HepRotationX(0) * CLHEP::HepRotationY(0) * CLHEP::HepRotationZ(0);
707 if (!m_local_rotation.empty()) {
708 rot = CLHEP::HepRotationX(m_local_rotation[0]) * CLHEP::HepRotationY(m_local_rotation[1]) * CLHEP::HepRotationZ(m_local_rotation[2]);
709 }
710
711 // Assign transformation
712 parameterizedTrafo = HepGeom::Transform3D(rot, shift);
713 }
714 }
715
716
717 else { // systematic misalignments
718 if (m_MisalignmentMode/10==1) {
719 //radial misalignments
720 double deltaR;
721 if (m_MisalignmentMode==11) {
722 //R deltaR = radial expansion
723 if (m_idHelper->is_trt(ModuleID) && abs(m_trtIdHelper->barrel_ec(ModuleID))==2) {
724 //radial mode cannot handle TRT endcap, sorry
725 deltaR = 0.;
726 ATH_MSG_DEBUG( "will not move TRT endcap for radial distortion " );
727 } else {
728 //deltaR = 0.5 * cos ( 2*phi ) * r/maxRadius * maxDeltaR;
729 deltaR = r/maxRadius * maxDeltaR; //scale linearly in r
730 }
731 } else if (m_MisalignmentMode==12) {
732 //Phi deltaR = elliptical (egg-shape)
733 if (m_idHelper->is_trt(ModuleID) && abs(m_trtIdHelper->barrel_ec(ModuleID))==2) {
734 //elliptical mode cannot handle TRT endcap, sorry
735 deltaR = 0.;
736 ATH_MSG_DEBUG( "will not move TRT endcap for elliptical distortion " );
737 } else {
738 // deltaR = 0.5 * cos ( 2*phi ) * r/maxRadius * maxDeltaR;
739 deltaR = cos ( 2*phi ) * r/maxRadius * maxDeltaR;
740 }
741 } else if (m_MisalignmentMode==13) {
742 //Z deltaR = funnel
743 if (m_idHelper->is_trt(ModuleID) && abs(m_trtIdHelper->barrel_ec(ModuleID))==2) {
744 //funnel mode cannot handle TRT endcap, sorry
745 deltaR = 0.;
746 ATH_MSG_DEBUG( "will not move TRT endcap for funnel distortion " );
747 } else {
748 //deltaR = z/maxLength * maxDeltaR; // linearly in z
749 deltaR = 2. * z/maxLength * maxDeltaR; // linearly in z
750 }
751 } else {
752 ATH_MSG_DEBUG( "Wrong misalignment mode entered, doing nothing." );
753 deltaR=0;
754 }
755
756 ATH_MSG_DEBUG( "deltaR for this module: " << deltaR / CLHEP::micrometer << " um" );
757 parameterizedTrafo = HepGeom::Translate3D(deltaR*cos(phi),deltaR * sin(phi),0.); // translation along R vector
758 }
759
760 else if (m_MisalignmentMode/10==2) {
761 //azimuthal misalignments
762 double deltaPhi;
763 if (m_MisalignmentMode==21) {
764
765 deltaPhi = r/maxRadius * maxAngle + minRadius/r * maxAngleInner; //linearly + reciprocal term in r
766 } else if (m_MisalignmentMode==22) {
767 //Phi deltaPhi = clamshell
768 // deltaPhi = std::abs( sin ( phi )) * maxAngle;
769 if (m_idHelper->is_trt(ModuleID) && abs(m_trtIdHelper->barrel_ec(ModuleID))==2) {
770 //clamshell mode cannot handle TRT endcap, sorry
771 deltaPhi = 0.;
772 ATH_MSG_DEBUG( "will not move TRT endcap for clamshell distortion " );
773 } else {
774 // deltaPhi = 0.5 * cos ( 2*phi ) * maxAngle;
775 deltaPhi = cos ( 2*phi ) * maxAngle;
776 }
777 } else if (m_MisalignmentMode==23) {
778 //Z deltaPhi = Twist
779 deltaPhi = 2*z/maxLength * maxAngle;
780 //deltaPhi = z/maxLength * maxAngle;
781 } else {
782 ATH_MSG_WARNING( "Wrong misalignment mode entered, doing nothing." );
783 deltaPhi=0;
784 }
785
786 ATH_MSG_DEBUG( "deltaPhi for this module: " << deltaPhi/CLHEP::mrad << " mrad" );
787 parameterizedTrafo = HepGeom::RotateZ3D(deltaPhi); // rotation around z axis => in phi
788 }
789
790 else if (m_MisalignmentMode/10==3) {
791 //z misalignments
792 double deltaZ;
793 if (m_MisalignmentMode==31) {
794 //R deltaZ = Telescope
795 deltaZ = r/maxRadius * maxDeltaZ; //scale linearly in r
796 } else if (m_MisalignmentMode==32) {
797
798 if (m_idHelper->is_trt(ModuleID) && abs(m_trtIdHelper->barrel_ec(ModuleID))==2) {
799 //clamshell mode cannot handle TRT endcap, sorry
800 deltaZ = 0.;
801 ATH_MSG_DEBUG( "will not move TRT endcap for skew distortion " );
802 } else {
803
804 deltaZ = cos ( 2*phi ) * maxDeltaZ;
805 }
806 } else if (m_MisalignmentMode==33) {
807 //Z deltaZ = Z expansion
808 // deltaZ = z/maxLength * maxDeltaZ;
809 deltaZ = 2. * z/maxLength * maxDeltaZ;
810 } else {
811 ATH_MSG_WARNING( "Wrong misalignment mode entered, doing nothing." );
812 deltaZ=0;
813 }
814
815 ATH_MSG_DEBUG( "deltaZ for this module: " << deltaZ/CLHEP::micrometer << " um" );
816 parameterizedTrafo = HepGeom::Translate3D(0,0,deltaZ); // translation in z direction
817 }
818
819 else {
820 //no or wrong misalignment selected
821 ATH_MSG_WARNING( "Wrong misalignment mode entered, doing nothing." );
822
823 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
824 }
825 } //end of misalignment
826
827 if ( m_MisalignmentMode==21 && m_idHelper->is_trt(ModuleID) && m_trtIdHelper->is_barrel(ModuleID) ) {
828 //curl for TRT barrel
829 ATH_MSG_DEBUG( "additional rotation for TRT barrel module!" );
830 HepGeom::Transform3D realLocalToGlobalTRT = HepGeom::Translate3D(center.x(),center.y(),center.z());
831 //rotate a TRT barrel module by the same angle again, but around its local z axis
832 //this is an approximation to accomodate the impossible curling of TRT segments
833 alignmentTrafo = parameterizedTrafo * realLocalToGlobalTRT * parameterizedTrafo * realLocalToGlobalTRT.inverse();
834 } else if (m_MisalignmentMode==23 && m_idHelper->is_trt(ModuleID) && m_trtIdHelper->is_barrel(ModuleID) ) {
835 //do the twist! (for TRT barrel)
836 HepGeom::Transform3D realLocalToGlobalTRT = HepGeom::Translate3D(center.x(),center.y(),center.z());
837 double deltaAlpha = (-2.) * r * maxAngle/maxLength;
838 ATH_MSG_DEBUG( "TRT barrel module alpha for twist: " << deltaAlpha/CLHEP::mrad << " mrad" );
839
840 CLHEP::HepRotation twistForTRTRotation(HepGeom::Vector3D<double>(center.x(),center.y(),center.z()), deltaAlpha );
841 HepGeom::Transform3D twistForTRT= HepGeom::Transform3D(twistForTRTRotation,HepGeom::Vector3D<double>(0.,0.,0.));
842 // HepGeom::Transform3D twistForTRTRotation = HepGeom::RotateZ3D( r * maxAngle/maxLength );
843
844 alignmentTrafo = realLocalToGlobalTRT * twistForTRT * realLocalToGlobalTRT.inverse();
845 } else if (m_MisalignmentMode==13 && m_idHelper->is_trt(ModuleID) && m_trtIdHelper->is_barrel(ModuleID) ) {
846 // funneling for TRT barrel
847 HepGeom::Transform3D realLocalToGlobalTRT = HepGeom::Translate3D(center.x(),center.y(),center.z());
848 double deltaAlpha = (-2.) * maxDeltaR/maxLength;
849 //double deltaAlpha = maxDeltaR/maxLength;
850 ATH_MSG_DEBUG( "TRT barrel module alpha for funnel: " << deltaAlpha/CLHEP::mrad << " mrad" );
851
852 HepGeom::Vector3D<double> normalVector(center.x(),center.y(),center.z());
853 HepGeom::Vector3D<double> beamVector(0.,0.,1.);
854 HepGeom::Vector3D<double> rotationAxis = normalVector.cross(beamVector);
855 CLHEP::HepRotation twistForTRTRotation(rotationAxis, deltaAlpha );
856 HepGeom::Transform3D twistForTRT= HepGeom::Transform3D(twistForTRTRotation,HepGeom::Vector3D<double>(0.,0.,0.));
857
858 alignmentTrafo = realLocalToGlobalTRT * twistForTRT * realLocalToGlobalTRT.inverse();
859
860
861
862 } else if (m_MisalignmentMode==2 || m_MisalignmentMode==3 || m_MisalignmentMode==7) //random misalignment in local frame
863 {
864 alignmentTrafo = parameterizedTrafo;
865 }
866 else {
867 // final transformation executed in global coordinates, converted to local coordinates
868 alignmentTrafo = localToGlobal.inverse() * parameterizedTrafo * localToGlobal;
869 }
870
871 if (msgLvl(MSG::INFO)) {
872 msg() << "Align Transformation x = (" << alignmentTrafo.getTranslation().x() / CLHEP::micrometer << " um)" << endmsg;
873 msg() << "Align Transformation y = (" << alignmentTrafo.getTranslation().y() / CLHEP::micrometer << " um)" << endmsg;
874 msg() << "Align Transformation z = (" << alignmentTrafo.getTranslation().z() / CLHEP::micrometer << " um)" << endmsg;
875 msg() << "Align Transformation x phi = (" << alignmentTrafo.getRotation().phiX() / CLHEP::deg << ")" << endmsg;
876 msg() << "Align Transformation x Theta = (" << alignmentTrafo.getRotation().thetaX() / CLHEP::deg << ")" << endmsg;
877 msg() << "Align Transformation y phi = (" << alignmentTrafo.getRotation().phiY() / CLHEP::deg << ")" << endmsg;
878 msg() << "Align Transformation y Theta = (" << alignmentTrafo.getRotation().thetaY() / CLHEP::deg << ")" << endmsg;
879 msg() << "Align Transformation z phi = (" << alignmentTrafo.getRotation().phiZ() / CLHEP::deg << ")" << endmsg;
880 msg() << "Align Transformation z Theta = (" << alignmentTrafo.getRotation().thetaZ() / CLHEP::deg << ")" << endmsg;
881 }
882
883 // suppress tiny translations that occur due to trafo.inverse*trafo numerics
884 if ( std::abs(alignmentTrafo.getTranslation().x()) < 1e-10) {
885 HepGeom::Vector3D<double>
886 zeroSuppressedTranslation(0,alignmentTrafo.getTranslation().y(),alignmentTrafo.
887 getTranslation().z());
888 alignmentTrafo =
889 HepGeom::Transform3D(alignmentTrafo.getRotation(),zeroSuppressedTranslation);
890 }
891 if ( std::abs(alignmentTrafo.getTranslation().y()) < 1e-10) {
892 HepGeom::Vector3D<double>
893 zeroSuppressedTranslation(alignmentTrafo.getTranslation().x(),0,alignmentTrafo.
894 getTranslation().z());
895 alignmentTrafo =
896 HepGeom::Transform3D(alignmentTrafo.getRotation(),zeroSuppressedTranslation);
897 }
898 if ( std::abs(alignmentTrafo.getTranslation().z()) < 1e-10) {
899 HepGeom::Vector3D<double>
900 zeroSuppressedTranslation(alignmentTrafo.getTranslation().x(),alignmentTrafo.getTranslation().y(),0);
901 alignmentTrafo =
902 HepGeom::Transform3D(alignmentTrafo.getRotation(),zeroSuppressedTranslation);
903 }
904 if ( std::abs(alignmentTrafo.getRotation().getDelta()) < 1e-10) {
905 CLHEP::HepRotation zeroSuppressedRotation(alignmentTrafo.getRotation());
906 zeroSuppressedRotation.setDelta(0.);
907 alignmentTrafo =
908 HepGeom::Transform3D(zeroSuppressedRotation,alignmentTrafo.getTranslation());
909 }
910
911
912 Amg::Transform3D alignmentTrafoAmg = Amg::CLHEPTransformToEigen(alignmentTrafo);
913
914 if (m_idHelper->is_sct(ModuleID) || m_idHelper->is_pixel(ModuleID)) {
915 if (m_IDAlignDBTool->tweakTrans(ModuleID,3, alignmentTrafoAmg)) {
916 ATH_MSG_INFO( "Update of alignment constants for module " << m_idHelper->show_to_string(ModuleID,nullptr,'/') << " successful" );
917 } else {
918 ATH_MSG_ERROR( "Update of alignment constants for module " << m_idHelper->show_to_string(ModuleID,nullptr,'/') << " not successful" );
919 }
920 } else if (m_idHelper->is_trt(ModuleID)) {
921 if (!m_trtIdHelper->is_barrel(ModuleID) && m_trtIdHelper->phi_module(ModuleID)!=0) {
922 //don't align - there's no trans in the DB for phi sectors other than 0
923 ATH_MSG_DEBUG( "TRT endcap phi sector " << m_trtIdHelper->phi_module(ModuleID) << " not aligned" );
924 } else {
925 //if (m_trtaligndbservice->tweakTrans(ModuleID,alignmentTrafo).isFailure()) {
926 if (m_trtaligndbservice->tweakAlignTransform(ModuleID,alignmentTrafoAmg,2).isFailure()) {
927 ATH_MSG_ERROR( "Update of alignment constants for module " << m_idHelper->show_to_string(ModuleID,nullptr,'/') << " not successful" );
928 } else {
929 ATH_MSG_INFO( "Update of alignment constants for module " << m_idHelper->show_to_string(ModuleID,nullptr,'/') << " successful" );
930 }
931 }
932 } else {
933 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
934 }
935
936 double alpha, beta, gamma;
937 m_IDAlignDBTool->extractAlphaBetaGamma(alignmentTrafoAmg, alpha, beta, gamma);
938
939 m_AlignResults_x = alignmentTrafo.getTranslation().x();
940 m_AlignResults_y = alignmentTrafo.getTranslation().y();
941 m_AlignResults_z = alignmentTrafo.getTranslation().z();
942 m_AlignResults_alpha = alpha;
943 m_AlignResults_beta = beta;
944 m_AlignResults_gamma = gamma;
945
946
947 HepGeom::Transform3D LocalaGlobal = HepGeom::Transform3D();
948 LocalaGlobal = Amg::EigenTransformToCLHEP(SiModule->moduleTransform());
949 HepGeom::Point3D<double> alignedPosLocal(m_AlignResults_x,m_AlignResults_y,m_AlignResults_z);
950
951
952
953
954 m_Initial_center_x = center.x() ;
955 m_Initial_center_y = center.y() ;
956 m_Initial_center_z = center.z() ;
957
958 HepGeom::Point3D<double> alignedPosGlobal = LocalaGlobal * alignedPosLocal;
959
960 // Global Misalignment HERE
961 if (m_idHelper->is_sct(ModuleID)) {
962 // non-zero local center position gives additional radial shift of SCT endcap
963 const InDetDD::StripStereoAnnulusDesign *p_design_check = dynamic_cast<const InDetDD::StripStereoAnnulusDesign*>(&(SiModule->design()));
964 if (p_design_check){
965 Amg::Vector3D SCT_Center = p_design_check->sensorCenter();
966 double radialShift_x = SCT_Center[0]; // in sensor frame, x direction
967 double radialShift_y = SCT_Center[1]; // in sensor frame, y direction
968 HepGeom::Transform3D radial_shift = HepGeom::Translate3D(radialShift_x,radialShift_y,0); // the additional radial shift applied as translation
969 HepGeom::Transform3D LocalaaGlobal = LocalaGlobal * radial_shift; // apply additional radial shift
970 HepGeom::Point3D<double> SCT_endcap_alignedPosGlobal = LocalaaGlobal * alignedPosLocal; // corrected global transformation
971 m_Global_center_x = SCT_endcap_alignedPosGlobal.x();
972 m_Global_center_z = SCT_endcap_alignedPosGlobal.z();
973 m_Global_center_y = SCT_endcap_alignedPosGlobal.y();
974 }
975
976 else { // no additional radial shift for SCT barrel
977 m_Global_center_x = alignedPosGlobal.x();
978 m_Global_center_y = alignedPosGlobal.y();
979 m_Global_center_z = alignedPosGlobal.z();
980
981 }
982
983 }
984
985 else { // no additional radial shift for non-SCT elements
986 m_Global_center_x = alignedPosGlobal.x();
987 m_Global_center_y = alignedPosGlobal.y();
988 m_Global_center_z = alignedPosGlobal.z();
989 }
990
991
992 if (m_idHelper->is_sct(ModuleID)) {
997 m_AlignResults_Identifier_Phi = m_sctIdHelper->phi_module(ModuleID);
998 m_AlignResults_Identifier_Eta = m_sctIdHelper->eta_module(ModuleID);
999 } else if (m_idHelper->is_pixel(ModuleID)) {
1004 m_AlignResults_Identifier_Phi = m_pixelIdHelper->phi_module(ModuleID);
1005 m_AlignResults_Identifier_Eta = m_pixelIdHelper->eta_module(ModuleID);
1006 } else if (m_idHelper->is_trt(ModuleID)) {
1010 m_AlignResults_Identifier_LayerDisc = m_trtIdHelper->layer_or_wheel(ModuleID);
1011 m_AlignResults_Identifier_Phi = m_trtIdHelper->phi_module(ModuleID);
1012 m_AlignResults_Identifier_Eta = m_trtIdHelper->straw_layer(ModuleID);
1013
1014 } else {
1015 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
1016 }
1017
1018 // Write out AlignResults ntuple
1019 if (StatusCode::SUCCESS!=ntupleSvc()->writeRecord("NTUPLES/CREATEMISALIGN/InitialAlignment")) {
1020 ATH_MSG_ERROR( "Could not write InitialAlignment ntuple." );
1021 }
1022
1023 } // end of module loop
1024
1025 // i = 0;
1026
1027 //m_IDAlignDBTool->printDB(2);
1028 if(m_doPix || m_doStrip){
1029 if (StatusCode::SUCCESS!=m_IDAlignDBTool->outputObjs()) {
1030 ATH_MSG_ERROR( "Writing of AlignableTransforms failed" );
1031 } else {
1032 ATH_MSG_INFO( "AlignableTransforms were written" );
1033 ATH_MSG_INFO( "Writing database to textfile" );
1034 m_IDAlignDBTool->writeFile(false,m_asciiFileNameBase+"_Si.txt");
1035 ATH_MSG_INFO( "Writing IoV information to mysql file" );
1037 }
1038 }
1039
1040 if(m_doTRT){
1041 if (StatusCode::SUCCESS!=m_trtaligndbservice->streamOutAlignObjects()) {
1042 ATH_MSG_ERROR( "Write of AlignableTransforms (TRT) failed" );
1043 } else {
1044 ATH_MSG_INFO( "AlignableTransforms for TRT were written" );
1045 ATH_MSG_INFO( "Writing TRT database to textfile" );
1046 if ( StatusCode::SUCCESS != m_trtaligndbservice->writeAlignTextFile(m_asciiFileNameBase+"_TRT.txt") ) {
1047 ATH_MSG_ERROR( "Failed to write AlignableTransforms (TRT) to txt file " << m_asciiFileNameBase+"_TRT.txt" );
1048 }
1049 ATH_MSG_INFO( "Writing IoV information for TRT to mysql file" );
1050 if ( StatusCode::SUCCESS
1052 ATH_MSG_ERROR( "Write of AIoV information (TRT) to mysql failed (tag=" << m_SQLiteTag << "_TRT)");
1053 }
1054 }
1055 }
1056
1057 return StatusCode::SUCCESS;
1058
1059 }
1060
1061 //__________________________________________________________________________
1062 const HepGeom::Transform3D CreateMisalignAlg::BuildAlignTransform(const CLHEP::HepVector & AlignParams)
1063 {
1064 HepGeom::Vector3D<double> AlignShift(AlignParams[0],AlignParams[1],AlignParams[2]);
1065 CLHEP::HepRotation AlignRot;
1066
1067 AlignRot = CLHEP::HepRotationX(AlignParams[3]) * CLHEP::HepRotationY(AlignParams[4]) * CLHEP::HepRotationZ(AlignParams[5]);
1068
1069 HepGeom::Transform3D AlignTransform = HepGeom::Transform3D(AlignRot,AlignShift);
1070 return AlignTransform;
1071 }
1072
1073 //__________________________________________________________________________
1075 {
1076 // msg(MSG::DEBUG) << "in CreateMisalignAlg::reduceTRTID" << endmsg;
1077 ATH_MSG_DEBUG( "reduceTRTID got Id " << m_idHelper->show_to_string(id,nullptr,'/'));
1078
1079 int barrel_ec= m_trtIdHelper->barrel_ec(id);
1080 // attention: TRT DB only has one alignment correction per barrel module (+1/-1) pair
1081 // which is stored in -1 identifier
1082 if (barrel_ec==1) barrel_ec=-1; //only regard -1 barrel modules, +1 modules will belong to them
1083
1084 //if (abs(barrel_ec)==2) phi_module=0;
1085 // only regard phi sector 0, the only one having an alignmentTrafo
1086 //does not work, since the center-of-mass of all phi sectors is on the beamline,so
1087 // transformations would become zero -> this has to be handled later
1088 int phi_module=m_trtIdHelper->phi_module(id);
1089
1090 int layer_or_wheel=m_trtIdHelper->layer_or_wheel(id);
1091
1092 int strawlayer=0;
1093 if (!m_trtIdHelper->is_barrel(id)) {
1094 strawlayer = m_trtIdHelper->straw_layer(id) / 4 * 4;
1095 // only strawlayers 0,4,8,12 are fed into DB for endcap
1096 }
1097
1098 // if (msgLvl(MSG::DEBUG)) msg() << " and returns Id " << m_idHelper->show_to_string(m_trtIdHelper->module_id(barrel_ec,phi_module,layer_or_wheel),0,'/') << endmsg;
1099 ATH_MSG_DEBUG( " and returns Id " << m_idHelper->show_to_string(m_trtIdHelper->layer_id(barrel_ec,phi_module,layer_or_wheel,strawlayer),nullptr,'/'));
1100 // return m_trtIdHelper->module_id(barrel_ec,phi_module,layer_or_wheel);
1101 return m_trtIdHelper->layer_id(barrel_ec,phi_module,layer_or_wheel,strawlayer);
1102 }
1103
1104 //__________________________________________________________________________
1106 {
1107 Identifier id= m_trtIdHelper->module_id(hash);
1108 return reduceTRTID(id);
1109 }
1110
1111 //__________________________________________________________________________
1113 {
1114 // IBL staves are straight at a set point of 15 degrees.
1115 // Get set point value to use for magnitude parameter from temp_shift starting at 15 degrees
1116 double T = 15 + temp_shift;
1117 return 1.53e-12 - 1.02e-13*T;
1118 }
1119
1120 //__________________________________________________________________________
1121 double CreateMisalignAlg::getBowingTx(double p1, double z)
1122 {
1123 // Bowing fit function has the following form
1124 // [0]-[1]*(x+[2]) * (4.0*[2]*(x+[2])**2 - (x+[2])**3 - (2.0*[2])**3)
1125 // param 0 : is the baseline shift (fixed at 0 for MC)
1126 // param 1 : is the magnitude fit param (temp dependent input param)
1127 // param 2 : is the stave fix pointat both ends (fixed at 366.5)
1128 double p0 = 0;
1129 double p2 = 366.5;
1130 double Tx = p0 - p1*(z+p2) * (4.*p2*pow((z+p2),2) - pow((z+p2),3) - pow((2.*p2),3));
1131 return Tx;
1132 }
1133
1134} // end of namespace bracket
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar deltaR(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
#define endmsg
#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_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...
Validity Range object.
abstract interface to Service to manage TRT alignment conditions
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
INTupleSvc * ntupleSvc()
This is an Identifier helper class for the TRT subdetector.
#define z
constexpr int pow(int base, int exp) noexcept
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
static constexpr uint32_t MAXRUN
Definition IOVTime.h:48
static constexpr uint32_t MINEVENT
Definition IOVTime.h:50
static constexpr uint32_t MAXEVENT
Definition IOVTime.h:51
static constexpr uint32_t MINRUN
Definition IOVTime.h:44
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
std::vector< double > m_rotation
Flag which turns on misalignment with rotation.
Gaudi::Property< double > m_RndmMisalignWidth_gamma
std::map< Identifier, HepGeom::Point3D< double > > m_ModuleList
map of all SiIdentifiers to be misaligned and their centerpoints in global coordinates
std::string m_index
Generate misalignment according to module indices.
SG::ReadCondHandleKey< InDetDD::TRT_DetElementContainer > m_trtDetEleCollKey
const HepGeom::Transform3D BuildAlignTransform(const CLHEP::HepVector &)
builds a HepGeom::Transform3D from the 6 Alignment Parameters
double m_IBLBowingTshift
The relative temp shift of set point that intriduces bowing (sign is important)
Gaudi::Property< double > m_RndmMisalignWidth_alpha
NTuple::Item< double > m_AlignResults_z
AP normal to module plane.
NTuple::Item< double > m_Initial_center_x
Initial global center of module.
double getBowingTx(double p1, double z)
bool m_createFreshDB
Flag to call the createDB method of DBTool (to be switched off when adding misalignments to a given g...
NTuple::Item< long > m_AlignResults_Identifier_PixelSCT
ID information for this module.
Gaudi::Property< double > m_Misalign_x
Gaudi::Property< double > m_RndmMisalignWidth_z
NTuple::Item< double > m_Global_center_x
Misaligned global center of module.
std::string m_SQLiteTag
tag name for the ConditionsDB
const Identifier reduceTRTID(Identifier id)
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
Gaudi::Property< double > m_Misalign_z
Gaudi::Property< double > m_RndmMisalignWidth_beta
int m_MisalignmentMode
Flag which Misalignment mode is to be generated.
double getBowingMagParam(double temp_shift)
NTuple::Item< long > m_AlignResults_Identifier_BarrelEC
ID information for this module.
const AtlasDetectorID * m_idHelper
bool m_firstEvent
Flag for Setup of AlignModuleList (1st event)
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
NTuple::Item< double > m_Initial_center_z
Initial global center of module.
NTuple::Item< long > m_AlignResults_Identifier_LayerDisc
ID information for this module.
std::vector< double > m_local_translation
Specify misalignment with translation.
Gaudi::Property< double > m_Misalign_y
NTuple::Item< double > m_AlignResults_x
Alignment parameter sensitive coordinate.
StatusCode finalize()
standard Athena-Algorithm method
NTuple::Item< double > m_Global_center_y
Misaligned global center of module.
StatusCode initialize()
standard Athena-Algorithm method
StatusCode execute()
standard Athena-Algorithm method
NTuple::Item< double > m_Initial_center_y
Initial global center of module.
double m_Misalign_maxShift_Inner
Maximum shift of the Pixel B-layer in curl (d0 bias!)
NTuple::Item< long > m_AlignResults_Identifier_Eta
ID information for this module.
NTuple::Item< double > m_AlignResults_alpha
AP rotation around x-axis.
NTuple::Item< long > m_AlignResults_Identifier_Phi
ID information for this module.
Gaudi::Property< double > m_RndmMisalignWidth_y
Gaudi::Property< double > m_RndmMisalignWidth_x
NTuple::Item< long > m_AlignResults_Identifier_ID
ID information for this module.
Gaudi::Property< double > m_Misalign_beta
std::vector< double > m_local_rotation
Specify misalignment with rotation.
std::vector< double > m_translation
Flag which turns on misalignment with translation.
NTuple::Item< double > m_AlignResults_y
AP not-so-sensitive coordinate.
StatusCode GenerateMisaligment()
the main function which calculates and applies a transformation to each detector element
ServiceHandle< ITRT_AlignDbSvc > m_trtaligndbservice
NTuple::Item< double > m_Global_center_z
Misaligned global center of module.
NTuple::Item< double > m_AlignResults_gamma
AP rotation around z-axis.
Gaudi::Property< double > m_Misalign_gamma
std::string m_asciiFileNameBase
filename basis for ASCII files with alignment constants
ToolHandle< IInDetAlignDBTool > m_IDAlignDBTool
CreateMisalignAlg(const std::string &name, ISvcLocator *pSvcLocator)
Standard Athena-Algorithm Constructor.
double m_Misalign_maxShift
Maximum shift for global modes.
NTuple::Item< double > m_AlignResults_beta
AP rotation aorund y-axis.
Gaudi::Property< double > m_Misalign_alpha
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
const Amg::Transform3D & moduleTransform() const
Module to global frame transform.
virtual Amg::Vector3D sensorCenter() const override
Return the centre of a sensor in the local reference frame.
Virtual base class of TRT readout elements.
Class to hold collection of TRT detector elements.
int r
Definition globals.cxx:22
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