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