ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/cbrown/Development/Plotting/Modules/Systematics.C
Revision: 1.3
Committed: Thu Mar 15 20:38:00 2012 UTC (13 years, 1 month ago) by buchmann
Content type: text/plain
Branch: MAIN
Changes since 1.2: +219 -16 lines
Log Message:
Added mSUGRA efficiency calculation

File Contents

# User Rev Content
1 buchmann 1.1 #include <iostream>
2     #include <vector>
3 buchmann 1.3 #include <assert.h>
4 buchmann 1.1 #include <sys/stat.h>
5     #include <algorithm>
6     #include <cmath>
7    
8     #include <TMath.h>
9     #include <TColor.h>
10     #include <TPaveText.h>
11     #include <TRandom.h>
12     #include <TF1.h>
13    
14     #ifndef SampleClassLoaded
15     #include "SampleClass.C"
16     #endif
17    
18 buchmann 1.3 /*#ifndef CrossSectionReaderLoaded
19     #include "CrossSectionReader.C"
20     #endif*/
21    
22 buchmann 1.1 #ifndef Verbosity
23     #define Verbosity 0
24     #endif
25    
26     #include <TFile.h>
27     #include <TTree.h>
28     #include <TH1.h>
29     #include <TCut.h>
30     #include <TMath.h>
31     #include <TLine.h>
32     #include <TCanvas.h>
33     #include <TProfile.h>
34     #include <TF1.h>
35    
36    
37    
38     Int_t nBins = 100;
39     Float_t jzbMin = -207;
40     Float_t jzbMax = 243;
41     Float_t jzbSel = 100;
42     int iplot=0;
43     int verbose=0;
44     string geqleq;
45     string mcjzbexpression;
46     bool automatized=false;//if we're running this fully automatized we don't want each function to flood the screen
47    
48     TString geq_or_leq() {
49     if(geqleq=="geq") return TString(">=");
50     if(geqleq=="leq") return TString("<=");
51     return TString("GEQ_OR_LEQ_ERROR");
52     }
53    
54     TString ngeq_or_leq() {
55     if(geqleq=="geq") return TString("<=");
56     if(geqleq=="leq") return TString(">=");
57     return TString("NGEQ_OR_LEQ_ERROR");
58     }
59    
60     //______________________________________________________________________________
61     Double_t Interpolate(Double_t x, TH1 *histo)
62     {
63     // Given a point x, approximates the value via linear interpolation
64     // based on the two nearest bin centers
65     // Andy Mastbaum 10/21/08
66     // in newer ROOT versions but not in the one I have so I had to work around that ...
67    
68     Int_t xbin = histo->FindBin(x);
69     Double_t x0,x1,y0,y1;
70    
71     if(x<=histo->GetBinCenter(1)) {
72     return histo->GetBinContent(1);
73     } else if(x>=histo->GetBinCenter(histo->GetNbinsX())) {
74     return histo->GetBinContent(histo->GetNbinsX());
75     } else {
76     if(x<=histo->GetBinCenter(xbin)) {
77     y0 = histo->GetBinContent(xbin-1);
78     x0 = histo->GetBinCenter(xbin-1);
79     y1 = histo->GetBinContent(xbin);
80     x1 = histo->GetBinCenter(xbin);
81     } else {
82     y0 = histo->GetBinContent(xbin);
83     x0 = histo->GetBinCenter(xbin);
84     y1 = histo->GetBinContent(xbin+1);
85     x1 = histo->GetBinCenter(xbin+1);
86     }
87     return y0 + (x-x0)*((y1-y0)/(x1-x0));
88     }
89     }
90    
91     //____________________________________________________________________________________
92     // Plotting with all contributions, i.e. sidebands, peak, osof,ossf ... (for a systematic)
93     float allcontributionsplot(TTree* events, TCut kBaseCut, TCut kMassCut, TCut kSidebandCut, TCut JZBPosCut, TCut JZBNegCut, int flipped) {
94     iplot++;
95     int count=iplot;
96     string locmcjzbexpression=mcjzbexpression;
97     // Define new histogram
98     string hname=GetNumericHistoName();
99     TH1F* hossfp = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
100     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kMassCut&&JZBPosCut&&cutOSSF,"goff");
101     hname=GetNumericHistoName();
102     TH1F* hossfn = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
103     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kMassCut&&JZBNegCut&&cutOSSF,"goff");
104    
105     hname=GetNumericHistoName();
106     TH1F* hosofp = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
107     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kMassCut&&JZBPosCut&&cutOSOF,"goff");
108     hname=GetNumericHistoName();
109     TH1F* hosofn = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
110     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kMassCut&&JZBNegCut&&cutOSOF,"goff");
111    
112     float obs=0;
113     float pred=0;
114     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
115     if(PlottingSetup::RestrictToMassPeak) {
116     hname=GetNumericHistoName();
117     TH1F* sbhossfp = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
118     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kSidebandCut&&JZBPosCut&&cutOSSF,"goff");
119     hname=GetNumericHistoName();
120     TH1F* sbhossfn = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
121     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kSidebandCut&&JZBNegCut&&cutOSSF,"goff");
122    
123     hname=GetNumericHistoName();
124     TH1F* sbhosofp = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
125     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kSidebandCut&&JZBPosCut&&cutOSOF,"goff");
126     hname=GetNumericHistoName();
127     TH1F* sbhosofn = new TH1F(hname.c_str(),hname.c_str(),1,-14000,14000);
128     events->Draw("("+TString(locmcjzbexpression)+")>>"+TString(hname),kBaseCut&&kSidebandCut&&JZBNegCut&&cutOSOF,"goff");
129    
130     obs = hossfp->Integral();
131     pred= hossfn->Integral() + (1.0/3)*( hosofp->Integral() - hosofn->Integral() + sbhossfp->Integral() - sbhossfn->Integral() + sbhosofp->Integral() - sbhosofn->Integral());
132    
133     if(flipped>0) {
134     obs = hossfn->Integral();
135     pred= hossfp->Integral() - (1.0/3)*( hosofp->Integral() - hosofn->Integral() + sbhossfp->Integral() - sbhossfn->Integral() + sbhosofp->Integral() - sbhosofn->Integral());
136     }
137     delete sbhossfp,sbhossfn,sbhosofp,sbhosofn;
138     } else {
139     obs = hossfp->Integral();
140     pred= hossfn->Integral() + (hosofp->Integral() - hosofn->Integral());
141     if(flipped>0) {
142     obs = hossfn->Integral();
143     pred= hossfp->Integral() - (hosofp->Integral() - hosofn->Integral());;
144     }
145     }
146    
147     delete hossfp,hossfn,hosofp,hosofn;
148     return obs-pred;
149     }
150    
151    
152     //____________________________________________________________________________________
153     // Efficiency plot
154     TH1F* plotEff(TTree* events, TCut kbase, TString informalname, int flipped) {
155     iplot++;
156     int count=iplot;
157     iplot++;
158     int count2=iplot;
159     // Define new histogram
160     char hname[30]; sprintf(hname,"hJzbEff%d",count);
161     char hname2[30]; sprintf(hname2,"hJzbEff%d",count2);
162     TH1F* hJzbEff = new TH1F(hname,"JZB selection efficiency ; JZB [GeV]; Efficiency",nBins,jzbMin,jzbMax);
163     TH1F* hJzbEff2= new TH1F(hname2,"JZB selection efficiency ; JZB [GeV]; Efficiency",1,-14000,14000);
164     Float_t step = (jzbMax-jzbMin)/static_cast<Float_t>(nBins);
165    
166     if(flipped==0) events->Draw((mcjzbexpression+">>"+(string)hname2).c_str(),("genJZB>-400"&&kbase),"goff");
167     else events->Draw(("(-"+mcjzbexpression+")>>"+(string)hname2).c_str(),("genJZB>-400"&&kbase),"goff");
168     Float_t maxEff = hJzbEff2->Integral();
169     if(verbose>0) dout << hname << " (" << informalname <<") " << maxEff << std::endl;
170    
171     if(verbose>0) dout << "JZB max = " << jzbMax << std::endl;
172     // Loop over steps to get efficiency curve
173     char cut[256];
174     for ( Int_t iBin = 0; iBin<nBins; ++iBin ) {
175     sprintf(cut,"genJZB>%3f",jzbMin+iBin*step);
176     if(flipped==0) events->Draw((mcjzbexpression+">>"+(string)hname2).c_str(),(TCut(cut)&&kbase),"goff");
177     if(flipped>0) events->Draw(("(-"+mcjzbexpression+")>>"+(string)hname2).c_str(),(TCut(cut)&&kbase),"goff");
178     Float_t eff = static_cast<Float_t>(hJzbEff2->Integral())/maxEff;
179     hJzbEff->SetBinContent(iBin+1,eff);
180     hJzbEff->SetBinError(iBin+1,TMath::Sqrt(eff*(1-eff)/maxEff));
181     }
182     delete hJzbEff2;
183     return hJzbEff;
184     }
185    
186    
187    
188     //________________________________________________________________________________________
189     // Master Formula
190     void master_formula(std::vector<float> eff, float &errHi, float &errLo) {
191    
192     float x0 = eff[0];
193     float deltaPos = 0, deltaNeg = 0;
194     for(int k = 0; k < (eff.size()-1)/2; k++) {
195     float xneg = eff[2*k+2];
196     float xpos = eff[2*k+1];
197     if(xpos-x0>0 || xneg-x0>0) {
198     if(xpos-x0 > xneg-x0) {
199     deltaPos += (xpos-x0)*(xpos-x0);
200     } else {
201     deltaPos += (xneg-x0)*(xneg-x0);
202     }
203     }
204     if(x0-xpos>0 || x0-xneg>0) {
205     if(x0-xpos > x0-xneg) {
206     deltaNeg += (xpos-x0)*(xpos-x0);
207     } else {
208     deltaNeg += (xneg-x0)*(xneg-x0);
209     }
210     }
211     }
212     errHi = sqrt(deltaPos);
213     errLo = sqrt(deltaNeg);
214    
215     }
216    
217    
218     //________________________________________________________________________________________
219     // Get normalization factor for the PDFs
220     float get_norm_pdf_factor(TTree *events, int k, string addcut) {
221    
222     TH1F *haux = new TH1F("haux", "", 10000, 0, 5);
223     char nameVar[20];
224     sprintf(nameVar, "pdfW[%d]", k);
225     events->Project("haux", nameVar, addcut.c_str());
226     float thisW = haux->Integral();
227     events->Project("haux", "pdfW[0]");
228     float normW = haux->Integral();
229    
230     float factor=thisW/normW;
231    
232     delete haux;
233    
234     return factor;
235    
236     }
237    
238    
239    
240     //________________________________________________________________________________________
241     // Pile-up efficiency
242     float pileup(TTree *events, bool requireZ, string informalname, int flipped, string addcut="",Float_t myJzbMax = 140. ) {
243     nBins = 16;
244     jzbMax = myJzbMax;
245    
246     // Acceptance cuts
247     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
248     TCut kbase(PlottingSetup::genMassCut&&"genNjets>2&&genZPt>0"&&cutmass&&cutOSSF);
249     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
250    
251     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
252     TH1F* hLM4 = plotEff(events,kbase,informalname,flipped);
253     hLM4->SetMinimum(0.);
254    
255     // Nominal function
256     TF1* func = new TF1("func","0.5*TMath::Erfc([0]*x-[1])",jzbMin,jzbMax);
257     func->SetParameter(0,0.03);
258     func->SetParameter(1,0.);
259     hLM4->Fit(func,"Q");
260    
261     // Pimped-up function
262     TF1* funcUp = (TF1*)func->Clone();
263     funcUp->SetParameter( 0, func->GetParameter(0)/1.1); // 10% systematic error (up in sigma => 0.1 in erfc)
264     if(!automatized) dout << " PU: " << funcUp->Eval(jzbSel) << " " << func->Eval(jzbSel)
265     << "(" << (funcUp->Eval(jzbSel)-func->Eval(jzbSel))/func->Eval(jzbSel)*100. << "%)" << std::endl;
266    
267     return (funcUp->Eval(jzbSel)-func->Eval(jzbSel))/func->Eval(jzbSel);
268    
269     }
270    
271     //____________________________________________________________________________________
272     // Effect of peak shifting
273     void PeakError(TTree *events,float &result, string mcjzb, float peakerr,int flipped,string addcut="") {
274     //Note: the cut used here is something like (JZBEXPRESSION+(peakerr)>50) without all the other cuts, to increase statistics (particularly for scans)
275     TString peakup("("+TString(mcjzb)+"+"+TString(any2string(TMath::Abs(peakerr)))+")"+geq_or_leq()+TString(any2string(jzbSel)));
276     TString peakdown("("+TString(mcjzb)+"-"+TString(any2string(TMath::Abs(peakerr)))+")"+geq_or_leq()+TString(any2string(jzbSel)));
277     TString peakcentral("("+TString(mcjzb)+")"+geq_or_leq()+TString(any2string(jzbSel)));
278     TString npeakup("("+TString(mcjzb)+"+"+TString(any2string(TMath::Abs(peakerr)))+")"+ngeq_or_leq()+"-"+TString(any2string(jzbSel)));
279     TString npeakdown("("+TString(mcjzb)+"-"+TString(any2string(TMath::Abs(peakerr)))+")"+ngeq_or_leq()+"-"+TString(any2string(jzbSel)));
280     TString npeakcentral("("+TString(mcjzb)+")"+ngeq_or_leq()+"-"+TString(any2string(jzbSel)));
281     nBins = 1;
282     string informalname="PeakErrorCalculation";
283     float resup,resdown,rescent;
284     for(int i=0;i<3;i++) {
285     string poscut,negcut;
286     if(i==0) {
287     poscut=peakcentral;
288     negcut=npeakcentral;
289     } else if(i==1) {
290     poscut=peakdown;
291     negcut=npeakdown;
292     } else if(i==2) {
293     poscut=peakup;
294     negcut=npeakup;
295     }
296     float res;
297     if(addcut=="") res=allcontributionsplot(events,cutnJets,cutmass,sidebandcut,poscut.c_str(),negcut.c_str(),flipped);
298     else res=allcontributionsplot(events,cutnJets&&addcut.c_str(),cutmass,sidebandcut,poscut.c_str(),negcut.c_str(),flipped);
299     if(i==0) rescent=res;
300     else if(i==1) resdown=res;
301     else if(i==2) resup=res;
302     }
303     if(TMath::Abs(rescent-resup)>TMath::Abs(rescent-resdown)) result=(TMath::Abs(rescent-resup)/(float)rescent);
304     else result=(TMath::Abs(rescent-resdown)/(float)rescent);
305     if(!automatized) cout << " " << result << endl;
306     }
307    
308    
309     void MCPartialefficiency(TTree *events,float &result, float &resulterr,int flipped, string mcjzb,bool requireZ,int Neventsinfile, string addcut="", int k = 0, int type = 0) {
310     if(!events) {
311     write_error(__FUNCTION__,"Tree passed for efficiency calculation is invalid!");
312     result=0;resulterr=0;
313     return;
314     }
315    
316     char jzbSelStr[256]; sprintf(jzbSelStr,"%f",jzbSel);
317     char metSel[256]; sprintf(metSel, "met[4] > %f", jzbSel);
318     string metSelection(metSel);
319     // All acceptance cuts at gen. level
320     //TCut kbase("abs(genMll-91.2)<20&&genNjets>2&&genZPt>0&&genJZB"+geq_or_leq()+TString(jzbSelStr)+"&&genId1==-genId2");
321     TCut kbase("");
322     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
323     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
324     // Corresponding reco. cuts
325    
326     TCut acceptance("genPt2 != 0");
327     TCut massId(cutmass&&cutOSSF);
328     TCut njets(cutnJets);
329     TCut jzbp;
330     TCut jzbn;
331     TCut met(("pfJetGoodNum > 1 && abs(mll-91.2) < 10.0 && id1 == id2 &&" + metSelection).c_str());
332     if(flipped==0) {
333     jzbp=TCut((TString(mcjzb)+geq_or_leq()+TString(jzbSelStr)));
334     jzbn=TCut((TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr)));
335     } else {
336     jzbp=TCut(TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
337     jzbn=TCut(TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
338     }
339     float ntotal = events->Draw("pt1", addcut.c_str(), "goff");
340     TCut theCut;
341     switch(type) {
342     case 1:
343     theCut = kbase+acceptance;
344     break;
345     case 2:
346     theCut = kbase+massId;
347     break;
348     case 3:
349     theCut = kbase+massId+njets;
350     break;
351     case 4:
352     theCut = kbase+massId+njets+jzbn;
353     break;
354     case 5:
355     theCut = kbase + met;
356     break;
357     default:
358     theCut = kbase+massId+njets+jzbn;
359     break;
360     }
361    
362     string stheCut(theCut);
363     char var[20];
364     sprintf(var, "pdfW[%d]", k);
365    
366     string svar(var);
367     string newtheCut;
368     if(k>0) newtheCut = "(" + stheCut + ")*" + svar;
369     else newtheCut = "(" + stheCut + ")"; // for k==0 or even k==-1 we don't need to evaluate PDFs
370    
371     TH1F *effh= new TH1F("effh","effh",1,-14000,14000);
372     if(k>=0) events->Draw((mcjzbexpression+">>effh").c_str(), newtheCut.c_str(),"goff");
373     else events->Draw((mcjzbexpression+">>effh").c_str(), theCut,"goff");
374     Float_t sel = effh->Integral();
375     Float_t nsel=0;
376     //Corrections due to normalization in the PDF. This has to be applied as well to the number of events in a file if the definition changes at some point.
377     float normFactor = 1;
378     if(k>=0) get_norm_pdf_factor(events, k, addcut);
379     sel = sel/normFactor;
380    
381     result=(sel)/ntotal;
382     resulterr=TMath::Sqrt(sel/ntotal*(1+sel/ntotal)/ntotal);
383    
384     delete effh;
385     }
386    
387 buchmann 1.3
388    
389     float XSForProcessViaAddCutWrapper(string addcut, map < pair<float, float>, map<string, float> > xsec, int i) {
390     int position = addcut.find("Abs(M0-");
391     string M0string=addcut.substr(position+7,4);
392     position=M0string.find(")");
393     if(position>0&&position<5) M0string=M0string.substr(0,position);
394     position = addcut.find("Abs(M12-");
395     string M12string=addcut.substr(position+8,4);
396     position=M0string.find(")");
397     if(position>0&&position<5) M12string=M12string.substr(0,position);
398     float m0=atof(M0string.c_str());
399     float m12=atof(M12string.c_str());
400     return GetXSecForPointAndChannel(m0,m12,xsec,i);
401     }
402    
403     float sum(vector<float> v) {
404     float sum=0;
405     for(int i=0;i<v.size();i++) sum+=v[i];
406     return sum;
407     }
408     Value mSUGRAefficiency(TTree *events,float &result, float &resulterr, int flipped, string mcjzb,bool requireZ,int Neventsinfile, int scantype, map < pair<float, float>, map<string, float> > xsec, string addcut="", int kwrong = -2) {
409     if(kwrong>0) {
410     write_error(__FUNCTION__,"Watch out, evaluation of PDF uncerts is done differently now .... asserting this and exiting, so long!");
411     assert(kwrong<=0);
412     }
413    
414     if(!events) {
415     write_error(__FUNCTION__,"Tree passed for efficiency calculation is invalid!");
416     result=0;
417     resulterr=0;
418     return Value(0,0);
419     }
420     char jzbSelStr[256]; sprintf(jzbSelStr,"%f",jzbSel);
421     // All acceptance cuts at gen. level
422     //TCut kbase("abs(genMll-91.2)<20&&genNjets>2&&genZPt>0&&genJZB"+geq_or_leq()+TString(jzbSelStr)+"&&genId1==-genId2");
423     TCut kbase(basiccut&&leptoncut);
424    
425     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
426     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
427     TCut ksel;//("pfJetGoodNum>2"&&cutmass&&"id1==id2&&"+TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
428    
429     TCut ksel2;//("pfJetGoodNum>2"&&cutmass&&"id1==id2&&"+TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
430     if(PlottingSetup::RestrictToMassPeak||!ConsiderSignalContaminationForLimits) {
431     ksel=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
432     ksel2=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
433     if(flipped>0) {
434     ksel=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
435     ksel2=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
436     }
437     }else {
438     //for off peak analysis we don't use the OSSF condition here yet so we can recycle these two cuts for the em condition!
439     ksel=TCut(cutnJets&&cutmass&&(TString(mcjzb)+geq_or_leq()+TString(jzbSelStr)));
440     ksel2=TCut(cutnJets&&cutmass&&(TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr)));
441     if(flipped>0) {
442     ksel=TCut(cutnJets&&cutmass&&(TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr)));
443     ksel2=TCut(cutnJets&&cutmass&&(TString(mcjzb)+geq_or_leq()+TString(jzbSelStr)));
444     }
445     }
446    
447     TCut posSide = kbase&&ksel;
448     TCut negSide = kbase&&ksel2;
449     string sposSide(posSide);
450     string snegSide(negSide);
451     char var[20];
452     string newPosSide = "((id1==id2)&&(" + sposSide + "))";
453     string newNegSide = "((id1==id2)&&(" + snegSide + "))";
454     string emnewPosSide = "((id1!=id2)&&(" + sposSide + "))"; // only used for off peak analysis
455     string emnewNegSide = "((id1!=id2)&&(" + snegSide + "))"; // only used for off peak analysis
456    
457     TH1F *effh= new TH1F("effh","effh",1,-14000,14000);
458     vector<float> sel;
459     vector<float> nsel;
460     vector<float> Nproc;
461    
462     for(int i=0;i<11;i++) {
463     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut(((string)sposSide+"&&(id1==id2)&&process=="+any2string(i)).c_str()))*cutWeight,"goff");//the OSSF condition is added for the offpeak analysis, in onpeak case it's there already but doesn't change anything.
464     sel.push_back(effh->Integral());
465     events->Draw(("id1>>effh"), (addcut+"&&process=="+any2string(i)).c_str(),"goff");
466     Nproc.push_back(effh->Integral());
467     }
468    
469    
470     ///----------------------------------------------- THIS PART REQUIRES STUDYING! -------------------------
471    
472     if(ConsiderSignalContaminationForLimits) {
473     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
474     if(PlottingSetup::RestrictToMassPeak) {
475     for(int i=0;i<11;i++) {
476     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut((newNegSide+"&&process=="+any2string(i)).c_str()))*cutWeight,"goff");
477     nsel.push_back(effh->Integral());
478     }
479     } else {
480     for(int i=0;i<11;i++) {
481     float nselproc=0;
482     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut((newNegSide+"&&process=="+any2string(i)).c_str()))*cutWeight,"goff");
483     nselproc += effh->Integral();
484     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut((emnewPosSide+"&&process=="+any2string(i)).c_str()))*cutWeight,"goff");
485     nselproc += effh->Integral();
486     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut((emnewNegSide+"&&process=="+any2string(i)).c_str()))*cutWeight,"goff");
487     nselproc -= effh->Integral();
488     nsel.push_back(nselproc);
489     }
490     }
491     }
492    
493     Value result_wo_signalcont;
494    
495     float resultwosigcont;
496     float resultwosigconterr;
497     if(ConsiderSignalContaminationForLimits) {
498     result=0;
499     resulterr=0;
500     float totalXS=0;
501     resultwosigcont=0;
502     resultwosigconterr=0;
503     for(int i=0;i<11;i++) {
504     float xsi=XSForProcessViaAddCutWrapper(addcut,xsec,i);
505     if(Nproc[i]<1) continue;
506     result+=((sel[i]-nsel[i])/Nproc[i])*xsi;
507     totalXS+=xsi;
508     resulterr+=xsi*(sel[i]+nsel[i]+(sel[i]-nsel[i])*(sel[i]-nsel[i])/Nproc[i])/(Nproc[i]*Nproc[i]);
509     resultwosigcont+=(sel[i]/Nproc[i])*xsi;
510     resultwosigconterr+=xsi*(sel[i]+(sel[i]*sel[i])/Nproc[i])/(Nproc[i]*Nproc[i]);
511     }
512     result=result/totalXS;
513     resulterr=TMath::Sqrt((1/totalXS)*resulterr);
514     resultwosigcont=resultwosigcont/totalXS;
515     resultwosigconterr=TMath::Sqrt((1/totalXS)*resultwosigconterr);
516     result_wo_signalcont=Value(resultwosigcont,resultwosigconterr);
517     } else {//no signal contamination considered:
518     result=0;
519     resulterr=0;
520     float totalXS=0;
521     for(int i=0;i<11;i++) {
522     float xsi=XSForProcessViaAddCutWrapper(addcut,xsec,i);
523     result+=((sel[i])/Nproc[i])*xsi;
524     totalXS+=xsi;
525     resulterr+=xsi*(sel[i]+(sel[i]*sel[i])/Nproc[i])/(Nproc[i]*Nproc[i]);
526     }
527     result=result/totalXS;
528     resulterr=TMath::Sqrt((1/totalXS)*resulterr);
529     result_wo_signalcont=Value(result,resulterr);
530     }
531    
532    
533     if(!automatized) dout << " MC efficiency: " << result << "+-" << resulterr << " ( JZB>" << jzbSel << " : " << sum(sel) << " , signal contamination : " << sum(nsel) << " and nevents=" << sum(Nproc) << ") " << std::endl;
534     delete effh;
535     return result_wo_signalcont;
536    
537     }
538    
539    
540 buchmann 1.1 //____________________________________________________________________________________
541     // Total selection efficiency (MC)
542     //returns the efficiency WITHOUT signal contamination, and the result and resulterr contain the result and the corresponding error
543 buchmann 1.3 Value MCefficiency(TTree *events,float &result, float &resulterr, int flipped, string mcjzb,bool requireZ,int Neventsinfile, int scantype, map < pair<float, float>, map<string, float> > xsec, string addcut="", int k = 0) {
544    
545     if(scantype==mSUGRA) return mSUGRAefficiency(events,result,resulterr,flipped,mcjzb,requireZ,Neventsinfile,scantype,xsec,addcut,k);
546 buchmann 1.1 if(!events) {
547     write_error(__FUNCTION__,"Tree passed for efficiency calculation is invalid!");
548     result=0;
549     resulterr=0;
550     return Value(0,0);
551     }
552    
553     char jzbSelStr[256]; sprintf(jzbSelStr,"%f",jzbSel);
554     // All acceptance cuts at gen. level
555     //TCut kbase("abs(genMll-91.2)<20&&genNjets>2&&genZPt>0&&genJZB"+geq_or_leq()+TString(jzbSelStr)+"&&genId1==-genId2");
556 buchmann 1.2 TCut kbase(basiccut&&leptoncut);
557 buchmann 1.1
558     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
559     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
560     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
561     // Corresponding reco. cuts
562     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
563     TCut ksel;//("pfJetGoodNum>2"&&cutmass&&"id1==id2&&"+TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
564     TCut ksel2;//("pfJetGoodNum>2"&&cutmass&&"id1==id2&&"+TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
565     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
566     if(PlottingSetup::RestrictToMassPeak||!ConsiderSignalContaminationForLimits) {
567 buchmann 1.2 ksel=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
568     ksel2=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
569 buchmann 1.1 if(flipped>0) {
570 buchmann 1.2 ksel=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr));
571     ksel2=TCut(cutnJets&&cutmass&&"id1==id2&&"+TString(mcjzb)+geq_or_leq()+TString(jzbSelStr));
572 buchmann 1.1 }
573     } else {
574     //for off peak analysis we don't use the OSSF condition here yet so we can recycle these two cuts for the em condition!
575 buchmann 1.2 ksel=TCut(cutnJets&&cutmass&&(TString(mcjzb)+geq_or_leq()+TString(jzbSelStr)));
576     ksel2=TCut(cutnJets&&cutmass&&(TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr)));
577 buchmann 1.1 if(flipped>0) {
578 buchmann 1.2 ksel=TCut(cutnJets&&cutmass&&(TString(mcjzb)+ngeq_or_leq()+TString("-")+TString(jzbSelStr)));
579     ksel2=TCut(cutnJets&&cutmass&&(TString(mcjzb)+geq_or_leq()+TString(jzbSelStr)));
580 buchmann 1.1 }
581     }
582    
583     TCut posSide = kbase&&ksel;
584     TCut negSide = kbase&&ksel2;
585     string sposSide(posSide);
586     string snegSide(negSide);
587     char var[20];
588     sprintf(var, "pdfW[%d]", k);
589     if(k==-1) sprintf(var,"1.0");//case in which we don't want to evaluate PDFs
590     string svar(var);
591     string newPosSide = "((id1==id2)&&(" + sposSide + "))*" + svar;
592     string newNegSide = "((id1==id2)&&(" + snegSide + "))*" + svar;
593     string emnewPosSide = "((id1!=id2)&&(" + sposSide + "))*" + svar; // only used for off peak analysis
594     string emnewNegSide = "((id1!=id2)&&(" + snegSide + "))*" + svar; // only used for off peak analysis
595    
596     TH1F *effh= new TH1F("effh","effh",1,-14000,14000);
597     if(k>=0)events->Draw((mcjzbexpression+">>effh").c_str(), TCut(newPosSide.c_str())*cutWeight,"goff");
598     else events->Draw((mcjzbexpression+">>effh").c_str(), TCut((sposSide+"&&(id1==id2)").c_str())*cutWeight,"goff");//the OSSF condition is added for the offpeak analysis, in onpeak case it's there already but doesn't change anything.
599     Float_t sel = effh->Integral();
600     Float_t nsel=0;
601    
602     ///----------------------------------------------- THIS PART REQUIRES STUDYING! -------------------------
603    
604     if(ConsiderSignalContaminationForLimits) {
605     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
606     if(PlottingSetup::RestrictToMassPeak) {
607     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut(newNegSide.c_str()))*cutWeight,"goff");
608     nsel += effh->Integral();
609 buchmann 1.3 cout << "Drawn with " << (TCut(newNegSide.c_str()))*cutWeight << endl;
610 buchmann 1.1 } else {
611     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut(newNegSide.c_str()))*cutWeight,"goff");
612 buchmann 1.2
613 buchmann 1.1 nsel += effh->Integral();
614     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut(emnewPosSide.c_str()))*cutWeight,"goff");
615     nsel += effh->Integral();
616     events->Draw((mcjzbexpression+">>effh").c_str(), (TCut(emnewNegSide.c_str()))*cutWeight,"goff");
617     nsel -= effh->Integral();
618     }
619     }
620    
621     //Corrections due to normalization in the PDF. This has to be applied as well to the number of events in a file if the definition changes at some point.
622     float normFactor = 1;
623     if(k>=0) get_norm_pdf_factor(events, k, addcut);
624     sel = sel/normFactor;
625     nsel = nsel/normFactor;
626    
627     Float_t tot = Neventsinfile;
628    
629     Value result_wo_signalcont;
630    
631     if(ConsiderSignalContaminationForLimits) {
632     result=(sel-nsel)/tot;
633     resulterr=(1.0/tot)*TMath::Sqrt(sel+nsel+(sel-nsel)*(sel-nsel)/tot);
634     result_wo_signalcont=Value(sel/tot,TMath::Sqrt(sel/tot*(1+sel/tot)/tot));
635     } else {//no signal contamination considered:
636     result=(sel)/tot;
637     resulterr=TMath::Sqrt(sel/tot*(1+sel/tot)/tot);
638     result_wo_signalcont=Value(result,resulterr);
639     }
640     if(!automatized && k>0 ) dout << "PDF assessment [" << k << "] : ";
641     if(!automatized) dout << " MC efficiency: " << result << "+-" << resulterr << " ( JZB>" << jzbSel << " : " << sel << " , signal contamination : " << nsel << " and nevents=" << tot << ") with normFact=" << normFactor << std::endl;
642     delete effh;
643     return result_wo_signalcont;
644     }
645    
646    
647    
648     //____________________________________________________________________________________
649     // Selection efficiency for one process (MC)
650     // not in use anymore.
651     /*
652     vector<float> processMCefficiency(TTree *events,int flipped, string mcjzb,bool requireZ,int Neventsinfile, string addcut) {
653     vector<float> process_efficiencies;
654     for(int iprocess=0;iprocess<=10;iprocess++) {
655     float this_process_efficiency,efferr;
656     stringstream addcutplus;
657     addcutplus<<addcut<<"&&(process=="<<iprocess<<")";
658     MCefficiency(events,this_process_efficiency, efferr,flipped,mcjzb,requireZ,Neventsinfile, addcutplus.str(),-1);
659     process_efficiencies.push_back(this_process_efficiency);
660     }
661     return process_efficiencies;
662     }
663     */
664    
665     void JZBefficiency(TTree *events, string informalname, float &jzbeff, float &jzbefferr, int flipped, bool requireZ, string addcut="") {
666     TCut kbase(genMassCut&&"genNjets>2&&genZPt>0"&&cutmass&&cutOSSF);
667     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
668     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
669     TH1F* hLM4 = plotEff(events,kbase,informalname,flipped);
670     Int_t bin = hLM4->FindBin(jzbSel); // To get the error
671     jzbeff=Interpolate(jzbSel,hLM4);
672     jzbefferr=hLM4->GetBinError(bin);
673     if(!automatized) dout << " Efficiency at JZB==" << jzbSel << std::endl;
674     if(!automatized) dout << " " << jzbeff << "+-" << jzbefferr << std::endl;
675     }
676    
677     //________________________________________________________________________
678     // Effect of energy scale on efficiency
679 buchmann 1.3 void JZBjetScale(TTree *events, bool domSUGRA, map < pair<float, float>, map<string, float> > xsec, float &jesdown, float &jesup, string informalname, int flipped, bool requireZ,string addcut="",Float_t jzbSelection=-1, TString plotName = "" ) {
680 buchmann 1.1 TCut kbase(genMassCut&&"genZPt>0");
681     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
682     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
683     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
684    
685     TCut ksel(cutmass&&cutOSSF);
686     TCut nJets("pfJetGoodNum>2");
687     stringstream down,up;
688     down << "pfJetGoodNumn1sigma>=3";
689     up << "pfJetGoodNump1sigma>=3";
690    
691     TCut nJetsP(up.str().c_str());
692     TCut nJetsM(down.str().c_str());
693    
694     if ( !(plotName.Length()>1) ) plotName = informalname;
695    
696 buchmann 1.3 TCut susyweight("1.0");
697     if(domSUGRA) {
698     stringstream susyweightS;
699     float sumweights=0;
700     susyweightS << "((";
701     for(int i=0;i<11;i++) {
702     if(i==0) susyweightS << "(";
703     if(i>0) susyweightS << " + ";
704     susyweightS << "(process==" << i << ")*";
705     float thisxsec=XSForProcessViaAddCutWrapper(addcut,xsec,i);
706     susyweightS << thisxsec;
707     sumweights+=thisxsec;
708     if(i==10) susyweightS << ")";
709     }
710     susyweightS << ")/" << sumweights << ")";
711     susyweight=TCut(susyweightS.str().c_str());
712     }
713    
714 buchmann 1.1 nBins = 1; jzbMin = jzbSel*0.95; jzbMax = jzbSel*1.05;
715 buchmann 1.3 TH1F* hist = plotEff(events,((kbase&&ksel&&nJets)*susyweight),informalname,flipped);
716     TH1F* histp = plotEff(events,((kbase&&ksel&&nJetsP)*susyweight),informalname,flipped);
717     TH1F* histm = plotEff(events,((kbase&&ksel&&nJetsM)*susyweight),informalname,flipped);
718 buchmann 1.1
719     // Dump some information
720     Float_t eff = Interpolate(jzbSel,hist);
721     Float_t effp = Interpolate(jzbSel,histp);
722     Float_t effm = Interpolate(jzbSel,histm);
723     if(!automatized) dout << " Efficiency at JZB==" << jzbSel << std::endl;
724     if(!automatized) dout << " JESup: " << effp << " (" << (effp-eff)/eff*100. << "%)" << std::endl;
725     if(!automatized) dout << " central: " << eff << std::endl;
726     if(!automatized) dout << " JESdown: " << effm << " (" << (effm-eff)/eff*100. << "%)" << std::endl;
727     jesup=(effp-eff)/eff;
728     jesdown=(effm-eff)/eff;
729     }
730    
731     //________________________________________________________________________
732     // Effect of energy scale on JZB efficiency
733 buchmann 1.3 void doJZBscale(TTree *events, bool domSUGRA, map < pair<float, float>, map<string, float> > xsec, float &down, float &up, float &syst, float systematic, string informalname, int flipped, bool requireZ, string addcut) {
734 buchmann 1.1
735     TCut kbase(genMassCut&&"genZPt>0&&genNjets>2");
736     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
737     flag_this_change(__FUNCTION__,__LINE__,true);//PlottingSetup::RestrictToMassPeak
738     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
739     TCut ksel(cutmass&&cutOSSF);
740    
741     nBins = 50;
742     jzbMin = 0.5*jzbSel;
743     jzbMax = 2.0*jzbSel;
744    
745 buchmann 1.3 TCut susyweight("1.0");
746     if(domSUGRA) {
747     stringstream susyweightS;
748     float sumweights=0;
749     susyweightS << "((";
750     for(int i=0;i<11;i++) {
751     if(i==0) susyweightS << "(";
752     if(i>0) susyweightS << " + ";
753     susyweightS << "(process==" << i << ")*";
754     float thisxsec=XSForProcessViaAddCutWrapper(addcut,xsec,i);
755     susyweightS << thisxsec;
756     sumweights+=thisxsec;
757     if(i==10) susyweightS << ")";
758     }
759     susyweightS << ")/" << sumweights << ")";
760     susyweight=TCut(susyweightS.str().c_str());
761     }
762    
763    
764    
765     TH1F* hist = plotEff(events,((kbase&&ksel)*susyweight),informalname,flipped);
766 buchmann 1.1
767     // Dump some information
768     Float_t eff = Interpolate(jzbSel,hist);
769     Float_t effp = Interpolate(jzbSel*(1.+systematic),hist);
770     Float_t effm = Interpolate(jzbSel*(1.-systematic),hist);
771     if(!automatized) dout << " efficiency at JZB==" << jzbSel*(1.+systematic) << "(-"<<systematic*100<<"%) : " << effp << " (" << ((effp-eff)/eff)*100. << "%)" << std::endl;
772     if(!automatized) dout << " efficiency at JZB==" << jzbSel << ": " << eff << std::endl;
773     if(!automatized) dout << " efficiency at JZB==" << jzbSel*(1.-systematic) << "(-"<<systematic*100<<"%) : " << effm << " (" << ((effm-eff)/eff)*100. << "%)" << std::endl;
774     up=((effp-eff)/eff);
775     down=((effm-eff)/eff);
776     }
777    
778     //________________________________________________________________________
779     // JZB response (true/reco. vs. true)
780     void JZBresponse(TTree *events, string name, bool requireZ, float &resp, float &resperr, int flipped, string addcut="", bool isMET = kFALSE, Float_t myJzbMax = 200., Int_t nPeriods = 9 ) {
781    
782     jzbMin = 20;
783     flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
784     TCut kbase(genMassCut&&"genZPt>0&&genNjets>2");
785     if(addcut!="") kbase=kbase&&addcut.c_str();//this is mostly for SUSY scans (adding requirements on masses)
786     flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
787     if(requireZ&&PlottingSetup::RestrictToMassPeak) kbase=kbase&&"TMath::Abs(genMID)==23";
788     flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
789     TCut ksel(cutmass&&cutOSSF);
790    
791     TProfile* hJzbResp = new TProfile("hJzbResp","JZB response ; JZB true (GeV/c); JZB reco. / JZB true", nPeriods, jzbMin, myJzbMax, "" );
792    
793     string locmcjzbexpression=mcjzbexpression;
794     if(flipped>0) locmcjzbexpression="-"+locmcjzbexpression;
795     string possibleminus="";
796     if(flipped>0) possibleminus="-";
797     if (!isMET) events->Project("hJzbResp","("+TString(locmcjzbexpression)+")/("+possibleminus+"genJZB):("+possibleminus+"genJZB)",kbase&&ksel);
798     else events->Project("hJzbResp","met[4]/genMET:genMET",kbase&&ksel);
799    
800     hJzbResp->SetMaximum(1.2);
801     hJzbResp->SetMinimum(0.2);
802     hJzbResp->Fit("pol0","Q");
803     TF1 *fittedfunction = hJzbResp->GetFunction("pol0");
804     if(!fittedfunction) {
805     // in case there are not enough points passing our selection
806     cout << "OOPS response function invalid, assuming 100% error !!!!" << endl;
807     resp=1;
808     resperr=1;
809     } else {
810     resp=fittedfunction->GetParameter(0);
811     resperr=fittedfunction->GetParError(0);
812     if(!automatized) dout << " Response: " << resp << " +/- " << resperr << endl;
813     }
814     delete hJzbResp;
815     }
816    
817    
818     //________________________________________________________________________________________
819     // PDF uncertainty
820 buchmann 1.3 float get_pdf_uncertainty(TTree *events, int flipped, string mcjzb, bool requireZ, int Neventsinfile, int scantype, map < pair<float, float>, map<string, float> > xsec, int NPdfs, string addcut="") {
821 buchmann 1.1 std::vector<float> efficiency;
822     for(int k = 1; k < NPdfs; k++) {
823     float result, resulterr;
824     Value flipval;
825 buchmann 1.3 MCefficiency(events, result, resulterr, flipped, mcjzb, requireZ, Neventsinfile, scantype, xsec, addcut, k);
826 buchmann 1.1 efficiency.push_back(result);
827     }
828     float errHi, errLow,err;
829     master_formula(efficiency, errHi, errLow);
830     err=errLow;
831     if(errHi>errLow) err=errHi;
832     if(!automatized) dout << " Uncertainty from PDF: " << errLow << " (low) and " << errHi << "(high) ---> Picked " << err << endl;
833     return err;
834    
835     }
836    
837     int get_npdfs(TTree *events) {
838     int NPDFs;
839     events->SetBranchAddress("NPdfs",&NPDFs);
840     events->GetEntry(1);
841     return NPDFs;
842     }
843    
844    
845 buchmann 1.3 void do_systematics_for_one_file(TTree *events,int Neventsinfile,string informalname, vector<vector<float> > &results,int flipped, map < pair<float, float>, map<string, float> > xsec, string mcjzb,string datajzb,float peakerror,bool requireZ=false, string addcut="", bool isscan=false,int scantype=-1) {
846 buchmann 1.1 float JZBScaleUncert=0.05;
847     mcjzbexpression=mcjzb;
848     float triggereff=2.0/100;// in range [0,1]
849     dout << "Trigger efficiency not implemented in this script yet, still using external one" << endl;
850     float leptonseleff=2.0/100;// in range [0,1]
851     leptonseleff=TMath::Sqrt(leptonseleff*leptonseleff+leptonseleff*leptonseleff); // because the 2% is per lepton
852     dout << "Lepton selection efficiency not implemented in this script yet, still using external one" << endl;
853    
854     int NPdfs=0;
855     if(isscan) NPdfs = get_npdfs(events);
856    
857     float mceff,mcefferr,jzbeff,jzbefferr;
858     if(!automatized) dout << "MC efficiencies:" << endl;
859     Value flipefficiency;
860 buchmann 1.3 Value mceff_nosigcont = MCefficiency(events,mceff,mcefferr,flipped,mcjzb,requireZ,Neventsinfile,scantype,xsec,addcut,-1);
861 buchmann 1.1 if(!automatized) cout << " Without signal contamination, we find an efficiency of " << mceff_nosigcont << endl;
862    
863     if(PlottingSetup::computeJZBefficiency) JZBefficiency(events,informalname,jzbeff,jzbefferr,flipped,requireZ,addcut);
864     if(!automatized) dout << "JZB efficiency: " << jzbeff << "+/-" << jzbefferr << endl;
865    
866     if(!automatized) dout << "Error from Peak position:";
867     float sysfrompeak=0;
868     PeakError(events,sysfrompeak,mcjzb,peakerror,flipped,addcut);
869 buchmann 1.3
870     bool docomplicatedmSUGRAxsreweighting=false;
871    
872 buchmann 1.1 if(!automatized) dout << "Jet energy scale (JES): " << std::endl;
873     float jesup,jesdown;
874 buchmann 1.3 JZBjetScale(events,scantype==mSUGRA&&docomplicatedmSUGRAxsreweighting,xsec,jesdown,jesup,informalname,flipped,requireZ,addcut);
875 buchmann 1.1
876     if(!automatized) dout << "JZB scale: " << std::endl;
877     float scaleup,scaledown,scalesyst;
878 buchmann 1.3 doJZBscale(events,scantype==mSUGRA&&docomplicatedmSUGRAxsreweighting,xsec,scaledown,scaleup,scalesyst,JZBScaleUncert,informalname,flipped,requireZ,addcut);
879 buchmann 1.1
880     if(!automatized) dout << "JZB response: " << std::endl;
881     float resp,resperr;
882     if(PlottingSetup::computeJZBresponse) {
883     if(!automatized) dout << "JZB response: " << std::endl;
884     if(!isscan) JZBresponse(events,informalname,requireZ,resp,resperr,flipped,addcut);
885     }
886    
887     if(!automatized) dout << "Pileup: " << std::endl;
888     // float resolution;
889     //resolution=pileup(events,requireZ,informalname,flipped,addcut);
890    
891     float PDFuncert=0;
892     if(!automatized) dout << "Assessing PDF uncertainty: " << std::endl;
893 buchmann 1.3 if(isscan&&scantype!=mSUGRA) PDFuncert = get_pdf_uncertainty(events, flipped, mcjzb, requireZ, Neventsinfile, scantype, xsec, NPdfs, addcut);//for mSUGRA this is done differently!
894 buchmann 1.1
895     dout << "_______________________________________________" << endl;
896     dout << " SUMMARY FOR " << informalname << " with JZB>" << jzbSel << " (all in %) ";
897     if(addcut!="") dout << "With additional cut: " << addcut;
898     dout << endl;
899     dout << "MC efficiency: " << mceff << "+/-" << mcefferr << endl; // in range [0,1]
900     dout << "Trigger efficiency: " << triggereff << endl; // in range [0,1]
901     dout << "Lepton Sel Eff: " << leptonseleff << endl; // in range [0,1]
902     dout << "Jet energy scale: " << jesup << " " << jesdown << endl; // in range [0,1]
903     dout << "JZB Scale Uncert: " << scaledown << " " << scaleup << endl; // in range [0,1]
904     // dout << "Resolution : " << resolution << endl; // in range [0,1]
905     dout << "From peak : " << sysfrompeak << endl; // in range [0,1]
906     if(isscan) dout << "PDF uncertainty : " << PDFuncert << endl; // in range [0,1]
907     if(PlottingSetup::computeJZBefficiency) dout << "JZB efficiency: " << jzbeff << "+/-" << jzbefferr << " (not yet included below) " << endl; // in range [0,1]
908     if(PlottingSetup::computeJZBresponse)dout << "JZB response : " << resp << " +/-" << resperr << " (not yet included below) " << endl; // in range [0,1]
909    
910     float toterr=0;
911     toterr+=(triggereff)*(triggereff);
912     toterr+=(leptonseleff)*(leptonseleff);
913     if(fabs(jesup)>fabs(jesdown)) toterr+=(jesup*jesup); else toterr+=(jesdown*jesdown);
914     if(fabs(scaleup)>fabs(scaledown)) toterr+=(scaleup*scaleup); else toterr+=(scaledown*scaledown);
915     // toterr+=(resolution*resolution);
916     toterr+=(sysfrompeak*sysfrompeak);
917     if(isscan) toterr+=(PDFuncert*PDFuncert);
918     dout << "TOTAL SYSTEMATICS: " << TMath::Sqrt(toterr) << " --> " << TMath::Sqrt(toterr)*mceff << endl;
919     float systerr=TMath::Sqrt(toterr)*mceff;
920     toterr=TMath::Sqrt(toterr*mceff*mceff+mcefferr*mcefferr);//also includes stat err!
921    
922     dout << "FINAL RESULT : " << 100*mceff << " +/- "<< 100*mcefferr << " (stat) +/- " << 100*systerr << " (syst) %" << endl;
923     dout << " we thus use the sqrt of the sum of the squares of the stat & syst err, which is : " << 100*toterr << endl;
924     dout << "_______________________________________________" << endl;
925    
926     //Do not modify the lines below or mess with the order; this order is expected by all limit calculating functions!
927     vector<float> res;
928     res.push_back(jzbSel);
929     res.push_back(mceff);
930     res.push_back(mcefferr);
931     res.push_back(toterr);
932     res.push_back(TMath::Sqrt((mcefferr)*(mcefferr)+(toterr*toterr)));
933     if(fabs(jesup)>fabs(jesdown)) res.push_back(fabs(jesup)); else res.push_back(fabs(jesdown));
934     if(fabs(scaleup)>fabs(scaledown)) res.push_back(fabs(scaleup)); else res.push_back(fabs(scaledown));
935     // res.push_back(fabs(resolution));
936     res.push_back(0.0);
937     res.push_back(mceff_nosigcont.getValue());
938     res.push_back(mceff_nosigcont.getError());
939     if(isscan) res.push_back(PDFuncert);
940     results.push_back(res);
941     }
942    
943     vector<vector<float> > compute_systematics(string mcjzb, float mcpeakerror, int flipped, string datajzb, samplecollection &signalsamples, vector<float> bins, bool requireZ=false) {
944     automatized=true;
945     vector< vector<float> > systematics;
946 buchmann 1.3 map < pair<float, float>, map<string, float> > xsec; // only needed for mSUGRA, and in that case this funciton isn't called
947    
948 buchmann 1.1 for (int isignal=0; isignal<signalsamples.collection.size();isignal++) {
949     dout << "Looking at signal " << (signalsamples.collection)[isignal].filename << endl;
950     for(int ibin=0;ibin<bins.size();ibin++) {
951     jzbSel=bins[ibin];
952     geqleq="geq";
953 buchmann 1.3 do_systematics_for_one_file((signalsamples.collection)[isignal].events,(signalsamples.collection)[isignal].Nentries,(signalsamples.collection)[isignal].samplename,systematics,flipped,xsec,mcjzb,datajzb,mcpeakerror,requireZ);
954 buchmann 1.1 }//end of bin loop
955     }//end of signal loop
956     return systematics;
957     }