135 return StatusCode::SUCCESS;
139 return StatusCode::FAILURE;
152 for (
const auto truthMu : *TruthMuons) {
154 const int theType = truthTypeAcc(*truthMu);
155 const int theOrigin = truthOriginAcc(*truthMu);
156 ATH_MSG_VERBOSE(
"Truth muon: pt " << truthMu->pt() <<
" eta " << truthMu->eta());
157 ATH_MSG_VERBOSE(
"first loop: type " << theType <<
" origin " << theOrigin);
158 if (truthMu->pt() < 2000. || std::abs(truthMu->eta()) > 2.8)
continue;
159 if (std::abs(truthMu->eta()) > 2.5)
160 ATH_MSG_VERBOSE(
" SA |eta| > 2.5 muon with truth prec layers " << (
int)nprecLayersAcc(*truthMu));
162 if (std::abs(truthMu->eta()) > 2.5 && (
int)nprecLayersAcc(*truthMu) < 2)
continue;
163 if (theType != 6 && theType != 7)
continue;
164 if (theOrigin == 0 || theOrigin > 17)
continue;
165 bool insideID =
false;
166 if (std::abs(truthMu->eta()) < 2.0) insideID =
true;
167 ATH_MSG_VERBOSE(
"Accepted Truth muon: pt " << truthMu->pt() <<
" eta " << truthMu->eta());
173 for (
int n = 1; n < 6; n++)
m_ntruth[n] += 1;
175 for (
int n = 7; n < 11; n++)
m_ntruth[n] += 1;
177 if (truthMu->pt() > 5000.) {
182 for (
int n = 1; n < 6; n++)
m_ntruth5[n] += 1;
184 for (
int n = 7; n < 11; n++)
m_ntruth5[n] += 1;
187 if (truthMu->pt() > 10000.) {
192 for (
int n = 1; n < 6; n++)
m_ntruth10[n] += 1;
194 for (
int n = 7; n < 11; n++)
m_ntruth10[n] += 1;
198 link = recoMuonLinkAcc(*truthMu);
204 if (((*link)->quality() <= xAOD::Muon_v1::Loose)) loose =
true;
205 if (((*link)->quality() <= xAOD::Muon_v1::Medium)) medium =
true;
206 if (((*link)->quality() <= xAOD::Muon_v1::Tight)) tight =
true;
216 if (truthMu->pt() > 5000.)
m_ntruth5[6] += 1;
217 if (truthMu->pt() > 10000.)
m_ntruth10[6] += 1;
219 bool passesIDcuts =
passID(tp,
true);
220 ATH_MSG_VERBOSE(
" all authors " << (*link)->allAuthors() <<
" passesIDcuts " << passesIDcuts);
221 if (passesIDcuts != (*link)->passesIDCuts()) {
222 ATH_MSG_DEBUG(
" PROBLEM passedIDcuts from xAOD muon: " << (*link)->passesIDCuts()
223 <<
" BUT MuonPerformancAlg code gives " << passesIDcuts);
226 passesIDcuts = (*link)->passesIDCuts();
228 if (nprecLayersAcc(*truthMu) > 0) {
230 if (truthMu->pt() > 5000.)
m_ntruth5[11] += 1;
231 if (truthMu->pt() > 10000.)
m_ntruth10[11] += 1;
236 print(
" Muon not found by Loose ", truthMu);
240 print(
" Muon not found by Medium ", truthMu);
244 print(
" Muon not found by Tight ", truthMu);
246 if (truthMu->pt() > 5000.) {
252 if (truthMu->pt() > 10000.) {
259 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8)) {
261 if (truthMu->pt() > 5000.)
m_nfound5[5] += 1;
262 if (truthMu->pt() > 10000.)
m_nfound10[5] += 1;
264 print(
" Muon not found by CaloTag and Calolikelihood ", truthMu);
266 if (((*link)->allAuthors() & 32)) {
268 if (truthMu->pt() > 5000.)
m_nfound5[7] += 1;
269 if (truthMu->pt() > 10000.)
m_nfound10[7] += 1;
270 }
else if (!((*link)->allAuthors() & 2))
271 print(
" Muon not found by MuidSA ", truthMu);
273 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16)) {
275 if (truthMu->pt() > 5000.)
m_nfound5[4] += 1;
276 if (truthMu->pt() > 10000.)
m_nfound10[4] += 1;
278 print(
" Muon not found by MuTagIMO ", truthMu);
280 if (((*link)->allAuthors() & 64)) {
282 if (truthMu->pt() > 5000.)
m_nfound5[3] += 1;
283 if (truthMu->pt() > 10000.)
m_nfound10[3] += 1;
285 print(
" Muon not found by MuGirl ", truthMu);
287 if (((*link)->allAuthors() & 2)) {
289 if (truthMu->pt() > 5000.)
m_nfound5[2] += 1;
290 if (truthMu->pt() > 10000.)
m_nfound10[2] += 1;
292 print(
" Muon not found by MuidCo ", truthMu);
294 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
295 (*link)->muonType() == xAOD::Muon::MuonType::Combined) {
297 if (truthMu->pt() > 5000.)
m_nfound5[1] += 1;
298 if (truthMu->pt() > 10000.)
m_nfound10[1] += 1;
299 if (nprecLayersAcc(*truthMu) > 0) {
301 if (truthMu->pt() > 5000.)
m_nfound5[11] += 1;
302 if (truthMu->pt() > 10000.)
m_nfound10[11] += 1;
305 print(
" Combined Muon not found ", truthMu);
308 if (((*link)->allAuthors() & 32) || (*link)->muonType() == xAOD::Muon::MuonType::Combined) {
310 if (truthMu->pt() > 5000.)
m_nfound5[7] += 1;
311 if (truthMu->pt() > 10000.)
m_nfound10[7] += 1;
313 print(
" SA (CB) Muon not found ", truthMu);
317 else if (!insideID) {
318 if ((((*link)->allAuthors() & 32)) || ((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4)) {
320 if (truthMu->pt() > 5000.)
m_nfound5[0] += 1;
321 if (truthMu->pt() > 10000.)
m_nfound10[0] += 1;
323 print(
" Muon not found by MuidSA endcap ", truthMu);
326 if (truthMu->pt() > 5000.)
m_nfound5[10] += 1;
327 if (truthMu->pt() > 10000.)
m_nfound10[10] += 1;
329 print(
" Muon not found by Loose endcap ", truthMu);
332 if (truthMu->pt() > 5000.)
m_nfound5[9] += 1;
333 if (truthMu->pt() > 10000.)
m_nfound10[9] += 1;
335 print(
" Muon not found by Medium endcap ", truthMu);
338 print(
" No link Muon not found by CaloTag and Calolikelihood ", truthMu);
339 print(
" No link Muon not found by MuidSA ", truthMu);
340 print(
" No link Muon not found by MuTagIMO ", truthMu);
341 print(
" No link Muon not found by MuGirl ", truthMu);
342 print(
" No link Muon not found by MuidCo ", truthMu);
343 print(
" No link Combined Muon not found ", truthMu);
348 for (
const auto truthMu : *TruthMuons) {
350 if (truthMu->pt() < 2000. || std::abs(truthMu->eta()) > 3.)
continue;
351 const int theType = truthTypeAcc(*truthMu);
352 const int theOrigin = truthOriginAcc(*truthMu);
353 if (theType != 6 && theType != 7)
continue;
354 if (theOrigin == 0 || theOrigin > 17)
continue;
355 if (std::abs(truthMu->eta()) > 2.5 && (
int)nprecLayersAcc(*truthMu) < 2)
continue;
356 bool insideID =
false;
358 link = recoMuonLinkAcc(*truthMu);
362 if ((*link)->pt() < 2000. || std::abs((*link)->eta()) > 2.8)
continue;
363 if (std::abs((*link)->eta()) < 2.0) insideID =
true;
367 if (((*link)->quality() == xAOD::Muon_v1::Loose)) loose =
true;
368 if (((*link)->quality() == xAOD::Muon_v1::Medium)) loose =
true;
369 if (((*link)->quality() == xAOD::Muon_v1::Tight)) loose =
true;
370 if (((*link)->quality() == xAOD::Muon_v1::Medium)) medium =
true;
371 if (((*link)->quality() == xAOD::Muon_v1::Tight)) medium =
true;
372 if (((*link)->quality() == xAOD::Muon_v1::Tight)) tight =
true;
374 bool passesIDcuts =
passID(tp,
false);
376 passesIDcuts = (*link)->passesIDCuts();
382 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8))
m_nfoundr[5] += 1;
383 if (((*link)->allAuthors() & 32))
m_nfoundr[7] += 1;
384 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16))
m_nfoundr[4] += 1;
385 if (((*link)->allAuthors() & 64))
m_nfoundr[3] += 1;
386 if (((*link)->allAuthors() & 2))
m_nfoundr[2] += 1;
387 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
388 (*link)->muonType() == xAOD::Muon::MuonType::Combined)
390 if ((*link)->pt() > 5000.) {
395 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8))
m_nfoundr5[5] += 1;
396 if (((*link)->allAuthors() & 32))
m_nfoundr5[7] += 1;
397 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16))
m_nfoundr5[4] += 1;
398 if (((*link)->allAuthors() & 64))
m_nfoundr5[3] += 1;
399 if (((*link)->allAuthors() & 2))
m_nfoundr5[2] += 1;
400 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
401 (*link)->muonType() == xAOD::Muon::MuonType::Combined)
404 if ((*link)->pt() > 10000.) {
409 if (((*link)->allAuthors() & 64 * 4) || ((*link)->allAuthors() & 64 * 8))
m_nfoundr10[5] += 1;
410 if (((*link)->allAuthors() & 32))
m_nfoundr10[7] += 1;
411 if (((*link)->allAuthors() & 8) || ((*link)->allAuthors() & 16))
m_nfoundr10[4] += 1;
412 if (((*link)->allAuthors() & 64))
m_nfoundr10[3] += 1;
413 if (((*link)->allAuthors() & 2))
m_nfoundr10[2] += 1;
414 if (((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4) ||
415 (*link)->muonType() == xAOD::Muon::MuonType::Combined)
419 if (((*link)->allAuthors() & 32) || (*link)->muonType() == xAOD::Muon::MuonType::Combined) {
421 if ((*link)->pt() > 5000.)
m_nfoundr5[7] += 1;
425 }
else if (!insideID) {
426 if ((((*link)->allAuthors() & 32)) || ((*link)->allAuthors() & 2) || ((*link)->allAuthors() & 4)) {
428 if ((*link)->pt() > 5000.)
m_nfoundr5[0] += 1;
433 if ((*link)->pt() > 5000.) {
437 if ((*link)->pt() > 10000.) {
450 if (!
Muons.isValid()) {
452 return StatusCode::FAILURE;
456 for (
const auto mu : *
Muons) {
457 if (mu->pt() < 2000. || std::abs(mu->eta()) > 2.8)
continue;
462 bool passesIDcuts =
passID(tp,
false);
464 passesIDcuts = mu->passesIDCuts();
466 bool insideID =
false;
467 if (std::abs(mu->eta()) < 2.0) insideID =
true;
469 truthParticleLinkAcc (
"truthParticleLink");
471 truthLink = truthParticleLinkAcc(*tp);
474 if (
selectPdg((*truthLink)->pdgId())) fake =
false;
479 if (mu->quality() == xAOD::Muon_v1::Loose) loose =
true;
480 if (mu->quality() == xAOD::Muon_v1::Medium) loose =
true;
481 if (mu->quality() == xAOD::Muon_v1::Tight) loose =
true;
482 if (mu->quality() == xAOD::Muon_v1::Medium) medium =
true;
483 if (mu->quality() == xAOD::Muon_v1::Tight) medium =
true;
484 if (mu->quality() == xAOD::Muon_v1::Tight) tight =
true;
491 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
m_nreco[5] += 1;
492 if ((mu->allAuthors() & 32))
m_nreco[7] += 1;
493 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
m_nreco[4] += 1;
494 if ((mu->allAuthors() & 64))
m_nreco[3] += 1;
495 if ((mu->allAuthors() & 2))
m_nreco[2] += 1;
496 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
498 if (mu->pt() > 5000.) {
503 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
m_nreco5[5] += 1;
504 if ((mu->allAuthors() & 32))
m_nreco5[7] += 1;
505 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
m_nreco5[4] += 1;
506 if ((mu->allAuthors() & 64))
m_nreco5[3] += 1;
507 if ((mu->allAuthors() & 2))
m_nreco5[2] += 1;
508 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
511 if (mu->pt() > 10000.) {
516 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
m_nreco10[5] += 1;
517 if ((mu->allAuthors() & 32))
m_nreco10[7] += 1;
518 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
m_nreco10[4] += 1;
519 if ((mu->allAuthors() & 64))
m_nreco10[3] += 1;
520 if ((mu->allAuthors() & 2))
m_nreco10[2] += 1;
521 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
525 if ((mu->quality() == xAOD::Muon_v1::Loose))
print(
" Fake muon found by Loose ", mu);
526 if ((mu->quality() == xAOD::Muon_v1::Medium))
print(
" Fake muon found by Medium ", mu);
527 if ((mu->quality() == xAOD::Muon_v1::Tight))
print(
" Fake muon found by Tight ", mu);
528 if ((mu->allAuthors() & 64 * 4) || (mu->allAuthors() & 64 * 8))
529 print(
" Fake muon found by CaloTag and Calolikelihood ", mu);
530 if ((mu->allAuthors() & 32))
print(
" Fake muon found by MuidSA ", mu);
531 if ((mu->allAuthors() & 8) || (mu->allAuthors() & 16))
print(
" Fake muon found by MuTagIMO ", mu);
532 if ((mu->allAuthors() & 64))
print(
" Fake muon found by MuGirl ", mu);
533 if ((mu->allAuthors() & 2))
print(
" Fake muon found by MuidCo ", mu);
534 if ((mu->allAuthors() & 2) || (mu->allAuthors() & 4) || mu->muonType() == xAOD::Muon::MuonType::Combined)
535 print(
" Fake Combined muon ", mu);
538 if ((mu->allAuthors() & 32) || mu->muonType() == xAOD::Muon::MuonType::Combined) {
540 if (fake)
print(
" Fake muon found by MuidSA with no ID", mu);
541 if (mu->pt() > 5000.)
m_nreco5[7] += 1;
542 if (mu->pt() > 10000.)
m_nreco10[7] += 1;
545 }
else if (!insideID) {
548 if (loose && fake)
print(
" Fake muon found by Loose Endcap ", mu);
549 if (medium && fake && !loose)
print(
" Fake muon found by Medium Endcap ", mu);
550 if (tight && !medium && fake)
print(
" Fake muon found by Tight Endcap ", mu);
551 if (mu->pt() > 5000.) {
555 if (mu->pt() > 10000.) {
559 if (((mu->allAuthors() & 32)) || (mu->allAuthors() & 2) || (mu->allAuthors() & 4)) {
561 if (fake)
print(
" Fake muon found by MuidSA Endcap ", mu);
562 if (mu->pt() > 5000.)
m_nreco5[0] += 1;
563 if (mu->pt() > 10000.)
m_nreco10[0] += 1;
569 return StatusCode::SUCCESS;
597 std::ofstream fileOutput;
598 std::string outfile =
"muonPerformance_xAOD.txt";
599 fileOutput.open(outfile.c_str(), std::ios::trunc);
600 std::ostringstream sout;
603 unsigned int width = 9;
604 unsigned int precision = 3;
607 sout <<
" Summary of the xAOD Muon performance " << std::endl;
608 sout <<
" Muon type #Truth muons Efficiency #Truth muons Efficiency #Truth muons Efficiency" << std::endl;
609 sout <<
" (pt>2) (pt>5) (pt>10 GeV/c) " << std::endl;
610 for (
unsigned int i = 0; i < 12; ++i) {
612 sout <<
" " << std::endl;
615 sout << std::setw(
width) << std::setprecision(precision);
616 sout << static_cast<double>(
m_ntruth[i]);
618 sout << std::setw(
width) << std::setprecision(precision);
619 sout << static_cast<double>(
m_nfound[i]) /
static_cast<double>(
m_ntruth[i]);
620 sout << std::setw(
width) << std::setprecision(precision);
621 sout << static_cast<double>(
m_ntruth5[i]);
623 sout << std::setw(
width) << std::setprecision(precision);
629 sout << std::setw(
width) << std::setprecision(precision);
632 sout << std::setw(
width) << std::setprecision(precision);
636 sout << 0. << std::endl;
639 sout <<
" The efficiency of the ID is calculated inside |eta| < 2 for the MCP ID hit selection cuts (it uses identified - Combined, "
640 "Tagged or CaloTagged - muons with an ID track)"
642 sout <<
" The efficiencies for CB all, MuidCB, MuGirl, Tag and Calo include the MCP ID cuts" << std::endl;
643 sout <<
" The Tight, Medium and Loose efficiencies include MCP ID cuts for muons |eta| < 2" << std::endl;
644 sout <<
" The SA 2.0 for |eta| >2 and SA (no ID) for |eta| < 2 doesnot include MCP ID cuts" << std::endl;
645 sout <<
" The Combined efficiency is defined ID tracks after MCP cuts and requiring at least 1 muon station at truth level"
647 sout <<
" Fakes are calculated with the selections listed above" << std::endl;
650 sout <<
" Muon type #Fake muons rate #Fake muons rate #Fake muons rate " << std::endl;
651 sout <<
" (all pt>0,2) (pt>5) (pt>10 GeV/c) " << std::endl;
652 for (
unsigned int i = 0; i < 11; ++i) {
653 if (i == 6)
continue;
655 sout <<
" " << std::endl;
658 sout << std::setw(
width) << std::setprecision(precision);
660 sout << std::setw(
width) << std::setprecision(precision);
662 sout << std::setw(
width) << std::setprecision(precision);
664 sout << std::setw(
width) << std::setprecision(precision);
666 sout << std::setw(
width) << std::setprecision(precision);
668 sout << std::setw(
width) << std::setprecision(precision);
673 fileOutput << sout.str() << std::endl;
675 return StatusCode::SUCCESS;