ATLAS Offline Software
TrigmuCombHypoTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "GaudiKernel/SystemOfUnits.h"
9 #include "TrigmuCombHypoTool.h"
10 #include "CxxUtils/phihelper.h"
11 
12 #include <cmath>
13 
14 using namespace TrigCompositeUtils;
15 // --------------------------------------------------------------------------------
16 // --------------------------------------------------------------------------------
17 
19  const std::string & name,
20  const IInterface* parent )
21  : AthAlgTool( type, name, parent ),
22  m_decisionId( HLT::Identifier::fromToolName( name ) )
23 {
24 }
25 
27 }
28 
29 // --------------------------------------------------------------------------------
30 // --------------------------------------------------------------------------------
31 
33 {
34  ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId );
35 
36  if (m_acceptAll) {
37  ATH_MSG_DEBUG("Accepting all the events!");
38  } else {
39  ATH_MSG_DEBUG("AcceptAll = False");
40  m_bins.resize (m_ptBins.size());
41  for ( size_t j=0; j<m_ptBins.size(); ++j) {
42  m_bins[j] = m_ptBins[j].size() - 1;
43  if (m_bins[j] != m_ptThresholds[j].size()) {
44  ATH_MSG_ERROR("bad thresholds setup .... exiting!");
45  return StatusCode::FAILURE;
46  }
47 
48  for (std::vector<float>::size_type i = 0; i < m_bins[j]; ++i) {
49 
50  ATH_MSG_DEBUG("bin[" << j << "] " << m_ptBins[j][i] << " - " << m_ptBins[j][i + 1]
51  << " with Pt Threshold of " << (m_ptThresholds[j][i]) / Gaudi::Units::GeV << " GeV");
52  }
53  }
54  }
55 
56  if ( not m_monTool.name().empty() ) {
57  ATH_CHECK( m_monTool.retrieve() );
58  ATH_MSG_DEBUG("MonTool name: " << m_monTool);
59  }
60 
61  // Overlap Removal
62  if( m_applyOR ) {
63  ATH_MSG_DEBUG( "--- overlap removal as: ---" );
64  if( m_requireDR ) {
65  ATH_MSG_DEBUG( "+ dR cut:" );
66  if( (m_etaBins.size()-1) != m_dRThres.size() ) {
67  ATH_MSG_ERROR( "bad thresholds setup .... exiting!" );
68  return StatusCode::FAILURE;
69  }
70  for(unsigned int i=0; i<m_dRThres.size(); i++) {
71  ATH_MSG_DEBUG( " EtaBin " << m_etaBins[i] << " - " << m_etaBins[i+1]
72  << " : dR < " << m_dRThres[i] );
73  }
74  }
75  if( m_requireMufastDR ) {
76  ATH_MSG_DEBUG( "+ dr(by mF) cut:" );
77  if( (m_etaBins.size()-1) != m_mufastDRThres.size() ) {
78  ATH_MSG_ERROR( "bad thresholds setup .... exiting!" );
79  return StatusCode::FAILURE;
80  }
81  for(unsigned int i=0; i<m_mufastDRThres.size(); i++) {
82  ATH_MSG_DEBUG( " EtaBin " << m_etaBins[i] << " - " << m_etaBins[i+1]
83  << " : dR(mF) < " << m_mufastDRThres[i] );
84  }
85  }
86  if( m_requireMass ) {
87  ATH_MSG_DEBUG( "+ Mass cut:" );
88  if( (m_etaBins.size()-1) != m_massThres.size() ) {
89  ATH_MSG_ERROR( "bad thresholds setup .... exiting!" );
90  return StatusCode::FAILURE;
91  }
92  for(unsigned int i=0; i<m_massThres.size(); i++) {
93  ATH_MSG_DEBUG( " EtaBin " << m_etaBins[i] << " - " << m_etaBins[i+1]
94  << " : Mass < " << m_massThres[i] );
95  }
96  }
97  if( m_requireSameSign ) ATH_MSG_DEBUG( "+ Same charge sign" );
98  }
99  // minimum d0 cut for displaced muon triggers
100  if (m_d0min>0.) ATH_MSG_DEBUG( " Rejecting muons with abs(d0) < "<<m_d0min<<" mm");
101 
102  return StatusCode::SUCCESS;
103 }
104 
106 {
107 
108  // defined Monitoring variables
109  auto fexPt = Monitored::Scalar("Pt", -9999.);
110  auto ptFL = Monitored::Scalar("PtFL", -9999.);
111  auto Strategy = Monitored::Scalar("StrategyFlag", 0);
112  auto idEta = Monitored::Scalar("Eta", -9999.);
113  auto idPhi = Monitored::Scalar("Phi", -9999.);
114  auto idZ0 = Monitored::Scalar("Z0", -9999.);
115  auto idA0 = Monitored::Scalar("A0", -9999.);
116 
117  auto monitorIt = Monitored::Group(m_monTool, fexPt, ptFL, Strategy,
118  idEta, idPhi, idZ0, idA0);
119 
120  ATH_MSG_VERBOSE( "Cut index " << cutIndex );
121 
122  // flag to pass or not
123  bool result = false;
124 
125  if(m_acceptAll) {
126  result = true;
127  ATH_MSG_DEBUG("Accept property is set: taking all the events");
128  return result;
129  } else {
130  result = false;
131  ATH_MSG_DEBUG("Accept property not set: applying selection!");
132  }
133 
134  //Retrieve combined muon
135  //xAOD::L2CombinedMuon
136  auto pMuon = input.muComb;
137  if (!pMuon) {
138  result = false;
139  ATH_MSG_ERROR("Retrieval of xAOD::L2CombinedMuon from vector failed");
140  return result;
141  }
142 
143  auto ptValue = pMuon->pt() * pMuon->charge() / Gaudi::Units::GeV;
144 
145 
146  if (pMuon->pt() == 0) {
147  ATH_MSG_DEBUG("L2CombinedMuon pt == 0, empty container -> rejected");
148  result = false;
149  return result;
150  }
151 
152  fexPt = ptValue;
153  ptFL = ptValue;
154  idEta = pMuon->eta();
155  idPhi = pMuon->phi();
156  int usealgo = pMuon->strategy();
157  float ptresComb = pMuon->sigmaPt() / Gaudi::Units::GeV;
158  Strategy = usealgo;
159  ATH_MSG_DEBUG("combined muon pt (GeV)/ sigma_pt (GeV)/ eta / phi / usedalgo: "
160  << fexPt << " (GeV) / " << ptresComb << " (GeV) / " << idEta << " / " << idPhi
161  << " / " << usealgo);
162 
163  // check the pointers to the L2StandAloneMuon
164  if (!pMuon->muSATrack()) {
165  ATH_MSG_DEBUG("L2CombinedMuon has no valid xaOD::L2StandaloneMuon -> rejected");
166  result = false;
167  return result;
168  }
169 
170  // check the pointer to the ID track
171  if (!pMuon->idTrack()) {
172  ATH_MSG_DEBUG("L2CombinedMuon has no valid xAOD:TrackParticle IDtrack -> rejected");
173  result = false;
174  return result;
175  }
176 
177  idA0 = pMuon->idTrack()->d0();
178  idZ0 = pMuon->idTrack()->z0();
179 
180  //Get the Pt cut for that eta bin
181  float threshold = (idEta != -9999) ? 0 : 999999;
182  float absEta = fabs(idEta);
183  for (std::vector<float>::size_type i = 0; i < m_bins[cutIndex]; ++i) {
184  if (absEta > m_ptBins[cutIndex][i] && absEta < m_ptBins[cutIndex][i + 1]) threshold = m_ptThresholds[cutIndex][i];
185  }
186 
187  // Check pt threshold for hypothesis and pi/k rejection cuts,
188  // convert units since Muonfeature is in GeV
189 
190  //Kpi rejection
191  bool pikCut = true;
192  if (m_pikCuts && (std::abs(fexPt) < m_maxPtToApplyPik)) {
193  if (pMuon->idTrack()->chiSquared() > m_chi2MaxID) pikCut = false;
194  }
195 
196  //Std Pt cut
197  bool stdCut = true;
198  if (std::abs(fexPt) <= (threshold / Gaudi::Units::GeV)) stdCut = false;
199  ATH_MSG_DEBUG("REGTEST muon pt is " << fexPt
200  << " GeV and threshold cut is " << threshold / Gaudi::Units::GeV
201  << " GeV and pik_cut is " << (pikCut ? "true" : "false"));
202 
203  //Strategy dependent Pt cuts
204  bool sdpCut = true;
205  if (m_strategydependent && usealgo > 0) {
206  if (usealgo >= 1 && usealgo <= 4) {
207  double tmpcut = m_strategyDependentPtCuts.value()[usealgo - 1];
208  if (std::abs(fexPt) <= std::abs(tmpcut)) sdpCut = false;
209  if (tmpcut < 0) stdCut = true; //Do not apply std Pt cut
210  ATH_MSG_DEBUG("REGTEST muon pt is " << fexPt << " GeV"
211  << " and threshold for strategy dependent cut is " << tmpcut
212  << " GeV and strategy dependent / std cuts are " << (sdpCut ? "true" : "false") << " / " << (stdCut ? "true" : "false"));
213  } else {
214  ATH_MSG_DEBUG("usealgo out of range, is: " << usealgo << " while should be in [1, 4]");
215  }
216  }
217 
218 
219  //d0 cut
220  bool d0Cut = true;
221  if (m_d0min>0. && std::abs(idA0)<m_d0min) d0Cut = false;
222 
223  result = stdCut && pikCut && sdpCut && d0Cut;
224 
225  if (result) ptFL = -9999.;
226 
227  if (m_d0min>0.) {
228  ATH_MSG_DEBUG("REGTEST: Muon passed pt threshold: " << (stdCut ? "true" : "false")
229  << " and pik_cut is " << (pikCut ? "true" : "false")
230  << " and strategy dependent cuts is " << (sdpCut ? "true" : "false")
231  << " and result of d0min cut is "<< (d0Cut ? "true" : "false")
232  << " so hypothesis is " << (result ? "true" : "false"));
233  } else {
234  ATH_MSG_DEBUG("REGTEST: Muon passed pt threshold: " << (stdCut ? "true" : "false")
235  << " and pik_cut is " << (pikCut ? "true" : "false")
236  << " and strategy dependent cuts is " << (sdpCut ? "true" : "false")
237  << " so hypothesis is " << (result ? "true" : "false"));
238  }
239  return result;
240 }
241 
242 // --------------------------------------------------------------------------------
243 // --------------------------------------------------------------------------------
244 
245 // from TrigmuCombHypoAlg
246 StatusCode TrigmuCombHypoTool::decide(std::vector<TrigmuCombHypoTool::CombinedMuonInfo>& toolInput) const
247 {
248  size_t numTrigger = m_ptBins.size();
249  size_t numMuon = toolInput.size();
250  ATH_MSG_DEBUG("Retrieved from TrigmuCombHypoAlg and Running TrigmuCombHypoTool for selections.");
251 
252  if ( numTrigger == 1 ) { // in case of HLT_mu4, HLT_mu6 and so on.
253  ATH_MSG_DEBUG("Number of muon event = " << numMuon );
254  ATH_MSG_DEBUG("Applying selection of single << " << m_decisionId );
255  return inclusiveSelection(toolInput);
256  } else { // in case of HLT_2mu6 and so on.
257  ATH_MSG_DEBUG("Number of muon event = " << numMuon );
258  ATH_MSG_DEBUG("Applying selection of multiplicity << " << m_decisionId );
259 
260  if(m_applyOR)
261  ATH_CHECK(applyOverlapRemoval(toolInput));
262 
263  return multiplicitySelection(toolInput);
264  }
265 
266  return StatusCode::SUCCESS;
267 }
268 
269 
270 StatusCode TrigmuCombHypoTool::inclusiveSelection(std::vector<TrigmuCombHypoTool::CombinedMuonInfo>& input) const
271 {
272  for ( auto& i: input) {
273  // If muon event has difference DecisionID, it shouldn't apply.
274  if (TrigCompositeUtils::passed(m_decisionId.numeric(), i.previousDecisionIDs)) {
275  if ( decideOnSingleObject(i, 0)==true ) {
276  ATH_MSG_DEBUG("Pass through selection " << m_decisionId );
278  } else {
279  ATH_MSG_DEBUG("Not pass through selection " << m_decisionId );
280  }
281  } else {
282  ATH_MSG_DEBUG("Not match DecisionID:" << m_decisionId );
283  }
284  }
285 
286  return StatusCode::SUCCESS;
287 }
288 
289 
290 StatusCode TrigmuCombHypoTool::multiplicitySelection(std::vector<TrigmuCombHypoTool::CombinedMuonInfo>& input) const
291 {
292  HLT::Index2DVec passingSelection( m_ptBins.size() );
293 
294  for ( size_t cutIndex=0; cutIndex < m_ptBins.size(); ++cutIndex ) {
295  size_t elementIndex{ 0 };
296  for ( auto& i: input ) {
297 
298  if(!m_acceptAll && m_applyOR && (i.isOR.find(m_decisionId.numeric()) != i.isOR.end())) {
299  ATH_MSG_DEBUG("skip due to overap, DecisionID " << m_decisionId );
300  elementIndex++;
301  continue;
302  }
303 
304  // If muon event has difference DecisionID, it shouldn't apply.
305  if ( TrigCompositeUtils::passed( m_decisionId.numeric(), i.previousDecisionIDs ) ) {
306  if ( decideOnSingleObject( i, cutIndex ) == true ) {
307  ATH_MSG_DEBUG("Pass through selection " << m_decisionId << " : Event[" << elementIndex << "]" );
308  passingSelection[cutIndex].push_back( elementIndex );
309  } else {
310  ATH_MSG_DEBUG("Not pass through selection " << m_decisionId << " : Event[" << elementIndex << "]" );
311  }
312  } else {
313  ATH_MSG_DEBUG("Not match DecisionID " << m_decisionId );
314  }
315  elementIndex++;
316  }
317 
318  // If no object passes the selection, multipul selection should stop.
319  if ( passingSelection[cutIndex].empty() ) {
320  ATH_MSG_DEBUG( "No object passed selection " << cutIndex << " rejecting" );
321  return StatusCode::SUCCESS;
322  }
323  }
324 
325  std::set<size_t> passingIndices;
326  if ( m_decisionPerCluster==true ) {
327  auto notFromSameRoI = [&]( const HLT::Index1DVec& comb ) {
328  std::set<const xAOD::L2CombinedMuon*> setOfClusters;
329  for ( auto index: comb ) {
330  setOfClusters.insert( input[index].muComb );
331  }
332  return setOfClusters.size() == comb.size();
333  };
334 
335  HLT::elementsInUniqueCombinations( passingSelection, passingIndices, std::move(notFromSameRoI) );
336 
337  } else {
338  HLT::elementsInUniqueCombinations( passingSelection, passingIndices );
339  }
340 
341  if ( passingIndices.empty() ) {
342  ATH_MSG_DEBUG("No muon event passed through selection " << m_decisionId );
343  return StatusCode::SUCCESS;
344  }
345 
346  for ( auto idx: passingIndices ) {
347  ATH_MSG_DEBUG("Muon event[" << idx << "] passes through Chain/ID " << m_decisionId
348  << " with pT = " << input[idx].muComb->pt() << "GeV" );
350  }
351 
352  return StatusCode::SUCCESS;
353 }
354 
355 
356 // --------------------------------------------------------------------------------
357 // --------------------------------------------------------------------------------
358 
359 StatusCode TrigmuCombHypoTool::applyOverlapRemoval(std::vector<TrigmuCombHypoTool::CombinedMuonInfo>& toolInput) const {
360 
361  ATH_MSG_DEBUG("Running Overlap Removal for muComb");
362 
363  std::vector<TrigmuCombHypoTool::CombinedMuonInfo*> input;
364 
365  // set pT threshold for events where so many muons
366  // in such events, muons are removed if pT < pTthreshold
367  // pT threshold is set to the pT value of m_numMuonThreshold-th leading muon
368  float pTthreshold = 0;
369  std::vector<float> pTvec;
370  for ( auto& i: toolInput ) {
371  if ( TrigCompositeUtils::passed( m_decisionId.numeric(), i.previousDecisionIDs) &&
372  i.muComb!=nullptr ){
373  pTvec.emplace_back(i.muComb->pt());
374  }
375  }
376  if(pTvec.size() > m_numMuonThreshold) {
377  std::sort(pTvec.begin(),pTvec.end(), std::greater<float>{});
378  pTthreshold = pTvec.at(m_numMuonThreshold);
379  }
380 
381  for ( auto& i: toolInput ) {
382  if ( TrigCompositeUtils::passed( m_decisionId.numeric(), i.previousDecisionIDs) &&
383  i.muComb!=nullptr ){
384  if(i.muComb->pt() > pTthreshold)
385  input.emplace_back(&i);
386  else // set isOR for removed muons
387  i.isOR.insert(m_decisionId.numeric());
388  }
389  }
390 
391  size_t numMuon = input.size();
392 
393  auto mucombNrAllEVs = Monitored::Scalar("NrAllEVs", -9999.);
394  auto mucombNrActiveEVs = Monitored::Scalar("NrActiveEVs", -9999.);
395  auto monitorIt = Monitored::Group(m_monTool, mucombNrAllEVs, mucombNrActiveEVs);
396  if ( numMuon == 0) {
397  ATH_MSG_DEBUG( "No positive previous hypo decision. Not need overlap removal." );
398  mucombNrActiveEVs = numMuon;
399  mucombNrAllEVs = numMuon;
400  return StatusCode::SUCCESS;
401  }
402  else if ( numMuon == 1 ) {
403  ATH_MSG_DEBUG("Number of muon event = " << numMuon );
404  ATH_MSG_DEBUG("no overlap Removal necessary. exitting with all EventViews active." );
405  mucombNrActiveEVs = numMuon;
406  mucombNrAllEVs = numMuon;
407  return StatusCode::SUCCESS;
408  } else {
409  ATH_MSG_DEBUG("Number of muon event = " << numMuon );
410  mucombNrAllEVs = numMuon;
412  return StatusCode::SUCCESS;
413  }
414 
415  return StatusCode::SUCCESS;
416 }
417 
418 // --------------------------------------------------------------------------------
419 // --------------------------------------------------------------------------------
420 
421 StatusCode TrigmuCombHypoTool::checkOverlap(std::vector<TrigmuCombHypoTool::CombinedMuonInfo*>& input) const {
422 
423  size_t numMuon = input.size();
424  unsigned int i,j;
425  std::vector<unsigned int> mucombResult;
426 
427  bool errorWhenIdentifyingOverlap = false;
428 
429  for(i=0; i<numMuon; i++) {mucombResult.emplace_back(i); }
430  for(i=0; i<numMuon-1; i++){
431  for(j=i+1; j<numMuon; j++){
432  ATH_MSG_DEBUG("++ i=" << i << " vs j=" << j);
433  bool overlapped = isOverlap((*input[i]).muComb, (*input[j]).muComb);
434  if( ! overlapped ){ // judged as different
435  ATH_MSG_DEBUG(" judged as: differenr objects");
436  if( mucombResult[i] == mucombResult[j] ) { // but marked as same by someone
437  ATH_MSG_DEBUG( "inconsistentency in muComb overlap removal for more than two objects" );
438  ATH_MSG_DEBUG( "two objects are judged as different but both were already marked as identical by someone else as: " );
439  ATH_MSG_DEBUG( "i/j/result[i]/result[j]=" << i << " / " << j << " / " << mucombResult[i] << " / " << mucombResult[j] );
440  auto mucombError = Monitored::Scalar("MucombError", -9999.);
441  auto monitorIt = Monitored::Group(m_monTool, mucombError);
443  errorWhenIdentifyingOverlap = true;
444  }
445  }
446  else{ // judged as overlap
447  if( (mucombResult[j] != j && mucombResult[i] != mucombResult[j]) || (mucombResult[j] == j && mucombResult[i] != i) ){
448  ATH_MSG_DEBUG( "inconsistentency in muComb based overlap removal for more than two objects" );
449  ATH_MSG_DEBUG( "two objects are judged as overlap but only either was already marked as overlap to someone else: " );
450  ATH_MSG_DEBUG( "i/j/result[i]/result[j]=" << i << " / " << j << " / " << mucombResult[i] << " / " << mucombResult[j] );
451  auto mucombError = Monitored::Scalar("MucombError", -9999.);
452  auto monitorIt = Monitored::Group(m_monTool, mucombError);
454  errorWhenIdentifyingOverlap = true;
455  }
456  ATH_MSG_DEBUG(" judged as: overlapped objects");
457  if( mucombResult[i] == i ) {
458  ATH_MSG_DEBUG( " i is not yet marked as overlap. so, it is a newly found overlap" );
459  ATH_MSG_DEBUG( " -> marking mucombResult[j] as i..." );
460  mucombResult[j] = i;
461  } else {
462  ATH_MSG_DEBUG( " both i/j already marked as overlap by: mucombResult[i]=" << mucombResult[i] );
463  ATH_MSG_DEBUG( " -> do nothing..." );
464  }
465  }
466  }
467  }
468 
469  if( errorWhenIdentifyingOverlap ) {
470  ATH_MSG_WARNING( "error when resolving overlap. exitting with all EVs active..." );
471  auto mucombNrActiveEVs = Monitored::Scalar("NrActiveEVs", -9999.);
472  auto monitorIt = Monitored::Group(m_monTool, mucombNrActiveEVs);
473  mucombNrActiveEVs = numMuon;
474  // for(i=0; i<numMuon; i++) TrigCompositeUtils::addDecisionID( m_decisionId, toolInput[i].decision );
475  return StatusCode::SUCCESS;
476  }
477 
478  unsigned int n_uniqueMuon = 0;
479  for(i=0; i<numMuon; i++) {
480  ATH_MSG_DEBUG( "muComb based results: i=" << i << ": ");
481  if( mucombResult[i] != i ) { ATH_MSG_DEBUG( " overlap to j=" << mucombResult[i] ); }
482  else {
483  n_uniqueMuon++;
484  ATH_MSG_DEBUG( " unique" );
485  }
486  }
487 
488  ATH_MSG_DEBUG( "nr of unique Muons after muComb-based removal=" << n_uniqueMuon );
489 
490  if( numMuon != n_uniqueMuon ){
491  ATH_CHECK(chooseBestMuon(input, mucombResult));
492  } else {
493  ATH_MSG_DEBUG( "no overlap identified. exitting with all EventViews active" );
494  auto mucombNrActiveEVs = Monitored::Scalar("NrActiveEVs", -9999.);
495  auto monitorIt = Monitored::Group(m_monTool, mucombNrActiveEVs);
496  mucombNrActiveEVs = n_uniqueMuon;
497  }
498 
499  return StatusCode::SUCCESS;
500 }
501 
502 // --------------------------------------------------------------------------------
503 // --------------------------------------------------------------------------------
504 
506  const xAOD::L2CombinedMuon *combMf2) const
507 {
508 
509  auto mucombDR = Monitored::Scalar("DR", -9999.);
510  auto mucombMass = Monitored::Scalar("Mass", -9999.);
511  auto mucombDRLog10 = Monitored::Scalar("DRLog10", -9999.);
512  auto mucombMassLog10 = Monitored::Scalar("MassLog10", -9999.);
513 
514  auto monitorIt = Monitored::Group(m_monTool, mucombDR, mucombMass, mucombDRLog10, mucombMassLog10);
515 
516 
517  ATH_MSG_DEBUG( " ...mF1: pt/eta/phi=" << combMf1->pt()/Gaudi::Units::GeV << " / " << combMf1->eta() << " / " << combMf1->phi() );
518  ATH_MSG_DEBUG( " ...mF2: pt/eta/phi=" << combMf2->pt()/Gaudi::Units::GeV << " / " << combMf2->eta() << " / " << combMf2->phi() );
519 
520  // if dR or invMass is necessary but (eta,phi) info is not avaiable
521  // (i.e. eta,phi=0,0; rec failed)
522  const double ZERO_LIMIT_FOR_ETAPHI = 1e-4;
523  if( (fabs(combMf1->eta()) <ZERO_LIMIT_FOR_ETAPHI && fabs(combMf1->phi()) < ZERO_LIMIT_FOR_ETAPHI) ||
524  (fabs(combMf2->eta()) <ZERO_LIMIT_FOR_ETAPHI && fabs(combMf2->phi()) < ZERO_LIMIT_FOR_ETAPHI) ) {
525  ATH_MSG_DEBUG( " ...-> (eta,phi) info not available (rec at (eta,phi)=(0,0))" );
526  if( m_requireDR || m_requireMass ) {
527  ATH_MSG_DEBUG( " ...-> but dR of invMass check is required. cannot judge overlap -> return with false" );
528  return false;
529  }
530  }
531 
532  // if charge or invMass is necessary but charge(=pT) info is not avaiable
533  const double ZERO_LIMIT_FOR_PT = 1e-4;
534  if( (fabs(combMf1->pt()) <ZERO_LIMIT_FOR_PT) || (fabs(combMf2->pt()) < ZERO_LIMIT_FOR_PT) ) {
535  ATH_MSG_DEBUG( " ...-> pT info not available (rec at pT=0)" );
537  ATH_MSG_DEBUG( " ...-> but same sign or invMass check is required. cannot judge overlap -> return with false" );
538  return false;
539  }
540  }
541 
542  // determine etabin and thresholds
543  double absEta = (fabs(combMf1->pt()) > fabs(combMf2->pt())) ? fabs(combMf1->eta()) : fabs(combMf2->eta());
544  unsigned int iThres = 0;
545  for(unsigned int i=0; i<(m_etaBins.size()-1); i++) {
546  if ( m_etaBins[i] <= absEta && absEta < m_etaBins[i+1] ) iThres = i;
547  }
548  double dRThres = m_requireDR ? m_dRThres[iThres] : 0.;
549  double dRbyMFThres = m_requireMufastDR ? m_mufastDRThres[iThres] : 0.;
550  double massThres = m_requireMass ? m_massThres[iThres] : 0.;
551  ATH_MSG_DEBUG( " ...iThres=" << iThres );
552  if(m_requireDR) ATH_MSG_DEBUG( " ...dR threshold=" << dRThres );
553  if(m_requireMufastDR) ATH_MSG_DEBUG( " ...dR(byMF) threshold=" << dRbyMFThres );
554  if(m_requireMass) ATH_MSG_DEBUG( " ...mass threshold=" << massThres );
555 
556  // same sign cut
557  bool sameSign = false;
558  if( m_requireSameSign ) {
559  sameSign = ((combMf1->pt()*combMf2->pt()) > 0) ? true : false;
560  ATH_MSG_DEBUG( " ...-> sameSign=" << sameSign );
561  }
562 
563  // dR cut
564  bool dRisClose = false;
565  double dr = dR(combMf1->eta(),combMf1->phi(),combMf2->eta(),combMf2->phi());
566 
567  mucombDR = dr;
568  const double monitor_limit = 1e-4;
569  double dr_mon = (dr>=monitor_limit) ? dr : monitor_limit;
570  mucombDRLog10 = log10(dr_mon);
571 
572  if( m_requireDR ) {
573  if( dr < dRThres ) dRisClose = true;
574  ATH_MSG_DEBUG( " ...-> dR=" << dr << " : dRisClose=" << dRisClose );
575  }
576 
577  // dR(by MF) cut
578  bool dRbyMFisClose = false;
579  if( m_requireMufastDR ) {
580  const xAOD::L2StandAloneMuon* mf1 = combMf1->muSATrack();
581  const xAOD::L2StandAloneMuon* mf2 = combMf2->muSATrack();
582  if( mf1 == 0 || mf2 == 0 ) {
583  ATH_MSG_DEBUG( "mF link from combinedMF broken" );
584  ATH_MSG_DEBUG( " ...-> mF dR is required but mF link broken. cannot judge overlap -> return with false" );
585  return false;
586  }
587  else {
588  // here, we do not check (eta,phi) of mF is not (0,0)
589  // (i.e. we apply muComb based cut even if muFast rec is failed)
590  double dRByMF = dR(mf1->etaMS(),mf1->phiMS(),mf2->etaMS(),mf2->phiMS());
591  if( dRByMF < dRbyMFThres ) dRbyMFisClose = true;
592  ATH_MSG_DEBUG( " ...-> dR(by MF)=" << dRByMF << " : dRbyMFisClose=" << dRbyMFisClose );
593  }
594  }
595 
596  // mass cut
597  const double TRACK_MASS = 0; // just assume zero mass
598  bool massIsClose = false;
599  double mass = invMass(TRACK_MASS,combMf1->pt()/Gaudi::Units::GeV,combMf1->eta(),combMf1->phi(),TRACK_MASS,combMf2->pt()/Gaudi::Units::GeV,combMf2->eta(),combMf2->phi());
600 
601  mucombMass = mass;
602  double mass_mon = (mass>=monitor_limit) ? mass : monitor_limit;
603  mucombMassLog10 = log10(mass_mon);
604 
605  if( m_requireMass ) {
606  if( mass < massThres ) massIsClose = true;
607  ATH_MSG_DEBUG( " ...-> mass=" << mass << " : massIsClose=" << massIsClose );
608  }
609 
610  // total judge
611  bool overlap = false;
612  if( ((m_requireSameSign && sameSign) || (! m_requireSameSign)) &&
613  ((m_requireDR && dRisClose) || (! m_requireDR)) &&
614  ((m_requireMufastDR && dRbyMFisClose) || (! m_requireMufastDR)) &&
615  ((m_requireMass && massIsClose) || (! m_requireMass)) ) {
616  overlap = true;
617  }
618 
619  ATH_MSG_DEBUG( " ...=> isOverlap=" << overlap );
620 
621  return overlap;
622 
623 }
624 
625 // --------------------------------------------------------------------------------
626 // --------------------------------------------------------------------------------
627 
628 double TrigmuCombHypoTool::dR(double eta1, double phi1, double eta2, double phi2) const
629 {
630  const double deta = eta1 - eta2;
631  const double dphi = CxxUtils::deltaPhi(phi1, phi2);
632  return std::sqrt(deta*deta + dphi*dphi);
633 }
634 
635 // --------------------------------------------------------------------------------
636 // --------------------------------------------------------------------------------
637 
638 double TrigmuCombHypoTool::invMass(double m1, double pt1, double eta1, double phi1,
639  double m2, double pt2, double eta2, double phi2) const
640 {
641  const double ZERO_LIMIT = 1e-12;
642 
643  double theta1 = 2*atan2((double)exp(-eta1),1.);
644  double theta2 = 2*atan2((double)exp(-eta2),1.);
645 
646  double fpt1 = fabs(pt1);
647  double fpt2 = fabs(pt2);
648 
649  double px1 = fpt1*cos(phi1);
650  double py1 = fpt1*sin(phi1);
651  double pz1 = fpt1/tan(theta1);
652  double e1 = sqrt(px1*px1+py1*py1+pz1*pz1+m1*m1);
653 
654  double px2 = fpt2*cos(phi2);
655  double py2 = fpt2*sin(phi2);
656  double pz2 = fpt2/tan(theta2);
657  double e2 = sqrt(px2*px2+py2*py2+pz2*pz2+m2*m2);
658 
659  double pxsum = px1 + px2;
660  double pysum = py1 + py2;
661  double pzsum = pz1 + pz2;
662  double esum = e1 + e2;
663 
664  double mass = 0;
665  double mass2 = esum*esum - pxsum*pxsum - pysum*pysum - pzsum*pzsum;
666  if( mass2 > ZERO_LIMIT ) mass = sqrt(mass2);
667 
668  return mass;
669 }
670 
671 // --------------------------------------------------------------------------------
672 // --------------------------------------------------------------------------------
673 
674 StatusCode TrigmuCombHypoTool::chooseBestMuon(std::vector<TrigmuCombHypoTool::CombinedMuonInfo*>& input, const std::vector<unsigned int>& mucombResult) const
675 {
676  const double ZERO_LIMIT = 1e-4;
677  size_t numMuon = input.size();
678  unsigned int i,j,k;
679 
680  auto mucombNrActiveEVs = Monitored::Scalar("NrActiveEVs", -9999.);
681  auto mucombNrOverlapped = Monitored::Scalar("NrOverlapped", 0);
682  auto mucombOverlappedEta = Monitored::Scalar("OverlappedEta", -9999.);
683  auto mucombOverlappedPhi = Monitored::Scalar("OverlappedPhi", -9999.);
684  auto mucombOverlappedPt = Monitored::Scalar("OverlappedPt", -9999.);
685 
686  auto monitorIt = Monitored::Group(m_monTool, mucombNrActiveEVs, mucombNrOverlapped,
687  mucombOverlappedPt, mucombOverlappedEta, mucombOverlappedPhi);
688 
689  ATH_MSG_DEBUG( "--- choose best among overlaps & disable EVs (muComb based) ---" );
690  for(i=0; i<numMuon; i++) {
691  ATH_MSG_DEBUG( "++ i=" << i << ": result=" << mucombResult[i] );
692  if( mucombResult[i] != i ) {
693  ATH_MSG_DEBUG( " overlap to some one. already the best one was chosen. skip." );
694  continue;
695  }
696  std::vector<unsigned int> others;
697  for(j=0; j<numMuon; j++) {
698  if( mucombResult[j] == mucombResult[i] ) others.emplace_back(j);
699  }
700  if( others.size() == 1 ) {
701  ATH_MSG_DEBUG( " unique object. keep it active." );
702  continue;
703  }
704  else {// must choose one best
705  ATH_MSG_DEBUG( " overlapped objects among: " << others );
706  unsigned int best_ev = 0;
707  float maxPtCombMf = 0;
708  float mindRRoadRoI = 999;
709  for(k=0; k<others.size(); k++) {
710  j=others[k];
711 
712  float ptCombMf = 0.;
713  const xAOD::L2CombinedMuon* combMf = (*input[j]).muComb;
714  ptCombMf = fabs(combMf->pt()/Gaudi::Units::GeV);
715 
716  const xAOD::L2StandAloneMuon* mf = (*input[j]).muComb->muSATrack();
717  const float roadPhiP = atan2(mf->dirPhiMS(),1.);
718  const float roadPhiM = atan2(-1*mf->dirPhiMS(),-1.);
719  const float roadPhi = (std::abs(CxxUtils::deltaPhi(roadPhiP, mf->roiPhi())) < std::abs(CxxUtils::deltaPhi(roadPhiM, mf->roiPhi())))? roadPhiP : roadPhiM;
720  float roadAw = 0;
721  if(std::abs(mf->roiEta()) < 1.05) { // barrel
722  if( std::abs(mf->roadAw(1,0)) > ZERO_LIMIT ) roadAw = mf->roadAw(1,0);
723  else if( std::abs(mf->roadAw(2,0)) > ZERO_LIMIT ) roadAw = mf->roadAw(2,0);
724  else if( std::abs(mf->roadAw(0,0)) > ZERO_LIMIT ) roadAw = mf->roadAw(0,0);
725  }
726  else { // endcap
727  if( std::abs(mf->roadAw(4,0)) > ZERO_LIMIT ) roadAw = mf->roadAw(4,0);
728  else if( std::abs(mf->roadAw(5,0)) > ZERO_LIMIT ) roadAw = mf->roadAw(5,0);
729  else if( std::abs(mf->roadAw(3,0)) > ZERO_LIMIT ) roadAw = mf->roadAw(3,0);
730  }
731  float roadEta = 999;
732  if(std::abs(roadAw) > ZERO_LIMIT)
733  roadEta = -std::log(std::tan(0.5*std::atan(std::abs(roadAw))));
734  if(roadAw < 0) roadEta *= -1.;
735  const double dRRoadRoI = dR(roadEta, roadPhi, mf->roiEta(), mf->roiPhi());
736  ATH_MSG_DEBUG(" j="<< j << " , ptCombMf=" << ptCombMf << ", dRRoadRoI=" << dRRoadRoI);
737 
738  if( (ptCombMf > maxPtCombMf) ||
739  (std::abs(ptCombMf - maxPtCombMf) < ZERO_LIMIT &&
740  dRRoadRoI < mindRRoadRoI) ) {
741  maxPtCombMf = ptCombMf;
742  mindRRoadRoI = dRRoadRoI;
743  best_ev = j;
744  }
745  }
746  ATH_MSG_DEBUG( " best is: best_ev/maxPtCombMf=" << best_ev << " / " << maxPtCombMf );
747 
748  for(k=0; k<others.size(); k++) {
749  j=others[k];
750  if( j != best_ev ) {
751  ATH_MSG_DEBUG( " EventView( j=" << j << " ) is not active" );
752 
753  (*input[j]).isOR.insert(m_decisionId.numeric());
754 
755  // monitoring
756  const xAOD::L2CombinedMuon* CombMf = (*input[j]).muComb;
757  ++mucombNrOverlapped;
758  mucombOverlappedPt = CombMf->pt()* CombMf->charge() /Gaudi::Units::GeV;
759  mucombOverlappedEta = CombMf->eta();
760  mucombOverlappedPhi = CombMf->phi();
761  }
762  if( j == best_ev ){
763  ATH_MSG_DEBUG( " EventView( j=" << j << " ) is best one" );
764  }
765  }
766  }
767  }
768  mucombNrActiveEVs = numMuon - mucombNrOverlapped;
769 
770  return StatusCode::SUCCESS;
771 }
xAOD::L2CombinedMuon_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TrigmuCombHypoTool::CombinedMuonInfo
Definition: TrigmuCombHypoTool.h:39
TrigmuCombHypoTool::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: TrigmuCombHypoTool.h:82
TrigmuCombHypoTool::m_dRThres
Gaudi::Property< std::vector< float > > m_dRThres
Definition: TrigmuCombHypoTool.h:146
TrigmuCombHypoTool::checkOverlap
StatusCode checkOverlap(std::vector< TrigmuCombHypoTool::CombinedMuonInfo * > &input) const
Definition: TrigmuCombHypoTool.cxx:421
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
muComb
Main LVL2 Algorithm.
Definition: muComb.h:54
TrigmuCombHypoTool::multiplicitySelection
StatusCode multiplicitySelection(std::vector< TrigmuCombHypoTool::CombinedMuonInfo > &input) const
Definition: TrigmuCombHypoTool.cxx:290
get_generator_info.result
result
Definition: get_generator_info.py:21
python.SystemOfUnits.m2
int m2
Definition: SystemOfUnits.py:92
ParticleGun_SamplingFraction.eta2
eta2
Definition: ParticleGun_SamplingFraction.py:96
xAOD::L2StandAloneMuon_v2::etaMS
float etaMS() const
Get the eta at muon spectrometer.
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
HLT::Identifier::numeric
TrigCompositeUtils::DecisionID numeric() const
numeric ID
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:47
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
TrigmuCombHypoTool::m_d0min
Gaudi::Property< float > m_d0min
Definition: TrigmuCombHypoTool.h:155
egammaEnergyPositionAllSamples::e1
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
xAOD::L2StandAloneMuon_v2
Class describing standalone muons reconstructed in the LVL2 trigger.
Definition: L2StandAloneMuon_v2.h:36
index
Definition: index.py:1
Trig::MatchingStrategy::Strategy
Strategy
Definition: MatchingImplementation.h:26
TrigmuCombHypoTool::m_applyOR
Gaudi::Property< bool > m_applyOR
Definition: TrigmuCombHypoTool.h:128
TrigCompositeUtils::addDecisionID
void addDecisionID(DecisionID id, Decision *d)
Appends the decision (given as ID) to the decision object.
Definition: TrigCompositeUtilsRoot.cxx:61
TrigmuCombHypoTool::invMass
double invMass(double m1, double pt1, double eta1, double phi1, double m2, double pt2, double eta2, double phi2) const
Definition: TrigmuCombHypoTool.cxx:638
xAOD::L2CombinedMuon_v1::charge
float charge() const
get seeding muon charge
TrigmuCombHypoTool::m_strategyDependentPtCuts
Gaudi::Property< std::vector< double > > m_strategyDependentPtCuts
Definition: TrigmuCombHypoTool.h:116
TrigmuCombHypoTool::m_maxPtToApplyPik
Gaudi::Property< double > m_maxPtToApplyPik
Definition: TrigmuCombHypoTool.h:97
xAOD::eta1
setEt setPhi setE277 setWeta2 eta1
Definition: TrigEMCluster_v1.cxx:41
TrigmuCombHypoTool.h
xAOD::L2StandAloneMuon_v2::phiMS
float phiMS() const
Get the phi at muon spectrometer.
TrigmuCombHypoTool::m_acceptAll
Gaudi::Property< bool > m_acceptAll
Definition: TrigmuCombHypoTool.h:90
TrigmuCombHypoTool::m_strategydependent
Gaudi::Property< bool > m_strategydependent
Definition: TrigmuCombHypoTool.h:113
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
TrigmuCombHypoTool::m_decisionPerCluster
Gaudi::Property< bool > m_decisionPerCluster
Definition: TrigmuCombHypoTool.h:123
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
TrigmuCombHypoTool::chooseBestMuon
StatusCode chooseBestMuon(std::vector< TrigmuCombHypoTool::CombinedMuonInfo * > &input, const std::vector< unsigned int > &mucombResult) const
Definition: TrigmuCombHypoTool.cxx:674
empty
bool empty(TH1 *h)
Definition: computils.cxx:295
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
TrigmuCombHypoTool::inclusiveSelection
StatusCode inclusiveSelection(std::vector< TrigmuCombHypoTool::CombinedMuonInfo > &input) const
Definition: TrigmuCombHypoTool.cxx:270
xAOD::L2CombinedMuon_v1
Class describing combined muon reconstructed in the LVL2 trigger.
Definition: L2CombinedMuon_v1.h:41
DQPostProcessTest.mf
mf
Definition: DQPostProcessTest.py:19
TrigmuCombHypoTool::TrigmuCombHypoTool
TrigmuCombHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: TrigmuCombHypoTool.cxx:18
xAOD::L2CombinedMuon_v1::muSATrack
const xAOD::L2StandAloneMuon * muSATrack() const
Get the SA muon as a bare pointer.
TrigmuCombHypoTool::m_ptBins
Gaudi::Property< std::vector< std::vector< double > > > m_ptBins
Definition: TrigmuCombHypoTool.h:84
HLT::Index1DVec
std::vector< size_t > Index1DVec
Unique combinations for case when one can not repeat the index (i.e.
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:139
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
TrigmuCombHypoTool::~TrigmuCombHypoTool
virtual ~TrigmuCombHypoTool()
Definition: TrigmuCombHypoTool.cxx:26
TrigCompositeUtils.h
xAOD::L2CombinedMuon_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
TrigmuCombHypoTool::m_etaBins
Gaudi::Property< std::vector< float > > m_etaBins
Definition: TrigmuCombHypoTool.h:143
python.changerun.m1
m1
Definition: changerun.py:32
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigmuCombHypoTool::m_bins
std::vector< size_t > m_bins
Definition: TrigmuCombHypoTool.h:159
HLT
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
Definition: HLTResultReader.h:26
lumiFormat.i
int i
Definition: lumiFormat.py:85
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
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
xAOD::L2CombinedMuon_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
TrigmuCombHypoTool::m_massThres
Gaudi::Property< std::vector< float > > m_massThres
Definition: TrigmuCombHypoTool.h:152
Monitored.h
Header file to be included by clients of the Monitored infrastructure.
HLT::elementsInUniqueCombinations
void elementsInUniqueCombinations(const Index2DVec &indices, std::set< size_t > &participants, std::function< bool(const Index1DVec &)> &&filter)
Definition: Combinators.cxx:154
ZERO_LIMIT
const float ZERO_LIMIT
Definition: VP1TriggerHandleL2.cxx:37
TrigmuCombHypoTool::initialize
virtual StatusCode initialize() override
Definition: TrigmuCombHypoTool.cxx:32
TrigmuCombHypoTool::decideOnSingleObject
bool decideOnSingleObject(TrigmuCombHypoTool::CombinedMuonInfo &input, size_t cutIndex) const
Definition: TrigmuCombHypoTool.cxx:105
TrigmuCombHypoTool::m_numMuonThreshold
Gaudi::Property< size_t > m_numMuonThreshold
Definition: TrigmuCombHypoTool.h:103
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
threshold
Definition: chainparser.cxx:74
CxxUtils::deltaPhi
T deltaPhi(T phiA, T phiB)
Return difference phiA - phiB in range [-pi, pi].
Definition: phihelper.h:42
phihelper.h
Helper for azimuthal angle calculations.
TrigmuCombHypoTool::m_requireMass
Gaudi::Property< bool > m_requireMass
Definition: TrigmuCombHypoTool.h:137
TrigmuCombHypoTool::m_decisionId
HLT::Identifier m_decisionId
Definition: TrigmuCombHypoTool.h:80
TrigmuCombHypoTool::isOverlap
bool isOverlap(const xAOD::L2CombinedMuon *mf1, const xAOD::L2CombinedMuon *mf2) const
Definition: TrigmuCombHypoTool.cxx:505
TrigmuCombHypoTool::m_chi2MaxID
Gaudi::Property< double > m_chi2MaxID
Definition: TrigmuCombHypoTool.h:100
Combinators.h
egammaEnergyPositionAllSamples::e2
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigmuCombHypoTool::m_requireMufastDR
Gaudi::Property< bool > m_requireMufastDR
Definition: TrigmuCombHypoTool.h:134
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
TrigmuCombHypoToolConsts::errorCode_inconsistent_overlap1
const int errorCode_inconsistent_overlap1
Definition: TrigmuCombHypoTool.h:23
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
TauGNNUtils::Variables::absEta
bool absEta(const xAOD::TauJet &tau, double &out)
Definition: TauGNNUtils.cxx:234
TrigmuCombHypoTool::m_requireDR
Gaudi::Property< bool > m_requireDR
Definition: TrigmuCombHypoTool.h:131
TrigCompositeUtils
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:19
HLT::Index2DVec
std::vector< Index1DVec > Index2DVec
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:140
TrigmuCombHypoTool::m_ptThresholds
Gaudi::Property< std::vector< std::vector< double > > > m_ptThresholds
Definition: TrigmuCombHypoTool.h:87
TrigmuCombHypoTool::decide
virtual StatusCode decide(std::vector< TrigmuCombHypoTool::CombinedMuonInfo > &toolInput) const
Definition: TrigmuCombHypoTool.cxx:246
TrigmuCombHypoTool::dR
double dR(double eta1, double phi1, double eta2, double phi2) const
Definition: TrigmuCombHypoTool.cxx:628
TrigmuCombHypoTool::applyOverlapRemoval
StatusCode applyOverlapRemoval(std::vector< TrigmuCombHypoTool::CombinedMuonInfo > &toolInput) const
Definition: TrigmuCombHypoTool.cxx:359
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
AthAlgTool
Definition: AthAlgTool.h:26
TrigmuCombHypoTool::m_requireSameSign
Gaudi::Property< bool > m_requireSameSign
Definition: TrigmuCombHypoTool.h:140
TrigmuCombHypoTool::m_mufastDRThres
Gaudi::Property< std::vector< float > > m_mufastDRThres
Definition: TrigmuCombHypoTool.h:149
TrigmuCombHypoTool::m_pikCuts
Gaudi::Property< bool > m_pikCuts
Definition: TrigmuCombHypoTool.h:94
fitman.k
k
Definition: fitman.py:528
Identifier
Definition: IdentifierFieldParser.cxx:14
TrigmuCombHypoToolConsts::errorCode_inconsistent_overlap2
const int errorCode_inconsistent_overlap2
Definition: TrigmuCombHypoTool.h:24