5 #include "GaudiKernel/SystemOfUnits.h"
19 const std::string &
name,
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) {
68 return StatusCode::FAILURE;
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");
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();
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;
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;
286 return StatusCode::SUCCESS;
294 for (
size_t cutIndex=0; cutIndex <
m_ptBins.size(); ++cutIndex ) {
295 size_t elementIndex{ 0 };
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 ) {
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)
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;
522 const double ZERO_LIMIT_FOR_ETAPHI = 1
e-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 = 1
e-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;
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 = 1
e-4;
569 double dr_mon = (
dr>=monitor_limit) ?
dr : monitor_limit;
570 mucombDRLog10 = log10(dr_mon);
573 if(
dr < dRThres ) dRisClose =
true;
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;
602 double mass_mon = (
mass>=monitor_limit) ?
mass : monitor_limit;
603 mucombMassLog10 = log10(mass_mon);
606 if(
mass < massThres ) massIsClose =
true;
611 bool overlap =
false;
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++) {
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++) {
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);
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;
759 mucombOverlappedEta = CombMf->
eta();
760 mucombOverlappedPhi = CombMf->
phi();
768 mucombNrActiveEVs = numMuon - mucombNrOverlapped;
770 return StatusCode::SUCCESS;