5#include "GaudiKernel/SystemOfUnits.h"
19 const std::string & name,
20 const IInterface* parent )
41 for (
size_t j=0; j<
m_ptBins.size(); ++j) {
45 return StatusCode::FAILURE;
48 for (std::vector<float>::size_type i = 0; i <
m_bins[j]; ++i) {
51 <<
" with Pt Threshold of " << (
m_ptThresholds[j][i]) / Gaudi::Units::GeV <<
" GeV");
68 return StatusCode::FAILURE;
70 for(
unsigned int i=0; i<
m_dRThres.size(); i++) {
79 return StatusCode::FAILURE;
90 return StatusCode::FAILURE;
102 return StatusCode::SUCCESS;
118 idEta, idPhi, idZ0, idA0);
127 ATH_MSG_DEBUG(
"Accept property is set: taking all the events");
131 ATH_MSG_DEBUG(
"Accept property not set: applying selection!");
136 auto pMuon = input.muComb;
139 ATH_MSG_ERROR(
"Retrieval of xAOD::L2CombinedMuon from vector failed");
143 auto ptValue = pMuon->pt() * pMuon->charge() / Gaudi::Units::GeV;
146 if (pMuon->pt() == 0) {
147 ATH_MSG_DEBUG(
"L2CombinedMuon pt == 0, empty container -> rejected");
154 idEta = pMuon->eta();
155 idPhi = pMuon->phi();
156 int usealgo = pMuon->strategy();
157 float ptresComb = pMuon->sigmaPt() / Gaudi::Units::GeV;
159 ATH_MSG_DEBUG(
"combined muon pt (GeV)/ sigma_pt (GeV)/ eta / phi / usedalgo: "
160 << fexPt <<
" (GeV) / " << ptresComb <<
" (GeV) / " << idEta <<
" / " << idPhi
161 <<
" / " << usealgo);
164 if (!pMuon->muSATrack()) {
165 ATH_MSG_DEBUG(
"L2CombinedMuon has no valid xaOD::L2StandaloneMuon -> rejected");
171 if (!pMuon->idTrack()) {
172 ATH_MSG_DEBUG(
"L2CombinedMuon has no valid xAOD:TrackParticle IDtrack -> rejected");
177 idA0 = pMuon->idTrack()->d0();
178 idZ0 = pMuon->idTrack()->z0();
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) {
193 if (pMuon->idTrack()->chiSquared() >
m_chi2MaxID) pikCut =
false;
198 if (std::abs(fexPt) <= (
threshold / Gaudi::Units::GeV)) stdCut =
false;
200 <<
" GeV and threshold cut is " <<
threshold / Gaudi::Units::GeV
201 <<
" GeV and pik_cut is " << (pikCut ?
"true" :
"false"));
206 if (usealgo >= 1 && usealgo <= 4) {
208 if (std::abs(fexPt) <= std::abs(tmpcut)) sdpCut =
false;
209 if (tmpcut < 0) stdCut =
true;
211 <<
" and threshold for strategy dependent cut is " << tmpcut
212 <<
" GeV and strategy dependent / std cuts are " << (sdpCut ?
"true" :
"false") <<
" / " << (stdCut ?
"true" :
"false"));
214 ATH_MSG_DEBUG(
"usealgo out of range, is: " << usealgo <<
" while should be in [1, 4]");
223 result = stdCut && pikCut && sdpCut && d0Cut;
225 if (
result) ptFL = -9999.;
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"));
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"));
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.");
252 if ( numTrigger == 1 ) {
266 return StatusCode::SUCCESS;
272 for (
auto& i: input) {
286 return StatusCode::SUCCESS;
294 for (
size_t cutIndex=0; cutIndex <
m_ptBins.size(); ++cutIndex ) {
295 size_t elementIndex{ 0 };
296 for (
auto& i: input ) {
308 passingSelection[cutIndex].push_back( elementIndex );
319 if ( passingSelection[cutIndex].
empty() ) {
320 ATH_MSG_DEBUG(
"No object passed selection " << cutIndex <<
" rejecting" );
321 return StatusCode::SUCCESS;
325 std::set<size_t> passingIndices;
328 std::set<const xAOD::L2CombinedMuon*> setOfClusters;
329 for (
auto index: comb ) {
332 return setOfClusters.size() == comb.size();
341 if ( passingIndices.empty() ) {
343 return StatusCode::SUCCESS;
346 for (
auto idx: passingIndices ) {
348 <<
" with pT = " << input[idx].
muComb->pt() <<
"GeV" );
352 return StatusCode::SUCCESS;
363 std::vector<TrigmuCombHypoTool::CombinedMuonInfo*> input;
368 float pTthreshold = 0;
369 std::vector<float> pTvec;
370 for (
auto& i: toolInput ) {
373 pTvec.emplace_back(i.muComb->pt());
377 std::sort(pTvec.begin(),pTvec.end(), std::greater<float>{});
381 for (
auto& i: toolInput ) {
384 if(i.muComb->pt() > pTthreshold)
385 input.emplace_back(&i);
391 size_t numMuon = input.size();
397 ATH_MSG_DEBUG(
"No positive previous hypo decision. Not need overlap removal." );
398 mucombNrActiveEVs = numMuon;
399 mucombNrAllEVs = numMuon;
400 return StatusCode::SUCCESS;
402 else if ( numMuon == 1 ) {
404 ATH_MSG_DEBUG(
"no overlap Removal necessary. exitting with all EventViews active." );
405 mucombNrActiveEVs = numMuon;
406 mucombNrAllEVs = numMuon;
407 return StatusCode::SUCCESS;
410 mucombNrAllEVs = numMuon;
412 return StatusCode::SUCCESS;
415 return StatusCode::SUCCESS;
423 size_t numMuon = input.size();
425 std::vector<unsigned int> mucombResult;
427 bool errorWhenIdentifyingOverlap =
false;
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++){
436 if( mucombResult[i] == mucombResult[j] ) {
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] );
443 errorWhenIdentifyingOverlap =
true;
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] );
454 errorWhenIdentifyingOverlap =
true;
457 if( mucombResult[i] == i ) {
458 ATH_MSG_DEBUG(
" i is not yet marked as overlap. so, it is a newly found overlap" );
462 ATH_MSG_DEBUG(
" both i/j already marked as overlap by: mucombResult[i]=" << mucombResult[i] );
469 if( errorWhenIdentifyingOverlap ) {
470 ATH_MSG_WARNING(
"error when resolving overlap. exitting with all EVs active..." );
473 mucombNrActiveEVs = numMuon;
475 return StatusCode::SUCCESS;
478 unsigned int n_uniqueMuon = 0;
479 for(i=0; i<numMuon; i++) {
481 if( mucombResult[i] != i ) {
ATH_MSG_DEBUG(
" overlap to j=" << mucombResult[i] ); }
488 ATH_MSG_DEBUG(
"nr of unique Muons after muComb-based removal=" << n_uniqueMuon );
490 if( numMuon != n_uniqueMuon ){
493 ATH_MSG_DEBUG(
"no overlap identified. exitting with all EventViews active" );
496 mucombNrActiveEVs = n_uniqueMuon;
499 return StatusCode::SUCCESS;
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() );
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))" );
527 ATH_MSG_DEBUG(
" ...-> but dR of invMass check is required. cannot judge overlap -> return with false" );
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" );
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++) {
557 bool sameSign =
false;
559 sameSign = ((combMf1->
pt()*combMf2->
pt()) > 0) ? true :
false;
564 bool dRisClose =
false;
565 double dr =
dR(combMf1->
eta(),combMf1->
phi(),combMf2->
eta(),combMf2->
phi());
568 const double monitor_limit = 1e-4;
569 double dr_mon = (dr>=monitor_limit) ? dr : monitor_limit;
570 mucombDRLog10 = log10(dr_mon);
573 if( dr < dRThres ) dRisClose =
true;
574 ATH_MSG_DEBUG(
" ...-> dR=" << dr <<
" : dRisClose=" << dRisClose );
578 bool dRbyMFisClose =
false;
582 if( mf1 == 0 || mf2 == 0 ) {
584 ATH_MSG_DEBUG(
" ...-> mF dR is required but mF link broken. cannot judge overlap -> return with false" );
591 if( dRByMF < dRbyMFThres ) dRbyMFisClose =
true;
592 ATH_MSG_DEBUG(
" ...-> dR(by MF)=" << dRByMF <<
" : dRbyMFisClose=" << dRbyMFisClose );
597 const double TRACK_MASS = 0;
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());
602 double mass_mon = (mass>=monitor_limit) ? mass : monitor_limit;
603 mucombMassLog10 = log10(mass_mon);
606 if( mass < massThres ) massIsClose =
true;
607 ATH_MSG_DEBUG(
" ...-> mass=" << mass <<
" : massIsClose=" << massIsClose );
611 bool overlap =
false;
630 const double deta = eta1 - eta2;
632 return std::sqrt(deta*deta + dphi*dphi);
639 double m2,
double pt2,
double eta2,
double phi2)
const
643 double theta1 = 2*atan2((
double)exp(-eta1),1.);
644 double theta2 = 2*atan2((
double)exp(-eta2),1.);
646 double fpt1 = fabs(pt1);
647 double fpt2 = fabs(pt2);
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);
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);
659 double pxsum = px1 + px2;
660 double pysum = py1 + py2;
661 double pzsum = pz1 + pz2;
662 double esum = e1 + e2;
665 double mass2 = esum*esum - pxsum*pxsum - pysum*pysum - pzsum*pzsum;
677 size_t numMuon = input.size();
687 mucombOverlappedPt, mucombOverlappedEta, mucombOverlappedPhi);
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." );
696 std::vector<unsigned int> others;
697 for(j=0; j<numMuon; j++) {
698 if( mucombResult[j] == mucombResult[i] ) others.emplace_back(j);
700 if( others.size() == 1 ) {
706 unsigned int best_ev = 0;
707 float maxPtCombMf = 0;
708 float mindRRoadRoI = 999;
709 for(k=0; k<others.size(); k++) {
714 ptCombMf = fabs(combMf->
pt()/Gaudi::Units::GeV);
717 const float roadPhiP = atan2(mf->dirPhiMS(),1.);
718 const float roadPhiM = atan2(-1*mf->dirPhiMS(),-1.);
721 if(std::abs(mf->roiEta()) < 1.05) {
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);
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);
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);
738 if( (ptCombMf > maxPtCombMf) ||
739 (std::abs(ptCombMf - maxPtCombMf) <
ZERO_LIMIT &&
740 dRRoadRoI < mindRRoadRoI) ) {
741 maxPtCombMf = ptCombMf;
742 mindRRoadRoI = dRRoadRoI;
746 ATH_MSG_DEBUG(
" best is: best_ev/maxPtCombMf=" << best_ev <<
" / " << maxPtCombMf );
748 for(k=0; k<others.size(); k++) {
751 ATH_MSG_DEBUG(
" EventView( j=" << j <<
" ) is not active" );
757 ++mucombNrOverlapped;
758 mucombOverlappedPt = CombMf->
pt()* CombMf->
charge() /Gaudi::Units::GeV;
759 mucombOverlappedEta = CombMf->
eta();
760 mucombOverlappedPhi = CombMf->
phi();
768 mucombNrActiveEVs = numMuon - mucombNrOverlapped;
770 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Header file to be included by clients of the Monitored infrastructure.
static const Attributes_t empty
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
float charge() const
get seeding muon charge
virtual double pt() const
The transverse momentum ( ) of the particle.
const xAOD::L2StandAloneMuon * muSATrack() const
Get the SA muon as a bare pointer.
float etaMS() const
Get the eta at muon spectrometer.
float phiMS() const
Get the phi at muon spectrometer.
T deltaPhi(T phiA, T phiB)
Return difference phiA - phiB in range [-pi, pi].
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
void elementsInUniqueCombinations(const Index2DVec &indices, std::set< size_t > &participants, const std::function< bool(const Index1DVec &)> &filter)
std::vector< Index1DVec > Index2DVec
std::vector< size_t > Index1DVec
Unique combinations for case when one can not repeat the index (i.e.
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
void addDecisionID(DecisionID id, Decision *d)
Appends the decision (given as ID) to the decision object.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
L2CombinedMuon_v1 L2CombinedMuon
Define the latest version of the muon CB class.
L2StandAloneMuon_v2 L2StandAloneMuon
Define the latest version of the muon SA class.
Helper for azimuthal angle calculations.