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