14 #include "CLHEP/Units/SystemOfUnits.h"
24 const IInterface*
p) :
26 m_trigDecisionTool(
"Trig::TrigDecisionTool/TrigDecisionTool"),
31 declareProperty(
"RequireGRL",
m_reqGRL =
true);
38 declareProperty(
"IncludeSingleMuonPreselection",
m_incSingleMuon =
true);
39 declareProperty(
"IncludeDoubleMuonPreselection",
m_incDoubleMuon =
false);
43 declareProperty(
"IncludeDoublePhotonPreselection",
m_incTwoPhotons =
true);
52 declareProperty(
"DefaultTrigger",
m_defaultTrigger =
"EF_g35_loose_g25_loose");
53 declareProperty(
"Triggers",
m_triggers = std::vector<std::string>());
54 declareProperty(
"MergedElectronTriggers",
m_mergedtriggers = std::vector<std::string>() );
63 declareProperty(
"MaxEta",
m_maxEta = 2.47);
87 if(m_trigDecisionTool.retrieve(DisableTool{!m_reqTrigger}).isFailure()) {
88 ATH_MSG_FATAL(
"Failed to retrieve tool: " << m_trigDecisionTool);
89 return StatusCode::FAILURE;
91 if (m_triggers.empty()) m_triggers.push_back(m_defaultTrigger);
95 if(m_incMergedElectronPhoton){
96 if( m_mergedCutTools.retrieve().isFailure() )
98 ATH_MSG_FATAL(
"Failed to retrieve tool: ElectronPhotonSelectorTools");
99 return StatusCode::FAILURE;
103 ATH_CHECK( m_eventInfoKey.initialize() );
112 return StatusCode::SUCCESS;
118 ATH_MSG_INFO(
"Processed " << m_n_tot <<
" events, " << m_n_pass <<
" events passed filter ");
125 if(m_incDoubleElectron)
126 ATH_MSG_INFO(
"2e :: " << m_n_passDoubleElectronPreselect);
127 if(m_incSingleElectron)
128 ATH_MSG_INFO(
"1y1e :: " << m_n_passSingleElectronPreselect);
130 ATH_MSG_INFO(
"1y1mu :: " << m_n_passSingleMuonPreselect);
132 ATH_MSG_INFO(
"1y2mu :: " << m_n_passSinglePhotonDoubleMuonPreselect);
133 if(m_incDoubleElectronPhoton)
134 ATH_MSG_INFO(
"1y2e :: " << m_n_passSinglePhotonDoubleElectronPreselect);
135 if(m_incMergedElectronPhoton)
136 ATH_MSG_INFO(
"1y1eMerge :: " << m_n_passSinglePhotonMergedElectronPreselect);
137 if(m_incHighPtElectronPhoton)
138 ATH_MSG_INFO(
"1y1e HiPt :: " << m_n_passHighPtPhotonMergedElectronPreselect);
139 if(m_incMergedElectron)
140 ATH_MSG_INFO(
"1eMerge :: " << m_n_passSingleMergedElectronPreselect);
153 return StatusCode::SUCCESS;
162 bool writeEvent(
false);
163 const EventContext& ctx = Gaudi::Hive::currentContext();
166 if (m_reqGRL && !SubcutGoodRunList() )
return false;
167 if (m_reqLArError && !SubcutLArError(*eventInfo) )
return false;
168 if (m_reqTrigger && !SubcutTrigger() )
return false;
170 const auto leadingPhotons = SubcutPreselect();
171 if (m_incTwoPhotons && !m_reqPreselection) writeEvent =
true;
174 if (m_incSingleElectron && SubcutOnePhotonOneElectron() ) writeEvent =
true;
175 if (m_incDoubleElectron && SubcutTwoElectrons() ) writeEvent =
true;
176 if (m_incSingleMuon && SubcutOnePhotonOneMuon() ) writeEvent =
true;
179 if (m_incMergedElectronPhoton && SubcutOnePhotonMergedElectrons(*eventInfo)) writeEvent =
true;
180 if (m_incDoubleMuon && SubcutOnePhotonTwoMuons() ) writeEvent =
true;
181 if (m_incDoubleElectronPhoton && SubcutOnePhotonTwoElectrons() ) writeEvent =
true;
182 if (m_incHighPtElectronPhoton && SubcutHighPtOnePhotonOneElectron() ) writeEvent =
true;
184 if (m_incMergedElectron && SubcutOneMergedElectron() ) writeEvent =
true;
187 if (m_incTwoPhotons && leadingPhotons) {
189 const double mass = CalculateInvariantMass(leadingPhotons.value());
191 bool passTwoPhotonCuts(
true);
192 if (m_reqQuality && !SubcutQuality(leadingPhotons.value())) passTwoPhotonCuts =
false;
193 if (m_reqKinematic && !SubcutKinematic(leadingPhotons.value(),
mass)) passTwoPhotonCuts =
false;
194 if (m_reqIsolation && !SubcutIsolation()) passTwoPhotonCuts =
false;
195 if (m_reqInvariantMass && !SubcutInvariantMass(
mass)) passTwoPhotonCuts =
false;
197 if (passTwoPhotonCuts) writeEvent =
true;
202 if (!writeEvent)
return false;
229 bool passTrigger = !m_reqTrigger;
231 if(m_triggers.empty()) passTrigger =
true;
233 for (
unsigned int i = 0;
i < m_triggers.size();
i++) {
235 if(m_trigDecisionTool->isPassed(m_triggers.at(
i)))
239 if (passTrigger) m_n_passTrigger++;
245 std::optional<DerivationFramework::SkimmingToolHIGG1::LeadingPhotons_t>
253 int ph_pos_lead = -1;
254 int ph_pos_subl = -1;
258 for(
int i = 0; ph_itr != ph_end; ++ph_itr, ++
i) {
260 if (PhotonPreselect(*ph_itr)) {
262 if ((*ph_itr)->pt() > ph_pt_lead) {
264 ph_pos_subl = ph_pos_lead; ph_pos_lead =
i;
265 ph_pt_subl = ph_pt_lead;
266 ph_pt_lead = (*ph_itr)->pt();
268 }
else if ((*ph_itr)->pt() > ph_pt_subl) {
270 ph_pt_subl = (*ph_itr)->pt();
282 if (ph_pos_subl != -1) {
296 if (!ph)
return false;
298 if (!ph->
isGoodOQ(34214))
return false;
306 val =
static_cast<bool>(DFCommonPhotonsIsEMLooseAcc(*ph));
312 if(!defined || !
val)
return false;
322 double eta = std::abs(caloCluster->
etaBE(2));
324 if (eta > m_maxEta)
return false;
326 1.37 <= eta && eta <= 1.52)
return false;
327 if (caloCluster->
e()/cosh(eta) < m_minPhotonPt)
return false;
336 if (m_relativePtCuts) {
337 passKinematic = (leadingPhotons[0]->pt() > invariantMass * m_leadingPhotonPt);
338 passKinematic &= (leadingPhotons[1]->pt() > invariantMass * m_subleadingPhotonPt);
340 passKinematic = (leadingPhotons[0]->pt() > m_leadingPhotonPt);
341 passKinematic &= (leadingPhotons[1]->pt() > m_subleadingPhotonPt);
344 if (passKinematic) m_n_passKinematic++;
345 return passKinematic;
352 bool passQuality =
false;
353 leadingPhotons[0]->passSelection(
val,
"Tight");
354 const int ph_tight_lead =
val;
356 leadingPhotons[1]->passSelection(
val,
"Tight");
357 const int ph_tight_subl =
val;
359 passQuality = (ph_tight_lead && ph_tight_subl);
361 if (passQuality) m_n_passQuality++;
376 bool passInvariantMass = (!m_minInvariantMass ||
377 m_minInvariantMass < invariantMass);
379 passInvariantMass &= (!m_maxInvariantMass ||
380 invariantMass < m_maxInvariantMass);
382 if (passInvariantMass) m_n_passInvariantMass++;
383 return passInvariantMass;
390 const double ph_e_lead = CorrectedEnergy(leadingPhotons[0]);
391 const double ph_e_subl = CorrectedEnergy(leadingPhotons[1]);
394 const double ph_eta_lead = CorrectedEta(leadingPhotons[0]);
395 const double ph_eta_subl = CorrectedEta(leadingPhotons[1]);
397 const double ph_phi_lead = leadingPhotons[0]->phi();
398 const double ph_phi_subl = leadingPhotons[1]->phi();
400 const double ph_pt_lead = ph_e_lead / cosh(ph_eta_lead);
401 const double ph_pt_subl = ph_e_subl / cosh(ph_eta_subl);
403 TLorentzVector leadPhotonLV;
404 TLorentzVector sublPhotonLV;
405 leadPhotonLV.SetPtEtaPhiM(ph_pt_lead, ph_eta_lead, ph_phi_lead, 0.);
406 sublPhotonLV.SetPtEtaPhiM(ph_pt_subl, ph_eta_subl, ph_phi_subl, 0.);
408 return (leadPhotonLV + sublPhotonLV).M();
434 double R_photom_n_front, Z_photom_n_front;
435 if (std::abs(
eta1) < 1.5) {
436 R_photom_n_front = ReturnRZ_1stSampling_cscopt2(
eta1);
437 Z_photom_n_front = R_photom_n_front*sinh(
eta1);
439 Z_photom_n_front = ReturnRZ_1stSampling_cscopt2(
eta1);
440 R_photom_n_front = Z_photom_n_front/sinh(
eta1);
443 return asinh((Z_photom_n_front - GetDiphotonVertex())/R_photom_n_front);
450 float abs_eta1 = std::abs(
eta1);
453 if (abs_eta1 < 0.8) {
454 radius = 1558.859292 - 4.990838 * abs_eta1 - 21.144279 * abs_eta1 * abs_eta1;
455 }
else if (abs_eta1 < 1.5) {
456 radius = 1522.775373 + 27.970192 * abs_eta1 - 21.104108 * abs_eta1 * abs_eta1;
478 bool passSingleElectronPreselect =
false;
480 for( ; ph_itr != ph_end; ++ph_itr){
481 if(PhotonPreselect(*ph_itr)){
482 for( ; el_itr != el_end; ++el_itr){
483 if(ElectronPreselect(*el_itr)){
484 passSingleElectronPreselect =
true;
491 if(passSingleElectronPreselect) m_n_passSingleElectronPreselect++;
492 return passSingleElectronPreselect;
502 if(
el->pt() < m_minElectronPt)
507 for(
unsigned int trk_i(0); trk_i <
el->nTrackParticles(); ++trk_i){
508 const auto *ele_tp =
el->trackParticle(trk_i);
513 bool allFound =
true;
520 int nSiHitsPlusDeadSensors = nPixHits + nPixDead +
nSCTHits + nSCTDead;
521 if(nSiHitsPlusDeadSensors >= 7)
526 else if( std::abs(z0_1 - ele_tp->z0()) > 10 )
536 ++m_n_passSingleMergedElectronPreselect;
550 bool passDoubleElectronPreselect =
false;
552 for( ; el_itr != el_end; ++el_itr){
553 if(ElectronPreselect(*el_itr))
557 if(nEle >=2) passDoubleElectronPreselect =
true;
559 if(passDoubleElectronPreselect) m_n_passDoubleElectronPreselect++;
560 return passDoubleElectronPreselect;
576 bool passSingleMuonPreselect =
false;
578 for( ; ph_itr != ph_end; ++ph_itr){
579 if(PhotonPreselect(*ph_itr)){
580 for( ; mu_itr != mu_end; ++mu_itr){
581 if(MuonPreselect(*mu_itr)){
582 passSingleMuonPreselect =
true;
589 if(passSingleMuonPreselect) m_n_passSingleMuonPreselect++;
590 return passSingleMuonPreselect;
608 for( ; ph_itr != ph_end; ++ph_itr){
609 if(PhotonPreselect(*ph_itr)){
614 for( ; mu_itr != mu_end; ++mu_itr){
615 if(MuonPreselect(*mu_itr)){
621 if(nPhoton >= 1 && nMuon >= 2){
622 ATH_MSG_DEBUG(
"Event selected with " << nPhoton <<
" photons and " << nMuon <<
" muons");
623 m_n_passSinglePhotonDoubleMuonPreselect++;
646 for( ; ph_itr != ph_end; ++ph_itr){
647 if(PhotonPreselect(*ph_itr)){
652 for( ; el_itr != el_end; ++el_itr){
653 if(ElectronPreselect(*el_itr)){
658 if(nPhoton >= 1 && nElectron >= 2){
659 ATH_MSG_DEBUG(
"Event selected with " << nPhoton <<
" photons and " << nElectron <<
" electrons");
660 ++m_n_passSinglePhotonDoubleElectronPreselect;
672 bool passTrigger=
false;
673 if(!m_mergedtriggers.empty()) {
674 for (
unsigned int i = 0;
i < m_mergedtriggers.size();
i++) {
676 if(m_trigDecisionTool->isPassed(m_mergedtriggers.at(
i)))
681 ATH_MSG_WARNING(
"Selecting Merged electrons but no Merged Triggers Selected ! -- was that intentional?");
692 bool passSelection =
false;
695 if(MergedElectronPreselect(
el)){
696 for(
const auto *ph: *photons){
697 if(PhotonPreselect(ph)){
698 passSelection =
true;
699 auto eph = ph->p4() +
el->p4();
714 ATH_MSG_DEBUG(
"Event selected with a photons and a merged electron");
715 ++m_n_passSinglePhotonMergedElectronPreselect;
741 for( ; ph_itr != ph_end; ++ph_itr){
742 if(PhotonPreselect(*ph_itr) && (*ph_itr)->pt() > 500*
CLHEP::GeV){
747 for( ; el_itr != el_end; ++el_itr){
748 if( std::abs((*el_itr)->eta()) <= m_maxEta && (*el_itr)->pt() > m_minElectronPt){
753 if(nPhoton >= 1 && nElectron >= 1 ){
754 ATH_MSG_DEBUG(
"Event selected with " << nPhoton <<
" high pt photons and " << nElectron <<
" merged electron");
755 ++m_n_passHighPtPhotonMergedElectronPreselect;
767 if (!
el)
return false;
775 val =
val ||
static_cast<bool>(DFCommonElectronsLooseAcc(*
el));
777 defined =
el->passSelection(
val,
"Loose");
783 val =
val ||
static_cast<bool>(DFCommonElectronsLHLooseAcc(*
el));
786 if(!defined || !
val)
return false;
788 double eta = std::abs(
el->eta());
789 double pt =
el->pt();
791 if (eta > m_maxEta)
return false;
792 if (m_removeCrack && 1.37 <= eta && eta <= 1.52)
return false;
793 if (
pt <= m_minElectronPt)
return false;
801 if (!
el)
return false;
803 double eta = std::abs(
el->eta());
804 double pt =
el->pt();
806 if (eta > m_maxEta)
return false;
807 if (m_removeCrack && 1.37 <= eta && eta <= 1.52)
return false;
808 if (
pt <= m_minMergedElectronPt)
return false;
810 return m_mergedCutTools->accept(
el) || ElectronPreselect(
el);
816 if (!
mu)
return false;
820 if( !
static_cast<bool>(DFCommonGoodMuonAcc(*
mu)) )
825 if( !
static_cast<bool>(DFCommonMuonsPreselectionAcc(*
mu)) )
828 double eta = std::abs(
mu->eta());
829 double pt =
mu->pt();
831 if (eta > m_maxMuonEta)
return false;
832 if (
pt <= m_minMuonPt)
return false;