99int main(
int argc,
char* argv[])
102 const char* filename =
nullptr;
103 bool debug =
false, cmdline_error =
false, toys =
false;
104 for(
int i=1;i<argc;++i)
106 if(
string(argv[i]) ==
"--debug")
debug =
true;
107 else if(
string(argv[i]) ==
"--toys") toys =
true;
108 else if(!filename && *argv[i]!=
'-') filename = argv[i];
109 else cmdline_error =
true;
111 if(!filename || cmdline_error)
113 Error(
MSGSOURCE,
"No file name received!");
114 Error(
MSGSOURCE,
" Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
117 #ifdef XAOD_STANDALONE
119 TFile*
file = TFile::Open(filename,
"READ");
122 Error(
MSGSOURCE,
"Unable to open file!");
127 StatusCode::enableFailure();
131 TString
file(filename);
133 event.readFrom(
file).ignore();
134 Long64_t
entries =
event.getEntries();
139 Info(
MSGSOURCE,
"Configuring the electron CP tools");
141 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
143 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
145 std::map<std::string,std::string> legsPerTool;
147 std::map<std::string,std::string> tagsPerTool;
149 std::map<std::string,std::string> legsPerTag;
153 std::bernoulli_distribution bernoulliPdf(0.9);
156 vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
157 enum{ cLEGS, cTAG, cKEY, cPID, cISO };
158 std::vector<std::array<std::string,5> > toolConfigs = {
161 {
"e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose",
"Signal",
"2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose",
"Medium",
""},
163 {
"e12_lhloose_L1EM10VH",
"*,Signal",
"2015_e12_lhloose_L1EM10VH",
"LooseBLayer",
""}
166 const char* mapPath =
"ElectronEfficiencyCorrection/2015_2017/"
167 "rel21.2/Moriond_February2018_v2/map6.txt";
168 for(
auto& cfg : toolConfigs)
171 string name =
"AsgElectronEfficiencyCorrectionTool/"
172 + ((j?
"ElTrigEff_" :
"ElTrigSF_")
173 + std::to_string(factory.size()/2));
174 auto t = factory.emplace(factory.end(), name);
175 t->setProperty(
"MapFilePath", mapPath).ignore();
176 t->setProperty(
"TriggerKey",
string(j?
"":
"Eff_") + cfg[cKEY]).ignore();
177 t->setProperty(
"IdKey", cfg[cPID]).ignore();
178 t->setProperty(
"IsoKey", cfg[cISO]).ignore();
180 t->setProperty(
"CorrelationModel",
"TOTAL").ignore();
182 if(t->initialize() != StatusCode::SUCCESS)
184 Error(
MSGSOURCE,
"Unable to initialize the electron CP tool <%s>!",
188 auto& handles = (j? electronSFTools : electronEffTools);
189 handles.push_back(t->getHandle());
192 name = handles[handles.size()-1].name();
193 legsPerTool[name] = cfg[cLEGS];
194 tagsPerTool[name] = cfg[cTAG];
197 for(
auto& tag : ::split_comma_delimited(cfg[cTAG]))
199 if(legsPerTag[tag]==
"") legsPerTag[tag] = cfg[cLEGS];
200 else legsPerTag[tag] +=
"," + cfg[cLEGS];
208 Info(
MSGSOURCE,
"Configuring the global trigger SF tool");
210 myTool.
setProperty(
"ElectronEfficiencyTools", electronEffTools).ignore();
211 myTool.
setProperty(
"ElectronScaleFactorTools", electronSFTools).ignore();
212 const char* triggers2015 =
213 "e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose"
214 "|| 2e12_lhloose_L12EM10VH";
215 myTool.
setProperty(
"TriggerCombination2015", triggers2015).ignore();
216 myTool.
setProperty(
"LeptonTagDecorations",
"Signal").ignore();
217 myTool.
setProperty(
"ListOfLegsPerTool", legsPerTool).ignore();
218 myTool.
setProperty(
"ListOfTagsPerTool", tagsPerTool).ignore();
219 myTool.
setProperty(
"ListOfLegsPerTag", legsPerTag).ignore();
222 if(toys) myTool.
setProperty(
"NumberOfToys", 1000).ignore();
223 if(myTool.
initialize() != StatusCode::SUCCESS)
225 Error(
MSGSOURCE,
"Unable to initialize the TrigGlob tool!");
231 const unsigned periodRuns[] = {
233 276073, 278727, 279932, 280423, 281130, 282625
235 std::uniform_int_distribution<unsigned> uniformPdf(0,
236 sizeof(periodRuns)/
sizeof(*periodRuns) - 1);
237 std::default_random_engine randomEngine;
244 Info(
MSGSOURCE,
"Starting the event loop");
246 double nSuitableEvents = 0., sumW = 0.;
248 for(Long64_t entry = 0; entry <
entries; ++entry)
250 event.getEntry(entry);
254 event.retrieve(eventInfo,
"EventInfo").ignore();
255 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
256 RandomRunNumberDec(*eventInfo) = runNumber;
257 vector<const xAOD::Electron*> myTriggeringElectrons;
259 event.retrieve(electrons,
"Electrons").ignore();
260 for(
auto electron : *electrons)
262 if(!electron->caloCluster())
continue;
263 float eta = fabs(electron->caloCluster()->etaBE(2));
264 float pt = electron->pt();
265 if(pt<10e3f || eta>=2.47)
continue;
266 if(!truthType.isAvailable(*electron))
continue;
267 if(!truthOrigin.isAvailable(*electron))
continue;
268 int t = truthType(*electron), o = truthOrigin(*electron);
269 if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
271 if(pt < 13e3f)
continue;
273 myTriggeringElectrons.push_back(electron);
276 vector<const xAOD::Muon*> myTriggeringMuons;
280 unsigned nTrig1L = 0;
281 for(
auto electron : myTriggeringElectrons)
283 bool signal = bernoulliPdf(randomEngine);
284 dec_signal(*electron) = signal? 1 : 0;
285 if(signal && electron->pt()>25e3f) ++nTrig1L;
290 && myTriggeringElectrons.size() < 2)
298 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
299 myTriggeringMuons, sf);
302 nSuitableEvents += 1;
307 Warning(
MSGSOURCE,
"Scale factor evaluation failed");
312 Error(
MSGSOURCE,
"Too many errors reported!");
316 Info(
MSGSOURCE,
"Average scale factor: %f (over %ld events)",
317 sumW / nSuitableEvents,
long(nSuitableEvents));
318 #ifndef XAOD_STANDALONE
321 return errors? 4 : 0;