ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/auterman/SusyScan/Limits/cls.cc
Revision: 1.1.1.1 (vendor branch)
Committed: Wed Jan 26 14:37:51 2011 UTC (14 years, 3 months ago) by auterman
Content type: text/plain
Branch: Limits
CVS Tags: start
Changes since 1.1: +0 -0 lines
Error occurred while calculating annotation data.
Log Message:
Limt calculation code

File Contents

# Content
1 //root
2 #include "TCanvas.h"
3 #include "TPostScript.h"
4 #include "TH1D.h"
5 #include "TF1.h"
6 #include "TLegend.h"
7 #include "TStyle.h"
8 #include "TRandom3.h"
9 #include "TGraph.h"
10 #include "TLatex.h"
11 #include "TLine.h"
12 #include "TArrow.h"
13 #include "TLimit.h"
14 #include "TLimitDataSource.h"
15 #include "TConfidenceLevel.h"
16 #include "TVectorT.h"
17
18 //User
19 #include "cls.h"
20 #include "solve.h"
21 #include "table.h"
22 #include "significance.h"
23 #include "ConfigFile.h"
24 //system
25 #include <iostream>
26 #include <iomanip>
27 #include <cmath>
28 #include <assert.h>
29 #include <fstream>
30 #include <time.h>
31
32 cls::cls():
33 plotindex_(0),fNMC_(5000),outputfilename_("cls.ps"),signal_(0),backgd_(0),data_(0)
34 {
35 stat_=false;syst_=false;
36 do1DScan_ = false;
37 if (!data_ && signal_ && backgd_) {
38 data_ = (TH1D*)MakePseudoData( backgd_ );//, signal_ );
39 isPseudoData = true;
40 } else
41 isPseudoData = false;
42 }
43
44 cls::cls(std::string n,TH1*s,TH1*b,TH1*d):
45 plotindex_(0),fNMC_(50000),outputfilename_(n),signal_(s),backgd_(b),data_(d)
46 {
47 stat_=false;syst_=false;
48 do1DScan_ = false;
49 if (!data_ && signal_ && backgd_) {
50 data_ = (TH1D*)MakePseudoData( backgd_ );//, signal_ );
51 isPseudoData = true;
52 } else
53 isPseudoData = false;
54 }
55
56 cls::cls(std::string n,std::string ScanParName,std::vector<double>ScanPar,std::vector<TH1*>s,TH1*b,TH1*d):
57 plotindex_(0),fNMC_(100000),outputfilename_(n),ScanParName_(ScanParName),ScanPar_(ScanPar),backgd_(b),data_(d)
58 {
59 stat_=true;syst_=false;
60 signals_ = s;
61 signal_ = (signals_.size()>0 ? signals_[0] : 0);
62 do1DScan_ = (signals_.size()>1 ? true : false);
63
64 if (!data_ && signal_ && backgd_) {
65 data_ = (TH1D*)MakePseudoData( backgd_ );//, signal_ );
66 isPseudoData = true;
67 } else
68 isPseudoData = false;
69 }
70
71
72 void cls::GetXandYbyInterpolation( const double x, TH1D *& sig)
73 {
74 ///naive linear interpolation for each bin contents and bin error:
75 sig=0;
76 double xmin=-99999, xmax=999999;
77 int imin, imax;
78 for (std::vector<double>::const_iterator it=ScanPar_.begin();it!=ScanPar_.end();++it){
79 if (*it<=x && xmin<*it) { xmin= *it; imin=it-ScanPar_.begin(); continue;}
80 if (*it>=x && xmax>*it) { xmax= *it; imax=it-ScanPar_.begin(); }
81 }
82 if (xmin<0) return;
83 sig = (TH1D*)signals_[imin]->Clone();
84 if (xmax>99999||xmin==xmax) return;
85 TH1D * SIG = (TH1D*)signals_[imax]->Clone();
86
87 for (int i=1; i<=sig->GetXaxis()->GetNbins(); ++i){//avoid under- and overflow bins
88 //std::cout <<"sig_left: x="<<xmin<<", y="<<sig->GetBinContent(i);
89 double k = (SIG->GetBinContent(i)-sig->GetBinContent(i))/(xmax-xmin);
90 double kerr = (SIG->GetBinError(i)-sig->GetBinError(i))/(xmax-xmin);
91 sig->SetBinContent(i,sig->GetBinContent(i)+k*(x-xmin));
92 sig->SetBinError(i,sig->GetBinError(i)+kerr*(x-xmin));
93 //std::cout <<"; sig_new: x="<<x<<", y="<<sig->GetBinContent(i)
94 // <<"; sig_right: x="<<xmax<<", y="<<SIG->GetBinContent(i)
95 // <<std::endl;
96 }
97 delete SIG;
98 }
99
100
101
102 double cls::operator()(const double x, const double * par)
103 {
104 double cl;
105 TH1D *sig=0;
106 if (do1DScan_) {
107 GetXandYbyInterpolation(x, sig);
108 if (!sig) return 99999;
109 }
110 else {
111 sig = (TH1D*)signal_->Clone();
112 sig->Scale( x );
113 }
114 TLimitDataSource * source = new TLimitDataSource(sig,(TH1D*)backgd_,(TH1D*)data_);
115 TConfidenceLevel * confl = TLimit::ComputeLimit(source,fNMC_,stat_);
116 if (par[1]) cl = confl->CLs();
117 else cl = confl->GetExpectedCLs_b();
118 delete confl;
119 delete sig;
120 delete source;
121 return cl - par[0]; //par[0] is the requested Confidence Level (e.g. 0.05)
122 }
123
124 double cls::GetObservedXsecLimit(double cl, double min, double max)
125 {
126 double par[] = {cl,true};
127 return TSolve<cls>( this, &cls::operator(), par, min, max)();
128 }
129 double cls::GetExpectedXsecLimit(double cl, double min, double max)
130 {
131 double par[] = {cl,false};
132 return TSolve<cls>( this, &cls::operator(), par, min, max)();
133 }
134
135 TH1 * cls::MakePseudoData(TH1 const *b, TH1 const *s)
136 {
137 char * name = new char[100];
138 sprintf(name,"data%d",plotindex_++);
139 char * title = new char[128];
140 sprintf(title,";%s;events",b->GetXaxis()->GetTitle());
141 TH1 * result = (TH1D*)b->Clone( title );
142 TRandom3 * rand = new TRandom3(0);
143 for (int i=0; i<=b->GetNbinsX(); ++i){
144 double entry;
145 double uncert;
146 if (s==0) {
147 entry = rand->Poisson( b->GetBinContent(i) );
148 uncert = rand->Gaus(0, b->GetBinError(i));
149 }
150 else {
151 entry = rand->Poisson( b->GetBinContent(i)+s->GetBinContent(i) );
152 uncert = rand->Gaus(0, b->GetBinError(i)+s->GetBinError(i));
153 }
154 result->SetBinContent(i,entry+uncert);
155 result->SetBinError(i,sqrt(entry+uncert));
156 }
157 delete name;
158 delete title;
159 delete rand;
160 return result;
161 }
162
163 void cls::Draw(bool doeps)
164 {
165 if (do1DScan_) DrawVsSignalParam(doeps);
166 else DrawVsXsec(doeps);
167 }
168
169 void cls::Sort(double &v1, double &v2)
170 {
171 if (v1>v2){
172 double temp(v1);
173 v1=v2;
174 v2=temp;
175 }
176 }
177
178 void cls::DrawVsSignalParam(bool doeps)
179 {
180 gStyle->SetHistFillColor(0);
181 gStyle->SetPalette(1);
182 gStyle->SetCanvasColor(0);
183 gStyle->SetCanvasBorderMode(0);
184 gStyle->SetPadColor(0);
185 gStyle->SetPadBorderMode(0);
186 gStyle->SetFrameBorderMode(0);
187
188 gStyle->SetTitleFillColor(0);
189 gStyle->SetTitleBorderSize(0);
190 gStyle->SetTitleX(0.10);
191 gStyle->SetTitleY(0.98);
192 gStyle->SetTitleW(0.8);
193 gStyle->SetTitleH(0.06);
194
195 gStyle->SetErrorX(0);
196 gStyle->SetStatColor(0);
197 gStyle->SetStatBorderSize(0);
198 gStyle->SetStatX(0);
199 gStyle->SetStatY(0);
200 gStyle->SetStatW(0);
201 gStyle->SetStatH(0);
202
203 gStyle->SetTitleFont(22);
204 gStyle->SetLabelFont(22,"X");
205 gStyle->SetLabelFont(22,"Y");
206 gStyle->SetLabelFont(22,"Z");
207 gStyle->SetLabelSize(0.03,"X");
208 gStyle->SetLabelSize(0.03,"Y");
209 gStyle->SetLabelSize(0.03,"Z");
210
211 if (!backgd_ || !signal_)
212 {
213 std::cerr << "ERROR! &(background histogram)="<<backgd_
214 << ", &(signal histogram)="<<signal_<<std::endl;
215 return;
216 }
217
218 //Draw MET for background, signal & data:
219 TCanvas * c1 = new TCanvas("","",600,600);
220 TPostScript * ps = new TPostScript( outputfilename_.c_str(),111);
221
222 //CLs vs x-section:
223 //int n_points = signals_.size();
224 int n_points = 51;
225 double min = 999999.;
226 double max = -99999.;
227 for (std::vector<double>::const_iterator it=ScanPar_.begin();it!=ScanPar_.end();++it){
228 if (*it<min) min = *it;
229 if (*it>max) max = *it;
230 }
231 --n_points;
232
233 TLine * line = new TLine( );
234
235 char * title = new char[256];
236 sprintf(title,";%s;CLs",ScanParName_.c_str());
237 TH1D * axis_cls = new TH1D("axis", title,0,min,max);
238 TGraph * cls_obs = new TGraph(1);
239 TGraph * cls_exp = new TGraph(1);
240 sprintf(title,";%s;-2 ln Q",ScanParName_.c_str());
241 TH1D * axis_lnQ = new TH1D("-2lnQ_obs", title,0,min,max);
242 TGraph * lnQ_obs = new TGraph(1);
243 TGraph * lnQ_exp_b = new TGraph(1);
244 TGraph * lnQ_exp_sb = new TGraph(1);
245 double y_cls_exp1[n_points*2+2];
246 double x_cls[n_points*2+2];
247 double y_cls_exp2[n_points*2+2];
248 double y_lnQ_exp1[n_points*2+2];
249 double y_lnQ_exp2[n_points*2+2];
250 double x_lnQ[n_points*2+2];
251 int i_cls=0; // i_lnQ=0;
252
253
254 TH1D * backgd = (TH1D*)backgd_->Clone();
255 TH1D * data = (TH1D*)data_->Clone();
256 data->SetMarkerStyle(8);
257 backgd->SetTitle("");
258
259 TTable limits("Limits of parameter scan","|");
260 limits.AddColumn<double>(ScanParName_);
261 limits.AddColumn<double>(" #s ");
262 limits.AddColumn<double>("+-ds");
263 limits.AddColumn<double>("CL_s ");limits.SetPrecision(3,5);
264 limits.AddColumn<double>("CL_sb");limits.SetPrecision(4,5);
265 limits.AddColumn<double>("CL_b ");limits.SetPrecision(5,5);
266 limits.AddColumn<double>("<CL_sb>_b");limits.SetPrecision(6,5);
267 limits.AddColumn<double>("<CL_b>_b");limits.SetPrecision(7,5);
268 limits.AddColumn<double>("<CL_s>_b-2s");limits.SetPrecision(8,5);
269 limits.AddColumn<double>("<CL_s>_b-1s");limits.SetPrecision(9,5);
270 limits.AddColumn<double>("<CL_s>_b");limits.SetPrecision(10,5);
271 limits.AddColumn<double>("<CL_s>_b+1s");limits.SetPrecision(11,5);
272 limits.AddColumn<double>("<CL_s>_b+2s");limits.SetPrecision(12,5);
273 limits.AddColumn<double>("-2lnQ");
274 limits.AddColumn<double>("<lnQ_b>");
275 limits.AddColumn<double>("<lnQ_sb>");
276
277 std::cout << "Scanning " << ScanParName_ << " in " << n_points << " steps from " << min << " to "<< max << ":"<<std::endl;
278 for (int i=0; i<=n_points; ++i){
279
280 double x;
281 TH1D * signal;
282
283 if (n_points-1==(int)signals_.size()){
284 x = ScanPar_[i];
285 signal = (TH1D*)signals_[i]->Clone();
286 } else {
287 x = min + (max-min)/(double)(n_points)*(double)i;
288 GetXandYbyInterpolation( x, signal);
289 }
290
291 if (!signal) { std::cout << "Error at x="<<x<<"; skipping..."<< std::endl; continue;}
292
293 signal->SetLineColor(2);
294 signal->SetLineWidth(3);
295 c1->SetLogy(0);
296 if (!i) backgd->GetXaxis()->SetTitle( signal->GetXaxis()->GetTitle() );
297 backgd->Draw("h");
298 signal->Draw("h,same");
299 data->Draw("pe,same");
300 c1->Update();
301 ps->NewPage();
302
303 //cout the CL's:
304 TLimitDataSource* mydatasource = new TLimitDataSource(signal,backgd,data);
305 TConfidenceLevel *myconfidence = TLimit::ComputeLimit(mydatasource,fNMC_,stat_);
306
307 double cls = myconfidence->CLs();
308 double cls_b = myconfidence->GetExpectedCLs_b();
309 double cls_b_p1 = myconfidence->GetExpectedCLs_b(1);
310 double cls_b_n1 = myconfidence->GetExpectedCLs_b(-1);
311 double cls_b_p2 = myconfidence->GetExpectedCLs_b(2);
312 double cls_b_n2 = myconfidence->GetExpectedCLs_b(-2);
313 Sort(cls_b_n1, cls_b_p1);
314 Sort(cls_b_n2, cls_b_p2);
315
316 double ds=0, db=0;
317 for (int a=0; a<signal->GetNbinsX()+1; ++a) ds+=signal->GetBinError(a);
318 for (int a=0; a<backgd->GetNbinsX()+1; ++a) db+=backgd->GetBinError(a);
319
320 limits.Fill(x,
321 signal->Integral(),ds,
322 backgd->Integral(),db,
323 cls,myconfidence->CLsb(),myconfidence->CLb(),
324 myconfidence->GetExpectedCLsb_b(),myconfidence->GetExpectedCLb_b(),
325 //myconfidence->GetExpectedStatistic_b(1),myconfidence->GetExpectedStatistic_b(-1),myconfidence->GetExpectedStatistic_b(2),myconfidence->GetExpectedStatistic_b(-2),
326 cls_b_n2,cls_b_n1,cls_b,cls_b_p1,cls_b_p2,
327 myconfidence->GetStatistic(),myconfidence->GetExpectedStatistic_b(),myconfidence->GetExpectedStatistic_sb()
328 );
329
330 //Draw the expected and observed test statistics:
331 c1->SetLogy(1);
332 TH1D h("TConfidenceLevel_Draw","",50,0,0);
333 double * fTSB = myconfidence->GetTestStatistic_B();
334 double * fTSS = myconfidence->GetTestStatistic_SB();
335 for (int j=0; j<fNMC_; j++) {
336 h.Fill(-2*(fTSB[j]-myconfidence->GetStot() ));
337 h.Fill(-2*(fTSS[j]-myconfidence->GetStot() ));
338 }
339 sprintf(title,"b_hist_%d",plotindex_++);
340 TH1D* b_hist = new TH1D(title, ";-2 ln Q;normalized p.d.f.",50,h.GetXaxis()->GetXmin(),h.GetXaxis()->GetXmax());
341 sprintf(title,"sb_hist_%d",plotindex_++);
342 TH1D* sb_hist = new TH1D(title,";-2 ln Q;normalized p.d.f.",50,h.GetXaxis()->GetXmin(),h.GetXaxis()->GetXmax());
343 for (int j=0; j<fNMC_; j++) {
344 b_hist->Fill(-2*(fTSB[j]-myconfidence->GetStot() ));
345 sb_hist->Fill(-2*(fTSS[j]-myconfidence->GetStot() ));
346 }
347 b_hist->Scale(1.0/b_hist->Integral());
348 sb_hist->Scale(1.0/sb_hist->Integral());
349 b_hist->GetYaxis()->SetTitleOffset(1.3);
350 b_hist->SetMinimum(0.001);
351 b_hist->SetMaximum(3*b_hist->GetMaximum());
352 b_hist->SetLineWidth(3);
353 sb_hist->SetLineWidth(3);
354 b_hist->SetLineColor(kBlue);
355 sb_hist->SetLineColor( 28 );
356 line->SetLineWidth(3);
357 TLegend * leg = new TLegend(0.11,0.78,0.48,0.89);
358 leg->SetBorderSize(0);
359 leg->SetFillColor(0);
360 leg->AddEntry(line,"Observed ","l");
361 leg->AddEntry(b_hist,"Expected background-only ","l");
362 leg->AddEntry(sb_hist,"Expected signal+background ","l");
363 b_hist->Draw("h");
364 line->DrawLine(myconfidence->GetStatistic(),b_hist->GetMinimum(),
365 myconfidence->GetStatistic(),0.6*b_hist->GetMaximum());
366 leg->Draw("same");
367 sb_hist->Draw("h,same");
368 c1->Update();
369 ps->NewPage();
370
371 //Fill Test-Statistics hists
372 lnQ_obs->SetPoint( i, x, myconfidence->GetStatistic() );
373 lnQ_exp_b->SetPoint( i, x, myconfidence->GetExpectedStatistic_b() );
374 lnQ_exp_sb->SetPoint( i, x, myconfidence->GetExpectedStatistic_sb() );
375 y_lnQ_exp1[i] = myconfidence->GetExpectedStatistic_b(1);
376 y_lnQ_exp1[2*n_points-i+1] = myconfidence->GetExpectedStatistic_b(-1);
377 y_lnQ_exp2[i] = myconfidence->GetExpectedStatistic_b(2);
378 y_lnQ_exp2[2*n_points-i+1] = myconfidence->GetExpectedStatistic_b(-2);
379 x_lnQ[i] = x;
380 x_lnQ[2*n_points-i+1] = x;
381
382 //Fill CLs hists:
383 if (cls<=1. && cls_b<=1. && cls_b_p1<999. &&cls_b_n1<999. &&cls_b_p2<999. &&cls_b_n2<999. &&
384 cls_b>0.) {
385 cls_obs->SetPoint( i_cls, x, cls );
386 cls_exp->SetPoint( i_cls, x, cls_b );
387 y_cls_exp1[i_cls] = cls_b_p1;
388 y_cls_exp1[2*n_points-i_cls+1] =cls_b_n1;
389 y_cls_exp2[i_cls] = cls_b_p2;
390 y_cls_exp2[2*n_points-i_cls+1] = cls_b_n2;
391 x_cls[i_cls] = x;
392 x_cls[2*n_points-i_cls+1] = x;
393
394 ++i_cls;
395 }
396
397 delete myconfidence;
398 delete mydatasource;
399 delete signal;
400 }
401 delete data;
402 delete backgd;
403
404 std::cout << limits << std::endl;
405
406 //-2 ln Q vs mass:
407 //c1->SetLogx(1);
408 c1->SetLogy(0);
409 TGraph * lnQ_exp1 = new TGraph(2*n_points+2,x_lnQ,y_lnQ_exp1);
410 TGraph * lnQ_exp2 = new TGraph(2*n_points+2,x_lnQ,y_lnQ_exp2);
411 lnQ_exp2->SetLineColor(5);
412 lnQ_exp2->SetFillColor(5);
413 lnQ_exp1->SetLineColor(3);
414 lnQ_exp1->SetFillColor(3);
415 lnQ_obs->SetLineColor(kRed);
416 lnQ_obs->SetLineWidth(3);
417 lnQ_exp_b->SetLineColor(kBlue);
418 lnQ_exp_b->SetLineStyle(3);
419 lnQ_exp_b->SetLineWidth(3);
420 lnQ_exp_sb->SetLineColor( 28 );
421 lnQ_exp_sb->SetLineStyle(3);
422 lnQ_exp_sb->SetLineWidth(3);
423 axis_lnQ->SetMaximum( lnQ_exp2->GetYaxis()->GetXmax() );
424 axis_lnQ->SetMinimum( lnQ_exp_sb->GetYaxis()->GetXmin() );
425 line->SetLineWidth(1);
426 TLegend * lgd = new TLegend(0.5,0.28,0.89,0.4);
427 lgd->SetBorderSize(0);
428 lgd->SetFillColor(0);
429 if (isPseudoData) lgd->AddEntry(lnQ_obs,"Observed (pseudo data)","l");
430 else lgd->AddEntry(lnQ_obs,"Observed","l");
431 lgd->AddEntry(lnQ_exp_b,"Expected background-only","l");
432 lgd->AddEntry(lnQ_exp_sb,"Expected signal+background","l");
433 axis_lnQ->Draw("");
434 lnQ_exp2->Draw("lf,same");
435 lnQ_exp1->Draw("lf,same");
436 lnQ_obs->Draw("l,same");
437 line->DrawLine(min,0.0,max,0.0);
438 lnQ_exp_b->Draw("l,same");
439 lnQ_exp_sb->Draw("l,same");
440 lgd->Draw("same");
441 if (doeps) c1->SaveAs("pictures/lnQ_vs_param.eps");
442 c1->Update();
443 ps->NewPage();
444
445 //c1->SetLogx(1);
446 double exp_xsec_limit=min;
447 double obs_xsec_limit=min;
448 std::cout<<"Limits on "<<ScanParName_<<":"<<std::endl;
449 exp_xsec_limit = GetExpectedXsecLimit(0.05, min, max);
450 std::cout<<"Expected: "<<exp_xsec_limit<<" @ 95%CL in " << ScanParName_ << std::endl;
451 obs_xsec_limit = GetObservedXsecLimit(0.05, min, max);
452 std::cout<<"Observed: "<<obs_xsec_limit<<" @ 95%CL in " << ScanParName_ << std::endl;
453
454 //double par[] = {1.6449};//<->5%
455 //TSignificance eSignif(backgd->Integral(), 0);
456 //double exp_signif = TSolve<TSignificance>( &eSignif, &TSignificance::operator(), par, 0.1, 10.)();
457 ////double obs_signif = exp_signif/(data->Integral()-backgd->Integral());
458 //std::cout<<"Expected s: "<< exp_signif/signal->Integral() <<" * signal cross section @ 95%CL significance" << std::endl;
459 ////std::cout<<"Observed s: "<< obs_signif <<" * signal cross section @ 95%CL" << std::endl;
460
461 c1->SetLogy(1);
462 //remove empty array elements, to get a smooth TGraph:
463 --i_cls;
464 double ny_cls_exp1[i_cls*2];
465 double nx_cls[i_cls*2];
466 double ny_cls_exp2[i_cls*2];
467 for (int i=0; i<=i_cls; ++i) {
468 ny_cls_exp1[i] = y_cls_exp1[i];
469 ny_cls_exp2[i] = y_cls_exp2[i];
470 nx_cls[i] = x_cls[i];
471 ny_cls_exp1[i_cls+i] = y_cls_exp1[2*n_points-i_cls+i];
472 ny_cls_exp2[i_cls+i] = y_cls_exp2[2*n_points-i_cls+i];
473 nx_cls[i_cls+i] = x_cls[2*n_points-i_cls+i];
474 }
475
476 TGraph * cls_exp1 = new TGraph(2*i_cls,nx_cls,ny_cls_exp1);
477 TGraph * cls_exp2 = new TGraph(2*i_cls,nx_cls,ny_cls_exp2);
478 cls_exp2->SetLineColor(5);
479 cls_exp2->SetFillColor(5);
480 cls_exp1->SetLineColor(3);
481 cls_exp1->SetFillColor(3);
482 cls_obs->SetLineColor(kRed);
483 cls_exp->SetLineColor(kBlue);
484 cls_exp->SetLineStyle(3);
485 cls_exp->SetLineWidth(3);
486 cls_obs->SetLineWidth(3);
487 //axis_cls->SetMinimum( cls_exp2->GetYaxis()->GetXmin() );
488 axis_cls->SetMinimum( 0.000001 );
489 axis_cls->SetMaximum(1.1);
490 TLegend * lg = new TLegend(0.5,0.28,0.89,0.4);
491 lg->SetBorderSize(0);
492 lg->SetFillColor(0);
493 if (isPseudoData) lg->AddEntry(cls_obs,"Observed (pseudo data)","l");
494 else lg->AddEntry(cls_obs,"Observed","l");
495 lg->AddEntry(cls_exp,"Expected background-only ","l");
496 axis_cls->Draw("l");
497 cls_exp2->Draw("lf,same");
498 cls_exp1->Draw("lf,same");
499 cls_exp->Draw("l,same");
500 cls_obs->Draw("l,same");
501 lg->Draw("same");
502 line->SetLineWidth(1);
503 line->DrawLine(min,0.05,max,0.05);
504 TArrow * arrow = new TArrow();
505 arrow->SetLineWidth(1);
506 if (obs_xsec_limit>min && obs_xsec_limit<max)
507 arrow->DrawArrow(obs_xsec_limit,0.05,obs_xsec_limit,axis_cls->GetMinimum(),0.03,">");
508 arrow->SetLineStyle(7);
509 if (exp_xsec_limit>min && exp_xsec_limit<max)
510 arrow->DrawArrow(exp_xsec_limit,50.*axis_cls->GetMinimum(),
511 exp_xsec_limit, axis_cls->GetMinimum(),0.03,">");
512
513 if (doeps) c1->SaveAs("pictures/CLs_vs_param.eps");
514 c1->Update();
515 ps->Close();
516 }
517
518 void cls::DrawVsXsec(bool doeps)
519 {
520 gStyle->SetHistFillColor(0);
521 gStyle->SetPalette(1);
522 gStyle->SetCanvasColor(0);
523 gStyle->SetCanvasBorderMode(0);
524 gStyle->SetPadColor(0);
525 gStyle->SetPadBorderMode(0);
526 gStyle->SetFrameBorderMode(0);
527
528 gStyle->SetTitleFillColor(0);
529 gStyle->SetTitleBorderSize(0);
530 gStyle->SetTitleX(0.10);
531 gStyle->SetTitleY(0.98);
532 gStyle->SetTitleW(0.8);
533 gStyle->SetTitleH(0.06);
534
535 gStyle->SetErrorX(0);
536 gStyle->SetStatColor(0);
537 gStyle->SetStatBorderSize(0);
538 gStyle->SetStatX(0);
539 gStyle->SetStatY(0);
540 gStyle->SetStatW(0);
541 gStyle->SetStatH(0);
542
543 gStyle->SetTitleFont(22);
544 gStyle->SetLabelFont(22,"X");
545 gStyle->SetLabelFont(22,"Y");
546 gStyle->SetLabelFont(22,"Z");
547 gStyle->SetLabelSize(0.03,"X");
548 gStyle->SetLabelSize(0.03,"Y");
549 gStyle->SetLabelSize(0.03,"Z");
550
551 if (!backgd_ || !signal_)
552 {
553 std::cerr << "ERROR! &(background histogram)="<<backgd_
554 << ", &(signal histogram)="<<signal_<<std::endl;
555 return;
556 }
557
558 TH1D * backgd = (TH1D*)backgd_->Clone();
559 TH1D * signal = (TH1D*)signal_->Clone();
560 TH1D * data = (TH1D*)data_->Clone();
561 backgd->GetXaxis()->SetTitle( signal->GetXaxis()->GetTitle() );
562 backgd->SetTitle("");
563
564 std::cout << "DATA = " << data->Integral(0, data->GetXaxis()->GetNbins()+1) <<std::endl;
565
566 //Draw MET for background, signal & data:
567 TCanvas * c1 = new TCanvas("","",600,600);
568 TPostScript * ps = new TPostScript( outputfilename_.c_str(),111);
569 TLine * line = new TLine();
570 signal->SetLineColor(2);
571 signal->SetLineWidth(3);
572 data->SetMarkerStyle(8);
573 backgd->SetMinimum(0);
574 backgd->Draw("he");
575 signal->Draw("he,same");
576 data->Draw("pe,same");
577 c1->Update();
578 ps->NewPage();
579
580 //CLs vs x-section:
581 int n_points = 10;
582 double min = 0.01;
583 double max = 1;
584
585 //min *= signalxsec;
586 //max *= signalxsec;
587
588 TH1D * cls_obs = new TH1D("cls_obs", ";relative cross section k [k * #sigma];CLs",n_points,min,max);
589 // TH1D * cls_obs = new TH1D("cls_obs", ";signal cross section #sigma;CLs",n_points,min,max);
590 TH1D * cls_exp = new TH1D("cls_exp", ";relative cross section k [k * #sigma];CLs",n_points,min,max);
591 TH1D * lnQ_obs = new TH1D("lnQ_obs", ";relative cross section k [k * #sigma];-2 ln Q",n_points,min,max);
592 TH1D * lnQ_exp_b = new TH1D("lnQ_exp_b", ";relative cross section k [k * #sigma];-2 ln Q",n_points,min,max);
593 TH1D * lnQ_exp_sb = new TH1D("lnQ_exp_sb", ";relative cross section k [k * #sigma];-2 ln Q",n_points,min,max);
594 double y_cls_exp1[n_points*2+2];
595 double x_cls_exp[n_points*2+2];
596 double x_lnQ_exp[n_points*2+2];
597 double y_cls_exp2[n_points*2+2];
598 double y_lnQ_exp1[n_points*2+2];
599 double y_lnQ_exp2[n_points*2+2];
600
601 std::cout<<"Scanning signal coss-section from x = "<<(int)(min*100)<<"% till "<<(int)(max*100)<<"%:"<<std::endl;
602 TTable limits("Limits of cross-section scan","|");
603 //limits.AddColumn<int>("i");
604 limits.AddColumn<double>("x/sigma");
605 limits.AddColumn<double>(" #s ");
606 limits.AddColumn<double>("+-ds");
607 limits.AddColumn<double>(" #b ");
608 limits.AddColumn<double>("+-db");
609 limits.AddColumn<double>("CL_s");
610 limits.AddColumn<double>("<CL_b>_b");limits.SetPrecision(6,5);
611 limits.AddColumn<double>("<CL_sb>_b");limits.SetPrecision(7,5);
612 limits.AddColumn<double>("<lnQ_b>");
613 limits.AddColumn<double>("<lnQ_sb>");
614 limits.AddColumn<double>("<CL_s-2s>_b");limits.SetPrecision(10,5);
615 limits.AddColumn<double>("<CL_s-1s>_b");limits.SetPrecision(11,5);
616 limits.AddColumn<double>("<CL_s>_b");limits.SetPrecision(12,5);
617 limits.AddColumn<double>("<CL_s+1s>_b");limits.SetPrecision(13,5);
618 limits.AddColumn<double>("<CL_s+2s>_b");limits.SetPrecision(14,5);
619 char * title = new char[100];
620 int i_cls=0;
621
622 for (int i=0; i<=n_points; ++i){
623 if ((int)(100*(float)i/n_points)%10==0)
624 std::cout << std::setw(2)<<100*i/n_points << "% done"<<std::endl;
625
626
627 TH1D * sig = (TH1D*)signal_->Clone();
628 double x = min + (max-min)*i/n_points;
629 sig->Scale( x );
630
631 // double x = min + (double)i/n_points*(max-min);
632 // sig->Scale( x/signalxsec );
633 // x *= signalxsec;
634
635 TLimitDataSource * source = new TLimitDataSource();
636 if (!syst_) source->AddChannel(sig,backgd,data);
637 else source->AddChannel(sig,backgd,data,(TH1D*)esup_,(TH1D*)esdn_,(TH1D*)ebup_,(TH1D*)ebdn_,names_);
638 TConfidenceLevel * conf = TLimit::ComputeLimit(source,fNMC_,stat_);
639
640 //Draw plot
641 c1->SetLogy(0);
642 sig->SetLineColor(2);
643 sig->SetLineWidth(3);
644 data->SetMarkerStyle(8);
645 backgd->SetMinimum(0);
646 if (sig->GetMaximum()>backgd->GetMaximum()) backgd->SetMaximum(sig->GetMaximum()*sqrt(sig->GetMaximum()));
647 backgd->Draw("he");
648 sig->Draw("he,same");
649 data->Draw("pe,same");
650 if (doeps) {
651 sprintf(title,"pictures/N_for_x%.3f.eps",x);
652 c1->SaveAs(title);
653 }
654 c1->Update();
655 ps->NewPage();
656
657 //Draw the expected and observed test statistics:
658 c1->SetLogy(1);
659 sprintf(title,"xTConfidenceLevel_Draw_%i",plotindex_++);
660 TH1D h(title,"",50,0,0);
661 double * fTSB = conf->GetTestStatistic_B();
662 double * fTSS = conf->GetTestStatistic_SB();
663 for (int j=0; j<fNMC_; j++) {
664 h.Fill(-2*(fTSB[j]-conf->GetStot() ));
665 h.Fill(-2*(fTSS[j]-conf->GetStot() ));
666 }
667 sprintf(title,"xb_hist_%i",plotindex_++);
668 TH1D* b_hist = new TH1D(title, ";-2 ln Q;normalized p.d.f.",50,h.GetXaxis()->GetXmin(),h.GetXaxis()->GetXmax());
669 sprintf(title,"xsb_hist_%i",plotindex_++);
670 TH1D* sb_hist = new TH1D(title,";-2 ln Q;normalized p.d.f.",50,h.GetXaxis()->GetXmin(),h.GetXaxis()->GetXmax());
671 for (int j=0; j<fNMC_; j++) {
672 b_hist->Fill(-2*(fTSB[j]-conf->GetStot() ));
673 sb_hist->Fill(-2*(fTSS[j]-conf->GetStot() ));
674 }
675 b_hist->Scale(1.0/b_hist->Integral());
676 sb_hist->Scale(1.0/sb_hist->Integral());
677 b_hist->GetYaxis()->SetTitleOffset(1.3);
678 b_hist->SetMinimum( 1./fNMC_ );
679 b_hist->SetMaximum(3*b_hist->GetMaximum());
680 b_hist->SetLineWidth(3);
681 sb_hist->SetLineWidth(3);
682 b_hist->SetLineColor(kBlue);
683 sb_hist->SetLineColor( 28 );
684 line->DrawLine(conf->GetStatistic(),b_hist->GetMinimum(),
685 conf->GetStatistic(),0.6*b_hist->GetMaximum() );
686 line->SetLineWidth(3);
687 TLegend leg(0.11,0.78,0.48,0.89);
688 leg.SetBorderSize(0);
689 leg.SetFillColor(0);
690 leg.AddEntry(line,"Observed ","l");
691 leg.AddEntry(b_hist,"Expected background-only ","l");
692 leg.AddEntry(sb_hist,"Expected signal+background ","l");
693 sprintf(title,"#sigma_{s} #times %f",x);
694
695 b_hist->Draw("h");
696 line->Draw();
697 leg.Draw("same");
698 sb_hist->Draw("h,same");
699 if (doeps) {
700 sprintf(title,"pictures/lnQ_for_x%.3f.eps",x);
701 c1->SaveAs(title);
702 }
703 c1->Update();
704 ps->NewPage();
705
706 //Plot # of signal and backgd events of pseudo experiments:
707 c1->SetLogy(0);
708 double * psig = conf->GetSig();
709 double * pbgd = conf->GetBgd();
710 double ds=0, db=0;
711 for (int a=0; a<sig->GetNbinsX()+1; ++a) ds+=sig->GetBinError(a);
712 for (int a=0; a<backgd->GetNbinsX()+1; ++a) db+=backgd->GetBinError(a);
713
714 double pmin=999999, pmax=-999999;
715 for (int it=0; it<fNMC_; ++it){
716 if (psig[it]<pmin) pmin = psig[it];
717 if (psig[it]>pmax && psig[it]<99999.) pmax = psig[it];
718 }
719 for (int it=0; it<fNMC_; ++it){
720 if (pbgd[it]<pmin) pmin = pbgd[it];
721 if (pbgd[it]>pmax && pbgd[it]<99999.) pmax = pbgd[it];
722 }
723 sprintf(title,"pseudosig_%i",plotindex_++);
724 TH1F * pseudosig = new TH1F(title,";# events;# pseudo experiments",100,pmin-5,pmax+5);
725 sprintf(title,"pseudobgd_%i",plotindex_++);
726 TH1F * pseudobgd = new TH1F(title,";# events;# pseudo experiments",100,pmin-5,pmax+5);
727 for (int it=0; it<fNMC_; ++it){
728 pseudosig->Fill(psig[it]);
729 }
730 for (int it=0; it<fNMC_; ++it){
731 pseudobgd->Fill(pbgd[it]);
732 }
733 pseudosig->SetLineColor(2);
734 pseudosig->SetLineWidth(3);
735 pseudobgd->SetLineWidth(3);
736 pseudosig->Draw("h");
737 pseudobgd->Draw("h,same");
738 TLegend pleg(0.31,0.8,0.68,0.89);
739 pleg.SetBorderSize(0);
740 pleg.SetFillColor(0);
741 sprintf(title,"Signal %.2f#pm%.2f",sig->Integral(),ds);
742 pleg.AddEntry(pseudosig,title,"l");
743 sprintf(title,"Background %.2f#pm%.2f",backgd->Integral(),db);
744 pleg.AddEntry(pseudobgd,title,"l");
745 pleg.Draw("same");
746 if (doeps) {
747 sprintf(title,"pictures/pseudoN_for_x%.3f.eps",x);
748 c1->SaveAs(title);
749 }
750 c1->Update();
751 ps->NewPage();
752 delete pseudosig;
753 delete pseudobgd;
754
755 //Calculate CLs and lnQ:
756 double cls = conf->CLs();
757 double cls_b = conf->GetExpectedCLs_b();
758 double cls_b_p1 = conf->GetExpectedCLs_b(1);
759 double cls_b_n1 = conf->GetExpectedCLs_b(-1);
760 double cls_b_p2 = conf->GetExpectedCLs_b(2);
761 double cls_b_n2 = conf->GetExpectedCLs_b(-2);
762 Sort(cls_b_n1, cls_b_p1);
763 Sort(cls_b_n2, cls_b_p2);
764 if (cls_b>0 && cls_b<=1.) {
765 cls_obs->SetBinContent(i_cls, cls );
766 cls_exp->SetBinContent(i_cls, cls_b );
767 y_cls_exp1[i_cls] = cls_b_p1;
768 y_cls_exp1[n_points*2-i_cls+1] = cls_b_n1;
769 y_cls_exp2[i_cls] = cls_b_p2;
770 y_cls_exp2[n_points*2-i_cls+1] = cls_b_n2;
771 x_cls_exp[i_cls] = x;
772 x_cls_exp[n_points*2-i_cls+1] = x;
773 ++i_cls;
774 }
775
776 lnQ_obs->SetBinContent( i, conf->GetStatistic() );
777 lnQ_exp_b->SetBinContent( i, conf->GetExpectedStatistic_b() );
778 lnQ_exp_sb->SetBinContent( i, conf->GetExpectedStatistic_sb() );
779 y_lnQ_exp1[i] = conf->GetExpectedStatistic_b(1);
780 y_lnQ_exp1[n_points*2-i+1] = conf->GetExpectedStatistic_b(-1);
781 y_lnQ_exp2[i] = conf->GetExpectedStatistic_b(2);
782 y_lnQ_exp2[n_points*2-i+1] = conf->GetExpectedStatistic_b(-2);
783 x_lnQ_exp[i] = x;
784 x_lnQ_exp[n_points*2-i+1] = x;
785
786 limits.Fill(x,
787 sig->Integral(),ds,
788 backgd->Integral(),db,
789 cls,
790 conf->GetExpectedCLb_b(),conf->GetExpectedCLsb_b(),
791 conf->GetExpectedStatistic_b(),conf->GetExpectedStatistic_sb(),
792 cls_b_n2,cls_b_n1,
793 cls_b,
794 cls_b_p1,cls_b_p2
795 );
796 delete conf;
797 delete source;
798 delete sig;
799 }
800 std::cout << limits << std::endl;
801
802 //-2 ln Q vs mass:
803 //c1->SetLogx(1);
804 c1->SetLogy(0);
805 TGraph * lnQ_exp1 = new TGraph(2*n_points,x_lnQ_exp,y_lnQ_exp1);
806 TGraph * lnQ_exp2 = new TGraph(2*n_points,x_lnQ_exp,y_lnQ_exp2);
807 lnQ_exp2->SetLineColor(5);
808 lnQ_exp2->SetFillColor(5);
809 lnQ_exp1->SetLineColor(3);
810 lnQ_exp1->SetFillColor(3);
811 lnQ_obs->SetLineColor(kRed);
812 lnQ_obs->SetLineWidth(3);
813 lnQ_exp_b->SetLineColor(kBlue);
814 lnQ_exp_b->SetLineStyle(3);
815 lnQ_exp_b->SetLineWidth(3);
816 lnQ_exp_sb->SetLineColor( 28 );
817 lnQ_exp_sb->SetLineStyle(3);
818 lnQ_exp_sb->SetLineWidth(3);
819 lnQ_obs->SetMinimum(-20);
820 line->SetLineWidth(1);
821 TLegend * lgd = new TLegend(0.5,0.28,0.89,0.4);
822 lgd->SetBorderSize(0);
823 lgd->SetFillColor(0);
824 if (isPseudoData) lgd->AddEntry(lnQ_obs,"Observed (pseudo data)","l");
825 else lgd->AddEntry(lnQ_obs,"Observed","l");
826 lgd->AddEntry(lnQ_exp_b,"Expected background-only","l");
827 lgd->AddEntry(lnQ_exp_sb,"Expected signal+background","l");
828 lnQ_obs->Draw("c");
829 lnQ_exp2->Draw("lf,same");
830 lnQ_exp1->Draw("lf,same");
831 lnQ_obs->Draw("c,same");
832 line->DrawLine(100,0.0,500,0.0);
833 lnQ_exp_b->Draw("c,same");
834 lnQ_exp_sb->Draw("c,same");
835 lgd->Draw("same");
836 //if (doeps)
837 c1->SaveAs("pictures/lnQvsxsec.eps");
838 c1->Update();
839 ps->NewPage();
840
841 //c1->SetLogx(1);
842 double exp_xsec_limit = 0;
843 double obs_xsec_limit = 0;
844 std::cout<<"Cross-section limit:"<<std::endl;
845 //exp_xsec_limit = GetExpectedXsecLimit(0.05, min, max);
846 //obs_xsec_limit = GetObservedXsecLimit(0.05, min, max);
847 std::cout<<"Expected: "<<exp_xsec_limit<<" * signal cross section @ 95%CL" << std::endl;
848 std::cout<<"Observed: "<<obs_xsec_limit<<" * signal cross section @ 95%CL" << std::endl;
849
850 //double par[] = {1.6449};//<->5%
851 //TSignificance eSignif(backgd->Integral(), 0);
852 //double exp_signif = TSolve<TSignificance>( &eSignif, &TSignificance::operator(), par, 0.1, 10.)();
853 ////double obs_signif = exp_signif/(data->Integral()-backgd->Integral());
854 //std::cout<<"Expected s: "<< exp_signif/signal->Integral() <<" * signal cross section @ 95%CL significance" << std::endl;
855 ////std::cout<<"Observed s: "<< obs_signif <<" * signal cross section @ 95%CL" << std::endl;
856 //remove empty array elements, to get a smooth TGraph:
857
858 --i_cls;
859 double ny_cls_exp1[i_cls*2];
860 double nx_cls[i_cls*2];
861 double ny_cls_exp2[i_cls*2];
862 for (int i=0; i<=i_cls; ++i) {
863 ny_cls_exp1[i] = y_cls_exp1[i];
864 ny_cls_exp2[i] = y_cls_exp2[i];
865 nx_cls[i] = x_cls_exp[i];
866 ny_cls_exp1[i_cls+i] = y_cls_exp1[2*n_points-i_cls+i];
867 ny_cls_exp2[i_cls+i] = y_cls_exp2[2*n_points-i_cls+i];
868 nx_cls[i_cls+i] = x_cls_exp[2*n_points-i_cls+i];
869 }
870
871 c1->SetLogy(1);
872 TGraph * cls_exp1 = new TGraph(2*i_cls,nx_cls,ny_cls_exp1);
873 TGraph * cls_exp2 = new TGraph(2*i_cls,nx_cls,ny_cls_exp2);
874 cls_exp2->SetLineColor(5);
875 cls_exp2->SetFillColor(5);
876 cls_exp1->SetLineColor(3);
877 cls_exp1->SetFillColor(3);
878 cls_obs->SetLineColor(kRed);
879 cls_exp->SetLineColor(kBlue);
880 cls_exp->SetLineStyle(3);
881 cls_exp->SetLineWidth(3);
882 cls_obs->SetLineWidth(3);
883 //cls_obs->SetMinimum(0.00001);
884 cls_exp->SetMaximum(1.1);
885 TLegend * lg = new TLegend(0.5,0.28,0.89,0.4);
886 lg->SetBorderSize(0);
887 lg->SetFillColor(0);
888 if (isPseudoData) lg->AddEntry(cls_obs,"Observed (pseudo data)","l");
889 else lg->AddEntry(cls_obs,"Observed","l");
890 lg->AddEntry(cls_exp,"Expected background-only ","l");
891 cls_exp->Draw("c");
892 cls_exp2->Draw("lf,same");
893 cls_exp1->Draw("lf,same");
894 cls_obs->Draw("c,same");
895 cls_exp->Draw("c,same");
896 lg->Draw("same");
897 line->SetLineWidth(1);
898 line->DrawLine(min,0.05,max,0.05);
899 TArrow * arrow = new TArrow();
900 arrow->SetLineWidth(1);
901 if (obs_xsec_limit) arrow->DrawArrow(obs_xsec_limit,0.05,obs_xsec_limit,cls_obs->GetYaxis()->GetXmin(),0.03,">");
902 arrow->SetLineStyle(7);
903 if (exp_xsec_limit) arrow->DrawArrow(exp_xsec_limit,50.*cls_obs->GetMinimum(),
904 exp_xsec_limit, cls_obs->GetYaxis()->GetXmin(),0.03,">");
905
906 //if (doeps)
907 c1->SaveAs("pictures/CLsvsxsec.eps");
908 c1->Update();
909 delete data;
910 delete backgd;
911 delete signal;
912
913 ps->Close();
914
915 }
916
917 double cls::GetTotalStatError(const TH1* arg)
918 {
919 if (!arg) return 0;
920 TH1F * h = (TH1F*)arg->Clone();
921 h->Rebin( h->GetXaxis()->GetNbins() );
922 double result = sqrt(pow(h->GetBinError(0),2)+pow(h->GetBinError(1),2)+pow(h->GetBinError(2),2));
923 delete h;
924 return result;
925 }
926
927 void cls::WriteResult(ConfigFile * config)
928 {
929 double min=0.01; //min. limit on xsection in which CLs = 95% is searched for
930 double max=1000; //max. limit on xsection in which CLs = 95% is searched for
931 double xsec = config->read<double>("Xsection",1.0);
932
933 TH1D * backgd = (TH1D*)backgd_->Clone();
934 TH1D * signal = (TH1D*)signal_->Clone();
935 TH1D * data = (TH1D*)data_->Clone();
936 double nsignal = signal->Integral(0,signal->GetXaxis()->GetNbins()+1);
937
938 //std::cout << "...calculating ExpectedXsecLimit" <<std::endl;
939 double exp_xsec_limit = GetExpectedXsecLimit(0.05, min, max);
940 //std::cout << "...calculating ObservedXsecLimit" <<std::endl;
941 double obs_xsec_limit = GetObservedXsecLimit(0.05, min, max);
942
943 config->add("ExpXsecLimit", exp_xsec_limit * xsec);
944 config->add("ObsXsecLimit", obs_xsec_limit * xsec);
945 config->add("ExpNsigLimit", exp_xsec_limit * nsignal);
946 config->add("ObsNsigLimit", obs_xsec_limit * nsignal);
947 config->add("CLsUseStat", stat_);
948
949 if (obs_xsec_limit>=min && obs_xsec_limit<=max) {
950 TH1D * sig = (TH1D*)signal_->Clone();
951 sig->Scale( obs_xsec_limit );
952 TLimitDataSource * source = new TLimitDataSource();
953 if (!syst_) source->AddChannel(sig,backgd,data);
954 else source->AddChannel(sig,backgd,data,(TH1D*)esup_,(TH1D*)esdn_,(TH1D*)ebup_,(TH1D*)ebdn_,names_);
955 TConfidenceLevel * conf = TLimit::ComputeLimit(source,fNMC_,stat_);
956 config->add("CLs@obs", conf->CLs());
957 config->add("CLs_b@obs", conf->GetExpectedCLs_b());
958 config->add("CLs_b_p1@obs", conf->GetExpectedCLs_b(1));
959 config->add("CLs_b_n1@obs", conf->GetExpectedCLs_b(-1));
960 config->add("CLs_b_p2@obs", conf->GetExpectedCLs_b(2));
961 config->add("CLs_b_n2@obs", conf->GetExpectedCLs_b(-2));
962 config->add("CLb_b@obs", conf->GetExpectedCLb_b());
963 config->add("CLsb_b@obs", conf->GetExpectedCLsb_b());
964 config->add("-2lnQ_b@obs", conf->GetExpectedStatistic_b());
965 config->add("-2lnQ_sb@obs", conf->GetExpectedStatistic_sb());
966 delete sig;
967 delete conf;
968 delete source;
969 }
970 if (exp_xsec_limit>=min && exp_xsec_limit<=max) {
971 TH1D * sig = (TH1D*)signal_->Clone();
972 sig->Scale( exp_xsec_limit );
973 TLimitDataSource * source = new TLimitDataSource();
974 if (!syst_) source->AddChannel(sig,backgd,data);
975 else source->AddChannel(sig,backgd,data,(TH1D*)esup_,(TH1D*)esdn_,(TH1D*)ebup_,(TH1D*)ebdn_,names_);
976 TConfidenceLevel * conf = TLimit::ComputeLimit(source,fNMC_,stat_);
977 config->add("CLs@exp", conf->CLs());
978 config->add("CLs_b@exp", conf->GetExpectedCLs_b());
979 config->add("CLs_b_p1@exp", conf->GetExpectedCLs_b(1));
980 config->add("CLs_b_n1@exp", conf->GetExpectedCLs_b(-1));
981 config->add("CLs_b_p2@exp", conf->GetExpectedCLs_b(2));
982 config->add("CLs_b_n2@exp", conf->GetExpectedCLs_b(-2));
983 config->add("CLb_b@exp", conf->GetExpectedCLb_b());
984 config->add("CLsb_b@exp", conf->GetExpectedCLsb_b());
985 config->add("-2lnQ_b@exp", conf->GetExpectedStatistic_b());
986 config->add("-2lnQ_sb@exp", conf->GetExpectedStatistic_sb());
987 delete sig;
988 delete conf;
989 delete source;
990 }
991 delete backgd;
992 delete signal;
993 delete data;
994 }
995
996 void cls::WriteResult(const std::string out)
997 {
998 if (out=="") {
999 std::cerr<<"ERROR [cls::WriteResult(const std::string out="<<out<<")]: No filename and no signal parameters specified!" <<std::endl;
1000 return;
1001 }
1002 if (!backgd_ || !signal_) {
1003 std::cerr<<"ERROR [cls::WriteResult(const std::string out="<<out<<")]: No signal ("
1004 <<signal_<<") or no background ("<<backgd_<<") hypothesis specified!" <<std::endl;
1005 return;
1006 }
1007 std::stringstream ss;
1008 ss << out;
1009 ConfigFile * res = new ConfigFile();
1010 WriteResult( res );
1011
1012 //write stuff:
1013 time_t rawtime;
1014 struct tm * timeinfo;
1015 time ( &rawtime );
1016 timeinfo = localtime ( &rawtime );
1017 ofstream ofile;
1018 ofile.open (ss.str().c_str());
1019 ofile << res->getComment() << asctime (timeinfo)
1020 << res->getComment()<< "\n"
1021 << *res;
1022 ofile.close();
1023 delete res;
1024 }