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_ERROR( "Orientation of local depth axis does not follow correct convention.");
393 dir.m_depthDirection = true; // Don't swap.
394 }
395
396 // for HGTD modules, the check on phi and eta directions don't make sense
397 // as the modules do not respect the conventional position for endcap discs:
398 // - the local eta axis is never parallel to the radial direction
399 // - the local phi axis is never perpendicular to the radial direction
400 // hence, removing errors and allowing swap of the axis when needed
401 bool isHGTD = this->getIdHelper()->is_hgtd(m_id);
402
403 //
404 // Phi axis
405 //
406 dir.m_phiAngle = globalPhiAxis.dot(nominalPhi);
407 dir.m_phiDirection = true;
408 if (dir.m_phiAngle < 0) {
409 if (m_design->phiSymmetric()) {
410 dir.m_phiDirection = false;
411 } else {
412 ATH_MSG_DEBUG("Unable to swap local xPhi axis.");
413 }
414 }
415 if (not isHGTD and std::abs(dir.m_phiAngle) < 0.5) { // Check that it is in roughly the right direction.
416 ATH_MSG_ERROR( "Orientation of local xPhi axis does not follow correct convention.");
417 dir.m_phiDirection = true; // Don't swap.
418 }
419
420 //
421 // Eta axis
422 //
423 dir.m_etaAngle = globalEtaAxis.dot(nominalEta);
424 dir.m_etaDirection = true;
425 if (dir.m_etaAngle < 0) {
426 if (m_design->etaSymmetric()) {
427 dir.m_etaDirection = false;
428 } else {
429 ATH_MSG_DEBUG("Unable to swap local xEta axis.");
430 }
431 }
432 if (not isHGTD and std::abs(dir.m_etaAngle) < 0.5) { // Check that it is in roughly the right direction.
433 ATH_MSG_ERROR( "Orientation of local xEta axis does not follow correct convention.");
434 dir.m_etaDirection = true; // Don't swap
435 }
436
437 m_axisDir.set (dir);
438#ifndef NDEBUG
439 setAxisDir = true;
440#endif
441 } // end if (!m_axisDir.isValid())
442
445
446 #ifndef NDEBUG
447 // Check that local frame is right-handed. (ie transform has no reflection)
448 // This can be done by checking that the determinant is >0.
449 if (setAxisDir) { // Only need to check this once.
450 const AxisDir& dir = *m_axisDir.ptr();
451 HepGeom::Transform3D & t = cache.m_transformCLHEP;
452 double det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) -
453 t(0,1) * (t(1,0)*t(2,2) - t(1,2)*t(2,0)) +
454 t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0));
455 if (det < 0) {
456 ATH_MSG_DEBUG( "Local frame is left-handed. (hitEtaDirection, hitPhiDirection, hitDepthDirection) = ("
457 << dir.m_etaDirection <<", "
458 << dir.m_phiDirection <<", "
459 << dir.m_depthDirection <<")");
460 }
461 }
462 #endif
463
464 // Initialize various cached members, needs to be done here otherwise the necessary transforms are not yet initialized
465 // The unit vectors
466 cache.m_normal = cache.m_transform.linear() * localRecoDepthAxis;
467
468 cache.m_phiAxis = cache.m_transform.linear() * localRecoPhiAxis;
469 cache.m_etaAxis = cache.m_transform.linear() * localRecoEtaAxis;
470
471 //Check where these are actually needed - candidates for removal?
472 cache.m_phiAxisCLHEP = HepGeom::Vector3D<double>(cache.m_phiAxis[0],cache.m_phiAxis[1],cache.m_phiAxis[2]);
473 cache.m_etaAxisCLHEP = HepGeom::Vector3D<double>(cache.m_etaAxis[0],cache.m_etaAxis[1],cache.m_etaAxis[2]);
474
475 getExtent(cache);
476 m_cache.set (std::move (cache));
477 }
478
479 // Get min/max or r, z,and phi
480 // helper method only to be used for the cache construction
481 // i.e inside updateCache
482 void
484 {
485 Amg::Vector3D sensorCenter = m_design->sensorCenter();
486 double radialShift = sensorCenter[0];//in sensor frame, x is radius
487
488 HepGeom::Point3D<double> corners[4];
489 getCorners(corners);
490
491 bool first = true;
492
493 double phiOffset = 0.;
494
495
496 const HepGeom::Transform3D rShift = HepGeom::TranslateY3D(radialShift);//in local frame, radius is y=distEta
497
498 for (auto & corner : corners) {
499
500 corner.transform(rShift);
501
502 // m_tranform is already there as part of the cache construction
503 // This method seems to be used only as a helper for updateCache
504 HepGeom::Point3D<double> globalPoint = cache.m_transformCLHEP * corner;
505
506 double rPoint = globalPoint.perp();
507 double zPoint = globalPoint.z();
508 double phiPoint = globalPoint.phi();
509
510 // Use first point to initializa min/max values.
511 if (first) {
512
513 // Put phi in a range so that we are not near -180/+180 division.
514 // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg.
515 // This offset is later removed.
516 if (phiPoint < -0.5 * M_PI) {
517 phiOffset = -0.5 * M_PI;
518 } else if (phiPoint > 0.5 * M_PI) {
519 phiOffset = 0.5 * M_PI;
520 }
521 cache.m_minPhi = cache.m_maxPhi = phiPoint - phiOffset;
522 cache.m_minR = cache.m_maxR = rPoint;
523 cache.m_minZ = cache.m_maxZ = zPoint;
524
525 } else {
526 phiPoint -= phiOffset;
527 // put phi back in -M_PI < phi < +M_PI range
528 if (phiPoint < -M_PI) phiPoint += 2. * M_PI;
529 if (phiPoint > M_PI) phiPoint -= 2. * M_PI;
530 cache.m_minPhi = std::min(cache.m_minPhi, phiPoint);
531 cache.m_maxPhi = std::max(cache.m_maxPhi, phiPoint);
532 cache.m_minR = std::min(cache.m_minR, rPoint);
533 cache.m_maxR = std::max(cache.m_maxR, rPoint);
534 cache.m_minZ = std::min(cache.m_minZ, zPoint);
535 cache.m_maxZ = std::max(cache.m_maxZ, zPoint);
536 }
537 first = false;
538 }
539
540 // put phi back in -M_PI < phi < +M_PI range
541 cache.m_minPhi += phiOffset;
542 cache.m_maxPhi += phiOffset;
543 if (cache.m_minPhi < -M_PI) cache.m_minPhi += 2. * M_PI;
544 if (cache.m_minPhi > M_PI) cache.m_minPhi -= 2. * M_PI;
545 if (cache.m_maxPhi < -M_PI) cache.m_maxPhi += 2. * M_PI;
546 if (cache.m_maxPhi > M_PI) cache.m_maxPhi -= 2. * M_PI;
547
548 }
549
550 void
551 SolidStateDetectorElementBase::getCorners(HepGeom::Point3D<double>* corners) const
552 {
553 // This makes the assumption that the forward SCT detectors are orientated such that
554 // the positive etaAxis corresponds to the top of the detector where the width is largest.
555 // This is currently always the case.
556 // For the SCT barrel and pixel detectors minWidth and maxWidth are the same and so should
557 // work for all orientations.
558
559 double tmpMinWidth = minWidth();
560 double tmpMaxWidth = maxWidth();
561 double tmpLength = length();
562
563 // Lower left
564 corners[0][distPhi] = -0.5 * tmpMinWidth;
565 corners[0][distEta] = -0.5 * tmpLength;
566 corners[0][distDepth] = 0.;
567
568 // Lower right
569 corners[1][distPhi] = 0.5 * tmpMinWidth;
570 corners[1][distEta] = -0.5 * tmpLength;
571 corners[1][distDepth] = 0.;
572
573 // Upper Right
574 corners[2][distPhi] = 0.5 * tmpMaxWidth;
575 corners[2][distEta] = 0.5 * tmpLength;
576 corners[2][distDepth] = 0.;
577
578 // Upper left
579 corners[3][distPhi] = -0.5 * tmpMaxWidth;
580 corners[3][distEta] = 0.5 * tmpLength;
581 corners[3][distDepth] = 0.;
582 }
583
584 // Gets eta phi for a point given in local coordinates. deltaZ is specified to
585 // account for the vertex spread. phi is independent of this vertex
586 // spread. etaMax will correspond to zMin (-deltaZ) and etaMin will
587 // correspond to zMax (+deltaZ).
588 void
589 SolidStateDetectorElementBase::getEtaPhiPoint(const HepGeom::Point3D<double>& point, double deltaZ,
590 double& etaMin, double& etaMax, double& phi) const
591 {
592 // Get the point in global coordinates.
593 HepGeom::Point3D<double> globalPoint = globalPosition(point);
594
595 double r = globalPoint.perp();
596 double z = globalPoint.z();
597
598 double thetaMin = std::atan2(r,(z + deltaZ));
599 etaMax = -std::log(tan(0.5 * thetaMin));
600 double thetaMax = std::atan2(r,(z - deltaZ));
601 etaMin = -std::log(tan(0.5 * thetaMax));
602
603 phi = globalPoint.phi();
604 }
605 //TODO: can we make this Amg??? Save some back/forth conversions elsewhere...
606 const HepGeom::Transform3D
608 {
609 if (!m_axisDir.isValid()) updateCache();
610 const AxisDir& dir = *m_axisDir.ptr();
611
612 // = transfromHit * hitLocal
613 // = transformHit * recoToHitTransform * recoLocal
614 // recoToHitTransform takes recoLocal to hitLocal
615 // x,y,z -> y,z,x
616 // equiv to a rotation around Y of 90 deg followed by a rotation around X of 90deg
617 //
618 // recoToHit is static as it needs to be calculated once only.
619 // We use the HepGeom::Transform3D constructor which takes one coordinates system to another where the
620 // coordinate system is defined by it center and two axes.
621 // distPhi, distEta are the reco local axes and hitPhi and hitEta are the hit local axes.
622 // It assume phi, eta, depth makes a right handed system which is the case.
623 static const HepGeom::Vector3D<double> localAxes[3] = {
624 HepGeom::Vector3D<double>(1., 0., 0.),
625 HepGeom::Vector3D<double>(0., 1., 0.),
626 HepGeom::Vector3D<double>(0., 0., 1.)
627 };
628
629 //correct phi and eta as necessary - do not change depth, this will be defined by the transform based on the other two
630 int signPhi = dir.m_phiDirection? +1:-1;
631 int signEta = dir.m_etaDirection? +1:-1;
632
633 const HepGeom::Transform3D recoToHit(HepGeom::Point3D<double>(0., 0., 0.),
634 signPhi * localAxes[distPhi],
635 signEta *localAxes[distEta],
636 HepGeom::Point3D<double>(0., 0., 0.),
637 localAxes[m_hitPhi],
638 localAxes[m_hitEta]);
639
640 return recoToHit ;
641
642 }
643
644
645} // namespace InDetDD
#define M_PI
Scalar phi() const
phi method
#define ATH_MSG_ERROR(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