129 const EventContext& ctx = Gaudi::Hive::currentContext();
138 return StatusCode::SUCCESS;
142 return StatusCode::FAILURE;
156 for (
const auto truthMu : *TruthMuons) {
158 const int theType = truthTypeAcc(*truthMu);
159 const int theOrigin = truthOriginAcc(*truthMu);
160 const unsigned int theClassification = truthClassificationAcc(*truthMu);
161 ATH_MSG_VERBOSE(
"Truth muon: pt " << truthMu->pt() <<
" eta " << truthMu->eta());
162 ATH_MSG_VERBOSE(
"first loop: type " << theType <<
" origin " << theOrigin <<
" classification " << theClassification);
163 if (truthMu->pt() < 2000. || std::abs(truthMu->eta()) > 2.8)
continue;
164 if (std::abs(truthMu->eta()) > 2.5)
165 ATH_MSG_VERBOSE(
" SA |eta| > 2.5 muon with truth prec layers " << (
int)nprecLayersAcc(*truthMu));
167 if (std::abs(truthMu->eta()) > 2.5 && (
int)nprecLayersAcc(*truthMu) < 2)
continue;
168 if (theType != 6 && theType != 7)
continue;
169 if (theOrigin == 0 || theOrigin > 17)
continue;
170 bool insideID =
false;
171 if (std::abs(truthMu->eta()) < 2.0) insideID =
true;
172 ATH_MSG_VERBOSE(
"Accepted Truth muon: pt " << truthMu->pt() <<
" eta " << truthMu->eta());
178 for (
int n = 1; n < 6; n++)
m_ntruth[n] += 1;
180 for (
int n = 7; n < 11; n++)
m_ntruth[n] += 1;
182 if (truthMu->pt() > 5000.) {
187 for (
int n = 1; n < 6; n++)
m_ntruth5[n] += 1;
189 for (
int n = 7; n < 11; n++)
m_ntruth5[n] += 1;
192 if (truthMu->pt() > 10000.) {
197 for (
int n = 1; n < 6; n++)
m_ntruth10[n] += 1;
199 for (
int n = 7; n < 11; n++)
m_ntruth10[n] += 1;
203 link = recoMuonLinkAcc(*truthMu);
209 if (((*link)->quality() <= xAOD::Muon_v1::Loose)) loose =
true;
210 if (((*link)->quality() <= xAOD::Muon_v1::Medium)) medium =
true;
211 if (((*link)->quality() <= xAOD::Muon_v1::Tight)) tight =
true;
221 if (truthMu->pt() > 5000.)
m_ntruth5[6] += 1;
222 if (truthMu->pt() > 10000.)
m_ntruth10[6] += 1;
224 bool passesIDcuts =
passID(tp,
true);
225 ATH_MSG_VERBOSE(
" all authors " << (*link)->allAuthors() <<
" passesIDcuts " << passesIDcuts);
226 if (passesIDcuts != (*link)->passesIDCuts()) {
227 ATH_MSG_DEBUG(
" PROBLEM passedIDcuts from xAOD muon: " << (*link)->passesIDCuts()
228 <<
" BUT MuonPerformancAlg code gives " << passesIDcuts);
231 passesIDcuts = (*link)->passesIDCuts();
233 if (nprecLayersAcc(*truthMu) > 0) {
235 if (truthMu->pt() > 5000.)
m_ntruth5[11] += 1;
236 if (truthMu->pt() > 10000.)
m_ntruth10[11] += 1;
241 print(
" Muon not found by Loose ", truthMu);
245 print(
" Muon not found by Medium ", truthMu);
249 print(
" Muon not found by Tight ", truthMu);
251 if (truthMu->pt() > 5000.) {
257 if (truthMu->pt() > 10000.) {
264 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8)) {
266 if (truthMu->pt() > 5000.)
m_nfound5[5] += 1;
267 if (truthMu->pt() > 10000.)
m_nfound10[5] += 1;
269 print(
" Muon not found by CaloTag and Calolikelihood ", truthMu);
271 if (((*link)->allAuthors() & 32)) {
273 if (truthMu->pt() > 5000.)
m_nfound5[7] += 1;
274 if (truthMu->pt() > 10000.)
m_nfound10[7] += 1;
275 }
else if (!((*link)->allAuthors() & 2))
276 print(
" Muon not found by MuidSA ", truthMu);
278 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16)) {
280 if (truthMu->pt() > 5000.)
m_nfound5[4] += 1;
281 if (truthMu->pt() > 10000.)
m_nfound10[4] += 1;
283 print(
" Muon not found by MuTagIMO ", truthMu);
285 if (((*link)->allAuthors() & 64)) {
287 if (truthMu->pt() > 5000.)
m_nfound5[3] += 1;
288 if (truthMu->pt() > 10000.)
m_nfound10[3] += 1;
290 print(
" Muon not found by MuGirl ", truthMu);
292 if (((*link)->allAuthors() & 2)) {
294 if (truthMu->pt() > 5000.)
m_nfound5[2] += 1;
295 if (truthMu->pt() > 10000.)
m_nfound10[2] += 1;
297 print(
" Muon not found by MuidCo ", truthMu);
299 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
300 (*link)->muonType() == xAOD::Muon::MuonType::Combined) {
302 if (truthMu->pt() > 5000.)
m_nfound5[1] += 1;
303 if (truthMu->pt() > 10000.)
m_nfound10[1] += 1;
304 if (nprecLayersAcc(*truthMu) > 0) {
306 if (truthMu->pt() > 5000.)
m_nfound5[11] += 1;
307 if (truthMu->pt() > 10000.)
m_nfound10[11] += 1;
310 print(
" Combined Muon not found ", truthMu);
313 if (((*link)->allAuthors() & 32) || (*link)->muonType() == xAOD::Muon::MuonType::Combined) {
315 if (truthMu->pt() > 5000.)
m_nfound5[7] += 1;
316 if (truthMu->pt() > 10000.)
m_nfound10[7] += 1;
318 print(
" SA (CB) Muon not found ", truthMu);
322 else if (!insideID) {
323 if ((((*link)->allAuthors() & 32)) || ((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4)) {
325 if (truthMu->pt() > 5000.)
m_nfound5[0] += 1;
326 if (truthMu->pt() > 10000.)
m_nfound10[0] += 1;
328 print(
" Muon not found by MuidSA endcap ", truthMu);
331 if (truthMu->pt() > 5000.)
m_nfound5[10] += 1;
332 if (truthMu->pt() > 10000.)
m_nfound10[10] += 1;
334 print(
" Muon not found by Loose endcap ", truthMu);
337 if (truthMu->pt() > 5000.)
m_nfound5[9] += 1;
338 if (truthMu->pt() > 10000.)
m_nfound10[9] += 1;
340 print(
" Muon not found by Medium endcap ", truthMu);
343 print(
" No link Muon not found by CaloTag and Calolikelihood ", truthMu);
344 print(
" No link Muon not found by MuidSA ", truthMu);
345 print(
" No link Muon not found by MuTagIMO ", truthMu);
346 print(
" No link Muon not found by MuGirl ", truthMu);
347 print(
" No link Muon not found by MuidCo ", truthMu);
348 print(
" No link Combined Muon not found ", truthMu);
353 for (
const auto truthMu : *TruthMuons) {
355 if (truthMu->pt() < 2000. || std::abs(truthMu->eta()) > 3.)
continue;
356 const int theType = truthTypeAcc(*truthMu);
357 const int theOrigin = truthOriginAcc(*truthMu);
358 if (theType != 6 && theType != 7)
continue;
359 if (theOrigin == 0 || theOrigin > 17)
continue;
360 if (std::abs(truthMu->eta()) > 2.5 && (
int)nprecLayersAcc(*truthMu) < 2)
continue;
361 bool insideID =
false;
363 link = recoMuonLinkAcc(*truthMu);
367 if ((*link)->pt() < 2000. || std::abs((*link)->eta()) > 2.8)
continue;
368 if (std::abs((*link)->eta()) < 2.0) insideID =
true;
372 if (((*link)->quality() == xAOD::Muon_v1::Loose)) loose =
true;
373 if (((*link)->quality() == xAOD::Muon_v1::Medium)) loose =
true;
374 if (((*link)->quality() == xAOD::Muon_v1::Tight)) loose =
true;
375 if (((*link)->quality() == xAOD::Muon_v1::Medium)) medium =
true;
376 if (((*link)->quality() == xAOD::Muon_v1::Tight)) medium =
true;
377 if (((*link)->quality() == xAOD::Muon_v1::Tight)) tight =
true;
379 bool passesIDcuts =
passID(tp,
false);
381 passesIDcuts = (*link)->passesIDCuts();
387 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8))
m_nfoundr[5] += 1;
388 if (((*link)->allAuthors() & 32))
m_nfoundr[7] += 1;
389 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16))
m_nfoundr[4] += 1;
390 if (((*link)->allAuthors() & 64))
m_nfoundr[3] += 1;
391 if (((*link)->allAuthors() & 2))
m_nfoundr[2] += 1;
392 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
393 (*link)->muonType() == xAOD::Muon::MuonType::Combined)
395 if ((*link)->pt() > 5000.) {
400 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8))
m_nfoundr5[5] += 1;
401 if (((*link)->allAuthors() & 32))
m_nfoundr5[7] += 1;
402 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16))
m_nfoundr5[4] += 1;
403 if (((*link)->allAuthors() & 64))
m_nfoundr5[3] += 1;
404 if (((*link)->allAuthors() & 2))
m_nfoundr5[2] += 1;
405 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
406 (*link)->muonType() == xAOD::Muon::MuonType::Combined)
409 if ((*link)->pt() > 10000.) {
414 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8))
m_nfoundr10[5] += 1;
415 if (((*link)->allAuthors() & 32))
m_nfoundr10[7] += 1;
416 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16))
m_nfoundr10[4] += 1;
417 if (((*link)->allAuthors() & 64))
m_nfoundr10[3] += 1;
418 if (((*link)->allAuthors() & 2))
m_nfoundr10[2] += 1;
419 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
420 (*link)->muonType() == xAOD::Muon::MuonType::Combined)
424 if (((*link)->allAuthors() & 32) || (*link)->muonType() == xAOD::Muon::MuonType::Combined) {
426 if ((*link)->pt() > 5000.)
m_nfoundr5[7] += 1;
430 }
else if (!insideID) {
431 if ((((*link)->allAuthors() & 32)) || ((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4)) {
433 if ((*link)->pt() > 5000.)
m_nfoundr5[0] += 1;
438 if ((*link)->pt() > 5000.) {
442 if ((*link)->pt() > 10000.) {
455 if (!
Muons.isValid()) {
457 return StatusCode::FAILURE;
461 for (
const auto mu : *
Muons) {
462 if (mu->pt() < 2000. || std::abs(mu->eta()) > 2.8)
continue;
467 bool passesIDcuts =
passID(tp,
false);
469 passesIDcuts = mu->passesIDCuts();
471 bool insideID =
false;
472 if (std::abs(mu->eta()) < 2.0) insideID =
true;
474 truthParticleLinkAcc (
"truthParticleLink");
476 truthLink = truthParticleLinkAcc(*tp);
479 if (
selectPdg((*truthLink)->pdgId())) fake =
false;
484 if (mu->quality() == xAOD::Muon_v1::Loose) loose =
true;
485 if (mu->quality() == xAOD::Muon_v1::Medium) loose =
true;
486 if (mu->quality() == xAOD::Muon_v1::Tight) loose =
true;
487 if (mu->quality() == xAOD::Muon_v1::Medium) medium =
true;
488 if (mu->quality() == xAOD::Muon_v1::Tight) medium =
true;
489 if (mu->quality() == xAOD::Muon_v1::Tight) tight =
true;
496 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
m_nreco[5] += 1;
497 if ((mu->allAuthors() & 32))
m_nreco[7] += 1;
498 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
m_nreco[4] += 1;
499 if ((mu->allAuthors() & 64))
m_nreco[3] += 1;
500 if ((mu->allAuthors() & 2))
m_nreco[2] += 1;
501 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
503 if (mu->pt() > 5000.) {
508 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
m_nreco5[5] += 1;
509 if ((mu->allAuthors() & 32))
m_nreco5[7] += 1;
510 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
m_nreco5[4] += 1;
511 if ((mu->allAuthors() & 64))
m_nreco5[3] += 1;
512 if ((mu->allAuthors() & 2))
m_nreco5[2] += 1;
513 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
516 if (mu->pt() > 10000.) {
521 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
m_nreco10[5] += 1;
522 if ((mu->allAuthors() & 32))
m_nreco10[7] += 1;
523 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
m_nreco10[4] += 1;
524 if ((mu->allAuthors() & 64))
m_nreco10[3] += 1;
525 if ((mu->allAuthors() & 2))
m_nreco10[2] += 1;
526 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
530 if ((mu->quality() == xAOD::Muon_v1::Loose))
print(
" Fake muon found by Loose ", mu);
531 if ((mu->quality() == xAOD::Muon_v1::Medium))
print(
" Fake muon found by Medium ", mu);
532 if ((mu->quality() == xAOD::Muon_v1::Tight))
print(
" Fake muon found by Tight ", mu);
533 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
534 print(
" Fake muon found by CaloTag and Calolikelihood ", mu);
535 if ((mu->allAuthors() & 32))
print(
" Fake muon found by MuidSA ", mu);
536 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
print(
" Fake muon found by MuTagIMO ", mu);
537 if ((mu->allAuthors() & 64))
print(
" Fake muon found by MuGirl ", mu);
538 if ((mu->allAuthors() & 2))
print(
" Fake muon found by MuidCo ", mu);
539 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
540 print(
" Fake Combined muon ", mu);
543 if ((mu->allAuthors() & 32) || mu->muonType() == xAOD::Muon::MuonType::Combined) {
545 if (fake)
print(
" Fake muon found by MuidSA with no ID", mu);
546 if (mu->pt() > 5000.)
m_nreco5[7] += 1;
547 if (mu->pt() > 10000.)
m_nreco10[7] += 1;
550 }
else if (!insideID) {
553 if (loose && fake)
print(
" Fake muon found by Loose Endcap ", mu);
554 if (medium && fake && !loose)
print(
" Fake muon found by Medium Endcap ", mu);
555 if (tight && !medium && fake)
print(
" Fake muon found by Tight Endcap ", mu);
556 if (mu->pt() > 5000.) {
560 if (mu->pt() > 10000.) {
564 if (((mu->allAuthors() & 32)) || (mu->allAuthors() & 2) || (mu->allAuthors() & 4)) {
566 if (fake)
print(
" Fake muon found by MuidSA Endcap ", mu);
567 if (mu->pt() > 5000.)
m_nreco5[0] += 1;
568 if (mu->pt() > 10000.)
m_nreco10[0] += 1;
574 return StatusCode::SUCCESS;
602 std::ofstream fileOutput;
603 std::string outfile =
"muonPerformance_xAOD.txt";
604 fileOutput.open(outfile.c_str(), std::ios::trunc);
605 std::ostringstream sout;
608 unsigned int width = 9;
609 unsigned int precision = 3;
612 sout <<
" Summary of the xAOD Muon performance " << std::endl;
613 sout <<
" Muon type #Truth muons Efficiency #Truth muons Efficiency #Truth muons Efficiency" << std::endl;
614 sout <<
" (pt>2) (pt>5) (pt>10 GeV/c) " << std::endl;
615 for (
unsigned int i = 0; i < 12; ++i) {
617 sout <<
" " << std::endl;
620 sout << std::setw(
width) << std::setprecision(precision);
621 sout << static_cast<double>(
m_ntruth[i]);
623 sout << std::setw(
width) << std::setprecision(precision);
624 sout << static_cast<double>(
m_nfound[i]) /
static_cast<double>(
m_ntruth[i]);
625 sout << std::setw(
width) << std::setprecision(precision);
626 sout << static_cast<double>(
m_ntruth5[i]);
628 sout << std::setw(
width) << std::setprecision(precision);
634 sout << std::setw(
width) << std::setprecision(precision);
637 sout << std::setw(
width) << std::setprecision(precision);
641 sout << 0. << std::endl;
644 sout <<
" The efficiency of the ID is calculated inside |eta| < 2 for the MCP ID hit selection cuts (it uses identified - Combined, "
645 "Tagged or CaloTagged - muons with an ID track)"
647 sout <<
" The efficiencies for CB all, MuidCB, MuGirl, Tag and Calo include the MCP ID cuts" << std::endl;
648 sout <<
" The Tight, Medium and Loose efficiencies include MCP ID cuts for muons |eta| < 2" << std::endl;
649 sout <<
" The SA 2.0 for |eta| >2 and SA (no ID) for |eta| < 2 doesnot include MCP ID cuts" << std::endl;
650 sout <<
" The Combined efficiency is defined ID tracks after MCP cuts and requiring at least 1 muon station at truth level"
652 sout <<
" Fakes are calculated with the selections listed above" << std::endl;
655 sout <<
" Muon type #Fake muons rate #Fake muons rate #Fake muons rate " << std::endl;
656 sout <<
" (all pt>0,2) (pt>5) (pt>10 GeV/c) " << std::endl;
657 for (
unsigned int i = 0; i < 11; ++i) {
658 if (i == 6)
continue;
660 sout <<
" " << std::endl;
663 sout << std::setw(
width) << std::setprecision(precision);
665 sout << std::setw(
width) << std::setprecision(precision);
667 sout << std::setw(
width) << std::setprecision(precision);
669 sout << std::setw(
width) << std::setprecision(precision);
671 sout << std::setw(
width) << std::setprecision(precision);
673 sout << std::setw(
width) << std::setprecision(precision);
678 fileOutput << sout.str() << std::endl;
680 return StatusCode::SUCCESS;