91int main(
int argc,
char* argv[])
94 const char* filename =
nullptr;
95 bool debug =
false, cmdline_error =
false, toys =
false;
96 for(
int i=1;i<argc;++i)
98 if(
string(argv[i]) ==
"--debug")
debug =
true;
99 else if(
string(argv[i]) ==
"--toys") toys =
true;
100 else if(!filename && *argv[i]!=
'-') filename = argv[i];
101 else cmdline_error =
true;
103 if(!filename || cmdline_error)
105 Error(
MSGSOURCE,
"No file name received!");
106 Error(
MSGSOURCE,
" Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
109 #ifdef XAOD_STANDALONE
111 TFile*
file = TFile::Open(filename,
"READ");
114 Error(
MSGSOURCE,
"Unable to open file!");
119 StatusCode::enableFailure();
123 TString
file(filename);
125 event.readFrom(
file).ignore();
126 Long64_t
entries =
event.getEntries();
131 Info(
MSGSOURCE,
"Configuring the electron CP tools");
133 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
135 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
137 std::map<std::string,std::string> legsPerTool;
139 std::map<std::string,std::string> tagsPerTool;
141 std::map<std::string,std::string> legsPerTag;
146 std::bernoulli_distribution bernoulliPdf(0.9);
149 vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
150 enum{ cLEGS, cTAG, cKEY, cPID, cISO };
151 std::vector<std::array<std::string,5> > toolConfigs = {
154 {
"e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
"MyTight",
155 "2016_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
"Tight",
"GradientLoose"},
157 {
"e7_lhmedium_nod0",
"MyMedium,MyTight",
"2016_e7_lhmedium_nod0",
"Medium",
""},
159 {
"e17_lhvloose_nod0",
"*,MyMedium,MyTight",
"2016_e17_lhvloose_nod0",
"LooseBLayer",
""},
162 const char* mapPath =
"ElectronEfficiencyCorrection/2015_2017/"
163 "rel21.2/Moriond_February2018_v2/map6.txt";
164 for(
auto& cfg : toolConfigs)
167 string name =
"AsgElectronEfficiencyCorrectionTool/"
168 + ((j?
"ElTrigEff_" :
"ElTrigSF_")
169 + std::to_string(factory.size()/2));
170 auto t = factory.emplace(factory.end(), name);
171 t->setProperty(
"MapFilePath", mapPath).ignore();
172 t->setProperty(
"TriggerKey",
string(j?
"":
"Eff_") + cfg[cKEY]).ignore();
173 t->setProperty(
"IdKey", cfg[cPID]).ignore();
174 t->setProperty(
"IsoKey", cfg[cISO]).ignore();
176 t->setProperty(
"CorrelationModel",
"TOTAL").ignore();
178 if(t->initialize() != StatusCode::SUCCESS)
180 Error(
MSGSOURCE,
"Unable to initialize the electron CP tool <%s>!",
184 auto& handles = (j? electronSFTools : electronEffTools);
185 handles.push_back(t->getHandle());
188 name = handles[handles.size()-1].name();
189 legsPerTool[name] = cfg[cLEGS];
190 tagsPerTool[name] = cfg[cTAG];
193 for(
auto& tag : ::split_comma_delimited(cfg[cTAG]))
195 if(legsPerTag[tag]==
"") legsPerTag[tag] = cfg[cLEGS];
196 else legsPerTag[tag] +=
"," + cfg[cLEGS];
204 Info(
MSGSOURCE,
"Configuring the muon CP tools");
206 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
208 muonTool.
setProperty(
"MuonQuality",
"Tight").ignore();
210 if(muonTool.
initialize() != StatusCode::SUCCESS)
212 Error(
MSGSOURCE,
"Unable to initialize the muon CP tool!");
215 muonTools.push_back(muonTool.
getHandle());
219 Info(
MSGSOURCE,
"Configuring the global trigger SF tool");
221 myTool.
setProperty(
"ElectronEfficiencyTools", electronEffTools).ignore();
222 myTool.
setProperty(
"ElectronScaleFactorTools", electronSFTools).ignore();
223 myTool.
setProperty(
"MuonTools", muonTools).ignore();
224 const char* triggers2016 =
225 "e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
226 "|| e7_lhmedium_nod0_mu24"
227 "|| 2e17_lhvloose_nod0";
228 myTool.
setProperty(
"TriggerCombination2016", triggers2016).ignore();
231 myTool.
setProperty(
"LeptonTagDecorations",
"MyTight,MyMedium").ignore();
232 myTool.
setProperty(
"ListOfLegsPerTool", legsPerTool).ignore();
233 myTool.
setProperty(
"ListOfTagsPerTool", tagsPerTool).ignore();
234 myTool.
setProperty(
"ListOfLegsPerTag", legsPerTag).ignore();
237 if(toys) myTool.
setProperty(
"NumberOfToys", 1000).ignore();
238 if(myTool.
initialize() != StatusCode::SUCCESS)
240 Error(
MSGSOURCE,
"Unable to initialize the TrigGlob tool!");
246 const unsigned periodRuns[] = {
248 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
249 305359, 309311, 310015
251 std::uniform_int_distribution<unsigned> uniformPdf(0,
252 sizeof(periodRuns)/
sizeof(*periodRuns) - 1);
253 std::default_random_engine randomEngine;
260 Info(
MSGSOURCE,
"Starting the event loop");
262 double nSuitableEvents = 0., sumW = 0.;
264 for(Long64_t entry = 0; entry <
entries; ++entry)
266 event.getEntry(entry);
270 event.retrieve(eventInfo,
"EventInfo").ignore();
271 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
272 RandomRunNumberDec(*eventInfo) = runNumber;
274 unsigned nTrig_e26 = 0, nTrig_e7 = 0, nTrig_e17 = 0;
276 vector<const xAOD::Electron*> myTriggeringElectrons;
278 event.retrieve(electrons,
"Electrons").ignore();
279 for(
auto electron : *electrons)
281 if(!electron->caloCluster())
continue;
282 float eta = fabs(electron->caloCluster()->etaBE(2));
283 float pt = electron->pt();
284 if(pt<10e3f || eta>=2.47)
continue;
285 if(!truthType.isAvailable(*electron))
continue;
286 if(!truthOrigin.isAvailable(*electron))
continue;
287 int t = truthType(*electron), o = truthOrigin(*electron);
288 if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
290 if(pt < 7e3f)
continue;
291 if(pt >= 18e3f) ++nTrig_e17;
293 myTriggeringElectrons.push_back(electron);
296 vector<const xAOD::Muon*> myTriggeringMuons;
298 event.retrieve(muons,
"Muons").ignore();
299 for(
auto muon : *muons)
301 if(runNumber >= 324320)
break;
302 float pt = muon->pt();
303 if(pt<10e3f || fabs(muon->eta())>=2.5)
continue;
304 auto mt = muon->muonType();
305 if(mt!=xAOD::Muon::Combined && mt!=xAOD::Muon::MuonStandAlone)
continue;
306 auto& mtp = *(muon->primaryTrackParticle());
307 if(!truthType.isAvailable(mtp))
continue;
308 if(!truthOrigin.isAvailable(mtp))
continue;
309 int t = truthType(mtp), o = truthOrigin(mtp);
310 if(t!=6 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
312 if(pt < 25.2e3f)
continue;
314 myTriggeringMuons.push_back(muon);
320 for(
auto electron : myTriggeringElectrons)
322 bool medium = bernoulliPdf(randomEngine);
323 dec_medium(*electron) = medium? 1 : 0;
324 if(medium && electron->pt()>8e3f) ++nTrig_e7;
325 bool tight = medium && bernoulliPdf(randomEngine);
326 dec_tight(*electron) = tight? 1 : 0;
327 if(tight && electron->pt()>27e3f) ++nTrig_e26;
332 && (nTrig_e7==0 || myTriggeringMuons.size()==0)
341 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
342 myTriggeringMuons, sf);
345 nSuitableEvents += 1;
350 Warning(
MSGSOURCE,
"Scale factor evaluation failed");
355 Error(
MSGSOURCE,
"Too many errors reported!");
359 Info(
MSGSOURCE,
"Average scale factor: %f (over %ld events)",
360 sumW / nSuitableEvents,
long(nSuitableEvents));
361 #ifndef XAOD_STANDALONE
364 return errors? 4 : 0;