ATLAS Offline Software
Loading...
Searching...
No Matches
RectangularSegmentation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// RectangularSegmentation.cxx, ATLAS Detector software
8
9
13// Amg includes
15
16Trk::RectangularSegmentation::RectangularSegmentation(std::shared_ptr<const Trk::RectangleBounds> mBounds,
17 size_t numCellsX, size_t numCellsY) :
18 m_activeBounds(std::move(mBounds)),
19 m_binUtility(nullptr),
22{
23 // first the x dimension if needed
24 if (numCellsX > 1)
26 // use y dimension if needed
27 if (numCellsY > 1){
28 Trk::BinUtility yBinUtility(numCellsY, -m_activeBounds->halflengthY(), m_activeBounds->halflengthY(), Trk::open, Trk::binY);
29 if (m_binUtility)
30 (*m_binUtility) += yBinUtility;
31 else
32 m_binUtility = new Trk::BinUtility(std::move(yBinUtility));
33 }
34}
35
37Trk::RectangularSegmentation::RectangularSegmentation(std::shared_ptr<const Trk::RectangleBounds> mBounds, size_t numCellsX, double longY, size_t numCellsY, double numberOfChip):
38 m_activeBounds(std::move(mBounds)),
39 m_binUtility(nullptr),
42{
43 // first the x dimension if needed
44 if (numCellsX > 1)
46 // use y dimension if needed
47 if (numCellsY > 1){
48
49 int numCellsYinChip = numCellsY/numberOfChip;
50 double begin = -m_activeBounds->halflengthY();
51 double end = (2. * m_activeBounds->halflengthY() / numberOfChip) - m_activeBounds->halflengthY();
52 std::vector<float> boundaries;
53
54 boundaries.push_back(begin);
55
56 for (int i = 0; i< numberOfChip; i++){
57 Trk::BinUtility SmallBinUtility((size_t) numCellsYinChip-2, begin+longY, end-longY, Trk::open, Trk::binY);
58
59
60 boundaries.insert(boundaries.end(), SmallBinUtility.binningData().at(0).boundaries.begin(), SmallBinUtility.binningData().at(0).boundaries.end());
61 boundaries.push_back(end);
62
63 begin=end;
64 end+=(2 * m_activeBounds->halflengthY() / numberOfChip);
65
66 }
67
68
69 if (boundaries.size() != numCellsY+1) {
70 throw std::runtime_error("RectangularSegmentation: invalid numCellsY");
71 }
72
73 Trk::BinUtility yBinUtility(boundaries, Trk::open, Trk::binY);
74 if (m_binUtility)
75 (*m_binUtility) += yBinUtility;
76 else
77 m_binUtility = new Trk::BinUtility(std::move(yBinUtility));
78
79 boundaries.clear();
80 }
81}
82
83
88
89void Trk::RectangularSegmentation::createSegmenationSurfaces(std::vector< std::shared_ptr< const Trk::Surface> >& boundarySurfaces,
90 std::vector< std::shared_ptr< const Trk::Surface> >& segmentationSurfacesX,
91 std::vector< std::shared_ptr< const Trk::Surface> >& segmentationSurfacesY,
92 double halfThickness,
93 int readoutDirection,
94 double lorentzAngle) const
95{
96 // may be needed throughout
97 double lorentzAngleTan = std::tan(lorentzAngle);
98 double lorentzPlaneShiftX = halfThickness*lorentzAngleTan;
99
100 // (A) --- top/bottom surfaces -----------------------------------------------------------
101 // let's create the top/botten surfaces first - we call them readout / counter readout
102 // there are some things to consider
103 // - they share the RectangleBounds only if the lorentzAngle is 0, otherwise only the readout surface has full length bounds like the module
104 std::shared_ptr<Trk::SurfaceBounds> moduleBounds = std::make_shared<Trk::RectangleBounds>(m_activeBounds->halflengthX(),m_activeBounds->halflengthY());
105 // - they are separated by half a thickness in z
106 Amg::Transform3D readoutPlaneTransform(Amg::Transform3D::Identity());
107 Amg::Transform3D counterPlaneTransform(Amg::Transform3D::Identity());
108 // readout and counter readout bounds, the bounds of the readout plane are like the active ones
109 std::shared_ptr<Trk::SurfaceBounds> readoutPlaneBounds = moduleBounds;
110 std::shared_ptr<Trk::SurfaceBounds> counterPlaneBounds(nullptr);
111 // the transform of the readout plane is always centric
112 readoutPlaneTransform.translation() = Amg::Vector3D(0.,0.,readoutDirection*halfThickness);
113 // no lorentz angle and everything is straight-forward
114 if (lorentzAngle == 0.){
115 counterPlaneBounds = std::move(moduleBounds);
116 counterPlaneTransform.translation() = Amg::Vector3D(0.,0.,-readoutDirection*halfThickness);
117 } else {
118 // lorentz reduced Bounds
119 double lorentzReducedHalfX = m_activeBounds->halflengthX() - std::abs(lorentzPlaneShiftX);
120 std::shared_ptr<Trk::SurfaceBounds> lorentzReducedBounds(std::make_shared<Trk::RectangleBounds>(lorentzReducedHalfX,m_activeBounds->halflengthY()));
121 counterPlaneBounds = std::move(lorentzReducedBounds);
122 // now we shift the counter plane in position - this depends on lorentz angle
123 double counterPlaneShift = -readoutDirection*lorentzPlaneShiftX;
124 counterPlaneTransform.translation() = Amg::Vector3D(counterPlaneShift,0.,-readoutDirection*halfThickness);
125 }
126 // - build the readout & counter readout surfaces
127 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(readoutPlaneTransform,readoutPlaneBounds));
128 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(counterPlaneTransform,counterPlaneBounds));
129
130 // (B) - bin X and lorentz surfaces -----------------------------------------------------------
131 // easy stuff first, constant pitch size and
132 double pitchX = 2.*m_activeBounds->halflengthX()/m_binsX;
133
134 // now, let's create the SharedBounds of all surfaces marking x bins - choice fixes orientation of the matrix
135 std::shared_ptr<Trk::SurfaceBounds> xBinBounds(std::make_shared<Trk::RectangleBounds>(m_activeBounds->halflengthY(),halfThickness));
136 // now, let's create the SharedBounds of all surfaces marking lorentz planes
137 double lorentzPlaneHalfX = std::abs(halfThickness/std::cos(lorentzAngle));
138 // the bounds of the lorentz plane
139 std::shared_ptr<Trk::SurfaceBounds> lorentzPlaneBounds = (lorentzAngle==0.) ? xBinBounds :
140 std::shared_ptr<Trk::SurfaceBounds>(std::make_shared<Trk::RectangleBounds>(m_activeBounds->halflengthY(),lorentzPlaneHalfX));
141
142 // now the rotation matrix for the xBins
143 Amg::RotationMatrix3D xBinRotationMatrix;
144 xBinRotationMatrix.col(0) = Amg::Vector3D::UnitY();
145 xBinRotationMatrix.col(1) = Amg::Vector3D::UnitZ();
146 xBinRotationMatrix.col(2) = Amg::Vector3D::UnitX();
147 // now the lorentz plane rotation should be the xBin rotation, rotated by the lorentz angle around y
148 Amg::RotationMatrix3D lorentzPlaneRotationMatrix = (lorentzAngle !=0.) ?
149 xBinRotationMatrix * Amg::AngleAxis3D(lorentzAngle, Amg::Vector3D::UnitX()) : xBinRotationMatrix;
150
151 // reserve, it's always (number of bins-1) as the boundaries are within the boundarySurfaces
152 segmentationSurfacesX.reserve(m_binsX);
153 for (size_t ibinx = 0; ibinx <= m_binsX; ++ibinx){
154 // the current step x position
155 double cPosX = -m_activeBounds->halflengthX()+ibinx*pitchX;
156 // (i) this is the low/high boundary --- ( ibin == 0/m_binsX )
157 if (!ibinx || ibinx == m_binsX){
158 // check if it a straight boundary or not: always straight for no lorentz angle, and either the first boundary or the last dependening on lorentz & readout
159 bool boundaryStraight = (lorentzAngle == 0. || (!ibinx && readoutDirection*lorentzAngle > 0.) || (ibinx==m_binsX && readoutDirection*lorentzAngle < 0));
160 // set the low boundary parameters : position & rotation
161 Amg::Vector3D boundaryXPosition = boundaryStraight ? Amg::Vector3D(cPosX, 0.,0.) : Amg::Vector3D(cPosX-readoutDirection*lorentzPlaneShiftX, 0., 0.);
162 const Amg::RotationMatrix3D& boundaryXRotation = boundaryStraight ? xBinRotationMatrix : lorentzPlaneRotationMatrix;
163 // build the rotation from it
164 Amg::Transform3D boundaryXTransform(Amg::getTransformFromRotTransl(boundaryXRotation, boundaryXPosition));
165 // the correct bounds for this
166 std::shared_ptr<Trk::SurfaceBounds> boundaryXBounds = boundaryStraight ? xBinBounds : lorentzPlaneBounds;
167 // boundary surfaces
168 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(boundaryXTransform,boundaryXBounds));
169 // (ii) this is the in between bins --- ( 1 <= ibin < m_mbnsX )
170 } else {
171 // shift by the lorentz angle
172 Amg::Vector3D lorentzPlanePosition(cPosX-readoutDirection*lorentzPlaneShiftX, 0., 0.);
173 Amg::Transform3D lorentzPlaneTransform(Amg::getTransformFromRotTransl(lorentzPlaneRotationMatrix,lorentzPlanePosition));
174 // lorentz plane surfaces
175 segmentationSurfacesX.push_back(std::make_shared<Trk::PlaneSurface>(lorentzPlaneTransform,lorentzPlaneBounds));
176 }
177 }
178
179 // (C) - bin Y surfaces - everything is defined -----------------------------------------------------------
180 // now the rotation matrix for the yBins - anticyclic
181 Amg::RotationMatrix3D yBinRotationMatrix;
182 yBinRotationMatrix.col(0) = Amg::Vector3D::UnitX();
183 yBinRotationMatrix.col(1) = Amg::Vector3D::UnitZ();
184 yBinRotationMatrix.col(2) = Amg::Vector3D(0.,-1.,0.);
185 // easy stuff first, constant pitch in Y
186 // let's create the SharedBounds of all surfaces marking y bins
187 std::shared_ptr<Trk::SurfaceBounds> yBinBounds(std::make_shared<Trk::RectangleBounds>(m_activeBounds->halflengthX(),halfThickness));
188 // reserve, it's always (number of bins-1) as the boundaries are within the boundarySurfaces
189 segmentationSurfacesY.reserve(m_binsY);
190 for (size_t ibiny = 0; ibiny <= m_binsY; ++ibiny){
191 // the position of the bin surface
192 //Use the bin utility to find center of different surfaces
193 double binPosY = m_binUtility->binningData().at(1).boundaries[ibiny];
194 Amg::Vector3D binSurfaceCenter(0.,binPosY,0.);
195 Amg::Transform3D binTransform(Amg::getTransformFromRotTransl(yBinRotationMatrix,binSurfaceCenter));
196 // these are the boundaries
197 if (ibiny == 0 || ibiny == m_binsY)
198 boundarySurfaces.push_back(std::make_shared<const Trk::PlaneSurface>(binTransform,yBinBounds));
199 else // these are the bin boundaries
200 segmentationSurfacesY.push_back(std::make_shared<const Trk::PlaneSurface>(binTransform,yBinBounds));
201 }
202}
203
204
206{
207
208 // use the bin utility for this job
209 double bX = m_binsX ? m_binUtility->binPosition(dCell.first,0.,0) : 0.;
210 double bY = m_binsY ? m_binUtility->binPosition(dCell.second,0.,1) : 0.;
211 return Amg::Vector2D(bX,bY);
212}
213
214
217 const Amg::Vector3D& endStep,
218 double halfThickness,
219 int readoutDirection,
220 double lorentzAngle) const
221{
222 Amg::Vector3D stepCenter = 0.5*(startStep+endStep);
223 // take the full drift length
224 // this is the absolute drift in z
225 double driftInZ = halfThickness-readoutDirection*stepCenter.z();
226 // this is the absolute drift length
227 double driftLength = driftInZ/cos(lorentzAngle);
228 // project to parameter the readout surface
229 double lorentzDeltaX = readoutDirection*driftInZ*tan(lorentzAngle);
230 // the projected center, it has the lorentz shift applied
231 Amg::Vector2D stepCenterProjected(stepCenter.x()+lorentzDeltaX,stepCenter.y());
232 // the cell & its center
233 Trk::DigitizationCell dCell = cell(stepCenterProjected);
234 Amg::Vector2D cellCenter = cellPosition(dCell);
235 // we are ready to return what we have
236 return Trk::DigitizationStep((endStep-startStep).mag(),driftLength,dCell,startStep,endStep,stepCenterProjected,cellCenter);
237}
238
239
240
241
242
Scalar mag() const
mag method
if(pathvar)
A generic symmetric BinUtility, for fully symmetric binning in terms of binning grid and binning type...
Definition BinUtility.h:39
const std::vector< BinningData > & binningData() const
return the binning data
Definition BinUtility.h:123
const DigitizationCell cell(const Amg::Vector3D &position) const override
Get the digitization cell fropm a 3D position - ignores the shift.
virtual ~RectangularSegmentation()
Virtual Destructor.
const Amg::Vector2D cellPosition(const DigitizationCell &cId) const override
calculate the cell Position from the Id
const SurfaceBounds & moduleBounds() const override
return the surface bounds by reference
size_t numCellsY() const
Return the simple binning parameters.
const DigitizationStep digitizationStep(const Amg::Vector3D &start, const Amg::Vector3D &end, double halfThickness, int readoutDirection=1, double lorentzAngle=0.) const override
Fill the associated digitsation cell from this start and end position, correct for lorentz effect if ...
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.
size_t numCellsX() const
Return the simple binning parameters.
RectangularSegmentation(std::shared_ptr< const Trk::RectangleBounds >, size_t numCellsX, size_t numCellsY=1)
Constructor for all same-size pixels or strips (in cas numCellsY is set to 1).
std::shared_ptr< const RectangleBounds > m_activeBounds
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.