Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:41

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/TrackFitting/GsfMixtureReduction.hpp"
0010 
0011 #include "Acts/TrackFitting/detail/SymmetricKlDistanceMatrix.hpp"
0012 
0013 template <typename proj_t, typename angle_desc_t>
0014 void reduceWithKLDistanceImpl(std::vector<Acts::GsfComponent> &cmpCache,
0015                               std::size_t maxCmpsAfterMerge, const proj_t &proj,
0016                               const angle_desc_t &desc) {
0017   Acts::detail::SymmetricKLDistanceMatrix distances(cmpCache, proj);
0018 
0019   auto remainingComponents = cmpCache.size();
0020 
0021   while (remainingComponents > maxCmpsAfterMerge) {
0022     const auto [minI, minJ] = distances.minDistancePair();
0023 
0024     // Set one component and compute associated distances
0025     cmpCache[minI] =
0026         mergeComponents(cmpCache[minI], cmpCache[minJ], proj, desc);
0027     distances.recomputeAssociatedDistances(minI, cmpCache, proj);
0028 
0029     // Set weight of the other component to -1 so we can remove it later and
0030     // mask its distances
0031     proj(cmpCache[minJ]).weight = -1.0;
0032     distances.maskAssociatedDistances(minJ);
0033 
0034     remainingComponents--;
0035   }
0036 
0037   // Remove all components which are labeled with weight -1
0038   std::sort(cmpCache.begin(), cmpCache.end(),
0039             [&](const auto &a, const auto &b) {
0040               return proj(a).weight < proj(b).weight;
0041             });
0042   cmpCache.erase(
0043       std::remove_if(cmpCache.begin(), cmpCache.end(),
0044                      [&](const auto &a) { return proj(a).weight == -1.0; }),
0045       cmpCache.end());
0046 
0047   assert(cmpCache.size() == maxCmpsAfterMerge && "size mismatch");
0048 }
0049 
0050 namespace Acts {
0051 
0052 void reduceMixtureLargestWeights(std::vector<GsfComponent> &cmpCache,
0053                                  std::size_t maxCmpsAfterMerge,
0054                                  const Surface & /*surface*/) {
0055   if (cmpCache.size() <= maxCmpsAfterMerge) {
0056     return;
0057   }
0058 
0059   std::nth_element(
0060       cmpCache.begin(), cmpCache.begin() + maxCmpsAfterMerge, cmpCache.end(),
0061       [](const auto &a, const auto &b) { return a.weight > b.weight; });
0062   cmpCache.resize(maxCmpsAfterMerge);
0063 }
0064 
0065 void reduceMixtureWithKLDistance(std::vector<Acts::GsfComponent> &cmpCache,
0066                                  std::size_t maxCmpsAfterMerge,
0067                                  const Surface &surface) {
0068   if (cmpCache.size() <= maxCmpsAfterMerge) {
0069     return;
0070   }
0071 
0072   auto proj = [](auto &a) -> decltype(auto) { return a; };
0073 
0074   // We must differ between surface types, since there can be different
0075   // local coordinates
0076   detail::angleDescriptionSwitch(surface, [&](const auto &desc) {
0077     reduceWithKLDistanceImpl(cmpCache, maxCmpsAfterMerge, proj, desc);
0078   });
0079 }
0080 
0081 }  // namespace Acts