Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2019-2020 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 "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::find_if(particleHitCounts.begin(), particleHitCounts.end(),
0029                          [=](const ActsExamples::ParticleHitCount& phc) {
0030                            return (phc.particleId == particleId);
0031                          });
0032   // either increase count if we saw the particle before or add it
0033   if (it != particleHitCounts.end()) {
0034     it->hitCount += 1u;
0035   } else {
0036     particleHitCounts.push_back({particleId, 1u});
0037   }
0038 }
0039 
0040 /// Sort hit counts by decreasing values, i.e. majority particle comes first.
0041 inline void sortHitCount(
0042     std::vector<ActsExamples::ParticleHitCount>& particleHitCounts) {
0043   std::sort(particleHitCounts.begin(), particleHitCounts.end(),
0044             [](const ActsExamples::ParticleHitCount& lhs,
0045                const ActsExamples::ParticleHitCount& rhs) {
0046               return (lhs.hitCount > rhs.hitCount);
0047             });
0048 }
0049 
0050 }  // namespace
0051 
0052 void ActsExamples::identifyContributingParticles(
0053     const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap,
0054     const ProtoTrack& protoTrack,
0055     std::vector<ActsExamples::ParticleHitCount>& particleHitCounts) {
0056   particleHitCounts.clear();
0057 
0058   for (auto hitIndex : protoTrack) {
0059     // register all particles that generated this hit
0060     for (auto hitParticle : makeRange(hitParticlesMap.equal_range(hitIndex))) {
0061       increaseHitCount(particleHitCounts, hitParticle.second);
0062     }
0063   }
0064   sortHitCount(particleHitCounts);
0065 }
0066 
0067 void ActsExamples::identifyContributingParticles(
0068     const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap,
0069     const Trajectories& trajectories, std::size_t tip,
0070     std::vector<ParticleHitCount>& particleHitCounts) {
0071   particleHitCounts.clear();
0072 
0073   if (!trajectories.hasTrajectory(tip)) {
0074     return;
0075   }
0076 
0077   trajectories.multiTrajectory().visitBackwards(tip, [&](const auto& state) {
0078     // no truth info with non-measurement state
0079     if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
0080       return true;
0081     }
0082     // register all particles that generated this hit
0083     IndexSourceLink sl =
0084         state.getUncalibratedSourceLink().template get<IndexSourceLink>();
0085     auto hitIndex = sl.index();
0086     for (auto hitParticle : makeRange(hitParticlesMap.equal_range(hitIndex))) {
0087       increaseHitCount(particleHitCounts, hitParticle.second);
0088     }
0089     return true;
0090   });
0091   sortHitCount(particleHitCounts);
0092 }
0093 
0094 void ActsExamples::identifyContributingParticles(
0095     const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap,
0096     const ConstTrackContainer::ConstTrackProxy& track,
0097     std::vector<ParticleHitCount>& particleHitCounts) {
0098   particleHitCounts.clear();
0099 
0100   for (const auto& state : track.trackStatesReversed()) {
0101     // no truth info with non-measurement state
0102     if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
0103       continue;
0104     }
0105     // register all particles that generated this hit
0106     IndexSourceLink sl =
0107         state.getUncalibratedSourceLink().template get<IndexSourceLink>();
0108     auto hitIndex = sl.index();
0109     for (auto hitParticle : makeRange(hitParticlesMap.equal_range(hitIndex))) {
0110       increaseHitCount(particleHitCounts, hitParticle.second);
0111     }
0112   }
0113   sortHitCount(particleHitCounts);
0114 }