20 constexpr
unsigned int dummy_unsigned = 999;
21 constexpr
int com_bit = (1<<xAOD::Muon::Author::Commissioning);
22 void increment_unsigned(
unsigned&
val) {
23 if (
val == dummy_unsigned)
45 using namespace MuonStationIndex;
52 if (m_recoLink.empty()){
53 m_muonTruthRecoLink =
"" ;
55 m_muonTruthRecoLink = m_recoLink;
58 ATH_CHECK(m_muonTruthRecoLink.initialize(!m_recoLink.empty()));
59 ATH_CHECK(m_muonTruthParticleLink.initialize());
60 ATH_CHECK(m_muonTruthParticleOrigin.initialize());
61 ATH_CHECK(m_muonTruthParticleType.initialize());
62 ATH_CHECK(m_muonTruthParticleNPrecMatched.initialize());
63 ATH_CHECK(m_muonTruthParticleNPhiMatched.initialize());
64 ATH_CHECK(m_muonTruthParticleNTrigEtaMatched.initialize());
65 for (
const std::string& trk_coll : m_assocTrkContainers.value()){
66 m_inputDecorKey.emplace_back(trk_coll +
".truthParticleLink");
74 return StatusCode::SUCCESS;
81 std::unique_ptr<SG::WriteDecorHandle<xAOD::TruthParticleContainer, ElementLink<xAOD::MuonContainer>>> muonTruthParticleRecoLink{};
82 if (!m_muonTruthRecoLink.empty()) {
83 muonTruthParticleRecoLink = std::make_unique<SG::WriteDecorHandle<xAOD::TruthParticleContainer, ElementLink<xAOD::MuonContainer>>>(m_muonTruthRecoLink, ctx);
88 if (!muonTruthParticleLink.isValid()) {
90 return StatusCode::FAILURE;
100 bool saw_staco =
false;
101 bool decor_staco =
false;
111 tp =
muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
113 tp =
muon->primaryTrackParticle();
116 bool foundTruth{
false}, setOrigin{
false};
121 if (acc_origin.isAvailable(*
tp) && acc_origin(*
tp) != 0) {
122 muonTruthParticleOrigin(*
muon) = acc_origin(*
tp);
123 muonTruthParticleType(*
muon) = acc_type(*
tp);
128 if (acc_link.isAvailable(*
tp)) {
129 truthLink = acc_link(*
tp);
131 ATH_MSG_DEBUG(
"Could not find any truth link associated with track having pt:"<<
tp->pt()<<
" MeV, eta: "<<
tp->eta()<<
", phi: "<<
tp->phi()<<
", charge: "<<
tp->charge()<<
". d0:"<<
tp->d0()<<
", z0: "<<
tp->z0());
149 truthParticle->
index(),
151 muonTruthLink.toPersistent();
152 muonTruthParticleLink(*
muon) = muonTruthLink;
154 muonTruthParticleOrigin(*
muon) = acc_origin(*
tp);
155 muonTruthParticleType(*
muon) = acc_type(*
tp);
159 if (muonTruthParticleRecoLink && muonTruthParticleRecoLink->operator()(*truthParticle).isValid()){
160 const xAOD::Muon* decor_muon = *muonTruthParticleRecoLink->operator()(*truthParticle);
161 ATH_MSG_VERBOSE(
"Truth particle is already decorated with reco muon "<<decor_muon->
pt()*1.e-3
162 <<
" eta: "<<decor_muon->
eta()<<
" phi: "<<decor_muon->
phi()<<
" charge: "<<
163 decor_muon->
charge()<<
" author: "<<decor_muon->
author()<<
" all authors: "<<
168 ATH_MSG_DEBUG(
"Author of the decorated muon is better than the one of the new candidate");
172 const int com_score = (
muon->allAuthors() & com_bit) - (decor_muon->
allAuthors() &com_bit);
174 ATH_MSG_DEBUG(
"Found two muons reconstructed by an equivalent author. But this one is from the commissioning chain");
185 std::vector<unsigned int> nprecHitsPerChamberLayer(
toInt(ChIndex::ChIndexMax), dummy_unsigned);
186 std::vector<unsigned int> nphiHitsPerChamberLayer(
toInt(PhiIndex::PhiIndexMax), dummy_unsigned);
187 std::vector<unsigned int> ntrigEtaHitsPerChamberLayer(
toInt(PhiIndex::PhiIndexMax), dummy_unsigned);
190 count_chamber_layers(
muon->allAuthors() & author_sel
193 tp->track(), nprecHitsPerChamberLayer, nphiHitsPerChamberLayer, ntrigEtaHitsPerChamberLayer);
195 muonTruthParticleNPrecMatched(*
muon) = nprecHitsPerChamberLayer;
196 muonTruthParticleNPhiMatched(*
muon) = nphiHitsPerChamberLayer;
197 muonTruthParticleNTrigEtaMatched(*
muon) = ntrigEtaHitsPerChamberLayer;
199 if (muonTruthParticleRecoLink) (*muonTruthParticleRecoLink)(*truthParticle) = muonLink;
206 ATH_MSG_WARNING(
"Could not find the appropiate track particle for muon with pT: " <<
muon->pt() * 1.e-3 <<
" GeV, eta: "
207 <<
muon->eta() <<
", phi: " <<
muon->phi()
208 <<
" author: " <<
muon->author());
212 muonTruthParticleOrigin(*
muon) = 0;
213 muonTruthParticleType(*
muon) = 0;
218 muonTruthParticleNPrecMatched(*
muon) = std::vector<unsigned int>{};
219 muonTruthParticleNPhiMatched(*
muon) = std::vector<unsigned int>{};
220 muonTruthParticleNTrigEtaMatched(*
muon) = std::vector<unsigned int>{};
232 decor_staco = !dec_origin.isAvailable (*cmb_trk);
235 dec_origin(*cmb_trk) = acc_origin(*
muon);
236 dec_type(*cmb_trk) = acc_type(*
muon);
237 dec_link(*cmb_trk) = acc_link(*
muon);
243 if (muonTruthParticleRecoLink && !muonTruthParticleRecoLink->isAvailable()) {
250 return StatusCode::SUCCESS;
254 std::vector<unsigned int>& nprecHitsPerChamberLayer,
255 std::vector<unsigned int>& nphiHitsPerChamberLayer,
256 std::vector<unsigned int>& ntrigEtaHitsPerChamberLayer)
const {
258 if (!truthParticle || !truthMdtHitsAcc.
isAvailable(*truthParticle)) {
259 ATH_MSG_DEBUG(
"muon has no truth hits vector in the truth association alg");
260 nprecHitsPerChamberLayer.clear();
261 nphiHitsPerChamberLayer.clear();
262 ntrigEtaHitsPerChamberLayer.clear();
265 const std::vector<unsigned long long>& mdtTruth = truthMdtHitsAcc(*truthParticle);
266 std::vector<unsigned long long> cscTruth;
268 if (m_idHelperSvc->hasCSC()) cscTruth = truthCscHitsAcc(*truthParticle);
269 const std::vector<unsigned long long>& rpcTruth = truthRpcHitsAcc(*truthParticle);
270 const std::vector<unsigned long long>& tgcTruth = truthTgcHitsAcc(*truthParticle);
273 if (!tsit || !tsit->trackParameters() || !tsit->measurementOnTrack())
continue;
283 if (!m_idHelperSvc->isMuon(
id))
continue;
285 bool measPhi = m_idHelperSvc->measuresPhi(
id);
286 bool isTgc = m_idHelperSvc->isTgc(
id);
287 ChIndex chIndex = !isTgc ? m_idHelperSvc->chamberIndex(
id) : ChIndex::ChUnknown;
288 if (m_idHelperSvc->isMdt(
id)) {
289 for (
unsigned int i = 0;
i < mdtTruth.size(); ++
i) {
290 if (
id == mdtTruth[
i]) {
291 if (
chIndex != ChIndex::ChUnknown) {
292 increment_unsigned(nprecHitsPerChamberLayer.at(
toInt(
chIndex)));
297 }
else if (m_idHelperSvc->hasCSC() && m_idHelperSvc->isCsc(
id)) {
298 for (
unsigned int i = 0;
i < cscTruth.size(); ++
i) {
299 if (
id != cscTruth[
i])
continue;
302 if (
index != PhiIndex::PhiUnknown) {
303 increment_unsigned(nphiHitsPerChamberLayer.at(
toInt(
index)));
306 if (
chIndex != ChIndex::ChUnknown) {
307 increment_unsigned(nprecHitsPerChamberLayer.at(
toInt(
chIndex)));
312 }
else if (m_idHelperSvc->isRpc(
id)) {
313 for (
unsigned int i = 0;
i < rpcTruth.size(); ++
i) {
314 if (
id != rpcTruth[
i]) {
continue; }
316 if (
index != PhiIndex::PhiUnknown) {
318 increment_unsigned(nphiHitsPerChamberLayer.at(
toInt(
index)));
320 increment_unsigned(ntrigEtaHitsPerChamberLayer.at(
toInt(
index)));
325 }
else if (m_idHelperSvc->isTgc(
id)) {
326 for (
unsigned int i = 0;
i < tgcTruth.size(); ++
i) {
327 if (
id != tgcTruth[
i]) {
continue; }
329 if (
index != PhiIndex::PhiUnknown) {
331 increment_unsigned(nphiHitsPerChamberLayer.at(
toInt(
index)));
333 increment_unsigned(ntrigEtaHitsPerChamberLayer.at(
toInt(
index)));
343 clear_dummys(mdtTruth, nprecHitsPerChamberLayer);
344 clear_dummys(cscTruth, nprecHitsPerChamberLayer);
346 clear_dummys(cscTruth, nphiHitsPerChamberLayer);
347 clear_dummys(rpcTruth, nphiHitsPerChamberLayer);
348 clear_dummys(tgcTruth, nphiHitsPerChamberLayer);
350 clear_dummys(rpcTruth, ntrigEtaHitsPerChamberLayer);
351 clear_dummys(tgcTruth, ntrigEtaHitsPerChamberLayer);
353 void RecoToTruthAssociationAlg::clear_dummys(
const std::vector<unsigned long long>&
identifiers, std::vector<unsigned int>&
vec)
const {
357 for (
unsigned int i = 0;
i <
vec.size(); ++
i) {
358 if (
vec[
i] != dummy_unsigned)
continue;
359 for (
unsigned j = 0; j <
identifiers.size(); ++j) {
361 if (m_idHelperSvc->measuresPhi(
id)) {
362 const auto phiIdx =
static_cast<PhiIndex>(
i);
363 if (m_idHelperSvc->phiIndex(
id) == phiIdx) {
368 const auto chIdx =
static_cast<ChIndex>(
i);
369 if (m_idHelperSvc->chamberIndex(
id) == chIdx) {