1 |
buchmann |
1.1 |
#include <iostream>
|
2 |
|
|
#include <string>
|
3 |
|
|
#include <sstream>
|
4 |
|
|
#include <TRandom.h>
|
5 |
|
|
#include <TH1.h>
|
6 |
|
|
#include <TCanvas.h>
|
7 |
|
|
#include <TF1.h>
|
8 |
|
|
#include <TMath.h>
|
9 |
|
|
#include <TText.h>
|
10 |
|
|
#include <TLine.h>
|
11 |
|
|
#include <TColor.h>
|
12 |
|
|
#ifndef VERBOSITY
|
13 |
|
|
#define VERBOSITY 0
|
14 |
|
|
#endif
|
15 |
|
|
#ifndef GeneralToolBoxLoaded
|
16 |
|
|
#include "GeneralToolBox.C"
|
17 |
|
|
#endif
|
18 |
|
|
|
19 |
|
|
#define PoissonCalculatorLoaded
|
20 |
|
|
|
21 |
|
|
using namespace std;
|
22 |
|
|
|
23 |
|
|
TH1F *compute_area(TH1F *histo, float low, float hi) {
|
24 |
|
|
TH1F *markedhisto = (TH1F*)histo->Clone();
|
25 |
|
|
markedhisto->SetName("marked");
|
26 |
|
|
markedhisto->SetFillColor(TColor::GetColor("#87CeFA"));
|
27 |
|
|
markedhisto->SetLineWidth(0);
|
28 |
|
|
for(int i=1;i<=histo->GetNbinsX();i++) {
|
29 |
|
|
if(histo->GetBinCenter(i)<low||histo->GetBinCenter(i)>hi) markedhisto->SetBinContent(i,0);
|
30 |
|
|
}
|
31 |
|
|
return markedhisto;
|
32 |
|
|
}
|
33 |
|
|
|
34 |
|
|
Double_t PoissonDistribution(Double_t *par,Double_t *x) {
|
35 |
|
|
// Double_t result = (1.0)/TMath::Gamma(1.2);
|
36 |
|
|
Double_t result = (TMath::Power(par[0],x[0])*TMath::Exp(-par[0]))/(TMath::Gamma(x[0]+1));
|
37 |
|
|
//function << "(TMath::Power(" << lambda << ",x)*TMath::Exp(-" << lambda << "))/(TMath::Gamma(x+1))";
|
38 |
|
|
return result;
|
39 |
|
|
}
|
40 |
|
|
|
41 |
|
|
void find68(TH1F* histo, long N, int rounds,float &maximum,float &errordown,float &errorup)
|
42 |
|
|
{
|
43 |
|
|
//float max = histo->GetBinCenter(histo->GetMaximumBin());
|
44 |
|
|
float max=maximum;
|
45 |
|
|
int startbin=histo->GetMaximumBin();
|
46 |
|
|
int left=startbin;
|
47 |
|
|
int right=startbin;
|
48 |
|
|
float want=(float)N * 0.68*rounds;
|
49 |
|
|
float have=histo->GetBinContent(startbin);
|
50 |
|
|
if(VERBOSITY>0) dout << "found maximum at " << max << " ( this is bin " << startbin << ")" << endl;
|
51 |
|
|
while(have<want)
|
52 |
|
|
{
|
53 |
|
|
if(histo->GetBinContent(left-1)>histo->GetBinContent(right+1))
|
54 |
|
|
{
|
55 |
|
|
have+=histo->GetBinContent(left-1);
|
56 |
|
|
left--;
|
57 |
|
|
}
|
58 |
|
|
else
|
59 |
|
|
{
|
60 |
|
|
have+=histo->GetBinContent(right+1);
|
61 |
|
|
right++;
|
62 |
|
|
}
|
63 |
|
|
}
|
64 |
|
|
float loweredge=histo->GetBinCenter(left);
|
65 |
|
|
float upperedge=histo->GetBinCenter(right);
|
66 |
|
|
if(VERBOSITY>0) dout << "we now have " << have << " and we wanted at least " << want << endl;
|
67 |
|
|
if(VERBOSITY>0) dout << "the range is " << loweredge << " to " << upperedge<< " corresponding to :" << endl;
|
68 |
|
|
if(VERBOSITY>0) dout << "\033[1;34m " << max << "+ " << (upperedge-max) << " - " << (max-loweredge) << " \033[0m" << endl;
|
69 |
|
|
errorup=(upperedge-max);
|
70 |
|
|
errordown=(max-loweredge);
|
71 |
|
|
maximum=max;
|
72 |
|
|
}
|
73 |
|
|
|
74 |
|
|
void combine_advanced_dists(TH1F *combdist,float *x1,float *x2,float *x3, float *x4, float *x5, float *x6, float *x7, long N)
|
75 |
|
|
{
|
76 |
|
|
float temp=-99;
|
77 |
|
|
for (int i=0;i<N;i++)
|
78 |
|
|
{
|
79 |
|
|
flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
|
80 |
|
|
if(PlottingSetup::RestrictToMassPeak) temp = x1[i]+(1.0/3)*(x2[i]-x3[i])+(1.0/3)*(x4[i]-x5[i])+(1.0/3)*(x6[i]-x7[i]);
|
81 |
|
|
else temp = x1[i]+(x2[i]-x3[i]);
|
82 |
|
|
combdist->Fill(temp);
|
83 |
|
|
}
|
84 |
|
|
}
|
85 |
|
|
|
86 |
|
|
void combine_dists(TH1F *combdist,float *x1,float *x2,float *x3, long N)
|
87 |
|
|
{
|
88 |
|
|
float temp=-99;
|
89 |
|
|
for (int i=0;i<N;i++)
|
90 |
|
|
{
|
91 |
|
|
temp = x1[i]+x2[i]-x3[i];
|
92 |
|
|
combdist->Fill(temp);
|
93 |
|
|
}
|
94 |
|
|
}
|
95 |
|
|
|
96 |
|
|
void generate(float *x1, float lambda,long N,float range)
|
97 |
|
|
{
|
98 |
|
|
stringstream function;
|
99 |
|
|
function << "(TMath::Power(" << lambda << ",x)*TMath::Exp(-" << lambda << "))/(TMath::Gamma(x+1))";
|
100 |
|
|
TF1 *f1 = new TF1("f1",function.str().c_str(),0,range);
|
101 |
|
|
for(int i=0;i<N;i++)
|
102 |
|
|
{
|
103 |
|
|
if(lambda>0) x1[i]=f1->GetRandom();
|
104 |
|
|
else x1[i]=0; //if we want to do this for lambda=0 then all we can provide is zero ...
|
105 |
|
|
}//end of for
|
106 |
|
|
}//end of generate_x1
|
107 |
|
|
|
108 |
|
|
void megagen(float a, float b, float c, float d, float e, float f, float g, int N,float range,TH1 *combineddist) {
|
109 |
|
|
stringstream function;
|
110 |
|
|
function << "(TMath::Power(" << a << ",x)*TMath::Exp(-" << a << "))/(TMath::Gamma(x+1))";
|
111 |
|
|
TF1 *f1 = new TF1("f1",function.str().c_str(),0,range);
|
112 |
|
|
|
113 |
|
|
stringstream function2;
|
114 |
|
|
function2 << "(TMath::Power(" << b << ",x)*TMath::Exp(-" << b << "))/(TMath::Gamma(x+1))";
|
115 |
|
|
TF1 *f2 = new TF1("f2",function2.str().c_str(),0,range);
|
116 |
|
|
|
117 |
|
|
stringstream function3;
|
118 |
|
|
function3 << "(TMath::Power(" << c << ",x)*TMath::Exp(-" << c << "))/(TMath::Gamma(x+1))";
|
119 |
|
|
TF1 *f3 = new TF1("f3",function3.str().c_str(),0,range);
|
120 |
|
|
|
121 |
|
|
stringstream function4;
|
122 |
|
|
function4 << "(TMath::Power(" << d << ",x)*TMath::Exp(-" << d << "))/(TMath::Gamma(x+1))";
|
123 |
|
|
TF1 *f4 = new TF1("f4",function4.str().c_str(),0,range);
|
124 |
|
|
|
125 |
|
|
stringstream function5;
|
126 |
|
|
function5 << "(TMath::Power(" << e << ",x)*TMath::Exp(-" << e << "))/(TMath::Gamma(x+1))";
|
127 |
|
|
TF1 *f5 = new TF1("f5",function5.str().c_str(),0,range);
|
128 |
|
|
|
129 |
|
|
stringstream function6;
|
130 |
|
|
function6 << "(TMath::Power(" << f << ",x)*TMath::Exp(-" << f << "))/(TMath::Gamma(x+1))";
|
131 |
|
|
TF1 *f6 = new TF1("f6",function6.str().c_str(),0,range);
|
132 |
|
|
|
133 |
|
|
stringstream function7;
|
134 |
|
|
function7 << "(TMath::Power(" << g << ",x)*TMath::Exp(-" << g << "))/(TMath::Gamma(x+1))";
|
135 |
|
|
TF1 *f7 = new TF1("f7",function7.str().c_str(),0,range);
|
136 |
|
|
|
137 |
|
|
float fillval;
|
138 |
|
|
for(int i=0;i<N;i++) {
|
139 |
|
|
flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
|
140 |
|
|
if(PlottingSetup::RestrictToMassPeak) fillval=f1->GetRandom()+(1.0/3)*(f2->GetRandom()-f3->GetRandom())+(1.0/3)*(f4->GetRandom()-f5->GetRandom())+(1.0/3)*(f6->GetRandom()-f7->GetRandom());
|
141 |
|
|
else fillval=f1->GetRandom()+(f2->GetRandom()-f3->GetRandom());
|
142 |
|
|
combineddist->Fill(fillval);
|
143 |
|
|
}
|
144 |
|
|
}
|
145 |
|
|
|
146 |
|
|
|
147 |
|
|
|
148 |
|
|
int poisson_canvas_counter=-1;
|
149 |
|
|
|
150 |
|
|
void ComputePoissonError(float one, float two, float three,float &maximum, float &errordown, float &errorup, string title="no title has been passed") {
|
151 |
|
|
maximum=one+two-three;
|
152 |
|
|
if(one+two+three>0.01) {
|
153 |
|
|
long N=500000;
|
154 |
|
|
float range=(one+two-three)*2;
|
155 |
|
|
if(range<3) range=3;
|
156 |
|
|
float x1[N];
|
157 |
|
|
float x2[N];
|
158 |
|
|
float x3[N];
|
159 |
|
|
|
160 |
|
|
TCanvas *c1 = new TCanvas("c1","c1");
|
161 |
|
|
TH1F *combineddist = new TH1F("combineddist","",500,0,range);
|
162 |
|
|
generate(x1,one,N,range);
|
163 |
|
|
generate(x2,two,N,range);
|
164 |
|
|
generate(x3,three,N,range);
|
165 |
|
|
combine_dists(combineddist,x1,x2,x3,N);
|
166 |
|
|
find68(combineddist,N,1,maximum,errordown,errorup);
|
167 |
|
|
|
168 |
|
|
//from here on we only do "cosmetics" :-)
|
169 |
|
|
combineddist->Draw();
|
170 |
|
|
combineddist->GetYaxis()->SetRangeUser(0,1.1*combineddist->GetMaximum());
|
171 |
|
|
TLine *central = new TLine(maximum,0,maximum,combineddist->GetMaximum());
|
172 |
|
|
central->SetLineColor(kBlue);
|
173 |
|
|
TH1F *drawarea = compute_area(combineddist,maximum-errordown,maximum+errorup);
|
174 |
|
|
//blublu : need to implement the compute_area function which gives the integration area in a nice color :-)
|
175 |
|
|
drawarea->Draw("same");
|
176 |
|
|
combineddist->Draw("same");
|
177 |
|
|
central->Draw();
|
178 |
|
|
TText *ttitle = write_title(title);
|
179 |
|
|
ttitle->Draw();
|
180 |
|
|
stringstream result1;
|
181 |
|
|
result1 << "Pred: "<<one<<" + " << two << " - " << three << " = " << one+two-three;
|
182 |
|
|
TText *res1=write_text(0.10,0.05,result1.str().c_str());
|
183 |
|
|
res1->SetTextSize(0.03);
|
184 |
|
|
res1->SetTextAlign(11);
|
185 |
|
|
stringstream result2;
|
186 |
|
|
result2 << "Error band: [" << maximum-errordown << " , " << maximum+errorup << "]";
|
187 |
|
|
TText *res2=write_text(0.10,0.01,result2.str().c_str());
|
188 |
|
|
res2->SetTextSize(0.03);
|
189 |
|
|
res2->SetTextAlign(11);
|
190 |
|
|
res1->Draw();
|
191 |
|
|
res2->Draw();
|
192 |
|
|
stringstream result3;
|
193 |
|
|
result3 << "Result: " << maximum << " + " << errorup << " - " << errordown;
|
194 |
|
|
TText *res3=write_text(0.95,0.03,result3.str().c_str());
|
195 |
|
|
res3->SetTextColor(kBlue);
|
196 |
|
|
res3->SetTextSize(0.03);
|
197 |
|
|
res3->SetTextAlign(31);
|
198 |
|
|
res3->Draw();
|
199 |
|
|
poisson_canvas_counter++;
|
200 |
|
|
stringstream savename;
|
201 |
|
|
savename << "Poisson/PoissonStatisticsCanvas_" << poisson_canvas_counter;
|
202 |
|
|
CompleteSave(c1,savename.str());
|
203 |
|
|
|
204 |
|
|
delete combineddist;
|
205 |
|
|
|
206 |
|
|
}
|
207 |
|
|
else {
|
208 |
|
|
if(VERBOSITY>0) dout << "Entries are too small. Not much to be done." << endl;
|
209 |
|
|
maximum=one+two-three;errordown=0;errorup=0;
|
210 |
|
|
}
|
211 |
|
|
}
|
212 |
|
|
|
213 |
|
|
|
214 |
|
|
void advanced_poisson(float a, float b, float c, float d, float e, float f, float g,float &errordown,float &errorup)
|
215 |
|
|
{
|
216 |
|
|
float maximum=a;
|
217 |
|
|
flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
|
218 |
|
|
if(PlottingSetup::RestrictToMassPeak) maximum+=(1.0/3)*(b-c)+(1.0/3)*(d-e)+(1.0/3)*(f-g);
|
219 |
|
|
else maximum+=(b-c);
|
220 |
|
|
float parametersum=a+b+c;
|
221 |
|
|
if(PlottingSetup::RestrictToMassPeak) parametersum+=d+e+f+g;
|
222 |
|
|
flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
|
223 |
|
|
if(parametersum>0.01) {
|
224 |
|
|
long N=500000;
|
225 |
|
|
float range=a;
|
226 |
|
|
flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
|
227 |
|
|
if(PlottingSetup::RestrictToMassPeak) range+=(1.0/3)*(b-c)+(1.0/3)*(d-e)+(1.0/3)*(f-g);
|
228 |
|
|
else range+=(b-c);
|
229 |
|
|
range*=2;
|
230 |
|
|
if(range<3) range=3;
|
231 |
|
|
|
232 |
|
|
TCanvas *c1 = new TCanvas("c1","c1");
|
233 |
|
|
TH1F *combineddist = new TH1F("combineddist","",500,0,range);
|
234 |
|
|
megagen(a,b,c,d,e,f,g,N,range,combineddist);
|
235 |
|
|
find68(combineddist,N,1,maximum,errordown,errorup);
|
236 |
|
|
|
237 |
|
|
//from here on we only do "cosmetics" :-)
|
238 |
|
|
combineddist->Draw();
|
239 |
|
|
combineddist->GetYaxis()->SetRangeUser(0,1.1*combineddist->GetMaximum());
|
240 |
|
|
TLine *central = new TLine(maximum,0,maximum,combineddist->GetMaximum());
|
241 |
|
|
central->SetLineColor(kBlue);
|
242 |
|
|
TH1F *drawarea = compute_area(combineddist,maximum-errordown,maximum+errorup);
|
243 |
|
|
//blublu : need to implement the compute_area function which gives the integration area in a nice color :-)
|
244 |
|
|
drawarea->Draw("same");
|
245 |
|
|
combineddist->Draw("same");
|
246 |
|
|
central->Draw();
|
247 |
|
|
stringstream result1;
|
248 |
|
|
flag_this_change(__FUNCTION__,__LINE__,false);//PlottingSetup::RestrictToMassPeak
|
249 |
|
|
if(PlottingSetup::RestrictToMassPeak) result1 << "Pred: "<<a<<" + (1/3)*(" << b<<"-"<<c<<")+ (1/3)*(" << d<<"-"<<e<<")+ (1/3)*(" << f<<"-"<<g<<") = " << maximum;
|
250 |
|
|
else result1 << "Pred: "<<a<<" + (" << b<<"-"<<c<<") = " << maximum;
|
251 |
|
|
TText *res1=write_text(0.10,0.05,result1.str().c_str());
|
252 |
|
|
res1->SetTextSize(0.03);
|
253 |
|
|
res1->SetTextAlign(11);
|
254 |
|
|
stringstream result2;
|
255 |
|
|
result2 << "Error band: [" << maximum-errordown << " , " << maximum+errorup << "]";
|
256 |
|
|
TText *res2=write_text(0.10,0.01,result2.str().c_str());
|
257 |
|
|
res2->SetTextSize(0.03);
|
258 |
|
|
res2->SetTextAlign(11);
|
259 |
|
|
res1->Draw();
|
260 |
|
|
res2->Draw();
|
261 |
|
|
stringstream result3;
|
262 |
|
|
result3 << "Result: " << maximum << " + " << errorup << " - " << errordown;
|
263 |
|
|
TText *res3=write_text(0.95,0.03,result3.str().c_str());
|
264 |
|
|
res3->SetTextColor(kBlue);
|
265 |
|
|
res3->SetTextSize(0.03);
|
266 |
|
|
res3->SetTextAlign(31);
|
267 |
|
|
res3->Draw();
|
268 |
|
|
poisson_canvas_counter++;
|
269 |
|
|
stringstream savename;
|
270 |
|
|
savename << "Poisson/Result_PoissonStatisticsCanvas_" << poisson_canvas_counter;
|
271 |
|
|
CompleteSave(c1,savename.str());
|
272 |
|
|
|
273 |
|
|
delete combineddist;
|
274 |
|
|
|
275 |
|
|
}
|
276 |
|
|
else {
|
277 |
|
|
if(VERBOSITY>0) dout << "Entries are too small. Not much to be done." << endl;
|
278 |
|
|
errordown=0;errorup=0;
|
279 |
|
|
}
|
280 |
|
|
}
|
281 |
|
|
|
282 |
|
|
|
283 |
|
|
/***
|
284 |
|
|
*
|
285 |
|
|
* SAMPLE USAGE BELOW !!!!
|
286 |
|
|
*
|
287 |
|
|
*
|
288 |
|
|
|
289 |
|
|
int main()
|
290 |
|
|
{
|
291 |
|
|
dout << "hello!" << endl;
|
292 |
|
|
float max,down,up;
|
293 |
|
|
ComputePoissonError(2,6,0.001,max,down,up);
|
294 |
|
|
dout << "RESULTS: " << max << " + " << up << " - " << down << endl;
|
295 |
|
|
return 0;
|
296 |
|
|
}
|
297 |
|
|
*/
|