37#ifndef XAOD_STANDALONE
63 if (electrons.empty())
return StatusCode::SUCCESS;
65 if (ElectronsToRemove.find(
electron) != ElectronsToRemove.end()){
86 return StatusCode::SUCCESS;
98 std::unique_ptr<xAOD::Electron> copyElectron = std::make_unique<xAOD::Electron>(*
electron);
103 copy->push_back( std::move(copyElectron) );
108 std::unique_ptr<xAOD::Electron> copyElectron = std::make_unique<xAOD::Electron>(*
electron);
111 copy->push_back( std::move(copyElectron) );
114 return StatusCode::SUCCESS;
122 return StatusCode::FAILURE;
126 auto outputCol = std::make_unique<xAOD::ElectronContainer>();
127 std::unique_ptr<xAOD::ElectronAuxContainer> outputAuxCol;
128 outputAuxCol = std::make_unique<xAOD::ElectronAuxContainer>();
129 outputCol->setStore(outputAuxCol.get());
137 ATH_MSG_DEBUG(
"Merged prompt/LRT container already created in TStore");
139 ATH_MSG_DEBUG(
"Creating merged prompt/LRT container in TStore");
146 auto filtered_electrons = std::make_unique<xAOD::ElectronContainer>();
147 std::unique_ptr<xAOD::ElectronAuxContainer> filtered_electrons_aux = std::make_unique<xAOD::ElectronAuxContainer>();
148 filtered_electrons->setStore(filtered_electrons_aux.get());
152 std::set<const xAOD::Electron *> ElectronsToRemove;
168 }
else if (!lrtelekey.empty()) {
170 ATH_MSG_DEBUG(
"Not applying prompt/LRT electron OR procedure");
173 if (
m_isPHYSLITE && elekey.find(
"AnalysisElectrons")==std::string::npos){
174 ATH_MSG_ERROR(
"You are running on PHYSLITE derivation. Please change the Electrons container to 'AnalysisElectrons'");
175 return StatusCode::FAILURE;
186 if (containerToBeCopied !=
nullptr) {
188 electrons = containerToBeCopied;
199 copy = shallowcopy.first;
200 copyaux = shallowcopy.second;
206 ATH_MSG_DEBUG(
"Not retrieving electron collection, using existing one provided by user");
219 return StatusCode::SUCCESS;
225 ATH_MSG_VERBOSE(
"Starting FillElectron on el with pre-calibration pt=" << input.pt() );
243 ATH_MSG_DEBUG(
"No primary track particle for this electron. Skipping.");
244 return StatusCode::SUCCESS;
246 double primvertex_z = pv ? pv->z() : 0;
247 double el_z0 =
track->z0() +
track->vz() - primvertex_z;
254 float d0sigError = -99.;
255 ATH_MSG_WARNING(
"FillElectron : Exception catched from d0significance() calculation. Setting dummy decoration d0sig=" << d0sigError );
260 if ( input.pt() < 4e3 )
return StatusCode::SUCCESS;
261 if ( !input.caloCluster() ) {
ATH_MSG_WARNING(
"FillElectron: no caloCluster found: " << input.caloCluster() );
return StatusCode::SUCCESS; }
267 unsigned char el_nPixHits(0), el_nSCTHits(0);
273 ATH_MSG_INFO(
"ELECTRON cl eta: " << input.caloCluster()->eta());
274 ATH_MSG_INFO(
"ELECTRON cl phi: " << input.caloCluster()->phi());
275 ATH_MSG_INFO(
"ELECTRON cl e: " << input.caloCluster()->e());
276 ATH_MSG_INFO(
"ELECTRON trk eta: " << input.trackParticle()->eta());
277 ATH_MSG_INFO(
"ELECTRON trk phi: " << input.trackParticle()->phi());
280 ATH_MSG_INFO(
"ELECTRON nPixHits: " <<
static_cast<int>(el_nPixHits));
281 ATH_MSG_INFO(
"ELECTRON nSCTHits: " <<
static_cast<int>(el_nSCTHits));
282 ATH_MSG_INFO(
"ELECTRON deadHVTools: " <<
static_cast<bool>(pass_deadHVTool));
285 if (!pass_deadHVTool)
return StatusCode::SUCCESS;
290 return StatusCode::FAILURE;
293 bool passBaseID =
false;
300 ATH_MSG_VERBOSE (
"DFCommonElectronsLHxxx variables are not found. Calculating the ID from LH tool..");
311 if (std::abs(input.caloCluster()->etaBE(2)) >= etacut)
return StatusCode::SUCCESS;
314 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
315 return StatusCode::SUCCESS;
321 ATH_MSG_ERROR(
"FillElectron: EgammaCalibTool applyCorrection failed ");
324 ATH_MSG_ERROR(
"FillElectron: IsolationCorrectionTool applyCorrection failed");
328 if (input.pt() < etcut)
return StatusCode::SUCCESS;
358 return StatusCode::SUCCESS;
375 ATH_MSG_VERBOSE (
"DFCommonElectronsLHxxx variables are not found. Calculating the ID from LH tool..");
385 if (input.p4().Perp2() <= etcut * etcut || input.p4().Perp2() == 0)
return false;
387 if(std::abs(input.caloCluster()->etaBE(2)) >
m_eleEta )
return false;
389 else if ( std::abs(input.caloCluster()->etaBE(2)) > etacut )
return false;
392 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
398 if (d0sigcut > 0.0 && std::abs(
acc_d0sig(input)) > d0sigcut)
return false;
401 if (z0cut > 0.0 && std::abs(
acc_z0sinTheta(input)) > z0cut)
return false;
423 const bool triggerSF,
425 const std::string& trigExpr,
430 ATH_MSG_ERROR(
"No signal electron ID or trigger scale factors provided for the selected working point!");
435 std::string singleLepStr =
"singleLepton";
436 std::string diLepStr =
"diLepton";
437 std::string multiLepStr =
"multiLepton";
450 ATH_MSG_ERROR(
"Failed to retrieve signal electron reco SF");
453 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron reco SF");
472 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron id SF");
481 std::vector<std::string> trigMChains={};
482 std::string theExpr (
"");
483 if(trigExpr==singleLepStr) {
494 ATH_MSG_WARNING(
"Only single lepton trigger SFs are supported in GetSignalElecSF(). Use GetTriggerGlobalEfficiencySF() for dilepton or multilepton triggers!");
501 ATH_MSG_DEBUG(
"Electron was not matched to trigger " << theExpr <<
" - scale factor does not apply (year " << this->
treatAsYear() <<
") Returning 1." );
504 if (trigExpr==multiLepStr || trigExpr==diLepStr) {
505 ATH_MSG_WARNING(
"The dilepton or multilepton trigger SFs are not supported in GetSignalElecSF(). Use GetTriggerGlobalEfficiencySF()!");
530 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron iso SF");
538 if ( ecidsSF || cidSF ) {
562 std::string single_str =
"SINGLE_E";
563 std::string single_Run3 =
"202";
564 std::string dilep_str =
"DI_E";
565 std::string multi_str =
"MULTI_L";
568 if ( trigExpr.find(single_str) != std::string::npos || trigExpr.find(single_Run3) != std::string::npos)
570 else if ( trigExpr.find(dilep_str) != std::string::npos )
571 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
572 else if ( trigExpr.find(multi_str) != std::string::npos )
573 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
575 ATH_MSG_ERROR(
"The trigger expression (" << trigExpr <<
") is not supported by the electron trigger SF!");
579 ATH_MSG_ERROR(
"Failed to retrieve signal electron trigger SF");
582 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron trigger SF");
594 std::string single_str =
"SINGLE_E";
595 std::string single_Run3 =
"202";
596 std::string dilep_str =
"DI_E";
597 std::string multi_str =
"MULTI_L";
602 if ( trigExpr.find(single_str) != std::string::npos || trigExpr.find(single_Run3) != std::string::npos)
604 else if ( trigExpr.find(dilep_str) != std::string::npos )
605 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
606 else if ( trigExpr.find(multi_str) != std::string::npos )
607 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
609 ATH_MSG_ERROR(
"The trigger expression (" << trigExpr <<
") is not supported by the electron trigger efficiency!");
613 ATH_MSG_ERROR(
"Failed to retrieve signal electron trigger efficiency");
616 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron trigger efficiency");
644 StatusCode ret(StatusCode::SUCCESS);
647 if (ret != StatusCode::SUCCESS) {
648 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (reco) for systematic var. " << systConfig.
name() );
654 if (ret != StatusCode::SUCCESS) {
655 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (id) for systematic var. " << systConfig.
name() );
661 if (ret != StatusCode::SUCCESS) {
662 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
668 if (ret != StatusCode::SUCCESS) {
669 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso) for systematic var. " << systConfig.
name() );
675 if (ret != StatusCode::SUCCESS) {
676 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso high-pt) for systematic var. " << systConfig.
name() );
682 if (ret != StatusCode::SUCCESS) {
683 ATH_MSG_ERROR(
"Cannot configure ElectronChargeEfficiencyCorrectionTool for systematic var. " << systConfig.
name() );
689 sf =
GetTotalElectronSF(electrons, recoSF, idSF, triggerSF, isoSF, trigExpr, ecidsSF, cidSF);
694 if (ret != StatusCode::SUCCESS) {
695 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (reco) back to default.");
701 if (ret != StatusCode::SUCCESS) {
702 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (id) back to default.");
708 if (ret != StatusCode::SUCCESS) {
709 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (trigger) back to default.");
715 if (ret != StatusCode::SUCCESS) {
716 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso) back to default.");
722 if (ret != StatusCode::SUCCESS) {
723 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso high-pt) back to default.");
729 if (ret != StatusCode::SUCCESS) {
730 ATH_MSG_ERROR(
"Cannot configure ElectronChargeEfficiencyCorrectionTool back to default.");
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
DataVector adapter that acts like it holds const pointers.
ServiceHandle< StoreGateSvc > & evtStore()
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ OutOfValidityRange
Input object is out of validity range.
@ Ok
The correction was done successfully.
Class to wrap a set of SystematicVariations.
std::string name() const
returns: the systematics joined into a single string.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Helper class to provide constant type-safe access to aux data.
Helper class to provide type-safe access to aux data.
std::vector< std::string > m_v_trigs24_cache_singleEle
double m_elebaselined0sig
StatusCode FillElectron(xAOD::Electron &input, const float etcut, const float etacut) override final
asg::AnaToolHandle< CP::IElectronLRTOverlapRemovalTool > m_elecLRTORTool
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoBaselineTool
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecEfficiencySFTool_isoHighPt
asg::AnaToolHandle< IAsgElectronLikelihoodTool > m_elecSelLikelihood
StatusCode prepareLRTElectrons(const xAOD::ElectronContainer *inMuons, xAOD::ElectronContainer *copy) const override final
std::vector< std::string > m_v_trigs15_cache_singleEle
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoHighPtTool
asg::AnaToolHandle< IAsgElectronLikelihoodTool > m_elecSelLikelihoodBaseline
double GetEleTriggerEfficiencySF(const xAOD::Electron &el, const std::string &trigExpr="SINGLE_E_2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose_2016_2018_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0") const override final
StatusCode MergeElectrons(const xAOD::ElectronContainer &electrons, xAOD::ElectronContainer *outputCol, const std::set< const xAOD::Electron * > &ElectronsToRemove) const override final
double m_eleIsoHighPtThresh
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecEfficiencySFTool_id
const xAOD::ElectronContainer * lrt_electrons
asg::AnaToolHandle< CP::IIsolationSelectionTool > m_isoTool
SG::ConstAccessor< char > m_acc_eleId
asg::AnaToolHandle< IAsgElectronLikelihoodTool > m_elecChargeIDSelectorTool
SG::WriteHandleKey< xAOD::ElectronContainer > m_outElectronLocation
bool m_eleBaselineCrackVeto
std::vector< std::string > m_v_trigs23_cache_singleEle
double GetEleTriggerEfficiency(const xAOD::Electron &el, const std::string &trigExpr="SINGLE_E_2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose_2016_2018_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0") const override final
const xAOD::ElectronContainer * prompt_electrons
std::vector< std::string > m_v_trigs18_cache_singleEle
int treatAsYear(const int runNumber=-1) const override final
asg::AnaToolHandle< IAsgDeadHVCellRemovalTool > m_deadHVTool
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecEfficiencySFTool_trigEff_singleLep
CP::SystematicSet m_currentSyst
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecChargeEffCorrTool
std::string m_eleIsoHighPt_WP
asg::AnaToolHandle< CP::IIsolationCorrectionTool > m_isoCorrTool
float GetSignalElecSF(const xAOD::Electron &el, const bool recoSF=true, const bool idSF=true, const bool triggerSF=true, const bool isoSF=true, const std::string &trigExpr="singleLepton", const bool ecidsSF=false, const bool cidSF=false) override final
SG::ConstAccessor< char > m_acc_eleIdBaseline
StatusCode GetElectrons(xAOD::ElectronContainer *©, xAOD::ShallowAuxContainer *©aux, const bool recordSG=true, const std::string &elekey="Electrons", const std::string &lrtelekey="LRTElectrons", const xAOD::ElectronContainer *containerToBeCopied=nullptr) override final
std::vector< std::string > m_v_trigs22_cache_singleEle
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecEfficiencySFTool_reco
Combined muon collection.
float GetTotalElectronSF(const xAOD::ElectronContainer &electrons, const bool recoSF=true, const bool idSF=true, const bool triggerSF=true, const bool isoSF=true, const std::string &trigExpr="singleLepton", const bool ecidsSF=false, const bool cidSF=false) override final
const xAOD::Vertex * GetPrimVtx() const override final
std::vector< std::string > m_v_trigs17_cache_singleEle
std::vector< std::string > m_v_trigs16_cache_singleEle
bool IsSignalElectron(const xAOD::Electron &input, const float etcut, const float d0sigcut, const float z0cut, const float etacut=DUMMYDEF) const override final
asg::AnaToolHandle< CP::IEgammaCalibrationAndSmearingTool > m_egammaCalibTool
Combined electron collection.
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecEfficiencySFTool_trig_singleLep
asg::AnaToolHandle< IAsgElectronEfficiencyCorrectionTool > m_elecEfficiencySFTool_iso
float GetTotalElectronSFsys(const xAOD::ElectronContainer &electrons, const CP::SystematicSet &systConfig, const bool recoSF=true, const bool idSF=true, const bool triggerSF=true, const bool isoSF=true, const std::string &trigExpr="singleLepton", const bool ecidsSF=false, const bool cidSF=false) override final
std::string m_eleBaselineIso_WP
std::string m_electronTriggerSFStringSingle
float beamPosSigmaY() const
The width of the beam spot in the Y direction.
float beamPosSigmaXY() const
The beam spot shape's X-Y correlation.
float beamPosSigmaX() const
The width of the beam spot in the X direction.
Class creating a shallow copy of an existing auxiliary container.
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
static const SG::ConstAccessor< float > acc_d0sig("d0sig")
static const SG::ConstAccessor< char > acc_isolHighPt("isolHighPt")
static const SG::Decorator< double > dec_effscalefact("effscalefact")
static const SG::Decorator< char > dec_baseline("baseline")
static const SG::Decorator< char > dec_isolHighPt("isolHighPt")
static const SG::ConstAccessor< float > acc_z0sinTheta("z0sinTheta")
static const SG::Decorator< float > dec_d0sig("d0sig")
static const SG::Decorator< float > dec_sfChIDEff("chargeIDEffiSF")
static const SG::ConstAccessor< char > acc_passSignalID("passSignalID")
static const SG::Decorator< char > dec_isLRT("isLRT")
static const SG::ConstAccessor< char > acc_passECIDS("DFCommonElectronsECIDS")
static const SG::Decorator< double > dec_ecisBDT("ecisBDT")
static const SG::ConstAccessor< char > acc_trigmatched("trigmatched")
static const SG::ConstAccessor< unsigned int > acc_OQ("OQ")
static const SG::ConstAccessor< float > acc_sfChIDEff("chargeIDEffiSF")
static const SG::ConstAccessor< char > acc_signal("signal")
static const SG::ConstAccessor< char > acc_baseline("baseline")
static const SG::Decorator< char > dec_passSignalID("passSignalID")
static const double DUMMYDEF
static const SG::ConstAccessor< char > acc_passOR("passOR")
static const SG::ConstAccessor< char > acc_isLRT("isLRT")
static const SG::ConstAccessor< char > acc_lrtFilter("passLRTFilter")
static const SG::Decorator< char > dec_passChID("passChID")
static const SG::ConstAccessor< char > acc_isol("isol")
static const SG::Decorator< char > dec_isol("isol")
static const SG::ConstAccessor< char > acc_passChID("passChID")
static const SG::Decorator< char > dec_signal("signal")
static const SG::Decorator< char > dec_selected("selected")
static const SG::Decorator< float > dec_z0sinTheta("z0sinTheta")
helper namespace for calculating deltaR for unknown object types
const uint32_t BADCLUSELECTRON
double d0significance(const xAOD::TrackParticle *tp, double d0_uncert_beam_spot_2)
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant container.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
const IParticle * getOriginalObject(const IParticle ©)
This function can be used to conveniently get a pointer back to the original object from which a copy...
Vertex_v1 Vertex
Define the latest version of the vertex class.
bool setOriginalObjectLink(const IParticle &original, IParticle ©)
This function should be used by CP tools when they make a deep copy of an object in their correctedCo...
setBGCode setTAP setLVL2ErrorBits bool
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".