55int main(
int argc,
char* argv[])
58 const char* filename =
nullptr;
59 bool debug =
false, cmdline_error =
false, toys =
false;
60 for(
int i=1;i<argc;++i)
62 if(
string(argv[i]) ==
"--debug")
debug =
true;
63 else if(
string(argv[i]) ==
"--toys") toys =
true;
64 else if(!filename && *argv[i]!=
'-') filename = argv[i];
65 else cmdline_error =
true;
67 if(!filename || cmdline_error)
69 Error(
MSGSOURCE,
"No file name received!");
70 Error(
MSGSOURCE,
" Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
73 #ifdef XAOD_STANDALONE
75 TFile*
file = TFile::Open(filename,
"READ");
83 StatusCode::enableFailure();
87 TString
file(filename);
89 event.readFrom(
file).ignore();
90 Long64_t
entries =
event.getEntries();
95 Info(
MSGSOURCE,
"Configuring the electron CP tools");
97 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
99 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
101 std::map<string,string> legsPerTool;
104 vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
106 vector<std::array<string,2>> toolConfigs = {
109 {
"e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose, e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
110 "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"},
112 {
"e12_lhloose_L1EM10VH, e17_lhvloose_nod0, e24_lhvloose_nod0_L1EM20VH",
113 "DI_E_2015_e12_lhloose_L1EM10VH_2016_e17_lhvloose_nod0_2017_2018_e24_lhvloose_nod0_L1EM20VH"},
115 {
"e17_lhvloose_nod0_L1EM15VHI",
116 "DI_E_2015_e12_lhloose_L1EM10VH_2016_e17_lhvloose_nod0_2017_2018_e17_lhvloose_nod0_L1EM15VHI"}
119 const char* mapPath =
"ElectronEfficiencyCorrection/2015_2017/"
120 "rel21.2/Consolidation_September2018_v1/map2.txt";
121 for(
auto& cfg : toolConfigs)
124 string name =
"AsgElectronEfficiencyCorrectionTool/"
125 + ((j?
"ElTrigEff_" :
"ElTrigSF_")
126 + std::to_string(factory.size()/2));
127 auto t = factory.emplace(factory.end(), name);
128 t->setProperty(
"MapFilePath", mapPath).ignore();
129 t->setProperty(
"TriggerKey",
string(j?
"":
"Eff_") + cfg[cKEY]).ignore();
130 t->setProperty(
"IdKey",
"Tight").ignore();
131 t->setProperty(
"IsoKey",
"FCTight").ignore();
132 t->setProperty(
"CorrelationModel",
"TOTAL").ignore();
134 if(t->initialize() != StatusCode::SUCCESS)
136 Error(
MSGSOURCE,
"Unable to initialize the electron CP tool <%s>!",
140 auto& handles = (j? electronSFTools : electronEffTools);
141 handles.push_back(t->getHandle());
144 name = handles[handles.size()-1].name();
145 legsPerTool[name] = cfg[cLEGS];
151 Info(
MSGSOURCE,
"Configuring the muon CP tools");
153 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
155 muonTool.
setProperty(
"MuonQuality",
"Tight").ignore();
157 if(muonTool.
initialize() != StatusCode::SUCCESS)
159 Error(
MSGSOURCE,
"Unable to initialize the muon CP tool!");
162 muonTools.push_back(muonTool.
getHandle());
166 Info(
MSGSOURCE,
"Configuring the global trigger SF tool");
168 myTool.
setProperty(
"ElectronEfficiencyTools", electronEffTools).ignore();
169 myTool.
setProperty(
"ElectronScaleFactorTools", electronSFTools).ignore();
170 myTool.
setProperty(
"MuonTools", muonTools).ignore();
171 std::map<std::string, std::string> triggers;
173 "mu20_iloose_L1MU15_OR_mu50"
175 "|| e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose"
176 "|| 2e12_lhloose_L12EM10VH";
178 "mu26_ivarmedium_OR_mu50"
180 "|| e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
181 "|| 2e17_lhvloose_nod0";
182 std::string only2e24 =
183 "mu26_ivarmedium_OR_mu50"
185 "|| e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
186 "|| 2e24_lhvloose_nod0";
187 std::string nominal = only2e24 +
"|| 2e17_lhvloose_nod0_L12EM15VHI";
188 triggers[
"324320-326695"] = nominal;
189 triggers[
"326834-328393"] = only2e24;
190 triggers[
"329385-364292"] = nominal;
191 myTool.
setProperty(
"TriggerCombination", triggers).ignore();
192 myTool.
setProperty(
"ListOfLegsPerTool", legsPerTool).ignore();
195 if(toys) myTool.
setProperty(
"NumberOfToys", 1000).ignore();
196 if(myTool.
initialize() != StatusCode::SUCCESS)
198 Error(
MSGSOURCE,
"Unable to initialize the TrigGlob tool!");
204 const unsigned periodRuns[] = {
206 276073, 278727, 279932, 280423, 281130, 282625,
208 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
209 305359, 309311, 310015,
211 325713, 329385, 330857, 332720, 334842, 336497, 336832, 338183,
213 348885, 349534, 350310, 352274, 354107, 354826, 355261, 355331,
214 355529, 357050, 359191, 361635, 361738, 363664
216 std::uniform_int_distribution<unsigned> uniformPdf(0,
217 sizeof(periodRuns)/
sizeof(*periodRuns) - 1);
218 std::default_random_engine randomEngine;
225 Info(
MSGSOURCE,
"Starting the event loop");
227 double nSuitableEvents = 0., sumW = 0.;
229 for(Long64_t entry = 0; entry <
entries; ++entry)
231 event.getEntry(entry);
235 event.retrieve(eventInfo,
"EventInfo").ignore();
236 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
237 RandomRunNumberDec(*eventInfo) = runNumber;
239 unsigned nTrig1L = 0, nTrig2mu = 0;
241 vector<const xAOD::Electron*> myTriggeringElectrons;
243 event.retrieve(electrons,
"Electrons").ignore();
244 for(
auto electron : *electrons)
246 if(!electron->caloCluster())
continue;
247 float eta = fabs(electron->caloCluster()->etaBE(2));
248 float pt = electron->pt();
249 if(pt<10e3f || eta>=2.47)
continue;
250 if(!truthType.isAvailable(*electron))
continue;
251 if(!truthOrigin.isAvailable(*electron))
continue;
252 int t = truthType(*electron), o = truthOrigin(*electron);
253 if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
255 if((runNumber>=326834 && runNumber<=328393 && pt<25e3f)
256 || (runNumber>290000 && pt<18e3f)
257 || (pt<13e3f))
continue;
259 if(pt >= (runNumber>290000? 27e3f : 25e3f)) ++nTrig1L;
261 myTriggeringElectrons.push_back(electron);
264 vector<const xAOD::Muon*> myTriggeringMuons;
266 event.retrieve(muons,
"Muons").ignore();
267 for(
auto muon : *muons)
269 float pt = muon->pt();
270 if(pt<10e3f || fabs(muon->eta())>=2.5)
continue;
271 auto mt = muon->muonType();
272 if(mt!=xAOD::Muon::Combined && mt!=xAOD::Muon::MuonStandAlone)
continue;
273 auto& mtp = *(muon->primaryTrackParticle());
274 if(!truthType.isAvailable(mtp))
continue;
275 if(!truthOrigin.isAvailable(mtp))
continue;
276 int t = truthType(mtp), o = truthOrigin(mtp);
277 if(t!=6 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
279 if(pt < 10e3f)
continue;
281 if(pt >= (runNumber>290000? 27.3e3f : 21e3f)) ++nTrig1L;
283 if(pt >= (runNumber>290000? 23e3f : 19e3f)) ++nTrig2mu;
285 myTriggeringMuons.push_back(muon);
290 && myTriggeringElectrons.size()<2
291 && (nTrig2mu==0 || myTriggeringMuons.size()<2))
299 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
300 myTriggeringMuons, sf);
303 nSuitableEvents += 1;
308 Warning(
MSGSOURCE,
"Scale factor evaluation failed");
313 Error(
MSGSOURCE,
"Too many errors reported!");
317 Info(
MSGSOURCE,
"Average scale factor: %f (over %ld events)",
318 sumW / nSuitableEvents,
long(nSuitableEvents));
319 #ifndef XAOD_STANDALONE
322 return errors? 4 : 0;