ATLAS Offline Software
Loading...
Searching...
No Matches
PixelDiodeMap.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// PixelDiodeMap.cxx
7// Implementation file for class PixelDiodeMap
9// (c) ATLAS Pixel Detector software
11// Version 4.2 14/08/2001 David Calvet
12// Modified: Grant Gorfine
14
18
19#include <algorithm>
20#include <cmath>
21#include <utility>
22
23namespace InDetDD {
24
25
26
27// Implicit constructor:
28PixelDiodeMap::PixelDiodeMap(std::shared_ptr<const PixelDiodeMatrix> matrix) :
29 m_matrix(std::move(matrix)),
30 m_generalLayout(false)
31{
32}
33
35= default;
36
37
39{
40 using std::abs;
41 using Trk::distPhi;
42 using Trk::distEta;
43
44 // Check that we are in the bounds of the top level matrix
45 // NB. edge is included in bounds.
46
47 double halfWidth = 0.5*width();
48 double halfLength = 0.5*length();
49 if ( (abs(localPos[distPhi]) > halfWidth) ||
50 (abs(localPos[distEta]) > halfLength) ) {
51 return {}; // Invalid Id.
52 }
53
54 // position relative to bottom left corner.
55 Amg::Vector2D relativePos = localPos + Amg::Vector2D(halfWidth, halfLength);
56
57 // The cellId returned will be added to this so we must start with 0,0.
58 SiCellId cellId(0,0);
59
60 const PixelDiodeMatrix *cell = m_matrix->cellIdOfPosition(relativePos, cellId);
61 // return invalid Id if there was a problem (don't expect this to be the case).
62 if (cell==nullptr) {
63 return {}; // Invalid id.
64 }
65
66 return cellId;
67
68}
69
70
71// Get diodes parameters (position and size):
74{
75
76 // Check we are in range
77
78 if (!cellId.isValid() ||
79 (cellId.phiIndex() < 0) ||
80 (cellId.phiIndex() >= m_matrix->phiCells()) ||
81 (cellId.etaIndex() < 0) ||
82 (cellId.etaIndex() >= m_matrix->etaCells())) {
83 return {};
84 }
85
86 //
87 // Position is relative to left bottom corner.
88 //
89 Amg::Vector2D position;
90 const PixelDiodeMatrix *cell = m_matrix->positionOfCell(cellId, position);
91 if (cell != nullptr) {
92
93 // get size
94 Amg::Vector2D size(cell->phiWidth(), cell->etaWidth());
95
96 // return parameters
97 return SiDiodesParameters(position,size);
98 }
99
100 // return something in case of failure.
101 return {};
102}
103
105 std::vector<SiCellId> &neighbours) const
106{
107 neighbours.clear();
108
109 if (!cellId.isValid()) return;
110
111 // If non regular layout revert to slower method
112 if (m_generalLayout) return neighboursOfCellGeneral(cellId, neighbours);
113
114 neighbours.reserve(8);
115 // neighbours easily determined from cell number
116 // normally 8 neighbours 4 edge and 4 corners
117
118 int phiIndex = cellId.phiIndex();
119 int etaIndex = cellId.etaIndex();
120
121 // M = minus
122 // P = plus
123 int phiM = phiIndex-1;
124 int phiP = phiIndex+1;
125 int etaM = etaIndex-1;
126 int etaP = etaIndex+1;
127
128 // -,0
129 if (phiM >= 0) neighbours.emplace_back(phiM,etaIndex);
130 // -,-
131 if (phiM >= 0 && etaM >= 0) neighbours.emplace_back(phiM,etaM);
132 // 0,-
133 if (etaM >= 0) neighbours.emplace_back(phiIndex,etaM);
134 // +,-
135 if (phiP < phiDiodes() && etaM >= 0) neighbours.emplace_back(phiP,etaM);
136 // +,0
137 if (phiP < phiDiodes()) neighbours.emplace_back(phiP,etaIndex);
138 // -,+
139 if (phiM >= 0 && etaP < etaDiodes()) neighbours.emplace_back(phiM,etaP);
140 // 0,+
141 if (etaP < etaDiodes()) neighbours.emplace_back(phiIndex,etaP);
142 // +,+
143 if (phiP < phiDiodes() && etaP < etaDiodes()) neighbours.emplace_back(phiP,etaP);
144}
145
146// Get the neighbouring PixelDiodes of a given PixelDiode:
147// This will work for more complex layouts such as bricking. Probably never really needed but
148// since the code was here I keep it available.
150 std::vector<SiCellId> &neighbours) const
151{
152 // extract the diode spatial parameters
153 const SiDiodesParameters params=parameters(cellId);
154 const SiLocalPosition diodeCenter=params.centre();
155 const SiLocalPosition diodeSize=params.width();
156 const double &centerColumn=diodeCenter.xColumn();
157 const double &centerRow=diodeCenter.xRow();
158 const double halfSizeColumn=diodeSize.xColumn()/2;
159 const double halfSizeRow=diodeSize.xRow()/2;
160
161 // parameter
162 const double epsilon=0.01;
163
164 // compute the points to check
165 const double left1=centerColumn-halfSizeColumn*(1+epsilon);
166 const double right1=centerColumn+halfSizeColumn*(1+epsilon);
167 const double left2=centerColumn-halfSizeColumn*(1-epsilon);
168 const double right2=centerColumn+halfSizeColumn*(1-epsilon);
169 const double top1=centerRow+halfSizeRow*(1+epsilon);
170 const double bot1=centerRow-halfSizeRow*(1+epsilon);
171 const double top2=centerRow+halfSizeRow*(1-epsilon);
172 const double bot2=centerRow-halfSizeRow*(1-epsilon);
173
174 // build the list of positions to check
175 std::vector<SiLocalPosition> positions;
176 positions.reserve(12);
177 SiLocalPosition position;
178 position.xRow(bot1); position.xColumn(left2); positions.push_back(position);
179 position.xRow(bot1); position.xColumn(left1); positions.push_back(position);
180 position.xRow(bot2); position.xColumn(left1); positions.push_back(position);
181 position.xRow(top2); position.xColumn(left1); positions.push_back(position);
182 position.xRow(top1); position.xColumn(left1); positions.push_back(position);
183 position.xRow(top1); position.xColumn(left2); positions.push_back(position);
184 position.xRow(bot1); position.xColumn(right2); positions.push_back(position);
185 position.xRow(bot1); position.xColumn(right1); positions.push_back(position);
186 position.xRow(bot2); position.xColumn(right1); positions.push_back(position);
187 position.xRow(top2); position.xColumn(right1); positions.push_back(position);
188 position.xRow(top1); position.xColumn(right1); positions.push_back(position);
189 position.xRow(top1); position.xColumn(right2); positions.push_back(position);
190
191 // build the list of neighbours
192 neighbours.reserve(8);
193
194 // loop on all positions to check
195 for(const auto & position : positions) {
196
197 // get the PixelDiode for this position
198 SiCellId cellId_neighb = cellIdOfPosition(position);
199
200 if (cellId.isValid()) {
201 // check if the diode is already in the list
202 //bool found=false;
203 std::vector<SiCellId>::const_iterator foundIter
204 = std::find(neighbours.begin(), neighbours.end(), cellId_neighb );
205
206 // If not found add this diode to the list
207 if (foundIter == neighbours.end()) neighbours.push_back(cellId_neighb);
208
209 }
210 }
211}
212
213
214// Compute the intersection length of two diodes:
216 const SiCellId &diode2) const
217{
218 if(!diode1.isValid() || !diode2.isValid()) return 0;
219 // If non regular layout revert to slower method
220 if (m_generalLayout) return intersectionLengthGeneral(diode1, diode2);
221
222 const SiLocalPosition size = parameters(diode1).width();
223
224 int phiIndexDelta = std::abs(diode1.phiIndex() - diode2.phiIndex());
225 int etaIndexDelta = std::abs(diode1.etaIndex() - diode2.etaIndex());
226
227 // Intersection length is just the length or width of the diode depending on which neighbour.
228 if (phiIndexDelta == 1 && etaIndexDelta == 0) return size.xEta();
229 if (phiIndexDelta == 0 && etaIndexDelta == 1) return size.xPhi();
230 // Will return 0 if it is a corner neighbour or if its not a neighbour or if they are oth the same diode.
231 return 0;
232}
233
234// Compute the intersection length of two diodes:
235// This will work for more complex layouts such as bricking. Probably never really needed but
236// since the code was here I keep it available.
238 const SiCellId &diode2) const
239
240{
241 const SiDiodesParameters params1=parameters(diode1);
242 const SiDiodesParameters params2=parameters(diode2);
243 const SiLocalPosition center1=params1.centre();
244 const SiLocalPosition center2=params2.centre();
245 const SiLocalPosition size1=params1.width();
246 const SiLocalPosition size2=params2.width();
247
248 // compute intersection length on column direction
249 const double intersectionColumn=intersectionLength1D(center1.xColumn(),
250 size1.xColumn(),
251 center2.xColumn(),
252 size2.xColumn());
253 // compute intersection length on row direction
254 const double intersectionRow=intersectionLength1D(center1.xRow(),
255 size1.xRow(),
256 center2.xRow(),
257 size2.xRow());
258
259 // return the real intersection
260 // (if both directions intersect, there is a problem)
261 if (intersectionColumn>0) {
262 if (intersectionRow>0) return 0;
263 return intersectionColumn;
264 } else {
265 return intersectionRow;
266 }
267}
268
269// Compute the intersection length along one direction:
270double PixelDiodeMap::intersectionLength1D(const double x1,const double dx1,
271 const double x2,const double dx2)
272{
273 // compute distance between the two centers
274 double distance=std::abs(x1-x2);
275
276 // compute theoretical intersection
277 double intersection=(dx1+dx2)/2-distance;
278
279 // if intersection if negative, no intersection
280 if (intersection<-1e-10) return intersection;
281 else if (intersection<1e-10) return 0;
282 else {
283 // intersection cannot exceed size
284 if (intersection>dx1) intersection=dx1;
285 if (intersection>dx2) intersection=dx2;
286 return intersection;
287 }
288}
289
290} // namespace InDetDD
291
static double intersectionLength1D(const double x1, const double dx1, const double x2, const double dx2)
Compute the intersection length along one direction: return 0 if no intersection x1,...
PixelDiodeMap(std::shared_ptr< const PixelDiodeMatrix > diodeMatrix)
Constructor from Diode matrix description.
bool m_generalLayout
Flag set to allow for dealing wth more general layouts.
~PixelDiodeMap()
Destructor.
double intersectionLength(const SiCellId &diode1, const SiCellId &diode2) const
Compute the intersection length of two diodes: return: the intersection length when the two diodes ar...
double intersectionLengthGeneral(const SiCellId &diode1, const SiCellId &diode2) const
Slower method.
std::shared_ptr< const PixelDiodeMatrix > m_matrix
diode matrix
void neighboursOfCell(const SiCellId &cellId, std::vector< SiCellId > &neighbours) const
Get the neighbouring PixelDiodes of a given PixelDiode: Cell for which the neighbours must be found L...
SiCellId cellIdOfPosition(const Amg::Vector2D &localPosition) const
cell id for a given local position
SiDiodesParameters parameters(const SiCellId &diodeId) const
Get diodes parameters (position and size):
void neighboursOfCellGeneral(const SiCellId &cellId, std::vector< SiCellId > &neighbours) const
Slower method.
Class used to describe the segmentation of the pixel and allow for conversion between cell id and pos...
Identifier for the strip or pixel cell.
Definition SiCellId.h:29
int phiIndex() const
Get phi index. Equivalent to strip().
Definition SiCellId.h:122
bool isValid() const
Test if its in a valid state.
Definition SiCellId.h:136
int etaIndex() const
Get eta index.
Definition SiCellId.h:114
Class to handle the position of the centre and the width of a diode or a cluster of diodes Version 1....
const SiLocalPosition & centre() const
position of the diodes centre:
const SiLocalPosition & width() const
width of the diodes:
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
double xColumn() const
positions for Pixel:
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Eigen::Matrix< double, 2, 1 > Vector2D
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
STL namespace.