Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:49

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 #include "ActsExamples/Validation/TrackClassification.hpp"
0010 
0011 #include "Acts/EventData/MultiTrajectory.hpp"
0012 #include "Acts/Utilities/MultiIndex.hpp"
0013 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0014 #include "ActsExamples/EventData/Track.hpp"
0015 #include "ActsExamples/EventData/Trajectories.hpp"
0016 #include "ActsExamples/Utilities/Range.hpp"
0017 
0018 #include <algorithm>
0019 #include <utility>
0020 
0021 namespace {
0022 
0023 /// Increase the hit count for the given particle id by one.
0024 inline void increaseHitCount(
0025     std::vector<ActsExamples::ParticleHitCount>& particleHitCounts,
0026     ActsFatras::Barcode particleId) {
0027   // linear search since there is no ordering
0028   auto it = std::ranges::find_if(particleHitCounts, [=](const auto& phc) {
0029     return (phc.particleId == particleId);
0030   });
0031   // either increase count if we saw the particle before or add it
0032   if (it != particleHitCounts.end()) {
0033     it->hitCount += 1u;
0034   } else {
0035     particleHitCounts.push_back({particleId, 1u});
0036   }
0037 }
0038 
0039 /// Sort hit counts by decreasing values, i.e. majority particle comes first.
0040 inline void sortHitCount(
0041     std::vector<ActsExamples::ParticleHitCount>& particleHitCounts) {
0042   std::ranges::sort(particleHitCounts, std::greater{},
0043                     [](const auto& p) { return p.hitCount; });
0044 }
0045 
0046 }  // namespace
0047 
0048 void ActsExamples::identifyContributingParticles(
0049     const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap,
0050     const ProtoTrack& protoTrack,
0051     std::vector<ActsExamples::ParticleHitCount>& particleHitCounts) {
0052   particleHitCounts.clear();
0053 
0054   for (auto hitIndex : protoTrack) {
0055     // register all particles that generated this hit
0056     for (const auto& [_, value] :
0057          makeRange(hitParticlesMap.equal_range(hitIndex))) {
0058       increaseHitCount(particleHitCounts, value);
0059     }
0060   }
0061   sortHitCount(particleHitCounts);
0062 }
0063 
0064 void ActsExamples::identifyContributingParticles(
0065     const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap,
0066     const Trajectories& trajectories, std::size_t tip,
0067     std::vector<ParticleHitCount>& particleHitCounts) {
0068   particleHitCounts.clear();
0069 
0070   if (!trajectories.hasTrajectory(tip)) {
0071     return;
0072   }
0073 
0074   trajectories.multiTrajectory().visitBackwards(tip, [&](const auto& state) {
0075     // no truth info with non-measurement state
0076     if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
0077       return true;
0078     }
0079     // register all particles that generated this hit
0080     IndexSourceLink sl =
0081         state.getUncalibratedSourceLink().template get<IndexSourceLink>();
0082     auto hitIndex = sl.index();
0083     for (const auto& [_, value] :
0084          makeRange(hitParticlesMap.equal_range(hitIndex))) {
0085       increaseHitCount(particleHitCounts, value);
0086     }
0087     return true;
0088   });
0089   sortHitCount(particleHitCounts);
0090 }
0091 
0092 void ActsExamples::identifyContributingParticles(
0093     const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap,
0094     const ConstTrackContainer::ConstTrackProxy& track,
0095     std::vector<ParticleHitCount>& particleHitCounts) {
0096   particleHitCounts.clear();
0097 
0098   for (const auto& state : track.trackStatesReversed()) {
0099     // no truth info with non-measurement state
0100     if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
0101       continue;
0102     }
0103     // register all particles that generated this hit
0104     IndexSourceLink sl =
0105         state.getUncalibratedSourceLink().template get<IndexSourceLink>();
0106     auto hitIndex = sl.index();
0107     for (const auto& [_, value] :
0108          makeRange(hitParticlesMap.equal_range(hitIndex))) {
0109       increaseHitCount(particleHitCounts, value);
0110     }
0111   }
0112   sortHitCount(particleHitCounts);
0113 }