ATLAS Offline Software
Loading...
Searching...
No Matches
SolidStateDetectorElementBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
10#include "CLHEP/Geometry/Vector3D.h"
11#include "CLHEP/Units/SystemOfUnits.h"
12#include "CLHEP/Vector/ThreeVector.h"
13
14namespace InDetDD {
15using Trk::distPhi;
16using Trk::distEta;
17using Trk::distDepth;
18
19// Constructor with parameters:
22 const GeoVFullPhysVol* geophysvol,
23 const SiCommonItems* commonItems,
24 const GeoAlignmentStore* geoAlignStore) :
25 TrkDetElementBase(geophysvol),
26 m_id(id),
28 m_commonItems(commonItems),
29 m_surface(),
30 m_geoAlignStore(geoAlignStore)
31 {
32 m_hitEta = m_design->etaAxis();
33 m_hitPhi = m_design->phiAxis();
34 m_hitDepth = m_design->depthAxis();
35
37 }
38
39 // Destructor:
41
42 const HepGeom::Transform3D&
44 {
45 if (!m_cache.isValid()) updateCache();
46 return m_cache.ptr()->m_transformCLHEP;
47 }
48
49 const HepGeom::Transform3D
51 {
52 if (m_geoAlignStore) {
53 const GeoTrf::Transform3D* ptrXf = m_geoAlignStore->getDefAbsPosition(getMaterialGeom());
54 if (ptrXf) return Amg::EigenTransformToCLHEP(*ptrXf) * recoToHitTransform();
55 }
56 return Amg::EigenTransformToCLHEP(getMaterialGeom()->getDefAbsoluteTransform()) * recoToHitTransform();
57 }
58
61 {
62 HepGeom::Transform3D tmpTransform = defTransformCLHEP();
63 return Amg::CLHEPTransformToEigen(tmpTransform);
64 }
65
66 const HepGeom::Vector3D<double>&
68 {
69 if (!m_cache.isValid()) updateCache();
70 return m_cache.ptr()->m_phiAxisCLHEP;
71 }
72
73 const Amg::Vector3D&
75 {
76 if (!m_cache.isValid()) updateCache();
77 return m_cache.ptr()->m_phiAxis;
78 }
79
80 const HepGeom::Vector3D<double>&
82 {
83 if (!m_cache.isValid()) updateCache();
84 return m_cache.ptr()->m_etaAxisCLHEP;
85 }
86
87 const Amg::Vector3D&
89 {
90 if (!m_cache.isValid()) updateCache();
91 return m_cache.ptr()->m_etaAxis;
92 }
93
95 SolidStateDetectorElementBase::hitLocalToLocal(double xEta, double xPhi) const // Will change order to phi, eta
96 { // due to whether module is centred on
97 if (!m_axisDir.isValid()) updateCache(); // z or y axes
98 const AxisDir& dir = *m_axisDir.ptr();
99
100 if (!dir.m_etaDirection) xEta = -xEta;
101 if (!dir.m_phiDirection) xPhi = -xPhi;
102 auto result = Amg::Vector2D(xPhi, xEta);
103
104 if (m_design->shape() == InDetDD::PolarAnnulus) { // Do conversion to polar co-ords as well
105 double y = result.x(); // Co-ordinate flip from cartesian needs to be temporarily un-done to
106 double x = result.y(); // allow atan2 to work in conversion
107
108 double r = std::hypot(x,y);
109 double phi = std::atan2(y,x);
110 result = Amg::Vector2D(phi,r); // now flip again
111 }
112
113 return result;
114 }
115
116 HepGeom::Point3D<double>
117 SolidStateDetectorElementBase::hitLocalToLocal3D(const HepGeom::Point3D<double>& hitPosition) const
118 {
119 // Equiv to transform().inverse * transformHit() * hitPosition
120 if (!m_axisDir.isValid()) updateCache();
121 const AxisDir& dir = *m_axisDir.ptr();
122
123 double xDepth = hitPosition[m_hitDepth];
124 double xPhi = hitPosition[m_hitPhi];
125 double xEta = hitPosition[m_hitEta];
126 if (!dir.m_depthDirection) xDepth = -xDepth;
127 if (!dir.m_phiDirection) xPhi = -xPhi;
128 if (!dir.m_etaDirection) xEta = -xEta;
129 return {xPhi, xEta, xDepth};
130 }
131
132 // Get eta/phi extent. Returns min/max eta and phi and r (for barrel)
133 // or z (for endcap) Takes as input the vertex spread in z (+-deltaZ).
134 // Gets 4 corners of the sensor and calculates eta phi for each corner
135 // for both +/- vertex spread. The returned phi is between -M_PI and M_PI
136 // with the direction minPhi to maxPhi always in the positive sense,
137 // so if the element extends across the -180/180 boundary then minPhi will
138 // be greater than maxPhi.
139 void
140 SolidStateDetectorElementBase::getEtaPhiRegion(double deltaZ, double& etaMin, double& etaMax, double& phiMin,
141 double& phiMax, double& rz) const
142 {
143 HepGeom::Point3D<double> corners[4];
144 getCorners(corners);
145
146 bool first = true;
147
148 double phiOffset = 0.;
149
150 for (auto & corner : corners) {
151 double etaMinPoint = 0.;
152 double etaMaxPoint = 0.;
153 double phiPoint = 0.;
154
155 // Get the eta phi value for this corner.
156 getEtaPhiPoint(corner, deltaZ, etaMinPoint, etaMaxPoint, phiPoint);
157
158 if (first) { // Use the first point to initialize the min/max values.
159
160 // Put phi in a range so that we are not near -180/+180 division.
161 // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg.
162 // This offset is later removed.
163 if (phiPoint < -0.5 * M_PI) {
164 phiOffset = -0.5 * M_PI;
165 } else if (phiPoint > 0.5 * M_PI) {
166 phiOffset = 0.5 * M_PI;
167 }
168 phiMin = phiMax = phiPoint - phiOffset;
169 etaMin = etaMinPoint;
170 etaMax = etaMaxPoint;
171 } else {
172 phiPoint -= phiOffset;
173 // put phi back in -M_PI < phi < +M_PI range
174 if (phiPoint < -M_PI) phiPoint += 2. * M_PI;
175 if (phiPoint > M_PI) phiPoint -= 2. * M_PI;
176 phiMin = std::min(phiMin, phiPoint);
177 phiMax = std::max(phiMax, phiPoint);
178 etaMin = std::min(etaMin, etaMinPoint);
179 etaMax = std::max(etaMax, etaMaxPoint);
180 }
181 first = false;
182 }
183
184 // put phi back in -M_PI < phi < +M_PI range
185 phiMin += phiOffset;
186 phiMax += phiOffset;
187 if (phiMin < -M_PI) phiMin += 2. * M_PI;
188 if (phiMin > M_PI) phiMin -= 2. * M_PI;
189 if (phiMax < -M_PI) phiMax += 2. * M_PI;
190 if (phiMax > M_PI) phiMax -= 2. * M_PI;
191 //does it make sense having this if the below is pure virtual for this base class?
192 //Should this just be postponed to the derived classes?
193 rz = get_rz();
194
195 }
196
197 const Trk::SurfaceBounds&
199 {
200 return m_design->bounds();
201 }
202
205 double phiTol, double etaTol) const
206 {
207 return m_design->inDetector(localPosition, phiTol, etaTol);
208 }
209
212 {
213 return m_design->inDetector(localPosition(globalPosition), phiTol, etaTol);
214 }
215
218 {
219 SiCellId cellId = m_design->cellIdOfPosition(localPosition);
220 return identifierFromCellId(cellId);
221 }
222
228
231 {
232 return m_design->localPositionOfCell(cellId);
233 }
234
237 {
238 SiCellId cellId = cellIdFromIdentifier(id);
239 return m_design->localPositionOfCell(cellId);
240 }
241
242 int
244 {
245 SiReadoutCellId readoutId = m_design->readoutIdOfCell(cellId);
246 return m_design->numberOfConnectedCells(readoutId);
247 }
248
251 {
252 SiReadoutCellId readoutId = m_design->readoutIdOfCell(cellId);
253 return m_design->connectedCell(readoutId, number);
254 }
255
256 void
258 {
259 //Do we need this at all in base class, or just in derived?
260 if (!m_id.is_valid()) throw std::runtime_error("SolidStateDetectorElementBase: Invalid identifier");
261
262 // Set surface
263 m_surface = std::make_unique<Trk::PlaneSurface>(*this);
264 }
265
266 // update cache
267 // This is supposed to be called like
268 //
269 // if (!m_cache.isValid()) updateCache();
270 //
271 void
273 {
274 if (m_cache.isValid()) return;
275 CachedVals cache;
276
277 // use aligned transform if available
278 const GeoTrf::Transform3D* ptrXf;
279 GeoTrf::Transform3D geotrf;
280
281 if (m_geoAlignStore){
282 ptrXf = m_geoAlignStore->getAbsPosition(getMaterialGeom());
283 if (ptrXf) {
284 cache.m_transformHit = (*ptrXf);
285 //the below can have an (optional) shift to acccount for transformations
286 //applied when constructing the DetectorElements from the GeoPhysVols
287 //(At the moment, only used for ITkStrip barrel when creating a DetElement per row)
288 geotrf = (*ptrXf) * m_design->moduleShift();
289 }
290 else {
291 geotrf.setIdentity();
292 }
293 }
294 else{
295 cache.m_transformHit = getMaterialGeom()->getAbsoluteTransform();
296 //the below can have an (optional) shift to acccount for transformations
297 //applied when constructing the DetectorElements from the GeoPhysVols
298 //(At the moment, only used for ITkStrip barrel when creating a DetElement per row)
299 geotrf = getMaterialGeom()->getAbsoluteTransform() * m_design->moduleShift();
300 }
301
302 const GeoTrf::Transform3D& geoTransform = geotrf;
303
304 cache.m_center = geoTransform * m_design->sensorCenter();
305
306 //Is this needed outside e.g. ReadSiDetElements? Maybe candidate for future removal?
307 cache.m_centerCLHEP = HepGeom::Point3D<double>(cache.m_center[0],cache.m_center[1],cache.m_center[2]);
308
309 Amg::Vector3D centerGeoModel(0., 0., 0.);
310 cache.m_origin = geoTransform * centerGeoModel;
311
312 //
313 // Determine directions depth, eta and phi axis in reconstruction local frame
314 // ie depth away from interaction point
315 // phi in direction of increasing phi
316 // eta in direction of increasing z in barrel, and increasing r in endcap
317 //
318
319 // depthAxis, phiAxis, and etaAxis are defined to be x,y,z respectively for all detectors for hit local frame.
320 // depthAxis, phiAxis, and etaAxis are defined to be z,x,y respectively for all detectors for reco local frame.
321 static const Amg::Vector3D localAxes[3] = {
322 Amg::Vector3D(1.,0.,0.),
323 Amg::Vector3D(0.,1.,0.),
324 Amg::Vector3D(0.,0.,1.)
325 };
326
327 static const Amg::Vector3D & localRecoPhiAxis = localAxes[distPhi]; // Defined to be same as x axis
328 static const Amg::Vector3D & localRecoEtaAxis = localAxes[distEta]; // Defined to be same as y axis
329 static const Amg::Vector3D & localRecoDepthAxis = localAxes[distDepth]; // Defined to be same as z axis
330
331 // We only need to calculate the rough orientation once.
332 //For it to change would require extreme unrealistic misalignment changes.
333#ifndef NDEBUG
334 bool setAxisDir = false;
335#endif
336 if (!m_axisDir.isValid()) {
337 AxisDir dir{};
338 // Determine the unit vectors in global frame
339
340 const Amg::Vector3D &geoModelPhiAxis = localAxes[m_hitPhi];
341 const Amg::Vector3D &geoModelEtaAxis = localAxes[m_hitEta];
342 const Amg::Vector3D &geoModelDepthAxis = localAxes[m_hitDepth];
343
344 Amg::Vector3D globalDepthAxis(geoTransform.linear() * geoModelDepthAxis);
345 Amg::Vector3D globalPhiAxis(geoTransform.linear() * geoModelPhiAxis);
346 Amg::Vector3D globalEtaAxis(geoTransform.linear() * geoModelEtaAxis);
347
348 // unit radial vector
349 Amg::Vector3D unitR(cache.m_center.x(), cache.m_center.y(), 0.);
350 unitR.normalize();
351
352 Amg::Vector3D nominalEta(0.0,0.0,1.0);
353 Amg::Vector3D nominalNormal(0.0,0.0,0.0);
354 Amg::Vector3D nominalPhi(-unitR.y(), unitR.x(), 0.0);
355
356 // In Barrel like geometry, the etaAxis is along increasing z, and normal is in increasing radial direction.
357 // In Endcap like geometry, the etaAxis is along increasing r, and normal is in decreasing z direction,
358 // We base whether it is barrel like or endcap like by the orientation of the local z axis of the
359 // the element. This allows the use of endcap identifiers in a TB setup.
360
361
362 nominalEta(2) = 1.0;
363 dir.m_barrelLike = true;
364
365 if (std::abs(globalEtaAxis.dot(nominalEta)) < 0.5) { // Check that it is in roughly the right direction. Allowed not to be for ITK inclined/barrel ring modules
366 dir.m_barrelLike = false;
367 }
368
369 if (dir.m_barrelLike) {
370 nominalEta(2) = 1.0;
371 nominalNormal = unitR;
372 } else { // endcap like
373 nominalNormal(2) = -1.0;
374 nominalEta = unitR;
375 }
376
377 // Determine if axes are to have there directions swapped.
378
379 //
380 // Depth axis.
381 //
382 dir.m_depthAngle = globalDepthAxis.dot(nominalNormal);
383 dir.m_depthDirection = true;
384 if (dir.m_depthAngle < 0) {
385 if (m_design->depthSymmetric()) {
386 dir.m_depthDirection = false;
387 } else {
388 ATH_MSG_DEBUG( "Unable to swap local depth axis.");
389 }
390 }
391 if (std::abs(dir.m_depthAngle) < 0.5 && (m_design->type())!=InDetDD::PLR) { // Check that it is in roughly the right direction. Ignore this for the PLR as it gives values as low as 0.489)
392 ATH_MSG_VERBOSE( "Orientation of local depth axis does not follow Run 1/2/3 convention.");
393 }
394
395 // for HGTD modules, the check on phi and eta directions don't make sense
396 // as the modules do not respect the conventional position for endcap discs:
397 // - the local eta axis is never parallel to the radial direction
398 // - the local phi axis is never perpendicular to the radial direction
399 // hence, removing errors and allowing swap of the axis when needed
400 bool isHGTD = this->getIdHelper()->is_hgtd(m_id);
401
402 //
403 // Phi axis
404 //
405 dir.m_phiAngle = globalPhiAxis.dot(nominalPhi);
406 dir.m_phiDirection = true;
407 if (dir.m_phiAngle < 0) {
408 if (m_design->phiSymmetric()) {
409 dir.m_phiDirection = false;
410 } else {
411 ATH_MSG_DEBUG("Unable to swap local xPhi axis.");
412 }
413 }
414 if (not isHGTD and std::abs(dir.m_phiAngle) < 0.5) { // Check that it is in roughly the right direction.
415 ATH_MSG_VERBOSE( "Orientation of local xPhi axis does not follow Run 1/2/3 convention.");
416 }
417
418 //
419 // Eta axis
420 //
421 dir.m_etaAngle = globalEtaAxis.dot(nominalEta);
422 dir.m_etaDirection = true;
423 if (dir.m_etaAngle < 0) {
424 if (m_design->etaSymmetric()) {
425 dir.m_etaDirection = false;
426 } else {
427 ATH_MSG_DEBUG("Unable to swap local xEta axis.");
428 }
429 }
430 if (not isHGTD and std::abs(dir.m_etaAngle) < 0.5) { // Check that it is in roughly the right direction.
431 ATH_MSG_VERBOSE( "Orientation of local xEta axis does not follow Run 1/2/3 convention.");
432 }
433
434 m_axisDir.set (dir);
435#ifndef NDEBUG
436 setAxisDir = true;
437#endif
438 } // end if (!m_axisDir.isValid())
439
442
443 #ifndef NDEBUG
444 // Check that local frame is right-handed. (ie transform has no reflection)
445 // This can be done by checking that the determinant is >0.
446 if (setAxisDir) { // Only need to check this once.
447 const AxisDir& dir = *m_axisDir.ptr();
448 HepGeom::Transform3D & t = cache.m_transformCLHEP;
449 double det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) -
450 t(0,1) * (t(1,0)*t(2,2) - t(1,2)*t(2,0)) +
451 t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0));
452 if (det < 0) {
453 ATH_MSG_DEBUG( "Local frame is left-handed. (hitEtaDirection, hitPhiDirection, hitDepthDirection) = ("
454 << dir.m_etaDirection <<", "
455 << dir.m_phiDirection <<", "
456 << dir.m_depthDirection <<")");
457 }
458 }
459 #endif
460
461 // Initialize various cached members, needs to be done here otherwise the necessary transforms are not yet initialized
462 // The unit vectors
463 cache.m_normal = cache.m_transform.linear() * localRecoDepthAxis;
464
465 cache.m_phiAxis = cache.m_transform.linear() * localRecoPhiAxis;
466 cache.m_etaAxis = cache.m_transform.linear() * localRecoEtaAxis;
467
468 //Check where these are actually needed - candidates for removal?
469 cache.m_phiAxisCLHEP = HepGeom::Vector3D<double>(cache.m_phiAxis[0],cache.m_phiAxis[1],cache.m_phiAxis[2]);
470 cache.m_etaAxisCLHEP = HepGeom::Vector3D<double>(cache.m_etaAxis[0],cache.m_etaAxis[1],cache.m_etaAxis[2]);
471
472 getExtent(cache);
473 m_cache.set (std::move (cache));
474 }
475
476 // Get min/max or r, z,and phi
477 // helper method only to be used for the cache construction
478 // i.e inside updateCache
479 void
481 {
482 Amg::Vector3D sensorCenter = m_design->sensorCenter();
483 double radialShift = sensorCenter[0];//in sensor frame, x is radius
484
485 HepGeom::Point3D<double> corners[4];
486 getCorners(corners);
487
488 bool first = true;
489
490 double phiOffset = 0.;
491
492
493 const HepGeom::Transform3D rShift = HepGeom::TranslateY3D(radialShift);//in local frame, radius is y=distEta
494
495 for (auto & corner : corners) {
496
497 corner.transform(rShift);
498
499 // m_tranform is already there as part of the cache construction
500 // This method seems to be used only as a helper for updateCache
501 HepGeom::Point3D<double> globalPoint = cache.m_transformCLHEP * corner;
502
503 double rPoint = globalPoint.perp();
504 double zPoint = globalPoint.z();
505 double phiPoint = globalPoint.phi();
506
507 // Use first point to initializa min/max values.
508 if (first) {
509
510 // Put phi in a range so that we are not near -180/+180 division.
511 // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg.
512 // This offset is later removed.
513 if (phiPoint < -0.5 * M_PI) {
514 phiOffset = -0.5 * M_PI;
515 } else if (phiPoint > 0.5 * M_PI) {
516 phiOffset = 0.5 * M_PI;
517 }
518 cache.m_minPhi = cache.m_maxPhi = phiPoint - phiOffset;
519 cache.m_minR = cache.m_maxR = rPoint;
520 cache.m_minZ = cache.m_maxZ = zPoint;
521
522 } else {
523 phiPoint -= phiOffset;
524 // put phi back in -M_PI < phi < +M_PI range
525 if (phiPoint < -M_PI) phiPoint += 2. * M_PI;
526 if (phiPoint > M_PI) phiPoint -= 2. * M_PI;
527 cache.m_minPhi = std::min(cache.m_minPhi, phiPoint);
528 cache.m_maxPhi = std::max(cache.m_maxPhi, phiPoint);
529 cache.m_minR = std::min(cache.m_minR, rPoint);
530 cache.m_maxR = std::max(cache.m_maxR, rPoint);
531 cache.m_minZ = std::min(cache.m_minZ, zPoint);
532 cache.m_maxZ = std::max(cache.m_maxZ, zPoint);
533 }
534 first = false;
535 }
536
537 // put phi back in -M_PI < phi < +M_PI range
538 cache.m_minPhi += phiOffset;
539 cache.m_maxPhi += phiOffset;
540 if (cache.m_minPhi < -M_PI) cache.m_minPhi += 2. * M_PI;
541 if (cache.m_minPhi > M_PI) cache.m_minPhi -= 2. * M_PI;
542 if (cache.m_maxPhi < -M_PI) cache.m_maxPhi += 2. * M_PI;
543 if (cache.m_maxPhi > M_PI) cache.m_maxPhi -= 2. * M_PI;
544
545 }
546
547 void
548 SolidStateDetectorElementBase::getCorners(HepGeom::Point3D<double>* corners) const
549 {
550 // This makes the assumption that the forward SCT detectors are orientated such that
551 // the positive etaAxis corresponds to the top of the detector where the width is largest.
552 // This is currently always the case.
553 // For the SCT barrel and pixel detectors minWidth and maxWidth are the same and so should
554 // work for all orientations.
555
556 double tmpMinWidth = minWidth();
557 double tmpMaxWidth = maxWidth();
558 double tmpLength = length();
559
560 // Lower left
561 corners[0][distPhi] = -0.5 * tmpMinWidth;
562 corners[0][distEta] = -0.5 * tmpLength;
563 corners[0][distDepth] = 0.;
564
565 // Lower right
566 corners[1][distPhi] = 0.5 * tmpMinWidth;
567 corners[1][distEta] = -0.5 * tmpLength;
568 corners[1][distDepth] = 0.;
569
570 // Upper Right
571 corners[2][distPhi] = 0.5 * tmpMaxWidth;
572 corners[2][distEta] = 0.5 * tmpLength;
573 corners[2][distDepth] = 0.;
574
575 // Upper left
576 corners[3][distPhi] = -0.5 * tmpMaxWidth;
577 corners[3][distEta] = 0.5 * tmpLength;
578 corners[3][distDepth] = 0.;
579 }
580
581 // Gets eta phi for a point given in local coordinates. deltaZ is specified to
582 // account for the vertex spread. phi is independent of this vertex
583 // spread. etaMax will correspond to zMin (-deltaZ) and etaMin will
584 // correspond to zMax (+deltaZ).
585 void
586 SolidStateDetectorElementBase::getEtaPhiPoint(const HepGeom::Point3D<double>& point, double deltaZ,
587 double& etaMin, double& etaMax, double& phi) const
588 {
589 // Get the point in global coordinates.
590 HepGeom::Point3D<double> globalPoint = globalPosition(point);
591
592 double r = globalPoint.perp();
593 double z = globalPoint.z();
594
595 double thetaMin = std::atan2(r,(z + deltaZ));
596 etaMax = -std::log(tan(0.5 * thetaMin));
597 double thetaMax = std::atan2(r,(z - deltaZ));
598 etaMin = -std::log(tan(0.5 * thetaMax));
599
600 phi = globalPoint.phi();
601 }
602 //TODO: can we make this Amg??? Save some back/forth conversions elsewhere...
603 const HepGeom::Transform3D
605 {
606 if (!m_axisDir.isValid()) updateCache();
607 const AxisDir& dir = *m_axisDir.ptr();
608
609 // = transfromHit * hitLocal
610 // = transformHit * recoToHitTransform * recoLocal
611 // recoToHitTransform takes recoLocal to hitLocal
612 // x,y,z -> y,z,x
613 // equiv to a rotation around Y of 90 deg followed by a rotation around X of 90deg
614 //
615 // recoToHit is static as it needs to be calculated once only.
616 // We use the HepGeom::Transform3D constructor which takes one coordinates system to another where the
617 // coordinate system is defined by it center and two axes.
618 // distPhi, distEta are the reco local axes and hitPhi and hitEta are the hit local axes.
619 // It assume phi, eta, depth makes a right handed system which is the case.
620 static const HepGeom::Vector3D<double> localAxes[3] = {
621 HepGeom::Vector3D<double>(1., 0., 0.),
622 HepGeom::Vector3D<double>(0., 1., 0.),
623 HepGeom::Vector3D<double>(0., 0., 1.)
624 };
625
626 //correct phi and eta as necessary - do not change depth, this will be defined by the transform based on the other two
627 int signPhi = dir.m_phiDirection? +1:-1;
628 int signEta = dir.m_etaDirection? +1:-1;
629
630 const HepGeom::Transform3D recoToHit(HepGeom::Point3D<double>(0., 0., 0.),
631 signPhi * localAxes[distPhi],
632 signEta *localAxes[distEta],
633 HepGeom::Point3D<double>(0., 0., 0.),
634 localAxes[m_hitPhi],
635 localAxes[m_hitEta]);
636
637 return recoToHit ;
638
639 }
640
641
642} // namespace InDetDD
#define M_PI
Scalar phi() const
phi method
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static Double_t rz
#define y
#define x
#define z
bool is_hgtd(Identifier id) const
Ensure that the extensions for the Vector3D are properly loaded.
Base class for the detector design classes for ITk and HGTD.
Identifier for the strip or pixel cell.
Definition SiCellId.h:29
Helper class to concentrate common items, such as the pointer to the IdHelper, the lorentzAngle tool ...
class to run intersection tests
Definition SiIntersect.h:23
Identifier for the strip or pixel readout cell.
void getExtent(CachedVals &cache) const
Calculate extent in r,z and phi.
double length() const
Length in eta direction (z - barrel, r - endcap)
virtual const DetectorDesign & design() const
access to the local description (inline):
HepGeom::Point3D< double > hitLocalToLocal3D(const HepGeom::Point3D< double > &hitPosition) const
Same as previuos method but 3D.
SiCellId connectedCell(const SiCellId cellId, int number) const
Get the cell ids sharing the readout for this cell.
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
void getEtaPhiRegion(double deltaZ, double &etaMin, double &etaMax, double &phiMin, double &phiMax, double &rz) const
Method for building up region of interest table.
Amg::Vector2D localPosition(const HepGeom::Point3D< double > &globalPosition) const
transform a global position into a 2D local position (reconstruction frame) (inline)
const HepGeom::Transform3D recoToHitTransform() const
Transform to go from local reconstruction frame to local hit frame.
void getCorners(HepGeom::Point3D< double > *corners) const
Return the four corners of an element in local coordinates.
const DetectorDesign * m_design
local description of this detector element
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const =0
SiCellId from Identifier.
SolidStateDetectorElementBase()=delete
Don't allow no-argument constructor.
virtual const Trk::SurfaceBounds & bounds() const override final
Return the boundaries of the element.
int numberOfConnectedCells(const SiCellId cellId) const
Test if readout cell has more than one diode associated with it.
virtual double get_rz() const =0
virtual ~SolidStateDetectorElementBase()
Destructor.
double maxWidth() const
Max width.
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
void getEtaPhiPoint(const HepGeom::Point3D< double > &point, double deltaZ, double &etaMin, double &etaMax, double &phi) const
Get eta and phi coresponding to a point in local coordinates.
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
const HepGeom::Vector3D< double > & phiAxisCLHEP() const
To determine if readout direction between online and offline needs swapping, see methods swapPhiReado...
virtual void updateCache() const
Recalculate cached values.
double minWidth() const
Min width.
const HepGeom::Transform3D & transformCLHEP() const
Local (reconstruction frame) to global transform.
const HepGeom::Vector3D< double > & etaAxisCLHEP() const
Get reconstruction local eta axes in global frame.
const HepGeom::Transform3D defTransformCLHEP() const
Default Local (reconstruction frame) to global transform ie with no misalignment.
virtual Identifier identifierFromCellId(const SiCellId &cellId) const =0
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
void commonConstructor()
Common code for constructors.
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
Amg::Vector2D rawLocalPositionOfCell(const SiCellId &cellId) const
Returns position (center) of cell.
Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const
Simulation/Hit local frame to reconstruction local frame.
Identifier m_id
identifier of this detector element
Abstract base class for surface bounds to be specified.
TrkDetElementBase(const GeoVFullPhysVol *fullPhysVol)
Constructor from GeoVFullPhysVolume.
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, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Message Stream Member.
@ distEta
readout for silicon
Definition ParamDefs.h:51
@ distPhi
Definition ParamDefs.h:50
@ distEta
readout for silicon
Definition ParamDefs.h:51
@ distPhi
Definition ParamDefs.h:50
std::string number(const double &d, const std::string &s)
Definition utils.cxx:186