Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-21 09:01:52

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