8 #include "AthLinks/ElementLink.h"
9 #include "Identifier/Identifier.h"
14 #include <unordered_set>
17 using IdSet_t = std::unordered_set<Identifier>;
18 unsigned int countMatched(
const std::unordered_set<const xAOD::MuonSimHit*>& simHits,
19 const IdSet_t& matchIds) {
20 return std::ranges::count_if(simHits, [&matchIds](
const xAOD::MuonSimHit* hit) {
21 return matchIds.count(hit->
identify());
36 return StatusCode::SUCCESS;
44 using TruthSegLink_t = std::vector<ElementLink<xAOD::MuonSegmentContainer>>;
48 std::vector<IdDecorHandle_t> idDecorHandles{};
50 idDecorHandles.emplace_back(hitKey, ctx);
53 using IdSet_t = std::unordered_set<Identifier>;
54 using TruthTuple_t = std::tuple<const xAOD::TruthParticle*, IdSet_t>;
55 std::vector<TruthTuple_t> truthPartWithIds{};
56 truthPartWithIds.reserve(truthParticles->size());
58 segLinkDecor(*truthMuon).clear();
62 for (
const IdDecorHandle_t& hitDecor : idDecorHandles) {
64 [
this](
unsigned long long rawId){
65 const Identifier id{rawId};
70 truthPartWithIds.emplace_back(std::make_tuple(
truthMuon, std::move(assocIds)));
85 <<
", phi: "<<
segment->sector()<<
", nPrecHits: "<<
segment->nPrecisionHits()
86 <<
", nDoF: "<<
segment->numberDoF()<<
" sim hits: "<<simHits.size());
88 std::vector<const xAOD::MuonSimHit*> sortedHits{simHits.begin(), simHits.end()};
90 return a->identify() <
b->identify();
93 ATH_MSG_VERBOSE(
" --- associated sim hit: "<<m_idHelperSvc->toString(hit->identify())
94 <<
", locPos: "<<
Amg::toString(xAOD::toEigen(hit->localPosition()))
95 <<
", locDir: "<<
Amg::toString(xAOD::toEigen(hit->localDirection()))
96 <<
", "<<hit->genParticleLink());
100 const auto best_itr = std::ranges::max_element(truthPartWithIds,
101 [&simHits](
const TruthTuple_t& truthTupleA,
102 const TruthTuple_t& truthTupleB) {
103 return countMatched(simHits, std::get<1>(truthTupleA)) <
106 if (best_itr == truthPartWithIds.end()) {
107 ATH_MSG_WARNING(
"No truth particle matched the truth hits of the segment");
110 if (1.*
countMatched(simHits, std::get<1>(*best_itr)) < 0.5* simHits.size()) {
112 for (
const auto& [
truthMuon, assocIds]: truthPartWithIds){
113 std::stringstream unMatchedStr{};
114 unsigned int counts{0};
116 if (!assocIds.count(hit->identify())){
117 unMatchedStr<<
" *** "<<m_idHelperSvc->toString(hit->identify())<<std::endl;
122 if (!counts)
continue;
124 <<
", barcode: "<<
HepMC::barcode(
truthMuon)<<
", matched hits: "<<counts<<
", unmatched: "<<std::endl<<unMatchedStr.str());
130 segLinkDecor(*truthPart).emplace_back(segments,
segment->index());
131 truthLinkDecor(*
segment) = TruthPartLink_t{truthParticles, truthPart->
index()};
134 return StatusCode::SUCCESS;