23#ifndef XAOD_STANDALONE
37HelperFunc(
double& sf,
const double input)
55AsgElectronEfficiencyCorrectionTool::AsgElectronEfficiencyCorrectionTool(
56 const std::string& myname)
57 :
asg::AsgMetadataTool(myname)
59 , m_appliedSystematics(nullptr)
65 , m_UncorrRegions(nullptr)
66 , m_nSimpleUncorrSyst(0)
72 , m_accessors{
std::make_unique<Accessors>(*this)}
75 m_rootTool = std::make_unique<Root::TElectronEfficiencyCorrectionTool>(
76 (
"T" + (this->
name())).c_str());
79 "CorrectionFileNameList",
81 "List of file names that store the correction factors for simulation.");
82 declareProperty(
"MapFilePath",
83 m_mapFile =
"ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run3_Consolidated_Recommendation_v4/map2.txt",
84 "Full path to the map file");
86 "RecoKey", m_recoKey =
"",
"Key associated with reconstruction");
88 "IdKey", m_idKey =
"",
"Key associated with identification working point");
90 "IsoKey", m_isoKey =
"",
"Key associated with isolation working point");
92 "TriggerKey", m_trigKey =
"",
"Key associated with trigger working point");
93 declareProperty(
"ForceDataType",
94 m_dataTypeOverwrite = -1,
95 "Force the DataType of the electron to specified value (to "
96 "circumvent problem of incorrect DataType for forward "
97 "electrons in some old releases)");
99 "ResultPrefix", m_resultPrefix =
"",
"The prefix string for the result");
100 declareProperty(
"ResultName", m_resultName =
"",
"The string for the result");
101 declareProperty(
"CorrelationModel",
102 m_correlation_model_name =
"SIMPLIFIED",
103 "Uncertainty correlation model. At the moment TOTAL, FULL, "
104 "SIMPLIFIED, SYST, MCTOYS and COMBMCTOYS are implemented. "
105 "SIMPLIFIED is the default option.");
106 declareProperty(
"NumberOfToys",
107 m_number_of_toys = 100,
108 "Number of ToyMC replica, affecting MCTOYS and COMBMCTOYS "
109 "correlation models only.");
110 declareProperty(
"MCToySeed",
112 "Seed for ToyMC replica, affecting MCTOYS and COMBMCTOYS "
113 "correlation models only.");
114 declareProperty(
"MCToyScale",
116 "Scales Toy systematics up by this factor, affecting MCTOYS "
117 "and COMBMCTOYS correlation models only.");
120 m_uncorrSimplfEtaBinsUser = { 0.0, 1.37, 4.9 },
121 "Custom Eta/Pt binning for the SIMPLIFIED correlation model.");
124 m_uncorrSimplfEtBinsUser = { 4000,
134 "Custom Eta/Pt binning for the SIMPLIFIED correlation model.");
135 declareProperty(
"EventInfoCollectionName",
136 m_eventInfoCollectionName =
"EventInfo",
137 "The EventInfo Collection Name");
138 declareProperty(
"UseRandomRunNumber", m_useRandomRunNumber =
true);
139 declareProperty(
"DefaultRandomRunNumber", m_defaultRandomRunNumber = 999999);
157 ATH_MSG_ERROR(
"CorrectionFileNameList as well as SFKeys are empty! Please "
158 "configure it properly...");
159 return StatusCode::FAILURE;
175 return StatusCode::FAILURE;
185 ATH_MSG_ERROR(
"No Root file input specified, and not available map file");
186 return StatusCode::FAILURE;
194 if (filename.empty()) {
196 return StatusCode::FAILURE;
203 if (ifile.find(
"efficiencySF.") != std::string::npos) {
206 if (ifile.find(
"efficiencySF.offline") != std::string::npos) {
209 if (ifile.find(
"efficiencySF.offline.RecoTrk") != std::string::npos) {
212 if (ifile.find(
"efficiencySF.offline.Fwd") != std::string::npos) {
215 if (ifile.find(
"efficiencySF.Isolation") != std::string::npos) {
218 if (ifile.find(
"efficiency.") != std::string::npos) {
221 if (ifile.find(
"efficiencySF.ChargeID") != std::string::npos) {
225 ATH_MSG_ERROR(
"Could NOT find systematics Substring file name "
227 return StatusCode::FAILURE;
244 ATH_MSG_ERROR(
"Something went wrong when specifying bins for the "
245 "SIMPLIFIED correlation model ");
246 return StatusCode::FAILURE;
254 return StatusCode::FAILURE;
288 "Could not initialize the TElectronEfficiencyCorrectionTool!");
289 return StatusCode::FAILURE;
294 std::map<float, std::vector<float>> tmp;
297 for (
const auto& i : tmp) {
306 " but input does not contain necessary histograms.");
307 return StatusCode::FAILURE;
313 return StatusCode::FAILURE;
317 ATH_MSG_ERROR(
"(registerSystematics() != StatusCode::SUCCESS)");
318 return StatusCode::FAILURE;
323 return StatusCode::FAILURE;
327 resetAccessor (
m_accessors->randomrunnumber, *
this,
"RandomRunNumber");
330 return StatusCode::SUCCESS;
336 double& efficiencyScaleFactor)
const
349 double& efficiencyScaleFactor,
354 efficiencyScaleFactor = 1;
358 if (!acc.randomrunnumber.isAvailable(eventInfo)) {
360 "Pileup tool not run before using ElectronEfficiencyTool! SFs do not "
361 "reflect PU distribution in data");
364 runNumber = acc.randomrunnumber(eventInfo);
369 double cluster_eta(-9999.9);
371 auto cluster = acc.caloClusterAcc (inputObject) [0].value();
374 if (acc.accAuthor.isAvailable(inputObject) &&
376 cluster_eta = acc.clusterEtaAcc (cluster);
378 cluster_eta = acc.clusterEtaBEAcc (cluster, 2);
383 const double energy = acc.clusterEAcc(cluster);
384 const double parEta = acc.m_eta(inputObject);
385 const double coshEta = std::cosh(parEta);
386 double et = (coshEta != 0.) ? energy / coshEta : 0.;
395 efficiencyScaleFactor);
401 const double cluster_eta,
402 const unsigned int runNumber,
403 double& efficiencyScaleFactor)
const
422 int indexCorrelated = -999;
423 int correlatedSign = 0;
424 if (!(doSFOnly || doToys || isTotal) && (isFull || isSimplified)) {
426 bool isUncorr = (sysName.find(
"UncorrUnc") != std::string::npos);
427 int currentUncorReg = -999;
432 }
else if (isSimplified) {
435 if (currentUncorReg < 0) {
447 if (sysName.find(
"CorrUnc") != std::string::npos) {
449 const auto varNumEnd = sysName.rfind(
"__");
450 const auto varNumBegin = sysName.rfind(
"NP") + 2;
452 std::stoi(sysName.substr(varNumBegin, (varNumEnd - varNumBegin)));
454 indexCorrelated = varIndex;
458 indexCorrelated = varIndex;
476 efficiencyScaleFactor = 1;
480 efficiencyScaleFactor =
result.SF;
492 efficiencyScaleFactor = sys;
499 return HelperFunc(efficiencyScaleFactor, sys);
502 return HelperFunc(efficiencyScaleFactor, -1 * sys);
506 else if (unCorrSign!=0) {
507 sys = unCorrSign *
result.UnCorr;
508 return HelperFunc(efficiencyScaleFactor, sys);
521 return HelperFunc(efficiencyScaleFactor, sys);
527 return HelperFunc(efficiencyScaleFactor, sys);
531 if (correlatedSign != 0) {
532 sys = correlatedSign *
result.Corr[indexCorrelated];
533 return HelperFunc(efficiencyScaleFactor, sys);
542 double efficiencyScaleFactor = 1.0;
547 dec(inputObject) = efficiencyScaleFactor;
559 if (systematic.
empty()) {
565 return (sys.begin()->ensembleContains(systematic));
567 return (sys.find(systematic) != sys.end());
585 "Failed to add systematic to list of recommended systematics.");
586 return StatusCode::FAILURE;
588 return StatusCode::SUCCESS;
614 systConfig, affectingSys, filteredSys)) {
616 "Unsupported combination of systematic variations passed to the tool!");
617 return StatusCode::FAILURE;
620 if (filteredSys.
size() > 1) {
622 "More than one systematic variation passed at the same time");
623 return StatusCode::FAILURE;
626 if (filteredSys.
empty() && !systConfig.
empty()) {
628 for (
const auto& syst : systConfig) {
634 itr =
m_systFilter.insert(std::make_pair(systConfig, filteredSys)).first;
639 return StatusCode::SUCCESS;
692 prefixUncorr + Form(
"UncorrUncertaintyNP%d", i), 1);
694 prefixUncorr + Form(
"UncorrUncertaintyNP%d", i), -1);
703 prefixUncorr + Form(
"UncorrUncertaintyNP%d", i), 1);
705 prefixUncorr + Form(
"UncorrUncertaintyNP%d", i), -1);
712 return StatusCode::SUCCESS;
717 const double cluster_eta,
718 const double et)
const
720 int ptbin = std::as_const(*m_UncorrRegions).GetXaxis()->FindBin(
et) - 1;
722 ptbin >= std::as_const(*m_UncorrRegions).GetXaxis()->GetNbins()) {
724 " Found electron with Et = "
725 <<
et / 1000. <<
" GeV, where you specified boundaries of ["
726 << std::as_const(*m_UncorrRegions).GetXaxis()->GetBinLowEdge(1) <<
","
730 std::as_const(*m_UncorrRegions).GetXaxis()->GetNbins())
731 <<
"] for the SIMPLIFIED correlation model ");
735 std::as_const(*m_UncorrRegions).GetYaxis()->FindBin(std::abs(cluster_eta)) -
738 etabin >= std::as_const(*m_UncorrRegions).GetYaxis()->GetNbins()) {
740 " Found electron with |eta| = "
741 << std::abs(cluster_eta) <<
", where you specified boundaries of ["
742 << std::as_const(*m_UncorrRegions).GetYaxis()->GetBinLowEdge(1) <<
","
746 std::as_const(*m_UncorrRegions).GetYaxis()->GetNbins())
747 <<
"] for the SIMPLIFIED correlation model ");
756 const double cluster_eta,
757 const double et)
const
762 float cluster_eta_electron = 0;
765 for (; itr_ptBEGIN != itr_ptEND; ++itr_ptBEGIN) {
766 auto itr_ptBEGINplusOne = itr_ptBEGIN;
767 ++itr_ptBEGINplusOne;
770 if (
et >= itr_ptBEGIN->first &&
772 if ((itr_ptBEGIN->second).at(0) >= 0) {
773 cluster_eta_electron = std::abs(cluster_eta);
775 cluster_eta_electron = (cluster_eta);
777 for (
unsigned int etab = 0; etab < ((itr_ptBEGIN->second).size());
779 unsigned int etabnext = etab + 1;
782 if ((cluster_eta_electron) >= (itr_ptBEGIN->second).at(etab) &&
783 (etabnext == itr_ptBEGIN->second.size() ||
784 cluster_eta_electron < itr_ptBEGIN->second.at(etabnext))) {
796 reg += (itr_ptBEGIN->second).size();
800 "returning the maximum index");
819 int currentSystRegion = -999;
820 double cluster_eta(-9999.9);
823 et = acc.m_pt(inputObject);
824 const auto cluster = acc.caloClusterAcc (inputObject) [0].value();
825 cluster_eta = acc.clusterEtaBEAcc (cluster, 2);
840 return currentSystRegion;
846 const std::string& idkey,
847 const std::string& isokey,
848 const std::string& trigkey)
856 if (!value.empty()) {
859 if (mapFileName.empty()) {
861 "Map file does not exist, Please set the path and version properly..");
866 <<
" does not exist in the map file, Please configure it properly..");
868 return StatusCode::FAILURE;
872 return StatusCode::SUCCESS;
903 return StatusCode::SUCCESS;
908 if (status == StatusCode::SUCCESS) {
915 :
"fast simulation")));
922 "Applying SF corrections to data while they make sense only for MC");
929 return StatusCode::SUCCESS;
937 return StatusCode::SUCCESS;
939 return StatusCode::SUCCESS;
942 return StatusCode::SUCCESS;
950#ifndef XAOD_STANDALONE
952 std::string dataType(
"");
956 if (!(dataType ==
"IS_SIMULATION")) {
959 return StatusCode::SUCCESS;
962 if (dataType ==
"IS_SIMULATION") {
963 std::string simType(
"");
968 std::transform(simType.begin(), simType.end(), simType.begin(), ::toupper);
969 result = (simType.find(
"ATLFAST") == std::string::npos)
972 return StatusCode::SUCCESS;
982 std::string simType(
"");
987 return StatusCode::SUCCESS;
990 std::transform(simType.begin(), simType.end(), simType.begin(), ::toupper);
991 result = (simType.find(
"ATLFAST") == std::string::npos)
994 return StatusCode::SUCCESS;
998 return StatusCode::FAILURE;
1013 acc.m_sfDec(electron) = sf;
1014 acc.m_validDec(electron) =
true;
1017 acc.m_sfDec(electron) = sf;
1018 acc.m_validDec(electron) =
false;
1021 throw std::runtime_error(
"Error in getEfficiencyScaleFactor");
1031 auto eventInfo = acc.m_eventInfo(event);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Base class for elements of a container that can have aux data.
float et(const xAOD::jFexSRJetRoI *j)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
static std::string retrieveMetadata(const std::string &folder, const std::string &key, const ServiceHandle< StoreGateSvc > &inputMetaStore)
method that always returns as a string you can use from, e.g, pyROOT with evt = ROOT....
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.
This module implements the central registry for handling systematic uncertainties with CP tools.
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
StatusCode registerSystematics(const IReentrantSystematicsTool &tool)
effects: register all the systematics from the tool
Class to wrap a set of SystematicVariations.
bool empty() const
returns: whether the set is empty
std::pair< unsigned, float > getToyVariationByBaseName(const std::string &basename) const
the toy variation for the given basename
const_iterator begin() const
description: const iterator to the beginning of the set
size_t size() const
returns: size of the set
static StatusCode filterForAffectingSystematics(const SystematicSet &systConfig, const SystematicSet &affectingSystematics, SystematicSet &filteredSystematics)
description: filter the systematics for the affected systematics returns: success guarantee: strong f...
bool empty() const
returns: whether this is an empty systematic, i.e.
static SystematicVariation makeToyEnsemble(const std::string &basename)
constructor for toy systematics ensemble
SG::Decorator< T, ALLOC > Decorator
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
std::string getValueByKey(const std::string &mapFile, const std::string &key)
std::string convertToOneKey(const std::string &recokey, const std::string &idkey, const std::string &isokey, const std::string &trigkey)
Information about type of data used to fill particle.
Information about type of data used to fill particle.
ObjectId< ContainerId::electron > ElectronId
ObjectRange< ContainerId::eventContext > EventContextRange
ObjectId< ContainerId::eventContext > EventContextId
ObjectRange< ContainerId::electron > ElectronRange
ObjectId< ContainerId::eventInfo > EventInfoId
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
EventInfo_v1 EventInfo
Definition of the latest event info version.
FileMetaData_v1 FileMetaData
Declare the latest version of the class.
Electron_v1 Electron
Definition of the current "egamma version".
Extra patterns decribing particle interation process.