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