ATLAS Offline Software
Loading...
Searching...
No Matches
MuonEfficiencyScaleFactorsTest.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4
9// System include(s):
10#include <memory>
11#include <cstdlib>
12#include <string>
13#include <map>
14
15// ROOT include(s):
16#include <TFile.h>
17#include <TError.h>
18#include <TStopwatch.h>
19#include <TString.h>
20
21// Infrastructure include(s):
22#include "xAODRootAccess/Init.h"
25#include "AsgMessaging/Check.h"
26
27// EDM include(s):
31
32// Local include(s):
33
35
38
39#include "AsgTools/ToolHandle.h"
43
45
46#define CHECK_CPCorr(Arg) \
47 if (Arg.code() == CP::CorrectionCode::Error){ \
48 Error(#Arg,"Correction Code 'Error' (returned in line %i) ",__LINE__); \
49 return 1; \
50 }
51#define CHECK_CPSys(Arg) \
52 if (Arg.isFailure()){ \
53 Warning(#Arg,"Unsupported systematic (in line %i) ",__LINE__); \
54 }
55
57
59
60EffiToolInstance createSFTool(const std::string& WP, const std::string& CustomInput, bool uncorrelate_Syst) {
61 EffiToolInstance tool(std::string("CP::MuonEfficiencyScaleFactors/EffiTool_") + WP);
62
63 tool.setProperty("WorkingPoint", WP).isSuccess();
64 tool.setProperty("UncorrelateSystematics", uncorrelate_Syst).isSuccess();
65 tool.setProperty("LowPtThreshold", 15.e3).isSuccess();
66 tool.retrieve().isSuccess();
67
68 if (!CustomInput.empty()) tool.setProperty("CustomInputFolder", CustomInput).isSuccess();
69
70 return tool;
71}
72int main(int argc, char* argv[]) {
73
74 // force strict checking of return codes
75 StatusCode::enableFailure();
76 StatusCode::enableFailure();
77
78 // The application's name:
79 const char* APP_NAME = argv[0];
80
81 // this default is for MC16a -> data2016
82 std::string prwFilename = "dev/PileupReweighting/share/DSID361xxx/pileup_mc20a_dsid361107_FS.root";
83 std::string ilumiFilename = "GoodRunsLists/data16_13TeV/20180129/PHYS_StandardGRL_All_Good_25ns_297730-311481_OflLumi-13TeV-009.root";
84 std::string InFile = "";
85 long long int nmax = -1;
86 // read the config provided by the user
87 for (int k = 1; k < argc - 1; ++k) {
88 if (std::string(argv[k]).find("-i") == 0) {
89 InFile = argv[k + 1];
90 }
91 if (std::string(argv[k]).find("-n") == 0) {
92 nmax = atoi(argv[k + 1]);
93 }
94 if (std::string(argv[k]).find("--ilumi") == 0) {
95 ilumiFilename = argv[k + 1];
96 }
97 if (std::string(argv[k]).find("--prw") == 0) {
98 prwFilename = argv[k + 1];
99 }
100 }
101 // Initialise the application:
103
104 // Open the input file:
105 Info(APP_NAME, "Opening file: %s", InFile.c_str());
106 std::unique_ptr<TFile> ifile(TFile::Open(InFile.c_str(), "READ"));
107 if (!ifile.get()) {
108 Error(APP_NAME, " Unable to load xAOD input file");
109 }
110
111 std::string DefaultCalibRelease("");
112 if (argc == 3) {
113 DefaultCalibRelease = argv[2];
114 std::cout << "Found second argument (" << DefaultCalibRelease << "), assuming it is the CalibrationRelease..." << std::endl;
115 }
116
117 // Create a TEvent object:
118 xAOD::TEvent event;
119 RETURN_CHECK(APP_NAME, event.readFrom(ifile.get(), xAOD::TEvent::kClassAccess));
120 Info(APP_NAME, "Number of events in the file: %i", static_cast<int>(event.getEntries()));
121
122 Long64_t entries = event.getEntries();
123 if ((nmax != -1) && (nmax<entries)) entries = nmax;
124
125 TStopwatch tsw;
126 tsw.Start();
127 double t_init = tsw.CpuTime();
128 tsw.Reset();
129
130 // instantiate the PRW tool which is needed to get random runnumbers
131 asg::StandaloneToolHandle < CP::IPileupReweightingTool > m_prw_tool("CP::PileupReweightingTool/myTool");
132 // This is just a placeholder configuration for testing. Do not use these config files for your analysis!
133 std::vector<std::string> m_ConfigFiles {
134 prwFilename
135 };
136 std::vector<std::string> m_LumiCalcFiles {
137 ilumiFilename
138 };
139 ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("ConfigFiles", m_ConfigFiles));
140 ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("LumiCalcFiles", m_LumiCalcFiles));
141
142 ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("DataScaleFactor", 1.0 / 1.09));
143 ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("DataScaleFactorUP", 1.));
144 ASG_CHECK_SA(APP_NAME, m_prw_tool.setProperty("DataScaleFactorDOWN", 1.0 / 1.18));
145 // Initialize the PRW tool
146 ASG_CHECK_SA(APP_NAME, m_prw_tool.initialize());
147
148 const std::vector<std::string> WPs {
149 // reconstruction WPs
150 "Loose", "Medium", "Tight", "HighPt", "LowPt",
151 // track-to-vertex-association WPs
152 "TTVA",
153 // BadMuon veto SFs
154 //"BadMuonVeto_HighPt",
155 // isolation WPs
156 "Loose_VarRadIso", "Tight_VarRadIso", "PflowLoose_VarRadIso", "PflowTight_VarRadIso"
157 };
158
159 std::vector<EffiToolInstance> EffiTools;
160 for (auto& WP : WPs) {
161 EffiTools.push_back(createSFTool(WP, DefaultCalibRelease, false));
162 }
163 // Start looping over the events:
164 tsw.Start();
165
166 // prepare a vector to hold SF replicas
167 // the size will tell the tool how many you want
168 // -> we will try 50!
169 std::vector<float> replicas(50);
170 for (Long64_t entry = 0; entry < entries; ++entry) {
171
172 // Tell the object which entry to look at:
173 event.getEntry(entry);
174
175 // Apply PRW to xAOD::EventInfo
176 const xAOD::EventInfo* ei = 0;
177 RETURN_CHECK(APP_NAME, event.retrieve(ei, "EventInfo"));
178 //Apply the prwTool first before calling the efficiency correction methods
179 RETURN_CHECK(APP_NAME, m_prw_tool->apply(*ei));
180 Info(APP_NAME, "===>>> start processing event #%i, run #%i %i events processed so far <<<===", static_cast<int>(ei->eventNumber()), static_cast<int>(ei->runNumber()), static_cast<int>(entry));
181
182 // Get the muons from the event:
183 const xAOD::MuonContainer* muons = 0;
184 RETURN_CHECK(APP_NAME, event.retrieve(muons, "Muons"));
185 Info(APP_NAME, "Number of muons: %i", static_cast<int>(muons->size()));
186
187 for (const auto *mu : *muons) {
188 // Print some info about the selected muon:
189 Info(APP_NAME, " Selected muon: eta = %g, phi = %g, pt = %g", mu->eta(), mu->phi(), mu->pt());
190 for (auto& effi : EffiTools) {
191 for (auto& syst : CP::make_systematics_vector(effi->recommendedSystematics())) {
192 CHECK_CPSys(effi->applySystematicVariation(syst));
193 float nominalSF = 1.;
194 float data_Eff = 1.;
195 float mc_Eff = 1.;
196 CHECK_CPCorr(effi->getEfficiencyScaleFactor(*mu, nominalSF));
197 CHECK_CPCorr(effi->getDataEfficiency(*mu, data_Eff));
198 CHECK_CPCorr(effi->getMCEfficiency(*mu, mc_Eff));
199 std::string sysName = (syst.name().empty()) ? "Nominal" : syst.name();
200 Info(APP_NAME, "Applied %s variation. The scale-factor is %.3f, the data-efficiency is %.3f and the mc-efficiency is %.3f", sysName.c_str(), nominalSF, data_Eff, mc_Eff);
201
202 CHECK_CPCorr(effi->getEfficiencyScaleFactorReplicas(*mu, replicas));
203 for (size_t t = 0; t < replicas.size(); t++) {
204 Info(APP_NAME, " scaleFactor Replica %d = %.8f", static_cast<int>(t), replicas[t]);
205 }
206 }
207 }
208 }
209 // Close with a message:
210 Info(APP_NAME, "===>>> done processing event #%i, "
211 "run #%i %i events processed so far <<<===", static_cast<int>(ei->eventNumber()), static_cast<int>(ei->runNumber()), static_cast<int>(entry + 1));
212 }
213 double t_run = tsw.CpuTime() / entries;
214 Info(APP_NAME, " MCP init took %gs", t_init);
215 Info(APP_NAME, " time per event: %gs", t_run);
216 //get smart slimming list
218
219 // Return gracefully:
220 return 0;
221}
#define APP_NAME
#define ASG_CHECK_SA(SOURCE, EXP)
Helper macro for checking the status code of a call outside of an ASG tool.
Definition Check.h:76
#define CHECK_CPSys(Arg)
#define CHECK_CPCorr(Arg)
a simple testing macro for the MuonEfficiencyScaleFactors class shamelessly stolen from CPToolTests....
asg::StandaloneToolHandle< CP::IMuonEfficiencyScaleFactors > EffiToolInstance
Example of how to run the MuonEfficiencyCorrections package to obtain information from muons.
EffiToolInstance createSFTool(const std::string &WP, const std::string &CustomInput, bool uncorrelate_Syst)
const int nmax(200)
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition ReturnCheck.h:26
static const Attributes_t empty
size_type size() const noexcept
Returns the number of elements in the collection.
an "initializing" ToolHandle for stand-alone applications
StatusCode setProperty(const std::string &name, T2 &&value)
StatusCode initialize()
initialize the tool, will fail if the tool was already initialized
uint32_t runNumber() const
The current event's run number.
uint64_t eventNumber() const
The current event's event number.
ReadStats & stats()
Access the object belonging to the current thread.
Definition IOStats.cxx:17
static IOStats & instance()
Singleton object accessor.
Definition IOStats.cxx:11
void printSmartSlimmingBranchList(bool autoIncludeLinks=false) const
Print the accessed variables, formatted for smart slimming.
Tool for accessing xAOD files outside of Athena.
@ kClassAccess
Access auxiliary data using the aux containers.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
int main()
Definition hello.cxx:18
double entries
Definition listroot.cxx:49
std::vector< CP::SystematicSet > make_systematics_vector(const SystematicSet &systematics)
utility functions for working with systematics
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31
EventInfo_v1 EventInfo
Definition of the latest event info version.
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".