ATLAS Offline Software
Loading...
Searching...
No Matches
EgammaFSRForMuonsCollectorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// EgammaFSRForMuonsCollectorAlg
7//
8// Algorithm to collect photons and electrons which close in dR
9// to muons as FSR candidates
11
14#include <xAODEgamma/Electron.h>
15
17
19
20namespace CP
21{
23 {
28 ANA_CHECK(m_systematicsList.initialize());
29
30 if (!m_vetoFSR) {
31 ATH_MSG_INFO("Reading container " << m_egammaContKey.getNamePattern() << " for FSR search for muons from " << m_muonContKey.getNamePattern() << ". Those passing " << m_wpSelection.getSelectionName() << " are also accepted.");
32 }
33 else {
34 ATH_MSG_INFO("Reading container " << m_egammaContKey.getNamePattern() << " for FSR search for muons from " << m_muonContKey.getNamePattern() << ". The electrons or photons matching FSR requirements with muons will be vetoed with " << m_outputDec.getDecorName());
35 }
36
37 // Return gracefully:
38 return StatusCode::SUCCESS;
39 }
40
41
42 StatusCode EgammaFSRForMuonsCollectorAlg::execute(const EventContext& ctx)
43 {
44 // Loop over systematics
45 for (const auto& sys : m_systematicsList.systematicsVector()) {
46
47 // Retrieve electrons or photons
48 const xAOD::IParticleContainer* egammaCont = nullptr;
49 ANA_CHECK(m_egammaContKey.retrieve(egammaCont, sys, ctx));
50
51 // Retrieve muons
52 const xAOD::MuonContainer* muonCont = nullptr;
53 ANA_CHECK(m_muonContKey.retrieve(muonCont, sys, ctx));
54
55 // Loop over each electron or photon and compute the combined selection
56 for (const xAOD::IParticle* eg : *egammaCont) {
57
58 // Read the WP selection (if configured)
59 bool passesWP = m_wpSelection.getBool(*eg, sys);
60
61 // Check if this particle passes FSR criteria (close to a muon)
62 bool passesFSR = false;
63
64 const xAOD::Electron* el = (eg->type() == xAOD::Type::Electron)
65 ? static_cast<const xAOD::Electron*>(eg) : nullptr;
66
67 ATH_MSG_DEBUG("Incoming eg: pt, eta, phi " << eg->pt()/1000. << ", "
68 << eg->eta() << ", " << eg->phi() << ", is electron " << (el != nullptr)
69 << ", passesWP " << passesWP);
70
71 // The FSR match only matters if the WP selection alone does not decide the outcome:
72 // normal mode is WP || FSR, veto mode is WP && !FSR
73 const bool needFSR = (m_vetoFSR == passesWP);
74
75 // Loop over muons and check dR
76 if (needFSR) {
77 for (const xAOD::Muon* mu : *muonCont) {
78 double dR = xAOD::P4Helpers::deltaR(*eg, *mu);
79
80 ATH_MSG_DEBUG("dR with mu: " << dR << ", pt, eta, phi "
81 << mu->pt()/1000. << ", " << mu->eta() << ", " << mu->phi());
82
83 if (dR < m_dRMax) {
84 // if electron (not photon) check track matching
85 bool elmutrackmatchOK = true; // default true for photons
86 if (el) {
87 const xAOD::TrackParticle* electron_track = el->trackParticle();
89 const xAOD::TrackParticle* muon_track = mu->trackParticle(xAOD::Muon::TrackParticleType::Primary);
90
91 if (electron_track && muon_track) {
92 elmutrackmatchOK =
93 (std::abs(electron_track->theta() - muon_track->theta()) < 0.01) &&
94 (std::abs(xAOD::P4Helpers::deltaPhi(electron_track->phi(), muon_track->phi())) < 0.01);
95 ATH_MSG_DEBUG("dtheta trk " << std::abs(electron_track->theta() - muon_track->theta())
96 << ", dphi trk " << std::abs(xAOD::P4Helpers::deltaPhi(electron_track->phi(), muon_track->phi())));
97 if (elOrig_track) {
98 ATH_MSG_DEBUG("origTrk: dtheta trk " << std::abs(elOrig_track->theta() - muon_track->theta())
99 << ", dphi trk " << std::abs(xAOD::P4Helpers::deltaPhi(elOrig_track->phi(), muon_track->phi())));
100 }
101 } else {
102 elmutrackmatchOK = false;
103 }
104 ATH_MSG_DEBUG("track match " << (elmutrackmatchOK ? "OK" : "NOT OK"));
105 }
106
107 if (elmutrackmatchOK) {
108 passesFSR = true;
109 ATH_MSG_DEBUG("FSR match found");
110 break;
111 }
112 }
113 }
114 }
115
116 // Compute and write the output selection
117 char outputValue;
118 if (!m_vetoFSR) {
119 // Normal mode: output = WP || FSR
120 outputValue = (passesWP || passesFSR) ? 1 : 0;
121 } else {
122 // Veto mode: output = WP && !FSR
123 outputValue = (passesWP && !passesFSR) ? 1 : 0;
124 }
125
126 m_outputDec.set(*eg, outputValue, sys);
127 ATH_MSG_DEBUG("Output selection: " << static_cast<int>(outputValue)
128 << " (passesWP=" << passesWP << ", passesFSR=" << passesFSR << ")");
129 }
130 }
131
132 ATH_MSG_DEBUG("Done !");
133
134 return StatusCode::SUCCESS;
135 }
136
137}
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_INFO(x,...)
#define ANA_CHECK(EXP)
check whether the given expression was successful
SysReadSelectionHandle m_wpSelection
the input WP selection to combine with FSR
SysWriteDecorHandle< char > m_outputDec
the output combined WP||FSR selection
SysListHandle m_systematicsList
the systematics list we run
Gaudi::Property< float > m_dRMax
Protected data:
SysReadHandle< xAOD::IParticleContainer > m_egammaContKey
SysReadHandle< xAOD::MuonContainer > m_muonContKey
virtual::StatusCode execute()
execute this algorithm
Class providing the definition of the 4-vector interface.
float theta() const
Returns the parameter, which has range 0 to .
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
Select isolated Photons, Electrons and Muons.
@ Electron
The object is an electron.
Definition ObjectType.h:46
const xAOD::TrackParticle * getOriginalTrackParticle(const xAOD::Electron *el)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the electron.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
Electron_v1 Electron
Definition of the current "egamma version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.