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.get();
200 copyaux = shallowcopy.second.get();
210 return StatusCode::FAILURE;
213 ATH_MSG_DEBUG(
"Not retrieving electron collection, using existing one provided by user");
222 return StatusCode::SUCCESS;
228 ATH_MSG_VERBOSE(
"Starting FillElectron on el with pre-calibration pt=" << input.pt() );
246 ATH_MSG_DEBUG(
"No primary track particle for this electron. Skipping.");
247 return StatusCode::SUCCESS;
249 double primvertex_z = pv ? pv->z() : 0;
250 double el_z0 =
track->z0() +
track->vz() - primvertex_z;
257 float d0sigError = -99.;
258 ATH_MSG_WARNING(
"FillElectron : Exception catched from d0significance() calculation. Setting dummy decoration d0sig=" << d0sigError );
263 if ( input.pt() < 4e3 )
return StatusCode::SUCCESS;
264 if ( !input.caloCluster() ) {
ATH_MSG_WARNING(
"FillElectron: no caloCluster found: " << input.caloCluster() );
return StatusCode::SUCCESS; }
270 unsigned char el_nPixHits(0), el_nSCTHits(0);
276 ATH_MSG_INFO(
"ELECTRON cl eta: " << input.caloCluster()->eta());
277 ATH_MSG_INFO(
"ELECTRON cl phi: " << input.caloCluster()->phi());
278 ATH_MSG_INFO(
"ELECTRON cl e: " << input.caloCluster()->e());
279 ATH_MSG_INFO(
"ELECTRON trk eta: " << input.trackParticle()->eta());
280 ATH_MSG_INFO(
"ELECTRON trk phi: " << input.trackParticle()->phi());
283 ATH_MSG_INFO(
"ELECTRON nPixHits: " <<
static_cast<int>(el_nPixHits));
284 ATH_MSG_INFO(
"ELECTRON nSCTHits: " <<
static_cast<int>(el_nSCTHits));
285 ATH_MSG_INFO(
"ELECTRON deadHVTools: " <<
static_cast<bool>(pass_deadHVTool));
288 if (!pass_deadHVTool)
return StatusCode::SUCCESS;
293 return StatusCode::FAILURE;
296 bool passBaseID =
false;
303 ATH_MSG_VERBOSE (
"DFCommonElectronsLHxxx variables are not found. Calculating the ID from LH tool..");
314 if (std::abs(input.caloCluster()->etaBE(2)) >= etacut)
return StatusCode::SUCCESS;
317 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
318 return StatusCode::SUCCESS;
324 ATH_MSG_ERROR(
"FillElectron: EgammaCalibTool applyCorrection failed ");
327 ATH_MSG_ERROR(
"FillElectron: IsolationCorrectionTool applyCorrection failed");
331 if (input.pt() < etcut)
return StatusCode::SUCCESS;
361 return StatusCode::SUCCESS;
378 ATH_MSG_VERBOSE (
"DFCommonElectronsLHxxx variables are not found. Calculating the ID from LH tool..");
388 if (input.p4().Perp2() <= etcut * etcut || input.p4().Perp2() == 0)
return false;
390 if(std::abs(input.caloCluster()->etaBE(2)) >
m_eleEta )
return false;
392 else if ( std::abs(input.caloCluster()->etaBE(2)) > etacut )
return false;
395 if ( std::abs( input.caloCluster()->etaBE(2) ) >1.37 && std::abs( input.caloCluster()->etaBE(2) ) <1.52) {
401 if (d0sigcut > 0.0 && std::abs(
acc_d0sig(input)) > d0sigcut)
return false;
404 if (z0cut > 0.0 && std::abs(
acc_z0sinTheta(input)) > z0cut)
return false;
426 const bool triggerSF,
428 const std::string& trigExpr,
433 ATH_MSG_ERROR(
"No signal electron ID or trigger scale factors provided for the selected working point!");
438 std::string singleLepStr =
"singleLepton";
439 std::string diLepStr =
"diLepton";
440 std::string multiLepStr =
"multiLepton";
453 ATH_MSG_ERROR(
"Failed to retrieve signal electron reco SF");
456 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron reco SF");
475 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron id SF");
484 std::vector<std::string> trigMChains={};
485 std::string theExpr (
"");
486 if(trigExpr==singleLepStr) {
497 ATH_MSG_WARNING(
"Only single lepton trigger SFs are supported in GetSignalElecSF(). Use GetTriggerGlobalEfficiencySF() for dilepton or multilepton triggers!");
504 ATH_MSG_DEBUG(
"Electron was not matched to trigger " << theExpr <<
" - scale factor does not apply (year " << this->
treatAsYear() <<
") Returning 1." );
507 if (trigExpr==multiLepStr || trigExpr==diLepStr) {
508 ATH_MSG_WARNING(
"The dilepton or multilepton trigger SFs are not supported in GetSignalElecSF(). Use GetTriggerGlobalEfficiencySF()!");
533 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron iso SF");
541 if ( ecidsSF || cidSF ) {
565 std::string single_str =
"SINGLE_E";
566 std::string single_Run3 =
"202";
567 std::string dilep_str =
"DI_E";
568 std::string multi_str =
"MULTI_L";
571 if ( trigExpr.find(single_str) != std::string::npos || trigExpr.find(single_Run3) != std::string::npos)
573 else if ( trigExpr.find(dilep_str) != std::string::npos )
574 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
575 else if ( trigExpr.find(multi_str) != std::string::npos )
576 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
578 ATH_MSG_ERROR(
"The trigger expression (" << trigExpr <<
") is not supported by the electron trigger SF!");
582 ATH_MSG_ERROR(
"Failed to retrieve signal electron trigger SF");
585 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron trigger SF");
597 std::string single_str =
"SINGLE_E";
598 std::string single_Run3 =
"202";
599 std::string dilep_str =
"DI_E";
600 std::string multi_str =
"MULTI_L";
605 if ( trigExpr.find(single_str) != std::string::npos || trigExpr.find(single_Run3) != std::string::npos)
607 else if ( trigExpr.find(dilep_str) != std::string::npos )
608 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
609 else if ( trigExpr.find(multi_str) != std::string::npos )
610 ATH_MSG_ERROR(
"Use GetTriggerGlobalEfficiency for logical OR of lepton triggers");
612 ATH_MSG_ERROR(
"The trigger expression (" << trigExpr <<
") is not supported by the electron trigger efficiency!");
616 ATH_MSG_ERROR(
"Failed to retrieve signal electron trigger efficiency");
619 ATH_MSG_VERBOSE(
"OutOfValidityRange found for signal electron trigger efficiency");
647 StatusCode ret(StatusCode::SUCCESS);
650 if (ret != StatusCode::SUCCESS) {
651 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (reco) for systematic var. " << systConfig.
name() );
657 if (ret != StatusCode::SUCCESS) {
658 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (id) for systematic var. " << systConfig.
name() );
664 if (ret != StatusCode::SUCCESS) {
665 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (trigger) for systematic var. " << systConfig.
name() );
671 if (ret != StatusCode::SUCCESS) {
672 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso) for systematic var. " << systConfig.
name() );
678 if (ret != StatusCode::SUCCESS) {
679 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso high-pt) for systematic var. " << systConfig.
name() );
685 if (ret != StatusCode::SUCCESS) {
686 ATH_MSG_ERROR(
"Cannot configure ElectronChargeEfficiencyCorrectionTool for systematic var. " << systConfig.
name() );
692 sf =
GetTotalElectronSF(electrons, recoSF, idSF, triggerSF, isoSF, trigExpr, ecidsSF, cidSF);
697 if (ret != StatusCode::SUCCESS) {
698 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (reco) back to default.");
704 if (ret != StatusCode::SUCCESS) {
705 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (id) back to default.");
711 if (ret != StatusCode::SUCCESS) {
712 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (trigger) back to default.");
718 if (ret != StatusCode::SUCCESS) {
719 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso) back to default.");
725 if (ret != StatusCode::SUCCESS) {
726 ATH_MSG_ERROR(
"Cannot configure AsgElectronEfficiencyCorrectionTool (iso high-pt) back to default.");
732 if (ret != StatusCode::SUCCESS) {
733 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.
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
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
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_passSignalID("passSignalID")
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::ConstAccessor< char > acc_passSignalID("passSignalID")
static const SG::ConstAccessor< char > acc_passECIDS("DFCommonElectronsECIDS")
static const SG::ConstAccessor< char > acc_trigmatched("trigmatched")
static const SG::ConstAccessor< unsigned int > acc_OQ("OQ")
static const SG::Decorator< char > dec_passChID("passChID")
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< float > dec_z0sinTheta("z0sinTheta")
static const SG::Decorator< double > dec_ecisBDT("ecisBDT")
static const double DUMMYDEF
static const SG::Decorator< char > dec_isLRT("isLRT")
static const SG::ConstAccessor< char > acc_passOR("passOR")
static const SG::Decorator< float > dec_sfChIDEff("chargeIDEffiSF")
static const SG::ConstAccessor< char > acc_isLRT("isLRT")
static const SG::ConstAccessor< char > acc_lrtFilter("passLRTFilter")
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< float > dec_d0sig("d0sig")
static const SG::Decorator< char > dec_selected("selected")
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)
typename ShallowCopyResult< T >::type ShallowCopyResult_t
Return type of xAOD::shallowCopy.
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
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.
ShallowCopyResult_t< T > shallowCopy(const T &cont, const EventContext &ctx)
Create a shallow copy of an existing container.
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".