ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitHzz4l/Efficiency/src/plotEff.cc
Revision: 1.1
Committed: Tue Jun 12 21:31:44 2012 UTC (12 years, 11 months ago) by dkralph
Content type: text/plain
Branch: MAIN
CVS Tags: compiled, HEAD
Log Message:
First commit: A tag and probe selector for id, iso, or trigger efficiencies and a port of Kevin's fitting code.

File Contents

# Content
1 //================================================================================================
2 //
3 // Signal Extraction
4 //-------------------
5 // 0: probe counting
6 // 1: Breit-Wigner convolved with Crystal Ball function
7 // 2: MC template convolved with Gaussian
8 // 3: Phil's Crystal Ball based "Voigtian" shape
9 // 4: Unbinned MC data convolved with Gaussian
10 //
11 // Background Model
12 //------------------
13 // 0: no background
14 // 1: exponential model
15 // 2: erfc*exp model
16 // 3: double exponential model
17 // 4: linear*exp model
18 // 5: quadratic*exp model
19 //
20 //________________________________________________________________________________________________
21
22 #include <TROOT.h> // access to gROOT, entry point to ROOT system
23 #include <TSystem.h> // interface to OS
24 #include <TStyle.h> // class to handle ROOT plotting style
25 #include <TFile.h> // file handle class
26 #include <TTree.h> // class to access ntuples
27 #include <TCanvas.h> // class for drawing
28 #include <TH1D.h> // 1D histograms
29 #include <TH2D.h> // 2D histograms
30 #include <TBenchmark.h> // class to track macro running statistics
31 #include <TLorentzVector.h> // class for 4-vector calculations
32 #include <TEfficiency.h> // class to handle efficiency calculations
33 #include <vector> // STL vector class
34 #include <iostream> // standard I/O
35 #include <iomanip> // functions to format standard I/O
36 #include <fstream> // functions for file I/O
37 #include <string> // C++ string class
38 #include <sstream> // class for parsing strings
39
40 #include "CPlot.h" // helper class for plots
41 #include "MitStyleRemix.h" // style settings for drawing
42 #include "CEffUser1D.h" // class for handling efficiency graphs
43 #include "CEffUser2D.h" // class for handling efficiency tables
44
45 // structure for output ntuple
46 #include "EffData.h"
47
48 #include "ZSignals.h"
49 #include "ZBackgrounds.h"
50
51 // RooFit headers
52 #include "RooRealVar.h"
53 #include "RooCategory.h"
54 #include "RooDataSet.h"
55 #include "RooDataHist.h"
56 #include "RooFormulaVar.h"
57 #include "RooSimultaneous.h"
58 #include "RooAddPdf.h"
59 #include "RooFitResult.h"
60 #include "RooExtendPdf.h"
61
62 #include "FitArgs.h"
63
64 // bin size constants
65 #define BIN_SIZE_PASS 2
66 #define BIN_SIZE_FAIL 2
67
68 TString sOutDir;
69
70 //=== FUNCTION DECLARATIONS ======================================================================================
71
72 // generate web page
73 void makeHTML(const TString outDir);
74 void makeHTML(const TString outDir, const TString name, const Int_t n);
75
76 // Make efficiency graph
77 TGraphAsymmErrors* makeEffGraph(const vector<Double_t> &edgesv, const vector<TTree*> &passv, const vector<TTree*> &failv, const Int_t method,
78 const TString name, const Double_t massLo, const Double_t massHi,
79 const TString format, const Bool_t doAbsEta);
80 TGraphAsymmErrors* makeEffGraph(const vector<Double_t> &edgesv, const vector<TTree*> &passv, const vector<TTree*> &failv,
81 const Int_t sigpass, const Int_t bkgpass, const Int_t sigfail, const Int_t bkgfail,
82 const TString name, const Double_t massLo, const Double_t massHi, const Double_t fitMassLo, const Double_t fitMassHi,
83 const TString format, const Bool_t doAbsEta);
84
85 // Make 2D efficiency map
86 void makeEffHist2D(TH2D *hEff, TH2D *hErrl, TH2D *hErrh, const vector<TTree*> &passv, const vector<TTree*> &failv, const Int_t method,
87 const TString name, const Double_t massLo, const Double_t massHi,
88 const TString format, const Bool_t doAbsEta);
89 void makeEffHist2D(TH2D *hEff, TH2D *hErrl, TH2D *hErrh, const vector<TTree*> &passv, const vector<TTree*> &failv,
90 const Int_t sigpass, const Int_t bkgpass, const Int_t sigfail, const Int_t bkgfail,
91 const TString name, const Double_t massLo, const Double_t massHi, const Double_t fitMassLo, const Double_t fitMassHi,
92 const TString format, const Bool_t doAbsEta);
93
94
95 // Generate MC-based signal templates
96 void generateHistTemplates(const TString infilename,
97 const vector<Double_t> &ptEdgesv, const vector<Double_t> &etaEdgesv, const vector<Double_t> &phiEdgesv, const vector<Double_t> &npvEdgesv,
98 const Double_t fitMassLo, const Double_t fitMassHi, const Bool_t doAbsEta, const Int_t charge, const TH1D* puWeights);
99 void generateDataTemplates(const TString infilename,
100 const vector<Double_t> &ptEdgesv, const vector<Double_t> &etaEdgesv, const vector<Double_t> &phiEdgesv, const vector<Double_t> &npvEdgesv,
101 const Double_t fitMassLo, const Double_t fitMassHi, const Bool_t doAbsEta, const Int_t charge);
102
103 // Perform count
104 void performCount(Double_t &resEff, Double_t &resErrl, Double_t &resErrh,
105 const Int_t ibin, const Double_t xbinLo, const Double_t xbinHi, const Double_t ybinLo, const Double_t ybinHi,
106 TTree *passTree, TTree *failTree, const Int_t method,
107 const TString name, const Double_t massLo, const Double_t massHi, const TString format, const Bool_t doAbsEta,
108 TCanvas *cpass, TCanvas *cfail);
109
110 // Perform fit
111 void performFit(Double_t &resEff, Double_t &resErrl, Double_t &resErrh,
112 const Int_t ibin, const Double_t xbinLo, const Double_t xbinHi, const Double_t ybinLo, const Double_t ybinHi,
113 TTree *passTree, TTree *failTree,
114 const Int_t sigpass, const Int_t bkgpass, const Int_t sigfail, const Int_t bkgfail,
115 const TString name, const Double_t massLo, const Double_t massHi, const Double_t fitMassLo, const Double_t fitMassHi,
116 const TString format, const Bool_t doAbsEta, TCanvas *cpass, TCanvas *cfail);
117
118 // Print correlations
119 void printCorrelations(ostream& os, RooFitResult *res);
120
121 // Parse fit results file
122 void parseFitResults(ifstream &ifs, double &eff, double &errl, double &errh);
123
124
125 //=== MAIN =================================================================================================
126 int main(int argc, char** argv)
127 {
128 FitFlags ctrl;
129 parse_fitargs( argc, argv, ctrl );
130 ctrl.dump();
131
132 const TString conf = ctrl.conf; // input binning file
133 const Int_t sigModPass = ctrl.sigModPass; // signal extraction method for PASS sample
134 const Int_t bkgModPass = ctrl.bkgModPass; // background model for PASS sample
135 const Int_t sigModFail = ctrl.sigModFail; // signal extraction method for FAIL sample
136 const Int_t bkgModFail = ctrl.bkgModFail; // background model for FAIL sample
137 const TString infilename = ctrl.infilename; // ROOT file of probes
138 const TString outputDir = ctrl.outputDir; // output directory
139 const TString format = ctrl.format; // plot format
140 const Bool_t doAbsEta = ctrl.doAbsEta; // bin in |eta| instead of eta?
141 const Int_t doPU = ctrl.doPU; // PU re-weighting mode
142 const Int_t charge = ctrl.charge; // 0 (no charge requirement), -1, +1
143 const TString mcfilename = ctrl.mcfilename; // ROOT file containing MC events to generate templates from
144 const UInt_t runNumLo = ctrl.runNumLo; // lower bound of run range
145 const UInt_t runNumHi = ctrl.runNumHi; // upper bound of run range
146
147 //--------------------------------------------------------------------------------------------------------------
148 // Settings
149 //==============================================================================================================
150
151 // signal extraction mass region
152 const Double_t massLo = 60;
153 const Double_t massHi = 120;
154
155 // fit mass region
156 const Double_t fitMassLo = massLo;
157 const Double_t fitMassHi = massHi;
158
159 // Weights for PU-reweighting
160 // TString datapath("/data/blue/ksung");
161 TString datapath("/temp/dkralph/ksung");
162 const TString pufnameA (datapath+"/TagAndProbeExample/PileupReweighting.Summer11DYmm_To_Run2011A.root");
163 const TString pufnameB (datapath+"/TagAndProbeExample/PileupReweighting.Summer11DYmm_To_Run2011B.root");
164 const TString pufnameFull(datapath+"/TagAndProbeExample/PileupReweighting.Summer11DYmm_To_Full2011.root");
165
166 // efficiency error calculation method
167 // method: 0 -> Clopper-Pearson
168 // 1 -> Feldman-Cousins
169 const Int_t method=0;
170
171 // y-axis range
172 const Double_t yhigh = 1.03;
173 const Double_t ylow = 0.6;
174
175 // bin edges for kinematic variables
176 vector<Double_t> ptBinEdgesv;
177 vector<Double_t> etaBinEdgesv;
178 vector<Double_t> phiBinEdgesv;
179 vector<Double_t> npvBinEdgesv;
180
181 //
182 // parse binning file
183 //
184 ifstream ifs;
185 ifs.open(conf.Data());
186 assert(ifs.is_open());
187 string line;
188 Int_t state=0;
189 Int_t opts[6];
190 while(getline(ifs,line)) {
191 if(line[0]=='#') continue;
192 if(line[0]=='%') {
193 state++;
194 continue;
195 }
196
197 Double_t edge;
198 stringstream ss(line);
199 if(state==0) {
200 ss >> opts[0] >> opts[1] >> opts[2] >> opts[3] >> opts[4] >> opts[5];
201 } else {
202 ss >> edge;
203 if(state==1) { ptBinEdgesv.push_back(edge); }
204 else if(state==2) { etaBinEdgesv.push_back(edge); }
205 else if(state==3) { phiBinEdgesv.push_back(edge); }
206 else if(state==4) { npvBinEdgesv.push_back(edge); }
207 }
208 }
209 ifs.close();
210
211 gSystem->mkdir(outputDir,kTRUE);
212 TString outdir(outputDir + TString("/plots"));
213 // hack!
214 sOutDir = ctrl.outputDir + TString("/plots");
215
216 //--------------------------------------------------------------------------------------------------------------
217 // Main analysis code
218 //==============================================================================================================
219
220 //
221 // Set up binning in kinematic variables
222 //
223 const UInt_t ptNbins = ptBinEdgesv.size()-1;
224 Double_t ptEdges[ptBinEdgesv.size()];
225 for(UInt_t iedge=0; iedge<ptBinEdgesv.size(); iedge++)
226 ptEdges[iedge] = ptBinEdgesv[iedge];
227
228 const UInt_t etaNbins = etaBinEdgesv.size()-1;
229 Double_t etaEdges[etaBinEdgesv.size()];
230 for(UInt_t iedge=0; iedge<etaBinEdgesv.size(); iedge++)
231 etaEdges[iedge] = etaBinEdgesv[iedge];
232
233 const UInt_t phiNbins = phiBinEdgesv.size()-1;
234 Double_t phiEdges[phiBinEdgesv.size()];
235 for(UInt_t iedge=0; iedge<phiBinEdgesv.size(); iedge++)
236 phiEdges[iedge] = phiBinEdgesv[iedge];
237
238 const UInt_t npvNbins = npvBinEdgesv.size()-1;
239 Double_t npvEdges[npvBinEdgesv.size()];
240 for(UInt_t iedge=0; iedge<npvBinEdgesv.size(); iedge++)
241 npvEdges[iedge] = npvBinEdgesv[iedge];
242
243 char tname[50];
244 Float_t mass,wgt;
245
246 vector<TTree*> passTreePtv;
247 vector<TTree*> failTreePtv;
248 for(UInt_t ibin=0; ibin<ptNbins; ibin++) {
249 sprintf(tname,"passPt_%i",ibin);
250 passTreePtv.push_back(new TTree(tname,""));
251 passTreePtv[ibin]->Branch("m",&mass,"m/F");
252 passTreePtv[ibin]->Branch("w",&wgt,"w/F");
253 passTreePtv[ibin]->SetDirectory(0);
254 sprintf(tname,"failPt_%i",ibin);
255 failTreePtv.push_back(new TTree(tname,""));
256 failTreePtv[ibin]->Branch("m",&mass,"m/F");
257 failTreePtv[ibin]->Branch("w",&wgt,"w/F");
258 failTreePtv[ibin]->SetDirectory(0);
259 }
260
261 vector<TTree*> passTreeEtav;
262 vector<TTree*> failTreeEtav;
263 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
264 sprintf(tname,"passEta_%i",ibin);
265 passTreeEtav.push_back(new TTree(tname,""));
266 passTreeEtav[ibin]->Branch("m",&mass,"m/F");
267 passTreeEtav[ibin]->Branch("w",&wgt,"w/F");
268 passTreeEtav[ibin]->SetDirectory(0);
269 sprintf(tname,"failEta_%i",ibin);
270 failTreeEtav.push_back(new TTree(tname,""));
271 failTreeEtav[ibin]->Branch("m",&mass,"m/F");
272 failTreeEtav[ibin]->Branch("w",&wgt,"w/F");
273 failTreeEtav[ibin]->SetDirectory(0);
274 }
275
276 vector<TTree*> passTreePhiv;
277 vector<TTree*> failTreePhiv;
278 for(UInt_t ibin=0; ibin<phiNbins; ibin++) {
279 sprintf(tname,"passPhi_%i",ibin);
280 passTreePhiv.push_back(new TTree(tname,""));
281 passTreePhiv[ibin]->Branch("m",&mass,"m/F");
282 passTreePhiv[ibin]->Branch("w",&wgt,"w/F");
283 passTreePhiv[ibin]->SetDirectory(0);
284 sprintf(tname,"failPhi_%i",ibin);
285 failTreePhiv.push_back(new TTree(tname,""));
286 failTreePhiv[ibin]->Branch("m",&mass,"m/F");
287 failTreePhiv[ibin]->Branch("w",&wgt,"w/F");
288 failTreePhiv[ibin]->SetDirectory(0);
289 }
290
291 vector<TTree*> passTreeEtaPtv;
292 vector<TTree*> failTreeEtaPtv;
293 for(UInt_t ibin=0; ibin<(etaNbins*ptNbins); ibin++) {
294 sprintf(tname,"passEtaPt_%i",ibin);
295 passTreeEtaPtv.push_back(new TTree(tname,""));
296 passTreeEtaPtv[ibin]->Branch("m",&mass,"m/F");
297 passTreeEtaPtv[ibin]->Branch("w",&wgt,"w/F");
298 passTreeEtaPtv[ibin]->SetDirectory(0);
299 sprintf(tname,"failEtaPt_%i",ibin);
300 failTreeEtaPtv.push_back(new TTree(tname,""));
301 failTreeEtaPtv[ibin]->Branch("m",&mass,"m/F");
302 failTreeEtaPtv[ibin]->Branch("w",&wgt,"w/F");
303 failTreeEtaPtv[ibin]->SetDirectory(0);
304 }
305
306 vector<TTree*> passTreeEtaPhiv;
307 vector<TTree*> failTreeEtaPhiv;
308 for(UInt_t ibin=0; ibin<(etaNbins*phiNbins); ibin++) {
309 sprintf(tname,"passEtaPhi_%i",ibin);
310 passTreeEtaPhiv.push_back(new TTree(tname,""));
311 passTreeEtaPhiv[ibin]->Branch("m",&mass,"m/F");
312 passTreeEtaPhiv[ibin]->Branch("w",&wgt,"w/F");
313 passTreeEtaPhiv[ibin]->SetDirectory(0);
314 sprintf(tname,"failEtaPhi_%i",ibin);
315 failTreeEtaPhiv.push_back(new TTree(tname,""));
316 failTreeEtaPhiv[ibin]->Branch("m",&mass,"m/F");
317 failTreeEtaPhiv[ibin]->Branch("w",&wgt,"w/F");
318 failTreeEtaPhiv[ibin]->SetDirectory(0);
319 }
320
321 vector<TTree*> passTreeNPVv;
322 vector<TTree*> failTreeNPVv;
323 for(UInt_t ibin=0; ibin<npvNbins; ibin++) {
324 sprintf(tname,"passNPV_%i",ibin);
325 passTreeNPVv.push_back(new TTree(tname,""));
326 passTreeNPVv[ibin]->Branch("m",&mass,"m/F");
327 passTreeNPVv[ibin]->Branch("w",&wgt,"w/F");
328 passTreeNPVv[ibin]->SetDirectory(0);
329 sprintf(tname,"failNPV_%i",ibin);
330 failTreeNPVv.push_back(new TTree(tname,""));
331 failTreeNPVv[ibin]->Branch("m",&mass,"m/F");
332 failTreeNPVv[ibin]->Branch("w",&wgt,"w/F");
333 failTreeNPVv[ibin]->SetDirectory(0);
334 }
335
336 //
337 // Pile-up reweighting functions
338 //
339 TFile *pufile = 0;
340 TH1D *puWeights = 0;
341 if(abs(doPU)==1) pufile = new TFile(pufnameA);
342 if(abs(doPU)==2) pufile = new TFile(pufnameB);
343 if(abs(doPU)==3) pufile = new TFile(pufnameFull);
344 if(doPU!=0) {
345 assert(pufile);
346 puWeights = (TH1D*)pufile->Get("puWeights");
347 }
348
349 //
350 // Generate histogram templates from MC if necessary
351 //
352 if(sigModPass==2 || sigModFail==2) {
353 generateHistTemplates(mcfilename,ptBinEdgesv,etaBinEdgesv,phiBinEdgesv,npvBinEdgesv,fitMassLo,fitMassHi,doAbsEta,charge,puWeights);
354 }
355 if(sigModPass==4 || sigModFail==4) {
356 generateDataTemplates(mcfilename,ptBinEdgesv,etaBinEdgesv,phiBinEdgesv,npvBinEdgesv,fitMassLo,fitMassHi,doAbsEta,charge);
357 }
358
359 //
360 // Read in probes data
361 //
362 TFile *infile = new TFile(infilename);
363 TTree *eventTree = (TTree*)infile->Get("Events");
364 EffData data;
365 eventTree->SetBranchAddress("Events",&data);
366
367 for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
368 eventTree->GetEntry(ientry);
369
370 if((data.q)*charge < 0) continue;
371 if(data.mass < fitMassLo) continue;
372 if(data.mass > fitMassHi) continue;
373 if(data.runNum < runNumLo) continue;
374 if(data.runNum > runNumHi) continue;
375
376 mass = data.mass;
377 wgt = data.weight;
378 if(doPU>0) wgt *= puWeights->GetBinContent(data.npu+1);
379
380 Int_t ipt=-1;
381 for(UInt_t ibin=0; ibin<ptNbins; ibin++)
382 if((data.pt >= ptBinEdgesv[ibin]) && (data.pt < ptBinEdgesv[ibin+1]))
383 ipt = ibin;
384 if(ipt<0) continue;
385
386 Int_t ieta=-1;
387 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
388 if(doAbsEta) {
389 assert(etaBinEdgesv[ibin]>=0);
390 if((fabs(data.eta) >= etaBinEdgesv[ibin]) && (fabs(data.eta) < etaBinEdgesv[ibin+1]))
391 ieta = ibin;
392 } else {
393 if((data.eta >= etaBinEdgesv[ibin]) && (data.eta < etaBinEdgesv[ibin+1]))
394 ieta = ibin;
395 }
396 }
397 if(ieta<0) continue;
398
399 Int_t iphi=-1;
400 for(UInt_t ibin=0; ibin<phiNbins; ibin++)
401 if((data.phi >= phiBinEdgesv[ibin]) && (data.phi < phiBinEdgesv[ibin+1]))
402 iphi = ibin;
403 if(iphi<0) continue;
404
405 Int_t inpv=-1;
406 for(UInt_t ibin=0; ibin<npvNbins; ibin++)
407 if((data.npv >= npvBinEdgesv[ibin]) && (data.npv < npvBinEdgesv[ibin+1]))
408 inpv = ibin;
409 // if(inpv<0) continue;
410
411 if(data.pass) {
412 passTreePtv[ipt]->Fill();
413 passTreeEtav[ieta]->Fill();
414 passTreePhiv[iphi]->Fill();
415 passTreeEtaPtv[ipt*etaNbins + ieta]->Fill();
416 passTreeEtaPhiv[iphi*etaNbins + ieta]->Fill();
417 if(inpv>=0) passTreeNPVv[inpv]->Fill();
418 } else {
419 failTreePtv[ipt]->Fill();
420 failTreeEtav[ieta]->Fill();
421 failTreePhiv[iphi]->Fill();
422 failTreeEtaPtv[ipt*etaNbins + ieta]->Fill();
423 failTreeEtaPhiv[iphi*etaNbins + ieta]->Fill();
424 if(inpv>=0) failTreeNPVv[inpv]->Fill();
425 }
426 }
427 delete infile;
428 infile=0, eventTree=0;
429
430
431 //
432 // Compute efficiencies and make plots
433 //
434 TCanvas *c = MakeCanvas("c","c",800,600);
435
436 TGraphAsymmErrors *grEffPt=0;
437 TGraphAsymmErrors *grEffEta=0;
438 TGraphAsymmErrors *grEffPhi=0;
439 TGraphAsymmErrors *grEffNPV=0;
440 TH2D *hEffEtaPt = new TH2D("hEffEtaPt","",etaNbins,etaEdges,ptNbins,ptEdges);
441 TH2D *hErrlEtaPt = (TH2D*)hEffEtaPt->Clone("hErrlEtaPt");
442 TH2D *hErrhEtaPt = (TH2D*)hEffEtaPt->Clone("hErrhEtaPt");
443 TH2D *hEffEtaPhi = new TH2D("hEffEtaPhi","",etaNbins,etaEdges,phiNbins,phiEdges);
444 TH2D *hErrlEtaPhi = (TH2D*)hEffEtaPhi->Clone("hErrlEtaPhi");
445 TH2D *hErrhEtaPhi = (TH2D*)hEffEtaPhi->Clone("hErrhEtaPhi");
446
447 if(sigModPass==0 && sigModFail==0) { // probe counting
448
449 // efficiency in pT
450 if(opts[0]) {
451 grEffPt = makeEffGraph(ptBinEdgesv, passTreePtv, failTreePtv, method, "pt", massLo, massHi, format, doAbsEta);
452 grEffPt->SetName("grEffPt");
453 CPlot plotEffPt("effpt","","probe p_{T} [GeV/c]","#varepsilon",sOutDir);
454 plotEffPt.AddGraph(grEffPt,"",kBlack);
455 plotEffPt.SetYRange(ylow,yhigh);
456 plotEffPt.SetXRange(0.9*(ptBinEdgesv[0]),1.1*(ptBinEdgesv[ptNbins-1]));
457 plotEffPt.Draw(c,kTRUE,format);
458 }
459
460 // efficiency in eta
461 if(opts[1]) {
462 grEffEta = makeEffGraph(etaBinEdgesv, passTreeEtav, failTreeEtav, method, "eta", massLo, massHi, format, doAbsEta);
463 grEffEta->SetName("grEffEta");
464 CPlot plotEffEta("effeta","","probe #eta","#varepsilon",sOutDir);
465 if(doAbsEta) plotEffEta.SetXTitle("probe |#eta|");
466 plotEffEta.AddGraph(grEffEta,"",kBlack);
467 plotEffEta.SetYRange(0.2,1.04);
468 plotEffEta.Draw(c,kTRUE,format);
469
470 CPlot plotEffEta2("effeta2","","probe #eta","#varepsilon",sOutDir);
471 if(doAbsEta) plotEffEta2.SetXTitle("probe |#eta|");
472 plotEffEta2.AddGraph(grEffEta,"",kBlack);
473 plotEffEta2.SetYRange(ylow,yhigh);
474 plotEffEta2.Draw(c,kTRUE,format);
475 }
476
477 // efficiency in phi
478 if(opts[2]) {
479 grEffPhi = makeEffGraph(phiBinEdgesv, passTreePhiv, failTreePhiv, method, "phi", massLo, massHi, format, doAbsEta);
480 grEffPhi->SetName("grEffPhi");
481 CPlot plotEffPhi("effphi","","probe #phi","#varepsilon",sOutDir);
482 plotEffPhi.AddGraph(grEffPhi,"",kBlack);
483 plotEffPhi.SetYRange(ylow,yhigh);
484 plotEffPhi.Draw(c,kTRUE,format);
485 }
486
487 // efficiency in N_PV
488 if(opts[3]) {
489 grEffNPV = makeEffGraph(npvBinEdgesv, passTreeNPVv, failTreeNPVv, method, "npv", massLo, massHi, format, doAbsEta);
490 grEffNPV->SetName("grEffNPV");
491 CPlot plotEffNPV("effnpv","","N_{PV}","#varepsilon",sOutDir);
492 plotEffNPV.AddGraph(grEffNPV,"",kBlack);
493 plotEffNPV.SetYRange(ylow,yhigh);
494 plotEffNPV.Draw(c,kTRUE,format);
495 }
496
497 gStyle->SetPalette(1);
498 c->SetRightMargin(0.15);
499 c->SetLeftMargin(0.15);
500
501 //
502 // eta-pT efficiency maps
503 //
504 if(opts[4]) {
505 makeEffHist2D(hEffEtaPt, hErrlEtaPt, hErrhEtaPt, passTreeEtaPtv, failTreeEtaPtv, method, "etapt", massLo, massHi, format, doAbsEta);
506 hEffEtaPt->SetTitleOffset(1.2,"Y");
507 if(ptNbins>2)
508 hEffEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins-2]);
509 CPlot plotEffEtaPt("effetapt","","probe #eta","probe p_{T} [GeV/c]",sOutDir);
510 if(doAbsEta) plotEffEtaPt.SetXTitle("probe |#eta|");
511 plotEffEtaPt.AddHist2D(hEffEtaPt,"COLZ");
512 plotEffEtaPt.Draw(c,kTRUE,format);
513
514 hErrlEtaPt->SetTitleOffset(1.2,"Y");
515 if(ptNbins>2)
516 hErrlEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins-2]);
517 CPlot plotErrlEtaPt("errletapt","","probe #eta","probe p_{T} [GeV/c]",sOutDir);
518 if(doAbsEta) plotErrlEtaPt.SetXTitle("probe |#eta|");
519 plotErrlEtaPt.AddHist2D(hErrlEtaPt,"COLZ");
520 plotErrlEtaPt.Draw(c,kTRUE,format);
521
522 hErrhEtaPt->SetTitleOffset(1.2,"Y");
523 if(ptNbins>2)
524 hErrhEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins-2]);
525 CPlot plotErrhEtaPt("errhetapt","","probe #eta","probe p_{T} [GeV/c]",sOutDir);
526 if(doAbsEta) plotErrhEtaPt.SetXTitle("probe |#eta|");
527 plotErrhEtaPt.AddHist2D(hErrhEtaPt,"COLZ");
528 plotErrhEtaPt.Draw(c,kTRUE,format);
529 }
530
531 //
532 // eta-phi efficiency maps
533 //
534 if(opts[5]) {
535 makeEffHist2D(hEffEtaPhi, hErrlEtaPhi, hErrhEtaPhi, passTreeEtaPhiv, failTreeEtaPhiv, method, "etaphi", massLo, massHi, format, doAbsEta);
536 hEffEtaPhi->SetTitleOffset(1.2,"Y");
537 CPlot plotEffEtaPhi("effetaphi","","probe #eta","probe #phi",sOutDir);
538 if(doAbsEta) plotEffEtaPhi.SetXTitle("probe |#eta|");
539 plotEffEtaPhi.AddHist2D(hEffEtaPhi,"COLZ");
540 plotEffEtaPhi.Draw(c,kTRUE,format);
541
542 hErrlEtaPhi->SetTitleOffset(1.2,"Y");
543 CPlot plotErrlEtaPhi("errletaphi","","probe #eta","probe #phi",sOutDir);
544 plotErrlEtaPhi.AddHist2D(hErrlEtaPhi,"COLZ");
545 if(doAbsEta) plotErrlEtaPhi.SetXTitle("probe |#eta|");
546 plotErrlEtaPhi.Draw(c,kTRUE,format);
547
548 hErrhEtaPhi->SetTitleOffset(1.2,"Y");
549 CPlot plotErrhEtaPhi("errhetaphi","","probe #eta","probe #phi",sOutDir);
550 if(doAbsEta) plotErrhEtaPhi.SetXTitle("probe |#eta|");
551 plotErrhEtaPhi.AddHist2D(hErrhEtaPhi,"COLZ");
552 plotErrhEtaPhi.Draw(c,kTRUE,format);
553 }
554
555 } else {
556
557 // efficiency in pT
558 if(opts[0]) {
559 grEffPt = makeEffGraph(ptBinEdgesv, passTreePtv, failTreePtv, sigModPass, bkgModPass, sigModFail, bkgModFail, "pt", massLo, massHi, fitMassLo, fitMassHi, format, doAbsEta);
560 grEffPt->SetName("grEffPt");
561 CPlot plotEffPt("effpt","","probe p_{T} [GeV/c]","#varepsilon",sOutDir);
562 plotEffPt.AddGraph(grEffPt,"",kBlack);
563 plotEffPt.SetYRange(ylow,yhigh);
564 plotEffPt.SetXRange(0.9*(ptBinEdgesv[0]),1.1*(ptBinEdgesv[ptNbins-1]));
565 plotEffPt.Draw(c,kTRUE,format);
566 }
567
568 // efficiency in eta
569 if(opts[1]) {
570 grEffEta = makeEffGraph(etaBinEdgesv, passTreeEtav, failTreeEtav, sigModPass, bkgModPass, sigModFail, bkgModFail, "eta", massLo, massHi, fitMassLo, fitMassHi, format, doAbsEta);
571 grEffEta->SetName("grEffEta");
572 CPlot plotEffEta("effeta","","probe #eta","#varepsilon",sOutDir);
573 if(doAbsEta) plotEffEta.SetXTitle("probe |#eta|");
574 plotEffEta.AddGraph(grEffEta,"",kBlack);
575 plotEffEta.SetYRange(0.2,1.04);
576 plotEffEta.Draw(c,kTRUE,format);
577
578 CPlot plotEffEta2("effeta2","","probe #eta","#varepsilon",sOutDir);
579 if(doAbsEta) plotEffEta2.SetXTitle("probe |#eta|");
580 plotEffEta2.AddGraph(grEffEta,"",kBlack);
581 plotEffEta2.SetYRange(ylow,yhigh);
582 plotEffEta2.Draw(c,kTRUE,format);
583 }
584
585 // efficiency in phi
586 if(opts[2]) {
587 grEffPhi = makeEffGraph(phiBinEdgesv, passTreePhiv, failTreePhiv, sigModPass, bkgModPass, sigModFail, bkgModFail, "phi", massLo, massHi, fitMassLo, fitMassHi, format, doAbsEta);
588 grEffPhi->SetName("grEffPhi");
589 CPlot plotEffPhi("effphi","","probe #phi","#varepsilon",sOutDir);
590 plotEffPhi.AddGraph(grEffPhi,"",kBlack);
591 plotEffPhi.SetYRange(ylow,yhigh);
592 plotEffPhi.Draw(c,kTRUE,format);
593 }
594
595 // efficiency in N_PV
596 if(opts[3]) {
597 grEffNPV = makeEffGraph(npvBinEdgesv, passTreeNPVv, failTreeNPVv, sigModPass, bkgModPass, sigModFail, bkgModFail, "npv", massLo, massHi, fitMassLo, fitMassHi, format, doAbsEta);
598 grEffNPV->SetName("grEffNPV");
599 CPlot plotEffNPV("effnpv","","N_{PV}","#varepsilon",sOutDir);
600 plotEffNPV.AddGraph(grEffNPV,"",kBlack);
601 plotEffNPV.SetYRange(ylow,yhigh);
602 plotEffNPV.Draw(c,kTRUE,format);
603 }
604
605
606 gStyle->SetPalette(1);
607 c->SetRightMargin(0.15);
608 c->SetLeftMargin(0.15);
609
610 //
611 // eta-pT efficiency maps
612 //
613 if(opts[4]) {
614 makeEffHist2D(hEffEtaPt, hErrlEtaPt, hErrhEtaPt, passTreeEtaPtv, failTreeEtaPtv, sigModPass, bkgModPass, sigModFail, bkgModFail, "etapt", massLo, massHi, fitMassLo, fitMassHi, format, doAbsEta);
615 hEffEtaPt->SetTitleOffset(1.2,"Y");
616 hEffEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins-2]);
617 CPlot plotEffEtaPt("effetapt","","probe #eta","probe p_{T} [GeV/c]",sOutDir);
618 if(doAbsEta) plotEffEtaPt.SetXTitle("probe |#eta|");
619 plotEffEtaPt.AddHist2D(hEffEtaPt,"COLZ");
620 plotEffEtaPt.Draw(c,kTRUE,format);
621
622 hErrlEtaPt->SetTitleOffset(1.2,"Y");
623 hErrlEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins-2]);
624 CPlot plotErrlEtaPt("errletapt","","probe #eta","probe p_{T} [GeV/c]",sOutDir);
625 if(doAbsEta) plotErrlEtaPt.SetXTitle("probe |#eta|");
626 plotErrlEtaPt.AddHist2D(hErrlEtaPt,"COLZ");
627 plotErrlEtaPt.Draw(c,kTRUE,format);
628
629 hErrhEtaPt->SetTitleOffset(1.2,"Y");
630 hErrhEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins-2]);
631 CPlot plotErrhEtaPt("errhetapt","","probe #eta","probe p_{T} [GeV/c]",sOutDir);
632 if(doAbsEta) plotErrhEtaPt.SetXTitle("probe |#eta|");
633 plotErrhEtaPt.AddHist2D(hErrhEtaPt,"COLZ");
634 plotErrhEtaPt.Draw(c,kTRUE,format);
635 }
636
637 //
638 // eta-phi efficiency maps
639 //
640 if(opts[5]) {
641 makeEffHist2D(hEffEtaPhi, hErrlEtaPhi, hErrhEtaPhi, passTreeEtaPhiv, failTreeEtaPhiv, sigModPass, bkgModPass, sigModFail, bkgModFail, "etaphi", massLo, massHi, fitMassLo, fitMassHi, format, doAbsEta);
642 hEffEtaPhi->SetTitleOffset(1.2,"Y");
643 CPlot plotEffEtaPhi("effetaphi","","probe #eta","probe #phi",sOutDir);
644 if(doAbsEta) plotEffEtaPhi.SetXTitle("probe |#eta|");
645 plotEffEtaPhi.AddHist2D(hEffEtaPhi,"COLZ");
646 plotEffEtaPhi.Draw(c,kTRUE,format);
647
648 hErrlEtaPhi->SetTitleOffset(1.2,"Y");
649 CPlot plotErrlEtaPhi("errletaphi","","probe #eta","probe #phi",sOutDir);
650 plotErrlEtaPhi.AddHist2D(hErrlEtaPhi,"COLZ");
651 if(doAbsEta) plotErrlEtaPhi.SetXTitle("probe |#eta|");
652 plotErrlEtaPhi.Draw(c,kTRUE,format);
653
654 hErrhEtaPhi->SetTitleOffset(1.2,"Y");
655 CPlot plotErrhEtaPhi("errhetaphi","","probe #eta","probe #phi",sOutDir);
656 if(doAbsEta) plotErrhEtaPhi.SetXTitle("probe |#eta|");
657 plotErrhEtaPhi.AddHist2D(hErrhEtaPhi,"COLZ");
658 plotErrhEtaPhi.Draw(c,kTRUE,format);
659 }
660 }
661
662 // Undo scaling of axes before saving to file
663 hEffEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins]);
664 hErrlEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins]);
665 hErrhEtaPt->GetYaxis()->SetRangeUser(ptBinEdgesv[0],ptBinEdgesv[ptNbins]);
666
667
668 //--------------------------------------------------------------------------------------------------------------
669 // Output
670 //==============================================================================================================
671
672 cout << "*" << endl;
673 cout << "* SUMMARY" << endl;
674 cout << "*--------------------------------------------------" << endl;
675 cout << endl;
676
677 TFile *outfile = new TFile(outputDir + TString("/eff.root"), "RECREATE");
678 if(grEffPt) grEffPt->Write();
679 if(grEffEta) grEffEta->Write();
680 if(grEffPhi) grEffPhi->Write();
681 if(grEffNPV) grEffNPV->Write();
682 hEffEtaPt->Write();
683 hErrlEtaPt->Write();
684 hErrhEtaPt->Write();
685 hEffEtaPhi->Write();
686 hErrlEtaPhi->Write();
687 hErrhEtaPhi->Write();
688 outfile->Close();
689 delete outfile;
690
691 makeHTML(outputDir);
692 makeHTML(outputDir, "pt", ptNbins);
693 makeHTML(outputDir, "eta", etaNbins);
694 makeHTML(outputDir, "phi", phiNbins);
695 makeHTML(outputDir, "npv", npvNbins);
696 makeHTML(outputDir, "etapt", etaNbins*ptNbins);
697 makeHTML(outputDir, "etaphi", etaNbins*phiNbins);
698
699 ofstream txtfile;
700 char txtfname[100];
701 sprintf(txtfname,"%s/summary.txt",outputDir.Data());
702 txtfile.open(txtfname);
703 assert(txtfile.is_open());
704
705 CEffUser2D effetapt;
706 CEffUser2D effetaphi;
707
708 CEffUser1D effpt;
709 CEffUser1D effeta;
710 CEffUser1D effphi;
711 CEffUser1D effnpv;
712
713 if(hEffEtaPt->GetEntries()>0) {
714 effetapt.loadEff(hEffEtaPt,hErrlEtaPt,hErrhEtaPt);
715 effetapt.printEff(txtfile); txtfile << endl;
716 effetapt.printErrLow(txtfile); txtfile << endl;
717 effetapt.printErrHigh(txtfile); txtfile << endl;
718 txtfile << endl;
719 }
720
721 if(hEffEtaPhi->GetEntries()>0) {
722 effetaphi.loadEff(hEffEtaPhi,hErrlEtaPhi,hErrhEtaPhi);
723 effetaphi.printEff(txtfile); txtfile << endl;
724 effetaphi.printErrLow(txtfile); txtfile << endl;
725 effetaphi.printErrHigh(txtfile); txtfile << endl;
726 txtfile << endl;
727 }
728
729 if(grEffPt) {
730 effpt.loadEff(grEffPt);
731 effpt.printEff(txtfile);
732 txtfile << endl;
733 effpt.printErrLow(txtfile);
734 txtfile << endl;
735 effpt.printErrHigh(txtfile);
736 txtfile << endl;
737 txtfile << endl;
738 }
739
740 if(grEffEta) {
741 effeta.loadEff(grEffEta);
742 effeta.printEff(txtfile);
743 txtfile << endl;
744 effeta.printErrLow(txtfile);
745 txtfile << endl;
746 effeta.printErrHigh(txtfile);
747 txtfile << endl;
748 txtfile << endl;
749 }
750
751 if(grEffPhi) {
752 effphi.loadEff(grEffPhi);
753 effphi.printEff(txtfile);
754 txtfile << endl;
755 effphi.printErrLow(txtfile);
756 txtfile << endl;
757 effphi.printErrHigh(txtfile);
758 txtfile << endl;
759 txtfile << endl;
760 }
761
762 if(grEffNPV) {
763 effnpv.loadEff(grEffNPV);
764 effnpv.printEff(txtfile);
765 txtfile << endl;
766 effnpv.printErrLow(txtfile);
767 txtfile << endl;
768 effnpv.printErrHigh(txtfile);
769 }
770 txtfile.close();
771
772 cout << endl;
773 cout << " <> Output saved in " << outputDir << "/" << endl;
774 cout << endl;
775
776 }
777
778
779 //=== FUNCTION DEFINITIONS ======================================================================================
780
781 //--------------------------------------------------------------------------------------------------
782 void makeHTML(const TString outDir)
783 {
784 ofstream htmlfile;
785 char htmlfname[100];
786 sprintf(htmlfname,"%s/plots.html",outDir.Data());
787 htmlfile.open(htmlfname);
788 htmlfile << "<!DOCTYPE html" << endl;
789 htmlfile << " PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" << endl;
790 htmlfile << "<html>" << endl;
791
792 htmlfile << "<body bgcolor=\"EEEEEE\">" << endl;
793
794 htmlfile << "<table border=\"0\" cellspacing=\"5\" width=\"100%\">" << endl;
795 htmlfile << "<tr>" << endl;
796 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effpt.png\"><img src=\"plots/effpt.png\" alt=\"plots/effpt.png\" width=\"100%\"></a></td>" << endl;
797 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effeta.png\"><img src=\"plots/effeta.png\" alt=\"plots/effeta.png\" width=\"100%\"></a></td>" << endl;
798 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effeta2.png\"><img src=\"plots/effeta2.png\" alt=\"plots/effeta2.png\" width=\"100%\"></a></td>" << endl;
799 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effphi.png\"><img src=\"plots/effphi.png\" alt=\"plots/effphi.png\" width=\"100%\"></a></td>" << endl;
800 htmlfile << "</tr>" << endl;
801 htmlfile << "<tr>" << endl;
802 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"pt.html\">pT bins</a></td>" << endl;
803 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"eta.html\">&eta; bins</a></td>" << endl;
804 htmlfile << "<td width=\"25%\"></td>" << endl;
805 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"phi.html\">&phi; bins</a></td>" << endl;
806 htmlfile << "</tr>" << endl;
807 htmlfile << "<tr>" << endl;
808 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effetapt.png\"><img src=\"plots/effetapt.png\" alt=\"plots/effetapt.png\" width=\"100%\"></a></td>" << endl;
809 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/errletapt.png\"><img src=\"plots/errletapt.png\" alt=\"plots/errletapt.png\" width=\"100%\"></a></td>" << endl;
810 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/errhetapt.png\"><img src=\"plots/errhetapt.png\" alt=\"plots/errhetapt.png\" width=\"100%\"></a></td>" << endl;
811 htmlfile << "<td width=\"25%\"></td>" << endl;
812 htmlfile << "</tr>" << endl;
813 htmlfile << "<tr>" << endl;
814 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"etapt.html\">&eta;-pT bins</a></td>" << endl;
815 htmlfile << "<td width=\"25%\"></td>" << endl;
816 htmlfile << "<td width=\"25%\"></td>" << endl;
817 htmlfile << "<td width=\"25%\"></td>" << endl;
818 htmlfile << "</tr>" << endl;
819 htmlfile << "<tr>" << endl;
820 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effetaphi.png\"><img src=\"plots/effetaphi.png\" alt=\"plots/effetaphi.png\" width=\"100%\"></a></td>" << endl;
821 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/errletaphi.png\"><img src=\"plots/errletaphi.png\" alt=\"plots/errletaphi.png\" width=\"100%\"></a></td>" << endl;
822 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/errhetaphi.png\"><img src=\"plots/errhetaphi.png\" alt=\"plots/errhetaphi.png\" width=\"100%\"></a></td>" << endl;
823 htmlfile << "<td width=\"25%\"></td>" << endl;
824 htmlfile << "</tr>" << endl;
825 htmlfile << "<tr>" << endl;
826 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"etaphi.html\">&eta;-&phi; bins</a></td>" << endl;
827 htmlfile << "<td width=\"25%\"></td>" << endl;
828 htmlfile << "<td width=\"25%\"></td>" << endl;
829 htmlfile << "<td width=\"25%\"></td>" << endl;
830 htmlfile << "</tr>" << endl;
831 htmlfile << "<tr>" << endl;
832 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/effnpv.png\"><img src=\"plots/effnpv.png\" alt=\"plots/effnpv.png\" width=\"100%\"></a></td>" << endl;
833 htmlfile << "<td width=\"25%\"></td>" << endl;
834 htmlfile << "<td width=\"25%\"></td>" << endl;
835 htmlfile << "<td width=\"25%\"></td>" << endl;
836 htmlfile << "</tr>" << endl;
837 htmlfile << "<tr>" << endl;
838 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"npv.html\">N_PV bins</a></td>" << endl;
839 htmlfile << "<td width=\"25%\"></td>" << endl;
840 htmlfile << "<td width=\"25%\"></td>" << endl;
841 htmlfile << "<td width=\"25%\"></td>" << endl;
842 htmlfile << "</tr>" << endl;
843 htmlfile << "</table>" << endl;
844 htmlfile << "<hr />" << endl;
845
846 htmlfile << "</body>" << endl;
847 htmlfile << "</html>" << endl;
848 htmlfile.close();
849 }
850
851 void makeHTML(const TString outDir, const TString name, const Int_t n)
852 {
853 ofstream htmlfile;
854 char htmlfname[100];
855 sprintf(htmlfname,"%s/%s.html",outDir.Data(),name.Data());
856 htmlfile.open(htmlfname);
857 htmlfile << "<!DOCTYPE html" << endl;
858 htmlfile << " PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" << endl;
859 htmlfile << "<html>" << endl;
860
861 htmlfile << "<body bgcolor=\"EEEEEE\">" << endl;
862
863 htmlfile << "<table border=\"0\" cellspacing=\"5\" width=\"100%\">" << endl;
864 Int_t i;
865 for(i=0; i<n; i++) {
866 if(i%2==0) htmlfile << "<tr>" << endl;
867 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/pass" << name << "_" << i << ".png\"><img src=\"plots/pass" << name << "_" << i << ".png\"alt=\"plots/pass" << name << "_" << i << ".png\" width=\"100%\"></a></td>" << endl;
868 htmlfile << "<td width=\"25%\"><a target=\"_blank\" href=\"plots/fail" << name << "_" << i << ".png\"><img src=\"plots/fail" << name << "_" << i << ".png\"alt=\"plots/fail" << name << "_" << i << ".png\" width=\"100%\"></a></td>" << endl;
869 if(i%2) htmlfile << "</tr>" << endl;
870 }
871 if(i%2) {
872 htmlfile << "<td width=\"25%\"></td>" << endl;
873 htmlfile << "<td width=\"25%\"></td>" << endl;
874 htmlfile << "</tr>" << endl;
875 }
876 htmlfile << "</table>" << endl;
877 htmlfile << "<hr />" << endl;
878
879 htmlfile << "</body>" << endl;
880 htmlfile << "</html>" << endl;
881 htmlfile.close();
882 }
883
884 //--------------------------------------------------------------------------------------------------
885 TGraphAsymmErrors* makeEffGraph(const vector<Double_t> &edgesv, const vector<TTree*> &passv, const vector<TTree*> &failv, const Int_t method,
886 const TString name, const Double_t massLo, const Double_t massHi, const TString format, const Bool_t doAbsEta)
887 {
888 const UInt_t n = edgesv.size()-1;
889 Double_t xval[n], xerr[n];
890 Double_t yval[n], yerrl[n], yerrh[n];
891
892 TCanvas *cpass = MakeCanvas("cpass","cpass",720,540);
893 cpass->SetWindowPosition(cpass->GetWindowTopX()+cpass->GetBorderSize()+800,0);
894 TCanvas *cfail = MakeCanvas("cfail","cfail",720,540);
895 cfail->SetWindowPosition(cfail->GetWindowTopX()+cfail->GetBorderSize()+800,cpass->GetWindowTopX()+cfail->GetBorderSize()+540);
896
897 for(UInt_t ibin=0; ibin<n; ibin++) {
898 xval[ibin] = 0.5*(edgesv[ibin+1] + edgesv[ibin]);
899 xerr[ibin] = 0.5*(edgesv[ibin+1] - edgesv[ibin]);
900
901 Double_t eff, errl, errh;
902 performCount(eff, errl, errh, ibin, edgesv[ibin], edgesv[ibin+1], 0, 0,
903 passv[ibin], failv[ibin], method,
904 name, massLo, massHi, format, doAbsEta,
905 cpass, cfail);
906
907 yval[ibin] = eff;
908 yerrl[ibin] = errl;
909 yerrh[ibin] = errh;
910 }
911 delete cpass;
912 delete cfail;
913
914 return new TGraphAsymmErrors(n,xval,yval,xerr,xerr,yerrl,yerrh);
915 }
916
917 TGraphAsymmErrors* makeEffGraph(const vector<Double_t> &edgesv, const vector<TTree*> &passv, const vector<TTree*> &failv,
918 const Int_t sigpass, const Int_t bkgpass, const Int_t sigfail, const Int_t bkgfail,
919 const TString name, const Double_t massLo, const Double_t massHi, const Double_t fitMassLo, const Double_t fitMassHi,
920 const TString format, const Bool_t doAbsEta)
921 {
922 const UInt_t n = edgesv.size()-1;
923 Double_t xval[n], xerr[n];
924 Double_t yval[n], yerrl[n], yerrh[n];
925
926 TCanvas *cpass = MakeCanvas("cpass","cpass",720,540);
927 cpass->SetWindowPosition(cpass->GetWindowTopX()+cpass->GetBorderSize()+800,0);
928 TCanvas *cfail = MakeCanvas("cfail","cfail",720,540);
929 cfail->SetWindowPosition(cfail->GetWindowTopX()+cfail->GetBorderSize()+800,cpass->GetWindowTopX()+cfail->GetBorderSize()+540);
930
931 for(UInt_t ibin=0; ibin<n; ibin++) {
932 xval[ibin] = 0.5*(edgesv[ibin+1] + edgesv[ibin]);
933 xerr[ibin] = 0.5*(edgesv[ibin+1] - edgesv[ibin]);
934
935 ifstream rfile;
936 char rname[100];
937 sprintf(rname,"%s/fitres%s_%i.txt",sOutDir.Data(),name.Data(),ibin);
938 rfile.open(rname);
939
940 Double_t eff, errl, errh;
941 if(rfile.is_open()) {
942 parseFitResults(rfile,eff,errl,errh);
943 rfile.close();
944
945 } else {
946 performFit(eff, errl, errh, ibin, edgesv[ibin], edgesv[ibin+1], 0, 0,
947 passv[ibin], failv[ibin],
948 sigpass, bkgpass, sigfail, bkgfail,
949 name, massLo, massHi, fitMassLo, fitMassHi,
950 format, doAbsEta, cpass, cfail);
951 }
952
953 yval[ibin] = eff;
954 yerrl[ibin] = errl;
955 yerrh[ibin] = errh;
956 }
957 delete cpass;
958 delete cfail;
959
960 return new TGraphAsymmErrors(n,xval,yval,xerr,xerr,yerrl,yerrh);
961 }
962
963 //--------------------------------------------------------------------------------------------------
964 void makeEffHist2D(TH2D *hEff, TH2D *hErrl, TH2D *hErrh, const vector<TTree*> &passv, const vector<TTree*> &failv, const Int_t method,
965 const TString name, const Double_t massLo, const Double_t massHi, const TString format, const Bool_t doAbsEta)
966 {
967 TCanvas *cpass = MakeCanvas("cpass","cpass",720,540);
968 cpass->SetWindowPosition(cpass->GetWindowTopX()+cpass->GetBorderSize()+800,0);
969 TCanvas *cfail = MakeCanvas("cfail","cfail",720,540);
970 cfail->SetWindowPosition(cfail->GetWindowTopX()+cfail->GetBorderSize()+800,cpass->GetWindowTopX()+cfail->GetBorderSize()+540);
971
972 for(Int_t iy=0; iy<hEff->GetNbinsY(); iy++) {
973 for(Int_t ix=0; ix<hEff->GetNbinsX(); ix++) {
974 Int_t ibin = iy*(hEff->GetNbinsX()) + ix;
975
976 Double_t eff, errl, errh;
977 performCount(eff, errl, errh, ibin,
978 hEff->GetXaxis()->GetBinLowEdge(ix+1), hEff->GetXaxis()->GetBinLowEdge(ix+2),
979 hEff->GetYaxis()->GetBinLowEdge(iy+1), hEff->GetYaxis()->GetBinLowEdge(iy+2),
980 passv[ibin], failv[ibin], method,
981 name, massLo, massHi, format, doAbsEta,
982 cpass, cfail);
983
984 hEff ->SetCellContent(ix+1, iy+1, eff);
985 hErrl->SetCellContent(ix+1, iy+1, errl);
986 hErrh->SetCellContent(ix+1, iy+1, errh);
987 }
988 }
989 delete cpass;
990 delete cfail;
991 }
992
993 void makeEffHist2D(TH2D *hEff, TH2D *hErrl, TH2D *hErrh, const vector<TTree*> &passv, const vector<TTree*> &failv,
994 const Int_t sigpass, const Int_t bkgpass, const Int_t sigfail, const Int_t bkgfail,
995 const TString name, const Double_t massLo, const Double_t massHi, const Double_t fitMassLo, const Double_t fitMassHi,
996 const TString format, const Bool_t doAbsEta)
997 {
998 TCanvas *cpass = MakeCanvas("cpass","cpass",720,540);
999 cpass->SetWindowPosition(cpass->GetWindowTopX()+cpass->GetBorderSize()+800,0);
1000 TCanvas *cfail = MakeCanvas("cfail","cfail",720,540);
1001 cfail->SetWindowPosition(cfail->GetWindowTopX()+cfail->GetBorderSize()+800,cpass->GetWindowTopX()+cfail->GetBorderSize()+540);
1002
1003 for(Int_t iy=0; iy<hEff->GetNbinsY(); iy++) {
1004 for(Int_t ix=0; ix<hEff->GetNbinsX(); ix++) {
1005 Int_t ibin = iy*(hEff->GetNbinsX()) + ix;
1006
1007 ifstream rfile;
1008 char rname[100];
1009 sprintf(rname,"%s/fitres%s_%i.txt",sOutDir.Data(),name.Data(),ibin);
1010 rfile.open(rname);
1011
1012 Double_t eff, errl, errh;
1013 if(rfile.is_open()) {
1014 parseFitResults(rfile,eff,errl,errh);
1015 rfile.close();
1016
1017 } else {
1018 performFit(eff, errl, errh, ibin,
1019 hEff->GetXaxis()->GetBinLowEdge(ix+1), hEff->GetXaxis()->GetBinLowEdge(ix+2),
1020 hEff->GetYaxis()->GetBinLowEdge(iy+1), hEff->GetYaxis()->GetBinLowEdge(iy+2),
1021 passv[ibin], failv[ibin],
1022 sigpass, bkgpass, sigfail, bkgfail,
1023 name, massLo, massHi, fitMassLo, fitMassHi,
1024 format, doAbsEta, cpass, cfail);
1025 }
1026 hEff ->SetCellContent(ix+1, iy+1, eff);
1027 hErrl->SetCellContent(ix+1, iy+1, errl);
1028 hErrh->SetCellContent(ix+1, iy+1, errh);
1029 }
1030 }
1031 delete cpass;
1032 delete cfail;
1033 }
1034
1035 //--------------------------------------------------------------------------------------------------
1036 void generateHistTemplates(const TString infilename,
1037 const vector<Double_t> &ptEdgesv, const vector<Double_t> &etaEdgesv, const vector<Double_t> &phiEdgesv, const vector<Double_t> &npvEdgesv,
1038 const Double_t fitMassLo, const Double_t fitMassHi, const Bool_t doAbsEta, const Int_t charge, const TH1D* puWeights)
1039 {
1040 cout << "Creating histogram templates... "; cout.flush();
1041
1042 char hname[50];
1043
1044 const UInt_t ptNbins = ptEdgesv.size()-1;
1045 const UInt_t etaNbins = etaEdgesv.size()-1;
1046 const UInt_t phiNbins = phiEdgesv.size()-1;
1047 const UInt_t npvNbins = npvEdgesv.size()-1;
1048
1049 TH1D* passPt[ptNbins];
1050 TH1D* failPt[ptNbins];
1051 for(UInt_t ibin=0; ibin<ptNbins; ibin++) {
1052 sprintf(hname,"passpt_%i",ibin);
1053 passPt[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_PASS),fitMassLo,fitMassHi);
1054 passPt[ibin]->SetDirectory(0);
1055 sprintf(hname,"failpt_%i",ibin);
1056 failPt[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_FAIL),fitMassLo,fitMassHi);
1057 failPt[ibin]->SetDirectory(0);
1058 }
1059
1060 TH1D* passEta[etaNbins];
1061 TH1D* failEta[etaNbins];
1062 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
1063 sprintf(hname,"passeta_%i",ibin);
1064 passEta[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_PASS),fitMassLo,fitMassHi);
1065 passEta[ibin]->SetDirectory(0);
1066 sprintf(hname,"faileta_%i",ibin);
1067 failEta[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_FAIL),fitMassLo,fitMassHi);
1068 failEta[ibin]->SetDirectory(0);
1069 }
1070
1071 TH1D* passPhi[phiNbins];
1072 TH1D* failPhi[phiNbins];
1073 for(UInt_t ibin=0; ibin<phiNbins; ibin++) {
1074 sprintf(hname,"passphi_%i",ibin);
1075 passPhi[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_PASS),fitMassLo,fitMassHi);
1076 passPhi[ibin]->SetDirectory(0);
1077 sprintf(hname,"failphi_%i",ibin);
1078 failPhi[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_FAIL),fitMassLo,fitMassHi);
1079 failPhi[ibin]->SetDirectory(0);
1080 }
1081
1082 TH1D* passEtaPt[etaNbins*ptNbins];
1083 TH1D* failEtaPt[etaNbins*ptNbins];
1084 for(UInt_t ibin=0; ibin<(etaNbins*ptNbins); ibin++) {
1085 sprintf(hname,"passetapt_%i",ibin);
1086 passEtaPt[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_PASS),fitMassLo,fitMassHi);
1087 passEtaPt[ibin]->SetDirectory(0);
1088 sprintf(hname,"failetapt_%i",ibin);
1089 failEtaPt[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_FAIL),fitMassLo,fitMassHi);
1090 failEtaPt[ibin]->SetDirectory(0);
1091 }
1092
1093 TH1D* passEtaPhi[etaNbins*phiNbins];
1094 TH1D* failEtaPhi[etaNbins*phiNbins];
1095 for(UInt_t ibin=0; ibin<(etaNbins*phiNbins); ibin++) {
1096 sprintf(hname,"passetaphi_%i",ibin);
1097 passEtaPhi[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_PASS),fitMassLo,fitMassHi);
1098 passEtaPhi[ibin]->SetDirectory(0);
1099 sprintf(hname,"failetaphi_%i",ibin);
1100 failEtaPhi[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_FAIL),fitMassLo,fitMassHi);
1101 failEtaPhi[ibin]->SetDirectory(0);
1102 }
1103
1104 TH1D* passNPV[npvNbins];
1105 TH1D* failNPV[npvNbins];
1106 for(UInt_t ibin=0; ibin<npvNbins; ibin++) {
1107 sprintf(hname,"passnpv_%i",ibin);
1108 passNPV[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_PASS),fitMassLo,fitMassHi);
1109 passNPV[ibin]->SetDirectory(0);
1110 sprintf(hname,"failnpv_%i",ibin);
1111 failNPV[ibin] = new TH1D(hname,"",Int_t((fitMassHi-fitMassLo)/BIN_SIZE_FAIL),fitMassLo,fitMassHi);
1112 failNPV[ibin]->SetDirectory(0);
1113 }
1114
1115 TFile infile(infilename);
1116 TTree *intree = (TTree*)infile.Get("Events");
1117 EffData data;
1118 intree->SetBranchAddress("Events",&data);
1119
1120 for(UInt_t ientry=0; ientry<intree->GetEntries(); ientry++) {
1121 intree->GetEntry(ientry);
1122
1123 Double_t puWgt=1;
1124 if(puWeights)
1125 puWgt = puWeights->GetBinContent(data.npu+1);
1126
1127 if((data.q)*charge < 0) continue;
1128
1129 Int_t ipt=-1;
1130 for(UInt_t ibin=0; ibin<ptNbins; ibin++)
1131 if((data.pt >= ptEdgesv[ibin]) && (data.pt < ptEdgesv[ibin+1]))
1132 ipt = ibin;
1133 if(ipt<0) continue;
1134
1135 Int_t ieta=-1;
1136 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
1137 if(doAbsEta) {
1138 assert(etaEdgesv[ibin]>=0);
1139 if((fabs(data.eta) >= etaEdgesv[ibin]) && (fabs(data.eta) < etaEdgesv[ibin+1]))
1140 ieta = ibin;
1141 } else {
1142 if((data.eta >= etaEdgesv[ibin]) && (data.eta < etaEdgesv[ibin+1]))
1143 ieta = ibin;
1144 }
1145 }
1146 if(ieta<0) continue;
1147
1148 Int_t iphi=-1;
1149 for(UInt_t ibin=0; ibin<phiNbins; ibin++)
1150 if((data.phi >= phiEdgesv[ibin]) && (data.phi < phiEdgesv[ibin+1]))
1151 iphi = ibin;
1152 if(iphi<0) continue;
1153
1154 Int_t inpv=-1;
1155 for(UInt_t ibin=0; ibin<npvNbins; ibin++)
1156 if((data.npv >= npvEdgesv[ibin]) && (data.npv < npvEdgesv[ibin+1]))
1157 inpv = ibin;
1158 if(inpv<0) continue;
1159
1160 if(data.pass) {
1161 passPt[ipt]->Fill(data.mass,puWgt);
1162 passEta[ieta]->Fill(data.mass,puWgt);
1163 passPhi[iphi]->Fill(data.mass,puWgt);
1164 passEtaPt[ipt*etaNbins + ieta]->Fill(data.mass,puWgt);
1165 passEtaPhi[iphi*etaNbins + ieta]->Fill(data.mass,puWgt);
1166 passNPV[inpv]->Fill(data.mass,puWgt);
1167 } else {
1168 failPt[ipt]->Fill(data.mass,puWgt);
1169 failEta[ieta]->Fill(data.mass,puWgt);
1170 failPhi[iphi]->Fill(data.mass,puWgt);
1171 failEtaPt[ipt*etaNbins + ieta]->Fill(data.mass,puWgt);
1172 failEtaPhi[iphi*etaNbins + ieta]->Fill(data.mass,puWgt);
1173 failNPV[inpv]->Fill(data.mass,puWgt);
1174 }
1175 }
1176 infile.Close();
1177
1178 TFile outfile("histTemplates.root", "RECREATE");
1179 for(UInt_t ibin=0; ibin<ptNbins; ibin++) {
1180 passPt[ibin]->Write();
1181 failPt[ibin]->Write();
1182 delete passPt[ibin];
1183 delete failPt[ibin];
1184 }
1185 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
1186 passEta[ibin]->Write();
1187 failEta[ibin]->Write();
1188 delete passEta[ibin];
1189 delete failEta[ibin];
1190 }
1191 for(UInt_t ibin=0; ibin<phiNbins; ibin++) {
1192 passPhi[ibin]->Write();
1193 failPhi[ibin]->Write();
1194 delete passPhi[ibin];
1195 delete failPhi[ibin];
1196 }
1197 for(UInt_t ibin=0; ibin<(etaNbins*ptNbins); ibin++) {
1198 passEtaPt[ibin]->Write();
1199 failEtaPt[ibin]->Write();
1200 delete passEtaPt[ibin];
1201 delete failEtaPt[ibin];
1202 }
1203 for(UInt_t ibin=0; ibin<(etaNbins*phiNbins); ibin++) {
1204 passEtaPhi[ibin]->Write();
1205 failEtaPhi[ibin]->Write();
1206 delete passEtaPhi[ibin];
1207 delete failEtaPhi[ibin];
1208 }
1209 for(UInt_t ibin=0; ibin<npvNbins; ibin++) {
1210 passNPV[ibin]->Write();
1211 failNPV[ibin]->Write();
1212 delete passNPV[ibin];
1213 delete failNPV[ibin];
1214 }
1215 outfile.Write();
1216 outfile.Close();
1217
1218 cout << "Done!" << endl;
1219 }
1220
1221 //--------------------------------------------------------------------------------------------------
1222 void generateDataTemplates(const TString infilename,
1223 const vector<Double_t> &ptEdgesv, const vector<Double_t> &etaEdgesv, const vector<Double_t> &phiEdgesv, const vector<Double_t> &npvEdgesv,
1224 const Double_t fitMassLo, const Double_t fitMassHi, const Bool_t doAbsEta, const Int_t charge)
1225 {
1226 cout << "Creating data templates... "; cout.flush();
1227
1228 char tname[50];
1229
1230 const UInt_t ptNbins = ptEdgesv.size()-1;
1231 const UInt_t etaNbins = etaEdgesv.size()-1;
1232 const UInt_t phiNbins = phiEdgesv.size()-1;
1233 const UInt_t npvNbins = npvEdgesv.size()-1;
1234
1235 Float_t mass;
1236
1237 TTree* passPt[ptNbins];
1238 TTree* failPt[ptNbins];
1239 for(UInt_t ibin=0; ibin<ptNbins; ibin++) {
1240 sprintf(tname,"passpt_%i",ibin);
1241 passPt[ibin] = new TTree(tname,"");
1242 passPt[ibin]->Branch("m",&mass,"m/F");
1243 passPt[ibin]->SetDirectory(0);
1244 sprintf(tname,"failpt_%i",ibin);
1245 failPt[ibin] = new TTree(tname,"");
1246 failPt[ibin]->Branch("m",&mass,"m/F");
1247 failPt[ibin]->SetDirectory(0);
1248 }
1249
1250 TTree* passEta[etaNbins];
1251 TTree* failEta[etaNbins];
1252 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
1253 sprintf(tname,"passeta_%i",ibin);
1254 passEta[ibin] = new TTree(tname,"");
1255 passEta[ibin]->Branch("m",&mass,"m/F");
1256 passEta[ibin]->SetDirectory(0);
1257 sprintf(tname,"faileta_%i",ibin);
1258 failEta[ibin] = new TTree(tname,"");
1259 failEta[ibin]->Branch("m",&mass,"m/F");
1260 failEta[ibin]->SetDirectory(0);
1261 }
1262
1263 TTree* passPhi[phiNbins];
1264 TTree* failPhi[phiNbins];
1265 for(UInt_t ibin=0; ibin<phiNbins; ibin++) {
1266 sprintf(tname,"passphi_%i",ibin);
1267 passPhi[ibin] = new TTree(tname,"");
1268 passPhi[ibin]->Branch("m",&mass,"m/F");
1269 passPhi[ibin]->SetDirectory(0);
1270 sprintf(tname,"failphi_%i",ibin);
1271 failPhi[ibin] = new TTree(tname,"");
1272 failPhi[ibin]->Branch("m",&mass,"m/F");
1273 failPhi[ibin]->SetDirectory(0);
1274 }
1275
1276 TTree* passEtaPt[etaNbins*ptNbins];
1277 TTree* failEtaPt[etaNbins*ptNbins];
1278 for(UInt_t ibin=0; ibin<(etaNbins*ptNbins); ibin++) {
1279 sprintf(tname,"passetapt_%i",ibin);
1280 passEtaPt[ibin] = new TTree(tname,"");
1281 passEtaPt[ibin]->Branch("m",&mass,"m/F");
1282 passEtaPt[ibin]->SetDirectory(0);
1283 sprintf(tname,"failetapt_%i",ibin);
1284 failEtaPt[ibin] = new TTree(tname,"");
1285 failEtaPt[ibin]->Branch("m",&mass,"m/F");
1286 failEtaPt[ibin]->SetDirectory(0);
1287 }
1288
1289 TTree* passEtaPhi[etaNbins*phiNbins];
1290 TTree* failEtaPhi[etaNbins*phiNbins];
1291 for(UInt_t ibin=0; ibin<(etaNbins*phiNbins); ibin++) {
1292 sprintf(tname,"passetaphi_%i",ibin);
1293 passEtaPhi[ibin] = new TTree(tname,"");
1294 passEtaPhi[ibin]->Branch("m",&mass,"m/F");
1295 passEtaPhi[ibin]->SetDirectory(0);
1296 sprintf(tname,"failetaphi_%i",ibin);
1297 failEtaPhi[ibin] = new TTree(tname,"");
1298 failEtaPhi[ibin]->Branch("m",&mass,"m/F");
1299 failEtaPhi[ibin]->SetDirectory(0);
1300 }
1301
1302 TTree* passNPV[npvNbins];
1303 TTree* failNPV[npvNbins];
1304 for(UInt_t ibin=0; ibin<npvNbins; ibin++) {
1305 sprintf(tname,"passnpv_%i",ibin);
1306 passNPV[ibin] = new TTree(tname,"");
1307 passNPV[ibin]->Branch("m",&mass,"m/F");
1308 passNPV[ibin]->SetDirectory(0);
1309 sprintf(tname,"failnpv_%i",ibin);
1310 failNPV[ibin] = new TTree(tname,"");
1311 failNPV[ibin]->Branch("m",&mass,"m/F");
1312 failNPV[ibin]->SetDirectory(0);
1313 }
1314
1315 TFile infile(infilename);
1316 TTree *intree = (TTree*)infile.Get("Events");
1317 EffData data;
1318 intree->SetBranchAddress("Events",&data);
1319
1320 for(UInt_t ientry=0; ientry<intree->GetEntries(); ientry++) {
1321 intree->GetEntry(ientry);
1322
1323 if((data.q)*charge < 0) continue;
1324 if(data.mass < fitMassLo) continue;
1325 if(data.mass > fitMassHi) continue;
1326
1327 mass = data.mass;
1328
1329 Int_t ipt=-1;
1330 for(UInt_t ibin=0; ibin<ptNbins; ibin++)
1331 if((data.pt >= ptEdgesv[ibin]) && (data.pt < ptEdgesv[ibin+1]))
1332 ipt = ibin;
1333 if(ipt<0) continue;
1334
1335 Int_t ieta=-1;
1336 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
1337 if(doAbsEta) {
1338 assert(etaEdgesv[ibin]>=0);
1339 if((fabs(data.eta) >= etaEdgesv[ibin]) && (fabs(data.eta) < etaEdgesv[ibin+1]))
1340 ieta = ibin;
1341 } else {
1342 if((data.eta >= etaEdgesv[ibin]) && (data.eta < etaEdgesv[ibin+1]))
1343 ieta = ibin;
1344 }
1345 }
1346 if(ieta<0) continue;
1347
1348 Int_t iphi=-1;
1349 for(UInt_t ibin=0; ibin<phiNbins; ibin++)
1350 if((data.phi >= phiEdgesv[ibin]) && (data.phi < phiEdgesv[ibin+1]))
1351 iphi = ibin;
1352 if(iphi<0) continue;
1353
1354 Int_t inpv=-1;
1355 for(UInt_t ibin=0; ibin<npvNbins; ibin++)
1356 if((data.npv >= npvEdgesv[ibin]) && (data.npv < npvEdgesv[ibin+1]))
1357 inpv = ibin;
1358 if(inpv<0) continue;
1359
1360 if(data.pass) {
1361 passPt[ipt]->Fill();
1362 passEta[ieta]->Fill();
1363 passPhi[iphi]->Fill();
1364 passEtaPt[ipt*etaNbins + ieta]->Fill();
1365 passEtaPhi[iphi*etaNbins + ieta]->Fill();
1366 passNPV[inpv]->Fill();
1367 } else {
1368 failPt[ipt]->Fill();
1369 failEta[ieta]->Fill();
1370 failPhi[iphi]->Fill();
1371 failEtaPt[ipt*etaNbins + ieta]->Fill();
1372 failEtaPhi[iphi*etaNbins + ieta]->Fill();
1373 failNPV[inpv]->Fill();
1374 }
1375 }
1376 infile.Close();
1377
1378 TFile outfile("dataTemplates.root", "RECREATE");
1379 for(UInt_t ibin=0; ibin<ptNbins; ibin++) {
1380 passPt[ibin]->Write();
1381 failPt[ibin]->Write();
1382 delete passPt[ibin];
1383 delete failPt[ibin];
1384 }
1385 for(UInt_t ibin=0; ibin<etaNbins; ibin++) {
1386 passEta[ibin]->Write();
1387 failEta[ibin]->Write();
1388 delete passEta[ibin];
1389 delete failEta[ibin];
1390 }
1391 for(UInt_t ibin=0; ibin<phiNbins; ibin++) {
1392 passPhi[ibin]->Write();
1393 failPhi[ibin]->Write();
1394 delete passPhi[ibin];
1395 delete failPhi[ibin];
1396 }
1397 for(UInt_t ibin=0; ibin<(etaNbins*ptNbins); ibin++) {
1398 passEtaPt[ibin]->Write();
1399 failEtaPt[ibin]->Write();
1400 delete passEtaPt[ibin];
1401 delete failEtaPt[ibin];
1402 }
1403 for(UInt_t ibin=0; ibin<(etaNbins*phiNbins); ibin++) {
1404 passEtaPhi[ibin]->Write();
1405 failEtaPhi[ibin]->Write();
1406 delete passEtaPhi[ibin];
1407 delete failEtaPhi[ibin];
1408 }
1409 for(UInt_t ibin=0; ibin<npvNbins; ibin++) {
1410 passNPV[ibin]->Write();
1411 failNPV[ibin]->Write();
1412 delete passNPV[ibin];
1413 delete failNPV[ibin];
1414 }
1415 outfile.Write();
1416 outfile.Close();
1417
1418 cout << "Done!" << endl;
1419 }
1420
1421 //--------------------------------------------------------------------------------------------------
1422 void performCount(Double_t &resEff, Double_t &resErrl, Double_t &resErrh,
1423 const Int_t ibin, const Double_t xbinLo, const Double_t xbinHi, const Double_t ybinLo, const Double_t ybinHi,
1424 TTree *passTree, TTree *failTree, const Int_t method,
1425 const TString name, const Double_t massLo, const Double_t massHi, const TString format, const Bool_t doAbsEta,
1426 TCanvas *cpass, TCanvas *cfail)
1427 {
1428 Float_t m,w;
1429 char pname[50];
1430 char binlabelx[100];
1431 char binlabely[100];
1432 char yield[50];
1433 char ylabel[50];
1434 char effstr[100];
1435
1436 Double_t npass=0, ntotal=0;
1437 passTree->SetBranchAddress("m",&m);
1438 passTree->SetBranchAddress("w",&w);
1439 for(UInt_t ientry=0; ientry<passTree->GetEntries(); ientry++) {
1440 passTree->GetEntry(ientry);
1441 if(m<massLo || m>massHi) continue;
1442 npass+=w;
1443 ntotal+=w;
1444 }
1445 failTree->SetBranchAddress("m",&m);
1446 failTree->SetBranchAddress("w",&w);
1447 for(UInt_t ientry=0; ientry<failTree->GetEntries(); ientry++) {
1448 failTree->GetEntry(ientry);
1449 if(m<massLo || m>massHi) continue;
1450 ntotal+=w;
1451 }
1452 resEff = (ntotal>0) ? npass/ntotal : 0;
1453 if(method==0) {
1454 resErrl = resEff - TEfficiency::ClopperPearson((UInt_t)ntotal, (UInt_t)npass, 0.68269, kFALSE);
1455 resErrh = TEfficiency::ClopperPearson((UInt_t)ntotal, (UInt_t)npass, 0.68269, kTRUE) - resEff;
1456 }
1457
1458 if(name.CompareTo("pt")==0) {
1459 sprintf(binlabelx,"%i GeV/c < p_{T} < %i GeV/c",Int_t(xbinLo),Int_t(xbinHi));
1460
1461 } else if(name.CompareTo("eta")==0) {
1462 if(doAbsEta) sprintf(binlabelx,"%.1f < |#eta| < %.1f",xbinLo,xbinHi);
1463 else sprintf(binlabelx,"%.1f < #eta < %.1f",xbinLo,xbinHi);
1464
1465 } else if(name.CompareTo("phi")==0) {
1466 sprintf(binlabelx,"%.1f < #phi < %.1f",xbinLo,xbinHi);
1467
1468 } else if(name.CompareTo("etapt")==0) {
1469 if(doAbsEta) sprintf(binlabelx,"%.1f < |#eta| < %.1f",xbinLo,xbinHi);
1470 else sprintf(binlabelx,"%.1f < #eta < %.1f",xbinLo,xbinHi);
1471 sprintf(binlabely,"%i GeV/c < p_{T} < %i GeV/c",Int_t(ybinLo),Int_t(ybinHi));
1472
1473 } else if(name.CompareTo("etaphi")==0) {
1474 if(doAbsEta) sprintf(binlabelx,"%.1f < |#eta| < %.1f",xbinLo,xbinHi);
1475 else sprintf(binlabelx,"%.1f < #eta < %.1f",xbinLo,xbinHi);
1476 sprintf(binlabely,"%.1f < #phi < %.1f",ybinLo,ybinHi);
1477
1478 } else if(name.CompareTo("npv")==0) {
1479 sprintf(binlabelx,"%i #leq N_{PV} < %i",(Int_t)xbinLo,(Int_t)xbinHi);
1480
1481 }
1482 sprintf(effstr,"#varepsilon = %.4f_{ -%.4f}^{ +%.4f}",resEff,resErrl,resErrh);
1483
1484 //
1485 // Plot passing probes
1486 //
1487 TH1D *hpass = new TH1D("hpass","",Int_t(massHi-massLo)/BIN_SIZE_PASS,massLo,massHi);
1488 passTree->SetBranchAddress("m",&m);
1489 passTree->SetBranchAddress("w",&w);
1490 hpass->Sumw2();
1491 for(UInt_t ientry=0; ientry<passTree->GetEntries(); ientry++) {
1492 passTree->GetEntry(ientry);
1493 hpass->Fill(m,w);
1494 }
1495 sprintf(pname,"pass%s_%i",name.Data(),ibin);
1496 sprintf(yield,"%i Events",(UInt_t)npass);
1497 sprintf(ylabel,"Events / %.1f GeV/c^{2}",(Double_t)BIN_SIZE_PASS);
1498 CPlot plotPass(pname,"Passing probes","tag-probe mass [GeV/c^{2}]",ylabel,sOutDir);
1499 plotPass.AddHist1D(hpass,"E");
1500 plotPass.AddTextBox(binlabelx,0.21,0.85,0.51,0.90,0,kBlack,-1);
1501 if((name.CompareTo("etapt")==0) || (name.CompareTo("etaphi")==0)) {
1502 plotPass.AddTextBox(binlabely,0.21,0.80,0.51,0.85,0,kBlack,-1);
1503 plotPass.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);
1504 } else {
1505 plotPass.AddTextBox(yield,0.21,0.81,0.51,0.85,0,kBlack,-1);
1506 }
1507 plotPass.AddTextBox(effstr,0.70,0.85,0.95,0.90,0,kBlack,-1);
1508 plotPass.Draw(cpass,kTRUE,format);
1509
1510 //
1511 // Plot failing probes
1512 //
1513 TH1D *hfail = new TH1D("hfail","",Int_t(massHi-massLo)/BIN_SIZE_FAIL,massLo,massHi);
1514 hfail->Sumw2();
1515 failTree->SetBranchAddress("m",&m);
1516 failTree->SetBranchAddress("w",&w);
1517 for(UInt_t ientry=0; ientry<failTree->GetEntries(); ientry++) {
1518 failTree->GetEntry(ientry);
1519 hfail->Fill(m,w);
1520 }
1521 sprintf(pname,"fail%s_%i",name.Data(),ibin);
1522 sprintf(yield,"%i Events",(UInt_t)(ntotal-npass));
1523 sprintf(ylabel,"Events / %.1f GeV/c^{2}",(Double_t)BIN_SIZE_FAIL);
1524 CPlot plotFail(pname,"Failing probes","tag-probe mass [GeV/c^{2}]",ylabel,sOutDir);
1525 plotFail.AddHist1D(hfail,"E");
1526 plotFail.AddTextBox(binlabelx,0.21,0.85,0.51,0.90,0,kBlack,-1);
1527 if((name.CompareTo("etapt")==0) || (name.CompareTo("etaphi")==0)) {
1528 plotFail.AddTextBox(binlabely,0.21,0.80,0.51,0.85,0,kBlack,-1);
1529 plotFail.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);
1530 } else {
1531 plotFail.AddTextBox(yield,0.21,0.81,0.51,0.85,0,kBlack,-1);
1532 }
1533 plotFail.AddTextBox(effstr,0.70,0.85,0.95,0.90,0,kBlack,-1);
1534 plotFail.Draw(cfail,kTRUE,format);
1535
1536 delete hpass;
1537 delete hfail;
1538 }
1539
1540 //--------------------------------------------------------------------------------------------------
1541 void performFit(Double_t &resEff, Double_t &resErrl, Double_t &resErrh,
1542 const Int_t ibin, const Double_t xbinLo, const Double_t xbinHi, const Double_t ybinLo, const Double_t ybinHi,
1543 TTree *passTree, TTree *failTree,
1544 const Int_t sigpass, const Int_t bkgpass, const Int_t sigfail, const Int_t bkgfail,
1545 const TString name, const Double_t massLo, const Double_t massHi, const Double_t fitMassLo, const Double_t fitMassHi,
1546 const TString format, const Bool_t doAbsEta, TCanvas *cpass, TCanvas *cfail)
1547 {
1548 RooRealVar m("m","mass",fitMassLo,fitMassHi);
1549 m.setBins(10000);
1550
1551 char pname[50];
1552 char binlabelx[100];
1553 char binlabely[100];
1554 char yield[50];
1555 char ylabel[50];
1556 char effstr[100];
1557 char nsigstr[100];
1558 char nbkgstr[100];
1559 char chi2str[100];
1560
1561 Int_t nflpass=0, nflfail=0;
1562
1563 TFile *histfile = 0;
1564 if(sigpass==2 || sigfail==2) {
1565 histfile = new TFile("histTemplates.root");
1566 assert(histfile);
1567 }
1568 TFile *datfile = 0;
1569 if(sigpass==4 || sigfail==4) {
1570 datfile = new TFile("dataTemplates.root");
1571 assert(datfile);
1572 }
1573
1574 // Define categories
1575 RooCategory sample("sample","");
1576 sample.defineType("Pass",1);
1577 sample.defineType("Fail",2);
1578
1579 RooAbsData *dataPass=0;
1580 RooAbsData *dataFail=0;
1581 TH1D histPass("histPass","",Int_t(fitMassHi-fitMassLo)/BIN_SIZE_PASS,fitMassLo,fitMassHi);
1582 TH1D histFail("histFail","",Int_t(fitMassHi-fitMassLo)/BIN_SIZE_FAIL,fitMassLo,fitMassHi);
1583 RooAbsData *dataCombined=0;
1584
1585 const Bool_t doBinned = kTRUE;//(passTree->GetEntries()>1000 && failTree->GetEntries()>1000);
1586
1587 if(doBinned) {
1588 passTree->Draw("m>>histPass","w");
1589 failTree->Draw("m>>histFail","w");
1590 dataPass = new RooDataHist("dataPass","dataPass",RooArgSet(m),&histPass);
1591 dataFail = new RooDataHist("dataFail","dataFail",RooArgSet(m),&histFail);
1592 //m.setBins(100);
1593
1594 dataCombined = new RooDataHist("dataCombined","dataCombined",RooArgList(m),
1595 RooFit::Index(sample),
1596 RooFit::Import("Pass",*((RooDataHist*)dataPass)),
1597 RooFit::Import("Fail",*((RooDataHist*)dataFail)));
1598
1599 } else {
1600 dataPass = new RooDataSet("dataPass","dataPass",passTree,RooArgSet(m));
1601 dataFail = new RooDataSet("dataFail","dataFail",failTree,RooArgSet(m));
1602
1603 dataCombined = new RooDataSet("dataCombined","dataCombined",RooArgList(m),
1604 RooFit::Index(sample),
1605 RooFit::Import("Pass",*((RooDataSet*)dataPass)),
1606 RooFit::Import("Fail",*((RooDataSet*)dataFail)));
1607 }
1608
1609 // Define signal and background models
1610 CSignalModel *sigPass = 0;
1611 CBackgroundModel *bkgPass = 0;
1612 CSignalModel *sigFail = 0;
1613 CBackgroundModel *bkgFail = 0;
1614
1615 if(sigpass==1) {
1616 sigPass = new CBreitWignerConvCrystalBall(m,kTRUE);
1617 nflpass += 4;
1618
1619 } else if(sigpass==2) {
1620 char hname[50];
1621 sprintf(hname,"pass%s_%i",name.Data(),ibin);
1622 TH1D *h = (TH1D*)histfile->Get(hname);
1623 assert(h);
1624 sigPass = new CMCTemplateConvGaussian(m,h,kTRUE);
1625 nflpass += 2;
1626
1627 } else if(sigpass==3) {
1628 sigPass = new CVoigtianCBShape(m,kTRUE);
1629 nflpass += 4;
1630
1631 } else if(sigpass==4) {
1632 char tname[50];
1633 sprintf(tname,"pass%s_%i",name.Data(),ibin);
1634 TTree *t = (TTree*)datfile->Get(tname);
1635 assert(t);
1636 sigPass = new CMCDatasetConvGaussian(m,t,kTRUE);
1637 nflpass += 2;
1638 }
1639
1640 if(bkgpass==1) {
1641 bkgPass = new CExponential(m,kTRUE);
1642 nflpass += 1;
1643
1644 } else if(bkgpass==2) {
1645 bkgPass = new CErfExpo(m,kTRUE);
1646 nflpass += 3;
1647
1648 } else if(bkgpass==3) {
1649 bkgPass = new CDoubleExp(m,kTRUE);
1650 nflpass += 3;
1651
1652 } else if(bkgpass==4) {
1653 bkgPass = new CLinearExp(m,kTRUE);
1654 nflpass += 2;
1655
1656 } else if(bkgpass==5) {
1657 bkgPass = new CQuadraticExp(m,kTRUE);
1658 nflpass += 3;
1659 }
1660
1661 if(sigfail==1) {
1662 sigFail = new CBreitWignerConvCrystalBall(m,kFALSE);
1663 nflfail += 4;
1664
1665 } else if(sigfail==2) {
1666 char hname[50];
1667 sprintf(hname,"fail%s_%i",name.Data(),ibin);
1668 TH1D *h = (TH1D*)histfile->Get(hname);
1669 assert(h);
1670 sigFail = new CMCTemplateConvGaussian(m,h,kFALSE);//,((CMCTemplateConvGaussian*)sigPass)->sigma);
1671 nflfail += 2;
1672
1673 } else if(sigfail==3) {
1674 sigFail = new CVoigtianCBShape(m,kFALSE);
1675 nflfail += 4;
1676
1677 } else if(sigfail==4) {
1678 char tname[50];
1679 sprintf(tname,"fail%s_%i",name.Data(),ibin);
1680 TTree *t = (TTree*)datfile->Get(tname);
1681 assert(t);
1682 sigFail = new CMCDatasetConvGaussian(m,t,kFALSE);
1683 nflfail += 2;
1684 }
1685
1686 if(bkgfail==1) {
1687 bkgFail = new CExponential(m,kFALSE);
1688 nflfail += 1;
1689
1690 } else if(bkgfail==2) {
1691 bkgFail = new CErfExpo(m,kFALSE);
1692 nflfail += 3;
1693
1694 } else if(bkgfail==3) {
1695 bkgFail = new CDoubleExp(m,kFALSE);
1696 nflfail += 3;
1697
1698 } else if(bkgfail==4) {
1699 bkgFail = new CLinearExp(m,kFALSE);
1700 nflfail += 2;
1701
1702 } else if(bkgfail==5) {
1703 bkgFail = new CQuadraticExp(m,kFALSE);
1704 nflfail += 3;
1705 }
1706
1707 // Define free parameters
1708 Double_t NsigMax = doBinned ? histPass.Integral()+histFail.Integral() : passTree->GetEntries()+failTree->GetEntries();
1709 Double_t NbkgFailMax = doBinned ? histFail.Integral() : failTree->GetEntries();
1710 Double_t NbkgPassMax = doBinned ? histPass.Integral() : passTree->GetEntries();
1711 RooRealVar Nsig("Nsig","Signal Yield",0.80*NsigMax,0,NsigMax);
1712 RooRealVar eff("eff","Efficiency",0.8,0,1.0);
1713 RooRealVar NbkgPass("NbkgPass","Background count in PASS sample",50,0,NbkgPassMax);
1714 if(bkgpass==0) NbkgPass.setVal(0);
1715 RooRealVar NbkgFail("NbkgFail","Background count in FAIL sample",0.1*NbkgFailMax,0.01,NbkgFailMax);
1716
1717 RooFormulaVar NsigPass("NsigPass","eff*Nsig",RooArgList(eff,Nsig));
1718 RooFormulaVar NsigFail("NsigFail","(1.0-eff)*Nsig",RooArgList(eff,Nsig));
1719 RooAddPdf *modelPass=0, *modelFail=0;
1720 RooExtendPdf *esignalPass=0, *ebackgroundPass=0, *esignalFail=0, *ebackgroundFail=0;
1721 if(massLo!=fitMassLo || massHi!=fitMassHi) {
1722 m.setRange("signalRange",massLo,massHi);
1723
1724 esignalPass = new RooExtendPdf("esignalPass","esignalPass",*(sigPass->model),NsigPass,"signalRange");
1725 ebackgroundPass = new RooExtendPdf("ebackgroundPass","ebackgroundPass",(bkgpass>0) ? *(bkgPass->model) : *(sigPass->model),NbkgPass,"signalRange");
1726 modelPass = new RooAddPdf("modelPass","Model for PASS sample",(bkgpass>0) ? RooArgList(*esignalPass,*ebackgroundPass) : RooArgList(*esignalPass));
1727
1728 esignalFail = new RooExtendPdf("esignalFail","esignalFail",*(sigFail->model),NsigFail,"signalRange");
1729 ebackgroundFail = new RooExtendPdf("ebackgroundFail","ebackgroundFail",*(bkgFail->model),NbkgFail,"signalRange");
1730 modelFail = new RooAddPdf("modelFail","Model for FAIL sample", (bkgfail>0) ? RooArgList(*esignalFail,*ebackgroundFail) : RooArgList(*esignalFail));
1731
1732 } else {
1733 modelPass = new RooAddPdf("modelPass","Model for PASS sample",
1734 (bkgpass>0) ? RooArgList(*(sigPass->model),*(bkgPass->model)) : RooArgList(*(sigPass->model)),
1735 (bkgpass>0) ? RooArgList(NsigPass,NbkgPass) : RooArgList(NsigPass));
1736
1737 modelFail = new RooAddPdf("modelFail","Model for FAIL sample",RooArgList(*(sigFail->model),*(bkgFail->model)),RooArgList(NsigFail,NbkgFail));
1738 }
1739
1740 RooSimultaneous totalPdf("totalPdf","totalPdf",sample);
1741 totalPdf.addPdf(*modelPass,"Pass");
1742 totalPdf.addPdf(*modelFail,"Fail");
1743
1744 RooFitResult *fitResult=0;
1745 fitResult = totalPdf.fitTo(*dataCombined,
1746 RooFit::Extended(),
1747 RooFit::Strategy(2),
1748 //RooFit::Minos(RooArgSet(eff)),
1749 RooFit::Save());
1750
1751
1752 // Refit w/o MINOS if MINOS errors are strange...
1753 if((fabs(eff.getErrorLo())<5e-5) || (eff.getErrorHi()<5e-5))
1754 fitResult = totalPdf.fitTo(*dataCombined, RooFit::Extended(), RooFit::Strategy(1), RooFit::Save());
1755
1756 resEff = eff.getVal();
1757 resErrl = fabs(eff.getErrorLo());
1758 resErrh = eff.getErrorHi();
1759
1760 if(name.CompareTo("pt")==0) {
1761 sprintf(binlabelx,"%i GeV/c < p_{T} < %i GeV/c",Int_t(xbinLo),Int_t(xbinHi));
1762
1763 } else if(name.CompareTo("eta")==0) {
1764 if(doAbsEta) sprintf(binlabelx,"%.1f < |#eta| < %.1f",xbinLo,xbinHi);
1765 else sprintf(binlabelx,"%.1f < #eta < %.1f",xbinLo,xbinHi);
1766
1767 } else if(name.CompareTo("phi")==0) {
1768 sprintf(binlabelx,"%.1f < #phi < %.1f",xbinLo,xbinHi);
1769
1770 } else if(name.CompareTo("etapt")==0) {
1771 if(doAbsEta) sprintf(binlabelx,"%.1f < |#eta| < %.1f",xbinLo,xbinHi);
1772 else sprintf(binlabelx,"%.1f < #eta < %.1f",xbinLo,xbinHi);
1773 sprintf(binlabely,"%i GeV/c < p_{T} < %i GeV/c",Int_t(ybinLo),Int_t(ybinHi));
1774
1775 } else if(name.CompareTo("etaphi")==0) {
1776 if(doAbsEta) sprintf(binlabelx,"%.1f < |#eta| < %.1f",xbinLo,xbinHi);
1777 else sprintf(binlabelx,"%.1f < #eta < %.1f",xbinLo,xbinHi);
1778 sprintf(binlabely,"%.1f < #phi < %.1f",ybinLo,ybinHi);
1779
1780 } else if(name.CompareTo("npv")==0) {
1781 sprintf(binlabelx,"%i #leq N_{PV} < %i",(Int_t)xbinLo,(Int_t)xbinHi);
1782
1783 }
1784 sprintf(effstr,"#varepsilon = %.4f_{ -%.4f}^{ +%.4f}",eff.getVal(),fabs(eff.getErrorLo()),eff.getErrorHi());
1785
1786 RooPlot *mframePass = m.frame(Bins(Int_t(fitMassHi-fitMassLo)/BIN_SIZE_PASS));
1787 dataPass->plotOn(mframePass,MarkerStyle(kFullCircle),MarkerSize(0.8),DrawOption("ZP"));
1788 modelPass->plotOn(mframePass);
1789 if(bkgpass>0)
1790 modelPass->plotOn(mframePass,Components("backgroundPass"),LineStyle(kDashed),LineColor(kRed));
1791
1792
1793 RooPlot *mframeFail = m.frame(Bins(Int_t(fitMassHi-fitMassLo)/BIN_SIZE_FAIL));
1794 dataFail->plotOn(mframeFail,MarkerStyle(kFullCircle),MarkerSize(0.8),DrawOption("ZP"));
1795 modelFail->plotOn(mframeFail);
1796 modelFail->plotOn(mframeFail,Components("backgroundFail"),LineStyle(kDashed),LineColor(kRed));
1797
1798 //
1799 // Plot passing probes
1800 //
1801 sprintf(pname,"pass%s_%i",name.Data(),ibin);
1802 sprintf(yield,"%u Events",(Int_t)passTree->GetEntries());
1803 sprintf(ylabel,"Events / %.1f GeV/c^{2}",(Double_t)BIN_SIZE_PASS);
1804 sprintf(nsigstr,"N_{sig} = %.1f #pm %.1f",NsigPass.getVal(),NsigPass.getPropagatedError(*fitResult));
1805 sprintf(chi2str,"#chi^{2}/DOF = %.3f",mframePass->chiSquare(nflpass));
1806 if(bkgpass>0)
1807 sprintf(nbkgstr,"N_{bkg} = %.1f #pm %.1f",NbkgPass.getVal(),NbkgPass.getPropagatedError(*fitResult));
1808 CPlot plotPass(pname,mframePass,"Passing probes","tag-probe mass [GeV/c^{2}]",ylabel,sOutDir);
1809 plotPass.AddTextBox(binlabelx,0.21,0.85,0.51,0.90,0,kBlack,-1);
1810 if((name.CompareTo("etapt")==0) || (name.CompareTo("etaphi")==0)) {
1811 plotPass.AddTextBox(binlabely,0.21,0.80,0.51,0.85,0,kBlack,-1);
1812 plotPass.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);
1813 } else {
1814 plotPass.AddTextBox(yield,0.21,0.81,0.51,0.85,0,kBlack,-1);
1815 }
1816 plotPass.AddTextBox(effstr,0.70,0.85,0.94,0.90,0,kBlack,-1);
1817 if(bkgpass>0)
1818 plotPass.AddTextBox(0.70,0.68,0.94,0.83,0,kBlack,-1,2,nsigstr,nbkgstr);//,chi2str);
1819 else
1820 plotPass.AddTextBox(0.70,0.73,0.94,0.83,0,kBlack,-1,1,nsigstr);//,chi2str);
1821 plotPass.Draw(cpass,kTRUE,format);
1822
1823 //
1824 // Plot failing probes
1825 //
1826 sprintf(pname,"fail%s_%i",name.Data(),ibin);
1827 sprintf(yield,"%u Events",(Int_t)failTree->GetEntries());
1828 sprintf(ylabel,"Events / %.1f GeV/c^{2}",(Double_t)BIN_SIZE_FAIL);
1829 sprintf(nsigstr,"N_{sig} = %.1f #pm %.1f",NsigFail.getVal(),NsigFail.getPropagatedError(*fitResult));
1830 sprintf(nbkgstr,"N_{bkg} = %.1f #pm %.1f",NbkgFail.getVal(),NbkgFail.getPropagatedError(*fitResult));
1831 sprintf(chi2str,"#chi^{2}/DOF = %.3f",mframePass->chiSquare(nflfail));
1832 CPlot plotFail(pname,mframeFail,"Failing probes","tag-probe mass [GeV/c^{2}]",ylabel,sOutDir);
1833 plotFail.AddTextBox(binlabelx,0.21,0.85,0.51,0.90,0,kBlack,-1);
1834 if((name.CompareTo("etapt")==0) || (name.CompareTo("etaphi")==0)) {
1835 plotFail.AddTextBox(binlabely,0.21,0.80,0.51,0.85,0,kBlack,-1);
1836 plotFail.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);
1837 } else {
1838 plotFail.AddTextBox(yield,0.21,0.81,0.51,0.85,0,kBlack,-1);
1839 }
1840 plotFail.AddTextBox(effstr,0.70,0.85,0.94,0.90,0,kBlack,-1);
1841 plotFail.AddTextBox(0.70,0.68,0.94,0.83,0,kBlack,-1,2,nsigstr,nbkgstr);//,chi2str);
1842 plotFail.Draw(cfail,kTRUE,format);
1843
1844 //
1845 // Write fit results
1846 //
1847 ofstream txtfile;
1848 char txtfname[100];
1849 sprintf(txtfname,"%s/fitres%s_%i.txt",sOutDir.Data(),name.Data(),ibin);
1850 txtfile.open(txtfname);
1851 assert(txtfile.is_open());
1852 fitResult->printStream(txtfile,RooPrintable::kValue,RooPrintable::kVerbose);
1853 txtfile << endl;
1854 printCorrelations(txtfile, fitResult);
1855 txtfile.close();
1856
1857 //
1858 // Clean up
1859 //
1860 delete esignalPass;
1861 delete ebackgroundPass;
1862 delete esignalFail;
1863 delete ebackgroundFail;
1864 delete modelPass;
1865 delete modelFail;
1866 delete dataCombined;
1867 delete dataPass;
1868 delete dataFail;
1869 delete sigPass;
1870 delete bkgPass;
1871 delete sigFail;
1872 delete bkgFail;
1873 delete histfile;
1874 delete datfile;
1875 }
1876
1877 //--------------------------------------------------------------------------------------------------
1878 void printCorrelations(ostream& os, RooFitResult *res)
1879 {
1880 ios_base::fmtflags flags = os.flags();
1881 const RooArgList *parlist = res->correlation("eff");
1882
1883 os << " Correlation Matrix" << endl;
1884 os << " --------------------" << endl;
1885 for(Int_t i=0; i<parlist->getSize(); i++) {
1886 for(Int_t j=0; j<parlist->getSize(); j++)
1887 os << " " << setw(7) << setprecision(4) << fixed << res->correlationMatrix()(i,j);
1888 os << endl;
1889 }
1890 os.flags(flags);
1891 }
1892
1893 //--------------------------------------------------------------------------------------------------
1894 void parseFitResults(ifstream &ifs, double &eff, double &errl, double &errh)
1895 {
1896 string line;
1897 while(getline(ifs,line)) {
1898 size_t found = line.find("eff");
1899 if(found!=string::npos) {
1900 found = line.find("+/-");
1901 if(found!=string::npos) {
1902 string varname, initval, pmstr;
1903 stringstream ss(line);
1904 ss >> varname >> initval >> eff >> pmstr >> errl;
1905 errh = errl;
1906
1907 } else {
1908 string varname, initval, errstr;
1909 stringstream ss(line);
1910 ss >> varname >> initval >> eff >> errstr;
1911 size_t ipos = errstr.find(",");
1912 string errlstr = errstr.substr(2,ipos-2);
1913 string errhstr = errstr.substr(ipos+2,errstr.length()-ipos-1);
1914 errl = atof(errlstr.c_str());
1915 errh = atof(errhstr.c_str());
1916 }
1917 }
1918 }
1919 }