ATLAS Offline Software
DiMuonTaggingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 #include "GaudiKernel/SystemOfUnits.h"
13 namespace {
15  constexpr double MeVtoGeV = 1./ Gaudi::Units::GeV;
16 
17 }
18 namespace DerivationFramework {
19  DiMuonTaggingAlg::DiMuonTaggingAlg(const std::string& name, ISvcLocator* pSvcLocator) :
20  AthReentrantAlgorithm(name, pSvcLocator) {}
21 
22  // Athena initialize and finalize
24  ATH_MSG_VERBOSE("initialize() ...");
25 
26  // trigger decision tool, needed when there is trigger requirement
27  if (!m_applyTrig) {
28  m_orTrigs.clear();
29  m_andTrigs.clear();
30  }
31  const bool has_trigs = m_orTrigs.size() || m_andTrigs.size();
32  ATH_CHECK(m_matchingTool.retrieve(EnableTool{has_trigs}));
33 
34  ATH_CHECK(m_muonSGKey.initialize());
37  ATH_CHECK(m_muonSelTool.retrieve(EnableTool{m_applyQualityMu1 || m_applyQualityMu2}));
38  m_muonKeepKey = "pass" + m_br_prefix.value();
39  m_trkKeepKey = "pass" + m_br_prefix.value();
40  m_skimmingKey = "DIMU_pass" + m_br_prefix;
41  ATH_CHECK(m_muonKeepKey.initialize());
44 
48 
49  return StatusCode::SUCCESS;
50  }
51 
52  StatusCode DiMuonTaggingAlg::execute(const EventContext& ctx) const {
53  SG::WriteHandle<int> keepEventHandle{m_skimmingKey, ctx};
54  ATH_CHECK(keepEventHandle.record(std::make_unique<int>(0)));
55  int& keepEvent = *keepEventHandle;
56 
59  if (!muons.isValid()) {
60  ATH_MSG_FATAL("Failed to retrieve " << m_muonSGKey.fullKey());
61  return StatusCode::FAILURE;
62  }
63  MuonPassDecor muo_decor{makeHandle<bool>(ctx, m_muonKeepKey)};
64  ATH_MSG_VERBOSE("Event "<<ctx.eventID().event_number()<<" - Retrieved muon Container from "<<m_muonSGKey.fullKey()<<" which contains "
65  <<muons->size()<<" muons. Created "<<muo_decor.decorKey()
66  <<" "<<SG::AuxTypeRegistry::instance().getName(muo_decor.auxid()));
67 
68 
70  std::vector<const xAOD::TruthParticle*> truth{};
71  if (!m_truthSGKey.empty()) {
72 
74  if (!handle.isValid()) {
75  ATH_MSG_FATAL("Failed to retrieve truth container " << m_truthSGKey.fullKey());
76  return StatusCode::FAILURE;
77  }
78  truth.reserve(handle->size());
79  std::copy_if(handle->begin(), handle->end(), std::back_inserter(truth),
80  [](const xAOD::TruthParticle* tpart) {
81  return MC::isStable(tpart) &&
82  !HepMC::is_simulation_particle(tpart) &&
83  tpart->isMuon();
84  });
85  }
86  for (const xAOD::Muon* mu_itr1 : *muons) {
88  if(std::find_if(truth.begin(), truth.end(),
89  [&](const xAOD::TruthParticle* truth_itr) {
90  return xAOD::P4Helpers::deltaR2(truth_itr, mu_itr1) < m_thinningConeSize2;
91  }) != truth.end()){
92  muo_decor(*mu_itr1) = true;
93  }
94 
95  ATH_MSG_VERBOSE("Check tag muon: "<<mu_itr1->pt() * MeVtoGeV<<" [GeV], eta: "<<mu_itr1->eta()
96  <<", phi: "<<mu_itr1->phi()<<", author: "<<mu_itr1->author());
98  ATH_MSG_VERBOSE("Muon failed selection criteria");
99  continue;
100  }
101  bool passOrTrig = passTrigger(mu_itr1, m_orTrigs);
102  bool passAndTrig = !m_andTrigs.empty() && passTrigger(mu_itr1, m_andTrigs);
103  for (const xAOD::Muon* mu_itr2 : *muons) {
104  if (mu_itr2 == mu_itr1) continue;
105  ATH_MSG_VERBOSE("Check probe muon: "<<mu_itr2->pt() * MeVtoGeV<<" [GeV], eta: "<<mu_itr2->eta()
106  <<", phi: "<<mu_itr2->phi()<<", author: "<<mu_itr2->author());
108  continue;
109  }
110  if (!muonPairCheck(mu_itr1, mu_itr2)) continue;
111  bool passDiLepTrig = passOrTrig || passTrigger(mu_itr2, m_orTrigs) || (passAndTrig && passTrigger(mu_itr2, m_andTrigs));
112  if (!passDiLepTrig) {
113  ATH_MSG_DEBUG("Trigger selection failed");
114  continue;
115  }
116  muo_decor(*mu_itr1) = true;
117  muo_decor(*mu_itr2) = true;
118  ATH_MSG_VERBOSE("T&P pair accepted");
119  ++keepEvent;
120  }
121  }
122  if (!m_useTrackProbe) {
123  return StatusCode::SUCCESS;
124  }
125 
127  if (!tracks.isValid()) {
128  ATH_MSG_FATAL("Failed to retrieve " << m_trackSGKey.fullKey());
129  return StatusCode::FAILURE;
130  }
131  ATH_MSG_VERBOSE("Event "<<ctx.eventID().event_number()<<" - Retrieved track Container from "<<m_trackSGKey.fullKey()<<" which contains "
132  <<tracks->size()<<" tracks.");
133  TrackPassDecor trk_decor{makeHandle<bool>(ctx, m_trkKeepKey)};
134  for (const xAOD::Muon* mu_itr1 : *muons) {
136  ATH_MSG_VERBOSE("Muon does not pass the trigger selection");
137  continue;
138  }
139  if (!passTrigger(mu_itr1, m_orTrigs)) {
140  ATH_MSG_VERBOSE("Muon does not trigger the event");
141  continue;
142  }
143 
144  for (const xAOD::TrackParticle* probe_trk : *tracks) {
145  if (probe_trk == mu_itr1->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle)) continue;
146  if (!passKinematicCuts(probe_trk, m_mu2PtMin, m_mu2AbsEtaMax)) continue;
147  if (!muonPairCheck(mu_itr1, probe_trk)) continue;
148  trk_decor(*probe_trk) = true;
149  ++keepEvent;
152  maskNearbyIDtracks(probe_trk, trk_decor);
153 
154  }
155  }
157  for (const xAOD::TruthParticle* mu_itr2 : truth) {
158  maskNearbyIDtracks(mu_itr2, trk_decor);
159  }
160  for (const xAOD::Muon* mu_itr : *muons) {
161  passKinematicCuts(mu_itr, -1., -1.);
162  ATH_MSG_VERBOSE("Pass decoration "<<muo_decor(*mu_itr));
163  }
164  return StatusCode::SUCCESS;
165  }
167  for (const xAOD::TrackParticle* trk : *decor) {
168  if (xAOD::P4Helpers::deltaR2(ref_part, trk) < m_thinningConeSize2) decor(*trk) = true;
169  }
170  }
171  bool DiMuonTaggingAlg::passKinematicCuts(const xAOD::IParticle* mu, const float ptMin, const float absEtaMax) const {
172  ATH_MSG_VERBOSE("Particle with pt: "<<mu->pt() * MeVtoGeV<<" [GeV], eta: "<<mu->eta()
173  <<", phi: "<<mu->phi()<<", needs to be more energetic than "<<ptMin * MeVtoGeV<<" [GeV] and within "<<absEtaMax);
174  return !(!mu || mu->pt() < ptMin || std::abs(mu->eta()) > absEtaMax);
175  }
176  bool DiMuonTaggingAlg::passMuonCuts(const xAOD::Muon* muon, const float ptMin, const float absEtaMax, const bool applyQuality) const{
177  return passKinematicCuts(muon, ptMin, absEtaMax) && (!applyQuality || m_muonSelTool->accept(*muon));
178  }
179  bool DiMuonTaggingAlg::passTrigger(const xAOD::Muon* muon, const std::vector<std::string>& trigList) const {
180  return trigList.empty() || std::find_if(trigList.begin(), trigList.end(), [&](const std::string& trig_item){
181  return m_matchingTool->match(*muon, trig_item, m_triggerMatchDeltaR);
182  }) != trigList.end();
183  }
184  template <class probe_type> bool DiMuonTaggingAlg::muonPairCheck(const xAOD::Muon* mu1, const probe_type* mu2) const {
185  if (m_requireOS != (mu1->charge() * mu2->charge() < 0)) {
186  ATH_MSG_VERBOSE("Charge cut failed ");
187  return false;
188  }
189  if (m_dPhiMin > 0 && std::abs(xAOD::P4Helpers::deltaPhi(mu1, mu2)) < m_dPhiMin) {
190  ATH_MSG_VERBOSE("Delta phi cut "<<m_dPhiMin<<" was undercut "<<std::abs(xAOD::P4Helpers::deltaPhi(mu1, mu2)));
191  return false;
192  }
193  const float mass2 = (mu1->p4() + mu2->p4()).M2();
194  ATH_MSG_VERBOSE("Invariant mass "<<std::sqrt(mass2)*MeVtoGeV<<" need to be in the window ["
196  return !(mass2 < m_invariantMassLow2 || (m_invariantMassHigh > 0. && mass2 > m_invariantMassHigh2));
197  }
198 } // namespace DerivationFramework
DerivationFramework::DiMuonTaggingAlg::m_applyQualityMu1
Gaudi::Property< bool > m_applyQualityMu1
Flag to toggle whether selection working point should be applied on the first muon.
Definition: DiMuonTaggingAlg.h:87
DerivationFramework::DiMuonTaggingAlg::m_dPhiMin
Gaudi::Property< float > m_dPhiMin
Require a minimal delta Phi between the two selected candidates.
Definition: DiMuonTaggingAlg.h:107
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DerivationFramework::DiMuonTaggingAlg::m_muonSelTool
ToolHandle< CP::IMuonSelectionTool > m_muonSelTool
Selection tool to filter muons with poor quality.
Definition: DiMuonTaggingAlg.h:81
DerivationFramework::DiMuonTaggingAlg::m_trkKeepKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trkKeepKey
Definition: DiMuonTaggingAlg.h:75
DerivationFramework::DiMuonTaggingAlg::m_requireOS
Gaudi::Property< bool > m_requireOS
Both particles have to be of opposite charge.
Definition: DiMuonTaggingAlg.h:105
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:49
Utils.h
xAOD::Muon_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: Muon_v1.cxx:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
xAODP4Helpers.h
DerivationFramework::DiMuonTaggingAlg::passMuonCuts
bool passMuonCuts(const xAOD::Muon *muon, const float ptMin, const float absEtaMax, const bool applyQuality) const
Definition: DiMuonTaggingAlg.cxx:176
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:277
DerivationFramework::DiMuonTaggingAlg::m_thinningConeSize
Gaudi::Property< float > m_thinningConeSize
Definition: DiMuonTaggingAlg.h:113
DerivationFramework::DiMuonTaggingAlg::m_applyQualityMu2
Gaudi::Property< bool > m_applyQualityMu2
Flag to toggle whether the selection working point should be applied on the second muon.
Definition: DiMuonTaggingAlg.h:94
DerivationFramework::DiMuonTaggingAlg::m_thinningConeSize2
float m_thinningConeSize2
Definition: DiMuonTaggingAlg.h:117
CP::MeVtoGeV
constexpr float MeVtoGeV
Definition: IsolationCloseByCorrectionTool.cxx:33
DerivationFramework::DiMuonTaggingAlg::m_br_prefix
Gaudi::Property< std::string > m_br_prefix
Name of the ouput selection flag.
Definition: DiMuonTaggingAlg.h:102
DerivationFramework::DiMuonTaggingAlg::m_mu1PtMin
Gaudi::Property< float > m_mu1PtMin
Pt cut on the primary muon in the event.
Definition: DiMuonTaggingAlg.h:83
DerivationFramework::DiMuonTaggingAlg::m_applyTrig
Gaudi::Property< bool > m_applyTrig
Definition: DiMuonTaggingAlg.h:50
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
DerivationFramework::DiMuonTaggingAlg::m_truthSGKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthSGKey
Definition: DiMuonTaggingAlg.h:70
DerivationFramework::DiMuonTaggingAlg::m_mu2PtMin
Gaudi::Property< float > m_mu2PtMin
Pt cut on the second muon in the event.
Definition: DiMuonTaggingAlg.h:90
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
DerivationFramework::DiMuonTaggingAlg::m_isMC
Gaudi::Property< bool > m_isMC
Flag whether it's MC.
Definition: DiMuonTaggingAlg.h:97
DerivationFramework::DiMuonTaggingAlg::m_invariantMassHigh
Gaudi::Property< float > m_invariantMassHigh
Upper invariant mass selection window (Negative number refers to disable)
Definition: DiMuonTaggingAlg.h:111
xAOD::P4Helpers::deltaR2
double deltaR2(double rapidity1, double phi1, double rapidity2, double phi2)
from bare rapidity,phi
Definition: xAODP4Helpers.h:111
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
DiMuonTaggingAlg.h
DerivationFramework::DiMuonTaggingAlg::passKinematicCuts
bool passKinematicCuts(const xAOD::IParticle *mu, const float ptMin, const float absEtaMax) const
Returns true of the pointer is valid and also whether the pt and absEta are above and below the thres...
Definition: DiMuonTaggingAlg.cxx:171
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
DerivationFramework::DiMuonTaggingAlg::m_invariantMassLow
Gaudi::Property< float > m_invariantMassLow
Lower invariant mass selection window.
Definition: DiMuonTaggingAlg.h:109
xAOD::Muon_v1::charge
float charge() const
DerivationFramework::DiMuonTaggingAlg::m_mu2AbsEtaMax
Gaudi::Property< float > m_mu2AbsEtaMax
Eta cut on the second muon in the event.
Definition: DiMuonTaggingAlg.h:92
DerivationFramework::DiMuonTaggingAlg::m_orTrigs
Gaudi::Property< std::vector< std::string > > m_orTrigs
List of triggers in which at least one muon in the pair needs to pass.
Definition: DiMuonTaggingAlg.h:54
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
DerivationFramework::DiMuonTaggingAlg::m_invariantMassHigh2
float m_invariantMassHigh2
Definition: DiMuonTaggingAlg.h:116
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:99
DerivationFramework::DiMuonTaggingAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: DiMuonTaggingAlg.cxx:52
DerivationFramework::DiMuonTaggingAlg::muonPairCheck
bool muonPairCheck(const xAOD::Muon *mu1, const probe_type *mu2) const
Definition: DiMuonTaggingAlg.cxx:184
DerivationFramework::DiMuonTaggingAlg::m_invariantMassLow2
float m_invariantMassLow2
Definition: DiMuonTaggingAlg.h:115
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework::DiMuonTaggingAlg::m_skimmingKey
SG::WriteHandleKey< int > m_skimmingKey
Event Decision Key.
Definition: DiMuonTaggingAlg.h:78
DerivationFramework
THE reconstruction tool.
Definition: ParticleSortingAlg.h:24
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DerivationFramework::DiMuonTaggingAlg::m_mu1AbsEtaMax
Gaudi::Property< float > m_mu1AbsEtaMax
Eta cut on the primary muon in the event.
Definition: DiMuonTaggingAlg.h:85
DerivationFramework::DiMuonTaggingAlg::m_muonSGKey
SG::ReadHandleKey< xAOD::MuonContainer > m_muonSGKey
Definition: DiMuonTaggingAlg.h:66
DerivationFramework::DiMuonTaggingAlg::initialize
StatusCode initialize() override
Definition: DiMuonTaggingAlg.cxx:23
DerivationFramework::DiMuonTaggingAlg::m_matchingTool
ToolHandle< Trig::IMatchingTool > m_matchingTool
Definition: DiMuonTaggingAlg.h:59
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
errorcheck.h
Helpers for checking error return status codes and reporting errors.
DerivationFramework::DiMuonTaggingAlg::m_trackSGKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackSGKey
Definition: DiMuonTaggingAlg.h:68
DerivationFramework::DiMuonTaggingAlg::m_useTrackProbe
Gaudi::Property< bool > m_useTrackProbe
Run the analysis with a Muon <--> Track pair — Muon has to hold criteria 1 and track to satisfy kinem...
Definition: DiMuonTaggingAlg.h:100
DerivationFramework::DiMuonTaggingAlg::maskNearbyIDtracks
void maskNearbyIDtracks(const xAOD::IParticle *mu, TrackPassDecor &decor) const
Definition: DiMuonTaggingAlg.cxx:166
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
DerivationFramework::DiMuonTaggingAlg::m_muonKeepKey
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_muonKeepKey
Keys to whitelist the muons & tracks needed for MCP studies to output.
Definition: DiMuonTaggingAlg.h:73
DerivationFramework::DiMuonTaggingAlg::DiMuonTaggingAlg
DiMuonTaggingAlg(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters.
Definition: DiMuonTaggingAlg.cxx:19
SG::WriteDecorHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
PhysDESDM_SmpCaloId.ptMin
ptMin
Definition: PhysDESDM_SmpCaloId.py:90
DerivationFramework::DiMuonTaggingAlg::passTrigger
bool passTrigger(const xAOD::Muon *muon, const std::vector< std::string > &trigList) const
Definition: DiMuonTaggingAlg.cxx:179
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
DerivationFramework::DiMuonTaggingAlg::m_andTrigs
Gaudi::Property< std::vector< std::string > > m_andTrigs
List of trigger in which both muons need to pass the selection.
Definition: DiMuonTaggingAlg.h:56
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
TrackingPrimitives.h
TrackParticleContainer.h
HepMCHelpers.h