Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 08:10:42

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Seeding/SeedFinderUtils.hpp"
0012 
0013 #include "Acts/Utilities/HashedString.hpp"
0014 
0015 namespace Acts {
0016 
0017 template <typename external_spacepoint_t, typename callable_t>
0018 inline LinCircle transformCoordinates(Acts::SpacePointMutableData& mutableData,
0019                                       const external_spacepoint_t& sp,
0020                                       const external_spacepoint_t& spM,
0021                                       bool bottom,
0022                                       callable_t&& extractFunction) {
0023   // The computation inside this function is exactly identical to that in the
0024   // vectorized version of this function, except that it operates on a single
0025   // spacepoint. Please see the other version of this function for more
0026   // detailed comments.
0027 
0028   auto [xM, yM, zM, rM, varianceRM, varianceZM] = extractFunction(spM);
0029   auto [xSP, ySP, zSP, rSP, varianceRSP, varianceZSP] = extractFunction(sp);
0030 
0031   float cosPhiM = xM / rM;
0032   float sinPhiM = yM / rM;
0033   float deltaX = xSP - xM;
0034   float deltaY = ySP - yM;
0035   float deltaZ = zSP - zM;
0036   float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
0037   float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
0038   float deltaR2 = (xNewFrame * xNewFrame + yNewFrame * yNewFrame);
0039   float iDeltaR2 = 1. / (deltaX * deltaX + deltaY * deltaY);
0040   float iDeltaR = std::sqrt(iDeltaR2);
0041   int bottomFactor = bottom ? -1 : 1;
0042   float cotTheta = deltaZ * iDeltaR * bottomFactor;
0043 
0044   // conformal transformation u=x/(x²+y²) v=y/(x²+y²) transform the
0045   // circle into straight lines in the u/v plane the line equation can
0046   // be described in terms of aCoef and bCoef, where v = aCoef * u +
0047   // bCoef
0048   const float U = xNewFrame * iDeltaR2;
0049   const float V = yNewFrame * iDeltaR2;
0050 
0051   // error term for sp-pair without correlation of middle space point
0052   const float Er = ((varianceZM + varianceZSP) +
0053                     (cotTheta * cotTheta) * (varianceRM + varianceRSP)) *
0054                    iDeltaR2;
0055 
0056   mutableData.setDeltaR(sp.index(), std::sqrt(deltaR2 + (deltaZ * deltaZ)));
0057   return LinCircle(cotTheta, iDeltaR, Er, U, V, xNewFrame, yNewFrame);
0058 }
0059 
0060 template <typename external_spacepoint_t>
0061 inline void transformCoordinates(
0062     Acts::SpacePointMutableData& mutableData,
0063     const std::vector<const external_spacepoint_t*>& vec,
0064     const external_spacepoint_t& spM, bool bottom,
0065     std::vector<LinCircle>& linCircleVec) {
0066   const float xM = spM.x();
0067   const float yM = spM.y();
0068   const float zM = spM.z();
0069   const float rM = spM.radius();
0070   const float varianceRM = spM.varianceR();
0071   const float varianceZM = spM.varianceZ();
0072 
0073   // resize + operator[] is faster than reserve and push_back
0074   linCircleVec.resize(vec.size());
0075 
0076   float cosPhiM = xM / rM;
0077   float sinPhiM = yM / rM;
0078 
0079   int bottomFactor = bottom ? -1 : 1;
0080 
0081   for (std::size_t idx(0); idx < vec.size(); ++idx) {
0082     const external_spacepoint_t* sp = vec[idx];
0083 
0084     const float xSP = sp->x();
0085     const float ySP = sp->y();
0086     const float zSP = sp->z();
0087     const float varianceRSP = sp->varianceR();
0088     const float varianceZSP = sp->varianceZ();
0089 
0090     const float deltaX = xSP - xM;
0091     const float deltaY = ySP - yM;
0092     const float deltaZ = zSP - zM;
0093     // calculate projection fraction of spM->sp vector pointing in same
0094     // direction as
0095     // vector origin->spM (x) and projection fraction of spM->sp vector pointing
0096     // orthogonal to origin->spM (y)
0097     const float xNewFrame = deltaX * cosPhiM + deltaY * sinPhiM;
0098     const float yNewFrame = deltaY * cosPhiM - deltaX * sinPhiM;
0099     // 1/(length of M -> SP)
0100     const float deltaR2 = (xNewFrame * xNewFrame + yNewFrame * yNewFrame);
0101     const float iDeltaR2 = 1. / deltaR2;
0102     const float iDeltaR = std::sqrt(iDeltaR2);
0103     //
0104     // cot_theta = (deltaZ/deltaR)
0105     const float cotTheta = deltaZ * iDeltaR * bottomFactor;
0106     // transformation of circle equation (x,y) into linear equation (u,v)
0107     // x^2 + y^2 - 2x_0*x - 2y_0*y = 0
0108     // is transformed into
0109     // 1 - 2x_0*u - 2y_0*v = 0
0110     // using the following m_U and m_V
0111     // (u = A + B*v); A and B are created later on
0112     const float U = xNewFrame * iDeltaR2;
0113     const float V = yNewFrame * iDeltaR2;
0114     // error term for sp-pair without correlation of middle space point
0115     const float Er = ((varianceZM + varianceZSP) +
0116                       (cotTheta * cotTheta) * (varianceRM + varianceRSP)) *
0117                      iDeltaR2;
0118 
0119     // Fill Line Circle
0120     linCircleVec[idx].cotTheta = cotTheta;
0121     linCircleVec[idx].iDeltaR = iDeltaR;
0122     linCircleVec[idx].Er = Er;
0123     linCircleVec[idx].U = U;
0124     linCircleVec[idx].V = V;
0125     linCircleVec[idx].x = xNewFrame;
0126     linCircleVec[idx].y = yNewFrame;
0127     mutableData.setDeltaR(sp->index(), std::sqrt(deltaR2 + (deltaZ * deltaZ)));
0128   }
0129 }
0130 
0131 template <typename external_spacepoint_t>
0132 inline bool xyzCoordinateCheck(
0133     const Acts::SeedFinderConfig<external_spacepoint_t>& m_config,
0134     const external_spacepoint_t& sp, const double* spacepointPosition,
0135     double* outputCoordinates) {
0136   // check the compatibility of SPs coordinates in xyz assuming the
0137   // Bottom-Middle direction with the strip measurement details
0138 
0139   using namespace Acts::HashedStringLiteral;
0140   const Acts::Vector3& topStripVector = sp.topStripVector();
0141   const Acts::Vector3& bottomStripVector = sp.bottomStripVector();
0142   const Acts::Vector3& stripCenterDistance = sp.stripCenterDistance();
0143 
0144   const double xTopStripVector = topStripVector[0];
0145   const double yTopStripVector = topStripVector[1];
0146   const double zTopStripVector = topStripVector[2];
0147   const double xBottomStripVector = bottomStripVector[0];
0148   const double yBottomStripVector = bottomStripVector[1];
0149   const double zBottomStripVector = bottomStripVector[2];
0150 
0151   // cross product between top strip vector and spacepointPosition
0152   double d1[3] = {yTopStripVector * spacepointPosition[2] -
0153                       zTopStripVector * spacepointPosition[1],
0154                   zTopStripVector * spacepointPosition[0] -
0155                       xTopStripVector * spacepointPosition[2],
0156                   xTopStripVector * spacepointPosition[1] -
0157                       yTopStripVector * spacepointPosition[0]};
0158 
0159   // scalar product between bottom strip vector and d1
0160   double bd1 = xBottomStripVector * d1[0] + yBottomStripVector * d1[1] +
0161                zBottomStripVector * d1[2];
0162 
0163   // compatibility check using distance between strips to evaluate if
0164   // spacepointPosition is inside the bottom detector element
0165   double s1 = (stripCenterDistance[0] * d1[0] + stripCenterDistance[1] * d1[1] +
0166                stripCenterDistance[2] * d1[2]);
0167   if (std::abs(s1) > std::abs(bd1) * m_config.toleranceParam) {
0168     return false;
0169   }
0170 
0171   // cross product between bottom strip vector and spacepointPosition
0172   double d0[3] = {yBottomStripVector * spacepointPosition[2] -
0173                       zBottomStripVector * spacepointPosition[1],
0174                   zBottomStripVector * spacepointPosition[0] -
0175                       xBottomStripVector * spacepointPosition[2],
0176                   xBottomStripVector * spacepointPosition[1] -
0177                       yBottomStripVector * spacepointPosition[0]};
0178 
0179   // compatibility check using distance between strips to evaluate if
0180   // spacepointPosition is inside the top detector element
0181   double s0 = (stripCenterDistance[0] * d0[0] + stripCenterDistance[1] * d0[1] +
0182                stripCenterDistance[2] * d0[2]);
0183   if (std::abs(s0) > std::abs(bd1) * m_config.toleranceParam) {
0184     return false;
0185   }
0186 
0187   // if arrive here spacepointPosition is compatible with strip directions and
0188   // detector elements
0189 
0190   const Acts::Vector3& topStripCenterPosition = sp.topStripCenterPosition();
0191 
0192   // spacepointPosition corrected with respect to the top strip position and
0193   // direction and the distance between the strips
0194   s0 = s0 / bd1;
0195   outputCoordinates[0] = topStripCenterPosition[0] + xTopStripVector * s0;
0196   outputCoordinates[1] = topStripCenterPosition[1] + yTopStripVector * s0;
0197   outputCoordinates[2] = topStripCenterPosition[2] + zTopStripVector * s0;
0198   return true;
0199 }
0200 }  // namespace Acts