ATLAS Offline Software
Loading...
Searching...
No Matches
fbtTestToyMC.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5//----------------------------------------------------------------------
6//
7// This program provides a toy MC model of a set of pseudoexperiments. It
8// is intended to explore the statistical properties of the fake lepton
9// background estimate for a given set of experiemental conditions (number
10// of events, number of leptons required, typical values of the real and
11// fake efficiencies, etc.)
12//
13//----------------------------------------------------------------------
14
17
20
24
25#include "xAODEgamma/Electron.h"
28
29#include "TFile.h"
30#include "TTree.h"
31#include "TH1F.h"
32#include "TH2F.h"
33#include "TRandom3.h"
34#include "TSystem.h"
35#include <getopt.h>
36#include <unistd.h>
37#include <map>
38#include <chrono>
39#include <fstream>
40#include <memory>
41
43ANA_MSG_SOURCE(Test, "fbtTestToyMC")
44using namespace Test;
45
47 unsigned nevents;
48 unsigned ncases;
49 unsigned minnbaseline;
50 unsigned maxnbaseline;
55 std::string selection;
56 std::string process;
59 std::string saveFileNameBase;
60 std::string mergeFileNameBase;
61 std::string outputdirname;
62 bool verbose;
66};
67
68using namespace FakeBkgTools;
69using namespace std;
70
71
72
75
76StatusCode initialize ATLAS_NOT_THREAD_SAFE(CP::BaseFakeBkgTool& tool, const std::vector<std::string>& input, const std::string& selection, const std::string& process, bool verbose);
77StatusCode writeXML(const string& name, int type);
78StatusCode writeROOT(const string& name, int type, float realeff_mean, float fakeeff_mean, float eff_spread, float eff_delta_with_pt);
79StatusCode setupEfficiencies ATLAS_NOT_THREAD_SAFE();
80StatusCode lookupEfficiencies ATLAS_NOT_THREAD_SAFE(xAOD::IParticle& lepton, ParticleData& lepton_data);
81
82StatusCode parseArguments ATLAS_NOT_THREAD_SAFE(int argc, char *argv[], fbtTestToyMC_config &config);
83StatusCode setupSystBranches(const char* baseName,
85 float &weight,
86 float &weight_err,
87 std::map<CP::SystematicVariation, float> &syst_map,
88 std::map<CP::SystematicVariation, float> &syst_err_map,
89 TTree* ntuple);
90
91StatusCode setupSystBranchesAsym(const char* baseName,
93 float &weight,
94 float &weight_poserr,
95 float &weight_negerr,
96 std::map<CP::SystematicVariation, float> &syst_map,
97 std::map<CP::SystematicVariation, float> &syst_poserr_map,
98 std::map<CP::SystematicVariation, float> &syst_negerr_map,
99 TTree* ntuple);
100
101std::unique_ptr<TFile> openRootFile(fbtTestToyMC_config &config);
102
103StatusCode doMerge ATLAS_NOT_THREAD_SAFE( const std::vector<std::string> & input, const std::string & name, fbtTestToyMC_config &config, TH1F* h_lep_pt, float &lep_pt, TH1F* h_lep_eta, float &lep_eta, TH2F* h_lep_pt_eta, float &fakes, float &poserr, float &negerr, int icase);
104
106
107double comboProb(const vector<FakeBkgTools::ParticleData> & leptons_data, const std::bitset<64> & tights, const std::bitset<64> &reals) ;
108
109StatusCode usage();
110
112double err_std;
116
118
120
121//additional variables that don't correspond to Tree branches
122
124
127
128std::ofstream *f_stdneg_lhood_pos;
129std::ofstream *f_stdpos_lhood_0;
130
131const int nSave = 4; // number of subjobs to split into when testing saveProgress
132
133int main ATLAS_NOT_THREAD_SAFE(int argc, char *argv[]){
134 ANA_CHECK_SET_TYPE (int);
135
137
138 // defaults
139 config.nevents = 100;
140 config.ncases = 100;
141 config.realeff_mean = 0.90;
142 config.fakeeff_mean = 0.20;
143 config.eff_spread = 0.10;
144 config.eff_delta_with_pt = 0.;
145 config.minnbaseline = 1;
146 config.maxnbaseline = 4;
147 config.test_save = false;
148 config.saveFileNameBase = "saveProgress";
149 config.mergeFileNameBase = "saveProgress";
150 config.test_merge = false;
151 config.test_histo = false;
152 config.test_systematics = false;
153 config.poisson_fluctuations = false;
154 config.verbose = false;
155 config.selection = ">=1T";
156 config.process = ">=1F[T]";
157
158 if (config.verbose) cout << "maxnbaseline = " << config.maxnbaseline << endl;
159
160 ANA_CHECK( parseArguments(argc, argv, config) );
161
162 ANA_CHECK( Loop(config) );
163}
164
166
167 //Open an output file
168 if (config.verbose) cout << "maxnbaseline = " << config.maxnbaseline << endl;
169
170 std::unique_ptr<TFile> f_out = openRootFile(config);
171
172 int nevents_thiscase;
173
174 // create output ntuple
175 TTree *ntuple = new TTree("FakeBkg", "Variables from toy MC");
176 ntuple->Branch("nevents", &nevents_thiscase, "nevents/I");
177 Int_t nevents_sel;
178 ntuple->Branch("nevents_sel", &nevents_sel, "nevents_sel/I");
179 Float_t fake_lep_frac;
180 ntuple->Branch("fake_lep_frac", &fake_lep_frac, "fake_lep_frac/F");
181 Float_t true_fakes;
182 ntuple->Branch("true_fakes", &true_fakes,"true_fakes/F");
183 Float_t asm_fakes;
184 ntuple->Branch("asm_fakes", &asm_fakes,"asm_fakes/F");
185 Float_t asm_err;
186 ntuple->Branch("asm_err", &asm_err,"asm_err/F");
187 Float_t fkf_fakes;
188 ntuple->Branch("fkf_fakes", &fkf_fakes,"fkf_fakes/F");
189 Float_t fkf_err;
190 ntuple->Branch("fkf_err", &fkf_err,"fkf_err/F");
191 Float_t lhoodMM_fakes;
192 ntuple->Branch("lhoodMM_fakes", &lhoodMM_fakes,"lhoodMM_fakes/F");
193 Float_t lhoodMM_poserr;
194 ntuple->Branch("lhoodMM_poserr", &lhoodMM_poserr,"lhoodMM_poserr/F");
195 Float_t lhoodMM_negerr;
196 ntuple->Branch("lhoodMM_negerr", &lhoodMM_negerr,"lhoodMM_negerr/F");
197 Float_t lhoodFF_fakes;
198 ntuple->Branch("lhoodFF_fakes", &lhoodFF_fakes,"lhoodFF_fakes/F");
199 Float_t lhoodFF_poserr;
200 ntuple->Branch("lhoodFF_poserr", &lhoodFF_poserr,"lhoodFF_poserr/F");
201 Float_t lhoodFF_negerr;
202 ntuple->Branch("lhoodFF_negerr", &lhoodFF_negerr,"lhoodFF_negerr/F");
203
204
205 map<CP::SystematicVariation,float> lhoodMM_weight_map, lhoodMM_poserr_map, lhoodMM_negerr_map;
206 map<CP::SystematicVariation,float> lhoodFF_weight_map, lhoodFF_poserr_map, lhoodFF_negerr_map;
207 map<CP::SystematicVariation,float> asm_weight_map, asm_err_map;
208 map<CP::SystematicVariation,float> fkf_weight_map, fkf_err_map;
209
210 TRandom3 rand(242868252);
211
212 Double_t realeff_spread = config.eff_spread;
213 Double_t fakeeff_spread = config.eff_spread;
214
215 std::vector<bool> isTight;
216 std::vector<std::string> input = { config.outputdirname+"efficiencies_full" };
217
218 if(false) // switch to test either XML or ROOT input
219 {
220 // not implemented yet!
221 // input.back().append(".xml");
222 // writeXML(input.back(), 0);
223 }
224 else
225 {
226 input.back().append(".root");
227 ANA_CHECK( writeROOT(input.back(), 0, config.realeff_mean, config.fakeeff_mean, config.eff_spread, config.eff_delta_with_pt) );
228 rootEffFileName = input.back();
229 ANA_CHECK( setupEfficiencies() );
230 }
231
232
233 for (unsigned icase(0); icase < config.ncases; icase++) {
234 nevents_sel = 0;
235
236 TH1F* h_lep_pt_lhoodMM = 0;
237 TH1F* h_lep_eta_lhoodMM = 0;
238 TH2F* h_lep_pt_eta_lhoodMM = 0;
239 TH1F* h_lep_pt_lhoodFF = 0;
240 TH1F* h_lep_eta_lhoodFF = 0;
241 TH2F* h_lep_pt_eta_lhoodFF = 0;
242 TH1F* h_lep_pt_asm = 0;
243 TH1F* h_lep_eta_asm = 0;
244 TH2F* h_lep_pt_eta_asm = 0;
245 TH1F* h_lep_pt_fkf = 0;
246 TH1F* h_lep_eta_fkf = 0;
247 TH2F* h_lep_pt_eta_fkf = 0;
248
249 if (config.test_histo) {
250 std::string hname = "lep_pt_lhoodMM_"+to_string(icase);
251 h_lep_pt_lhoodMM = new TH1F(hname.c_str(), hname.c_str(), 10, 0, 100);
252 hname = "lep_eta_lhoodMM_"+to_string(icase);
253 h_lep_eta_lhoodMM = new TH1F(hname.c_str(), hname.c_str(), 10, -5, 5);
254 hname = "lep_pt_eta_lhoodMM_"+to_string(icase);
255 h_lep_pt_eta_lhoodMM = new TH2F(hname.c_str(), hname.c_str(), 10, 0, 100, 10, -5, 5);
256 hname = "lep_pt_lhoodFF_"+to_string(icase);
257 h_lep_pt_lhoodFF = new TH1F(hname.c_str(), hname.c_str(), 10, 0, 100);
258 hname = "lep_eta_lhoodFF_"+to_string(icase);
259 h_lep_eta_lhoodFF = new TH1F(hname.c_str(), hname.c_str(), 10, -5, 5);
260 hname = "lep_pt_eta_lhoodFF_"+to_string(icase);
261 h_lep_pt_eta_lhoodFF = new TH2F(hname.c_str(), hname.c_str(), 10, 0, 100, 10, -5, 5);
262 hname = "lep_pt_asm_"+to_string(icase);
263 h_lep_pt_asm = new TH1F(hname.c_str(), hname.c_str(), 10, 0, 100);
264 hname = "lep_eta_asm_"+to_string(icase);
265 h_lep_eta_asm = new TH1F(hname.c_str(), hname.c_str(), 10, -5, 5);
266 hname = "lep_pt_eta_asm_"+to_string(icase);
267 h_lep_pt_eta_asm = new TH2F(hname.c_str(), hname.c_str(), 10, 0, 100, 10, -5, 5);
268 hname = "lep_pt_fkf_"+to_string(icase);
269 h_lep_pt_fkf = new TH1F(hname.c_str(), hname.c_str(), 10, 0, 100);
270 hname = "lep_eta_fkf_"+to_string(icase);
271 h_lep_eta_fkf = new TH1F(hname.c_str(), hname.c_str(), 10, -5, 5);
272 hname = "lep_pt_eta_fkf_"+to_string(icase);
273 h_lep_pt_eta_fkf = new TH2F(hname.c_str(), hname.c_str(), 10, 0, 100, 10, -5, 5);
274 }
275
276 float lep_pt = 0, lep_eta = 0;
277
278 if (!config.test_merge) {
279
280 cout << "Starting case " << icase << endl;
281 CP::LhoodMM_tools lhmTool("LhoodMM_tools");
282 // arrays of tool instances to test saveProgress
283 std::vector<CP::LhoodMM_tools*> lhmTool_sav;
284 CP::LhoodMM_tools lhmTool_FF("LhoodFF_tools");
285 std::vector<CP::LhoodMM_tools*> lhmTool_FF_sav;
286 CP::AsymptMatrixTool asmTool("AsymptMatrixTool");
287 std::vector<CP::AsymptMatrixTool*> asmTool_sav;
288 CP::ApplyFakeFactor fkfTool("fkfTool");
289 std::vector<CP::ApplyFakeFactor*> fkfTool_sav;
290
291 float asmYield(0);
292 float asmErr(0);
293 float fkfYield (0);
294 float fkfErr(0);
295 if (config.test_histo) {
296 ANA_CHECK( lhmTool.register1DHistogram(h_lep_pt_lhoodMM, &lep_pt) );
297 ANA_CHECK( lhmTool.register1DHistogram(h_lep_eta_lhoodMM, &lep_eta) );
298 ANA_CHECK( lhmTool.register2DHistogram(h_lep_pt_eta_lhoodMM, &lep_pt, &lep_eta) );
299 ANA_CHECK( lhmTool_FF.register1DHistogram(h_lep_pt_lhoodFF, &lep_pt) );
300 ANA_CHECK( lhmTool_FF.register1DHistogram(h_lep_eta_lhoodFF, &lep_eta) );
301 ANA_CHECK( lhmTool_FF.register2DHistogram(h_lep_pt_eta_lhoodFF, &lep_pt, &lep_eta) );
302 ANA_CHECK( fkfTool.register1DHistogram(h_lep_pt_fkf, &lep_pt) );
303 ANA_CHECK( fkfTool.register1DHistogram(h_lep_eta_fkf, &lep_eta) );
304 ANA_CHECK( fkfTool.register2DHistogram(h_lep_pt_eta_fkf, &lep_pt, &lep_eta) );
305 ANA_CHECK( asmTool.register1DHistogram(h_lep_pt_asm, &lep_pt) );
306 ANA_CHECK( asmTool.register1DHistogram(h_lep_eta_asm, &lep_eta) );
307 ANA_CHECK( asmTool.register2DHistogram(h_lep_pt_eta_asm, &lep_pt, &lep_eta) );
308 }
309
310 ANA_CHECK( initialize(asmTool, input, config.selection, config.process, config.verbose) );
311 ANA_CHECK( initialize(lhmTool, input, config.selection, config.process, config.verbose) );
312 ANA_CHECK( initialize(lhmTool_FF, input, config.selection, config.process, config.verbose) );
313 ANA_CHECK( lhmTool_FF.setProperty("DoFakeFactorFit", true) );
314
315 ANA_CHECK( initialize(fkfTool, input, config.selection, config.process, config.verbose) );
316
317 if (config.test_save) {
318 for (int iSave = 0; iSave <= nSave; iSave++) {
319 std:: string toolName = "LhoodMM_tools_save_" + std::to_string(icase) + "_" + std::to_string(iSave);
320 CP::LhoodMM_tools *lhmTool_is = new CP::LhoodMM_tools(toolName);
321 lhmTool_sav.push_back(lhmTool_is);
322 ANA_CHECK( initialize(*lhmTool_sav[iSave], input, config.selection, config.process, config.verbose) );
323 if (config.test_histo) {
324 ANA_CHECK( lhmTool_is->register1DHistogram(h_lep_pt_lhoodMM, &lep_pt) );
325 ANA_CHECK( lhmTool_is->register1DHistogram(h_lep_eta_lhoodMM, &lep_eta) );
326 ANA_CHECK( lhmTool_is->register2DHistogram(h_lep_pt_eta_lhoodMM, &lep_pt, &lep_eta) );
327 }
328 toolName = "LhoodMM_tools_FF_save_" + std::to_string(icase) + "_" + std::to_string(iSave);
329 CP::LhoodMM_tools *lhmTool_FF_is = new CP::LhoodMM_tools(toolName);
330 lhmTool_FF_sav.push_back(lhmTool_FF_is);
331 ANA_CHECK( initialize(*lhmTool_FF_sav[iSave], input, config.selection, config.process, config.verbose) );
332 ANA_CHECK( lhmTool_FF_sav[iSave]->setProperty("DoFakeFactorFit", true) );
333 if (config.test_histo) {
334 ANA_CHECK( lhmTool_FF_is->register1DHistogram(h_lep_pt_lhoodFF, &lep_pt) );
335 ANA_CHECK( lhmTool_FF_is->register1DHistogram(h_lep_eta_lhoodFF, &lep_eta) );
336 ANA_CHECK( lhmTool_FF_is->register2DHistogram(h_lep_pt_eta_lhoodFF, &lep_pt, &lep_eta) );
337 }
338
339 toolName = "AsymptMatrixTool_save_" + std::to_string(icase) + "_" + std::to_string(iSave);
340 CP::AsymptMatrixTool *asmTool_is = new CP::AsymptMatrixTool(toolName); if (config.test_histo) {
341 ANA_CHECK( asmTool_is->register1DHistogram(h_lep_pt_asm, &lep_pt) );
342 ANA_CHECK( asmTool_is->register1DHistogram(h_lep_eta_asm, &lep_eta) );
343 ANA_CHECK( asmTool_is->register2DHistogram(h_lep_pt_eta_asm, &lep_pt, &lep_eta) );
344 }
345 asmTool_sav.push_back(asmTool_is);
346 ANA_CHECK( initialize(*asmTool_sav[iSave], input, config.selection, config.process, config.verbose) );
347
348 toolName = "ApplyFakeFactor_save_" + std::to_string(icase) + "_" + std::to_string(iSave);
349 CP::ApplyFakeFactor *fkfTool_is = new CP::ApplyFakeFactor(toolName);
350 fkfTool_sav.push_back(fkfTool_is);
351 ANA_CHECK( initialize(*fkfTool_sav[iSave], input, config.selection, config.process, config.verbose) );
352 if (config.test_histo) {
353 ANA_CHECK( fkfTool_is->register1DHistogram(h_lep_pt_fkf, &lep_pt) );
354 ANA_CHECK( fkfTool_is->register1DHistogram(h_lep_eta_fkf, &lep_eta) );
355 ANA_CHECK( fkfTool_is->register2DHistogram(h_lep_pt_eta_fkf, &lep_pt, &lep_eta) );
356 }
357 }
358 }
359
360
361 Double_t realeff_mean_thiscase = rand.Gaus(config.realeff_mean, realeff_spread);
362 if (realeff_mean_thiscase > 0.99) realeff_mean_thiscase = 0.99;
363 Double_t fakeeff_mean_thiscase = rand.Gaus(config.fakeeff_mean, fakeeff_spread);
364 if (fakeeff_mean_thiscase < 0.01) fakeeff_mean_thiscase = 0.01;
365 if (fakeeff_mean_thiscase > realeff_mean_thiscase) fakeeff_mean_thiscase = realeff_mean_thiscase-0.01;
366
367 fake_lep_frac = rand.Uniform(); // fraction of fake leptons in the loose sample
368
369 totWeight_std = 0.;
370 err_std = 0;
371 n_fake_lhood = 0.;
374
375 std::vector<LhoodMMEvent> mmevts;
376
377 true_fakes = 0;
378
379 std::vector<double> realeff, fakeeff;
380
381 vector<FinalState*> fs;
382 FinalState* this_fs(0);
383 for (unsigned ilep(0); ilep <= config.maxnbaseline; ilep++) {
384 string error;
385 this_fs = new FinalState(0, ilep, config.selection, config.process, error);
386 fs.push_back(this_fs);
387 }
388
389 if (config.poisson_fluctuations) {
390 nevents_thiscase = rand.Poisson(config.nevents);
391 } else {
392 nevents_thiscase = config.nevents;
393 }
394
395 static const SG::Accessor<char> TightAcc("Tight");
396
397 // need two passes to simulate subtraction of real lepton contribution
398 // in fake factor method with a statistically-independent sample
399 for (int pass(0); pass<2; pass++) {
400 int savIndex(0);
401
402
403 int nEventsMultFactor = 1;
404 if (pass > 0) nEventsMultFactor = 10; // simulates higher-stats "MC" for removal of real contribution to fake factor result
405 for (Long64_t ievt(0); ievt<nevents_thiscase*nEventsMultFactor; ievt++) {
406
407 float nlep_frac = 1./(config.maxnbaseline-config.minnbaseline+1);
408 Int_t nlep_select = config.minnbaseline+rand.Uniform()/nlep_frac;
409
410 float extraweight(1.0);
411
412 realeff.clear();
413 fakeeff.clear();
414
416 vector<FakeBkgTools::ParticleData> leptons_data;
417
418 vector<bool> lep_real;
419
420 // set up an ordered vector of lepton pts
421 vector<float> lep_pts;
422 for (int ilep(0); ilep < nlep_select; ilep++) {
423 lep_pts.push_back(100*rand.Uniform());
424 }
425 // sort in descending order
426 sort(lep_pts.begin(), lep_pts.end(), std::greater<float>());
427
428 for (int ilep(0); ilep < nlep_select; ilep++) {
429 xAOD::Electron* lepton = new xAOD::Electron; // for toy MC the lepton flavor doesn't matter
430 // assign the lepton as real or fake
431 bool isReal(false);
432 if (rand.Uniform() > fake_lep_frac) {
433 isReal = true;
434 } else {
435 isReal = false;
436 }
437
438 lep_real.push_back(isReal);
439 lepton->makePrivateStore();
440 lepton->setCharge(rand.Uniform() > 0.5 ? 1 : -1 );
441
442 lep_pt = lep_pts[ilep];
443 lep_eta = -5. + 10*rand.Uniform();
444 lepton->setPtEtaPhi( 1000*lep_pt, lep_eta, 0);
445
446 FakeBkgTools::ParticleData lepton_data;
447 ANA_CHECK( lookupEfficiencies(*lepton, lepton_data) );
448 // decide if lepton is tight or not
449 if (isReal) {
450 if (rand.Uniform() < lepton_data.real_efficiency.nominal) {
451 TightAcc(*lepton) = true;
452 } else {
453 TightAcc(*lepton) = false;
454 }
455 } else {
456 if (rand.Uniform() < lepton_data.fake_efficiency.nominal) {
457 TightAcc(*lepton) = true;
458 } else {
459 TightAcc(*lepton) = false;
460 }
461 }
462 leptons.push_back(static_cast<xAOD::IParticle*>(lepton));
463
464 leptons_data.push_back(lepton_data);
465 }
466
467 if (pass == 0) {
468 ANA_CHECK( asmTool.addEvent(leptons, extraweight) );
469 ANA_CHECK( fkfTool.addEvent(leptons, extraweight) );
470 ANA_CHECK( lhmTool.addEvent(leptons, extraweight) );
471 ANA_CHECK( lhmTool_FF.addEvent(leptons, extraweight) );
472 if (config.test_save) {
473 ANA_CHECK( lhmTool_sav[savIndex]->addEvent(leptons, extraweight) );
474 ANA_CHECK( lhmTool_FF_sav[savIndex]->addEvent(leptons, extraweight) );
475 ANA_CHECK( asmTool_sav[savIndex]->addEvent(leptons, extraweight) );
476 ANA_CHECK( fkfTool_sav[savIndex]->addEvent(leptons, extraweight) );
477 }
478
479 }
480
481 bool all_real(true);
482 if (pass == 1) {
483 for (int ilep(0); ilep < nlep_select; ilep++) {
484 if (!lep_real[ilep]) {
485 all_real = false;
486 }
487 }
488 }
489
490 // fkfTool.addEvent(leptons, extraweight);
491 if (pass == 1 && all_real) {
492 ANA_CHECK( fkfTool.addEvent(leptons, -extraweight/nEventsMultFactor) );
493 // probably not the fully correct way to do it for the LhoodMM,
494 // but might be close enough
495 ANA_CHECK( lhmTool_FF.addEvent(leptons, -extraweight/nEventsMultFactor) );
496
497 if (config.test_save) {
498 ANA_CHECK( fkfTool_sav[savIndex]->addEvent(leptons, -extraweight/nEventsMultFactor) );
499 ANA_CHECK( lhmTool_FF_sav[savIndex]->addEvent(leptons, -extraweight/nEventsMultFactor) );
500 }
501 }
502
503 // determine the expected number of fake lepton events
504 // start by looping over all possible number of tight leptons
505 vector<int> lep_indices;
506 std::bitset<64> tights, reals, charges;
507 for (int ilep(0); ilep < nlep_select; ilep++) {
508 lep_indices.push_back(ilep);
509 if (lep_real[ilep]) reals.set(ilep);
510 }
511
512 if (pass == 0) {
513 for (long comb(0); comb < (1<<nlep_select); ++comb) {
514 tights = std::bitset<64>(comb);
515 if (fs[nlep_select]->accept_selection(tights, charges)) {
516 if (fs[nlep_select]->accept_process(nlep_select, reals, tights)) {
517 true_fakes += extraweight*comboProb(leptons_data, tights, reals);
518 }
519 }
520 }
521 // now see how many events actually passed the required selection
522 tights.reset();
523 for (int ilep = 0; ilep < nlep_select; ilep++) {
524 if (TightAcc(*leptons[ilep])) tights.set(ilep);
525 }
526 if (fs[nlep_select]->accept_selection(tights,charges) ) {
527 nevents_sel += extraweight;
528 }
529
530 float wgt(1.);
531 ANA_CHECK( asmTool.getEventWeight(wgt, config.selection, config.process) );
532 asmYield += wgt;
533 asmErr += wgt*wgt;
534
535 ANA_CHECK( fkfTool.getEventWeight(wgt, config.selection, config.process) );
536 fkfYield += wgt;
537 fkfErr += wgt*wgt;
538 } else {
539 // this is where the subtraction of the real contribution is simulated
540 if (all_real) {
541 float wgt(1.0);
542 ANA_CHECK( fkfTool.getEventWeight(wgt, config.selection, config.process) );
543 fkfYield -= wgt/nEventsMultFactor;
544 fkfErr += wgt*wgt/(nEventsMultFactor);
545 }
546 }
547
548 if (config.test_save) {
549 if (pass == 0) {
550 if (ievt > 0 && (((nSave*ievt)%nevents_thiscase ==0) || ievt == nevents_thiscase -1) ) {
551 string saveFileName = config.saveFileNameBase;
552 saveFileName+= "_lhm_"+to_string(icase)+"_"+to_string(savIndex)+".root";
553 std::unique_ptr<TFile> saveFile(TFile::Open(saveFileName.c_str(), "RECREATE"));
554 ANA_CHECK( lhmTool_sav[savIndex]->saveProgress(saveFile->mkdir("fakes")) );
555 saveFile->Close();
556
557 saveFileName = config.saveFileNameBase+"_asm_"+to_string(icase)+"_"+to_string(savIndex)+".root";
558 saveFile = std::make_unique<TFile>(saveFileName.c_str(), "RECREATE");
559 ANA_CHECK( asmTool_sav[savIndex]->saveProgress(saveFile.get()) );
560 saveFile->Close();
561
562 savIndex++;
563 }
564 } else {
565 if (ievt > 0 && (((nSave*ievt)%(nevents_thiscase*nEventsMultFactor) ==0) || ievt == nevents_thiscase*nEventsMultFactor -1) ) {
566 string saveFileName = config.saveFileNameBase;
567
568 saveFileName = config.saveFileNameBase+"_lhf_"+to_string(icase)+"_"+to_string(savIndex)+".root";
569 std::unique_ptr<TFile> saveFile(TFile::Open(saveFileName.c_str(), "RECREATE"));
570 ANA_CHECK( lhmTool_FF_sav[savIndex]->saveProgress(saveFile->mkdir("fakes")) );
571 saveFile->Close();
572
573 saveFileName = config.saveFileNameBase+"_fkf_"+to_string(icase)+"_"+to_string(savIndex)+".root";
574 saveFile = std::make_unique<TFile>(saveFileName.c_str(), "RECREATE");
575 ANA_CHECK( fkfTool_sav[savIndex]->saveProgress(saveFile.get()) );
576 saveFile->Close();
577 savIndex++;
578
579 float nfakes_tmp(0), err_tmp(0);
580 ANA_CHECK( fkfTool.getTotalYield(nfakes_tmp, err_tmp, err_tmp) );;
581 }
582 }
583 }
584
585 for (xAOD::IParticleContainer::iterator it = leptons.begin(); it != leptons.end(); ++it) {
586 if (*it != nullptr) delete *it;
587 }
588 leptons.clear();
589 }
590 }
591 asm_err = sqrt(asmErr);
592 asm_fakes = asmYield;
593 ANA_CHECK( asmTool.getTotalYield(asmYield, asmErr, asmErr) );
594
595
596 ANA_CHECK( lhmTool.getTotalYield(lhoodMM_fakes, lhoodMM_poserr, lhoodMM_negerr) );
597
598 ANA_CHECK( lhmTool_FF.getTotalYield(lhoodFF_fakes, lhoodFF_poserr, lhoodFF_negerr) );
599
600 ANA_CHECK( fkfTool.getTotalYield(fkfYield, fkfErr, fkfErr) );
601 fkf_err = fkfErr;
602 fkf_fakes = fkfYield;
603
604 if (config.test_systematics) {
605 auto sysvars = asmTool.affectingSystematics();
606 std::string systBrName, systBrNameF;
607
608 for(auto& sysvar : sysvars){
609 if (config.verbose) asmTool.getSystDescriptor().printUncertaintyDescription(sysvar);
610
611 float asm_syst_weight, asm_syst_err;
612 float fkf_syst_weight, fkf_syst_err;
613 float lhoodMM_syst_weight, lhoodMM_syst_poserr, lhoodMM_syst_negerr;
614 float lhoodFF_syst_weight, lhoodFF_syst_poserr, lhoodFF_syst_negerr;
615
616 if (icase == 0) {
617 ANA_CHECK( setupSystBranches("asm", sysvar, asm_syst_weight, asm_syst_err, asm_weight_map, asm_err_map, ntuple) );
618 ANA_CHECK( setupSystBranches("fkf", sysvar, fkf_syst_weight, fkf_syst_err, fkf_weight_map, fkf_err_map, ntuple) );;
619 ANA_CHECK( setupSystBranchesAsym("lhoodMM", sysvar, lhoodMM_syst_weight, lhoodMM_syst_poserr, lhoodMM_syst_negerr, lhoodMM_weight_map, lhoodMM_poserr_map, lhoodMM_negerr_map, ntuple) );
620 ANA_CHECK( setupSystBranchesAsym("lhoodFF", sysvar, lhoodFF_syst_weight, lhoodFF_syst_poserr, lhoodFF_syst_negerr, lhoodFF_weight_map, lhoodFF_poserr_map, lhoodFF_negerr_map, ntuple) );
621 }
622 ANA_CHECK( asmTool.applySystematicVariation({sysvar}) );
623 ANA_CHECK( asmTool.getTotalYield(asm_weight_map.find(sysvar)->second,
624 asm_err_map.find(sysvar)->second,
625 asm_err_map.find(sysvar)->second));
626
627 ANA_CHECK( fkfTool.applySystematicVariation({sysvar}) );;
628 ANA_CHECK( fkfTool.getTotalYield(fkf_weight_map.find(sysvar)->second,
629 fkf_err_map.find(sysvar)->second,
630 fkf_err_map.find(sysvar)->second) );
631 ANA_CHECK( lhmTool.applySystematicVariation({sysvar}) );;
632 ANA_CHECK( lhmTool.getTotalYield(lhoodMM_weight_map.find(sysvar)->second,
633 lhoodMM_poserr_map.find(sysvar)->second,
634 lhoodMM_negerr_map.find(sysvar)->second) );
635 ANA_CHECK( lhmTool_FF.applySystematicVariation({sysvar}) );;
636 ANA_CHECK( lhmTool_FF.getTotalYield(lhoodFF_weight_map.find(sysvar)->second,
637 lhoodFF_poserr_map.find(sysvar)->second,
638 lhoodFF_negerr_map.find(sysvar)->second) );
639 }
640 }
641
642
643 cout << "OUTPUT true_fakes = " << true_fakes << endl;
644 cout << "OUTPUT nfakes for lhoodMM = " << lhoodMM_fakes << " +" << lhoodMM_poserr << " -" << lhoodMM_negerr << endl;
645 cout << "OUTPUT nfakes for lhoodFF = " << lhoodFF_fakes << " +" << lhoodFF_poserr << " -" << lhoodFF_negerr << endl;
646 cout << "OUTPUT nfakes for asm = " << asm_fakes << " +- " << asm_err << endl;
647 cout << "OUTPUT nfakes for fkf = " << fkf_fakes << " +- " << fkf_err << endl;
648 cout << "OUTPUT true_fakes = " << true_fakes << endl;
649 } else {
650
651 ANA_CHECK( doMerge(input, "lhm", config, h_lep_pt_lhoodMM, lep_pt, h_lep_eta_lhoodMM, lep_eta, h_lep_pt_eta_lhoodMM, lhoodMM_fakes, lhoodMM_poserr, lhoodMM_negerr, icase) );
652 ANA_CHECK( doMerge(input, "lhf", config, h_lep_pt_lhoodFF, lep_pt, h_lep_eta_lhoodFF, lep_eta, h_lep_pt_eta_lhoodFF, lhoodFF_fakes, lhoodFF_poserr, lhoodFF_negerr, icase) );
653 ANA_CHECK( doMerge(input, "asm", config, h_lep_pt_asm, lep_pt, h_lep_eta_asm, lep_eta, h_lep_pt_eta_asm, asm_fakes, asm_err, asm_err, icase) );
654 ANA_CHECK( doMerge(input, "fkf", config, h_lep_pt_fkf, lep_pt, h_lep_eta_fkf, lep_eta, h_lep_pt_eta_fkf, fkf_fakes, fkf_err, fkf_err, icase) );
655 }
656
657 ntuple->Fill();
658
659 f_out->cd();
660 if (config.test_histo) {
661 h_lep_pt_lhoodMM->Write();
662 h_lep_eta_lhoodMM->Write();
663 h_lep_pt_eta_lhoodMM->Write();
664 h_lep_pt_lhoodFF->Write();
665 h_lep_eta_lhoodFF->Write();
666 h_lep_pt_eta_lhoodFF->Write();
667 h_lep_pt_asm->Write();
668 h_lep_eta_asm->Write();
669 h_lep_pt_eta_asm->Write();
670 h_lep_pt_fkf->Write();
671 h_lep_eta_fkf->Write();
672 h_lep_pt_eta_fkf->Write();
673
674 delete h_lep_pt_lhoodMM;
675 delete h_lep_eta_lhoodMM;
676 delete h_lep_pt_eta_lhoodMM;
677 delete h_lep_pt_lhoodFF;
678 delete h_lep_eta_lhoodFF;
679 delete h_lep_pt_eta_lhoodFF;
680 delete h_lep_pt_asm;
681 delete h_lep_eta_asm;
682 delete h_lep_pt_eta_asm;
683 delete h_lep_pt_fkf;
684 delete h_lep_eta_fkf;
685 delete h_lep_pt_eta_fkf;
686
687
688 }
689 }
690
691 f_out->Write();
692 f_out->Close();
693
694 return StatusCode::SUCCESS;
695}
696
697StatusCode writeROOT(const string& name, int type, float realeff_mean, float fakeeff_mean, float eff_spread, float eff_delta_with_pt){
698 TRandom3 rnd(235789);
699
700 int nbin = 100;
701
702 std::unique_ptr<TFile> file(TFile::Open(name.c_str(), "RECREATE"));
703
704 if(type == 0)
705 {
706 TH1D hElFake("FakeEfficiency_el_pt","FakeEfficiency_el_pt", nbin, 0., 1.*nbin);
707 TH1D hMuFake("FakeEfficiency_mu_pt","FakeEfficiency_mu_pt", nbin, 0., 1.*nbin);
708 TH1D hElReal("RealEfficiency_el_pt","RealEfficiency_el_pt", nbin, 0., 1.*nbin);
709 TH1D hMuReal("RealEfficiency_mu_pt","RealEfficiency_mu_pt", nbin, 0., 1.*nbin);
710
711 TH1D hElFake_bigSyst("FakeEfficiency_el_pt__bigSyst","FakeEfficiency_el_pt__bigSyst", nbin, 0., 1.*nbin);
712 TH1D hElFake_smallSyst("FakeEfficiency_el_pt__smallSyst","FakeEfficiency_el_pt__smallSyst", nbin, 0., 1.*nbin);
713 TH1D hMuFake_bigSyst("FakeEfficiency_mu_pt__bigSyst","FakeEfficiency_mu_pt__bigSyst", nbin, 0., 1.*nbin);
714 TH1D hMuFake_smallSyst("FakeEfficiency_mu_pt__smallSyst","FakeEfficiency_mu_pt__smallSyst", nbin, 0., 1.*nbin);
715 TH1D hElReal_bigSyst("RealEfficiency_el_pt__bigSyst","RealEfficiency_el_pt__bigSyst", nbin, 0., 1.*nbin);
716 TH1D hMuReal_bigSyst("RealEfficiency_mu_pt__bigSyst","RealEfficiency_mu_pt__bigSyst", nbin, 0., 1.*nbin);
717
718 for (int ibin = 1; ibin <= nbin; ibin++) {
719 Double_t realeff = TMath::Min(rnd.Gaus(realeff_mean, eff_spread)+eff_delta_with_pt*(ibin-nbin/2), 0.99);
720 Double_t fakeeff = TMath::Max(rnd.Gaus(fakeeff_mean, eff_spread)-eff_delta_with_pt*(ibin-nbin/2), 0.01);
721
722 float minrfdiff = 0.10;
723 if (realeff - fakeeff < minrfdiff) {
724 if (realeff > minrfdiff) {
725 fakeeff = realeff - minrfdiff;
726 } else {
727 realeff = realeff + 0.10;
728 }
729 }
730
731 // sanity checks on the efficiencies
732 if (realeff < 0 || realeff > 1.) cout << "ERROR: Bad real efficiency value: " << realeff << endl;
733 if (fakeeff < 0 || fakeeff > 1.) cout << "ERROR: Bad fake efficiency value: " << fakeeff << endl;
734 if ((realeff - fakeeff) < minrfdiff) cout << "ERROR: Too small difference between real and fake efficiencies: " << realeff << " " << fakeeff << endl;
735
736 hElFake.SetBinContent(ibin, fakeeff);
737 hElFake.SetBinError(ibin, eff_spread);
738 //hElFake.SetBinError(ibin, 0.);
739 hMuFake.SetBinContent(ibin, fakeeff);
740 hMuFake.SetBinError(ibin, eff_spread);
741 //hMuFake.SetBinError(ibin, 0.);
742 hElReal.SetBinContent(ibin, realeff);
743 hElReal.SetBinError(ibin, eff_spread);
744 //hElReal.SetBinError(ibin, 0.);
745 hMuReal.SetBinContent(ibin, realeff);
746 hMuReal.SetBinError(ibin, eff_spread);
747 //hMuReal.SetBinError(ibin, 0.);
748
749 hElFake_bigSyst.SetBinContent(ibin, 0.20*hElFake.GetBinContent(ibin));
750 hElFake_smallSyst.SetBinContent(ibin, 0.02*hElFake.GetBinContent(ibin));
751 hMuFake_bigSyst.SetBinContent(ibin, 0.20*hMuFake.GetBinContent(ibin));
752 hMuFake_smallSyst.SetBinContent(ibin, 0.02*hMuFake.GetBinContent(ibin));
753 hElReal_bigSyst.SetBinContent(ibin, 0.20*hElReal.GetBinContent(ibin));
754 hMuReal_bigSyst.SetBinContent(ibin, 0.20*hMuReal.GetBinContent(ibin));
755
756 }
757
758 file->cd();
759 hElFake.Write();
760 hElReal.Write();
761 hMuFake.Write();
762 hMuReal.Write();
763 hElFake_bigSyst.Write();
764 hElReal_bigSyst.Write();
765 hElFake_smallSyst.Write();
766 hMuFake_bigSyst.Write();
767 hMuFake_smallSyst.Write();
768 hMuReal_bigSyst.Write();
769 }
770 file->Close();
771 return StatusCode::SUCCESS;
772}
773
774StatusCode parseArguments ATLAS_NOT_THREAD_SAFE(int argc, char *argv[], fbtTestToyMC_config &config) {
775 static struct option long_options[] =
776 {
777 {"ncases", required_argument, 0, 'c'},
778 {"nevents", required_argument, 0, 'e'},
779 {"minnb", required_argument, 0, 'm'},
780 {"maxnb", required_argument, 0, 'n'},
781 {"rmean", required_argument, 0, 'r'},
782 {"fmean", required_argument, 0, 'f'},
783 {"effsigma", required_argument, 0, 's'},
784 {"effdeltawithpt", required_argument, 0, 'd'},
785 {"sel", required_argument, 0, 'l'},
786 {"proc", required_argument, 0, 'p'},
787 {"test_save", no_argument, 0, 'S'},
788 {"test_merge", required_argument, 0, 'M'},
789 {"test_histo", required_argument, 0, 'H'},
790 {"test_systematics", no_argument, 0, 'E'},
791 {"verbose", no_argument, 0, 'v'},
792 {"poisson", no_argument, 0, 'P'},
793 {"help", no_argument, 0, 'h'},
794 {0,0,0,0}
795 };
796
797 int c;
798 // int optind;
799 int longindex = 0;
800
801 while ((c = getopt_long(argc, argv, "c:e:m:n:r:f:s:d:l:p:S:M:HEPvh", long_options, &longindex)) != -1) {
802 switch(c) {
803 case 'c':
804 config.ncases = atoi(optarg);
805 break;
806 case 'e':
807 config.nevents = atoi(optarg);
808 break;
809 case 'r':
810 config.realeff_mean = atof(optarg);
811 break;
812 case 'f':
813 config.fakeeff_mean = atof(optarg);
814 break;
815 case 's':
816 config.eff_spread = atof(optarg);
817 break;
818 case 'd':
819 config.eff_delta_with_pt = atof(optarg);
820 break;
821 case 'l':
822 config.selection = optarg;
823 break;
824 case 'p':
825 config.process = optarg;
826 break;
827 case 'm':
828 config.minnbaseline = atoi(optarg);
829 break;
830 case 'n':
831 config.maxnbaseline = atoi(optarg);
832 break;
833 case 'S':
834 config.test_save = true;
835 config.saveFileNameBase = optarg;
836 break;
837 case 'M':
838 config.test_merge = true;
839 config.mergeFileNameBase = optarg;
840 break;
841 case 'H':
842 config.test_histo = true;
843 break;
844 case 'E':
845 config.test_systematics = true;
846 break;
847 case 'v':
848 config.verbose = true;
849 break;
850 case 'P':
851 config.poisson_fluctuations = true;
852 break;
853 case 'h':
854 ANA_CHECK( usage() );
855 exit(0);
856 case '?':
857 ANA_CHECK( usage() );
858 abort();
859 default:
860 abort();
861 }
862 }
863
864 // remove any \ from selection and process strings
865 size_t pos;
866
867 pos = config.selection.find("\"");
868 while (pos != string::npos) {
869 config.selection.replace(pos, 1, "");
870 pos = config.selection.find("\"");
871 }
872 pos = config.process.find("\"");
873 while (pos != string::npos) {
874 config.process.replace(pos, 1, "");
875 pos = config.process.find("\"");
876 }
877 return StatusCode::SUCCESS;
878}
879
880std::unique_ptr<TFile> openRootFile(fbtTestToyMC_config &config) {
881 string outputdirname;
882 string rootfilename;
883 outputdirname = "FakeBkgTools_toy_MC_nevents_";
884 outputdirname += to_string(config.nevents);
885 outputdirname += "_ncases_";
886 outputdirname += to_string(config.ncases);
887 outputdirname += "_minnbaseline_";
888 outputdirname += to_string(config.minnbaseline);
889 outputdirname += "_maxnbaseline_";
890 outputdirname += to_string(config.maxnbaseline);
891 outputdirname += "_realeff_";
892 outputdirname += to_string(config.realeff_mean);
893 outputdirname += "_fakeeff_";
894 outputdirname += to_string(config.fakeeff_mean);
895 outputdirname += "_effspread_";
896 outputdirname += to_string(config.eff_spread);
897 outputdirname += "_selection_";
898 outputdirname += config.selection;
899 outputdirname += "_process_";
900 outputdirname += config.process;
901 if (config.poisson_fluctuations) {
902 outputdirname += "_poisson_";
903 }
904
905 //now replace things like >, < from selection and process strings to get a
906 //legal directory name
907 size_t pos;
908 pos = outputdirname.find(">=");
909 while (pos != string::npos) {
910 outputdirname.replace(pos, 2, "ge");
911 pos = outputdirname.find(">=");
912 }
913 pos = outputdirname.find("<=");
914 while (pos != string::npos) {
915 outputdirname.replace(pos, 2, "le");
916 pos = outputdirname.find("<=");
917 }
918 pos = outputdirname.find(">");
919 while (pos != string::npos) {
920 outputdirname.replace(pos, 1, "gt");
921 pos = outputdirname.find(">");
922 }
923 pos = outputdirname.find("<");
924 while (pos != string::npos) {
925 outputdirname.replace(pos, 1, "lt");
926 pos = outputdirname.find("<");
927 }
928 pos = outputdirname.find("=");
929 while (pos != string::npos) {
930 outputdirname.replace(pos, 1, "eq");
931 pos = outputdirname.find("=");
932 }
933 pos = outputdirname.find(",");
934 while (pos != string::npos) {
935 outputdirname.replace(pos, 1, "");
936 pos = outputdirname.find(",");
937 }
938 pos = outputdirname.find("[");
939 while (pos != string::npos) {
940 outputdirname.replace(pos, 1, "");
941 pos = outputdirname.find("[");
942 }
943 pos = outputdirname.find("]");
944 while (pos != string::npos) {
945 outputdirname.replace(pos, 1, "");
946 pos = outputdirname.find("]");
947 }
948 pos = outputdirname.find("\"");
949 while (pos != string::npos) {
950 outputdirname.replace(pos, 1, "");
951 pos = outputdirname.find("\"");
952 }
953 pos = outputdirname.find("\\");
954 while (pos != string::npos) {
955 outputdirname.replace(pos, 1, "");
956 pos = outputdirname.find("\\");
957 }
958
959 gSystem->mkdir(outputdirname.c_str());
960 rootfilename = outputdirname+"/output.root";
961
962 config.outputdirname = outputdirname;
963
964 std::unique_ptr<TFile> f_out(TFile::Open(rootfilename.c_str(),"RECREATE"));
965
966 return f_out;
967}
968
969StatusCode initialize ATLAS_NOT_THREAD_SAFE(CP::BaseFakeBkgTool& tool, const std::vector<std::string>& input, const std::string& selection, const std::string& process, bool verbose)
970{
971 ANA_CHECK( tool.setProperty("InputFiles", input) );
972 ANA_CHECK( tool.setProperty("EnergyUnit", "GeV") );
973 ANA_CHECK( tool.setProperty("Selection", selection) );
974 ANA_CHECK( tool.setProperty("Process", process) );
975 if(verbose) {
976 ANA_CHECK( tool.setProperty("OutputLevel", MSG::VERBOSE) );
977 }
978 else{
979 ANA_CHECK( tool.setProperty("OutputLevel", MSG::INFO) );
980 }
981 ANA_CHECK( tool.setProperty("ConvertWhenMissing", true) );
982 ANA_CHECK( tool.initialize() );
983 return StatusCode::SUCCESS;
984}
985
986StatusCode setupEfficiencies ATLAS_NOT_THREAD_SAFE() {
987 rootEffFile = new TFile(rootEffFileName.c_str());
988 if (rootEffFile == 0) {
989 cout << "Um, no ROOT file!" << endl;
990 return StatusCode::FAILURE;
991 }
992
993 h_realeff_e = (TH1F*)rootEffFile->Get("RealEfficiency_el_pt");
994 h_fakeeff_e = (TH1F*)rootEffFile->Get("FakeEfficiency_el_pt");
995 h_realeff_mu = (TH1F*)rootEffFile->Get("RealEfficiency_mu_pt");
996 h_fakeeff_mu = (TH1F*)rootEffFile->Get("FakeEfficiency_mu_pt");
997
998 h_realeff_e->SetDirectory(0);
999 h_fakeeff_e->SetDirectory(0);
1000 h_realeff_mu->SetDirectory(0);
1001 h_fakeeff_mu->SetDirectory(0);
1002
1003 if (h_realeff_e == 0) cout << "No real e" << endl;
1004 if (h_fakeeff_e == 0) cout << "No fake e" << endl;
1005 if (h_realeff_mu == 0) cout << "No real mu" << endl;
1006 if (h_fakeeff_mu == 0) cout << "No fake mu" << endl;
1007
1008 rootEffFile->Close();
1009 delete rootEffFile;
1010 return StatusCode::SUCCESS;
1011}
1012
1013StatusCode lookupEfficiencies ATLAS_NOT_THREAD_SAFE(xAOD::IParticle& lepton, FakeBkgTools::ParticleData& lepton_data) {
1014
1015 if (h_realeff_e == 0) cout << "No real e" << endl;
1016 if (h_fakeeff_e == 0) cout << "No fake e" << endl;
1017 if (h_realeff_mu == 0) cout << "No real mu" << endl;
1018 if (h_fakeeff_mu == 0) cout << "No fake mu" << endl;
1019 if (lepton.type() == xAOD::Type::Electron) {
1020 lepton_data.real_efficiency.nominal = h_realeff_e->GetBinContent(h_realeff_e->FindBin(lepton.pt()/1000.));
1021 lepton_data.fake_efficiency.nominal = h_fakeeff_e->GetBinContent(h_fakeeff_e->FindBin(lepton.pt()/1000.));
1022 } else {
1023 lepton_data.real_efficiency.nominal = h_realeff_mu->GetBinContent(h_realeff_mu->FindBin(lepton.pt()/1000.));
1024 lepton_data.fake_efficiency.nominal = h_fakeeff_mu->GetBinContent(h_fakeeff_mu->FindBin(lepton.pt()/1000.));
1025 }
1026 return StatusCode::SUCCESS;
1027}
1028
1029double comboProb(const vector<FakeBkgTools::ParticleData> & leptons_data, const std::bitset<64> & tights, const std::bitset<64> &reals) {
1030
1031 double prob(1.);
1032 for (unsigned ilep = 0; ilep < leptons_data.size(); ilep++) {
1033 if (tights[ilep]) {
1034 if (reals[ilep]) {
1035 prob *= leptons_data[ilep].real_efficiency.nominal;
1036 } else {
1037 prob *= leptons_data[ilep].fake_efficiency.nominal;
1038 }
1039 } else {
1040 if (reals[ilep]) {
1041 prob *= (1.-leptons_data[ilep].real_efficiency.nominal);
1042 } else {
1043 prob *= (1.-leptons_data[ilep].fake_efficiency.nominal);
1044 }
1045 }
1046 }
1047
1048 return prob;
1049}
1050
1051double comboProb_FF(const vector<FakeBkgTools::ParticleData> & leptons_data, const std::bitset<64> &tights, const std::bitset<64> & reals) {
1052
1053 // like comboProb, but with real efficiencies set to 1.
1054 double prob(1.);
1055 for (unsigned ilep = 0; ilep < leptons_data.size(); ilep++) {
1056 if (tights[ilep]) {
1057 if (reals[ilep]) {
1058 } else {
1059 prob *= leptons_data[ilep].fake_efficiency.nominal;
1060 }
1061 } else {
1062 if (reals[ilep]) {
1063 prob *= 0;
1064 } else {
1065 prob *= (1.-leptons_data[ilep].fake_efficiency.nominal);
1066 }
1067 }
1068 }
1069 for (unsigned ilep = 0; ilep < leptons_data.size(); ilep++) {
1070 if (reals[ilep]) {
1071 float F = leptons_data[ilep].fake_efficiency.nominal/(1-leptons_data[ilep].fake_efficiency.nominal);
1072 prob += F;
1073 }
1074 }
1075 return prob;
1076}
1077
1078StatusCode setupSystBranches(const char* baseName,
1080 float &weight,
1081 float &weight_err,
1082 std::map<CP::SystematicVariation, float> &syst_map,
1083 std::map<CP::SystematicVariation, float> &syst_err_map,
1084 TTree* ntuple) {
1085 syst_map.emplace(std::make_pair(sysvar, weight));
1086 std::string systBrName = baseName;
1087 systBrName = systBrName+"_fakes_"+sysvar.name();
1088 std::string systBrNameF = systBrName+"/F";
1089 ntuple->Branch(systBrName.c_str(), &(syst_map.find(sysvar)->second), systBrNameF.c_str());
1090 syst_err_map.emplace(std::make_pair(sysvar, weight_err));
1091 systBrName = baseName;
1092 systBrName = systBrName+"_err_"+sysvar.name();
1093 systBrNameF = systBrName+"/F";
1094 ntuple->Branch(systBrName.c_str(), &(syst_err_map.find(sysvar)->second), systBrNameF.c_str());
1095
1096 return StatusCode::SUCCESS;
1097}
1098
1099StatusCode setupSystBranchesAsym(const char* baseName,
1101 float &weight,
1102 float &weight_poserr,
1103 float &weight_negerr,
1104 std::map<CP::SystematicVariation, float> &syst_map,
1105 std::map<CP::SystematicVariation, float> &syst_poserr_map,
1106 std::map<CP::SystematicVariation, float> &syst_negerr_map,
1107 TTree* ntuple) {
1108 syst_map.emplace(std::make_pair(sysvar, weight));
1109 std::string systBrName = baseName;
1110 systBrName = systBrName+"_fakes_"+sysvar.name();
1111 std::string systBrNameF = systBrName+"/F";
1112 ntuple->Branch(systBrName.c_str(), &(syst_map.find(sysvar)->second), systBrNameF.c_str());
1113 syst_poserr_map.emplace(std::make_pair(sysvar, weight_poserr));
1114 systBrName = baseName;
1115 systBrName = systBrName+"_poserr_"+sysvar.name();
1116 systBrNameF = systBrName+"/F";
1117 ntuple->Branch(systBrName.c_str(), &(syst_poserr_map.find(sysvar)->second), systBrNameF.c_str());
1118 syst_negerr_map.emplace(std::make_pair(sysvar, weight_negerr));
1119 systBrName = baseName;
1120 systBrName = systBrName+"_negerr_"+sysvar.name();
1121 systBrNameF = systBrName+"/F";
1122 ntuple->Branch(systBrName.c_str(), &(syst_negerr_map.find(sysvar)->second), systBrNameF.c_str());
1123
1124 return StatusCode::SUCCESS;
1125}
1126
1127StatusCode doMerge ATLAS_NOT_THREAD_SAFE( const std::vector<std::string> & input, const std::string & name, fbtTestToyMC_config &config, TH1F* h_lep_pt, float &lep_pt, TH1F* h_lep_eta, float &lep_eta, TH2F* h_lep_pt_eta, float &fakes, float &poserr, float &negerr, int icase) {
1128
1129 std::string haddcmd = "hadd -f "+config.mergeFileNameBase+"_"+name+"_"+to_string(icase)+".root "+config.mergeFileNameBase+"_"+name+"_"+to_string(icase)+"_*.root";
1130 system(haddcmd.c_str());
1131
1132 std::unique_ptr<CP::BaseFakeBkgTool> tool;
1133
1134 if (name == "lhm" || name == "lhf") {
1135 std::string toolName = "Lhood";
1136 if (name == "lhm") {
1137 toolName += "MM";
1138 } else {
1139 toolName += "FF";
1140 }
1141 toolName += to_string(icase)+"_tools_merge";
1142 tool = std::make_unique<CP::LhoodMM_tools>(toolName);
1143 if (name == "lhf") {
1144 ANA_CHECK( tool->setProperty("DoFakeFactorFit", true) );
1145 }
1146 ANA_CHECK( tool->setProperty("ProgressFileDirectory", "fakes") );
1147 } else if (name == "asm") {
1148 tool = std::make_unique<CP::AsymptMatrixTool>("asm_tool_merge");
1149 } else if (name == "fkf") {
1150 tool = std::make_unique<CP::ApplyFakeFactor>("fkf_tool_merge");
1151 }
1152
1153 std::string mergeFileName = config.mergeFileNameBase+"_"+name+"_"+to_string(icase)+".root";
1154 std::cout << mergeFileName << std::endl;
1155 ANA_CHECK( tool->setProperty("ProgressFileName", mergeFileName) );
1156 ANA_CHECK( initialize(*tool, input, config.selection, config.process, config.verbose) );
1157 if (config.test_histo) {
1158 ANA_CHECK( tool->register1DHistogram(h_lep_pt, &lep_pt) );
1159 ANA_CHECK( tool->register1DHistogram(h_lep_eta, &lep_eta) );
1160 ANA_CHECK( tool->register2DHistogram(h_lep_pt_eta, &lep_pt, &lep_eta) );
1161 }
1162
1163 ANA_CHECK( tool->getTotalYield(fakes, poserr, negerr) );
1164 // cout << "merged lhm nfakes = " << lhoodMM_fakes << " + " << lhoodMM_poserr << " " << lhoodMM_negerr << endl;
1165 return StatusCode::SUCCESS;
1166}
1167
1168StatusCode usage() {
1169 std::cout << std::endl << "fbtTestToyMC provides a toy MC model of a set of pseudoexperiments. It is intended to explore the statistical properties of the fake lepton background estimate for a given set of experiemental conditions (number of events, number of leptons required, typical values of the real and fake efficiencies, etc.)" << std::endl << std::endl;
1170 std::cout << "Options: " << std::endl;
1171 std::cout << " --ncases, -c: number of pseudoexperiments to run (default: 100)" << std::endl;
1172 std::cout << " --nevents, -e: number of events in each pseudoexperiment (default: 100)" << std::endl;
1173 std::cout << " --poisson, -P: use Poisson-distributed number of events in each pseudoexperiment, rather than a fixed number (default: false)" << std::endl;
1174 std::cout << " --minnb, -m: minimum number of baseline leptons per event (default: 1)" << std::endl;
1175 std::cout << " --maxnb, -m: maximum number of baseline leptons per event (default: 4)" << std::endl;
1176 std::cout << " --rmean, -r: average real lepton efficiency (default: 0.9)" << std::endl;
1177 std::cout << " --fmean, -f: average fake lepton efficiency (default: 0.2)" << std::endl;
1178 std::cout << " --effsigma, -s: standard deviation for lepton-to-lepton variation in real and fake efficiencies (default: 0.10)" << std::endl;
1179 std::cout << " --effdeltawithpt, -d: rate at which the real (fake) efficiency increases (decreases) with simulated pt. Note that the simulated pt range is 0 to 100" << std::endl;
1180 std::cout << " --sel, -l: selection string to be used by the tools (default \" >= 1T\") " << std::endl;
1181 std::cout << " --proc, -p: process string to be used by the tools (default \" >= 1F[T]\") " << std::endl;
1182 std::cout << " --test_save, -S: save output from subjobs in each pseudoexperiement. If set, requires an argument to specify the base name of the root files where the output will be saved. (default: false) " << std::endl;
1183 std::cout << " --test_merge, -M: merge output from subjobs in each pseudoexperiement. If set, requires an argument to specify the base name of the root files to be merged. This should match the base name used in a previous run with the --test_save option (default: false) " << std::endl;
1184 std::cout << " --test_histo, -H: test the filling of 1- and 2-dimensional histograms (default: false) " << std::endl;
1185 std::cout << " --test_systematics, -E: test the handling of systematic unceratinties (default: false) " << std::endl;
1186 std::cout << " --verbose, -v: enable verbose output (default: false) " << std::endl;
1187 std::cout << " --help, -h: print this help message" << std::endl;
1188 return StatusCode::SUCCESS;;
1189}
Helper class to provide type-safe access to aux data.
macros for messaging and checking status codes
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define ANA_MSG_HEADER(NAME)
for standalone code this creates a new message category
#define ANA_MSG_SOURCE(NAME, TITLE)
the source code part of ANA_MSG_SOURCE
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
int main(int, char **)
Main class for all the CppUnit test classes.
static std::string to_string(const std::vector< T > &v)
static Double_t fs
static TRandom * rnd
#define F(x, y, z)
Definition MD5.cxx:112
void setProperty(columnar::PythonToolHandle &self, const std::string &key, nb::object value)
A number of constexpr particle constants to avoid hardcoding them directly in various places.
virtual CP::SystematicSet affectingSystematics() const override
the list of all systematics this tool can be affected by
virtual StatusCode applySystematicVariation(const CP::SystematicSet &systConfig) override
effects: configure this tool for the given list of systematic variations.
virtual const IFakeBkgSystDescriptor & getSystDescriptor() const override
retrieves an interface to various helper methods to identify what the different SystematicVariations ...
virtual StatusCode addEvent(const xAOD::IParticleContainer &particles, float extraWeight=1.f) override final
supply list of leptons / global variables, internal counters incremented Does not return anything; ev...
virtual StatusCode getEventWeight(float &weight, const std::string &selection, const std::string &process) override final
returns an event weight addEvent() must have been called before hand.
virtual StatusCode register1DHistogram(TH1 *h1, const float *val) override
associates a 1D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
virtual StatusCode getTotalYield(float &yield, float &statErrorUp, float &statErrorDown) override final
returns the accumulated fake lepton background yield (or compute it, in the case of the likelihood ma...
virtual StatusCode register2DHistogram(TH2 *h2, const float *xval, const float *yval) override
associates a 2D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
virtual void printUncertaintyDescription(const CP::SystematicVariation &systematic) const =0
prints a human-readable description of the source of systematic uncertainty specified as argument
virtual StatusCode getTotalYield(float &yield, float &statErrUp, float &statErrDown) override final
returns the accumulated fake lepton background yield (or compute it, in the case of the likelihood ma...
virtual StatusCode register2DHistogram(TH2 *h2, const float *xval, const float *yval) override
associates a 2D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
virtual StatusCode register1DHistogram(TH1 *h1, const float *val) override
associates a 1D histogram to the tool, to obtain a binned estimate of the fake lepton background the ...
const std::string & name() const
description: the full systematics name, for use in strings, etc.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
Definition DataVector.h:842
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
void clear()
Erase all the elements in the collection.
Helper class to provide type-safe access to aux data.
void makePrivateStore()
Create a new (empty) private store for this object.
void setPtEtaPhi(float pt, float eta, float phi)
set the 4-vec
void setCharge(float charge)
set the charge of the object
Class providing the definition of the 4-vector interface.
virtual double pt() const =0
The transverse momentum ( ) of the particle.
virtual Type::ObjectType type() const =0
The type of the object as a simple enumeration.
const std::string selection
const std::string process
StatusCode setupEfficiencies ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
TH1F * h_realeff_e
TH1F * h_fakeeff_mu
TH1F * h_realeff_mu
std::ofstream * f_stdneg_lhood_pos
double weight_lepfakes_3tight
double comboProb_FF(const vector< FakeBkgTools::ParticleData > &leptons_data, const std::bitset< 64 > &tights, const std::bitset< 64 > &reals)
double weight_lepfakes_2tight
TFile * rootEffFile
double totWeight_std
double comboProb(const vector< FakeBkgTools::ParticleData > &leptons_data, const std::bitset< 64 > &tights, const std::bitset< 64 > &reals)
std::unique_ptr< TFile > openRootFile(fbtTestToyMC_config &config)
double err_std
string rootEffFileName
const int nSave
bool fitFailed
double weight_lepfakes_2tight_1loose
StatusCode setupSystBranches(const char *baseName, CP::SystematicVariation sysvar, float &weight, float &weight_err, std::map< CP::SystematicVariation, float > &syst_map, std::map< CP::SystematicVariation, float > &syst_err_map, TTree *ntuple)
StatusCode setupSystBranchesAsym(const char *baseName, CP::SystematicVariation sysvar, float &weight, float &weight_poserr, float &weight_negerr, std::map< CP::SystematicVariation, float > &syst_map, std::map< CP::SystematicVariation, float > &syst_poserr_map, std::map< CP::SystematicVariation, float > &syst_negerr_map, TTree *ntuple)
StatusCode usage()
StatusCode writeXML(const string &name, int type)
StatusCode writeROOT(const string &name, int type, float realeff_mean, float fakeeff_mean, float eff_spread, float eff_delta_with_pt)
Double_t n_fake_lhood_tot_negerr
std::ofstream * f_stdpos_lhood_0
Double_t n_fake_lhood
TH1F * h_fakeeff_e
Double_t n_fake_lhood_tot_poserr
bool verbose
Definition hcg.cxx:73
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ Electron
The object is an electron.
Definition ObjectType.h:46
Electron_v1 Electron
Definition of the current "egamma version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
void initialize()
std::string outputdirname
std::string saveFileNameBase
std::string mergeFileNameBase
TFile * file