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