Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SeedFinderUtils.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SeedFinderUtils.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 namespace Acts {
10 template <typename external_spacepoint_t>
13  const InternalSpacePoint<external_spacepoint_t>& spM, bool bottom) {
14  auto extractFunction =
16  -> std::array<float, 6> {
17  std::array<float, 6> output{obj.x(), obj.y(), obj.z(),
18  obj.radius(), obj.varianceR(), obj.varianceZ()};
19  return output;
20  };
21 
22  return transformCoordinates<InternalSpacePoint<external_spacepoint_t>>(
23  sp, spM, bottom, std::move(extractFunction));
24 }
25 
26 template <typename external_spacepoint_t, typename callable_t>
27 inline LinCircle transformCoordinates(const external_spacepoint_t& sp,
28  const external_spacepoint_t& spM,
29  bool bottom,
30  callable_t&& extractFunction) {
31  // The computation inside this function is exactly identical to that in the
32  // vectorized version of this function, except that it operates on a single
33  // spacepoint. Please see the other version of this function for more
34  // detailed comments.
35 
36  auto [xM, yM, zM, rM, varianceRM, varianceZM] = extractFunction(spM);
37  auto [xSP, ySP, zSP, rSP, varianceRSP, varianceZSP] = extractFunction(sp);
38 
39  float cosPhiM = xM / rM;
40  float sinPhiM = yM / rM;
41  float deltaX = xSP - xM;
42  float deltaY = ySP - yM;
43  float deltaZ = zSP - zM;
44  float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
45  float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
46  float deltaR2 = (xNewFrame * xNewFrame + yNewFrame * yNewFrame);
47  float iDeltaR2 = 1. / (deltaX * deltaX + deltaY * deltaY);
48  float iDeltaR = std::sqrt(iDeltaR2);
49  int bottomFactor = bottom ? -1 : 1;
50  float cotTheta = deltaZ * iDeltaR * bottomFactor;
51 
52  // conformal transformation u=x/(x²+y²) v=y/(x²+y²) transform the
53  // circle into straight lines in the u/v plane the line equation can
54  // be described in terms of aCoef and bCoef, where v = aCoef * u +
55  // bCoef
56  const float U = xNewFrame * iDeltaR2;
57  const float V = yNewFrame * iDeltaR2;
58 
59  // error term for sp-pair without correlation of middle space point
60  const float Er = ((varianceZM + varianceZSP) +
61  (cotTheta * cotTheta) * (varianceRM + varianceRSP)) *
62  iDeltaR2;
63 
64  sp.setDeltaR(std::sqrt(deltaR2 + (deltaZ * deltaZ)));
65  return LinCircle(cotTheta, iDeltaR, Er, U, V, xNewFrame, yNewFrame);
66 }
67 
68 template <typename external_spacepoint_t>
70  Acts::SpacePointData& spacePointData,
72  const InternalSpacePoint<external_spacepoint_t>& spM, bool bottom,
73  std::vector<LinCircle>& linCircleVec) {
74  auto extractFunction =
76  -> std::array<float, 6> {
77  std::array<float, 6> output{obj.x(), obj.y(), obj.z(),
78  obj.radius(), obj.varianceR(), obj.varianceZ()};
79  return output;
80  };
81 
82  transformCoordinates<InternalSpacePoint<external_spacepoint_t>>(
83  spacePointData, vec, spM, bottom, linCircleVec,
84  std::move(extractFunction));
85 }
86 
87 template <typename external_spacepoint_t, typename callable_t>
88 inline void transformCoordinates(Acts::SpacePointData& spacePointData,
89  const std::vector<external_spacepoint_t*>& vec,
90  const external_spacepoint_t& spM, bool bottom,
91  std::vector<LinCircle>& linCircleVec,
92  callable_t&& extractFunction) {
93  auto [xM, yM, zM, rM, varianceRM, varianceZM] = extractFunction(spM);
94 
95  // resize + operator[] is faster than reserve and push_back
96  linCircleVec.resize(vec.size());
97 
98  float cosPhiM = xM / rM;
99  float sinPhiM = yM / rM;
100 
101  int bottomFactor = bottom ? -1 : 1;
102 
103  for (std::size_t idx(0); idx < vec.size(); ++idx) {
104  auto& sp = vec[idx];
105  auto [xSP, ySP, zSP, rSP, varianceRSP, varianceZSP] = extractFunction(*sp);
106 
107  float deltaX = xSP - xM;
108  float deltaY = ySP - yM;
109  float deltaZ = zSP - zM;
110  // calculate projection fraction of spM->sp vector pointing in same
111  // direction as
112  // vector origin->spM (x) and projection fraction of spM->sp vector pointing
113  // orthogonal to origin->spM (y)
114  float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
115  float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
116  // 1/(length of M -> SP)
117  float deltaR2 = (xNewFrame * xNewFrame + yNewFrame * yNewFrame);
118  float iDeltaR2 = 1. / deltaR2;
119  float iDeltaR = std::sqrt(iDeltaR2);
120  //
121  // cot_theta = (deltaZ/deltaR)
122  float cotTheta = deltaZ * iDeltaR * bottomFactor;
123  // transformation of circle equation (x,y) into linear equation (u,v)
124  // x^2 + y^2 - 2x_0*x - 2y_0*y = 0
125  // is transformed into
126  // 1 - 2x_0*u - 2y_0*v = 0
127  // using the following m_U and m_V
128  // (u = A + B*v); A and B are created later on
129  float U = xNewFrame * iDeltaR2;
130  float V = yNewFrame * iDeltaR2;
131  // error term for sp-pair without correlation of middle space point
132  float Er = ((varianceZM + varianceZSP) +
133  (cotTheta * cotTheta) * (varianceRM + varianceRSP)) *
134  iDeltaR2;
135 
136  // Fill Line Circle
137  linCircleVec[idx].cotTheta = cotTheta;
138  linCircleVec[idx].iDeltaR = iDeltaR;
139  linCircleVec[idx].Er = Er;
140  linCircleVec[idx].U = U;
141  linCircleVec[idx].V = V;
142  linCircleVec[idx].x = xNewFrame;
143  linCircleVec[idx].y = yNewFrame;
144 
145  spacePointData.setDeltaR(sp->index(),
146  std::sqrt(deltaR2 + (deltaZ * deltaZ)));
147  }
148 }
149 
150 template <typename external_spacepoint_t>
151 inline bool xyzCoordinateCheck(
152  Acts::SpacePointData& spacePointData,
155  const double* spacepointPosition, double* outputCoordinates) {
156  // check the compatibility of SPs coordinates in xyz assuming the
157  // Bottom-Middle direction with the strip measurement details
158  bool hasValueStored = spacePointData.hasDynamicVariable();
159  if (not hasValueStored) {
160  return false;
161  }
162 
163  std::size_t index = sp.index();
164 
165  // prepare variables
166  const Acts::Vector3& topStripVector = spacePointData.getTopStripVector(index);
167  const Acts::Vector3& bottomStripVector =
168  spacePointData.getBottomStripVector(index);
169  const Acts::Vector3& stripCenterDistance =
170  spacePointData.getStripCenterDistance(index);
171 
172  const double xTopStripVector = topStripVector[0];
173  const double yTopStripVector = topStripVector[1];
174  const double zTopStripVector = topStripVector[2];
175  const double xBottomStripVector = bottomStripVector[0];
176  const double yBottomStripVector = bottomStripVector[1];
177  const double zBottomStripVector = bottomStripVector[2];
178 
179  // cross product between top strip vector and spacepointPosition
180  double d1[3] = {yTopStripVector * spacepointPosition[2] -
181  zTopStripVector * spacepointPosition[1],
182  zTopStripVector * spacepointPosition[0] -
183  xTopStripVector * spacepointPosition[2],
184  xTopStripVector * spacepointPosition[1] -
185  yTopStripVector * spacepointPosition[0]};
186 
187  // scalar product between bottom strip vector and d1
188  double bd1 = xBottomStripVector * d1[0] + yBottomStripVector * d1[1] +
189  zBottomStripVector * d1[2];
190 
191  // compatibility check using distance between strips to evaluate if
192  // spacepointPosition is inside the bottom detector element
193  double s1 = (stripCenterDistance[0] * d1[0] + stripCenterDistance[1] * d1[1] +
194  stripCenterDistance[2] * d1[2]);
195  if (std::abs(s1) > std::abs(bd1) * m_config.toleranceParam) {
196  return false;
197  }
198 
199  // cross product between bottom strip vector and spacepointPosition
200  double d0[3] = {yBottomStripVector * spacepointPosition[2] -
201  zBottomStripVector * spacepointPosition[1],
202  zBottomStripVector * spacepointPosition[0] -
203  xBottomStripVector * spacepointPosition[2],
204  xBottomStripVector * spacepointPosition[1] -
205  yBottomStripVector * spacepointPosition[0]};
206 
207  // compatibility check using distance between strips to evaluate if
208  // spacepointPosition is inside the top detector element
209  double s0 = (stripCenterDistance[0] * d0[0] + stripCenterDistance[1] * d0[1] +
210  stripCenterDistance[2] * d0[2]);
211  if (std::abs(s0) > std::abs(bd1) * m_config.toleranceParam) {
212  return false;
213  }
214 
215  // if arrive here spacepointPosition is compatible with strip directions and
216  // detector elements
217 
218  const Acts::Vector3& topStripCenterPosition =
219  spacePointData.getTopStripCenterPosition(index);
220 
221  // spacepointPosition corrected with respect to the top strip position and
222  // direction and the distance between the strips
223  s0 = s0 / bd1;
224  outputCoordinates[0] = topStripCenterPosition[0] + xTopStripVector * s0;
225  outputCoordinates[1] = topStripCenterPosition[1] + yTopStripVector * s0;
226  outputCoordinates[2] = topStripCenterPosition[2] + zTopStripVector * s0;
227  return true;
228 }
229 } // namespace Acts