ATLAS Offline Software
L2MuonSAIOMon.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "L2MuonSAIOMon.h"
6 
8 #include "MuonMatchingTool.h"
9 #include "math.h"
10 
11 L2MuonSAIOMon :: L2MuonSAIOMon(const std::string& name, ISvcLocator* pSvcLocator )
12  : TrigMuonMonitorAlgorithm(name, pSvcLocator)
13 {}
14 
16 
18  ATH_CHECK( m_L2MuonCBIOContainerKey.initialize() );
19 
20  unsigned int nchains = m_monitored_chains.size();
21  if(nchains!=m_monitored_chains_plateau.size()){
22  ATH_MSG_ERROR("Configuration seems to be wrong. The size of \"Plateaus\" should be same as \"MonitoredChainds\".");
23  return StatusCode::FAILURE;
24  } else {
25  for(unsigned int ichain=0; ichain<nchains; ++ichain){
27  }
28  }
29  return StatusCode::SUCCESS;
30 }
31 
32 
33 
34 StatusCode L2MuonSAIOMon :: fillVariablesPerChain(const EventContext &ctx, const std::string &chain) const {
35 
36  ATH_MSG_DEBUG ("Filling histograms for " << name() << "...");
37 
38  if( chain.find("probe") != std::string::npos ) return StatusCode::SUCCESS; // don't use TagAndProbe chains
39 
40 
41  const float ZERO_LIMIT = 0.00001;
42 
43 
44  //TDT workaround
45  std::vector< const xAOD::L2CombinedMuon* > Trig_L2IOobjects;
46  //std::vector< bool > pass_muCombHypo;
47  ATH_CHECK( matchL2IO_wContainer(ctx, chain, Trig_L2IOobjects) );
48  //bool pass_muCombHypo_evt = muCombHypo_TDTworkaround(chain, Trig_L2IOobjects, pass_muCombHypo);
49  ATH_MSG_DEBUG(" Trig_L2IOobjects.size(): " << Trig_L2IOobjects.size() );
50 
51  // check basic EDM variables using single muon chain
52  for(const auto& Trig_L2IOobject : Trig_L2IOobjects){
53  ATH_MSG_DEBUG(" Trig_L2IOobject->muSATrack()->roiWord()/Trig_L2IOobject->pt(): " << Trig_L2IOobject->muSATrack()->roiWord() << "/" << Trig_L2IOobject->pt() );
54  // basic EDM variables
55  bool mf_failure = false;
56  auto cbioPt = Monitored::Scalar<float>(chain+"_Pt",-999.);
57  auto cbioEta = Monitored::Scalar<float>(chain+"_Eta",-999.);
58  auto cbioPhi = Monitored::Scalar<float>(chain+"_Phi",-999.);
59  cbioPt = Trig_L2IOobject->pt()/1e3 * Trig_L2IOobject->charge(); // convert to GeV
60  cbioEta = Trig_L2IOobject->eta();
61  cbioPhi = Trig_L2IOobject->phi();
62  ATH_MSG_DEBUG("cbioPt = " << cbioPt << ", cbioEta =" << cbioEta << ", cbioPhi = " << cbioPhi);
63  if(std::abs(cbioPt) < ZERO_LIMIT || std::abs(Trig_L2IOobject->muSATrack()->pt()) < ZERO_LIMIT) mf_failure = true;
64 
65  if( mf_failure ) continue;
66 
67  // region variables
68  auto isBarrel = Monitored::Scalar<bool>(chain+"_isBarrel",false);
69  auto isEndcap = Monitored::Scalar<bool>(chain+"_isEndcap",false);
70 
71  // define regions
72  int saddr = Trig_L2IOobject->muSATrack()->sAddress();
73  if(saddr == -1) isEndcap = true;
74  else isBarrel = true;;
75 
76 
77  fill(m_group+"_"+chain, cbioPt, isBarrel, isEndcap);
78  fill(m_group+"_"+chain, cbioEta);
79  fill(m_group+"_"+chain, cbioPhi, isBarrel, isEndcap);
80 
81  }
82 
83  return StatusCode::SUCCESS;
84 }
85 
86 
87 StatusCode L2MuonSAIOMon :: fillVariablesPerOfflineMuonPerChain(const EventContext& ctx, const xAOD::Muon* mu, const std::string &chain) const {
88 
89  ATH_MSG_DEBUG ("Filling histograms for " << name() << "...");
90 
91  const float ZERO_LIMIT = 0.00001;
92 
93  // get the best L2Inside-Out object matched to offline muon(dR between L2Inside-Out object and offline muon is minimum)
94  const xAOD::L2CombinedMuon* Trig_L2IOobject = searchL2InsideOut(ctx, mu, chain);
95 
96  // offline muon variables
97  auto offPt = Monitored::Scalar<float>(chain+"_offPt",-999.);
98  auto offEta = Monitored::Scalar<float>(chain+"_offEta",-999.);
99  auto offPhi = Monitored::Scalar<float>(chain+"_offPhi",-999.);
100  offPt = mu->pt()/1e3 * mu->charge(); // convert to GeV
101  offEta = mu->eta();
102  offPhi = mu->phi();
103  float offCharge = mu->charge();
104 
105 
106  if( chain.find("probe") != std::string::npos ){ // L2Inside-Out efficiency using Tag&Probe chain
107  if(chain.find("L1MU14FCH") != std::string::npos){
108  if ( !getTrigDecisionTool()->isPassed("HLT_mu24_ivarmedium_L1MU14FCH") ) return StatusCode::SUCCESS; // impose trigger pass in order to eliminate bias
109  }
110  else if(chain.find("L1MU18VFCH") != std::string::npos){
111  if ( !getTrigDecisionTool()->isPassed("HLT_mu24_ivarmedium_L1MU18VFCH") ) return StatusCode::SUCCESS; // impose trigger pass in order to eliminate bias
112  }
113  else
114  {
115  return StatusCode::SUCCESS;
116  }
117 
118  // search tag offline muon
119  const xAOD::Muon* tag = searchTagOfflineMuon( ctx, mu );
120  if( tag == nullptr ) return StatusCode::SUCCESS; // mu doesn't have no tag muons
121 
122 
123  // efficiency variables
124  auto passL2InsideOut = Monitored::Scalar<bool>(chain+"_passL2InsideOut",false);
125  auto passL2SA = Monitored::Scalar<bool>(chain+"_passL2SA",false);
126  auto offdR = Monitored::Scalar<float>(chain+"_offdR",1000.);
127  const ElementLink<xAOD::TrackParticleContainer> &tag_ms_track = tag->muonSpectrometerTrackParticleLink();
128  if( !tag_ms_track.isValid() ) return StatusCode::SUCCESS; // tag muon dosen't have ms track
129  const ElementLink<xAOD::TrackParticleContainer> &probe_ms_track = mu->muonSpectrometerTrackParticleLink();
130  if( !probe_ms_track.isValid() ) return StatusCode::SUCCESS; // probe muon dosen't have ms track
131  float tpext_deta = (*tag_ms_track)->eta() - (*probe_ms_track)->eta();
132  float tpext_dphi = xAOD::P4Helpers::deltaPhi((*tag_ms_track)->phi(), (*probe_ms_track)->phi());
133  offdR = std::sqrt(tpext_deta*tpext_deta + tpext_dphi*tpext_dphi);
134 
135  passL2InsideOut = false;
136  passL2SA = false;
137 
138  // retrieve probe l2SA objects
139  int legIndex_probe = 1; // probe
140  std::vector< TrigCompositeUtils::LinkInfo<xAOD::L2StandAloneMuonContainer> > featureCont = getTrigDecisionTool()->features<xAOD::L2StandAloneMuonContainer>( chain,
141  TrigDefs::includeFailedDecisions,
142  "HLT_MuonL2SAInfo",
143  TrigDefs::lastFeatureOfType,
145  legIndex_probe );
146 
147  for(const TrigCompositeUtils::LinkInfo<xAOD::L2StandAloneMuonContainer>& probe_L2SALinkInfo : featureCont){
148  ATH_CHECK( probe_L2SALinkInfo.isValid() );
149  const ElementLink<xAOD::L2StandAloneMuonContainer> probe_L2SAobject = probe_L2SALinkInfo.link;
150  if( m_matchTool->isMatchedL2SA( (*probe_L2SAobject), mu ) ){
151  if( probe_L2SALinkInfo.state == TrigCompositeUtils::ActiveState::ACTIVE ) passL2SA = true;
152  }
153  }
154 
155  if(passL2SA == true){
156  if(m_matchTool->isMatchedL2InsideOut( Trig_L2IOobject, mu ))
157  {
158  bool isPass = false;
159  ATH_CHECK(isPassedmuCombHypo( chain, Trig_L2IOobject ,isPass));
160  passL2InsideOut = isPass;
161  }
162  }
163  else{
164  return StatusCode::SUCCESS;
165  }
166 
167 
168  fill(m_group+"_"+chain, passL2InsideOut, passL2SA, offPt);
169 
170  if( mu->pt()/1e3 > m_plateaus.at(chain) ){
171  fill(m_group+"_"+chain, passL2InsideOut, passL2SA, offEta, offPhi, offdR);
172  }
173  }
174  else{ // make detail histograms using normal L2Inside-Out chain
175  if( Trig_L2IOobject == nullptr ) return StatusCode::SUCCESS; // no L2Inside-Out objects
176  if( ! m_matchTool->isMatchedL2InsideOut(Trig_L2IOobject, mu) ) return StatusCode::SUCCESS; // offline muons is not matched to any L2Inside-Out objects
177 
178 
179  //L2Muon chamberID index
180  enum chamberID {
181  Inn_Barrel = 0,
182  Mid_Barrel,
183  Out_Barrel,
184  Inn_Endcap,
185  Mid_Endcap,
186  Out_Endcap
187  };
188  std::vector< int > L2Muon_chamberID_index;
189  auto mon_L2Muon_chamberID_index = Monitored::Collection(chain+"_L2Muon_chamberID_index",L2Muon_chamberID_index);
190  for( int i = 0; i < 6; i++){
191  L2Muon_chamberID_index.push_back(i);
192  }
193 
194  // dR wrt offline
195  auto dRmin = Monitored::Scalar<float>(chain+"_dRmin",1000.);
196  dRmin = xAOD::P4Helpers::deltaR(mu, Trig_L2IOobject, false);
197 
198  // region variables
199  const float ETA_OF_BARREL = 1.05;
200  auto regionBE = Monitored::Scalar<int>(chain+"_regionBE",-999);
201  auto isBarrel = Monitored::Scalar<bool>(chain+"_isBarrel",false);
202  auto isBarrelA = Monitored::Scalar<bool>(chain+"_isBarrelA",false);
203  auto isBarrelC = Monitored::Scalar<bool>(chain+"_isBarrelC",false);
204  auto isEndcap = Monitored::Scalar<bool>(chain+"_isEndcap",false);
205  auto isEndcapA = Monitored::Scalar<bool>(chain+"_isEndcapA",false);
206  auto isEndcapC = Monitored::Scalar<bool>(chain+"_isEndcapC",false);
207 
208  // offline pt variables
209  auto pt4to6 = Monitored::Scalar<bool>(chain+"_pt4to6",false);
210  auto pt6to8 = Monitored::Scalar<bool>(chain+"_pt6to8",false);
211  auto ptover8 = Monitored::Scalar<bool>(chain+"_ptover8",false);
212 
213  // define region
214  if( std::abs(offEta) < ETA_OF_BARREL ) {
215  regionBE = 0;
216  isBarrel = true;
217  if( offEta > 0. ) isBarrelA = true;
218  else isBarrelC = true;
219  }
220  else{
221  regionBE = 1;
222  isEndcap = true;
223  if( offEta > 0. ) isEndcapA = true;
224  else isEndcapC = true;
225  }
226 
227  if( std::abs(offPt) > 4 ){
228  if( std::abs(offPt) < 6 ) pt4to6 = true;
229  else if( std::abs(offPt) < 8 ) pt6to8 = true;
230  else ptover8 = true;
231  }
232 
233  // basic variables
234  auto cbioPt = Monitored::Scalar<float>(chain+"_Pt_wrt_offline",-999.);
235  auto cbioEta = Monitored::Scalar<float>(chain+"_Eta_wrt_offline",-999.);
236  auto cbioPhi = Monitored::Scalar<float>(chain+"_Phi_wrt_offline",-999.);
237  cbioPt = Trig_L2IOobject->pt()/1e3 * Trig_L2IOobject->charge(); // convert to GeV
238  cbioEta = Trig_L2IOobject->eta();
239  cbioPhi = Trig_L2IOobject->phi();
240 
241  // L2Inside-Out track multiplicity per L2SA track
242  auto L2InsideOut_multiplicity = Monitored::Scalar<float>(chain+"_L2InsideOut_track_multiplicity",-999.);
243  L2InsideOut_multiplicity = 0;
244  std::vector< const xAOD::L2CombinedMuon* > Trig_L2IOobjects_tmp;
245  ATH_CHECK( matchL2IO_wContainer(ctx, chain, Trig_L2IOobjects_tmp) );
246  for(const auto& Trig_L2IOobject_tmp : Trig_L2IOobjects_tmp){
247  if( Trig_L2IOobject_tmp->muSATrack()->roiWord() == Trig_L2IOobject->muSATrack()->roiWord() ) L2InsideOut_multiplicity++;
248  }
249 
250  // pt resolution
251  auto ptresol = Monitored::Scalar<float>(chain+"_ptresol",-999.);
252  if ( std::abs(offPt) > ZERO_LIMIT && std::abs(cbioPt) > ZERO_LIMIT ){
253  ptresol = std::abs(cbioPt)/std::abs(offPt) - 1.;
254  }
255 
256  std::vector< float > ptresol_pos, ptresol_neg;
257  auto mon_ptresol_pos = Monitored::Collection(chain+"_ptresol_pos",ptresol_pos);
258  auto mon_ptresol_neg = Monitored::Collection(chain+"_ptresol_neg",ptresol_neg);
259  if( offCharge > 0. ) ptresol_pos.push_back(ptresol);
260  else ptresol_neg.push_back(ptresol);
261 
262  // distance bw FTFroad and offlinesegment
263  std::vector< float > distance_bw_FTFroad_and_offlinesegment_Inn_Barrel;
264  std::vector< float > distance_bw_FTFroad_and_offlinesegment_Mid_Barrel;
265  std::vector< float > distance_bw_FTFroad_and_offlinesegment_Out_Barrel;
266  std::vector< float > distance_bw_FTFroad_and_offlinesegment_Inn_Endcap;
267  std::vector< float > distance_bw_FTFroad_and_offlinesegment_Mid_Endcap;
268  std::vector< float > distance_bw_FTFroad_and_offlinesegment_Out_Endcap;
269  auto mon_distance_bw_FTFroad_and_offlinesegment_Inn_Barrel = Monitored::Collection(chain+"_distance_bw_FTFroad_and_offlinesegment_Inn_Barrel",distance_bw_FTFroad_and_offlinesegment_Inn_Barrel);
270  auto mon_distance_bw_FTFroad_and_offlinesegment_Mid_Barrel = Monitored::Collection(chain+"_distance_bw_FTFroad_and_offlinesegment_Mid_Barrel",distance_bw_FTFroad_and_offlinesegment_Mid_Barrel);
271  auto mon_distance_bw_FTFroad_and_offlinesegment_Out_Barrel = Monitored::Collection(chain+"_distance_bw_FTFroad_and_offlinesegment_Out_Barrel",distance_bw_FTFroad_and_offlinesegment_Out_Barrel);
272  auto mon_distance_bw_FTFroad_and_offlinesegment_Inn_Endcap = Monitored::Collection(chain+"_distance_bw_FTFroad_and_offlinesegment_Inn_Endcap",distance_bw_FTFroad_and_offlinesegment_Inn_Endcap);
273  auto mon_distance_bw_FTFroad_and_offlinesegment_Mid_Endcap = Monitored::Collection(chain+"_distance_bw_FTFroad_and_offlinesegment_Mid_Endcap",distance_bw_FTFroad_and_offlinesegment_Mid_Endcap);
274  auto mon_distance_bw_FTFroad_and_offlinesegment_Out_Endcap = Monitored::Collection(chain+"_distance_bw_FTFroad_and_offlinesegment_Out_Endcap",distance_bw_FTFroad_and_offlinesegment_Out_Endcap);
275 
276  std::vector< float > distance_bw_FTFroad_and_offlinesegment_vec;
277  std::vector< float > FTFroad_Aw;
278  std::vector< float > FTFroad_Bw;
279  std::vector< bool > FTFroad_fill;
280  for(int i=0; i<6; i++){
281  distance_bw_FTFroad_and_offlinesegment_vec.push_back(10000.);
282  FTFroad_Aw.push_back(Trig_L2IOobject->muSATrack()->roadAw(i, 0));
283  FTFroad_Bw.push_back(Trig_L2IOobject->muSATrack()->roadBw(i, 0));
284  FTFroad_fill.push_back(false);
285  }
286 
287  // MDT hits residual
288  std::vector<float> res_Inn_Barrel, res_Mid_Barrel, res_Out_Barrel, res_Inn_Endcap, res_Mid_Endcap, res_Out_Endcap;
289  auto mon_res_Inn_Barrel = Monitored::Collection(chain+"_MDT_residual_Inn_Barrel",res_Inn_Barrel);
290  auto mon_res_Mid_Barrel = Monitored::Collection(chain+"_MDT_residual_Mid_Barrel",res_Mid_Barrel);
291  auto mon_res_Out_Barrel = Monitored::Collection(chain+"_MDT_residual_Out_Barrel",res_Out_Barrel);
292  auto mon_res_Inn_Endcap = Monitored::Collection(chain+"_MDT_residual_Inn_Endcap",res_Inn_Endcap);
293  auto mon_res_Mid_Endcap = Monitored::Collection(chain+"_MDT_residual_Mid_Endcap",res_Mid_Endcap);
294  auto mon_res_Out_Endcap = Monitored::Collection(chain+"_MDT_residual_Out_Endcap",res_Out_Endcap);
295 
296  // distance bw MDT hits and offlinesegment
297  std::vector< float > distance_bw_MDT_and_offlinesegment_Inn_Barrel;
298  std::vector< float > distance_bw_MDT_and_offlinesegment_Mid_Barrel;
299  std::vector< float > distance_bw_MDT_and_offlinesegment_Out_Barrel;
300  std::vector< float > distance_bw_MDT_and_offlinesegment_Inn_Endcap;
301  std::vector< float > distance_bw_MDT_and_offlinesegment_Mid_Endcap;
302  std::vector< float > distance_bw_MDT_and_offlinesegment_Out_Endcap;
303  auto mon_distance_bw_MDT_and_offlinesegment_Inn_Barrel = Monitored::Collection(chain+"_distance_bw_MDT_and_offlinesegment_Inn_Barrel",distance_bw_MDT_and_offlinesegment_Inn_Barrel);
304  auto mon_distance_bw_MDT_and_offlinesegment_Mid_Barrel = Monitored::Collection(chain+"_distance_bw_MDT_and_offlinesegment_Mid_Barrel",distance_bw_MDT_and_offlinesegment_Mid_Barrel);
305  auto mon_distance_bw_MDT_and_offlinesegment_Out_Barrel = Monitored::Collection(chain+"_distance_bw_MDT_and_offlinesegment_Out_Barrel",distance_bw_MDT_and_offlinesegment_Out_Barrel);
306  auto mon_distance_bw_MDT_and_offlinesegment_Inn_Endcap = Monitored::Collection(chain+"_distance_bw_MDT_and_offlinesegment_Inn_Endcap",distance_bw_MDT_and_offlinesegment_Inn_Endcap);
307  auto mon_distance_bw_MDT_and_offlinesegment_Mid_Endcap = Monitored::Collection(chain+"_distance_bw_MDT_and_offlinesegment_Mid_Endcap",distance_bw_MDT_and_offlinesegment_Mid_Endcap);
308  auto mon_distance_bw_MDT_and_offlinesegment_Out_Endcap = Monitored::Collection(chain+"_distance_bw_MDT_and_offlinesegment_Out_Endcap",distance_bw_MDT_and_offlinesegment_Out_Endcap);
309  std::vector< float > distance_bw_MDT_and_offlinesegment_vec;
310  std::vector< int > MDTHitChamber_fill;
311  std::vector< int > MDTHitChamber;
312  std::vector< float > MDTHitR;
313  std::vector< float > MDTHitZ;
314 
315  // # of MDT hits
316  std::vector<int> MDT_N_Inn_Barrel, MDT_N_Mid_Barrel, MDT_N_Out_Barrel, MDT_N_Inn_Endcap, MDT_N_Mid_Endcap, MDT_N_Out_Endcap;
317  auto mon_MDT_N_Inn_Barrel = Monitored::Collection(chain+"_MDT_N_Inn_Barrel",MDT_N_Inn_Barrel);
318  auto mon_MDT_N_Mid_Barrel = Monitored::Collection(chain+"_MDT_N_Mid_Barrel",MDT_N_Mid_Barrel);
319  auto mon_MDT_N_Out_Barrel = Monitored::Collection(chain+"_MDT_N_Out_Barrel",MDT_N_Out_Barrel);
320  auto mon_MDT_N_Inn_Endcap = Monitored::Collection(chain+"_MDT_N_Inn_Endcap",MDT_N_Inn_Endcap);
321  auto mon_MDT_N_Mid_Endcap = Monitored::Collection(chain+"_MDT_N_Mid_Endcap",MDT_N_Mid_Endcap);
322  auto mon_MDT_N_Out_Endcap = Monitored::Collection(chain+"_MDT_N_Out_Endcap",MDT_N_Out_Endcap);
323  int n_mdthits_BI = 0;
324  int n_mdthits_BM = 0;
325  int n_mdthits_BO = 0;
326  int n_mdthits_EI = 0;
327  int n_mdthits_EM = 0;
328  int n_mdthits_EO = 0;
329 
330  int n_mdt_hits = Trig_L2IOobject->muSATrack()->nMdtHits();
331  for(int i_tube=0; i_tube<n_mdt_hits; i_tube++){
332  if( Trig_L2IOobject->muSATrack()->mdtHitIsOutlier(i_tube) != 0 ) continue;
333  float res = Trig_L2IOobject->muSATrack()->mdtHitResidual(i_tube);
334  int imr = Trig_L2IOobject->muSATrack()->mdtHitChamber(i_tube);
335  MDTHitChamber.push_back(imr);
336  MDTHitR.push_back(Trig_L2IOobject->muSATrack()->mdtHitR(i_tube));
337  MDTHitZ.push_back(Trig_L2IOobject->muSATrack()->mdtHitZ(i_tube));
338 
339  if( imr == Inn_Barrel ){
340  n_mdthits_BI++;
341  res_Inn_Barrel.push_back(res);
342  }
343  else if( imr == Mid_Barrel ){
344  n_mdthits_BM++;
345  res_Mid_Barrel.push_back(res);
346  }
347  else if( imr == Out_Barrel ){
348  n_mdthits_BO++;
349  res_Out_Barrel.push_back(res);
350  }
351  else if( imr == Inn_Endcap ){
352  n_mdthits_EI++;
353  res_Inn_Endcap.push_back(res);
354  }
355  else if( imr == Mid_Endcap ){
356  n_mdthits_EM++;
357  res_Mid_Endcap.push_back(res);
358  }
359  else if( imr == Out_Endcap ){
360  n_mdthits_EO++;
361  res_Out_Endcap.push_back(res);
362  }
363  }
364 
365  // reconstruction efficiency of superpoint
366  std::vector<bool> superpoint_exist_pt4to6, superpoint_exist_pt6to8, superpoint_exist_ptover8;
367  auto mon_superpoint_exist_pt4to6 = Monitored::Collection(chain+"_superpoint_pt4to6",superpoint_exist_pt4to6);
368  auto mon_superpoint_exist_pt6to8 = Monitored::Collection(chain+"_superpoint_pt6to8",superpoint_exist_pt6to8);
369  auto mon_superpoint_exist_ptover8 = Monitored::Collection(chain+"_superpoint_ptover8",superpoint_exist_ptover8);
370  std::vector<bool> segment_superpoint_exist(6, false);
371  std::vector<bool> offlinesegment_exist_pt4to6, offlinesegment_exist_pt6to8, offlinesegment_exist_ptover8;
372  auto mon_offlinesegment_exist_pt4to6 = Monitored::Collection(chain+"_offlinesegment_pt4to6",offlinesegment_exist_pt4to6);
373  auto mon_offlinesegment_exist_pt6to8 = Monitored::Collection(chain+"_offlinesegment_pt6to8",offlinesegment_exist_pt6to8);
374  auto mon_offlinesegment_exist_ptover8 = Monitored::Collection(chain+"_offlinesegment_ptover8",offlinesegment_exist_ptover8);
375 
376  // # of superpoint
377  auto superpoint_multiplicity = Monitored::Scalar<int>(chain+"_superpoint_multiplicity",0);
378  std::vector< bool > superpoint_exist;
379  std::vector< float > superpointR;
380  int Num_L2Muon_chamberID = 12;
381  for( int i_chamber = 0; i_chamber < Num_L2Muon_chamberID; i_chamber++){
382  if( Trig_L2IOobject->muSATrack()->superPointR(i_chamber) < ZERO_LIMIT ){
383  superpoint_exist.push_back(false);
384  }
385  else{
386  superpoint_exist.push_back(true);
387  superpoint_multiplicity++;
388  }
389  superpointR.push_back(Trig_L2IOobject->muSATrack()->superPointR(i_chamber));
390  }
391 
392 
393  std::vector< bool > segment_exist(6, false);
394  for(unsigned int i_seg = 0; i_seg < mu->nMuonSegments(); i_seg++){
395  const xAOD::MuonSegment* segment = mu->muonSegment(i_seg);
396  if(!segment) continue;
397  float segmentX = segment->x();
398  float segmentY = segment->y();
399  float segmentZ = segment->z();
400  float segmentR = std::sqrt( std::pow(segmentX, 2.0) + std::pow(segmentY, 2.0) );
401  float segmentPx = segment->px();
402  float segmentPy = segment->py();
403  float segmentPz = segment->pz();
404  float segmentSector = segment->sector();
405  int segmentChamberIndex = segment->chamberIndex();
406  float distance_bw_FTFroad_and_offlinesegment = 99999.;
407  float distance_bw_MDT_and_offlinesegment = 99999.;
408  int roadChamberIndex = -1;
409  int MDTChamberIndex = -1;
410  if( segmentChamberIndex == 0 || segmentChamberIndex == 1 ){ // Inner Barrel
411  segment_exist.at(Inn_Barrel) = true;
412  roadChamberIndex = Inn_Barrel;
413  MDTChamberIndex = Inn_Barrel;
414  }
415  else if( segmentChamberIndex == 2 || segmentChamberIndex == 3 ){ // Middle Barrel
416  segment_exist.at(Mid_Barrel) = true;
417  roadChamberIndex = Mid_Barrel;
418  MDTChamberIndex = Mid_Barrel;
419  }
420  else if( segmentChamberIndex == 4 || segmentChamberIndex == 5 ){ // Outer Barrel
421  segment_exist.at(Out_Barrel) = true;
422  roadChamberIndex = Out_Barrel;
423  MDTChamberIndex = Out_Barrel;
424  }
425  else if( segmentChamberIndex == 7 || segmentChamberIndex == 8 ){ // Inner Endcap
426  segment_exist.at(Inn_Endcap) = true;
427  roadChamberIndex = Inn_Endcap;
428  MDTChamberIndex = Inn_Endcap;
429  }
430  else if( segmentChamberIndex == 9 || segmentChamberIndex == 10 ){ // Middle Endcap
431  segment_exist.at(Mid_Endcap) = true;
432  roadChamberIndex = Mid_Endcap;
433  MDTChamberIndex = Mid_Endcap;
434  }
435  else if( segmentChamberIndex == 11 || segmentChamberIndex == 12 ){ // Outer Endcap
436  segment_exist.at(Out_Endcap) = true;
437  roadChamberIndex = Out_Endcap;
438  MDTChamberIndex = Out_Endcap;
439  }
440 
441  // Calc distance bw FTFroad and offlinesegment
442  if( roadChamberIndex != -1 ){
443  if( FTFroad_Aw.at(roadChamberIndex) > ZERO_LIMIT || FTFroad_Bw.at(roadChamberIndex) > ZERO_LIMIT ){
444  FTFroad_fill.at(roadChamberIndex) = true;
445  if( FTFroad_Aw.at(roadChamberIndex) < ZERO_LIMIT) distance_bw_FTFroad_and_offlinesegment = segmentR - FTFroad_Bw.at(roadChamberIndex);
446  else{
447  float ia = 1.0/FTFroad_Aw.at(roadChamberIndex);
448  float iaq = ia * ia;
449  distance_bw_FTFroad_and_offlinesegment = (segmentZ - ia * (segmentR - FTFroad_Bw.at(roadChamberIndex)))/std::sqrt(1.0 + iaq);
450  }
451  if( std::abs(distance_bw_FTFroad_and_offlinesegment) < std::abs(distance_bw_FTFroad_and_offlinesegment_vec.at(roadChamberIndex)) )
452  distance_bw_FTFroad_and_offlinesegment_vec.at(roadChamberIndex) = distance_bw_FTFroad_and_offlinesegment;
453  }
454  }
455 
456  // Calc distance bw MDT hits and offlinesegment
457  if( MDTChamberIndex != -1 ){
458  float sector_phi = M_PI*(segmentSector - 1.0)/8.0;
459  float segmentR_projection = segmentX * std::cos(sector_phi) + segmentY * std::sin(sector_phi);
460  float segmentPr_projection = segmentPx * std::cos(sector_phi) + segmentPy * std::sin(sector_phi);
461 
462  for(unsigned int i_tube=0; i_tube<MDTHitChamber.size(); i_tube++){
463  if( MDTHitChamber.at(i_tube) != MDTChamberIndex ) continue;
464  if( MDTChamberIndex < 3 ){ //Barrel
465  if( std::abs(segmentPz) < ZERO_LIMIT ) distance_bw_MDT_and_offlinesegment = MDTHitZ.at(i_tube) - segmentZ;
466  else{
467  float denominator = segmentPr_projection/segmentPz;
468  if( std::abs(denominator) < ZERO_LIMIT ) continue;
469  distance_bw_MDT_and_offlinesegment = MDTHitZ.at(i_tube) - ((MDTHitR.at(i_tube) - segmentR_projection)/denominator + segmentZ);
470  }
471  }
472  else{ //Endcap
473  if( std::abs(segmentPz) < ZERO_LIMIT ){
474  distance_bw_MDT_and_offlinesegment = MDTHitR.at(i_tube) - segmentR;
475  }
476  else{
477  float coeffi = (MDTHitZ.at(i_tube) - segmentZ)/segmentPz;
478  float segmentR_extrapolated = std::sqrt(std::pow(segmentX + coeffi * segmentPx, 2.0) + std::pow(segmentY + coeffi * segmentPy, 2.0));
479  distance_bw_MDT_and_offlinesegment = MDTHitR.at(i_tube) - segmentR_extrapolated;
480  }
481  }
482  distance_bw_MDT_and_offlinesegment_vec.push_back(distance_bw_MDT_and_offlinesegment);
483  MDTHitChamber_fill.push_back(MDTHitChamber.at(i_tube));
484  }
485  }
486  }
487 
488  if( FTFroad_fill.at(Inn_Barrel) ){
489  distance_bw_FTFroad_and_offlinesegment_Inn_Barrel.push_back(distance_bw_FTFroad_and_offlinesegment_vec.at(Inn_Barrel));
490  }
491  if( FTFroad_fill.at(Mid_Barrel) ){
492  distance_bw_FTFroad_and_offlinesegment_Mid_Barrel.push_back(distance_bw_FTFroad_and_offlinesegment_vec.at(Mid_Barrel));
493  }
494  if( FTFroad_fill.at(Out_Barrel) ){
495  distance_bw_FTFroad_and_offlinesegment_Out_Barrel.push_back(distance_bw_FTFroad_and_offlinesegment_vec.at(Out_Barrel));
496  }
497  if( FTFroad_fill.at(Inn_Endcap) ){
498  distance_bw_FTFroad_and_offlinesegment_Inn_Endcap.push_back(distance_bw_FTFroad_and_offlinesegment_vec.at(Inn_Endcap));
499  }
500  if( FTFroad_fill.at(Mid_Endcap) ){
501  distance_bw_FTFroad_and_offlinesegment_Mid_Endcap.push_back(distance_bw_FTFroad_and_offlinesegment_vec.at(Mid_Endcap));
502  }
503  if( FTFroad_fill.at(Out_Endcap) ){
504  distance_bw_FTFroad_and_offlinesegment_Out_Endcap.push_back(distance_bw_FTFroad_and_offlinesegment_vec.at(Out_Endcap));
505  }
506 
507  for( unsigned int i = 0; i < distance_bw_MDT_and_offlinesegment_vec.size(); i++ ){
508  if( MDTHitChamber_fill.at(i) == Inn_Barrel ){
509  distance_bw_MDT_and_offlinesegment_Inn_Barrel.push_back(distance_bw_MDT_and_offlinesegment_vec.at(i));
510  }
511  else if( MDTHitChamber_fill.at(i) == Mid_Barrel ){
512  distance_bw_MDT_and_offlinesegment_Mid_Barrel.push_back(distance_bw_MDT_and_offlinesegment_vec.at(i));
513  }
514  else if( MDTHitChamber_fill.at(i) == Out_Barrel ){
515  distance_bw_MDT_and_offlinesegment_Out_Barrel.push_back(distance_bw_MDT_and_offlinesegment_vec.at(i));
516  }
517  else if( MDTHitChamber_fill.at(i) == Inn_Endcap ){
518  distance_bw_MDT_and_offlinesegment_Inn_Endcap.push_back(distance_bw_MDT_and_offlinesegment_vec.at(i));
519  }
520  else if( MDTHitChamber_fill.at(i) == Mid_Endcap ){
521  distance_bw_MDT_and_offlinesegment_Mid_Endcap.push_back(distance_bw_MDT_and_offlinesegment_vec.at(i));
522  }
523  else if( MDTHitChamber_fill.at(i) == Out_Endcap ){
524  distance_bw_MDT_and_offlinesegment_Out_Endcap.push_back(distance_bw_MDT_and_offlinesegment_vec.at(i));
525  }
526  else{
527  ATH_MSG_WARNING( "undefined chamberID is pushed back into MDTHitChamber_fill" );
528  }
529  }
530 
531  if( segment_exist.at(Inn_Barrel) ){
532  MDT_N_Inn_Barrel.push_back(n_mdthits_BI);
533  segment_superpoint_exist.at(Inn_Barrel) = superpoint_exist.at(Inn_Barrel);
534  }
535  if( segment_exist.at(Mid_Barrel) ){
536  MDT_N_Mid_Barrel.push_back(n_mdthits_BM);
537  segment_superpoint_exist.at(Mid_Barrel) = superpoint_exist.at(Mid_Barrel);
538  }
539  if( segment_exist.at(Out_Barrel) ){
540  MDT_N_Out_Barrel.push_back(n_mdthits_BO);
541  segment_superpoint_exist.at(Out_Barrel) = superpoint_exist.at(Out_Barrel);
542  }
543  if( segment_exist.at(Inn_Endcap) ){
544  MDT_N_Inn_Endcap.push_back(n_mdthits_EI);
545  segment_superpoint_exist.at(Inn_Endcap) = superpoint_exist.at(Inn_Endcap);
546  }
547  if( segment_exist.at(Mid_Endcap) ){
548  MDT_N_Mid_Endcap.push_back(n_mdthits_EM);
549  segment_superpoint_exist.at(Mid_Endcap) = superpoint_exist.at(Mid_Endcap);
550  }
551  if( segment_exist.at(Out_Endcap) ){
552  MDT_N_Out_Endcap.push_back(n_mdthits_EO);
553  segment_superpoint_exist.at(Out_Endcap) = superpoint_exist.at(Out_Endcap);
554  }
555 
556  if( pt4to6 ){
557  offlinesegment_exist_pt4to6 = segment_exist;
558  superpoint_exist_pt4to6 = segment_superpoint_exist;
559  }
560  else if( pt6to8 ){
561  offlinesegment_exist_pt6to8 = segment_exist;
562  superpoint_exist_pt6to8 = segment_superpoint_exist;
563  }
564  else if( ptover8 ){
565  offlinesegment_exist_ptover8 = segment_exist;
566  superpoint_exist_ptover8 = segment_superpoint_exist;
567  }
568 
569  fill(m_group+"_"+chain, dRmin, isBarrel, isEndcap);
570  fill(m_group+"_"+chain, cbioPt, isBarrel, isEndcap);
571  fill(m_group+"_"+chain, cbioEta);
572  fill(m_group+"_"+chain, cbioPhi, isBarrel, isEndcap);
573  fill(m_group+"_"+chain, L2InsideOut_multiplicity, offPt, isBarrel, isEndcap);
574  fill(m_group+"_"+chain, ptresol, offEta, pt4to6, pt6to8, ptover8);
575  fill(m_group+"_"+chain, ptresol, offPt, isBarrelA, isBarrelC, isEndcapA, isEndcapC);
576  fill(m_group+"_"+chain, mon_ptresol_pos, mon_ptresol_neg, isBarrelA, isBarrelC, isEndcapA, isEndcapC);
577  fill(m_group+"_"+chain, mon_distance_bw_FTFroad_and_offlinesegment_Inn_Barrel, pt4to6, pt6to8, ptover8);
578  fill(m_group+"_"+chain, mon_distance_bw_FTFroad_and_offlinesegment_Mid_Barrel, pt4to6, pt6to8, ptover8);
579  fill(m_group+"_"+chain, mon_distance_bw_FTFroad_and_offlinesegment_Out_Barrel, pt4to6, pt6to8, ptover8);
580  fill(m_group+"_"+chain, mon_distance_bw_FTFroad_and_offlinesegment_Inn_Endcap, pt4to6, pt6to8, ptover8);
581  fill(m_group+"_"+chain, mon_distance_bw_FTFroad_and_offlinesegment_Mid_Endcap, pt4to6, pt6to8, ptover8);
582  fill(m_group+"_"+chain, mon_distance_bw_FTFroad_and_offlinesegment_Out_Endcap, pt4to6, pt6to8, ptover8);
583  fill(m_group+"_"+chain, mon_res_Inn_Barrel);
584  fill(m_group+"_"+chain, mon_res_Mid_Barrel);
585  fill(m_group+"_"+chain, mon_res_Out_Barrel);
586  fill(m_group+"_"+chain, mon_res_Inn_Endcap);
587  fill(m_group+"_"+chain, mon_res_Mid_Endcap);
588  fill(m_group+"_"+chain, mon_res_Out_Endcap);
589  fill(m_group+"_"+chain, mon_distance_bw_MDT_and_offlinesegment_Inn_Barrel);
590  fill(m_group+"_"+chain, mon_distance_bw_MDT_and_offlinesegment_Mid_Barrel);
591  fill(m_group+"_"+chain, mon_distance_bw_MDT_and_offlinesegment_Out_Barrel);
592  fill(m_group+"_"+chain, mon_distance_bw_MDT_and_offlinesegment_Inn_Endcap);
593  fill(m_group+"_"+chain, mon_distance_bw_MDT_and_offlinesegment_Mid_Endcap);
594  fill(m_group+"_"+chain, mon_distance_bw_MDT_and_offlinesegment_Out_Endcap);
595  fill(m_group+"_"+chain, mon_MDT_N_Inn_Barrel);
596  fill(m_group+"_"+chain, mon_MDT_N_Mid_Barrel);
597  fill(m_group+"_"+chain, mon_MDT_N_Out_Barrel);
598  fill(m_group+"_"+chain, mon_MDT_N_Inn_Endcap);
599  fill(m_group+"_"+chain, mon_MDT_N_Mid_Endcap);
600  fill(m_group+"_"+chain, mon_MDT_N_Out_Endcap);
601  fill(m_group+"_"+chain, superpoint_multiplicity, regionBE, pt4to6, pt6to8, ptover8);
602  fill(m_group+"_"+chain, mon_L2Muon_chamberID_index, mon_superpoint_exist_pt4to6, mon_offlinesegment_exist_pt4to6);
603  fill(m_group+"_"+chain, mon_L2Muon_chamberID_index, mon_superpoint_exist_pt6to8, mon_offlinesegment_exist_pt6to8);
604  fill(m_group+"_"+chain, mon_L2Muon_chamberID_index, mon_superpoint_exist_ptover8, mon_offlinesegment_exist_ptover8);
605  }
606 
607  return StatusCode::SUCCESS;
608 }
609 
610 
611 StatusCode L2MuonSAIOMon :: matchL2IO_wContainer(const EventContext &ctx, const std::string &chain, std::vector< const xAOD::L2CombinedMuon* > &Trig_L2IOobjects) const {
612 
613  ATH_MSG_DEBUG ("matchL2IO_wContainer ..." );
614 
615  // retrieve l2io objects
617 
618  // retrieve l2SA objects
619  std::vector< TrigCompositeUtils::LinkInfo<xAOD::L2StandAloneMuonContainer> > featureCont;
620  if( chain.find("probe") != std::string::npos ){ // if tag & probe chain, retrieve probe L2SA objects
621  int legIndex_probe = 1; // probe
622  featureCont = getTrigDecisionTool()->features<xAOD::L2StandAloneMuonContainer>( chain,
623  TrigDefs::includeFailedDecisions,
624  "HLT_MuonL2SAInfo",
625  TrigDefs::lastFeatureOfType,
627  legIndex_probe );
628  }
629  else{
630  featureCont = getTrigDecisionTool()->features<xAOD::L2StandAloneMuonContainer>( chain,
631  TrigDefs::includeFailedDecisions,
632  "HLT_MuonL2SAInfo" );
633  }
634 
635  // match l2io objects to l2sa objects using roiWord
636  std::vector< const xAOD::L2CombinedMuon* > matchSA_L2IOobjects;
637  for(const auto L2IOobject : *L2IOobjects){
638  ATH_MSG_DEBUG(" L2IOobject->muSATrack()->roiWord()/L2IOobject->pt(): " << L2IOobject->muSATrack()->roiWord() << "/" << L2IOobject->pt() );
639  for(const TrigCompositeUtils::LinkInfo<xAOD::L2StandAloneMuonContainer>& L2SALinkInfo : featureCont){
640  ATH_CHECK( L2SALinkInfo.isValid() );
641  const ElementLink<xAOD::L2StandAloneMuonContainer> L2SAobject = L2SALinkInfo.link;
642  if( !L2SAobject.isValid() ) continue;
643  ATH_MSG_DEBUG(" L2SAobject->roiWord()/L2SALinkInfo.state: " << (*L2SAobject)->roiWord() << "/" << L2SALinkInfo.state );
644 
645  if( L2IOobject->muSATrack()->roiWord() != (*L2SAobject)->roiWord() ) continue;
646  if( L2SALinkInfo.state != TrigCompositeUtils::ActiveState::ACTIVE ){
647  break;
648  }else{
649  matchSA_L2IOobjects.push_back(L2IOobject);
650  ATH_MSG_DEBUG(" matchSA_L2IOobject->muSATrack()->roiWord()/matchSA_L2IOobject->pt(): " << L2IOobject->muSATrack()->roiWord() << "/" << L2IOobject->pt() );
651  break;
652  }
653  }
654  }
655  ATH_MSG_DEBUG(" matchSA_L2IOobjects.size(): " << matchSA_L2IOobjects.size() );
656 
657  const size_t num_matchSAMuon = matchSA_L2IOobjects.size();
658  if( num_matchSAMuon == 0 ){
659  ATH_MSG_DEBUG(" NO matchSA_L2IOobjects ");
660  return StatusCode::SUCCESS;
661  }
662 
663  std::vector< bool > isoverlap( num_matchSAMuon, false );
664  std::vector< bool > passOR( num_matchSAMuon, true );
665 
666  // L2CBOverlapRemover
667  ATH_CHECK( L2OverlapRemover( matchSA_L2IOobjects, isoverlap, passOR ) );
668  for(unsigned int i=0; i<num_matchSAMuon; i++) { // push back trig Inside-Out objects passing L2CBOverlapRemover
669  if( isoverlap[i] && !passOR[i] ) continue;
670  Trig_L2IOobjects.push_back(matchSA_L2IOobjects.at(i));
671  }
672 
673  return StatusCode::SUCCESS;
674 }
675 
676 
677 StatusCode L2MuonSAIOMon :: L2OverlapRemover( const std::vector< const xAOD::L2CombinedMuon* >& matchSA_L2IOobjects, std::vector< bool > &isoverlap, std::vector< bool > &passOR ) const {
678 
679  ATH_MSG_DEBUG ("L2OverlapRemover ..." );
680 
681  const size_t numMuon = matchSA_L2IOobjects.size();
682  bool errorWhenIdentifyingOverlap = false;
683 
684  if(numMuon > 1){
685  std::vector<unsigned int> mucombResult;
686  //unsigned int i,j;
687  for(unsigned int i=0; i<numMuon; i++) {mucombResult.emplace_back(i); }
688  for(unsigned int i=0; i<numMuon-1; i++){
689  for(unsigned int j=i+1; j<numMuon; j++){
690  ATH_MSG_DEBUG("++ i=" << i << " vs j=" << j);
691  bool overlapped = isOverlap(matchSA_L2IOobjects.at(i), matchSA_L2IOobjects.at(j));
692  ATH_MSG_DEBUG("matchSA_L2IOobjects: i/j/Overlap = " << i << "/" << j << "/" << overlapped );
693  if( ! overlapped ){ // judged as different
694  ATH_MSG_DEBUG(" judged as: differenr objects");
695  if( mucombResult[i] == mucombResult[j] ) { // but marked as same by someone
696  ATH_MSG_DEBUG( "inconsistentency in muComb overlap removal for more than two objects" );
697  ATH_MSG_DEBUG( "two objects are judged as different but both were already marked as identical by someone else as: " );
698  ATH_MSG_DEBUG( "i/j/result[i]/result[j]=" << i << " / " << j << " / " << mucombResult[i] << " / " << mucombResult[j] );
699  errorWhenIdentifyingOverlap = true;
700  }
701  }
702  else{ // judged as overlap
703  if( (mucombResult[j] != j && mucombResult[i] != mucombResult[j]) || (mucombResult[j] == j && mucombResult[i] != i) ){
704  ATH_MSG_DEBUG( "inconsistentency in muComb based overlap removal for more than two objects" );
705  ATH_MSG_DEBUG( "two objects are judged as overlap but only either was already marked as overlap to someone else: " );
706  ATH_MSG_DEBUG( "i/j/result[i]/result[j]=" << i << " / " << j << " / " << mucombResult[i] << " / " << mucombResult[j] );
707  errorWhenIdentifyingOverlap = true;
708  }
709  ATH_MSG_DEBUG(" judged as: overlapped objects");
710  if( mucombResult[i] == i ) {
711  ATH_MSG_DEBUG( " i is not yet marked as overlap. so, it is a newly found overlap" );
712  ATH_MSG_DEBUG( " -> marking mucombResult[j] as i..." );
713  mucombResult[j] = i;
714  isoverlap[i] = true;
715  isoverlap[j] = true;
716  } else {
717  ATH_MSG_DEBUG( " both i/j already marked as overlap by: mucombResult[i]=" << mucombResult[i] );
718  ATH_MSG_DEBUG( " -> do nothing..." );
719  }
720  }
721  }
722  }
723 
724 
725  if( errorWhenIdentifyingOverlap ) {
726  ATH_MSG_WARNING( "error when resolving overlap. exitting with all EVs active..." );
727  } else {
728 
729  unsigned int n_uniqueMuon = 0;
730  for(unsigned int i=0; i<numMuon; i++) {
731  ATH_MSG_DEBUG( "muComb based results: i=" << i << ": ");
732  if( mucombResult[i] != i ) {
733  ATH_MSG_DEBUG( " overlap to j=" << mucombResult[i] );
734  } else {
735  n_uniqueMuon++;
736  ATH_MSG_DEBUG( " unique" );
737  }
738  }
739 
740  ATH_MSG_DEBUG( "nr of unique Muons after muComb-based removal=" << n_uniqueMuon );
741 
742  if( numMuon != n_uniqueMuon ){
743  ATH_CHECK( chooseBestMuon(matchSA_L2IOobjects, passOR, mucombResult) );
744  } else {
745  ATH_MSG_DEBUG( "no overlap identified. exitting with all EventViews active" );
746  }
747  }
748  }
749 
750  return StatusCode::SUCCESS;
751 }
752 
753 
754 bool L2MuonSAIOMon :: isOverlap( const xAOD::L2CombinedMuon* matchSA_L2IOobject1, const xAOD::L2CombinedMuon* matchSA_L2IOobject2 ) const {
755 
756  ATH_MSG_DEBUG( " ...matchSA_L2IOobject1: pt/eta/phi=" << matchSA_L2IOobject1->pt()/Gaudi::Units::GeV << " / " << matchSA_L2IOobject1->eta() << " / " << matchSA_L2IOobject1->phi() );
757  ATH_MSG_DEBUG( " ...matchSA_L2IOobject2: pt/eta/phi=" << matchSA_L2IOobject2->pt()/Gaudi::Units::GeV << " / " << matchSA_L2IOobject2->eta() << " / " << matchSA_L2IOobject2->phi() );
758 
759  const auto [mu1Pt, mu1Eta, mu1Phi] = L2ORPosForMatchFunc(matchSA_L2IOobject1);
760  const auto [mu2Pt, mu2Eta, mu2Phi] = L2ORPosForMatchFunc(matchSA_L2IOobject2);
761 
762  // if dR or invMass is necessary but (eta,phi) info is not avaiable
763  // (i.e. eta,phi=0,0; rec failed)
764  const double ZERO_LIMIT_FOR_ETAPHI = 1e-4;
765  if( (std::abs(matchSA_L2IOobject1->eta()) <ZERO_LIMIT_FOR_ETAPHI && std::abs(matchSA_L2IOobject1->phi()) < ZERO_LIMIT_FOR_ETAPHI) ||
766  (std::abs(matchSA_L2IOobject2->eta()) <ZERO_LIMIT_FOR_ETAPHI && std::abs(matchSA_L2IOobject2->phi()) < ZERO_LIMIT_FOR_ETAPHI) ) {
767  ATH_MSG_DEBUG( " ...-> (eta,phi) info not available (rec at (eta,phi)=(0,0))" );
768  if( m_RequireDR || m_RequireMass ) {
769  ATH_MSG_DEBUG( " ...-> but dR of invMass check is required. cannot judge overlap -> return with false" );
770  return false;
771  }
772  }
773 
774  // if charge or invMass is necessary but charge(=pT) info is not avaiable
775  const double ZERO_LIMIT_FOR_PT = 1e-4;
776  if( (std::abs(matchSA_L2IOobject1->pt()) <ZERO_LIMIT_FOR_PT) || (std::abs(matchSA_L2IOobject2->pt()) < ZERO_LIMIT_FOR_PT) ) {
777  ATH_MSG_DEBUG( " ...-> pT info not available (rec at pT=0)" );
779  ATH_MSG_DEBUG( " ...-> but same sign or invMass check is required. cannot judge overlap -> return with false" );
780  return false;
781  }
782  }
783 
784 
785  double absEta = (std::abs(mu1Pt) > std::abs(mu2Pt)) ? std::abs(mu1Eta) : std::abs(mu2Eta);
786  unsigned int iThres=0;
787  for(unsigned int i=0; i<(m_etaBins.size()-1); i++) {
788  if ( m_etaBins[i] <= absEta && absEta < m_etaBins[i+1] ) iThres = i;
789  }
790  float dRThres = m_dRCBThres[iThres];
791  float dRbySAThres = m_dRbySAThres[iThres];
792  float massThres = m_massCBThres[iThres];
793  ATH_MSG_DEBUG( " ...iThres=" << iThres );
794  if(m_RequireDR) ATH_MSG_DEBUG( " ...dR threshold=" << dRThres );
795  if(m_RequireDRbySA) ATH_MSG_DEBUG( " ...dR(byMF) threshold=" << dRbySAThres );
796  if(m_RequireMass) ATH_MSG_DEBUG( " ...mass threshold=" << massThres );
797 
798 
799 
800  // same sign cut
801  bool sameSign = false;
802  if( m_RequireSameSign ) {
803  sameSign = ((mu1Pt*mu2Pt) > 0);
804  ATH_MSG_DEBUG( " ...-> sameSign=" << sameSign );
805  }
806 
807  // dR cut
808  bool dRisClose = false;
809  float deta = mu1Eta - mu2Eta;
810  float dphi = xAOD::P4Helpers::deltaPhi(mu1Phi, mu2Phi);
811  float dR = std::sqrt(deta*deta + dphi*dphi);
812  if( m_RequireDR ) {
813  if( dR < dRThres ) dRisClose = true;
814  ATH_MSG_DEBUG( " ...-> dR=" << dR << " : dRisClose=" << dRisClose );
815  }
816 
817  // dR(by L2SA) cut
818  bool dRbySAisClose = false;
819  const xAOD::L2StandAloneMuon* muSA1 = matchSA_L2IOobject1->muSATrack();
820  const xAOD::L2StandAloneMuon* muSA2 = matchSA_L2IOobject2->muSATrack();
821  if( m_RequireDRbySA ) {
822  // here, we do not check (eta,phi) of mF is not (0,0)
823  // (i.e. we apply muComb based cut even if muFast rec is failed)
824  float deta = muSA1->etaMS() - muSA2->etaMS();
825  float dphi = xAOD::P4Helpers::deltaPhi(muSA1->phiMS(), muSA2->phiMS());
826  float dRBySA = std::sqrt(deta*deta + dphi*dphi);
827  if( dRBySA < dRbySAThres ) dRbySAisClose = true;
828  ATH_MSG_DEBUG( " ...-> dR(by MF)=" << dRBySA << " : dRbySAisClose=" << dRbySAisClose );
829  }
830 
831  // mass cut
832  const double TRACK_MASS = 0.; // just assume zero mass
833  bool massIsClose = false;
834  TLorentzVector lvioobj1, lvioobj2;
835  lvioobj1.SetPtEtaPhiM(std::abs(mu1Pt), mu1Eta, mu1Phi, TRACK_MASS);
836  lvioobj2.SetPtEtaPhiM(std::abs(mu2Pt), mu2Eta, mu2Phi, TRACK_MASS);
837  TLorentzVector lvsum = lvioobj1 + lvioobj2;
838  float invMass = lvsum.M();
839  if( m_RequireMass ) {
840  if( invMass < massThres ) massIsClose = true;
841  ATH_MSG_DEBUG( " ...-> invMass=" << invMass << " : massIsClose=" << massIsClose );
842  }
843 
844 
845  // total judge
846  bool overlap = false;
847  if( ((m_RequireSameSign && sameSign) || (! m_RequireSameSign)) &&
848  ((m_RequireDR && dRisClose) || (! m_RequireDR)) &&
849  ((m_RequireDRbySA && dRbySAisClose) || (! m_RequireDRbySA)) &&
850  ((m_RequireMass && massIsClose) || (! m_RequireMass)) ) {
851  overlap = true;
852  }
853  ATH_MSG_DEBUG( " ...=> isOverlap=" << overlap );
854 
855  return overlap;
856 }
857 
858 
859 StatusCode L2MuonSAIOMon :: chooseBestMuon( const std::vector< const xAOD::L2CombinedMuon* >& matchSA_L2IOobjects, std::vector< bool > &passOR, std::vector< unsigned int > &mucombResult ) const{
860 
861  const double ZERO_LIMIT = 1e-4;
862  unsigned int i,j,k;
863 
864  ATH_MSG_DEBUG( "--- choose best among overlaps & disable EVs (muComb based) ---" );
865  for(i=0; i<matchSA_L2IOobjects.size(); i++) {
866  ATH_MSG_DEBUG( "++ i=" << i << ": result=" << mucombResult[i] );
867  if( mucombResult[i] != i ) {
868  ATH_MSG_DEBUG( " overlap to some one. skip." );
869  continue;
870  }
871  std::vector<unsigned int> others;
872  for(j=0; j<matchSA_L2IOobjects.size(); j++) {
873  if( mucombResult[j] == mucombResult[i] ) others.emplace_back(j);
874  }
875  if( others.size() == 1 ) {
876  ATH_MSG_DEBUG( " unique object. keep it active." );
877  continue;
878  }
879  else { // must choose one best
880  ATH_MSG_DEBUG( " overlapped objects among: " << others );
881  unsigned int bestMuon = 0;
882  float maxPtCombMf = 0.;
883  float mindRRoadRoI = 999.;
884  for(k=0; k<others.size(); k++) {
885  j=others[k];
886 
887  float ptCombMf = std::abs(matchSA_L2IOobjects.at(j)->pt()/1e3);
888 
889  const float roadPhiP = std::atan2(matchSA_L2IOobjects.at(j)->muSATrack()->dirPhiMS(),1.);
890  const float roadPhiM = std::atan2(-1*matchSA_L2IOobjects.at(j)->muSATrack()->dirPhiMS(),-1.);
891  const float roadPhi = (std::abs(xAOD::P4Helpers::deltaPhi(roadPhiP, matchSA_L2IOobjects.at(j)->muSATrack()->roiPhi()))
892  < std::abs(xAOD::P4Helpers::deltaPhi(roadPhiM, matchSA_L2IOobjects.at(j)->muSATrack()->roiPhi())))? roadPhiP : roadPhiM;
893  float roadAw = 0.;
894  if(std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roiEta()) < 1.05) { // barrel
895  if( std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(1,0)) > ZERO_LIMIT ) roadAw = matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(1,0);
896  else if( std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(2,0)) > ZERO_LIMIT ) roadAw = matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(2,0);
897  else if( std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(0,0)) > ZERO_LIMIT ) roadAw = matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(0,0);
898  }
899  else { // endcap
900  if( std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(4,0)) > ZERO_LIMIT ) roadAw = matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(4,0);
901  else if( std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(5,0)) > ZERO_LIMIT ) roadAw = matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(5,0);
902  else if( std::abs(matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(3,0)) > ZERO_LIMIT ) roadAw = matchSA_L2IOobjects.at(j)->muSATrack()->roadAw(3,0);
903  }
904  float roadEta = 999.;
905  if(std::abs(roadAw) > ZERO_LIMIT) roadEta = -std::log(std::tan(0.5*std::atan(std::abs(roadAw))));
906  if(roadAw < 0) roadEta *= -1.;
907  float detaRoadRoI = roadEta - matchSA_L2IOobjects.at(j)->muSATrack()->roiEta();
908  float dphiRoadRoI = xAOD::P4Helpers::deltaPhi(roadPhi, matchSA_L2IOobjects.at(j)->muSATrack()->roiPhi());
909  float dRRoadRoI = std::sqrt(detaRoadRoI*detaRoadRoI + dphiRoadRoI*dphiRoadRoI);
910  ATH_MSG_DEBUG(" j="<< j << " , ptCombMf=" << ptCombMf << ", dRRoadRoI=" << dRRoadRoI);
911 
912 
913  if( (ptCombMf > maxPtCombMf) ||
914  (std::abs(ptCombMf - maxPtCombMf) < ZERO_LIMIT &&
915  dRRoadRoI < mindRRoadRoI) ) {
916  maxPtCombMf = ptCombMf;
917  mindRRoadRoI = dRRoadRoI;
918  bestMuon = j;
919  }
920  }
921  ATH_MSG_DEBUG( " best is: bestMuon/maxPtCombMf=" << bestMuon << " / " << maxPtCombMf );
922 
923  for(k=0; k<others.size(); k++) {
924  j=others[k];
925  if( j != bestMuon ) {
926  ATH_MSG_DEBUG( " EventView( j=" << j << " ) is not active" );
927 
928  passOR.at(j) = false;
929  }
930  else{
931  ATH_MSG_DEBUG( " EventView( j=" << j << " ) is best one" );
932  }
933  }
934  }
935  }
936 
937 
938  return StatusCode::SUCCESS;
939 }
940 
941 
942 StatusCode L2MuonSAIOMon :: muCombHypo_TDTworkaround( const std::string &chain, const std::vector< const xAOD::L2CombinedMuon* >& Trig_L2IOobjects, std::vector< bool > &pass_muCombHypo ) const{
943 
944 
945  int requireMuonNum = 1;
946 
947  int passHypo_MuonNum = 0;
948  for(auto &Trig_L2IOobject : Trig_L2IOobjects){
949  bool isPass_muCombHypo = false;
950  ATH_CHECK(isPassedmuCombHypo( chain, Trig_L2IOobject ,isPass_muCombHypo));
951  bool pass_muCombHypo_obj = isPass_muCombHypo;
952  pass_muCombHypo.push_back(pass_muCombHypo_obj);
953  if( pass_muCombHypo_obj ) passHypo_MuonNum++;
954  }
955 
956  if( passHypo_MuonNum >= requireMuonNum ){
957  ATH_MSG_DEBUG("this evt passed muCombhypo");
958  }
959  return StatusCode::SUCCESS;
960 }
961 
962 
963 StatusCode L2MuonSAIOMon :: isPassedmuCombHypo( const std::string &chain, const xAOD::L2CombinedMuon* Trig_L2IOobject , bool &pass_muCombHypo) const{
964  pass_muCombHypo = false;
965 
966  // config
967  std::vector< float > my_EtaBins = {0, 1.05, 1.5, 2.0, 9.9};
968  std::vector< float > my_muCombThres = {0., 0., 0., 0.};
969  bool my_pikCuts = true;
970  float my_maxPtToApplyPik = 25.;
971  float my_chi2MaxID = 3.5;
972  ATH_CHECK( decision_ptthreshold( chain, my_EtaBins, my_muCombThres, my_pikCuts, my_maxPtToApplyPik, my_chi2MaxID ) );
973  bool pikCut = true;
974  bool stdCut = true;
975 
976  auto ptValue = Trig_L2IOobject->pt() * Trig_L2IOobject->charge()/1e3;
977  float fexPt = ptValue;
978  if(my_pikCuts && (std::abs(fexPt) < my_maxPtToApplyPik)){
979  if(Trig_L2IOobject->idTrack()->chiSquared() > my_chi2MaxID){
980  ATH_MSG_DEBUG("this obj failed at Kpi rejection:idTrack_chiSquared = " << Trig_L2IOobject->idTrack()->chiSquared() );
981  pikCut = false;
982  }
983  }
984 
985  float absEta = std::abs(Trig_L2IOobject->eta());
986  unsigned int iThres = 0;
987  for(unsigned int i=0; i<(my_EtaBins.size()-1); i++) {
988  if ( my_EtaBins[i] <= absEta && absEta < my_EtaBins[i+1] ) iThres = i;
989  }
990  const float muCombThres = my_muCombThres[iThres];
991  if(Trig_L2IOobject->pt()/1e3 < muCombThres){
992  ATH_MSG_DEBUG("this obj failed at std Pt cut:muCombThres = " << muCombThres);
993  stdCut = false;
994  }
995 
996  if(stdCut && pikCut){
997  ATH_MSG_DEBUG("this obj passed muCombhypo");
998  pass_muCombHypo = true;
999  }
1000  return StatusCode::SUCCESS;
1001 }
1002 
1003 
1004 StatusCode L2MuonSAIOMon :: decision_ptthreshold( const std::string &chain, std::vector< float > &my_EtaBins, std::vector< float > &my_muCombThres,
1005  bool &my_pikCuts, float &my_maxPtToApplyPik, float &my_chi2MaxID ) const{
1006 
1007  my_maxPtToApplyPik = 25.;
1008  my_chi2MaxID = 3.5;
1009  ATH_MSG_DEBUG("this chain is" << chain);
1010  if(chain == "HLT_mu4_l2io_L1MU3V"){
1011  my_EtaBins = {0, 1.05, 1.5, 2.0, 9.9}; //4GeV_v15a
1012  my_muCombThres = {3.86, 3.77, 3.69, 3.70}; //4GeV_v15a
1013  my_pikCuts = false;
1014  }else if(chain == "HLT_mu24_ivarmedium_mu6_l2io_probe_L1MU14FCH"){
1015  my_EtaBins = {0, 1.05, 1.5, 2.0, 9.9}; //6GeV_v15a
1016  my_muCombThres = {5.87, 5.79, 5.70, 5.62}; //6GeV_v15a
1017  my_pikCuts = false;
1018  }else if(chain == "HLT_mu24_ivarmedium_mu6_l2io_probe_L1MU18VFCH"){
1019  my_EtaBins = {0, 1.05, 1.5, 2.0, 9.9}; //6GeV_v15a
1020  my_muCombThres = {5.87, 5.79, 5.70, 5.62}; //6GeV_v15a
1021  my_pikCuts = false;
1022  }else{
1023  ATH_MSG_ERROR("muCombHypo config is NOT defined in this package:chain = " << chain);
1024  }
1025  return StatusCode::SUCCESS;
1026 }
1027 
1028 
1029 std::tuple<float,float,float> L2MuonSAIOMon :: L2ORPosForMatchFunc(const xAOD::L2StandAloneMuon *trig){
1030  return std::forward_as_tuple(trig->pt(), trig->etaMS(), trig->phiMS());
1031 }
1032 
1033 
1034 std::tuple<float,float,float> L2MuonSAIOMon :: L2ORPosForMatchFunc(const xAOD::L2CombinedMuon *trig){
1035  return std::forward_as_tuple( (trig->pt()/1e3 * trig->charge() ), trig->eta(), trig->phi());
1036 }
1037 
1038 
1039 const xAOD::L2CombinedMuon* L2MuonSAIOMon :: searchL2InsideOut( const EventContext &ctx, const xAOD::Muon *mu, const std::string& trig) const {
1040  ATH_MSG_DEBUG("MuonMonitoring::searchL2InsideOut()");
1041 
1042  const xAOD::L2CombinedMuon* offlinematched_L2IOobject = nullptr;
1043 
1044  //TDT workaround
1045  std::vector< const xAOD::L2CombinedMuon* > Trig_L2IOobjects;
1046  if( !matchL2IO_wContainer(ctx, trig, Trig_L2IOobjects).isSuccess() ) {
1047  ATH_MSG_WARNING("matchL2IO_wContainer failed, returning nullptr");
1048  return offlinematched_L2IOobject;
1049  }
1050  if( Trig_L2IOobjects.empty() ) {
1051  return offlinematched_L2IOobject;
1052  }
1053 
1054  float reqdR = 1000.;
1055 
1056  double offlEta = mu->eta();
1057  double offlPhi = mu->phi();
1058 
1059  int loop_counter = 0;
1060  int match_index = 0;
1061  for(auto Trig_L2IOobject : Trig_L2IOobjects){
1062  double trigEta = Trig_L2IOobject->eta();
1063  double trigPhi = Trig_L2IOobject->phi();
1064  double deta = offlEta - trigEta;
1065  double dphi = xAOD::P4Helpers::deltaPhi(offlPhi, trigPhi);
1066  double dR = std::sqrt(deta*deta + dphi*dphi);
1067 
1068  ATH_MSG_VERBOSE("Trigger muon candidate eta=" << trigEta << " phi=" << trigPhi << " pt=" << Trig_L2IOobject->pt() << " dR=" << dR);
1069  if( dR<reqdR ){
1070  reqdR = dR;
1071  match_index = loop_counter;
1072  ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi << " pt=" << Trig_L2IOobject->pt() << " dR=" << dR );
1073  }
1074  loop_counter++;
1075  }
1076 
1077  offlinematched_L2IOobject = Trig_L2IOobjects.at(match_index);
1078  return offlinematched_L2IOobject;
1079 }
1080 
1081 
1082 const xAOD::Muon* L2MuonSAIOMon :: searchTagOfflineMuon( const EventContext& ctx, const xAOD::Muon* probe ) const{
1083  ATH_MSG_DEBUG("MuonMonitoring::searchTagOfflineMuon()");
1084 
1085  const double ZERO_LIMIT = 0.00001;
1086 
1087  double Jpsimass = 3.0969;
1088  double Zmass = 91.1876;
1089  double my_Jpsimass_lowlim = 81.;
1090  double my_Jpsimass_highlim = 101.;
1091  double my_Zmass_lowlim = 2.7;
1092  double my_Zmass_highlim = 3.5;
1093 
1094  const xAOD::Muon *tag = nullptr;
1095 
1097  if (! muons.isValid() ) {
1098  ATH_MSG_ERROR("evtStore() does not contain muon Collection with name "<< m_MuonContainerKey);
1099  return tag;
1100  }
1101 
1102  double mass_diff_min = 999.;
1103  double tpdR_min = 999.;
1104  bool tpfromZ = false;
1105  for( const xAOD::Muon* mu : *muons ){
1106  if( mu->muonType()>m_muontype ) continue;
1107  if( mu->quality() != xAOD::Muon::Medium && mu->quality() != xAOD::Muon::Tight ) continue;
1108  if( mu->charge()*probe->charge() > 0 ) continue;
1109  const ElementLink<xAOD::TrackParticleContainer> &tag_ms_track = mu->muonSpectrometerTrackParticleLink();
1110  if( !tag_ms_track.isValid() ) continue; // tag muon dosen't have ms track
1111  TLorentzVector lvmu = mu->p4();
1112  TLorentzVector lvprobe = probe->p4();
1113  double dimu_mass = (lvmu+lvprobe).M()/1.e3;
1114  double tpdR = lvmu.DeltaR(lvprobe);
1115  if( dimu_mass > my_Jpsimass_lowlim && dimu_mass < my_Jpsimass_highlim ){
1116  if( tpfromZ ) continue; // Z has higher priority than Jpsi
1117  double mass_diff = std::abs(dimu_mass - Jpsimass);
1118  if( mass_diff - mass_diff_min < -1.*ZERO_LIMIT ){
1119  mass_diff_min = mass_diff;
1120  tpdR_min =tpdR;
1121  tag = mu;
1122  }
1123  else if( std::abs(mass_diff - mass_diff_min) < ZERO_LIMIT){
1124  if( tpdR - tpdR_min < 0. ){
1125  mass_diff_min = mass_diff;
1126  tpdR_min = tpdR;
1127  tag = mu;
1128  }
1129  }
1130  }
1131  else if( dimu_mass > my_Zmass_lowlim && dimu_mass < my_Zmass_highlim ){
1132  tpfromZ = true;
1133  double mass_diff = std::abs(dimu_mass - Zmass);
1134  if( mass_diff - mass_diff_min < -1.*ZERO_LIMIT ){
1135  mass_diff_min = mass_diff;
1136  tpdR_min =tpdR;
1137  tag = mu;
1138  }
1139  else if( std::abs(mass_diff - mass_diff_min) < ZERO_LIMIT){
1140  if( tpdR - tpdR_min < 0. ){
1141  mass_diff_min = mass_diff;
1142  tpdR_min =tpdR;
1143  tag = mu;
1144  }
1145  }
1146  }
1147  }
1148 
1149  return tag;
1150 }
xAOD::L2CombinedMuon_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
L2MuonSAIOMon::m_massCBThres
Gaudi::Property< std::vector< float > > m_massCBThres
Definition: L2MuonSAIOMon.h:49
L2MuonSAIOMon::L2OverlapRemover
StatusCode L2OverlapRemover(const std::vector< const xAOD::L2CombinedMuon * > &matchSA_L2IOobjects, std::vector< bool > &isoverlap, std::vector< bool > &passOR) const
Definition: L2MuonSAIOMon.cxx:677
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
TrigMuonMonitorAlgorithm::m_MuonContainerKey
SG::ReadHandleKey< xAOD::MuonContainer > m_MuonContainerKey
Definition: TrigMuonMonitorAlgorithm.h:133
TrigMuonMonitorAlgorithm::m_group
Gaudi::Property< std::string > m_group
Name of monitored group.
Definition: TrigMuonMonitorAlgorithm.h:141
L2MuonSAIOMon::m_RequireDR
bool m_RequireDR
Definition: L2MuonSAIOMon.h:52
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
P4Helpers::invMass
double invMass(const I4Momentum &pA, const I4Momentum &pB)
invariant mass from two I4momentum references
Definition: P4Helpers.h:252
xAOD::L2StandAloneMuon_v2::etaMS
float etaMS() const
Get the eta at muon spectrometer.
TrigMuonMonitorAlgorithm::m_matchTool
ToolHandle< MuonMatchingTool > m_matchTool
Definition: TrigMuonMonitorAlgorithm.h:129
xAOD::Muon_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: Muon_v1.cxx:79
xAOD::L2StandAloneMuon_v2
Class describing standalone muons reconstructed in the LVL2 trigger.
Definition: L2StandAloneMuon_v2.h:36
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
xAOD::L2StandAloneMuon_v2::mdtHitR
float mdtHitR(unsigned int tube) const
Definition: L2StandAloneMuon_v2.cxx:1436
L2MuonSAIOMon::m_L2MuonCBIOContainerKey
SG::ReadHandleKey< xAOD::L2CombinedMuonContainer > m_L2MuonCBIOContainerKey
Definition: L2MuonSAIOMon.h:29
xAOD::L2StandAloneMuon_v2::roadAw
float roadAw(int station, int sector) const
Slope.
Definition: L2StandAloneMuon_v2.cxx:480
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
L2MuonSAIOMon::chooseBestMuon
StatusCode chooseBestMuon(const std::vector< const xAOD::L2CombinedMuon * > &matchSA_L2IOobjects, std::vector< bool > &passOR, std::vector< unsigned int > &mucombResult) const
Definition: L2MuonSAIOMon.cxx:859
L2MuonSAIOMon::initialize
virtual StatusCode initialize() override
initialize
Definition: L2MuonSAIOMon.cxx:15
xAOD::L2CombinedMuon_v1::charge
float charge() const
get seeding muon charge
AthMonitorAlgorithm::getTrigDecisionTool
const ToolHandle< Trig::TrigDecisionTool > & getTrigDecisionTool() const
Get the trigger decision tool member.
Definition: AthMonitorAlgorithm.cxx:189
M_PI
#define M_PI
Definition: ActiveFraction.h:11
xAOD::TrackParticle_v1::chiSquared
float chiSquared() const
Returns the of the overall track fit.
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
xAOD::L2StandAloneMuon_v2::phiMS
float phiMS() const
Get the phi at muon spectrometer.
L2MuonSAIOMon::isOverlap
bool isOverlap(const xAOD::L2CombinedMuon *matchSA_L2IOobject1, const xAOD::L2CombinedMuon *matchSA_L2IOobject2) const
Definition: L2MuonSAIOMon.cxx:754
L2MuonSAIOMon::searchL2InsideOut
const xAOD::L2CombinedMuon * searchL2InsideOut(const EventContext &ctx, const xAOD::Muon *mu, const std::string &trigger) const
Definition: L2MuonSAIOMon.cxx:1039
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
L2MuonSAIOMon::m_plateaus
std::map< std::string, double > m_plateaus
Definition: L2MuonSAIOMon.h:28
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
L2MuonSAIOMon::m_RequireSameSign
bool m_RequireSameSign
Definition: L2MuonSAIOMon.h:55
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
Monitored::Collection
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
Definition: MonitoredCollection.h:38
xAOD::L2CombinedMuon_v1
Class describing combined muon reconstructed in the LVL2 trigger.
Definition: L2CombinedMuon_v1.h:41
xAOD::Muon_v1::charge
float charge() const
xAOD::L2CombinedMuon_v1::muSATrack
const xAOD::L2StandAloneMuon * muSATrack() const
Get the SA muon as a bare pointer.
xAOD::L2StandAloneMuon_v2::superPointR
float superPointR(int chamber) const
Get the measured radious of the muon in one particular super point.
Definition: L2StandAloneMuon_v2.cxx:179
xAOD::L2CombinedMuon_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
L2MuonSAIOMon::m_RequireMass
bool m_RequireMass
Definition: L2MuonSAIOMon.h:54
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
MuonMatchingTool.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
xAOD::P4Helpers::deltaR
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Definition: xAODP4Helpers.h:150
L2MuonSAIOMon::muCombHypo_TDTworkaround
StatusCode muCombHypo_TDTworkaround(const std::string &chain, const std::vector< const xAOD::L2CombinedMuon * > &Trig_L2IOobjects, std::vector< bool > &pass_muCombHypo) const
Definition: L2MuonSAIOMon.cxx:942
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
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
xAOD::L2CombinedMuon_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
xAOD::L2StandAloneMuon_v2::mdtHitChamber
int mdtHitChamber(unsigned int tube) const
Definition: L2StandAloneMuon_v2.cxx:1428
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
L2MuonSAIOMon.h
TrigMuonMonitorAlgorithm
Base class from which analyzers can define a derived class to do specific analysis.
Definition: TrigMuonMonitorAlgorithm.h:22
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
AthMonitorAlgorithm::fill
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &&variables) const
Fills a vector of variables to a group by reference.
ReadTripsProbsFromCool.denominator
denominator
Definition: ReadTripsProbsFromCool.py:96
L2MuonSAIOMon::m_RequireDRbySA
bool m_RequireDRbySA
Definition: L2MuonSAIOMon.h:53
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
TrigMuonMonitorAlgorithm::m_monitored_chains
Gaudi::Property< std::vector< std::string > > m_monitored_chains
List of trigger chains that are monitored in fillVariablesPerChain and fillVariablesPerOfflineMuonPer...
Definition: TrigMuonMonitorAlgorithm.h:137
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
ZERO_LIMIT
const float ZERO_LIMIT
Definition: VP1TriggerHandleL2.cxx:37
LikeEnum::Tight
@ Tight
Definition: LikelihoodEnums.h:15
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtilsRoot.cxx:884
L2MuonSAIOMon::fillVariablesPerOfflineMuonPerChain
virtual StatusCode fillVariablesPerOfflineMuonPerChain(const EventContext &ctx, const xAOD::Muon *mu, const std::string &chain) const override
Function that fills variables of trigger objects associated to specified trigger chains comparing off...
Definition: L2MuonSAIOMon.cxx:87
xAOD::L2StandAloneMuon_v2::mdtHitIsOutlier
int mdtHitIsOutlier(unsigned int tube) const
Definition: L2StandAloneMuon_v2.cxx:1420
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
L2MuonSAIOMon::m_etaBins
Gaudi::Property< std::vector< float > > m_etaBins
Definition: L2MuonSAIOMon.h:46
L2MuonSAIOMon::m_dRCBThres
Gaudi::Property< std::vector< float > > m_dRCBThres
Definition: L2MuonSAIOMon.h:47
TrigMuonDefs.h
TrigMuonMonitorAlgorithm::m_muontype
Gaudi::Property< int > m_muontype
Requirement for the offline muon type considered in analyses.
Definition: TrigMuonMonitorAlgorithm.h:139
L2MuonSAIOMon::L2MuonSAIOMon
L2MuonSAIOMon(const std::string &name, ISvcLocator *pSvcLocator)
Definition: L2MuonSAIOMon.cxx:11
L2MuonSAIOMon::isPassedmuCombHypo
StatusCode isPassedmuCombHypo(const std::string &chain, const xAOD::L2CombinedMuon *Trig_L2IOobjects, bool &pass_muCombHypo) const
Definition: L2MuonSAIOMon.cxx:963
TrigCompositeUtils::LinkInfo
Helper to keep a Decision object, ElementLink and ActiveState (with respect to some requested ChainGr...
Definition: LinkInfo.h:28
xAOD::L2StandAloneMuon_v2::nMdtHits
uint32_t nMdtHits() const
Get the online ID, offline ID, R, Z, redidual, time, space and sigma of each MDT tube.
Definition: L2StandAloneMuon_v2.cxx:1400
xAOD::L2StandAloneMuon_v2::mdtHitResidual
float mdtHitResidual(unsigned int tube) const
Definition: L2StandAloneMuon_v2.cxx:1460
LikeEnum::Medium
@ Medium
Definition: LikelihoodEnums.h:14
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
TrigMuonMonitorAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: TrigMuonMonitorAlgorithm.cxx:13
L2MuonSAIOMon::fillVariablesPerChain
virtual StatusCode fillVariablesPerChain(const EventContext &ctx, const std::string &chain) const override
Function that fills variables of trigger objects associated to specified trigger chains.
Definition: L2MuonSAIOMon.cxx:34
python.LArCondContChannels.isBarrel
isBarrel
Definition: LArCondContChannels.py:659
TauGNNUtils::Variables::absEta
bool absEta(const xAOD::TauJet &tau, double &out)
Definition: TauGNNUtils.cxx:234
xAOD::L2StandAloneMuon_v2::roadBw
float roadBw(int station, int sector) const
Intercept.
Definition: L2StandAloneMuon_v2.cxx:507
xAOD::L2StandAloneMuon_v2::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
xAOD::L2CombinedMuon_v1::idTrack
const xAOD::TrackParticle * idTrack() const
Get the ID track as a bare pointer.
Definition: L2CombinedMuon_v1.cxx:119
ACTIVE
@ ACTIVE
Definition: ZdcID.h:21
L2MuonSAIOMon::L2ORPosForMatchFunc
static std::tuple< float, float, float > L2ORPosForMatchFunc(const xAOD::L2StandAloneMuon *trig)
Definition: L2MuonSAIOMon.cxx:1029
xAOD::L2StandAloneMuon_v2::roiWord
uint32_t roiWord() const
Get the RoI ID of the seeding LVL1 muon.
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
L2MuonSAIOMon::searchTagOfflineMuon
const xAOD::Muon * searchTagOfflineMuon(const EventContext &ctx, const xAOD::Muon *probe) const
Definition: L2MuonSAIOMon.cxx:1082
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
L2MuonSAIOMon::m_monitored_chains_plateau
Gaudi::Property< std::vector< float > > m_monitored_chains_plateau
Definition: L2MuonSAIOMon.h:27
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
passOR
@ passOR
Definition: SUSYToolsTester.cxx:105
xAOD::L2StandAloneMuon_v2::mdtHitZ
float mdtHitZ(unsigned int tube) const
Definition: L2StandAloneMuon_v2.cxx:1444
L2MuonSAIOMon::decision_ptthreshold
StatusCode decision_ptthreshold(const std::string &chain, std::vector< float > &my_EtaBins, std::vector< float > &my_muCombThres, bool &my_pikCuts, float &my_maxPtToApplyPik, float &my_chi2MaxID) const
Definition: L2MuonSAIOMon.cxx:1004
fitman.k
k
Definition: fitman.py:528
L2MuonSAIOMon::m_dRbySAThres
Gaudi::Property< std::vector< float > > m_dRbySAThres
Definition: L2MuonSAIOMon.h:48
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
L2MuonSAIOMon::matchL2IO_wContainer
StatusCode matchL2IO_wContainer(const EventContext &ctx, const std::string &chain, std::vector< const xAOD::L2CombinedMuon * > &Trig_L2IOobjects) const
Definition: L2MuonSAIOMon.cxx:611