ATLAS Offline Software
Loading...
Searching...
No Matches
SiDetElementsLayer_xk.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Implementation file for class SiDetElemenstLauerLxk
8// (c) ATLAS Detector software
10//
12// Version 1.0 21/04/2004 I.Gavrilenko
14
15#include <cmath>
16
20
22// Get barrel detector elements
23// Input parameters: startPoint[0] - X searchDirection[0] - Ax
24// startPoint[1] - Y searchDirection[1] - Ay
25// startPoint[2] - Z searchDirection[2] - Az
26// startPoint[3] - R
27// startPoint[4] - width
28// startPoint[5] - step
30
32(const std::array<float,6> & startingPoint,
33 const std::array<float,3> & searchDirection,
34 std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
35 std::vector<bool> &used) const
36{
37 // Tell clang to optimize assuming that FP exceptions can trap.
38 // Otherwise, it can vectorize the division, which can lead to
39 // spurious division-by-zero traps from unused vector lanes.
41
45 float minusB =2*( searchDirection[0]*startingPoint[0]
46 +searchDirection[1]*startingPoint[1]);
47 float C = (m_r-startingPoint[0]-startingPoint[1])
48 *(m_r+startingPoint[0]+startingPoint[1])
49 +2.*startingPoint[0]*startingPoint[1];
50 float twoA = 2.*( searchDirection[0]*searchDirection[0]
51 +searchDirection[1]*searchDirection[1]);
52 if(twoA == 0.) return;
53 float sq = minusB*minusB+2.*C*twoA;
54 if (sq > 0){
55 sq=std::sqrt(sq);
56 }
57 else {
58 sq=0.;
59 }
61 float s1 =-(minusB+sq)/twoA;
62 float s2 =-(minusB-sq)/twoA;
63 float s;
67 if((s1*s2) > 0.) {
68 s = (std::abs(s1) < std::abs(s2) ? s1 : s2);
69 }
71 else{
72 s = (s1 > 0. ? s1 : s2);
73 }
75 float zc = startingPoint[2]+searchDirection[2]*s;
77 float At = std::sqrt(1.-searchDirection[2]*searchDirection[2]);
78
84 if(At != 0. && std::abs(zc-m_z) > (m_dz+(m_dr*std::abs(searchDirection[2])+startingPoint[4])/At)) return;
86 float phiCrossing = std::atan2(startingPoint[1]+searchDirection[1]*s,startingPoint[0]+searchDirection[0]*s);
88 float reducedRoadWidth = startingPoint[4]/m_r;
89 getDetElements(startingPoint,searchDirection,phiCrossing,reducedRoadWidth,lDE,used);
90
91}
92
93
95(const std::array<float,6> & startingPoint,
96 const std::array<float,3> & searchDirection,
97 std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
98 std::vector<bool> &used) const
99{
100 constexpr float pi = M_PI;
101 constexpr float pi2 = 2.*pi;
102
106 float minusB =2*( searchDirection[0]*startingPoint[0]
107 +searchDirection[1]*startingPoint[1]);
108 float C = (m_r-startingPoint[0]-startingPoint[1])
109 *(m_r+startingPoint[0]+startingPoint[1])
110 +2.*startingPoint[0]*startingPoint[1];
111 float twoA = 2.*( searchDirection[0]*searchDirection[0]
112 +searchDirection[1]*searchDirection[1]);
113 if(twoA == 0.) return;
114 float sq = minusB*minusB+2.*C*twoA;
115 if (sq > 0){
116 sq=std::sqrt(sq);
117 }
118 else {
119 sq=0.;
120 }
122 float s1 =-(minusB+sq)/twoA;
123 float s2 =-(minusB-sq)/twoA;
124 float s;
128 if((s1*s2) > 0.) {
129 s = (std::abs(s1) < std::abs(s2) ? s1 : s2);
130 }
132 else{
133 s = (s1 > 0. ? s1 : s2);
134 }
136 float zc = startingPoint[2]+searchDirection[2]*s;
138 float At = std::sqrt(1.-searchDirection[2]*searchDirection[2]);
139 float Sz = (m_dr*std::abs(searchDirection[2])+startingPoint[4])/At;
140
146 if(At != 0. && std::abs(zc-m_z) > (m_dz+Sz)) return;
148 float reducedRoadWidth = startingPoint[4]/m_r + m_dfe;
150 float phiCrossing = std::atan2(startingPoint[1]+searchDirection[1]*s,startingPoint[0]+searchDirection[0]*s) - reducedRoadWidth;
151 if(phiCrossing<-pi) phiCrossing += pi2;
152
153 int ie = m_elements.size();
154 int i1 = ie-1;
155
156 if (phiCrossing <= m_elements[ 0].phi()) i1 = 0 ;
157 else if(phiCrossing > m_elements[i1].phi()) i1 = ie;
158 else {
159 int i0=0;
160 while((i1-i0)>1) {
161 int i = (i0+i1)/2;
162 if (m_elements[i].phi() > phiCrossing) i1=i;
163 else i0=i;
164 }
165 }
166
167 phiCrossing += 2.*reducedRoadWidth;
168
169 for(int i = i1; i!=ie; ++i) {
170
171 if( m_elements[i].phi() > phiCrossing ) return;
172
173 if(std::abs(zc-m_elements[i].z()) < (m_elements[i].dz()+Sz)
174 && m_elements[i].intersectITk(&(startingPoint[0]),&(searchDirection[0]),s)) {
175 lDE.emplace_back(&m_elements[i],s,0); //distance not used for ITk?
176 used[i]=true;
177 }
178 }
179
180 phiCrossing -= pi2;
181
182 for(int i=0; i!=i1; ++i) {
183
184 if( m_elements[i].phi() > phiCrossing) return;
185
186 if(std::abs(zc-m_elements[i].z()) < (m_elements[i].dz()+Sz)
187 && m_elements[i].intersectITk(&(startingPoint[0]),&(searchDirection[0]),s)) {
188 lDE.emplace_back(&m_elements[i],s,0);
189 used[i]=true;
190 }
191 }
192
193}
194
195
197// Get endcap detector elements
198// Input parameters: startingPoint[0] - X searchDirection[0] - Ax
199// startingPoint[1] - Y searchDirection[1] - Ay
200// startingPoint[2] - Z searchDirection[2] - Az
201// startingPoint[3] - R
202// startingPoint[4] - width
203// startingPoint[5] - step
205
207(const std::array<float,6> & startingPoint,
208 const std::array<float,3> & searchDirection,
209 std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
210 std::vector<bool> &used) const
211{
214 float s =(m_z-startingPoint[2])/searchDirection[2];
216 float xc = startingPoint[0]+searchDirection[0]*s;
217 float yc = startingPoint[1]+searchDirection[1]*s;
218 float rc = std::sqrt(xc*xc+yc*yc);
220 float A23 = searchDirection[2]*startingPoint[3];
225 if(A23 != 0. && std::abs(rc-m_r) > m_dr+std::abs(2.*(startingPoint[0]*searchDirection[0]+startingPoint[1]*searchDirection[1])*m_dz/A23)+startingPoint[4]) return;
226 float phiCrossing = std::atan2(yc,xc);
227 float reducedRoadWidth = startingPoint[4]/rc;
228 getDetElements(startingPoint,searchDirection,phiCrossing,reducedRoadWidth,lDE,used);
229
230}
231
232
234(const std::array<float,6> & startingPoint,
235 const std::array<float,3> & searchDirection,
236 std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
237 std::vector<bool> &used) const
238{
239 constexpr float pi = M_PI;
240 constexpr float pi2 = 2.*pi;
241
244 float s =(m_z-startingPoint[2])/searchDirection[2];
246 float xc = startingPoint[0]+searchDirection[0]*s;
247 float yc = startingPoint[1]+searchDirection[1]*s;
248 float rc = std::sqrt(xc*xc+yc*yc);
250 float A23 = searchDirection[2]*startingPoint[3];
255 if(A23 != 0. && std::abs(rc-m_r) > m_dr+std::abs(2.*(startingPoint[0]*searchDirection[0]+startingPoint[1]*searchDirection[1])*m_dz/A23)+startingPoint[4]) return;
256 float reducedRoadWidth = startingPoint[4]/rc + m_dfe;
257 float phiCrossing = std::atan2(yc,xc)-reducedRoadWidth;
258 if(phiCrossing<-pi) phiCrossing += pi2;
259
260 int ie = m_elements.size();
261 int i1 = ie-1;
262
263 if (phiCrossing <= m_elements[ 0].phi()) i1 = 0 ;
264 else if(phiCrossing > m_elements[i1].phi()) i1 = ie;
265 else {
266 int i0=0;
267 while((i1-i0)>1) {
268 int i = (i0+i1)/2;
269 if (m_elements[i].phi() > phiCrossing) i1=i;
270 else i0=i;
271 }
272 }
273
274 phiCrossing += 2.*reducedRoadWidth;
275
276 for(int i = i1; i!=ie; ++i) {
277
278 if( m_elements[i].phi() > phiCrossing ) return;
279
280 if(m_elements[i].intersectITk(&(startingPoint[0]),&(searchDirection[0]),s)) {
281 lDE.emplace_back(&m_elements[i],s,0); //distance not used for ITk?
282 used[i]=true;
283 }
284 }
285
286 phiCrossing -= pi2;
287
288 for(int i=0; i!=i1; ++i) {
289
290 if( m_elements[i].phi() > phiCrossing) return;
291
292 if(m_elements[i].intersectITk(&(startingPoint[0]),&(searchDirection[0]),s)) {
293 lDE.emplace_back(&m_elements[i],s,0);
294 used[i]=true;
295 }
296 }
297
298}
299
300
302// Get detector elements
303// Input parameters: startingPoint[0] - X searchDirection[0] - Ax
304// startingPoint[1] - Y searchDirection[1] - Ay
305// startingPoint[2] - Z searchDirection[2] - Az
306// startingPoint[3] - R
307// startingPoint[4] - width
308// startingPoint[5] - step
310
312(const std::array<float,6> & startingPoint,
313 const std::array<float,3> & searchDirection,
314 float phiCrossing,
315 float reducedRoadWidth,
316 std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
317 std::vector<bool> &used) const
318{
319 constexpr float pi = M_PI;
320 constexpr float pi2 = 2.*pi;
321 int im = int(m_elements.size())-1;
322 if(im<0) return;
323 int i0 = 0;
324 int i1 = im;
325
327 if (phiCrossing> m_elements[i0].phi() && phiCrossing< m_elements[i1].phi()) {
328 while((i1-i0)>1) {
329 int i = (i0+i1)/2;
330 if (m_elements[i].phi() > phiCrossing){
331 i1=i;
332 }
333 else{
334 i0=i;
335 }
336 }
337 i0 = i1;
338 }
339 //
340 std::array<float,3> intersectionOutcome{};
341 int i = i0;
343 while(1) {
344 assert( static_cast<unsigned int>(i)<m_elements.size() );
346 if(!used[i]) {
348 float dPhi =std::abs(m_elements[i].phi()-phiCrossing);
349 if(dPhi>pi) dPhi=std::abs(dPhi-pi2);
350
353 if((dPhi-reducedRoadWidth)>m_dfe) break;
354
359 m_elements[i].intersect(&(startingPoint[0]),&(searchDirection[0]),&(intersectionOutcome[0]));
360
362 if ( intersectionOutcome[0]<=startingPoint[4]
363 && (intersectionOutcome[1]<=startingPoint[4])
364 ) {
366 lDE.emplace_back(&m_elements[i],startingPoint[5]+intersectionOutcome[2],std::max(intersectionOutcome[0],intersectionOutcome[1]));
367 used[i]=true;
368 }
369 }
370 ++i;
371 if(i>im) i=0;
372 if(i==i0) return;
373 }
375 i1 = i; i = i0;
376 while(1) {
378 --i;
380 if(i<0) i=im;
382 if(i==i1) return;
383 assert( static_cast<unsigned int>(i)<m_elements.size() );
384 if(!used[i]) {
385 float dPhi =std::abs(m_elements[i].phi()-phiCrossing);
386 if(dPhi>pi) dPhi=std::abs(dPhi-pi2);
387 if((dPhi-reducedRoadWidth)>m_dfe) return;
388 m_elements[i].intersect(&(startingPoint[0]),&(searchDirection[0]),&(intersectionOutcome[0]));
389
390 if((intersectionOutcome[0]-startingPoint[4])<=0 && (intersectionOutcome[1]-startingPoint[4])<=0.) {
391 lDE.emplace_back(&m_elements[i],startingPoint[5]+intersectionOutcome[2],std::max(intersectionOutcome[0],intersectionOutcome[1]));
392 used[i]=true;
393 }
394 }
395 }
396}
397
399// Sort detector elements in azimuthal angle order
401
406
#define M_PI
Scalar phi() const
phi method
#define sq(x)
static Double_t rc
#define pi
void getITkBarrelDetElements(const std::array< float, 6 > &startingPoint, const std::array< float, 3 > &searchDirection, std::vector< InDet::SiDetElementLink_xk::ElementWay > &lDE, std::vector< bool > &used) const
void getDetElements(const std::array< float, 6 > &startingPoint, const std::array< float, 3 > &searchDirection, float phiCrossing, float reducedRoadWidth, std::vector< InDet::SiDetElementLink_xk::ElementWay > &lDE, std::vector< bool > &used) const
internal helper which resolves the phi-multiplicity of elements within a layer.
std::vector< SiDetElementLink_xk > m_elements
void getEndcapDetElements(const std::array< float, 6 > &startingPoint, const std::array< float, 3 > &searchDirection, std::vector< InDet::SiDetElementLink_xk::ElementWay > &lDE, std::vector< bool > &used) const
void getBarrelDetElements(const std::array< float, 6 > &startingPoint, const std::array< float, 3 > &searchDirection, std::vector< InDet::SiDetElementLink_xk::ElementWay > &lDE, std::vector< bool > &used) const
Get barrel detector elements Input parameters: startPoint[0] - X searchDirection[0] - Ax startPoint[1...
void getITkEndcapDetElements(const std::array< float, 6 > &startingPoint, const std::array< float, 3 > &searchDirection, std::vector< InDet::SiDetElementLink_xk::ElementWay > &lDE, std::vector< bool > &used) const
holding In fact this class is here in order to allow STL container for all features This class is sho...
struct color C
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24