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
49
50
51namespace{
52 std::string commonAlignmentOutput(const HepGeom::Transform3D & initialAlignment){
53 std::ostringstream os;
54 os << "\nAlignment x = (" << initialAlignment.getTranslation().x() / CLHEP::micrometer << ") micron\n";
55 os << "Alignment y = (" << initialAlignment.getTranslation().y() / CLHEP::micrometer << ") micron\n";
56 os << "Alignment z = (" << initialAlignment.getTranslation().z() / CLHEP::micrometer << ") micron\n";
57 os << "Alignment x phi = (" << initialAlignment.getRotation().phiX() / CLHEP::deg << ") degree\n";
58 os << "Alignment x Theta = (" << initialAlignment.getRotation().thetaX() / CLHEP::deg << ") degree\n";
59 os << "Alignment y phi = (" << initialAlignment.getRotation().phiY() / CLHEP::deg << ") degree\n";
60 os << "Alignment y Theta = (" << initialAlignment.getRotation().thetaY() / CLHEP::deg << ") degree\n";
61 os << "Alignment z phi = (" << initialAlignment.getRotation().phiZ() / CLHEP::deg << ") degree\n";
62 os << "Alignment z Theta = (" << initialAlignment.getRotation().thetaZ() / CLHEP::deg << ") degree\n";
63 return os.str();
64 }
65}
66
68{
69
70 // Constructor
71 CreateMisalignAlg::CreateMisalignAlg(const std::string& name, ISvcLocator* pSvcLocator):
72 AthAlgorithm(name,pSvcLocator),
73 m_idHelper(nullptr),
74 m_pixelIdHelper(nullptr),
75 m_sctIdHelper(nullptr),
76 m_trtIdHelper(nullptr),
77 m_IDAlignDBTool("InDetAlignDBTool",this),
78 m_trtaligndbservice("TRT_AlignDbSvc",name),
79 m_asciiFileNameBase("MisalignmentSet"),
80 m_SQLiteTag("test_tag"),
81 m_firstEvent(true),
82 m_createFreshDB(true),
84 m_nEvents(0),
85 m_translation{0.1, 0.1, 0.1},
86 m_rotation{0.1, 0.1, 0.1},
87 m_local_translation{0., 0., 0.},
88 m_local_rotation{0., 0., 0.},
89 m_index(""),
91 m_Misalign_maxShift_Inner(50*CLHEP::micrometer),
104 m_doPix(true),
105 m_doStrip(true),
106 m_doTRT(true)
107 {
108 declareProperty("ASCIIFilenameBase" , m_asciiFileNameBase);
109 declareProperty("SQLiteTag" , m_SQLiteTag);
110 declareProperty("MisalignMode" , m_MisalignmentMode);
111 declareProperty("Translation_Scale" , m_translation);
112 declareProperty("Rotation_Scale" , m_rotation);
113 declareProperty("Local_Translation" , m_local_translation);
114 declareProperty("Local_Rotation" , m_local_rotation);
115 declareProperty("Index" , m_index);
118 declareProperty("CreateFreshDB" , m_createFreshDB);
119 declareProperty("IDAlignDBTool" , m_IDAlignDBTool);
120 declareProperty("TRTAlignDBService" , m_trtaligndbservice);
121 declareProperty("ScalePixelIBL" , m_ScalePixelIBL);
122 declareProperty("ScalePixelDBM" , m_ScalePixelDBM);
123 declareProperty("IBLBowingTshift" , m_IBLBowingTshift);
124 declareProperty("ScalePixelBarrel" , m_ScalePixelBarrel);
125 declareProperty("ScalePixelEndcap" , m_ScalePixelEndcap);
126 declareProperty("ScaleSCTBarrel" , m_ScaleSCTBarrel);
127 declareProperty("ScaleSCTEndcap" , m_ScaleSCTEndcap);
128 declareProperty("ScaleTRTBarrel" , m_ScaleTRTBarrel);
129 declareProperty("ScaleTRTEndcap" , m_ScaleTRTEndcap);
130 }
131
132 //__________________________________________________________________________
133 // Destructor
135 {
136 ATH_MSG_DEBUG( "CreateMisalignAlg destructor called" );
137 }
138
139 //__________________________________________________________________________
141 {
142 ATH_MSG_DEBUG("CreateMisalignAlg initialize()");
143 if(m_pixelDetEleCollKey.empty()) {m_doPix=false;ATH_MSG_INFO("Not creating misalignment for Pixel");}
144 if(m_SCTDetEleCollKey.empty()) {m_doStrip=false;ATH_MSG_INFO("Not creating misalignment for Strip/SCT");}
145 if(m_trtDetEleCollKey.empty()) {m_doTRT=false;ATH_MSG_INFO("Not creating misalignment for TRT");}
146
150
151 if (m_doPix || m_doStrip) ATH_CHECK(m_IDAlignDBTool.retrieve());
152 if(m_doTRT) ATH_CHECK(m_trtaligndbservice.retrieve());
153 //ID helpers
154 // Pixel
155 if(m_doPix){
156 ATH_CHECK(detStore()->retrieve(m_pixelIdHelper, "PixelID"));
157 }
158 // SCT
159 if(m_doStrip){
160 ATH_CHECK(detStore()->retrieve(m_sctIdHelper, "SCT_ID"));
161 }
162 // TRT
163 if(m_doTRT){
164 ATH_CHECK(detStore()->retrieve(m_trtIdHelper, "TRT_ID"));
165 }
166 ATH_CHECK(detStore()->retrieve(m_idHelper, "AtlasID"));
167
168 // Retrieve the Histo Service
169 SmartIF<ITHistSvc> hist_svc{Gaudi::svcLocator()->service("THistSvc")};
170 ATH_CHECK(hist_svc.isValid());
171 //Registering TTree for Visualization Lookup
172 m_VisualizationLookupTree = new TTree("IdentifierTree", "Visualization Identifier Lookup Tree");
173 ATH_CHECK(hist_svc->regTree("/IDENTIFIERTREE/IdentifierTree", m_VisualizationLookupTree));
174 m_VisualizationLookupTree->Branch ("AthenaHashedID", &m_AthenaHashedID, "AthenaID/i");
175 m_VisualizationLookupTree->Branch ("HumanReadableID", &m_HumanReadableID, "HumanID/I");
176
177 // initialize generated Initial Alignment NTuple
178 NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/CREATEMISALIGN");
179
180 NTuplePtr nt(ntupleSvc(), "/NTUPLES/CREATEMISALIGN/InitialAlignment");
181 if ( !nt ) { // Check if already booked
182 nt = ntupleSvc()->book("/NTUPLES/CREATEMISALIGN/InitialAlignment", CLID_ColumnWiseTuple, "InitialAlignment");
183 if ( nt ) {
184 ATH_MSG_INFO( "InitialAlignment ntuple booked." );
185 ATH_CHECK( nt->addItem("x" ,m_AlignResults_x) );
186 ATH_CHECK( nt->addItem("y" ,m_AlignResults_y) );
187 ATH_CHECK( nt->addItem("z" ,m_AlignResults_z) );
188 ATH_CHECK( nt->addItem("alpha" ,m_AlignResults_alpha) );
189 ATH_CHECK( nt->addItem("beta" ,m_AlignResults_beta) );
190 ATH_CHECK( nt->addItem("gamma" ,m_AlignResults_gamma) );
191 ATH_CHECK( nt->addItem("ID" ,m_AlignResults_Identifier_ID) );
192 ATH_CHECK( nt->addItem("PixelSCT" ,m_AlignResults_Identifier_PixelSCT) );
193 ATH_CHECK( nt->addItem("BarrelEC" ,m_AlignResults_Identifier_BarrelEC) );
194 ATH_CHECK( nt->addItem("LayerDisc" ,m_AlignResults_Identifier_LayerDisc) );
195 ATH_CHECK( nt->addItem("Phi" ,m_AlignResults_Identifier_Phi) );
196 ATH_CHECK( nt->addItem("Eta" ,m_AlignResults_Identifier_Eta) );
197 ATH_CHECK( nt->addItem("center_x" ,m_Initial_center_x ) );
198 ATH_CHECK( nt->addItem("center_y" ,m_Initial_center_y ) );
199 ATH_CHECK( nt->addItem("center_z" ,m_Initial_center_z ) );
200 ATH_CHECK( nt->addItem("misaligned_global_x" ,m_Global_center_x ) );
201 ATH_CHECK( nt->addItem("misaligned_global_y" ,m_Global_center_y ) );
202 ATH_CHECK( nt->addItem("misaligned_global_z" ,m_Global_center_z ) );
203 } else { // did not manage to book the N tuple....
204 msg(MSG::ERROR) << "Failed to book InitialAlignment ntuple." << endmsg;
205 }
206 }
207
208 if (m_MisalignmentMode) {
209 ATH_MSG_INFO( "Misalignment mode chosen: " << m_MisalignmentMode );
210 if (m_MisalignmentMode == 1) {
211 ATH_MSG_INFO( "MisalignmentX : " << m_Misalign_x / CLHEP::micrometer << " micrometer" );
212 ATH_MSG_INFO( "MisalignmentY : " << m_Misalign_y / CLHEP::micrometer << " micrometer" );
213 ATH_MSG_INFO( "MisalignmentZ : " << m_Misalign_z / CLHEP::micrometer << " micrometer" );
214 ATH_MSG_INFO( "MisalignmentAlpha : " << m_Misalign_alpha / CLHEP::mrad << " mrad" );
215 ATH_MSG_INFO( "MisalignmentBeta : " << m_Misalign_beta / CLHEP::mrad << " mrad" );
216 ATH_MSG_INFO( "MisalignmentGamma : " << m_Misalign_gamma / CLHEP::mrad << " mrad" );
217 } else {
218 ATH_MSG_INFO( "with maximum shift of " << m_Misalign_maxShift / CLHEP::micrometer << " micrometer" );
219 }
220 } else {
221 ATH_MSG_INFO( "Dry run, no misalignment will be generated." );
222 }
223
224 return StatusCode::SUCCESS;
225 }
226
227 //__________________________________________________________________________
229 {
230 ATH_MSG_DEBUG( "AlignAlg execute()" );
231 ++m_nEvents;
232
233 if (m_firstEvent) {
234 int nSCT = 0;
235 int nPixel = 0;
236 int nTRT = 0;
237
238 if (m_createFreshDB) {
239 m_IDAlignDBTool->createDB();
240 //m_trtaligndbservice->createAlignObjects(); //create DB for TRT? should be ok... //TODO
241 }
242
246
247 ATH_MSG_INFO( "Back from AlignModuleObject Setup. " );
248 ATH_MSG_INFO( nPixel << " Pixel modules found." );
249 ATH_MSG_INFO( nSCT << " SCT modules found," );
250 ATH_MSG_INFO( nTRT << " TRT modules found." );
251
252 ATH_MSG_INFO( m_ModuleList.size() << " entries in identifier list" );
253
254 if (StatusCode::SUCCESS!=GenerateMisaligment()) {
255 ATH_MSG_ERROR( "GenerateMisalignment failed!" );
256 return StatusCode::FAILURE;
257 };
258
259 m_firstEvent = false;
260 }
261
262 return StatusCode::SUCCESS;
263 }
264
265 //__________________________________________________________________________
267 {
268 ATH_MSG_DEBUG("CreateMisalignAlg finalize()" );
269
270 m_ModuleList.clear();
271
272 return StatusCode::SUCCESS;
273 }
274
275 //__________________________________________________________________________
277 {
278 // SiDetectorElementCollection for SCT
280 const InDetDD::SiDetectorElementCollection* elements(*sctDetEleHandle);
281 if (not sctDetEleHandle.isValid() or elements==nullptr) {
282 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " is not available.");
283 return;
284 }
285 for (const InDetDD::SiDetectorElement *element: *elements) {
286 const Identifier SCT_ModuleID = m_sctIdHelper->module_id(element->identify()); //from wafer id to module id
287 const IdentifierHash SCT_ModuleHash = m_sctIdHelper->wafer_hash(SCT_ModuleID);
288
289 if (m_ModuleList.find(SCT_ModuleID) == m_ModuleList.end())
290 {
291 const InDetDD::SiDetectorElement *module = elements->getDetectorElement(SCT_ModuleHash);
292 m_ModuleList[SCT_ModuleID][0] = module->center()[0];
293 m_ModuleList[SCT_ModuleID][1] = module->center()[1];
294 m_ModuleList[SCT_ModuleID][2] = module->center()[2];
295 ++nSCT;
296 ATH_MSG_VERBOSE( "SCT module " << nSCT );
297 }
298
299 if (m_sctIdHelper->side(element->identify()) == 0) { // inner side case
300 // Write out Visualization Lookup Tree
302 m_HumanReadableID = 1000000*2 /*2 = SCT*/
303 + 100000*m_sctIdHelper->layer_disk(SCT_ModuleID)
304 + 1000*(10+m_sctIdHelper->eta_module(SCT_ModuleID))
305 + m_sctIdHelper->phi_module(SCT_ModuleID);
306 if ( m_sctIdHelper->barrel_ec(SCT_ModuleID) != 0 ) {
307 m_HumanReadableID = m_sctIdHelper->barrel_ec(SCT_ModuleID)*(m_HumanReadableID + 10000000);
308 }
309
310 ATH_MSG_VERBOSE( "Human Readable ID: " << m_HumanReadableID );
311
313
314 // Syntax is (ID, Level) where Level is from 1 to 3 (3 is single module level)
315 if (msgLvl(MSG::VERBOSE)) {
316 HepGeom::Transform3D InitialAlignment = Amg::EigenTransformToCLHEP(m_IDAlignDBTool->getTrans(SCT_ModuleID,3));
317 msg() << "Initial Alignment of module " << m_idHelper->show_to_string(SCT_ModuleID,nullptr,'/') << endmsg;
318 msg() << commonAlignmentOutput(InitialAlignment);
319 msg() << endmsg;
320 }
321 } // end inner side case
322 } //end loop over SCT elements
323 }
324
325 //__________________________________________________________________________
327 {
328 // SiDetectorElementCollection for Pixel
330 const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
331 if (not pixelDetEleHandle.isValid() or elements==nullptr) {
332 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
333 return;
334 }
335 for (const InDetDD::SiDetectorElement *element: *elements) {
336 // get the ID
337 const Identifier Pixel_ModuleID = element->identify();
338 const IdentifierHash Pixel_ModuleHash = m_pixelIdHelper->wafer_hash(Pixel_ModuleID);
339 // check the validity
340 if (Pixel_ModuleID.is_valid()) {
341 if (m_ModuleList.find(Pixel_ModuleID) == m_ModuleList.end()) {
342 const InDetDD::SiDetectorElement *module = elements->getDetectorElement(Pixel_ModuleHash);
343 m_ModuleList[Pixel_ModuleID][0] = module->center()[0];
344 m_ModuleList[Pixel_ModuleID][1] = module->center()[1];
345 m_ModuleList[Pixel_ModuleID][2] = module->center()[2];
346
347 ++nPixel;
348 ATH_MSG_VERBOSE( "Pixel module " << nPixel );
349
350 // Write out Visualization Lookup Tree
351 m_AthenaHashedID = Pixel_ModuleID.get_identifier32().get_compact();
352 m_HumanReadableID = 1000000*1 /*1 = Pixel*/
353 + 100000*m_pixelIdHelper->layer_disk(Pixel_ModuleID)
354 + 1000*(10+m_pixelIdHelper->eta_module(Pixel_ModuleID))
355 + m_pixelIdHelper->phi_module(Pixel_ModuleID);
356 if ( m_pixelIdHelper->barrel_ec(Pixel_ModuleID) != 0 ) {
357 m_HumanReadableID = m_pixelIdHelper->barrel_ec(Pixel_ModuleID)*(m_HumanReadableID + 10000000);
358 }
359
360 ATH_MSG_VERBOSE( "Human Readable ID: " << m_HumanReadableID );
361
363
364 if (msgLvl(MSG::VERBOSE)) {
365 HepGeom::Transform3D InitialAlignment = Amg::EigenTransformToCLHEP(m_IDAlignDBTool->getTrans(Pixel_ModuleID,3));
366 msg() << "Initial Alignment of module " << m_idHelper->show_to_string(Pixel_ModuleID,nullptr,'/') << endmsg;
367 msg() << commonAlignmentOutput(InitialAlignment);
368 msg() << endmsg;
369 }
370 }
371 } else {
372 ATH_MSG_INFO( "not a valid PIXEL Module ID (setup)" );
373 }
374 }
375 }
376
377 //__________________________________________________________________________
379 {
380 //TODO: writing into the Identifier tree is undone for TRT (AthenaHashedID and HumanReadableID)
381
382 std::map< Identifier, std::vector<double> > trtModulesWithCOG;
383
384 // TRT_DetElementContainer->TRT_DetElementCollection for TRT
386 const InDetDD::TRT_DetElementCollection* elements(trtDetEleHandle->getElements());
387 if (not trtDetEleHandle.isValid() or elements==nullptr) {
388 ATH_MSG_FATAL(m_trtDetEleCollKey.fullKey() << " is not available.");
389 return;
390 }
391
392 //step through all detector elements (=strawlayers) and accumulate strawcenters per
393 // element (with DB granularity, i.e. phi sectors in endcap, bi-modules in barrel)
394 for (const InDetDD::TRT_BaseElement *element: *elements) {
395 const Identifier TRTID_orig = element->identify();
396 const Identifier TRTID = reduceTRTID(TRTID_orig);
397 bool insertSuccess{};
398 std::tie(std::ignore, insertSuccess) = trtModulesWithCOG.insert({TRTID,std::vector<double>(4,0.)}); //create fresh vector for module center
399 if (not insertSuccess){
400 ATH_MSG_VERBOSE("No insert was performed, identifier was already in the trtModulesWithCOG map");
401 }
402
403 unsigned int nStraws = element->nStraws();
404 for (unsigned int l = 0; l<nStraws; l++) {
405 const Amg::Vector3D strawcenter = element->strawCenter(l);
406 trtModulesWithCOG[TRTID].at(0) += strawcenter.x(); /*sumx*/
407 trtModulesWithCOG[TRTID].at(1) += strawcenter.y(); /*sumy*/
408 trtModulesWithCOG[TRTID].at(2) += strawcenter.z(); /*sumz*/
409 trtModulesWithCOG[TRTID].at(3) += 1.; /*nStraws*/
410
411 }
412
413 ATH_MSG_DEBUG( "this strawlayer has " << nStraws << " straws." );
414 ATH_MSG_DEBUG( "strawcount of this module: " << trtModulesWithCOG[TRTID].at(3) );
415
416 }
417
418 //go through cog list and create one COG per TRT module (at DB granularity)
419 std::map< Identifier, std::vector<double> >::const_iterator iter2;
420 for (iter2 = trtModulesWithCOG.begin(); iter2!=trtModulesWithCOG.end(); ++iter2) {
421 const Identifier TRTID = iter2->first;
422 double nStraws = iter2->second.at(3);
423 nTRT++;
424 ATH_MSG_VERBOSE( "TRT module " << nTRT );
425 m_ModuleList[TRTID] = HepGeom::Point3D<double>(iter2->second.at(0)/nStraws, iter2->second.at(1)/nStraws,iter2->second.at(2)/nStraws);
426
427 HepGeom::Transform3D InitialAlignment ;
428
429 const Amg::Transform3D* p = m_trtaligndbservice->getAlignmentTransformPtr(TRTID,2) ;
430 if ( p ) {
431 if (msgLvl(MSG::VERBOSE)) {
432 InitialAlignment = Amg::EigenTransformToCLHEP(*p) ;
433 msg() << "Initial Alignment of module " << m_idHelper->show_to_string(TRTID,nullptr,'/') << endmsg;
434 msg() << commonAlignmentOutput(InitialAlignment);
435 msg() << endmsg;
436 }
437 } else {
438
439 ATH_MSG_VERBOSE("No initial alignment for TRT module " << m_idHelper->show_to_string(TRTID,nullptr,'/') );
440 }
441
442
443 }
444 }
445
446 //__________________________________________________________________________
448 {
449
450 SmartIF<IRndmGenSvc> randsvc{Gaudi::svcLocator()->service("RndmGenSvc")};
451 ATH_CHECK(randsvc.isValid());
452 ATH_MSG_DEBUG( "Got RndmGenSvc" );
453
454 int i = 0;
455
456 /*
457 ===================================
458 Documentation of misalignment modes
459 ===================================
460
461 MisalignMode =
462 0: nothing, no misalignments are generated
463 1: Misalignment of whole InDet by 6 parameters
464 2: random misalignment
465 3: IBL-stave temperature dependent bowing
466
467 ====================================================
468 Global Distortions according to David Brown (LHC Detector Alignment Workshop 2006-09-04, slides page 11)
469 ====================================================
470 11: R delta R: Radial expansion linearly with r
471 12: Phi delta R: radial expansion sinuisoidally with phi
472 13: Z delta R: radial expansion linearly with z
473 21: R delta Phi: rotation linearly with r
474 22: Phi delta Phi: rotation sinusoidally with phi
475 23: Z delta Phi: rotation linearly with z
476 31: R delta Z: z-shift linearly with r
477 32: Phi delta Z: z-shift sinusoidally with phi
478 33: Z delta Z: z-shift linearly with z
479 */
480
481 const double maxRadius=51.4*CLHEP::cm; // maximum radius of Silicon Detector (=outermost SCT radius)
482 const double minRadius=50.5*CLHEP::mm; // minimum radius of Silicon Detector (=innermost PIX radius)
483 const double maxLength=158.*CLHEP::cm; // maximum length of Silicon Detector barrel (=length of SCT barrel)
484
485 const double maxDeltaR = m_Misalign_maxShift;
486 const double maxAngle = 2 * asin( m_Misalign_maxShift / (2*maxRadius));
487 const double maxAngleInner = 2 * asin ( m_Misalign_maxShift_Inner / (2*minRadius));
488 const double maxDeltaZ = m_Misalign_maxShift;
489 ATH_MSG_DEBUG( "maximum deltaPhi = " << maxAngle/CLHEP::mrad << " mrad" );
490 ATH_MSG_DEBUG( "maximum deltaPhi for 1/r term = " << maxAngleInner/CLHEP::mrad << " mrad" );
491 const InDetDD::SiDetectorElementCollection* pixelElements=nullptr;
492 const InDetDD::SiDetectorElementCollection* sctElements=nullptr;
493 if(m_doPix){
494 // SiDetectorElementCollection for Pixel
496 pixelElements = *pixelDetEleHandle;
497 if (not pixelDetEleHandle.isValid() or pixelElements==nullptr) {
498 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
499 return StatusCode::FAILURE;
500 }
501 }
502 if(m_doStrip){
503 // SiDetectorElementCollection for SCT
505 sctElements = *sctDetEleHandle;
506 if (not sctDetEleHandle.isValid() or sctElements==nullptr) {
507 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " is not available.");
508 return StatusCode::FAILURE;
509 }
510 }
511
512 for (std::map<Identifier, HepGeom::Point3D<double> >::const_iterator iter = m_ModuleList.begin(); iter != m_ModuleList.end(); ++iter) {
513 ++i;
514 const Identifier& ModuleID = iter->first;
515
516 const InDetDD::SiDetectorElement * SiModule = nullptr; //dummy to get moduleTransform() for silicon
517
518 if (m_idHelper->is_pixel(ModuleID)) {
519 const IdentifierHash Pixel_ModuleHash = m_pixelIdHelper->wafer_hash(ModuleID);
520 if(pixelElements) SiModule = pixelElements->getDetectorElement(Pixel_ModuleHash);
521 else ATH_MSG_WARNING("Trying to access a Pixel module when running with no Pixel!");
522 //module = SiModule;
523 } else if (m_idHelper->is_sct(ModuleID)) {
524 const IdentifierHash SCT_ModuleHash = m_sctIdHelper->wafer_hash(ModuleID);
525 if(sctElements) SiModule = sctElements->getDetectorElement(SCT_ModuleHash);
526 else ATH_MSG_WARNING("Trying to access an SCT/Strop module when running with no SCT/Strip!");
527 //module = SiModule;OB
528 } else if (m_idHelper->is_trt(ModuleID)) {
529 //module = m_TRT_Manager->getElement(ModuleID);
530 //const InDetDD::TRT_BaseElement *p_TRT_Module = m_TRT_Manager->getElement(iter->second.moduleID());
531 } else {
532 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
533 }
534
535 //TRT alignment transformations are given in global frame in DB,
536 // that's not fully correct, since the level2 transform can rotate the system in which level1 transforms
537 // are applied ...
538
539 //Si have a local coordinate system
540 // Take care: For SCT we have to ensure that module's
541 // system is taken, not the system of one of the wafers!
542 HepGeom::Transform3D localToGlobal = HepGeom::Transform3D();
543 if ((not m_idHelper->is_trt(ModuleID))){
544 if (SiModule){
545 localToGlobal=Amg::EigenTransformToCLHEP(SiModule->moduleTransform());
546 } else {
547 ATH_MSG_WARNING("Apparently in a silicon detector, but SiModule is a null pointer");
548 }
549 }
550 const HepGeom::Point3D<double> center = iter->second;
551
552 //center of module in global coordinates
553 double r = center.rho(); //distance from beampipe
554 double phi = center.phi();
555 double z = center.z();
556
557 HepGeom::Transform3D parameterizedTrafo;
558 HepGeom::Transform3D alignmentTrafo;
559
560
561 // prepare scale factor for different subsystems:
562 double ScaleFactor = 1.;
563
564 if (m_idHelper->is_pixel(ModuleID))
565 {
566 ATH_MSG_INFO( "ID Module " << i << " with ID " << m_pixelIdHelper->show_to_string(ModuleID,nullptr,'/') );
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 ATH_MSG_INFO( "ID Module " << i << " with ID " << m_sctIdHelper->show_to_string(ModuleID,nullptr,'/') );
583 if (m_sctIdHelper->is_barrel(ModuleID)) {
584 ScaleFactor=m_ScaleSCTBarrel;
585 }
586 else {
587 ScaleFactor=m_ScaleSCTEndcap;
588 }
589
590 } else if (m_idHelper->is_trt(ModuleID))
591 {
592 ATH_MSG_INFO( "ID Module " << i << " with ID " << m_trtIdHelper->show_to_string(ModuleID,nullptr,'/') );
593 if (m_trtIdHelper->is_barrel(ModuleID)) {
594 ScaleFactor=m_ScaleTRTBarrel;
595 }
596 else {
597 ScaleFactor=m_ScaleTRTEndcap;
598 }
599 } else {
600 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
601 }
602
603 if (msgLvl(MSG::DEBUG)) {
604 msg() << "radius " << r / CLHEP::cm << " centimeter" << endmsg;
605 msg() << "phi " << phi << endmsg;
606 msg() << "z " << z / CLHEP::cm << " centimeter" << endmsg;
607 if (msgLvl(MSG::VERBOSE)) {
608 msg() << "localToGlobal transformation:" << endmsg;
609 msg() << "translation: " << localToGlobal.dx() / CLHEP::cm << ";" << localToGlobal.dy() / CLHEP::cm << ";" << localToGlobal.dz() / CLHEP::cm << endmsg;
610 msg() << "rotation: " << endmsg;
611 msg() << localToGlobal.xx() << " " << localToGlobal.xy() << " " << localToGlobal.xz() << endmsg;
612 msg() << localToGlobal.yx() << " " << localToGlobal.yy() << " " << localToGlobal.yz() << endmsg;
613 msg() << localToGlobal.zx() << " " << localToGlobal.zy() << " " << localToGlobal.zz() << endmsg;
614 }
615 }
616
617 if (!m_MisalignmentMode) {
618 //no misalignment mode set
619 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
620 }
621
622 else if (m_MisalignmentMode==1) {
623 //shift whole detector
624 HepGeom::Vector3D<double> shift(ScaleFactor*m_Misalign_x, ScaleFactor*m_Misalign_y, ScaleFactor*m_Misalign_z);
625
626 CLHEP::HepRotation rot;
627 rot = CLHEP::HepRotationX(ScaleFactor*m_Misalign_alpha) * CLHEP::HepRotationY(ScaleFactor*m_Misalign_beta) * CLHEP::HepRotationZ(ScaleFactor*m_Misalign_gamma);
628
629 if (ScaleFactor == 0.0) {
630 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
631 } else {
632 parameterizedTrafo = HepGeom::Transform3D(rot, shift);
633 }
634
635 }
636
637 else if (m_MisalignmentMode == 2) {
638
639 // randomly misalign modules at L3
646 Rndm::Numbers RandMisX(randsvc, Rndm::Gauss(m_Misalign_x,m_RndmMisalignWidth_x*ScaleFactor));
647 Rndm::Numbers RandMisY(randsvc, Rndm::Gauss(m_Misalign_y,m_RndmMisalignWidth_y*ScaleFactor));
648 Rndm::Numbers RandMisZ(randsvc, Rndm::Gauss(m_Misalign_z,m_RndmMisalignWidth_z*ScaleFactor));
649 Rndm::Numbers RandMisalpha(randsvc, Rndm::Gauss(m_Misalign_alpha,m_RndmMisalignWidth_alpha*ScaleFactor));
650 Rndm::Numbers RandMisbeta(randsvc, Rndm::Gauss(m_Misalign_beta,m_RndmMisalignWidth_beta*ScaleFactor));
651 Rndm::Numbers RandMisgamma(randsvc, Rndm::Gauss(m_Misalign_gamma,m_RndmMisalignWidth_gamma*ScaleFactor));
652
653 double randMisX = RandMisX(); //assign to variables to allow the values to be queried
654 double randMisY = RandMisY();
655 double randMisZ = RandMisZ();
656
657 double randMisaplha = RandMisalpha();
658 double randMisbeta = RandMisbeta();
659 double randMisgamma = RandMisgamma();
660
661 CLHEP::HepRotation rot;
662 HepGeom::Vector3D<double> shift;
663
664
665 if (ScaleFactor == 0.0) {
666 parameterizedTrafo = HepGeom::Transform3D(); // initialized as identity transformation
667 } else {
668 shift = HepGeom::Vector3D<double>(randMisX, randMisY, randMisZ);
669 rot = CLHEP::HepRotationX(randMisaplha) * CLHEP::HepRotationY(randMisbeta) * CLHEP::HepRotationZ(randMisgamma);
670 parameterizedTrafo = HepGeom::Transform3D(rot, shift);}
671
672 }
673
674 else if (m_MisalignmentMode==3) {
675 //shift whole detector
676 double deltaX;
677 if ( m_idHelper->is_pixel(ModuleID) && m_pixelIdHelper->is_blayer(ModuleID) ) {
678 //function is parameterized in global z
680
681 } else {
682 //IBL-stave temperature distortion not applied to anything but IBL
683 deltaX = 0.;
684 ATH_MSG_DEBUG( "will not move this module for IBL temp distortion " );
685 }
686
687 ATH_MSG_DEBUG( "deltaX for this module: " << deltaX/CLHEP::micrometer << " um" );
688 parameterizedTrafo = HepGeom::Translate3D(deltaX,0,0); // translation in x direction
689 }
690
691 else if (m_MisalignmentMode == 7) {
692
693 std::string module_str;
694 if(m_idHelper->is_pixel(ModuleID)) module_str = m_pixelIdHelper->show_to_string(ModuleID,nullptr,'/');
695 if(m_idHelper->is_sct(ModuleID)) module_str = m_sctIdHelper->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_pixel(ModuleID)) {
915 if (m_IDAlignDBTool->tweakTrans(ModuleID,3, alignmentTrafoAmg)) {
916 ATH_MSG_INFO( "Update of alignment constants for module " << m_pixelIdHelper->show_to_string(ModuleID,nullptr,'/') << " successful" );
917 } else {
918 ATH_MSG_ERROR( "Update of alignment constants for module " << m_pixelIdHelper->show_to_string(ModuleID,nullptr,'/') << " not successful" );
919 }
920 } else if (m_idHelper->is_sct(ModuleID)) {
921 if (m_IDAlignDBTool->tweakTrans(ModuleID,3, alignmentTrafoAmg)) {
922 ATH_MSG_INFO( "Update of alignment constants for module " << m_sctIdHelper->show_to_string(ModuleID,nullptr,'/') << " successful" );
923 } else {
924 ATH_MSG_ERROR( "Update of alignment constants for module " << m_sctIdHelper->show_to_string(ModuleID,nullptr,'/') << " not successful" );
925 }
926 } else if (m_idHelper->is_trt(ModuleID)) {
927 if (!m_trtIdHelper->is_barrel(ModuleID) && m_trtIdHelper->phi_module(ModuleID)!=0) {
928 //don't align - there's no trans in the DB for phi sectors other than 0
929 ATH_MSG_DEBUG( "TRT endcap phi sector " << m_trtIdHelper->phi_module(ModuleID) << " not aligned" );
930 } else {
931 if (m_trtaligndbservice->tweakAlignTransform(ModuleID,alignmentTrafoAmg,2).isFailure()) {
932 ATH_MSG_ERROR( "Update of alignment constants for module " << m_trtIdHelper->show_to_string(ModuleID,nullptr,'/') << " not successful" );
933 } else {
934 ATH_MSG_INFO( "Update of alignment constants for module " << m_trtIdHelper->show_to_string(ModuleID,nullptr,'/') << " successful" );
935 }
936 }
937 } else {
938 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
939 }
940
941 double alpha, beta, gamma;
942 m_IDAlignDBTool->extractAlphaBetaGamma(alignmentTrafoAmg, alpha, beta, gamma);
943
944 m_AlignResults_x = alignmentTrafo.getTranslation().x();
945 m_AlignResults_y = alignmentTrafo.getTranslation().y();
946 m_AlignResults_z = alignmentTrafo.getTranslation().z();
947 m_AlignResults_alpha = alpha;
948 m_AlignResults_beta = beta;
949 m_AlignResults_gamma = gamma;
950
951
952 HepGeom::Transform3D LocalaGlobal = HepGeom::Transform3D();
953 LocalaGlobal = Amg::EigenTransformToCLHEP(SiModule->moduleTransform());
954 HepGeom::Point3D<double> alignedPosLocal(m_AlignResults_x,m_AlignResults_y,m_AlignResults_z);
955
956
957
958
959 m_Initial_center_x = center.x() ;
960 m_Initial_center_y = center.y() ;
961 m_Initial_center_z = center.z() ;
962
963 HepGeom::Point3D<double> alignedPosGlobal = LocalaGlobal * alignedPosLocal;
964
965 // Global Misalignment HERE
966 if (m_idHelper->is_sct(ModuleID)) {
967 // non-zero local center position gives additional radial shift of SCT endcap
968 const InDetDD::StripStereoAnnulusDesign *p_design_check = dynamic_cast<const InDetDD::StripStereoAnnulusDesign*>(&(SiModule->design()));
969 if (p_design_check){
970 Amg::Vector3D SCT_Center = p_design_check->sensorCenter();
971 double radialShift_x = SCT_Center[0]; // in sensor frame, x direction
972 double radialShift_y = SCT_Center[1]; // in sensor frame, y direction
973 HepGeom::Transform3D radial_shift = HepGeom::Translate3D(radialShift_x,radialShift_y,0); // the additional radial shift applied as translation
974 HepGeom::Transform3D LocalaaGlobal = LocalaGlobal * radial_shift; // apply additional radial shift
975 HepGeom::Point3D<double> SCT_endcap_alignedPosGlobal = LocalaaGlobal * alignedPosLocal; // corrected global transformation
976 m_Global_center_x = SCT_endcap_alignedPosGlobal.x();
977 m_Global_center_z = SCT_endcap_alignedPosGlobal.z();
978 m_Global_center_y = SCT_endcap_alignedPosGlobal.y();
979 }
980
981 else { // no additional radial shift for SCT barrel
982 m_Global_center_x = alignedPosGlobal.x();
983 m_Global_center_y = alignedPosGlobal.y();
984 m_Global_center_z = alignedPosGlobal.z();
985
986 }
987
988 }
989
990 else { // no additional radial shift for non-SCT elements
991 m_Global_center_x = alignedPosGlobal.x();
992 m_Global_center_y = alignedPosGlobal.y();
993 m_Global_center_z = alignedPosGlobal.z();
994 }
995
996
997 if (m_idHelper->is_sct(ModuleID)) {
1001 m_AlignResults_Identifier_LayerDisc = m_sctIdHelper->layer_disk(ModuleID);
1002 m_AlignResults_Identifier_Phi = m_sctIdHelper->phi_module(ModuleID);
1003 m_AlignResults_Identifier_Eta = m_sctIdHelper->eta_module(ModuleID);
1004 } else if (m_idHelper->is_pixel(ModuleID)) {
1009 m_AlignResults_Identifier_Phi = m_pixelIdHelper->phi_module(ModuleID);
1010 m_AlignResults_Identifier_Eta = m_pixelIdHelper->eta_module(ModuleID);
1011 } else if (m_idHelper->is_trt(ModuleID)) {
1015 m_AlignResults_Identifier_LayerDisc = m_trtIdHelper->layer_or_wheel(ModuleID);
1016 m_AlignResults_Identifier_Phi = m_trtIdHelper->phi_module(ModuleID);
1017 m_AlignResults_Identifier_Eta = m_trtIdHelper->straw_layer(ModuleID);
1018
1019 } else {
1020 ATH_MSG_WARNING( "Something fishy, identifier is neither Pixel, nor SCT or TRT!" );
1021 }
1022
1023 // Write out AlignResults ntuple
1024 if (StatusCode::SUCCESS!=ntupleSvc()->writeRecord("NTUPLES/CREATEMISALIGN/InitialAlignment")) {
1025 ATH_MSG_ERROR( "Could not write InitialAlignment ntuple." );
1026 }
1027
1028 } // end of module loop
1029
1030 // i = 0;
1031
1032 //m_IDAlignDBTool->printDB(2);
1033 if(m_doPix || m_doStrip){
1034 if (StatusCode::SUCCESS!=m_IDAlignDBTool->outputObjs()) {
1035 ATH_MSG_ERROR( "Writing of AlignableTransforms failed" );
1036 } else {
1037 ATH_MSG_INFO( "AlignableTransforms were written" );
1038 ATH_MSG_INFO( "Writing database to textfile" );
1039 m_IDAlignDBTool->writeFile(false,m_asciiFileNameBase+"_Si.txt");
1040 ATH_MSG_INFO( "Writing IoV information to mysql file" );
1042 }
1043 }
1044
1045 if(m_doTRT){
1046 if (StatusCode::SUCCESS!=m_trtaligndbservice->streamOutAlignObjects()) {
1047 ATH_MSG_ERROR( "Write of AlignableTransforms (TRT) failed" );
1048 } else {
1049 ATH_MSG_INFO( "AlignableTransforms for TRT were written" );
1050 ATH_MSG_INFO( "Writing TRT database to textfile" );
1051 if ( StatusCode::SUCCESS != m_trtaligndbservice->writeAlignTextFile(m_asciiFileNameBase+"_TRT.txt") ) {
1052 ATH_MSG_ERROR( "Failed to write AlignableTransforms (TRT) to txt file " << m_asciiFileNameBase+"_TRT.txt" );
1053 }
1054 ATH_MSG_INFO( "Writing IoV information for TRT to mysql file" );
1055 if ( StatusCode::SUCCESS
1057 ATH_MSG_ERROR( "Write of AIoV information (TRT) to mysql failed (tag=" << m_SQLiteTag << "_TRT)");
1058 }
1059 }
1060 }
1061
1062 return StatusCode::SUCCESS;
1063
1064 }
1065
1066 //__________________________________________________________________________
1067 const HepGeom::Transform3D CreateMisalignAlg::BuildAlignTransform(const CLHEP::HepVector & AlignParams)
1068 {
1069 HepGeom::Vector3D<double> AlignShift(AlignParams[0],AlignParams[1],AlignParams[2]);
1070 CLHEP::HepRotation AlignRot;
1071
1072 AlignRot = CLHEP::HepRotationX(AlignParams[3]) * CLHEP::HepRotationY(AlignParams[4]) * CLHEP::HepRotationZ(AlignParams[5]);
1073
1074 HepGeom::Transform3D AlignTransform = HepGeom::Transform3D(AlignRot,AlignShift);
1075 return AlignTransform;
1076 }
1077
1078 //__________________________________________________________________________
1080 {
1081 // msg(MSG::DEBUG) << "in CreateMisalignAlg::reduceTRTID" << endmsg;
1082 ATH_MSG_DEBUG( "reduceTRTID got Id " << m_idHelper->show_to_string(id,nullptr,'/'));
1083
1084 int barrel_ec= m_trtIdHelper->barrel_ec(id);
1085 // attention: TRT DB only has one alignment correction per barrel module (+1/-1) pair
1086 // which is stored in -1 identifier
1087 if (barrel_ec==1) barrel_ec=-1; //only regard -1 barrel modules, +1 modules will belong to them
1088
1089 //if (abs(barrel_ec)==2) phi_module=0;
1090 // only regard phi sector 0, the only one having an alignmentTrafo
1091 //does not work, since the center-of-mass of all phi sectors is on the beamline,so
1092 // transformations would become zero -> this has to be handled later
1093 int phi_module=m_trtIdHelper->phi_module(id);
1094
1095 int layer_or_wheel=m_trtIdHelper->layer_or_wheel(id);
1096
1097 int strawlayer=0;
1098 if (!m_trtIdHelper->is_barrel(id)) {
1099 strawlayer = m_trtIdHelper->straw_layer(id) / 4 * 4;
1100 // only strawlayers 0,4,8,12 are fed into DB for endcap
1101 }
1102
1103 // 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;
1104 ATH_MSG_DEBUG( " and returns Id " << m_idHelper->show_to_string(m_trtIdHelper->layer_id(barrel_ec,phi_module,layer_or_wheel,strawlayer),nullptr,'/'));
1105 // return m_trtIdHelper->module_id(barrel_ec,phi_module,layer_or_wheel);
1106 return m_trtIdHelper->layer_id(barrel_ec,phi_module,layer_or_wheel,strawlayer);
1107 }
1108
1109 //__________________________________________________________________________
1111 {
1112 Identifier id= m_trtIdHelper->module_id(hash);
1113 return reduceTRTID(id);
1114 }
1115
1116 //__________________________________________________________________________
1118 {
1119 // IBL staves are straight at a set point of 15 degrees.
1120 // Get set point value to use for magnitude parameter from temp_shift starting at 15 degrees
1121 double T = 15 + temp_shift;
1122 return 1.53e-12 - 1.02e-13*T;
1123 }
1124
1125 //__________________________________________________________________________
1126 double CreateMisalignAlg::getBowingTx(double p1, double z)
1127 {
1128 // Bowing fit function has the following form
1129 // [0]-[1]*(x+[2]) * (4.0*[2]*(x+[2])**2 - (x+[2])**3 - (2.0*[2])**3)
1130 // param 0 : is the baseline shift (fixed at 0 for MC)
1131 // param 1 : is the magnitude fit param (temp dependent input param)
1132 // param 2 : is the stave fix pointat both ends (fixed at 366.5)
1133 double p0 = 0;
1134 double p2 = 366.5;
1135 double Tx = p0 - p1*(z+p2) * (4.*p2*pow((z+p2),2) - pow((z+p2),3) - pow((2.*p2),3));
1136 return Tx;
1137 }
1138
1139} // 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