ATLAS Offline Software
Loading...
Searching...
No Matches
TrapezoidSegmentation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TrapezoidSegmentation.cxx, ATLAS Detector software
8
9// Trk includes
10#include <memory>
11
12
13
18// Amg includes
20
21Trk::TrapezoidSegmentation::TrapezoidSegmentation(std::shared_ptr<const Trk::TrapezoidBounds> mBounds,
22 size_t numCellsX, size_t numCellsY) :
23 m_activeBounds(std::move(mBounds)),
24 m_binUtility(nullptr),
27{
28 // first the x dimension if needed
29 if (numCellsX > 1) {
30 m_binUtility = new Trk::BinUtility(numCellsX, -0.5*(m_activeBounds->minHalflengthX()+m_activeBounds->maxHalflengthX()), 0.5*(m_activeBounds->minHalflengthX()+m_activeBounds->maxHalflengthX()), Trk::open, Trk::binX);
31 }
32 // use y dimension if needed
33 if (numCellsY > 1){
34 Trk::BinUtility yBinUtility(numCellsY, -m_activeBounds->halflengthY(), m_activeBounds->halflengthY(), Trk::open, Trk::binY);
35 if (m_binUtility)
36 (*m_binUtility) += yBinUtility;
37 else
38 m_binUtility = new Trk::BinUtility(yBinUtility);
39 }
40}
41
46
47void Trk::TrapezoidSegmentation::createSegmenationSurfaces(std::vector< std::shared_ptr< const Trk::Surface> >& boundarySurfaces,
48 std::vector< std::shared_ptr< const Trk::Surface> >& segmentationSurfacesX,
49 std::vector< std::shared_ptr< const Trk::Surface> >& segmentationSurfacesY,
50 double halfThickness,
51 int readoutDirection,
52 double) const
53{
54 // The Lorentz angle is not taken into account for trapezoidal segmentation
55 // (A) --- top/bottom surfaces -----------------------------------------------------------
56 // let's create the top/botten surfaces first - we call them readout / counter readout
57 // there are some things to consider
58 // - they share only the readout surface, then the segmentation surfaces are tilted and cannot be shared on the same module
59 std::shared_ptr<Trk::TrapezoidBounds> readoutPlaneBounds =
60 std::make_shared<Trk::TrapezoidBounds>(m_activeBounds->minHalflengthX(),
61 m_activeBounds->maxHalflengthX(),
62 m_activeBounds->halflengthY());
63 // - they are separated by half a thickness in z
64 Amg::Transform3D readoutPlaneTransform(Amg::Transform3D::Identity());
65 Amg::Transform3D counterPlaneTransform(Amg::Transform3D::Identity());
66 // readout and counter readout bounds, the bounds of the readout plane are like the active ones
67 // the transform of the readout plane is always centric
68 readoutPlaneTransform.translation() = Amg::Vector3D(0.,0.,readoutDirection*halfThickness);
69 // no lorentz angle and everything is straight-forward
70 std::shared_ptr<Trk::TrapezoidBounds> counterPlaneBounds = readoutPlaneBounds;
71 counterPlaneTransform.translation() = Amg::Vector3D(0.,0.,-readoutDirection*halfThickness);
72
73 // - build the readout & counter readout surfaces
74 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(readoutPlaneTransform,readoutPlaneBounds));
75 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(counterPlaneTransform,counterPlaneBounds));
76
77 // (B) - bin X -----------------------------------------------------------
78 // easy stuff first, constant pitch size and
79 double pitchX = 2.*(m_activeBounds->maxHalflengthX()+m_activeBounds->minHalflengthX())*0.5/m_binsX;
80
81 // now the rotation matrix for the xBins
82 Amg::RotationMatrix3D xBinRotationMatrix;
83 xBinRotationMatrix.col(0) = Amg::Vector3D::UnitY();
84 xBinRotationMatrix.col(1) = Amg::Vector3D::UnitZ();
85 xBinRotationMatrix.col(2) = Amg::Vector3D::UnitX();
86
87 // reserve, it's always (number of bins-1) as the boundaries are within the boundarySurfaces
88 segmentationSurfacesX.reserve(m_binsX);
89 for (size_t ibinx = 0; ibinx <= m_binsX; ++ibinx){
90 // the current step x position
91 double cPosX = -(m_activeBounds->minHalflengthX()+m_activeBounds->maxHalflengthX())*0.5+ibinx*pitchX;
92
93 // set position & rotation for all (boundaries and segmentations) --> Then you separate between them
94 Amg::Vector3D xPosition = Amg::Vector3D(cPosX, 0.,0.);
95 double stereoLocal = asin(sinStereoLocal(Amg::Vector2D(cPosX, 0.)));
96 const Amg::RotationMatrix3D xRotation = xBinRotationMatrix*Amg::AngleAxis3D(stereoLocal, Amg::Vector3D::UnitY());
97 // build the rotation from it
98 Amg::Transform3D binTransform(Amg::getTransformFromRotTransl(xRotation, xPosition));
99 // the correct bounds for this
100 auto xBinBounds = std::make_shared<Trk::RectangleBounds>(m_activeBounds->halflengthY()/cos(stereoLocal),halfThickness);
101 // these are the boundaries
102 if (ibinx==0 || ibinx == m_binsX) // (i) this is the low/high boundary --- ( ibin == 0/m_binsX )
103 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(binTransform, xBinBounds));
104 else // these are the bin boundaries
105 segmentationSurfacesX.push_back(std::make_shared<Trk::PlaneSurface>(binTransform, xBinBounds));
106 }
107
108 // (C) - bin Y surfaces - everything is defined -----------------------------------------------------------
109 // now the rotation matrix for the yBins - anticyclic
110 Amg::RotationMatrix3D yBinRotationMatrix;
111 yBinRotationMatrix.col(0) = Amg::Vector3D::UnitX();
112 yBinRotationMatrix.col(1) = Amg::Vector3D::UnitZ();
113 yBinRotationMatrix.col(2) = Amg::Vector3D(0.,-1.,0.);
114 // easy stuff first, constant pitch in Y
115 double pitchY = 2.*m_activeBounds->halflengthY()/m_binsY;
116 // reserve, it's always (number of bins-1) as the boundaries are within the boundarySurfaces
117 segmentationSurfacesY.reserve(m_binsY);
118 for (size_t ibiny = 0; ibiny <= m_binsY; ++ibiny){
119 // the position of the bin surface
120 double binPosY = -m_activeBounds->halflengthY()+ibiny*pitchY;
121 Amg::Vector3D binSurfaceCenter(0.,binPosY,0.);
122 double localPitchX = PitchX(Amg::Vector2D(0., binPosY));
123 auto yBinBounds = std::make_shared<Trk::RectangleBounds>(localPitchX*m_binsX*0.5,halfThickness);
124 Amg::Transform3D binTransform(Amg::getTransformFromRotTransl(yBinRotationMatrix,binSurfaceCenter));
125 // these are the boundaries
126 if (ibiny == 0 || ibiny == m_binsY)
127 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(binTransform,yBinBounds));
128 else // these are the bin boundaries
129 segmentationSurfacesY.push_back(std::make_shared<const Trk::PlaneSurface>(binTransform,yBinBounds));
130 }
131}
132
133
135{
136 // use the bin utility for this job
137 double bX = (m_binsX>1) ? m_binUtility->binPosition(projectLocX(Amg::Vector2D(dCell.first, dCell.second)),0.,0) : 0.;
138 double bY = (m_binsY>1) ? m_binUtility->binPosition(dCell.second,0.,1) : 0.;
139 return Amg::Vector2D(bX,bY);
140}
141
142
145 const Amg::Vector3D& endStep,
146 double halfThickness,
147 int readoutDirection,
148 double lorentzAngle) const
149{
150
151 Amg::Vector3D stepCenter = 0.5*(startStep+endStep);
152 // project to parameter surface
153 double lorentzDeltaX = -readoutDirection*stepCenter.z()*std::tan(lorentzAngle);
154 // take the full drift length
155 double driftInZ = (halfThickness-readoutDirection*stepCenter.z());
156 double driftLength = std::abs(driftInZ/std::cos(lorentzAngle));
157 // the projected center
158 Amg::Vector2D stepCenterProjected(stepCenter.x()+lorentzDeltaX,stepCenter.y());
159 // the cell & its center
160 Trk::DigitizationCell dCell = cell(stepCenterProjected);
161 Amg::Vector2D cellCenter = cellPosition(dCell);
162 // we are ready to return what we have
163 return Trk::DigitizationStep((endStep-startStep).mag(),driftLength,dCell,startStep,endStep,stepCenterProjected,cellCenter);
164}
165
166
167
168
169
Scalar mag() const
mag method
A generic symmetric BinUtility, for fully symmetric binning in terms of binning grid and binning type...
Definition BinUtility.h:39
double PitchX(const Amg::Vector2D &localPos) const
Return the local pitch X.
virtual ~TrapezoidSegmentation()
Virtual Destructor.
TrapezoidSegmentation(std::shared_ptr< const Trk::TrapezoidBounds >, size_t numCellsX, size_t numCellsY=1)
Constructor for all same-size pixels or strips (in case numCellsY is set to 1)
size_t numCellsY() const
Return the simple binning parameters.
void createSegmenationSurfaces(std::vector< std::shared_ptr< const Surface > > &boundarySurfaces, std::vector< std::shared_ptr< const Surface > > &segmentationSurfacesX, std::vector< std::shared_ptr< const Surface > > &segmentationSurfacesY, double halfThickness, int readoutDirection=1., double lorentzAngle=0.) const override
Create the segmentation surfaces in X.
double sinStereoLocal(const Amg::Vector2D &localPos) const
Return the local sinStereo.
double projectLocX(const Amg::Vector2D &localPos) const
Return the projected x value on the y=0.
size_t numCellsX() const
Return the simple binning parameters.
const Amg::Vector2D cellPosition(const DigitizationCell &cId) const override
calculate the cell Position from the Id
std::shared_ptr< const TrapezoidBounds > m_activeBounds
const DigitizationStep digitizationStep(const Amg::Vector3D &start, const Amg::Vector3D &end, double halfThickness, int readoutDirection=1, double lorentzAngle=0.) const override
Fill the associated digitisation cell from this start and end position, correct for lorentz effect if...
const DigitizationCell cell(const Amg::Vector3D &position) const override
Get the digitization cell from a 3D position - ignores the shift.
Eigen::AngleAxisd AngleAxis3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Amg::Transform3D getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec)
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
@ open
Definition BinningType.h:40
std::pair< size_t, size_t > DigitizationCell
@ binX
Definition BinningType.h:47
@ binY
Definition BinningType.h:48
STL namespace.