Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-21 08:08:41

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/SpacePointFormation/SpacePointBuilder.hpp"
0012 
0013 #include "Acts/Definitions/Algebra.hpp"
0014 
0015 namespace Acts {
0016 
0017 template <typename spacepoint_t>
0018 SpacePointBuilder<spacepoint_t>::SpacePointBuilder(
0019     const SpacePointBuilderConfig& cfg, BuilderFunction func,
0020     std::unique_ptr<const Logger> logger)
0021     : m_config(cfg), m_spConstructor(func), m_logger(std::move(logger)) {
0022   m_spUtility = std::make_shared<SpacePointUtility>(cfg);
0023 }
0024 
0025 template <typename spacepoint_t>
0026 template <template <typename...> typename container_t>
0027 void SpacePointBuilder<spacepoint_t>::buildSpacePoint(
0028     const GeometryContext& gctx, const std::vector<SourceLink>& sourceLinks,
0029     const SpacePointBuilderOptions& opt,
0030     std::back_insert_iterator<container_t<spacepoint_t>> spacePointIt) const {
0031   Acts::Vector3 gPos = Acts::Vector3::Zero();
0032   std::optional<double> gTime = std::nullopt;
0033   Acts::Vector2 gCov = Acts::Vector2::Zero();
0034   std::optional<double> gCovT = std::nullopt;
0035 
0036   if (sourceLinks.size() == 1) {  // pixel SP formation
0037     auto slink = sourceLinks.at(0);
0038     auto [param, cov] = opt.paramCovAccessor(slink);
0039     std::tie(gPos, gTime, gCov, gCovT) = m_spUtility->globalCoords(
0040         gctx, slink, m_config.slSurfaceAccessor, param, cov);
0041   } else if (sourceLinks.size() == 2) {  // strip SP formation
0042 
0043     const auto& ends1 = opt.stripEndsPair.first;
0044     const auto& ends2 = opt.stripEndsPair.second;
0045 
0046     Acts::SpacePointParameters spParams;
0047 
0048     if (!m_config.usePerpProj) {  // default strip SP building
0049 
0050       auto spFound = m_spUtility->calculateStripSPPosition(
0051           ends1, ends2, opt.vertex, spParams, opt.stripLengthTolerance);
0052 
0053       if (!spFound.ok()) {
0054         spFound = m_spUtility->recoverSpacePoint(spParams,
0055                                                  opt.stripLengthGapTolerance);
0056       }
0057 
0058       if (!spFound.ok()) {
0059         return;
0060       }
0061 
0062       gPos = 0.5 *
0063              (ends1.first + ends1.second + spParams.m * spParams.firstBtmToTop);
0064 
0065     } else {  // for cosmic without vertex constraint
0066 
0067       auto resultPerpProj =
0068           m_spUtility->calcPerpendicularProjection(ends1, ends2, spParams);
0069 
0070       if (!resultPerpProj.ok()) {
0071         return;
0072       }
0073       gPos = ends1.first + resultPerpProj.value() * spParams.firstBtmToTop;
0074     }
0075 
0076     double theta = std::acos(
0077         spParams.firstBtmToTop.dot(spParams.secondBtmToTop) /
0078         (spParams.firstBtmToTop.norm() * spParams.secondBtmToTop.norm()));
0079 
0080     gCov = m_spUtility->calcRhoZVars(gctx, sourceLinks.at(0), sourceLinks.at(1),
0081                                      m_config.slSurfaceAccessor,
0082                                      opt.paramCovAccessor, gPos, theta);
0083 
0084   } else {
0085     ACTS_ERROR("More than 2 sourceLinks are given for a space point.");
0086   }
0087   boost::container::static_vector<SourceLink, 2> slinks(sourceLinks.begin(),
0088                                                         sourceLinks.end());
0089 
0090   spacePointIt = m_spConstructor(gPos, gTime, gCov, gCovT, std::move(slinks));
0091 }
0092 
0093 template <typename spacepoint_t>
0094 void SpacePointBuilder<spacepoint_t>::makeSourceLinkPairs(
0095     const GeometryContext& gctx, const std::vector<SourceLink>& slinksFront,
0096     const std::vector<SourceLink>& slinksBack,
0097     std::vector<std::pair<SourceLink, SourceLink>>& slinkPairs,
0098     const StripPairOptions& pairOpt) const {
0099   if (slinksFront.empty() || slinksBack.empty()) {
0100     return;
0101   }
0102   double minDistance = 0;
0103   std::size_t closestIndex = 0;
0104 
0105   for (unsigned int i = 0; i < slinksFront.size(); i++) {
0106     const auto& slinkFront = slinksFront[i];
0107     minDistance = std::numeric_limits<double>::max();
0108     closestIndex = slinksBack.size();
0109     for (unsigned int j = 0; j < slinksBack.size(); j++) {
0110       const auto& slinkBack = slinksBack[j];
0111 
0112       const auto [paramFront, covFront] = pairOpt.paramCovAccessor(slinkFront);
0113       const auto [gposFront, gtimeFront, gcovFront, gcovtFront] =
0114           m_spUtility->globalCoords(gctx, slinkFront,
0115                                     m_config.slSurfaceAccessor, paramFront,
0116                                     covFront);
0117 
0118       const auto [paramBack, covBack] = pairOpt.paramCovAccessor(slinkBack);
0119       const auto [gposBack, gtimeBack, gcovBack, gcovtBack] =
0120           m_spUtility->globalCoords(gctx, slinkBack, m_config.slSurfaceAccessor,
0121                                     paramBack, covBack);
0122 
0123       auto res = m_spUtility->differenceOfMeasurementsChecked(
0124           gposFront, gposBack, pairOpt.vertex, pairOpt.diffDist,
0125           pairOpt.diffPhi2, pairOpt.diffTheta2);
0126       if (!res.ok()) {
0127         continue;
0128       }
0129       const auto distance = res.value();
0130       if (distance >= 0. && distance < minDistance) {
0131         minDistance = distance;
0132         closestIndex = j;
0133       }
0134     }
0135     if (closestIndex < slinksBack.size()) {
0136       slinkPairs.emplace_back(slinksFront[i], slinksBack[closestIndex]);
0137     }
0138   }
0139 }
0140 
0141 }  // namespace Acts