14 #include "CLHEP/Units/SystemOfUnits.h"
24 const IInterface*
p) :
26 m_trigDecisionTool(
"Trig::TrigDecisionTool/TrigDecisionTool"),
30 declareInterface<DerivationFramework::ISkimmingTool>(
this);
88 if(m_trigDecisionTool.retrieve(DisableTool{!m_reqTrigger}).isFailure()) {
89 ATH_MSG_FATAL(
"Failed to retrieve tool: " << m_trigDecisionTool);
90 return StatusCode::FAILURE;
92 if (m_triggers.empty()) m_triggers.push_back(m_defaultTrigger);
96 if(m_incMergedElectronPhoton){
97 if( m_mergedCutTools.retrieve().isFailure() )
99 ATH_MSG_FATAL(
"Failed to retrieve tool: ElectronPhotonSelectorTools");
100 return StatusCode::FAILURE;
104 ATH_CHECK( m_eventInfoKey.initialize() );
113 return StatusCode::SUCCESS;
119 ATH_MSG_INFO(
"Processed " << m_n_tot <<
" events, " << m_n_pass <<
" events passed filter ");
126 if(m_incDoubleElectron)
127 ATH_MSG_INFO(
"2e :: " << m_n_passDoubleElectronPreselect);
128 if(m_incSingleElectron)
129 ATH_MSG_INFO(
"1y1e :: " << m_n_passSingleElectronPreselect);
131 ATH_MSG_INFO(
"1y1mu :: " << m_n_passSingleMuonPreselect);
133 ATH_MSG_INFO(
"1y2mu :: " << m_n_passSinglePhotonDoubleMuonPreselect);
134 if(m_incDoubleElectronPhoton)
135 ATH_MSG_INFO(
"1y2e :: " << m_n_passSinglePhotonDoubleElectronPreselect);
136 if(m_incMergedElectronPhoton)
137 ATH_MSG_INFO(
"1y1eMerge :: " << m_n_passSinglePhotonMergedElectronPreselect);
138 if(m_incHighPtElectronPhoton)
139 ATH_MSG_INFO(
"1y1e HiPt :: " << m_n_passHighPtPhotonMergedElectronPreselect);
140 if(m_incMergedElectron)
141 ATH_MSG_INFO(
"1eMerge :: " << m_n_passSingleMergedElectronPreselect);
154 return StatusCode::SUCCESS;
163 bool writeEvent(
false);
164 const EventContext& ctx = Gaudi::Hive::currentContext();
167 if (m_reqGRL && !SubcutGoodRunList() )
return false;
168 if (m_reqLArError && !SubcutLArError(*eventInfo) )
return false;
169 if (m_reqTrigger && !SubcutTrigger() )
return false;
171 const auto leadingPhotons = SubcutPreselect();
172 if (m_incTwoPhotons && !m_reqPreselection) writeEvent =
true;
175 if (m_incSingleElectron && SubcutOnePhotonOneElectron() ) writeEvent =
true;
176 if (m_incDoubleElectron && SubcutTwoElectrons() ) writeEvent =
true;
177 if (m_incSingleMuon && SubcutOnePhotonOneMuon() ) writeEvent =
true;
180 if (m_incMergedElectronPhoton && SubcutOnePhotonMergedElectrons(*eventInfo)) writeEvent =
true;
181 if (m_incDoubleMuon && SubcutOnePhotonTwoMuons() ) writeEvent =
true;
182 if (m_incDoubleElectronPhoton && SubcutOnePhotonTwoElectrons() ) writeEvent =
true;
183 if (m_incHighPtElectronPhoton && SubcutHighPtOnePhotonOneElectron() ) writeEvent =
true;
185 if (m_incMergedElectron && SubcutOneMergedElectron() ) writeEvent =
true;
188 if (m_incTwoPhotons && leadingPhotons) {
190 const double mass = CalculateInvariantMass(leadingPhotons.value());
192 bool passTwoPhotonCuts(
true);
193 if (m_reqQuality && !SubcutQuality(leadingPhotons.value())) passTwoPhotonCuts =
false;
194 if (m_reqKinematic && !SubcutKinematic(leadingPhotons.value(),
mass)) passTwoPhotonCuts =
false;
195 if (m_reqIsolation && !SubcutIsolation()) passTwoPhotonCuts =
false;
196 if (m_reqInvariantMass && !SubcutInvariantMass(
mass)) passTwoPhotonCuts =
false;
198 if (passTwoPhotonCuts) writeEvent =
true;
203 if (!writeEvent)
return false;
230 bool passTrigger = !m_reqTrigger;
232 if(m_triggers.empty()) passTrigger =
true;
234 for (
unsigned int i = 0;
i < m_triggers.size();
i++) {
236 if(m_trigDecisionTool->isPassed(m_triggers.at(
i)))
240 if (passTrigger) m_n_passTrigger++;
246 std::optional<DerivationFramework::SkimmingToolHIGG1::LeadingPhotons_t>
254 int ph_pos_lead = -1;
255 int ph_pos_subl = -1;
259 for(
int i = 0; ph_itr != ph_end; ++ph_itr, ++
i) {
261 if (PhotonPreselect(*ph_itr)) {
263 if ((*ph_itr)->pt() > ph_pt_lead) {
265 ph_pos_subl = ph_pos_lead; ph_pos_lead =
i;
266 ph_pt_subl = ph_pt_lead;
267 ph_pt_lead = (*ph_itr)->pt();
269 }
else if ((*ph_itr)->pt() > ph_pt_subl) {
271 ph_pt_subl = (*ph_itr)->pt();
283 if (ph_pos_subl != -1) {
297 if (!ph)
return false;
299 if (!ph->
isGoodOQ(34214))
return false;
307 val =
static_cast<bool>(DFCommonPhotonsIsEMLooseAcc(*ph));
313 if(!defined || !
val)
return false;
323 double eta = std::abs(caloCluster->
etaBE(2));
325 if (eta > m_maxEta)
return false;
327 1.37 <= eta && eta <= 1.52)
return false;
328 if (caloCluster->
e()/cosh(eta) < m_minPhotonPt)
return false;
337 if (m_relativePtCuts) {
338 passKinematic = (leadingPhotons[0]->pt() > invariantMass * m_leadingPhotonPt);
339 passKinematic &= (leadingPhotons[1]->pt() > invariantMass * m_subleadingPhotonPt);
341 passKinematic = (leadingPhotons[0]->pt() > m_leadingPhotonPt);
342 passKinematic &= (leadingPhotons[1]->pt() > m_subleadingPhotonPt);
345 if (passKinematic) m_n_passKinematic++;
346 return passKinematic;
353 bool passQuality =
false;
354 leadingPhotons[0]->passSelection(
val,
"Tight");
355 const int ph_tight_lead =
val;
357 leadingPhotons[1]->passSelection(
val,
"Tight");
358 const int ph_tight_subl =
val;
360 passQuality = (ph_tight_lead && ph_tight_subl);
362 if (passQuality) m_n_passQuality++;
377 bool passInvariantMass = (!m_minInvariantMass ||
378 m_minInvariantMass < invariantMass);
380 passInvariantMass &= (!m_maxInvariantMass ||
381 invariantMass < m_maxInvariantMass);
383 if (passInvariantMass) m_n_passInvariantMass++;
384 return passInvariantMass;
391 const double ph_e_lead = CorrectedEnergy(leadingPhotons[0]);
392 const double ph_e_subl = CorrectedEnergy(leadingPhotons[1]);
395 const double ph_eta_lead = CorrectedEta(leadingPhotons[0]);
396 const double ph_eta_subl = CorrectedEta(leadingPhotons[1]);
398 const double ph_phi_lead = leadingPhotons[0]->phi();
399 const double ph_phi_subl = leadingPhotons[1]->phi();
401 const double ph_pt_lead = ph_e_lead / cosh(ph_eta_lead);
402 const double ph_pt_subl = ph_e_subl / cosh(ph_eta_subl);
404 TLorentzVector leadPhotonLV;
405 TLorentzVector sublPhotonLV;
406 leadPhotonLV.SetPtEtaPhiM(ph_pt_lead, ph_eta_lead, ph_phi_lead, 0.);
407 sublPhotonLV.SetPtEtaPhiM(ph_pt_subl, ph_eta_subl, ph_phi_subl, 0.);
409 return (leadPhotonLV + sublPhotonLV).M();
435 double R_photom_n_front, Z_photom_n_front;
436 if (std::abs(
eta1) < 1.5) {
437 R_photom_n_front = ReturnRZ_1stSampling_cscopt2(
eta1);
438 Z_photom_n_front = R_photom_n_front*sinh(
eta1);
440 Z_photom_n_front = ReturnRZ_1stSampling_cscopt2(
eta1);
441 R_photom_n_front = Z_photom_n_front/sinh(
eta1);
444 return asinh((Z_photom_n_front - GetDiphotonVertex())/R_photom_n_front);
451 float abs_eta1 = std::abs(
eta1);
454 if (abs_eta1 < 0.8) {
455 radius = 1558.859292 - 4.990838 * abs_eta1 - 21.144279 * abs_eta1 * abs_eta1;
456 }
else if (abs_eta1 < 1.5) {
457 radius = 1522.775373 + 27.970192 * abs_eta1 - 21.104108 * abs_eta1 * abs_eta1;
479 bool passSingleElectronPreselect =
false;
481 for( ; ph_itr != ph_end; ++ph_itr){
482 if(PhotonPreselect(*ph_itr)){
483 for( ; el_itr != el_end; ++el_itr){
484 if(ElectronPreselect(*el_itr)){
485 passSingleElectronPreselect =
true;
492 if(passSingleElectronPreselect) m_n_passSingleElectronPreselect++;
493 return passSingleElectronPreselect;
503 if(
el->pt() < m_minElectronPt)
508 for(
unsigned int trk_i(0); trk_i <
el->nTrackParticles(); ++trk_i){
509 const auto *ele_tp =
el->trackParticle(trk_i);
514 bool allFound =
true;
521 int nSiHitsPlusDeadSensors = nPixHits + nPixDead +
nSCTHits + nSCTDead;
522 if(nSiHitsPlusDeadSensors >= 7)
527 else if( std::abs(z0_1 - ele_tp->z0()) > 10 )
537 ++m_n_passSingleMergedElectronPreselect;
551 bool passDoubleElectronPreselect =
false;
553 for( ; el_itr != el_end; ++el_itr){
554 if(ElectronPreselect(*el_itr))
558 if(nEle >=2) passDoubleElectronPreselect =
true;
560 if(passDoubleElectronPreselect) m_n_passDoubleElectronPreselect++;
561 return passDoubleElectronPreselect;
577 bool passSingleMuonPreselect =
false;
579 for( ; ph_itr != ph_end; ++ph_itr){
580 if(PhotonPreselect(*ph_itr)){
581 for( ; mu_itr != mu_end; ++mu_itr){
582 if(MuonPreselect(*mu_itr)){
583 passSingleMuonPreselect =
true;
590 if(passSingleMuonPreselect) m_n_passSingleMuonPreselect++;
591 return passSingleMuonPreselect;
609 for( ; ph_itr != ph_end; ++ph_itr){
610 if(PhotonPreselect(*ph_itr)){
615 for( ; mu_itr != mu_end; ++mu_itr){
616 if(MuonPreselect(*mu_itr)){
622 if(nPhoton >= 1 && nMuon >= 2){
623 ATH_MSG_DEBUG(
"Event selected with " << nPhoton <<
" photons and " << nMuon <<
" muons");
624 m_n_passSinglePhotonDoubleMuonPreselect++;
647 for( ; ph_itr != ph_end; ++ph_itr){
648 if(PhotonPreselect(*ph_itr)){
653 for( ; el_itr != el_end; ++el_itr){
654 if(ElectronPreselect(*el_itr)){
659 if(nPhoton >= 1 && nElectron >= 2){
660 ATH_MSG_DEBUG(
"Event selected with " << nPhoton <<
" photons and " << nElectron <<
" electrons");
661 ++m_n_passSinglePhotonDoubleElectronPreselect;
673 bool passTrigger=
false;
674 if(!m_mergedtriggers.empty()) {
675 for (
unsigned int i = 0;
i < m_mergedtriggers.size();
i++) {
677 if(m_trigDecisionTool->isPassed(m_mergedtriggers.at(
i)))
682 ATH_MSG_WARNING(
"Selecting Merged electrons but no Merged Triggers Selected ! -- was that intentional?");
693 bool passSelection =
false;
696 if(MergedElectronPreselect(
el)){
697 for(
const auto *ph: *photons){
698 if(PhotonPreselect(ph)){
699 passSelection =
true;
700 auto eph = ph->p4() +
el->p4();
715 ATH_MSG_DEBUG(
"Event selected with a photons and a merged electron");
716 ++m_n_passSinglePhotonMergedElectronPreselect;
742 for( ; ph_itr != ph_end; ++ph_itr){
743 if(PhotonPreselect(*ph_itr) && (*ph_itr)->pt() > 500*
CLHEP::GeV){
748 for( ; el_itr != el_end; ++el_itr){
749 if( std::abs((*el_itr)->eta()) <= m_maxEta && (*el_itr)->pt() > m_minElectronPt){
754 if(nPhoton >= 1 && nElectron >= 1 ){
755 ATH_MSG_DEBUG(
"Event selected with " << nPhoton <<
" high pt photons and " << nElectron <<
" merged electron");
756 ++m_n_passHighPtPhotonMergedElectronPreselect;
768 if (!
el)
return false;
776 val =
val ||
static_cast<bool>(DFCommonElectronsLooseAcc(*
el));
778 defined =
el->passSelection(
val,
"Loose");
784 val =
val ||
static_cast<bool>(DFCommonElectronsLHLooseAcc(*
el));
787 if(!defined || !
val)
return false;
789 double eta = std::abs(
el->eta());
790 double pt =
el->pt();
792 if (eta > m_maxEta)
return false;
793 if (m_removeCrack && 1.37 <= eta && eta <= 1.52)
return false;
794 if (
pt <= m_minElectronPt)
return false;
802 if (!
el)
return false;
804 double eta = std::abs(
el->eta());
805 double pt =
el->pt();
807 if (eta > m_maxEta)
return false;
808 if (m_removeCrack && 1.37 <= eta && eta <= 1.52)
return false;
809 if (
pt <= m_minMergedElectronPt)
return false;
811 return m_mergedCutTools->accept(
el) || ElectronPreselect(
el);
817 if (!
mu)
return false;
821 if( !
static_cast<bool>(DFCommonGoodMuonAcc(*
mu)) )
826 if( !
static_cast<bool>(DFCommonMuonsPreselectionAcc(*
mu)) )
829 double eta = std::abs(
mu->eta());
830 double pt =
mu->pt();
832 if (eta > m_maxMuonEta)
return false;
833 if (
pt <= m_minMuonPt)
return false;