ATLAS Offline Software
MuonSelectionTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
10 #include "CxxUtils/trapping_fp.h"
11 
12 namespace {
13  static constexpr double const MeVtoGeV = 1. / 1000.;
14  // This function defines the order of chamber indices for the low-pT MVA,
15  // i.e. defining the meaning of "the first two segments", which are used in the BDT
16  std::vector<int> initializeChamberIdxOrder() {
17  // This vector defines the order. The current order follows the order of the enum "ChIndex"
18  // except for the CSCs, which appear first. Since the order is not strictly innermost-to-outermost,
19  // a reordering could be considered for a rel. 22 retuning, which can then easily be achieved by
20  // swapping around the elements in the below initialization.
22  const std::vector<ChIdx> orderedChIndices{
25  ChIdx::BEE, ChIdx::EIS, ChIdx::EIL, ChIdx::EMS,
26  ChIdx::EML, ChIdx::EOS, ChIdx::EOL, ChIdx::EES,
27  ChIdx::EEL};
28 
29  // This vector will hold the equivalent information in a form that can be efficiently accessed in the
30  // below function "chamberIndexCompare", using the chamber index as the vector index
31  std::vector<int> chamberIndexOrder(orderedChIndices.size());
32 
33  for (unsigned int i = 0; i < orderedChIndices.size(); i++) {
34  chamberIndexOrder[static_cast<int>(orderedChIndices[i])] = i;
35  }
36  return chamberIndexOrder;
37  }
38 
39  // This is the comparison function for the sorting of segments according to the chamber index
40  bool chamberIndexCompare(const xAOD::MuonSegment* first, const xAOD::MuonSegment* second) {
41  static const std::vector<int> chamberIndexOrder = initializeChamberIdxOrder();
42  return (chamberIndexOrder[static_cast<int>(first->chamberIndex())] <
43  chamberIndexOrder[static_cast<int>(second->chamberIndex())]);
44  }
45 
46  static const SG::AuxElement::Accessor<float> mePt_acc("MuonSpectrometerPt");
47  static const SG::AuxElement::Accessor<float> idPt_acc("InnerDetectorPt");
48  static const SG::AuxElement::Accessor<uint8_t> eta1stgchits_acc("etaLayer1STGCHits");
49  static const SG::AuxElement::Accessor<uint8_t> eta2stgchits_acc("etaLayer2STGCHits");
50  static const SG::AuxElement::Accessor<uint8_t> mmhits_acc("MMHits");
51 } // namespace
52 
53 namespace CP {
54 
55  MuonSelectionTool::MuonSelectionTool(const std::string& tool_name) : asg::AsgTool(tool_name), m_acceptInfo("MuonSelection"){}
56 
58 
60 
61  // Greet the user:
62  ATH_MSG_INFO("Initialising...");
63 
64  m_geoOnTheFly ? ATH_MSG_INFO("Is Run-3 geometry: On-the-fly determination")
65  : ATH_MSG_INFO("Is Run-3 geometry: " << m_isRun3.value());
66  ATH_MSG_INFO("Maximum muon |eta|: " << m_maxEta.value());
67  ATH_MSG_INFO("Muon quality: "<< m_quality.value());
68  if (m_toroidOff) ATH_MSG_INFO("!! CONFIGURED FOR TOROID-OFF COLLISIONS !!");
69  if (m_SctCutOff) ATH_MSG_WARNING("!! SWITCHING SCT REQUIREMENTS OFF !! FOR DEVELOPMENT USE ONLY !!");
70  if (m_PixCutOff) ATH_MSG_WARNING("!! SWITCHING PIXEL REQUIREMENTS OFF !! FOR DEVELOPMENT USE ONLY !!");
71  if (m_SiHolesCutOff) ATH_MSG_WARNING("!! SWITCHING SILICON HOLES REQUIREMENTS OFF !! FOR DEVELOPMENT USE ONLY !!");
72  if (m_custom_dir != "")
73  ATH_MSG_WARNING("!! SETTING UP WITH USER SPECIFIED INPUT LOCATION \"" << m_custom_dir << "\"!! FOR DEVELOPMENT USE ONLY !! ");
74  if (!m_useAllAuthors)
76  "Not using allAuthors variable as currently missing in many derivations; LowPtEfficiency working point will always return "
77  "false, but this is expected at the moment. Have a look here: "
78  "https://twiki.cern.ch/twiki/bin/view/Atlas/MuonSelectionToolR21#New_LowPtEfficiency_working_poin");
79 
80  // Print message to ensure that users excluding 2-station muons in the high-pT selection are aware of this
82  ATH_MSG_INFO("You have opted to select only 3-station muons in the high-pT selection! "
83  << "Please feed 'HighPt3Layers' to the 'WorkingPoint' property to retrieve the appropriate scale-factors");
84 
85  // Only an MVA-based selection is defined for segment-tagged muons for the Low-pT working point
87  ATH_MSG_WARNING("No cut-based selection is defined for segment-tagged muons in the Low-pT working point. "
88  << "Please set UseMVALowPt=true if you want to try the UseSegmentTaggedLowPt=true option.");
90  }
91  if (m_useLRT) {
92  ATH_MSG_INFO("MuonSelectionTool will assume both Standard and LRT Muons are being used, and that the necessary information is available to identify the type (standard or LRT).");
93  if (m_quality!=1) ATH_MSG_WARNING("Currently, only Medium quality is supported for LRT muons. Your chosen WP will be applied (w/o ID cuts), but no recommendations are available for this quality.");
94  }
95 
96  // Set up the TAccept object:
97  m_acceptInfo.addCut("Eta", "Selection of muons according to their pseudorapidity");
98  m_acceptInfo.addCut("IDHits", "Selection of muons according to whether they passed the MCP ID Hit cuts");
99  m_acceptInfo.addCut("Preselection", "Selection of muons according to their type/author");
100  m_acceptInfo.addCut("Quality", "Selection of muons according to their tightness");
101  // Sanity check
102  if (m_quality > 5) {
104  "Invalid quality (i.e. selection WP) set: "
105  << m_quality
106  << " - it must be an integer between 0 and 5! (0=Tight, 1=Medium, 2=Loose, 3=Veryloose, 4=HighPt, 5=LowPtEfficiency)");
107  return StatusCode::FAILURE;
108  }
109  if (m_quality == 5 && !m_useAllAuthors) {
110  ATH_MSG_ERROR("Cannot use lowPt working point if allAuthors is not available!");
111  return StatusCode::FAILURE;
112  }
113 
114  if(m_caloScoreWP<1 || m_caloScoreWP>4){
115  ATH_MSG_FATAL("CaloScoreWP property must be set to 1, 2, 3 or 4");
116  return StatusCode::FAILURE;
117  }
118 
119  // Load Tight WP cut-map
120  ATH_MSG_INFO("Initialising tight working point histograms...");
121  std::string tightWP_rootFile_fullPath;
122  if (!m_custom_dir.empty()) {
123  tightWP_rootFile_fullPath = PathResolverFindCalibFile(m_custom_dir + "/muonSelection_tightWPHisto.root");
124  } else {
125  tightWP_rootFile_fullPath = PathResolverFindCalibFile(
126  Form("MuonSelectorTools/%s/muonSelection_tightWPHisto.root", m_calibration_version.value().c_str()));
127  }
128 
129  ATH_MSG_INFO("Reading muon tight working point histograms from " << tightWP_rootFile_fullPath);
130  //
131  std::unique_ptr<TFile> file(TFile::Open(tightWP_rootFile_fullPath.c_str(), "READ"));
132 
133  if (!file->IsOpen()) {
134  ATH_MSG_ERROR("Cannot read tight working point file from " << tightWP_rootFile_fullPath);
135  return StatusCode::FAILURE;
136  }
137 
138  // Retrieve all the relevant histograms
139  ATH_CHECK(getHist(file.get(), "tightWP_lowPt_rhoCuts", m_tightWP_lowPt_rhoCuts));
140  ATH_CHECK(getHist(file.get(), "tightWP_lowPt_qOverPCuts", m_tightWP_lowPt_qOverPCuts));
141  ATH_CHECK(getHist(file.get(), "tightWP_mediumPt_rhoCuts", m_tightWP_mediumPt_rhoCuts));
142  ATH_CHECK(getHist(file.get(), "tightWP_highPt_rhoCuts", m_tightWP_highPt_rhoCuts));
143  //
144  file->Close();
145 
146  // Read bad muon veto efficiency histograms
147  std::string BMVcutFile_fullPath = PathResolverFindCalibFile(m_BMVcutFile);
148 
149  ATH_MSG_INFO("Reading bad muon veto cut functions from " << BMVcutFile_fullPath);
150  //
151  std::unique_ptr<TFile> BMVfile(TFile::Open(BMVcutFile_fullPath.c_str(), "READ"));
152 
153  if (!BMVfile->IsOpen()) {
154  ATH_MSG_ERROR("Cannot read bad muon veto cut function file from " << BMVcutFile_fullPath);
155  return StatusCode::FAILURE;
156  }
157 
158  m_BMVcutFunction_barrel = std::unique_ptr<TF1>((TF1*)BMVfile->Get("BMVcutFunction_barrel"));
159  m_BMVcutFunction_endcap = std::unique_ptr<TF1>((TF1*)BMVfile->Get("BMVcutFunction_endcap"));
160 
161  BMVfile->Close();
162 
164  ATH_MSG_ERROR("Cannot read bad muon veto cut functions");
165  return StatusCode::FAILURE;
166  }
167 
168  if (m_useMVALowPt) {
169  // Set up TMVA readers for MVA-based low-pT working point
170  // E and O refer to even and odd event numbers to avoid applying the MVA on events used for training
171  TString weightPath_EVEN_MuidCB = PathResolverFindCalibFile(m_MVAreaderFile_EVEN_MuidCB);
172  TString weightPath_ODD_MuidCB = PathResolverFindCalibFile(m_MVAreaderFile_ODD_MuidCB);
173  TString weightPath_EVEN_MuGirl = PathResolverFindCalibFile(m_MVAreaderFile_EVEN_MuGirl);
174  TString weightPath_ODD_MuGirl = PathResolverFindCalibFile(m_MVAreaderFile_ODD_MuGirl);
175 
176  auto make_mva_reader = [](TString file_path) {
177  std::vector<std::string> mva_var_names{"momentumBalanceSignificance",
178  "scatteringCurvatureSignificance",
179  "scatteringNeighbourSignificance",
180  "EnergyLoss",
181  "middleLargeHoles+middleSmallHoles",
182  "muonSegmentDeltaEta",
183  "muonSeg1ChamberIdx",
184  "muonSeg2ChamberIdx"};
185  std::unique_ptr<TMVA::Reader> reader = std::make_unique<TMVA::Reader>(mva_var_names);
186  reader->BookMVA("BDTG", file_path);
187  return reader;
188  };
189  m_readerE_MUID = make_mva_reader(weightPath_EVEN_MuidCB);
190 
191  m_readerO_MUID = make_mva_reader(weightPath_ODD_MuidCB);
192 
193  m_readerE_MUGIRL = make_mva_reader(weightPath_EVEN_MuGirl);
194 
195  m_readerO_MUGIRL = make_mva_reader(weightPath_ODD_MuGirl);
196 
198  TString weightPath_MuTagIMO_etaBin1 = PathResolverFindCalibFile(m_MVAreaderFile_MuTagIMO_etaBin1);
199  TString weightPath_MuTagIMO_etaBin2 = PathResolverFindCalibFile(m_MVAreaderFile_MuTagIMO_etaBin2);
200  TString weightPath_MuTagIMO_etaBin3 = PathResolverFindCalibFile(m_MVAreaderFile_MuTagIMO_etaBin3);
201 
202  auto make_mva_reader_MuTagIMO = [](TString file_path, bool useSeg2ChamberIndex) {
203  std::vector<std::string> mva_var_names;
204  if (useSeg2ChamberIndex) mva_var_names.push_back("muonSeg2ChamberIndex");
205  mva_var_names.push_back("muonSeg1ChamberIndex");
206  mva_var_names.push_back("muonSeg1NPrecisionHits");
207  mva_var_names.push_back("muonSegmentDeltaEta");
208  mva_var_names.push_back("muonSeg1GlobalR");
209  mva_var_names.push_back("muonSeg1Chi2OverDoF");
210  mva_var_names.push_back("muonSCS");
211 
212  std::unique_ptr<TMVA::Reader> reader = std::make_unique<TMVA::Reader>(mva_var_names);
213  reader->BookMVA("BDT", file_path);
214  return reader;
215  };
216 
217  m_reader_MUTAGIMO_etaBin1 = make_mva_reader_MuTagIMO(weightPath_MuTagIMO_etaBin1, false);
218  m_reader_MUTAGIMO_etaBin2 = make_mva_reader_MuTagIMO(weightPath_MuTagIMO_etaBin2, false);
219  m_reader_MUTAGIMO_etaBin3 = make_mva_reader_MuTagIMO(weightPath_MuTagIMO_etaBin3, true);
220  }
221  }
223 
224  // Return gracefully:
225  return StatusCode::SUCCESS;
226  }
227 
228  StatusCode MuonSelectionTool::getHist(TFile* file, const std::string& histName, std::unique_ptr<TH1>& hist) const {
229  //
230  if (!file) {
231  ATH_MSG_ERROR(" getHist(...) TFile is nullptr! Check that the Tight cut map is loaded correctly");
232  return StatusCode::FAILURE;
233  }
234  TH1* h_ptr = nullptr;
235  file->GetObject(histName.c_str(), h_ptr);
236  //
237  //
238  if (!h_ptr) {
239  ATH_MSG_ERROR("Cannot retrieve histogram " << histName);
240  return StatusCode::FAILURE;
241  }
242  hist = std::unique_ptr<TH1>{h_ptr};
243  hist->SetDirectory(nullptr);
244  ATH_MSG_INFO("Successfully read tight working point histogram: " << hist->GetName());
245  //
246  return StatusCode::SUCCESS;
247  }
248 
250 
252  // Check if this is a muon:
253  if (p->type() != xAOD::Type::Muon) {
254  ATH_MSG_ERROR("accept(...) Function received a non-muon");
255  return asg::AcceptData(&m_acceptInfo);
256  }
257 
258  // Cast it to a muon:
259  const xAOD::Muon* mu = dynamic_cast<const xAOD::Muon*>(p);
260  if (!mu) {
261  ATH_MSG_FATAL("accept(...) Failed to cast particle to muon");
262  return asg::AcceptData(&m_acceptInfo);
263  }
264 
265  // Let the specific function do the work:
266  return accept(*mu);
267  }
268 
269  //============================================================================
271 
272  static std::atomic<bool> checkDone{false};
273 
274  if(!checkDone) {
275  // Check that the user either set the correct geometry or enabled on-the-fly determination
276  // This can happen intentionally in developer mode. In any case don't throw an exception
277  // (we should either trust the user or ignore in the first place and force on-the-fly determination).
278  if (isRun3() != isRun3(true)) {
279  ATH_MSG_WARNING("MuonSelectionTool is configured with isRun3Geo="<<isRun3()
280  <<" while on-the fly check for runNumber "<<getRunNumber(true)<<" indicates isRun3Geo="<<isRun3(true));
281  }
282 
283  // Check that the requested WP is currently supported by the MCP group.
284  if (isRun3()) {
285  if(m_quality!=0 && m_quality!=1 && m_quality!=2 && m_quality!=4 && m_quality!=5) {
286  ATH_MSG_WARNING("MuonSelectionTool currently supports Loose, Medium, Tight, HighPt, and LowPtEfficiency WPs for Run3; all other WPs can only be used in ExpertDevelopMode mode");
287  }
288 
290  ATH_MSG_WARNING("For Run3, Tight WP is supported only when ExcludeNSWFromPrecisionLayers=False and RecalcPrecisionLayerswNSW=True");
291  }
292  }
293 
294  checkDone = true;
295  }
296  }
297 
298  //============================================================================
300  // Verbose information
301  ATH_MSG_VERBOSE("-----------------------------------");
302  ATH_MSG_VERBOSE("New muon passed to accept function:");
303  if (mu.muonType() == xAOD::Muon::Combined)
304  ATH_MSG_VERBOSE("Muon type: combined");
305  else if (mu.muonType() == xAOD::Muon::MuonStandAlone)
306  ATH_MSG_VERBOSE("Muon type: stand-alone");
307  else if (mu.muonType() == xAOD::Muon::SegmentTagged)
308  ATH_MSG_VERBOSE("Muon type: segment-tagged");
309  else if (mu.muonType() == xAOD::Muon::CaloTagged)
310  ATH_MSG_VERBOSE("Muon type: calorimeter-tagged");
311  else if (mu.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon)
312  ATH_MSG_VERBOSE("Muon type: silicon-associated forward");
313  ATH_MSG_VERBOSE("Muon pT [GeV]: " << mu.pt() * MeVtoGeV);
314  ATH_MSG_VERBOSE("Muon eta: " << mu.eta());
315  ATH_MSG_VERBOSE("Muon phi: " << mu.phi());
316 
317  checkSanity();
318 
319  asg::AcceptData acceptData(&m_acceptInfo);
320 
321  // Do the eta cut:
322  if (std::abs(mu.eta()) >= m_maxEta) {
323  ATH_MSG_VERBOSE("Failed eta cut");
324  return acceptData;
325  }
326  acceptData.setCutResult("Eta", true);
327 
328  // Passes ID hit cuts
329  bool passIDCuts = passedIDCuts(mu);
330  ATH_MSG_VERBOSE("Passes ID Hit cuts " << passIDCuts);
331  acceptData.setCutResult("IDHits", passIDCuts);
332 
333  // passes muon preselection
334  bool passMuonCuts = passedMuonCuts(mu);
335  ATH_MSG_VERBOSE("Passes preselection cuts " << passMuonCuts);
336  acceptData.setCutResult("Preselection", passMuonCuts);
337 
338  if (!passIDCuts || !passMuonCuts) { return acceptData; }
339 
340  // Passes quality requirements
341  xAOD::Muon::Quality thisMu_quality = getQuality(mu);
342  bool thisMu_highpt = false;
343  thisMu_highpt = passedHighPtCuts(mu);
344  bool thisMu_lowptE = false;
345  thisMu_lowptE = passedLowPtEfficiencyCuts(mu, thisMu_quality);
346  ATH_MSG_VERBOSE("Summary of quality information for this muon: ");
347  ATH_MSG_VERBOSE("Muon quality: " << thisMu_quality << " passes HighPt: " << thisMu_highpt
348  << " passes LowPtEfficiency: " << thisMu_lowptE);
349  if (m_quality < 4 && thisMu_quality > m_quality) { return acceptData; }
350  if (m_quality == 4 && !thisMu_highpt) { return acceptData; }
351  if (m_quality == 5 && !thisMu_lowptE) { return acceptData; }
352  acceptData.setCutResult("Quality", true);
353  // Return the result:
354  return acceptData;
355  }
356 
358  mu.setQuality(getQuality(mu));
359  return;
360  }
361  void MuonSelectionTool::IdMsPt(const xAOD::Muon& mu, float& idPt, float& mePt) const {
362  const xAOD::TrackParticle* idtrack = mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
363  const xAOD::TrackParticle* metrack = mu.trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
364  if (!idtrack || !metrack) idPt = mePt = -1.;
365  else if (m_turnOffMomCorr) {
366  mePt = metrack->pt();
367  idPt = idtrack->pt();
368  } else {
369  if (!mePt_acc.isAvailable(mu) || !idPt_acc.isAvailable(mu)) {
370  ATH_MSG_FATAL("The muon with pT " << mu.pt() * MeVtoGeV << " eta: " << mu.eta() << ", phi:" << mu.phi()
371  << " q:" << mu.charge() << ", author:" << mu.author()
372  << " is not decorated with calibrated momenta. Please fix");
373  throw std::runtime_error("MuonSelectionTool() - qOverP significance calculation failed");
374  }
375  mePt = mePt_acc(mu);
376  idPt = idPt_acc(mu);
377  }
378  }
379 
381  // Avoid spurious FPEs in the clang build.
383 
384  if (m_disablePtCuts) {
385  ATH_MSG_VERBOSE(__FILE__ << ":"<<__LINE__
386  << " Momentum dependent cuts are disabled. Return 0.");
387  return 0.;
388  }
389  const xAOD::TrackParticle* idtrack = muon.trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
390  const xAOD::TrackParticle* metrack = muon.trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
391  if (!idtrack || !metrack) {
392  ATH_MSG_VERBOSE("No ID / MS track. Return dummy large value of 1 mio");
393  return 1.e6;
394  }
395  float mePt{-1.}, idPt{-1.};
396  IdMsPt(muon, idPt, mePt);
397 
398  const float meP = mePt / std::sin(metrack->theta());
399  const float idP = idPt / std::sin(idtrack->theta());
400 
401  float qOverPsigma = std::sqrt(idtrack->definingParametersCovMatrix()(4, 4) + metrack->definingParametersCovMatrix()(4, 4));
402  return std::abs((metrack->charge() / meP) - (idtrack->charge() / idP)) / qOverPsigma;
403  }
405  if (m_disablePtCuts) {
406  ATH_MSG_VERBOSE(__FILE__ << ":"<<__LINE__
407  << "Momentum dependent cuts are disabled. Return 0.");
408  return 0.;
409  }
410  float mePt{-1.}, idPt{-1.};
411  IdMsPt(muon, idPt, mePt);
412  return std::abs(idPt - mePt) / muon.pt();
413  }
414 
415  xAOD::Muon::Quality MuonSelectionTool::getQuality(const xAOD::Muon& mu) const {
416  ATH_MSG_VERBOSE("Evaluating muon quality...");
417  if (isRun3() && mu.isAuthor(xAOD::Muon::Author::Commissioning) && !m_allowComm) {
418  ATH_MSG_VERBOSE("Reject authors from the commissioning chain");
419  return xAOD::Muon::VeryLoose;
420  }
421 
422  // SegmentTagged muons
423  if (mu.muonType() == xAOD::Muon::SegmentTagged) {
424  ATH_MSG_VERBOSE("Muon is segment-tagged");
425 
426  if (std::abs(mu.eta()) < 0.1) {
427  ATH_MSG_VERBOSE("Muon is loose");
428  return xAOD::Muon::Loose;
429  } else {
430  ATH_MSG_VERBOSE("Do not allow segment-tagged muon at |eta| > 0.1 - return VeryLoose");
431  return xAOD::Muon::VeryLoose;
432  }
433  }
434 
435  // CaloTagged muons
436  if (mu.muonType() == xAOD::Muon::CaloTagged) {
437  ATH_MSG_VERBOSE("Muon is calorimeter-tagged");
438 
439  if (std::abs(mu.eta()) < 0.1 && passedCaloTagQuality(mu)) {
440  ATH_MSG_VERBOSE("Muon is loose");
441  return xAOD::Muon::Loose;
442  }
443  }
444 
445  // Combined muons
448 
449  if (mu.muonType() == xAOD::Muon::Combined) {
450  ATH_MSG_VERBOSE("Muon is combined");
451  if (mu.author() == xAOD::Muon::STACO) {
452  ATH_MSG_VERBOSE("Muon is STACO - return VeryLoose");
453  return xAOD::Muon::VeryLoose;
454  }
455 
456  // rejection muons with out-of-bounds hits
459 
461  ATH_MSG_VERBOSE("Muon has out-of-bounds precision hits - return VeryLoose");
462  return xAOD::Muon::VeryLoose;
463  }
464 
465  // LOOSE / MEDIUM / TIGHT WP
466  const xAOD::TrackParticle* idtrack = mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
467  const xAOD::TrackParticle* metrack = mu.trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
468  if (idtrack && metrack && metrack->definingParametersCovMatrix()(4, 4) > 0) {
469  const float qOverPsignif = qOverPsignificance(mu);
470  const float rho = rhoPrime(mu);
471  const float reducedChi2 = mu.primaryTrackParticle()->chiSquared() / mu.primaryTrackParticle()->numberDoF();
472 
473  ATH_MSG_VERBOSE("Relevant cut variables:");
474  ATH_MSG_VERBOSE("number of precision layers = " << (int)summary.nprecisionLayers);
475  ATH_MSG_VERBOSE("reduced Chi2 = " << reducedChi2);
476  ATH_MSG_VERBOSE("qOverP significance = " << qOverPsignif);
477 
478  // NEW TIGHT WP
479  if (summary.nprecisionLayers > 1 && reducedChi2 < 8 && std::abs(qOverPsignif) < 7) {
480  if (passTight(mu, rho, qOverPsignif)) {
481  ATH_MSG_VERBOSE("Muon is tight");
482  return xAOD::Muon::Tight;
483  }
484  }
485 
486  ATH_MSG_VERBOSE("Muon did not pass requirements for tight combined muon");
487 
488  // MEDIUM WP
489  if ((std::abs(qOverPsignif) < 7 || m_toroidOff) &&
490  (summary.nprecisionLayers > 1 ||(summary.nprecisionLayers == 1 && summary.nprecisionHoleLayers < 2 && std::abs(mu.eta()) < 0.1))
491 
492  ) {
493  ATH_MSG_VERBOSE("Muon is medium");
494  return xAOD::Muon::Medium;
495  }
496 
497  ATH_MSG_VERBOSE("Muon did not pass requirements for medium combined muon");
498 
499  } else {
500  ATH_MSG_VERBOSE("Muon is missing the ID and/or ME tracks...");
501 
502  // CB muons with missing ID or ME track
503  if ((summary.nprecisionLayers > 1 ||
504  (summary.nprecisionLayers == 1 && summary.nprecisionHoleLayers < 2 && std::abs(mu.eta()) < 0.1))) {
505  // In toroid-off data ME/MS tracks often missing - need special treatment => flagging as "Medium"
506  // In toroid-on data ME/MS tracks missing only for <1% of CB muons, mostly MuGirl (to be fixed) => flagging as "Loose"
507  if (m_toroidOff) {
508  ATH_MSG_VERBOSE("...this is toroid-off data - returning medium");
509  return xAOD::Muon::Medium;
510  } else {
511  ATH_MSG_VERBOSE("...this is not toroid-off data - returning loose");
512  return xAOD::Muon::Loose;
513  }
514  }
515  }
516 
517  // Improvement for Loose targeting low-pT muons (pt<7 GeV)
518  if ((m_disablePtCuts || mu.pt() * MeVtoGeV < 7.) && std::abs(mu.eta()) < 1.3 && summary.nprecisionLayers > 0 &&
519  (mu.author() == xAOD::Muon::MuGirl && mu.isAuthor(xAOD::Muon::MuTagIMO))) {
520  ATH_MSG_VERBOSE("Muon passed selection for loose working point at low pT");
521  return xAOD::Muon::Loose;
522  }
523 
524  // didn't pass the set of requirements for a medium or tight combined muon
525  ATH_MSG_VERBOSE("Did not pass selections for combined muon - returning VeryLoose");
526  return xAOD::Muon::VeryLoose;
527  }
528 
529  // SA muons
530  if (mu.author() == xAOD::Muon::MuidSA) {
531  ATH_MSG_VERBOSE("Muon is stand-alone");
532 
533  if(isRun3() && !m_developMode){
534  ATH_MSG_VERBOSE("Standalone muons currently only used when in expert mode for run3");
535  return xAOD::Muon::VeryLoose; //SA muons currently disabled for run3
536  }
537 
538  if (std::abs(mu.eta()) > 2.5) {
539  ATH_MSG_VERBOSE("number of precision layers = " << (int)summary.nprecisionLayers);
540 
541  // 3 station requirement for medium
542  if (summary.nprecisionLayers > 2 && !m_toroidOff) {
543  ATH_MSG_VERBOSE("Muon is medium");
544  return xAOD::Muon::Medium;
545  }
546  }
547 
548  // didn't pass the set of requirements for a medium SA muon
549  ATH_MSG_VERBOSE("Muon did not pass selection for medium stand-alone muon - return VeryLoose");
550  return xAOD::Muon::VeryLoose;
551  }
552 
553  // SiliconAssociatedForward (SAF) muons
554  if (mu.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
555  ATH_MSG_VERBOSE("Muon is silicon-associated forward muon");
556 
557  if(isRun3() && !m_developMode){
558  ATH_MSG_VERBOSE("Silicon-associated forward muon muons currently only used when in expert mode for run3");
559  return xAOD::Muon::VeryLoose; //SAF muons currently disabled for run3
560  }
561 
562  const xAOD::TrackParticle* cbtrack = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
563  const xAOD::TrackParticle* metrack = mu.trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
564 
565  if (cbtrack && metrack) {
566  if (std::abs(cbtrack->eta()) > 2.5) {
567  ATH_MSG_VERBOSE("number of precision layers = " << (int)summary.nprecisionLayers);
568 
569  if (summary.nprecisionLayers > 2 && !m_toroidOff) {
570  if (mu.trackParticle(xAOD::Muon::Primary) == mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle) &&
571  !m_developMode) {
573  "SiliconForwardAssociated muon has ID track as primary track particle. "
574  << "This is a bug fixed starting with xAODMuon-00-17-07, which should be present in this release. "
575  << "Please report this to the Muon CP group!");
576  }
577  ATH_MSG_VERBOSE("Muon is medium");
578  return xAOD::Muon::Medium;
579  }
580  }
581  }
582 
583  // didn't pass the set of requirements for a medium SAF muon
584  ATH_MSG_VERBOSE("Muon did not pass selection for medium silicon-associated forward muon - return VeryLoose");
585  return xAOD::Muon::VeryLoose;
586  }
587 
588  ATH_MSG_VERBOSE("Muon did not pass selection for loose/medium/tight for any muon type - return VeryLoose");
589  return xAOD::Muon::VeryLoose;
590  }
591 
592  void MuonSelectionTool::setPassesIDCuts(xAOD::Muon& mu) const { mu.setPassesIDCuts(passedIDCuts(mu)); }
593 
595  if (m_useLRT) {
596  static const SG::AuxElement::Accessor<char> isLRTmuon("isLRT");
597  if (isLRTmuon.isAvailable(mu)) {
598  if (isLRTmuon(mu)) return true;
599  }
600  else {
601  static const SG::AuxElement::Accessor<uint64_t> patternAcc("patternRecoInfo");
602  const xAOD::TrackParticle* idtrack = mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
603  if(idtrack) {
604  if(!patternAcc.isAvailable(*idtrack)) {
605  ATH_MSG_FATAL("No information available to tell if the muon is LRT or standard. Either run MuonLRTMergingAlg to decorate with `isLRT` flag, or supply the patternRecoInfo for the original ID track.");
606  throw std::runtime_error("MuonSelectionTool() - isLRT decor and patternRecoInfo both unavailable for a muon.");
607  }
608  std::bitset<xAOD::NumberOfTrackRecoInfo> patternBitSet(patternAcc(*idtrack));
609  if (patternBitSet.test(xAOD::SiSpacePointsSeedMaker_LargeD0)) return true;
610  }
611  }
612  }
613  // do not apply the ID hit requirements for SA muons for |eta| > 2.5
614  if (mu.author() == xAOD::Muon::MuidSA && std::abs(mu.eta()) > 2.5) {
615  return true;
616  } else if (mu.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
617  const xAOD::TrackParticle* cbtrack = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
618  if (cbtrack && std::abs(cbtrack->eta()) > 2.5) { return true; }
619  return false;
620  } else {
621  if (mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle))
622  return passedIDCuts(*mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle));
623  else if (mu.primaryTrackParticle())
624  return passedIDCuts(*mu.primaryTrackParticle());
625  }
626  return false;
627  }
628 
630  if (mu.muonType() != xAOD::Muon::Combined) return false;
631  // ::
632  const xAOD::TrackParticle* idtrack = mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
633  const xAOD::TrackParticle* metrack = mu.trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
634  const xAOD::TrackParticle* cbtrack = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
635  // ::
636  // Some spurious muons are found to have negative ME track fit covariance, and are typically poorly reconstructed
637  if (metrack && metrack->definingParametersCovMatrix()(4, 4) < 0.0) return true;
638  // ::
639  bool IsBadMuon = false;
640  if (idtrack && metrack && cbtrack) {
641  // ::
642  double qOverP_ID = idtrack->qOverP();
643  double qOverPerr_ID = std::sqrt(idtrack->definingParametersCovMatrix()(4, 4));
644  double qOverP_ME = metrack->qOverP();
645  double qOverPerr_ME = std::sqrt(metrack->definingParametersCovMatrix()(4, 4));
646  double qOverP_CB = cbtrack->qOverP();
647  double qOverPerr_CB = std::sqrt(cbtrack->definingParametersCovMatrix()(4, 4));
648  // ::
649  if (m_quality == 4) {
650  // recipe for high-pt selection
651  IsBadMuon = !passedErrorCutCB(mu);
652 
655 
656  // temporarily apply same recipe as for other working points in addition to CB error
657  // cut for 2-station muons, pending better treatment of ID/MS misalignments
658  if (m_use2stationMuonsHighPt && summary.nprecisionLayers == 2) {
659  double IdCbRatio = std::abs((qOverPerr_ID / qOverP_ID) / (qOverPerr_CB / qOverP_CB));
660  double MeCbRatio = std::abs((qOverPerr_ME / qOverP_ME) / (qOverPerr_CB / qOverP_CB));
661  IsBadMuon = (IdCbRatio < 0.8 || MeCbRatio < 0.8 || IsBadMuon);
662  }
663  } else {
664  // recipe for other WP
665  double IdCbRatio = std::abs((qOverPerr_ID / qOverP_ID) / (qOverPerr_CB / qOverP_CB));
666  double MeCbRatio = std::abs((qOverPerr_ME / qOverP_ME) / (qOverPerr_CB / qOverP_CB));
667  IsBadMuon = (IdCbRatio < 0.8 || MeCbRatio < 0.8);
668  }
669  } else {
670  return true;
671  }
672  return IsBadMuon;
673  }
674 
676  xAOD::Muon::Quality thisMu_quality = getQuality(mu);
677  return passedLowPtEfficiencyCuts(mu, thisMu_quality);
678  }
679 
680  bool MuonSelectionTool::passedLowPtEfficiencyCuts(const xAOD::Muon& mu, xAOD::Muon::Quality thisMu_quality) const {
681  ATH_MSG_VERBOSE("Checking whether muon passes low-pT selection...");
682 
683  //LowPt Not supported in run3 for the time being
684  if(isRun3() && !m_developMode){
685  ATH_MSG_VERBOSE("LowPt WP currently not supported for run3 if not in expert mode");
686  return false;
687  }
688  if (!m_useAllAuthors) { // no allAuthors, always fail the WP
689  ATH_MSG_VERBOSE("Do not have allAuthors variable - fail low-pT");
690  return false;
691  }
692 
693  // requiring combined muons, unless segment-tags are included
695  if (mu.muonType() != xAOD::Muon::Combined) {
696  ATH_MSG_VERBOSE("Muon is not combined - fail low-pT");
697  return false;
698  }
699  } else {
700  if (mu.muonType() != xAOD::Muon::Combined && mu.muonType() != xAOD::Muon::SegmentTagged) {
701  ATH_MSG_VERBOSE("Muon is not combined or segment-tagged - fail low-pT");
702  return false;
703  }
704  }
705 
706  // author check
708  if (mu.author() != xAOD::Muon::MuGirl && mu.author() != xAOD::Muon::MuidCo) {
709  ATH_MSG_VERBOSE("Muon is neither MuGirl nor MuidCo - fail low-pT");
710  return false;
711  }
712  } else {
713  if (mu.author() != xAOD::Muon::MuGirl && mu.author() != xAOD::Muon::MuidCo && mu.author() != xAOD::Muon::MuTagIMO) {
714  ATH_MSG_VERBOSE("Muon is neither MuGirl / MuidCo / MuTagIMO - fail low-pT");
715  return false;
716  }
717  }
718 
719  // applying Medium selection above pT = 18 GeV
720  if (mu.pt() * MeVtoGeV > 18.) {
721  ATH_MSG_VERBOSE("pT > 18 GeV - apply medium selection");
722  if (thisMu_quality <= xAOD::Muon::Medium) {
723  ATH_MSG_VERBOSE("Muon passed low-pT selection");
724  return true;
725  } else {
726  ATH_MSG_VERBOSE("Muon failed low-pT selection");
727  return false;
728  }
729  }
730 
731  // requiring Medium in forward regions
732  if (!m_useMVALowPt && std::abs(mu.eta()) > 1.55 && thisMu_quality > xAOD::Muon::Medium) {
733  ATH_MSG_VERBOSE("Not using MVA selection, failing low-pT selection due to medium requirement in forward region");
734  return false;
735  }
736 
737  // rejection of muons with out-of-bounds hits
741  ATH_MSG_VERBOSE("Muon has out-of-bounds precision hits - fail low-pT");
742  return false;
743  }
744 
745  // requiring explicitely >=1 station (2 in the |eta|>1.3 region when Medium selection is not explicitely required)
746  if (mu.muonType() == xAOD::Muon::Combined) {
749  uint nStationsCut = (std::abs(mu.eta()) > 1.3 && std::abs(mu.eta()) < 1.55) ? 2 : 1;
750  if (summary.nprecisionLayers < nStationsCut) {
751  ATH_MSG_VERBOSE("number of precision layers = " << (int)summary.nprecisionLayers << " is lower than cut value " << nStationsCut
752  << " - fail low-pT");
753  return false;
754  }
755  }
756 
757  // reject MuGirl muon if not found also by MuTagIMO
758  if (m_useAllAuthors) {
759  if (mu.author() == xAOD::Muon::MuGirl && !mu.isAuthor(xAOD::Muon::MuTagIMO)) {
760  ATH_MSG_VERBOSE("MuGirl muon is not confirmed by MuTagIMO - fail low-pT");
761  return false;
762  }
763  } else
764  return false;
765 
766  if (m_useMVALowPt) {
767  ATH_MSG_VERBOSE("Applying MVA-based selection");
769  }
770 
771  ATH_MSG_VERBOSE("Applying cut-based selection");
772 
773  // apply some loose quality requirements
775 
779 
780  ATH_MSG_VERBOSE("momentum balance significance: " << momentumBalanceSignificance);
781  ATH_MSG_VERBOSE("scattering curvature significance: " << scatteringCurvatureSignificance);
782  ATH_MSG_VERBOSE("scattering neighbour significance: " << scatteringNeighbourSignificance);
783 
784  if (std::abs(momentumBalanceSignificance) > 3. || std::abs(scatteringCurvatureSignificance) > 3. ||
785  std::abs(scatteringNeighbourSignificance) > 3.) {
786  ATH_MSG_VERBOSE("Muon failed cut-based low-pT selection");
787  return false;
788  }
789 
790  // passed low pt selection
791  ATH_MSG_VERBOSE("Muon passed cut-based low-pT selection");
792  return true;
793  }
794 
795  std::vector<const xAOD::MuonSegment*> MuonSelectionTool::getSegmentsSorted(const xAOD::Muon& mu) const {
796  std::vector<const xAOD::MuonSegment*> segments_sorted;
797  segments_sorted.reserve(mu.nMuonSegments());
798 
799  for (unsigned int i = 0; i < mu.nMuonSegments(); i++) {
800  if (!mu.muonSegment(i))
801  ATH_MSG_WARNING("The muon reports more segments than are available. Please report this to the muon software community!");
802  else
803  segments_sorted.push_back(mu.muonSegment(i));
804  }
805 
806  std::sort(segments_sorted.begin(), segments_sorted.end(), chamberIndexCompare);
807 
808  return segments_sorted;
809  }
810 
812  //LowPt Not supported in run3 for the time being
813  if(isRun3() && !m_developMode){
814  ATH_MSG_VERBOSE("LowPt WP currently not supported for run3 if not in expert mode");
815  return false;
816  }
817  if (!m_useMVALowPt) {
818  ATH_MSG_DEBUG("Low pt MVA disabled. Return... ");
819  return false;
820  }
821  std::lock_guard<std::mutex> guard(m_low_pt_mva_mutex);
822  // set values for all BDT input variables from the muon in question
823  float momentumBalanceSig{-1}, CurvatureSig{-1}, energyLoss{-1}, muonSegmentDeltaEta{-1}, scatteringNeigbour{-1};
827  retrieveParam(mu, energyLoss, xAOD::Muon::EnergyLoss);
828  retrieveParam(mu, muonSegmentDeltaEta, xAOD::Muon::segmentDeltaEta);
829 
833 
834  float seg1ChamberIdx{-1.}, seg2ChamberIdx{-1.}, middleHoles{-1.}, seg1NPrecisionHits{-1.}, seg1GlobalR{-1.}, seg1Chi2OverDoF{-1.};
835 
836  std::vector<const xAOD::MuonSegment*> muonSegments = getSegmentsSorted(mu);
837 
838  if (mu.author() == xAOD::Muon::MuTagIMO && muonSegments.size() == 0)
839  ATH_MSG_WARNING("passedLowPtEfficiencyMVACut - found segment-tagged muon with no segments!");
840 
841  seg1ChamberIdx = (!muonSegments.empty()) ? muonSegments[0]->chamberIndex() : -9;
842  seg2ChamberIdx = (muonSegments.size() > 1) ? muonSegments[1]->chamberIndex() : -9;
843 
844  // these variables are only used for MuTagIMO
845  if (mu.author() == xAOD::Muon::MuTagIMO) {
846  seg1NPrecisionHits = (!muonSegments.empty()) ? muonSegments[0]->nPrecisionHits() : -1;
847  seg1GlobalR = (!muonSegments.empty())
848  ? std::hypot(muonSegments[0]->x(), muonSegments[0]->y(), muonSegments[0]->z())
849  : 0;
850  seg1Chi2OverDoF = (!muonSegments.empty()) ? muonSegments[0]->chiSquared() / muonSegments[0]->numberDoF() : -1;
851  }
852 
853  middleHoles = middleSmallHoles + middleLargeHoles;
854 
855  // get event number from event info
857 
858  // variables for the BDT
859  std::vector<float> var_vector;
860  if (mu.author() == xAOD::Muon::MuidCo || mu.author() == xAOD::Muon::MuGirl) {
861  var_vector = {momentumBalanceSig, CurvatureSig, scatteringNeigbour, energyLoss,
862  middleHoles, muonSegmentDeltaEta, seg1ChamberIdx, seg2ChamberIdx};
863  } else {
864  if (std::abs(mu.eta()) >= 1.3)
865  var_vector = {seg2ChamberIdx, seg1ChamberIdx, seg1NPrecisionHits, muonSegmentDeltaEta,
866  seg1GlobalR, seg1Chi2OverDoF, std::abs(CurvatureSig)};
867  else
868  var_vector = {seg1ChamberIdx, seg1NPrecisionHits, muonSegmentDeltaEta,
869  seg1GlobalR, seg1Chi2OverDoF, std::abs(CurvatureSig)};
870  }
871 
872  // use different trainings for even/odd numbered events
873  TMVA::Reader *reader_MUID, *reader_MUGIRL;
874  if (eventInfo->eventNumber() % 2 == 1) {
875  reader_MUID = m_readerE_MUID.get();
876  reader_MUGIRL = m_readerE_MUGIRL.get();
877  } else {
878  reader_MUID = m_readerO_MUID.get();
879  reader_MUGIRL = m_readerO_MUGIRL.get();
880  }
881 
882  // BDT for MuTagIMO is binned in |eta|
883  TMVA::Reader* reader_MUTAGIMO;
884  if (std::abs(mu.eta()) < 0.7)
885  reader_MUTAGIMO = m_reader_MUTAGIMO_etaBin1.get();
886  else if (std::abs(mu.eta()) < 1.3)
887  reader_MUTAGIMO = m_reader_MUTAGIMO_etaBin2.get();
888  else
889  reader_MUTAGIMO = m_reader_MUTAGIMO_etaBin3.get();
890 
891  // get the BDT discriminant response
892  float BDTdiscriminant;
893 
894  if (mu.author() == xAOD::Muon::MuidCo)
895  BDTdiscriminant = reader_MUID->EvaluateMVA(var_vector, "BDTG");
896  else if (mu.author() == xAOD::Muon::MuGirl)
897  BDTdiscriminant = reader_MUGIRL->EvaluateMVA(var_vector, "BDTG");
898  else if (mu.author() == xAOD::Muon::MuTagIMO && m_useSegmentTaggedLowPt)
899  BDTdiscriminant = reader_MUTAGIMO->EvaluateMVA(var_vector, "BDT");
900  else {
901  ATH_MSG_WARNING("Invalid author for low-pT MVA, failing selection...");
902  return false;
903  }
904 
905  // cut on dicriminant
906  float BDTcut = (mu.author() == xAOD::Muon::MuTagIMO) ? 0.12 : -0.6;
907 
908  if (BDTdiscriminant > BDTcut) {
909  ATH_MSG_VERBOSE("Passed low-pT MVA cut");
910  return true;
911  } else {
912  ATH_MSG_VERBOSE("Failed low-pT MVA cut");
913  return false;
914  }
915  }
916 
918  ATH_MSG_VERBOSE("Checking whether muon passes high-pT selection...");
919 
920  // :: Request combined muons
921  if (mu.muonType() != xAOD::Muon::Combined) {
922  ATH_MSG_VERBOSE("Muon is not combined - fail high-pT");
923  return false;
924  }
925  if (mu.author() == xAOD::Muon::STACO) {
926  ATH_MSG_VERBOSE("Muon is STACO - fail high-pT");
927  return false;
928  }
929 
930  // :: Reject muons with out-of-bounds hits
934  ATH_MSG_VERBOSE("Muon has out-of-bounds precision hits - fail high-pT");
935  return false;
936  }
937 
938  // :: Access MS hits information
941 
942 
943  ATH_MSG_VERBOSE("number of precision layers: " << (int)summary.nprecisionLayers);
944 
945  //::: Apply MS Chamber Vetoes
946  // Given according to their eta-phi locations in the muon spectrometer
947  // FORM: CHAMBERNAME[ array of four values ] = { eta 1, eta 2, phi 1, phi 2}
948  // The vetoes are applied based on the MS track if available. If the MS track is not available,
949  // the vetoes are applied according to the combined track, and runtime warning is printed to
950  // the command line.
951  const xAOD::TrackParticle* CB_track = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
952  const xAOD::TrackParticle* MS_track = mu.trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle);
953  if (!MS_track) {
954  ATH_MSG_VERBOSE("passedHighPtCuts - No MS track available for muon. Using combined track.");
955  MS_track = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
956  }
957 
958  if (MS_track && CB_track) {
959  float etaMS = MS_track->eta();
960  float phiMS = MS_track->phi();
961  float etaCB = CB_track->eta();
962 
963  //::: no unspoiled clusters in CSC
964  if (!isRun3() && (std::abs(etaMS) > 2.0 || std::abs(etaCB) > 2.0)) {
965  if (summary.cscUnspoiledEtaHits == 0) {
966  ATH_MSG_VERBOSE("Muon has only spoiled CSC clusters - fail high-pT");
967  return false;
968  }
969  }
970 
971  // veto bad CSC giving troubles with scale factors
972  if (!isRun3() && mu.eta() < -1.899 && std::abs(mu.phi()) < 0.211) {
973  ATH_MSG_VERBOSE("Muon is in eta/phi region vetoed due to disabled chambers in MC - fail high-pT");
974  return false;
975  }
976 
977  //::: Barrel/Endcap overlap region
978  if ((1.01 < std::abs(etaMS) && std::abs(etaMS) < 1.1) || (1.01 < std::abs(etaCB) && std::abs(etaCB) < 1.1)) {
979  ATH_MSG_VERBOSE("Muon is in barrel/endcap overlap region - fail high-pT");
980  return false;
981  }
982 
983  //::: BIS78
984  if (isBIS78(etaMS, phiMS)) {
985  if (!isRun3() || !(m_developMode && m_useBEEBISInHighPtRun3)) {
986  ATH_MSG_VERBOSE("Muon is in BIS7/8 eta/phi region - fail high-pT");
987  return false;
988  }
989  }
990 
993  //if (getRunNumber(true) >= 324320) {
994  //if (isBMG(etaMS, phiMS)) {
995  //ATH_MSG_VERBOSE("Muon is in BMG eta/phi region - fail high-pT");
996  //return false;
997  //}
998  //}
999 
1000  //::: BEE
1001  if (isBEE(etaMS, phiMS)) {
1002  // in Run3, large mis-alignment on the BEE chamber was found. temporarily mask the BEE region
1003  if (isRun3() && !(m_developMode && m_useBEEBISInHighPtRun3)) {
1004  ATH_MSG_VERBOSE("Muon is in BEE eta/phi region - fail high-pT");
1005  return false;
1006  }
1007  // Muon falls in the BEE eta-phi region: asking for 4 good precision layers
1008  // if( nGoodPrecLayers < 4 ) return false; // postponed (further studies needed)
1009  if (summary.nprecisionLayers < 4) {
1010  ATH_MSG_VERBOSE("Muon is in BEE eta/phi region and does not have 4 precision layers - fail high-pT");
1011  return false;
1012  }
1013  }
1014  if (std::abs(etaCB) > 1.4) {
1015  // Veto residual 3-station muons in BEE region due to MS eta/phi resolution effects
1016  // if( nGoodPrecLayers<4 && (extendedSmallHits>0||extendedSmallHoles>0) ) return false; // postponed (further studies
1017  // needed)
1018  if (summary.nprecisionLayers < 4 && (summary.extendedSmallHits > 0 || summary.extendedSmallHoles > 0)) {
1019  ATH_MSG_VERBOSE("Muon is in BEE eta/phi region and does not have 4 precision layers - fail high-pT");
1020  return false;
1021  }
1022  }
1023  } else {
1024  ATH_MSG_WARNING("passedHighPtCuts - MS or CB track missing in muon! Failing High-pT selection...");
1025  return false;
1026  }
1027 
1028  //::: Apply 1/p significance cut
1029  const xAOD::TrackParticle* idtrack = mu.trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
1030  const xAOD::TrackParticle* metrack = mu.trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
1031  if (idtrack && metrack && metrack->definingParametersCovMatrix()(4, 4) > 0) { const float qOverPsignif = qOverPsignificance(mu);
1032 
1033  ATH_MSG_VERBOSE("qOverP significance: " << qOverPsignif);
1034 
1035  if (std::abs(qOverPsignif) > 7) {
1036  ATH_MSG_VERBOSE("Muon failed qOverP significance cut");
1037  return false;
1038  }
1039  } else {
1040  ATH_MSG_VERBOSE("Muon missing ID or ME tracks - fail high-pT");
1041  return false;
1042  }
1043 
1044  // Accept good 2-station muons if the user has opted to include these
1045  if (m_use2stationMuonsHighPt && summary.nprecisionLayers == 2) {
1046  // should not accept EM+EO muons due to ID/MS alignment issues
1047  if (std::abs(mu.eta()) > 1.2 && summary.extendedSmallHits < 3 && summary.extendedLargeHits < 3) {
1048  ATH_MSG_VERBOSE("2-station muon with EM+EO - fail high-pT");
1049  return false;
1050  }
1051 
1052  // only select muons missing the inner precision layer
1053  // apply strict veto on overlap between small and large sectors
1054 
1055  if (summary.innerLargeHits == 0 && summary.middleLargeHits == 0 && summary.outerLargeHits == 0 &&
1056  summary.extendedLargeHits == 0 && summary.middleSmallHits > 2 &&
1057  (summary.outerSmallHits > 2 || summary.extendedSmallHits > 2)) {
1058  ATH_MSG_VERBOSE("Accepted 2-station muon in small sector");
1059  return true;
1060  }
1061 
1062  if (summary.innerSmallHits == 0 && summary.middleSmallHits == 0 && summary.outerSmallHits == 0 &&
1063  summary.extendedSmallHits == 0 && summary.middleLargeHits > 2 &&
1064  (summary.outerLargeHits > 2 || summary.extendedLargeHits > 2)) {
1065  ATH_MSG_VERBOSE("Accepted 2-station muon in large sector");
1066  return true;
1067  }
1068  }
1069 
1070  //::: Require 3 (good) station muons
1071  if (summary.nprecisionLayers < 3) {
1072  ATH_MSG_VERBOSE("Muon has less than 3 precision layers - fail high-pT");
1073  return false;
1074  }
1075 
1076  // Remove 3-station muons with small-large sectors overlap
1077  if (summary.isSmallGoodSectors) {
1078  if (!(summary.innerSmallHits > 2 && summary.middleSmallHits > 2 &&
1079  (summary.outerSmallHits > 2 || summary.extendedSmallHits > 2))) {
1080  ATH_MSG_VERBOSE("Muon has small/large sectors overlap - fail high-pT");
1081  return false;
1082  }
1083  } else {
1084  if (!(summary.innerLargeHits > 2 && summary.middleLargeHits > 2 &&
1085  (summary.outerLargeHits > 2 || summary.extendedLargeHits > 2))) {
1086  ATH_MSG_VERBOSE("Muon has small/large sectors overlap - fail high-pT");
1087  return false;
1088  }
1089  }
1090 
1091  ATH_MSG_VERBOSE("Muon passed high-pT selection");
1092  return true;
1093  }
1094 
1096  // ::
1097  if (mu.muonType() != xAOD::Muon::Combined) return false;
1098  // ::
1099  double start_cut = 3.0;
1100  double end_cut = 1.6;
1101  double abs_eta = std::abs(mu.eta());
1102 
1103  // parametrization of expected q/p error as function of pT
1104  double p0(8.0), p1(0.), p2(0.);
1105  if(isRun3()) //MC21 optimization
1106  {
1107  if(abs_eta<=1.05){
1108  p1=0.046;
1109  p2=0.00005;
1110  }
1111  else if (abs_eta > 1.05 && abs_eta <= 1.3) {
1112  p1 = 0.052;
1113  p2 = 0.00008;
1114  } else if (abs_eta > 1.3 && abs_eta <= 1.7) {
1115  p1 = 0.068;
1116  p2 = 0.00006;
1117  } else if (abs_eta > 1.7 && abs_eta <= 2.0) {
1118  p1 = 0.048;
1119  p2 = 0.00006;
1120  } else if (abs_eta > 2.0) {
1121  p1 = 0.037;
1122  p2 = 0.00006;
1123  }
1124  }
1125  else
1126  {
1127  if(abs_eta<=1.05){
1128  p1=0.039;
1129  p2=0.00006;
1130  }
1131  else if (abs_eta > 1.05 && abs_eta <= 1.3) {
1132  p1 = 0.040;
1133  p2 = 0.00009;
1134  } else if (abs_eta > 1.3 && abs_eta <= 1.7) {
1135  p1 = 0.056;
1136  p2 = 0.00008;
1137  } else if (abs_eta > 1.7 && abs_eta <= 2.0) {
1138  p1 = 0.041;
1139  p2 = 0.00006;
1140  } else if (abs_eta > 2.0) {
1141  p1 = 0.031;
1142  p2 = 0.00006;
1143  }
1144  }
1145  // ::
1146  hitSummary summary{};
1148 
1149  // independent parametrization for 2-station muons
1150  if (m_use2stationMuonsHighPt && summary.nprecisionLayers == 2) {
1151  start_cut = 1.1;
1152  end_cut=0.7;
1153  p1 = 0.0739568;
1154  p2 = 0.00012443;
1155  if (abs_eta > 1.05 && abs_eta < 1.3) {
1156  p1 = 0.0674484;
1157  p2 = 0.000119879;
1158  } else if (abs_eta >= 1.3 && abs_eta < 1.7) {
1159  p1 = 0.041669;
1160  p2 = 0.000178349;
1161  } else if (abs_eta >= 1.7 && abs_eta < 2.0) {
1162  p1 = 0.0488664;
1163  p2 = 0.000137648;
1164  } else if (abs_eta >= 2.0) {
1165  p1 = 0.028077;
1166  p2 = 0.000152707;
1167  }
1168  }
1169  // ::
1170  bool passErrorCutCB = false;
1171  const xAOD::TrackParticle* cbtrack = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
1172  if (cbtrack) {
1173  // ::
1174  double pt_CB = (cbtrack->pt() * MeVtoGeV < 5000.) ? cbtrack->pt() * MeVtoGeV : 5000.; // GeV
1175  double qOverP_CB = cbtrack->qOverP();
1176  double qOverPerr_CB = std::sqrt(cbtrack->definingParametersCovMatrix()(4, 4));
1177  // sigma represents the average expected error at the muon's pt/eta
1178  double sigma = std::sqrt(std::pow(p0 / pt_CB, 2) + std::pow(p1, 2) + std::pow(p2 * pt_CB, 2));
1179  // cutting at start_cut*sigma for pt <=1 TeV depending on eta region,
1180  // then linearly tightening until end_cut*sigma is reached at pt >= 5TeV.
1181  double a = (end_cut - start_cut) / 4000.0;
1182  double b = end_cut - a * 5000.0;
1183  double coefficient = (pt_CB > 1000.) ? (a * pt_CB + b) : start_cut;
1184  if (std::abs(qOverPerr_CB / qOverP_CB) < coefficient * sigma) { passErrorCutCB = true; }
1185  }
1186  // ::
1187  if (m_use2stationMuonsHighPt && m_doBadMuonVetoMimic && summary.nprecisionLayers == 2) {
1189 
1190  if (eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
1191  ATH_MSG_DEBUG("The current event is a MC event. Use bad muon veto mimic.");
1192  return passErrorCutCB && passedBMVmimicCut(mu);
1193  }
1194  }
1195 
1196  // ::
1197  return passErrorCutCB;
1198  }
1199 
1201  TF1* cutFunction;
1202  double p1, p2;
1203  if (std::abs(mu.eta()) < 1.05) {
1204  cutFunction = m_BMVcutFunction_barrel.get();
1205  p1 = 0.066265;
1206  p2 = 0.000210047;
1207  } else {
1208  cutFunction = m_BMVcutFunction_endcap.get();
1209  p1 = 0.0629747;
1210  p2 = 0.000196466;
1211  }
1212 
1213  double qOpRelResolution = std::hypot(p1, p2 * mu.primaryTrackParticle()->pt() * MeVtoGeV);
1214 
1215  double qOverPabs_unsmeared = std::abs(mu.primaryTrackParticle()->definingParameters()[4]);
1216  double qOverPabs_smeared = 1.0 / (mu.pt() * std::cosh(mu.eta()));
1217 
1218  if ((qOverPabs_smeared - qOverPabs_unsmeared) / (qOpRelResolution * qOverPabs_unsmeared) <
1219  cutFunction->Eval(mu.primaryTrackParticle()->pt() * MeVtoGeV))
1220  return false;
1221  else
1222  return true;
1223  }
1224 
1226  // ::
1227  if (mu.muonType() == xAOD::Muon::Combined) { return mu.author() != xAOD::Muon::STACO; }
1228  // ::
1229  if (mu.muonType() == xAOD::Muon::CaloTagged && std::abs(mu.eta()) < 0.105)
1230  return passedCaloTagQuality(mu);
1231  // ::
1232  if (mu.muonType() == xAOD::Muon::SegmentTagged && (std::abs(mu.eta()) < 0.105 || m_useSegmentTaggedLowPt)) return true;
1233  // ::
1234  if (mu.author() == xAOD::Muon::MuidSA && std::abs(mu.eta()) > 2.4) return true;
1235  // ::
1236  if (mu.muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) {
1237  const xAOD::TrackParticle* cbtrack = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
1238  return (cbtrack && std::abs(cbtrack->eta()) > 2.4);
1239  }
1240  // ::
1241  return false;
1242  }
1243 
1245  uint8_t value1{0}, value2{0};
1246 
1249  " !! Tool configured with some of the ID hits requirements changed... FOR DEVELOPMENT ONLY: muon efficiency SF won't be "
1250  "valid !! ");
1251 
1254  if ((value1 + value2 == 0) && !m_PixCutOff) return false;
1255 
1258  if ((value1 + value2 <= 4) && !m_SctCutOff) return false;
1259 
1262  if ((value1 + value2 >= 3) && !m_SiHolesCutOff) return false;
1263 
1264  if (!m_TrtCutOff) {
1265  const float abseta = std::abs(track.eta());
1268  const uint8_t totTRThits = value1 + value2;
1269  if (!((0.1 < abseta && abseta <= 1.9 && totTRThits > 5 && value2 < (0.9 * totTRThits)) || (abseta <= 0.1 || abseta > 1.9)))
1270  return false;
1271  }
1272  // Reached end - all ID hit cuts are passed.
1273  return true;
1274  } // passedIDCuts
1275 
1277  // Use CaloScore variable based on Neural Network if enabled
1278  // The neural network is only trained until eta = 1
1279  // cf. https://cds.cern.ch/record/2802605/files/CERN-THESIS-2021-290.pdf
1280  constexpr float eta_range = 1.;
1281  if (std::abs(mu.eta()) < eta_range && m_useCaloScore) return passedCaloScore(mu);
1282 
1283  // Otherwise we use CaloMuonIDTag
1284  int CaloMuonIDTag = -20;
1285 
1286  // Extract CaloMuonIDTag variable
1287  bool readID = mu.parameter(CaloMuonIDTag, xAOD::Muon::CaloMuonIDTag);
1288  if (!readID) {
1289  ATH_MSG_WARNING("Unable to read CaloMuonIDTag Quality information! Rejecting the CALO muon!");
1290  return false;
1291  }
1292 
1293  // Cut on CaloMuonIDTag variable
1294  return (CaloMuonIDTag > 10);
1295  }
1296 
1298  // We use a working point with a pT-dependent cut on the NN discriminant, designed to achieve a constant
1299  // fakes rejection as function of pT in Z->mumu MC
1300 
1301  // Extract the relevant score variable (NN discriminant)
1302  float CaloMuonScore{-999.0};
1303  retrieveParam(mu, CaloMuonScore, xAOD::Muon::CaloMuonScore);
1304 
1305  if(m_caloScoreWP==1) return (CaloMuonScore >= 0.92);
1306  if(m_caloScoreWP==2) return (CaloMuonScore >= 0.56);
1307  else if(m_caloScoreWP==3 || m_caloScoreWP==4)
1308  {
1309  // Cut on the score variable
1310  float pT = mu.pt() * MeVtoGeV; // GeV
1311 
1312  if (pT > 20.0) // constant cut above 20 GeV
1313  return (CaloMuonScore >= 0.77);
1314  else {
1315  // pT-dependent cut below 20 GeV
1316  // The pT-dependent cut is based on a fit of a third-degree polynomial, with coefficients as given below
1317 
1318  if(m_caloScoreWP==3) return (CaloMuonScore >= (-1.98e-4 * std::pow(pT, 3) +6.04e-3 * std::pow(pT, 2) -6.13e-2 * pT + 1.16));
1319  if(m_caloScoreWP==4) return (CaloMuonScore >= (-1.80e-4 * std::pow(pT, 3) +5.02e-3 * std::pow(pT, 2) -4.62e-2 * pT + 1.12));
1320  }
1321  }
1322 
1323  return false;
1324  }
1325 
1326  bool MuonSelectionTool::passTight(const xAOD::Muon& mu, float rho, float oneOverPSig) const {
1327 
1329  ATH_MSG_VERBOSE("for run3, Tight WP is only supported when ExcludeNSWFromPrecisionLayers=False and RecalcPrecisionLayerswNSW=True");
1330  return false;
1331  }
1332  float symmetric_eta = std::abs(mu.eta());
1333  float pt = mu.pt() * MeVtoGeV; // GeV
1334 
1335  // Impose pT and eta cuts; the bounds of the cut maps
1336  if (pt < 4.0 || symmetric_eta >= 2.5) return false;
1337  ATH_MSG_VERBOSE("Muon is passing tight WP kinematic cuts with pT,eta " << mu.pt() << " , " << mu.eta());
1338 
1339  // ** Low pT specific cuts ** //
1340  if (pt < 20.0) {
1341  double rhoCut = m_tightWP_lowPt_rhoCuts->Interpolate(pt, symmetric_eta);
1342  double qOverPCut = m_tightWP_lowPt_qOverPCuts->Interpolate(pt, symmetric_eta);
1343 
1344  ATH_MSG_VERBOSE("Applying tight WP cuts to a low pt muon with (pt,eta) ( " << pt << " , " << mu.eta() << " ) ");
1345  ATH_MSG_VERBOSE("Rho value " << rho << ", required to be less than " << rhoCut);
1346  ATH_MSG_VERBOSE("Momentum significance value " << oneOverPSig << ", required to be less than " << qOverPCut);
1347 
1348  if (rho > rhoCut) return false;
1349  ATH_MSG_VERBOSE("Muon passed tight WP, low pT rho cut!");
1350 
1351  if (oneOverPSig > qOverPCut) return false;
1352  ATH_MSG_VERBOSE("Muon passed tight WP, low pT momentum significance cut");
1353 
1354  // Tight muon!
1355  return true;
1356 
1357  }
1358 
1359  // ** Medium pT specific cuts ** //
1360  else if (pt < 100.0) {
1361  double rhoCut = m_tightWP_mediumPt_rhoCuts->Interpolate(pt, symmetric_eta);
1362  //
1363  ATH_MSG_VERBOSE("Applying tight WP cuts to a medium pt muon with (pt,eta) (" << pt << "," << mu.eta() << ")");
1364  ATH_MSG_VERBOSE("Rho value " << rho << " required to be less than " << rhoCut);
1365 
1366  // Apply cut
1367  if (rho > rhoCut) return false;
1368  ATH_MSG_VERBOSE("Muon passed tight WP, medium pT rho cut!");
1369 
1370  // Tight muon!
1371  return true;
1372  }
1373 
1374  // ** High pT specific cuts
1375  else if (pt < 500.0) {
1376  //
1377  ATH_MSG_VERBOSE("Applying tight WP cuts to a high pt muon with (pt,eta) (" << pt << "," << mu.eta() << ")");
1378  // No interpolation, since bins with -1 mean we should cut really loose
1379  double rhoCut = m_tightWP_highPt_rhoCuts->GetBinContent(m_tightWP_highPt_rhoCuts->FindFixBin(pt, symmetric_eta));
1380  ATH_MSG_VERBOSE("Rho value " << rho << ", required to be less than " << rhoCut << " unless -1, in which no cut is applied");
1381  //
1382  if (rhoCut < 0.0) return true;
1383  if (rho > rhoCut) return false;
1384  ATH_MSG_VERBOSE("Muon passed tight WP, high pT rho cut!");
1385 
1386  return true;
1387  }
1388  // For muons with pT > 500 GeV, no extra cuts
1389  else {
1390  ATH_MSG_VERBOSE("Not applying any tight WP cuts to a very high pt muon with (pt,eta) (" << pt << "," << mu.eta() << ")");
1391  return true;
1392  }
1393 
1394  // you should never reach this point
1395  return false;
1396  }
1397 
1398  //============================================================================
1400 
1401  checkSanity();
1402 
1416 
1417  if (!isRun3()) {
1418  // ignore missing of cscUnspoiledEtaHits in case we are running in expert developer mode
1419  // e.g. for when we want to apply Run2 WPs in Run3
1421 
1422  if (std::abs(muon.eta()) > 2.0) {
1423  ATH_MSG_VERBOSE("Recalculating number of precision layers for combined muon");
1424  summary.nprecisionLayers = (summary.innerSmallHits > 1 || summary.innerLargeHits > 1)
1425  + (summary.middleSmallHits > 2 || summary.middleLargeHits > 2)
1426  + (summary.outerSmallHits > 2 || summary.outerLargeHits > 2);
1427  }
1428 
1429  } else if (std::abs(muon.eta()) > 1.3 && (m_excludeNSWFromPrecisionLayers || m_recalcPrecisionLayerswNSW)) {
1430  summary.nprecisionLayers = (summary.middleSmallHits > 2 || summary.middleLargeHits > 2)
1431  + (summary.outerSmallHits > 2 || summary.outerLargeHits > 2)
1432  + (summary.extendedSmallHits > 2 || summary.extendedLargeHits > 2);
1433 
1435 
1436  if (!eta1stgchits_acc.isAvailable(muon) || !eta2stgchits_acc.isAvailable(muon) || !mmhits_acc.isAvailable(muon)) {
1437  ATH_MSG_FATAL(__FILE__ << ":" << __LINE__ << " Failed to retrieve NSW hits!"
1438  << " (Please use DxAODs with p-tags >= p5834 OR set ExcludeNSWFromPrecisionLayers to True (tests only)");
1439  throw std::runtime_error("Failed to retrieve NSW hits");
1440  }
1441 
1445  summary.nprecisionLayers += ((summary.etaLayer1STGCHits + summary.etaLayer2STGCHits) > 3 || summary.MMHits > 3);
1446  }
1447  }
1448  }
1449 
1450 
1452  if (!muon.parameter(value, param)) {
1453  ATH_MSG_FATAL(__FILE__ << ":" << __LINE__ << " Failed to retrieve parameter " << param
1454  << " for muon with pT:" << muon.pt() * MeVtoGeV << ", eta:" << muon.eta() << ", phi: " << muon.phi()
1455  << ", q:" << muon.charge() << ", author: " << muon.author());
1456  throw std::runtime_error("Failed to retrieve Parameter");
1457  }
1458  }
1459 
1460  // Returns an integer corresponding to categorization of muons with different resolutions
1462  // Resolutions have only been evaluated for medium combined muons
1464 
1465  // :: Access MS hits information
1466  hitSummary summary{};
1468 
1469  // For muons passing the high-pT working point, distinguish between 2-station tracks and the rest
1470  if (passedHighPtCuts(mu)) {
1471  if (summary.nprecisionLayers == 2)
1472  return ResolutionCategory::highPt2station;
1473  else
1475  }
1476 
1477  const xAOD::TrackParticle* CB_track = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
1478  const xAOD::TrackParticle* MS_track = mu.trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle);
1479  if (!MS_track) {
1480  ATH_MSG_VERBOSE("getResolutionCategory - No MS track available for muon. Using combined track.");
1481  MS_track = mu.trackParticle(xAOD::Muon::CombinedTrackParticle);
1482  }
1483 
1484  if (!MS_track || !CB_track) return ResolutionCategory::unclassified;
1485  const float etaMS = MS_track->eta();
1486  const float etaCB = CB_track->eta();
1487  const float phiMS = MS_track->phi();
1488 
1490 
1491  if ((summary.isSmallGoodSectors && summary.innerSmallHits < 3) || (!summary.isSmallGoodSectors && summary.innerLargeHits < 3))
1492  category = ResolutionCategory::missingInner; // missing-inner
1493 
1494  if ((summary.isSmallGoodSectors && summary.middleSmallHits < 3) || (!summary.isSmallGoodSectors && summary.middleLargeHits < 3))
1495  category = ResolutionCategory::missingMiddle; // missing-middle
1496 
1497  if ((summary.isSmallGoodSectors && summary.outerSmallHits < 3 && summary.extendedSmallHits < 3) ||
1498  (!summary.isSmallGoodSectors && summary.outerLargeHits < 3 && summary.extendedLargeHits < 3))
1499  category = ResolutionCategory::missingOuter; // missing-outer
1500 
1501  if (!isRun3() && (std::abs(etaMS) > 2.0 || std::abs(etaCB) > 2.0) && summary.cscUnspoiledEtaHits == 0)
1502  category = ResolutionCategory::spoiledCSC; // spoiled CSC
1503 
1504  if ((1.01 < std::abs(etaMS) && std::abs(etaMS) < 1.1) || (1.01 < std::abs(etaCB) && std::abs(etaCB) < 1.1))
1505  category = ResolutionCategory::BEoverlap; // barrel-end-cap overlap
1506 
1507  if (isBIS78(etaMS, phiMS)) category = ResolutionCategory::BIS78; // BIS7/8
1508 
1509  //::: BEE
1510  if (isBEE(etaMS, phiMS) || (std::abs(etaCB) > 1.4 && (summary.extendedSmallHits > 0 || summary.extendedSmallHoles > 0))) {
1511  if (summary.extendedSmallHits < 3 && summary.middleSmallHits >= 3 && summary.outerSmallHits >= 3)
1512  category = ResolutionCategory::missingBEE; // missing-BEE
1513 
1514  if (summary.extendedSmallHits >= 3 && summary.outerSmallHits < 3) category = ResolutionCategory::missingOuter; // missing-outer
1515 
1516  if (!summary.isSmallGoodSectors)
1517  category = ResolutionCategory::unclassified; // ambiguity due to eta/phi differences between MS and CB track
1518  }
1519 
1520  if (summary.nprecisionLayers == 1) category = ResolutionCategory::oneStation; // one-station track
1521 
1522  return category;
1523  }
1524 
1525  //============================================================================
1526  // need run number (or random run number) to apply period-dependent selections
1527  unsigned int MuonSelectionTool::getRunNumber(bool needOnlyCorrectYear /*=false*/) const {
1528 
1529  static const SG::AuxElement::ConstAccessor<unsigned int> acc_rnd("RandomRunNumber");
1530 
1532 
1533  // Case of data
1534  if (!eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
1535  ATH_MSG_DEBUG("The current event is a data event. Return runNumber.");
1536  return eventInfo->runNumber();
1537  }
1538 
1539  // Case of MC
1540  // attempt to get the run number assigned by the PRW tool
1541  static std::atomic<bool> issuedWarningPRW{false};
1542  if (acc_rnd.isAvailable(*eventInfo)) {
1543  unsigned int rn = acc_rnd(*eventInfo);
1544  if (rn != 0) return acc_rnd(*eventInfo);
1545 
1546  if (!issuedWarningPRW) {
1547  ATH_MSG_WARNING("Pile up tool has assigned runNumber = 0");
1548  issuedWarningPRW = true;
1549  }
1550  }
1551 
1552  // otherwise return a dummy run number
1553  if (needOnlyCorrectYear) {
1554  if (eventInfo->runNumber() < 300000) { // mc16a (2016): 284500
1555  ATH_MSG_DEBUG("Random run number not available and this is mc16a or mc20a, returning dummy 2016 run number.");
1556  return 311071;
1557 
1558  } else if (eventInfo->runNumber() < 310000) { // mc16d (2017): 300000
1559  ATH_MSG_DEBUG("Random run number not available and this is mc16d or mc20d, returning dummy 2017 run number.");
1560  return 340072;
1561 
1562  } else if (eventInfo->runNumber() < 320000) { // mc16e (2018): 310000
1563  ATH_MSG_DEBUG("Random run number not available and this is mc16e or mc20e, returning dummy 2018 run number.");
1564  return 351359;
1565 
1566  } else if (eventInfo->runNumber() < 500000) { //mc21: 330000, mc23a: 410000, mc23c: 450000
1567  ATH_MSG_DEBUG("Random run number not available and this is mc21/mc23, for the time being we're returing a dummy run number.");
1568  return 399999;
1569  } else {
1570  ATH_MSG_DEBUG("Detected some run 4 / phase II runnumber "<<eventInfo->runNumber()<<". ");
1571  return 666666;
1572  }
1573 
1574  ATH_MSG_FATAL("Random run number not available, fallback option of using runNumber failed since "<<eventInfo->runNumber()<<" cannot be recognised");
1575  throw std::runtime_error("MuonSelectionTool() - need RandomRunNumber decoration by the PileupReweightingTool");
1576  }
1577 
1578  ATH_MSG_FATAL("Failed to find the RandomRunNumber decoration by the PileupReweightingTool");
1579  throw std::runtime_error("MuonSelectionTool() - need RandomRunNumber decoration from PileupReweightingTool");
1580  }
1581 
1582 
1583  // Check if eta/phi coordinates correspond to BIS7/8 chambers
1584  bool MuonSelectionTool::isBIS78(const float eta, const float phi) const {
1585  static constexpr std::array<float, 2> BIS78_eta{1.05, 1.3};
1586  static constexpr std::array<float, 8> BIS78_phi{0.21, 0.57, 1.00, 1.33, 1.78, 2.14, 2.57, 2.93};
1587 
1588  float abs_eta = std::abs(eta);
1589  float abs_phi = std::abs(phi);
1590 
1591  if (abs_eta >= BIS78_eta[0] && abs_eta <= BIS78_eta[1]) {
1592  if ((abs_phi >= BIS78_phi[0] && abs_phi <= BIS78_phi[1]) || (abs_phi >= BIS78_phi[2] && abs_phi <= BIS78_phi[3]) ||
1593  (abs_phi >= BIS78_phi[4] && abs_phi <= BIS78_phi[5]) || (abs_phi >= BIS78_phi[6] && abs_phi <= BIS78_phi[7])) {
1594  return true;
1595  }
1596  }
1597 
1598  return false;
1599  }
1600 
1601  // Check if eta/phi coordinates correspond to BEE chambers
1602  bool MuonSelectionTool::isBEE(const float eta, const float phi) const {
1603  static constexpr std::array<float, 2> BEE_eta{1.440, 1.692};
1604  static constexpr std::array<float, 8> BEE_phi{0.301, 0.478, 1.086, 1.263, 1.872, 2.049, 2.657, 2.834};
1605 
1606  float abs_eta = std::abs(eta);
1607  float abs_phi = std::abs(phi);
1608 
1609  if (abs_eta >= BEE_eta[0] && abs_eta <= BEE_eta[1]) {
1610  if ((abs_phi >= BEE_phi[0] && abs_phi <= BEE_phi[1]) || (abs_phi >= BEE_phi[2] && abs_phi <= BEE_phi[3]) ||
1611  (abs_phi >= BEE_phi[4] && abs_phi <= BEE_phi[5]) || (abs_phi >= BEE_phi[6] && abs_phi <= BEE_phi[7])) {
1612  return true;
1613  }
1614  }
1615 
1616  return false;
1617  }
1618 
1619  // Check if eta/phi coordinates correspond to BMG chambers
1620  bool MuonSelectionTool::isBMG(const float eta, const float phi) const {
1621  static constexpr std::array<float, 6> BMG_eta{0.35, 0.47, 0.68, 0.80, 0.925, 1.04};
1622  static constexpr std::array<float, 4> BMG_phi{-1.93, -1.765, -1.38, -1.21};
1623 
1624  float abs_eta = std::abs(eta);
1625 
1626  if ((abs_eta >= BMG_eta[0] && abs_eta <= BMG_eta[1]) || (abs_eta >= BMG_eta[2] && abs_eta <= BMG_eta[3]) ||
1627  (abs_eta >= BMG_eta[4] && abs_eta <= BMG_eta[5])) {
1628  if ((phi >= BMG_phi[0] && phi <= BMG_phi[1]) || (phi >= BMG_phi[2] && phi <= BMG_phi[3])) { return true; }
1629  }
1630 
1631  return false;
1632  }
1633 
1634 } // namespace CP
BIS
@ BIS
Definition: RegSelEnums.h:11
xAOD::TrackParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TrackParticle_v1.cxx:73
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
xAOD::numberOfPixelHoles
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
Definition: TrackingPrimitives.h:261
LikeEnum::Loose
@ Loose
Definition: LikelihoodEnums.h:12
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
CXXUTILS_TRAPPING_FP
#define CXXUTILS_TRAPPING_FP
Definition: trapping_fp.h:24
CalculateHighPtTerm.pT
pT
Definition: ICHEP2016/CalculateHighPtTerm.py:57
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
CP::MuonSelectionTool::m_MVAreaderFile_MuTagIMO_etaBin2
Gaudi::Property< std::string > m_MVAreaderFile_MuTagIMO_etaBin2
Definition: MuonSelectionTool.h:217
CP::MuonSelectionTool::passTight
bool passTight(const xAOD::Muon &mu, float rho, float oneOverPSig) const
Returns true if the muon passed the tight working point cuts.
Definition: MuonSelectionTool.cxx:1326
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
CP::MuonSelectionTool::m_acceptInfo
asg::AcceptInfo m_acceptInfo
Store selection information.
Definition: MuonSelectionTool.h:169
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
CSS
@ CSS
Definition: ParabolaCscClusterFitter.h:25
BIL
@ BIL
Definition: RegSelEnums.h:10
xAOD::MuGirl
@ MuGirl
MuGirl.
Definition: TrackingPrimitives.h:141
LikeEnum::VeryLoose
@ VeryLoose
Definition: LikelihoodEnums.h:11
CP::MuonSelectionTool::m_use2stationMuonsHighPt
Gaudi::Property< bool > m_use2stationMuonsHighPt
Definition: MuonSelectionTool.h:190
xAOD::numberOfPrecisionHoleLayers
@ numberOfPrecisionHoleLayers
layers with holes AND no hits [unit8_t].
Definition: TrackingPrimitives.h:289
CP::MuonSelectionTool::m_quality
Gaudi::Property< int > m_quality
Definition: MuonSelectionTool.h:172
AddEmptyComponent.histName
string histName
Definition: AddEmptyComponent.py:64
CP::MuonSelectionTool::m_custom_dir
Gaudi::Property< std::string > m_custom_dir
Definition: MuonSelectionTool.h:226
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
CP::MuonSelectionTool::passedCaloTagQuality
virtual bool passedCaloTagQuality(const xAOD::Muon &mu) const override
Returns true if the muon passed additional calo-tag quality cuts.
Definition: MuonSelectionTool.cxx:1276
CP::MuonSelectionTool::m_MVAreaderFile_MuTagIMO_etaBin3
Gaudi::Property< std::string > m_MVAreaderFile_MuTagIMO_etaBin3
Definition: MuonSelectionTool.h:219
xAOD::etaMS
setSAddress etaMS
Definition: L2StandAloneMuon_v1.cxx:116
CP::MuonSelectionTool::getQuality
virtual xAOD::Muon::Quality getQuality(const xAOD::Muon &mu) const override
Returns the quality of the muon. To set the value on the muon, instead call setQuality(xAOD::Muon&) c...
Definition: MuonSelectionTool.cxx:415
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
CP::MuonSelectionTool::m_MVAreaderFile_EVEN_MuidCB
Gaudi::Property< std::string > m_MVAreaderFile_EVEN_MuidCB
Definition: MuonSelectionTool.h:201
xAOD::TrackParticle_v1::charge
float charge() const
Returns the charge.
Definition: TrackParticle_v1.cxx:150
CP::MuonSelectionTool::m_useAllAuthors
Gaudi::Property< bool > m_useAllAuthors
Definition: MuonSelectionTool.h:189
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
CP::MuonSelectionTool::m_reader_MUTAGIMO_etaBin3
std::unique_ptr< TMVA::Reader > m_reader_MUTAGIMO_etaBin3
Definition: MuonSelectionTool.h:257
CP::MuonSelectionTool::m_disablePtCuts
Gaudi::Property< bool > m_disablePtCuts
Definition: MuonSelectionTool.h:183
xAOD::TrackParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TrackParticle_v1.cxx:77
CP::MuonSelectionTool::m_readerE_MUID
std::unique_ptr< TMVA::Reader > m_readerE_MUID
Definition: MuonSelectionTool.h:250
plotmaker.hist
hist
Definition: plotmaker.py:148
xAOD::L2MuonParameters::BEE
@ BEE
BEE measurement point.
Definition: TrigMuonDefs.h:24
xAOD::extendedSmallHoles
@ extendedSmallHoles
number of precision holes in the extended small layer
Definition: TrackingPrimitives.h:345
CP::MuonSelectionTool::passedIDCuts
virtual bool passedIDCuts(const xAOD::Muon &) const override
Returns true if the muon passes the standard MCP ID cuts.
Definition: MuonSelectionTool.cxx:594
CP::MuonSelectionTool::m_BMVcutFunction_barrel
std::unique_ptr< TF1 > m_BMVcutFunction_barrel
Definition: MuonSelectionTool.h:240
CP::MuonSelectionTool::isBEE
bool isBEE(const float eta, const float phi) const
Check if muon eta/phi falls in BEE chambers.
Definition: MuonSelectionTool.cxx:1602
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
CP::MuonSelectionTool::m_readerE_MUGIRL
std::unique_ptr< TMVA::Reader > m_readerE_MUGIRL
Definition: MuonSelectionTool.h:252
MuonParameters::scatteringNeighbourSignificance
@ scatteringNeighbourSignificance
Definition: MuonParamDefs.h:135
asg
Definition: DataHandleTestTool.h:28
test_pyathena.pt
pt
Definition: test_pyathena.py:11
CP::MeVtoGeV
constexpr float MeVtoGeV
Definition: IsolationCloseByCorrectionTool.cxx:33
CP::MuonSelectionTool::m_turnOffMomCorr
Gaudi::Property< bool > m_turnOffMomCorr
Definition: MuonSelectionTool.h:182
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
CP::MuonSelectionTool::m_tightWP_highPt_rhoCuts
std::unique_ptr< TH1 > m_tightWP_highPt_rhoCuts
Definition: MuonSelectionTool.h:238
CP::MuonSelectionTool::getHist
StatusCode getHist(TFile *file, const std::string &histName, std::unique_ptr< TH1 > &hist) const
Checks for each histogram.
Definition: MuonSelectionTool.cxx:228
egammaParameters::ParamDef
ParamDef
Definition: egammaParamDefs.h:99
athena.value
value
Definition: athena.py:124
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:259
CP::MuonSelectionTool::passedLowPtEfficiencyCuts
virtual bool passedLowPtEfficiencyCuts(const xAOD::Muon &) const override
Returns true if the muon passes the standard MCP low pt cuts.
Definition: MuonSelectionTool.cxx:675
CP::MuonSelectionTool::m_PixCutOff
Gaudi::Property< bool > m_PixCutOff
Definition: MuonSelectionTool.h:187
CP::MuonSelectionTool::setPassesIDCuts
virtual void setPassesIDCuts(xAOD::Muon &) const override
set the passes ID cuts variable of the muon
Definition: MuonSelectionTool.cxx:592
xAOD::numberOfTRTHits
@ numberOfTRTHits
number of TRT hits [unit8_t].
Definition: TrackingPrimitives.h:275
xAOD::middleLargeHoles
@ middleLargeHoles
number of precision holes in the middle large layer
Definition: TrackingPrimitives.h:342
CP::MuonSelectionTool::m_readerO_MUGIRL
std::unique_ptr< TMVA::Reader > m_readerO_MUGIRL
Definition: MuonSelectionTool.h:253
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CP::MuonSelectionTool::retrieveParam
void retrieveParam(const xAOD::Muon &muon, float &value, const xAOD::Muon::ParamDef param) const
Definition: MuonSelectionTool.cxx:1451
CP::MuonSelectionTool::passedCaloScore
virtual bool passedCaloScore(const xAOD::Muon &mu) const override
Returns true if the muon passed the CaloScore calo-tag working point.
Definition: MuonSelectionTool.cxx:1297
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
BOL
@ BOL
Definition: RegSelEnums.h:14
CP::MuonSelectionTool::m_isRun3
Gaudi::Property< bool > m_isRun3
Definition: MuonSelectionTool.h:174
xAOD::EventInfo_v1::IS_SIMULATION
@ IS_SIMULATION
true: simulation, false: data
Definition: EventInfo_v1.h:151
x
#define x
CP::MuonSelectionTool::m_MVAreaderFile_ODD_MuGirl
Gaudi::Property< std::string > m_MVAreaderFile_ODD_MuGirl
Definition: MuonSelectionTool.h:211
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
CP::MuonSelectionTool::m_toroidOff
Gaudi::Property< bool > m_toroidOff
Definition: MuonSelectionTool.h:173
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
CP::MuonSelectionTool::passedHighPtCuts
virtual bool passedHighPtCuts(const xAOD::Muon &) const override
Returns true if the muon passes the standard MCP High Pt cuts.
Definition: MuonSelectionTool.cxx:917
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
xAOD::innerLargeHits
@ innerLargeHits
number of precision hits in the inner large layer
Definition: TrackingPrimitives.h:331
CP::MuonSelectionTool::m_BMVcutFile
Gaudi::Property< std::string > m_BMVcutFile
file for bad muon veto mimic cut functions
Definition: MuonSelectionTool.h:229
CP::MuonSelectionTool::m_useMVALowPt
Gaudi::Property< bool > m_useMVALowPt
Definition: MuonSelectionTool.h:191
CP::MuonSelectionTool::m_BMVcutFunction_endcap
std::unique_ptr< TF1 > m_BMVcutFunction_endcap
Definition: MuonSelectionTool.h:241
MuonParameters::MuTagIMO
@ MuTagIMO
Definition: MuonParamDefs.h:66
xAOD::cscUnspoiledEtaHits
@ cscUnspoiledEtaHits
number of unspoiled CSC eta clusters on track
Definition: TrackingPrimitives.h:450
CP::MuonSelectionTool::m_recalcPrecisionLayerswNSW
Gaudi::Property< bool > m_recalcPrecisionLayerswNSW
Definition: MuonSelectionTool.h:176
MuonParameters::momentumBalanceSignificance
@ momentumBalanceSignificance
Definition: MuonParamDefs.h:136
CP::MuonSelectionTool::m_developMode
Gaudi::Property< bool > m_developMode
Definition: MuonSelectionTool.h:184
CP::MuonSelectionTool::passedErrorCutCB
virtual bool passedErrorCutCB(const xAOD::Muon &) const override
Returns true if a CB muon passes a pt- and eta-dependent cut on the relative CB q/p error.
Definition: MuonSelectionTool.cxx:1095
xAOD::middleLargeHits
@ middleLargeHits
number of precision hits in the middle large layer
Definition: TrackingPrimitives.h:333
xAOD::phi
setEt phi
Definition: TrigEMCluster_v1.cxx:29
InDet::ExclusiveOrigin::Primary
@ Primary
Definition: InDetTrackTruthOriginDefs.h:163
MuonParameters::highPt
@ highPt
Definition: MuonParamDefs.h:51
CP::MuonSelectionTool::setQuality
virtual void setQuality(xAOD::Muon &mu) const override
set the passes low pT cuts variable of the muon
Definition: MuonSelectionTool.cxx:357
CP::MuonSelectionTool::m_doBadMuonVetoMimic
Gaudi::Property< bool > m_doBadMuonVetoMimic
Definition: MuonSelectionTool.h:194
CP::MuonSelectionTool::m_eventInfo
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo
Definition: MuonSelectionTool.h:198
uint
unsigned int uint
Definition: LArOFPhaseFill.cxx:20
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
CP::MuonSelectionTool::passedBMVmimicCut
bool passedBMVmimicCut(const xAOD::Muon &) const
Returns true if the muon passes a cut which mimics the effect of the combined error cut This is neces...
Definition: MuonSelectionTool.cxx:1200
CP::MuonSelectionTool::qOverPsignificance
float qOverPsignificance(const xAOD::Muon &muon) const
Returns q/p significance of the muon (see definition in https://cds.cern.ch/record/2665711 )
Definition: MuonSelectionTool.cxx:380
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
CP::MuonSelectionTool::passedMuonCuts
virtual bool passedMuonCuts(const xAOD::Muon &) const override
Returns true if the muon passes a standardized loose preselection.
Definition: MuonSelectionTool.cxx:1225
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
asg::AcceptInfo
Definition: AcceptInfo.h:28
CP::MuonSelectionTool::hitSummary
struct to handle easily number of hits in different parts of the MS
Definition: MuonSelectionTool.h:127
lumiFormat.i
int i
Definition: lumiFormat.py:85
xAOD::extendedLargeHits
@ extendedLargeHits
number of precision hits in the extended large layer
Definition: TrackingPrimitives.h:337
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
CP::MuonSelectionTool::isBMG
bool isBMG(const float eta, const float phi) const
Check if muon eta/phi falls in BMG chambers.
Definition: MuonSelectionTool.cxx:1620
ReweightUtils.category
category
Definition: ReweightUtils.py:15
CP::MuonSelectionTool::isBIS78
bool isBIS78(const float eta, const float phi) const
Check if muon eta/phi falls in BIS7/8 chambers.
Definition: MuonSelectionTool.cxx:1584
CP::MuonSelectionTool::m_useLRT
Gaudi::Property< bool > m_useLRT
Definition: MuonSelectionTool.h:179
xAOD::MMHits
@ MMHits
Definition: TrackingPrimitives.h:437
CP::MuonSelectionTool::m_caloScoreWP
Gaudi::Property< int > m_caloScoreWP
Definition: MuonSelectionTool.h:178
LHEF::Reader
Pythia8::Reader Reader
Definition: Prophecy4fMerger.cxx:11
MuonParameters::segmentDeltaEta
@ segmentDeltaEta
MuTag parameters.
Definition: MuonParamDefs.h:139
athena.file_path
file_path
Definition: athena.py:94
CP::MuonSelectionTool::getAcceptInfo
virtual const asg::AcceptInfo & getAcceptInfo() const override
Get an object describing the "selection steps" of the tool.
Definition: MuonSelectionTool.cxx:249
file
TFile * file
Definition: tile_monitor.h:29
python.BunchSpacingUtils.rn
rn
Definition: BunchSpacingUtils.py:87
xAOD::middleSmallHoles
@ middleSmallHoles
number of precision holes in the middle small layer
Definition: TrackingPrimitives.h:341
xAOD::combinedTrackOutBoundsPrecisionHits
@ combinedTrackOutBoundsPrecisionHits
total out-of-bounds hits on the combined track
Definition: TrackingPrimitives.h:377
CP::MuonSelectionTool::m_useSegmentTaggedLowPt
Gaudi::Property< bool > m_useSegmentTaggedLowPt
Definition: MuonSelectionTool.h:192
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonSelectionTool.h
CP::MuonSelectionTool::getSegmentsSorted
std::vector< const xAOD::MuonSegment * > getSegmentsSorted(const xAOD::Muon &mu) const
Returns a vector of the muon's segments, sorted according to chamber index.
Definition: MuonSelectionTool.cxx:795
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
CP::MuonSelectionTool::m_calibration_version
Gaudi::Property< std::string > m_calibration_version
Definition: MuonSelectionTool.h:223
CP::MuonSelectionTool::m_excludeNSWFromPrecisionLayers
Gaudi::Property< bool > m_excludeNSWFromPrecisionLayers
Definition: MuonSelectionTool.h:175
xAOD::numberOfSCTHoles
@ numberOfSCTHoles
number of SCT holes [unit8_t].
Definition: TrackingPrimitives.h:270
xAOD::isSmallGoodSectors
@ isSmallGoodSectors
if non-deweighted track chambers are small
Definition: TrackingPrimitives.h:380
xAOD::SiSpacePointsSeedMaker_LargeD0
@ SiSpacePointsSeedMaker_LargeD0
Definition: TrackingPrimitives.h:183
CP::MuonSelectionTool::getRunNumber
unsigned int getRunNumber(bool needOnlyCorrectYear=false) const
Definition: MuonSelectionTool.cxx:1527
xAOD::etaLayer2STGCHits
@ etaLayer2STGCHits
number of eta hits in the second STGC trigger layer (STGC2)
Definition: TrackingPrimitives.h:428
Trk::Combined
@ Combined
Definition: TrackSummaryTool.h:32
LikeEnum::Tight
@ Tight
Definition: LikelihoodEnums.h:15
trapping_fp.h
Tell the compiler to optimize assuming that FP may trap.
MuonParameters::scatteringCurvatureSignificance
@ scatteringCurvatureSignificance
Definition: MuonParamDefs.h:134
xAOD::TrackParticle_v1::qOverP
float qOverP() const
Returns the parameter.
PathResolver.h
CP::MuonSelectionTool::m_low_pt_mva_mutex
std::mutex m_low_pt_mva_mutex
Definition: MuonSelectionTool.h:260
xAOD::TrackParticle_v1::definingParametersCovMatrix
const ParametersCovMatrix_t definingParametersCovMatrix() const
Returns the 5x5 symmetric matrix containing the defining parameters covariance matrix.
Definition: TrackParticle_v1.cxx:246
xAOD::middleSmallHits
@ middleSmallHits
number of precision hits in the middle small layer
Definition: TrackingPrimitives.h:332
CP::MuonSelectionTool::accept
virtual asg::AcceptData accept(const xAOD::IParticle *p) const override
Get the decision using a generic IParticle pointer.
Definition: MuonSelectionTool.cxx:251
CP::MuonSelectionTool::m_useBEEBISInHighPtRun3
Gaudi::Property< bool > m_useBEEBISInHighPtRun3
Definition: MuonSelectionTool.h:196
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
CP::MuonSelectionTool::m_reader_MUTAGIMO_etaBin1
std::unique_ptr< TMVA::Reader > m_reader_MUTAGIMO_etaBin1
Definition: MuonSelectionTool.h:255
ReadHandle.h
Handle class for reading from StoreGate.
CP::MuonSelectionTool::m_tightWP_mediumPt_rhoCuts
std::unique_ptr< TH1 > m_tightWP_mediumPt_rhoCuts
Definition: MuonSelectionTool.h:237
CP::MuonSelectionTool::m_readerO_MUID
std::unique_ptr< TMVA::Reader > m_readerO_MUID
Definition: MuonSelectionTool.h:251
CP::MuonSelectionTool::m_useCaloScore
Gaudi::Property< bool > m_useCaloScore
Definition: MuonSelectionTool.h:177
CP::MuonSelectionTool::checkSanity
void checkSanity() const
Definition: MuonSelectionTool.cxx:270
MuonParameters::MuidSA
@ MuidSA
Definition: MuonParamDefs.h:59
MuonHough::ChIdx
Muon::MuonStationIndex::ChIndex ChIdx
Definition: MuonRegionHough.cxx:9
xAOD::outerSmallHits
@ outerSmallHits
number of precision hits in the outer small layer
Definition: TrackingPrimitives.h:334
CP::MuonSelectionTool::m_SiHolesCutOff
Gaudi::Property< bool > m_SiHolesCutOff
Definition: MuonSelectionTool.h:188
CP::MuonSelectionTool::m_MVAreaderFile_MuTagIMO_etaBin1
Gaudi::Property< std::string > m_MVAreaderFile_MuTagIMO_etaBin1
Definition: MuonSelectionTool.h:215
IDTPM::chiSquared
float chiSquared(const U &p)
Definition: TrackParametersHelper.h:128
CP::MuonSelectionTool::m_tightWP_lowPt_qOverPCuts
std::unique_ptr< TH1 > m_tightWP_lowPt_qOverPCuts
Definition: MuonSelectionTool.h:236
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
Muon
struct TBPatternUnitContext Muon
CP::MuonSelectionTool::initialize
virtual StatusCode initialize() override
Function initialising the tool.
Definition: MuonSelectionTool.cxx:59
CP::MuonSelectionTool::isBadMuon
virtual bool isBadMuon(const xAOD::Muon &) const override
Returns true if a CB muon fails some loose quaility requirements designed to remove pathological trac...
Definition: MuonSelectionTool.cxx:629
CP::MuonSelectionTool::m_reader_MUTAGIMO_etaBin2
std::unique_ptr< TMVA::Reader > m_reader_MUTAGIMO_etaBin2
Definition: MuonSelectionTool.h:256
CP::MuonSelectionTool::m_tightWP_lowPt_rhoCuts
std::unique_ptr< TH1 > m_tightWP_lowPt_rhoCuts
Definition: MuonSelectionTool.h:235
CP::MuonSelectionTool::MuonSelectionTool
MuonSelectionTool(const std::string &name="MuonSelection")
Create a proper constructor for Athena.
Definition: MuonSelectionTool.cxx:55
xAOD::numberOfTRTOutliers
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
Definition: TrackingPrimitives.h:276
CP::MuonSelectionTool::isRun3
bool isRun3(bool forceOnTheFly=false) const
Definition: MuonSelectionTool.h:266
MuonParameters::MuidCo
@ MuidCo
Definition: MuonParamDefs.h:60
xAOD::outerLargeHits
@ outerLargeHits
number of precision hits in the outer large layer
Definition: TrackingPrimitives.h:335
a
TList * a
Definition: liststreamerinfos.cxx:10
CP::MuonSelectionTool::m_maxEta
Gaudi::Property< double > m_maxEta
Definition: MuonSelectionTool.h:171
asg::AcceptData::setCutResult
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer)
Definition: AcceptData.h:134
BML
@ BML
Definition: RegSelEnums.h:12
LikeEnum::Medium
@ Medium
Definition: LikelihoodEnums.h:14
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::numberOfSCTDeadSensors
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:273
DeMoScan.first
bool first
Definition: DeMoScan.py:536
BMS
@ BMS
Definition: RegSelEnums.h:13
CP::MuonSelectionTool::m_TrtCutOff
Gaudi::Property< bool > m_TrtCutOff
Definition: MuonSelectionTool.h:185
xAOD::etaLayer1STGCHits
@ etaLayer1STGCHits
number of eta hits in the first STGC trigger layer (STGC1)
Definition: TrackingPrimitives.h:427
xAOD::numberOfGoodPrecisionLayers
@ numberOfGoodPrecisionLayers
layers with at least 3 hits that are not deweighted [uint8_t]
Definition: TrackingPrimitives.h:294
CP::MuonSelectionTool::IdMsPt
void IdMsPt(const xAOD::Muon &muon, float &idPt, float &msPt) const
Definition: MuonSelectionTool.cxx:361
CP::MuonSelectionTool::retrieveSummaryValue
void retrieveSummaryValue(const P &muon, T &value, const S type, bool ignoreMissing=false) const
helper function to retrieve a hitSummary value
Definition: MuonSelectionTool.h:148
Muon::MuonStationIndex::ChIndex
ChIndex
enum to classify the different chamber layers in the muon spectrometer
Definition: MuonStationIndex.h:15
CP::MuonSelectionTool::m_geoOnTheFly
Gaudi::Property< bool > m_geoOnTheFly
Definition: MuonSelectionTool.h:193
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:268
CP::MuonSelectionTool::~MuonSelectionTool
virtual ~MuonSelectionTool()
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
CP::MuonSelectionTool::m_allowComm
Gaudi::Property< bool > m_allowComm
Definition: MuonSelectionTool.h:195
xAOD::STACO
@ STACO
Tracks produced by STACO.
Definition: TrackingPrimitives.h:99
xAOD::numberOfPixelDeadSensors
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:266
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
xAOD::extendedSmallHits
@ extendedSmallHits
number of precision hits in the extended small layer
Definition: TrackingPrimitives.h:336
CP::MuonSelectionTool::m_MVAreaderFile_ODD_MuidCB
Gaudi::Property< std::string > m_MVAreaderFile_ODD_MuidCB
Definition: MuonSelectionTool.h:204
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
collisions.reader
reader
read the goodrunslist xml file(s)
Definition: collisions.py:22
CSL
@ CSL
Definition: ParabolaCscClusterFitter.h:25
xAOD::innerSmallHits
@ innerSmallHits
number of precision hits in the inner small layer
Definition: TrackingPrimitives.h:330
CP::MuonSelectionTool::passedLowPtEfficiencyMVACut
bool passedLowPtEfficiencyMVACut(const xAOD::Muon &) const
Definition: MuonSelectionTool.cxx:811
asg::AcceptData
Definition: AcceptData.h:30
CP::MuonSelectionTool::fillSummary
void fillSummary(const xAOD::Muon &muon, hitSummary &summary) const
functions that fills a hitSummary for a muon
Definition: MuonSelectionTool.cxx:1399
BOS
@ BOS
Definition: RegSelEnums.h:15
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
CP::MuonSelectionTool::getResolutionCategory
virtual int getResolutionCategory(const xAOD::Muon &) const override
Returns an integer corresponding to categorization of muons with different resolutions.
Definition: MuonSelectionTool.cxx:1461
xAOD::TrackParticle_v1::theta
float theta() const
Returns the parameter, which has range 0 to .
CP::MuonSelectionTool::m_SctCutOff
Gaudi::Property< bool > m_SctCutOff
Definition: MuonSelectionTool.h:186
TrackingPrimitives.h
CP::MuonSelectionTool::m_MVAreaderFile_EVEN_MuGirl
Gaudi::Property< std::string > m_MVAreaderFile_EVEN_MuGirl
Definition: MuonSelectionTool.h:208
fitman.rho
rho
Definition: fitman.py:532
TRTCalib_cfilter.p0
p0
Definition: TRTCalib_cfilter.py:129
xAOD::TrackParticle_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
xAOD::EventInfo_v1::eventType
bool eventType(EventType type) const
Check for one particular bitmask value.
GlobalVariables.eta_range
eta_range
Definition: GlobalVariables.py:359
asg::AcceptInfo::addCut
int addCut(const std::string &cutName, const std::string &cutDescription)
Add a cut; returning the cut position.
Definition: AcceptInfo.h:53
xAOD::TauJetParameters::unclassified
@ unclassified
Definition: TauDefs.h:410
CP::MuonSelectionTool::rhoPrime
float rhoPrime(const xAOD::Muon &muon) const
Returns rhoPrime of the muon (see definition in https://cds.cern.ch/record/2665711 )
Definition: MuonSelectionTool.cxx:404
xAOD::numberOfPrecisionLayers
@ numberOfPrecisionLayers
layers with at least 3 hits [unit8_t].
Definition: TrackingPrimitives.h:288
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65