12 #include <type_traits>
17 template <
typename T_EnumClass >
31 ISvcLocator *pSvcLocator)
46 return StatusCode::SUCCESS;
49 template <
bool IsDebug>
50 template <
class T_OutStream>
53 out <<
"Measurements per track :" << m_measPerTrack << std::endl
54 << m_measPerTrack.histogramToString() << std::endl
55 <<
"TruthParticles per track :" << m_truthParticlesPerTrack << std::endl
56 << m_truthParticlesPerTrack.histogramToString();
59 template <
bool IsDebug>
62 std::lock_guard<std::mutex> lock(m_mutex);
63 m_measPerTrack.add(n_measurements);
64 m_truthParticlesPerTrack.add(n_particles);
70 std::stringstream
label;
79 ATH_MSG_WARNING(
"Encountered measurements not compaible with provided association maps in "
83 msg(MSG::INFO) <<
"-- Statistics:" << std::endl;
85 for (
const std::atomic<std::size_t> &elm : m_nTracksWithAssociatedTruth) {
86 msg() << std::setw(20) << elm <<
" "
88 ? std::string(
" tracks without associated truth particles.")
89 : (
idx==m_nTracksWithAssociatedTruth.size()-1
91 m_nTracksWithAssociatedTruth.size()-1,
92 "associated truth particles.")
95 "associated truth particle(s).")));
108 return StatusCode::SUCCESS;
113 std::unique_ptr<TrackToTruthParticleAssociation>
114 track_association( std::make_unique<TrackToTruthParticleAssociation>() );
117 if (!pixelClustersToTruthAssociation.
isValid()) {
119 return StatusCode::FAILURE;
122 if (!stripClustersToTruthAssociation.
isValid()) {
124 return StatusCode::FAILURE;
127 if (!tracksContainer.
isValid()) {
129 return StatusCode::FAILURE;
131 track_association->resize( tracksContainer->size() );
137 measurement_to_truth_association_maps{};
143 unsigned int track_i=0;
144 std::array<unsigned int,s_NCounterForAssociatedTruth> tracks_with_associated_truth{};
145 std::pair<unsigned int, unsigned int> compatible_assoc_container_counts{};
149 ++compatible_assoc_container_counts.second;
152 std::vector<unsigned int> counted_truth_particles;
153 counted_truth_particles.reserve(10);
155 for (
const typename ActsTrk::TrackContainer::ConstTrackProxy
track : *tracksContainer) {
157 const auto lastMeasurementIndex =
track.tipIndex();
159 unsigned int n_measurements=0
u;
161 HitCounterArray &reco_hits = track_association->at(track_i).totalCounts();
162 HitCounterArray &noise_hits = track_association->at(track_i).noiseCounts();
164 tracksContainer->trackStateContainer().visitBackwards(
165 lastMeasurementIndex,
168 &measurement_to_truth_association_maps,
169 &truth_particle_counts,
172 &counted_truth_particles,
173 &compatible_assoc_container_counts
174 ](
const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state) ->
void
176 if (!state.typeFlags().test(Acts::TrackStateFlag::OutlierFlag) && state.hasUncalibratedSourceLink()) {
177 auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
178 assert( sl != nullptr );
179 const xAOD::UncalibratedMeasurement &uncalibMeas = getUncalibratedMeasurement(sl);
182 const ActsTrk::MeasurementToTruthParticleAssociation *association_map = measurement_to_truth_association_maps.at(to_underlying(uncalibMeas.type()));
183 if (association_map) {
184 if (!association_map->isCompatibleWith(dynamic_cast< const xAOD::UncalibratedMeasurementContainer *>(uncalibMeas.container()))) {
185 if (compatible_assoc_container_counts.second==0) {
186 ATH_MSG_ERROR(
"MeasurementToTruthParticleAssociation for measurement type " << to_underlying(uncalibMeas.type())
187 <<
" is not compatible with the measurement on track.");
189 ++compatible_assoc_container_counts.second;
193 ++compatible_assoc_container_counts.first;
196 counted_truth_particles.clear();
197 for (const xAOD::TruthParticle *truth_particle : association_map->at(uncalibMeas.index()) ) {
198 const xAOD::TruthParticle *mother_particle = m_elasticDecayUtil.getMother(*truth_particle, m_maxEnergyLoss.value());
201 if (std::find(counted_truth_particles.begin(), counted_truth_particles.end(), mother_particle->index())
202 ==counted_truth_particles.end()) {
203 counted_truth_particles.push_back(mother_particle->index());
205 ActsTrk::HitCountsPerTrack::container::iterator
206 hit_count_iter = std::find_if(truth_particle_counts.begin(),
207 truth_particle_counts.end(),
208 [mother_particle](const std::pair<const xAOD::TruthParticle *, HitCounterArray > &a) {
209 return a.first == mother_particle;
211 if (hit_count_iter == truth_particle_counts.end()) {
212 truth_particle_counts.push_back( std::make_pair(mother_particle, HitCounterArray{}));
213 hit_count_iter = truth_particle_counts.end()-1;
215 ++(hit_count_iter->second.at( to_underlying(uncalibMeas.type())));
218 if (association_map->at(uncalibMeas.index()).empty()) {
219 ++noise_hits.at( to_underlying(uncalibMeas.type()));
226 std::sort( truth_particle_counts.begin(),
227 truth_particle_counts.end(),
228 [](
const std::pair<const xAOD::TruthParticle *, HitCounterArray > &
a,
229 const std::pair<const xAOD::TruthParticle *, HitCounterArray > &
b) {
230 return std::accumulate(a.second.begin(),a.second.end(),0u) > std::accumulate(b.second.begin(),b.second.end(),0u);
233 ++(tracks_with_associated_truth[
std::min(truth_particle_counts.size(),tracks_with_associated_truth.size()-1
u)]);
236 for (
unsigned int elm : tracks_with_associated_truth) {
237 m_nTracksWithAssociatedTruth[
idx] += elm;
240 m_nIncompatibleMeasurementContainer += compatible_assoc_container_counts.second;
241 m_nCcompatibleMeasurementContainer += compatible_assoc_container_counts.first;
244 if (associationOutHandle.record( std::move(track_association)).isFailure()) {
245 ATH_MSG_ERROR(
"Failed to record track to truth assocition with key " << m_trackToTruthOut.key() );
246 return StatusCode::FAILURE;
248 return StatusCode::SUCCESS;