5 #include "TPaveStats.h"
14 gStyle->SetOptFit(112);
18 cout <<
"\nFits a distribution consisting of signal peak and background; prints out the integral of the signal in the fit region\n\n";
19 cout <<
"USAGE:\nfitsb(TH1* h, <TString type>, <TString parms>, <double N>, <double min>, <double max>)\n";
20 cout <<
" h : histogram pointer\n";
21 cout <<
" <type> : default = \"gaus2\"; definition of fit function (gaus,bw,vgt,dgaus,bigaus,novo) and degree of bkg polyn (max=5, no number->no bkg, 8=argus fcn). E.g.: \"bw3\" = breit wigner + pol3\n";
22 cout <<
" gaus = Gaussian; bw = Breit-Wigner; vgt = Voigt-Fcn; dgaus = Double Gaussian (common mean); bigaus = Bifurcated Gaussian; novo = Novosibirsk Fcn\n";
23 cout <<
" <parms> : defauls extracted from histogram; string with initial fit parameters w/o amplitude param. E.g.: \"3.5,0.2,1,1,1\" -> mean=3.5, sigma=0.2, a0=1, a1=1, a2=1\n";
24 cout <<
" a leading 'f' fixes the parameter. E.g.: \"f3.5,0.2\" -> mean=3.5 (fixed), sigma=0.2\n";
25 cout <<
" <A> : amplitude parameter; default = h.Entries()/3. Negative value fixes the parameter at -A.\n";
26 cout <<
" <min> : minimum of fit range; default = h min x\n";
27 cout <<
" <max> : maximum of fit range; default = h max x\n";
33 if (type==
"") type=
"gaus2";
36 double w =
h->GetBinWidth(1);
39 if (
min==-999.)
min =
h->GetXaxis()->GetXmin();
40 if (
max==-999.)
max =
h->GetXaxis()->GetXmax();
49 if (type.BeginsWith(
"gaus")) sigmode = 0;
50 else if (type.BeginsWith(
"bw")) sigmode = 1;
51 else if (type.BeginsWith(
"vgt")) sigmode = 2;
52 else if (type.BeginsWith(
"dgaus")) sigmode = 3;
53 else if (type.BeginsWith(
"bigaus")) sigmode = 4;
54 else if (type.BeginsWith(
"novo")) sigmode = 5;
57 if (sigmode==0) tmpl =
"%f*[0]/[2]/sqrt(2.0*pi)*exp(-0.5*((x-[1])/[2])^2)";
59 else if (sigmode==1) tmpl =
"%f*[0]*[2]/(2.0*pi*((x-[1])^2+([2]/2)^2))";
60 else if (sigmode==2) tmpl =
"%f*[0]*TMath::Voigt(x-[1],[2],[3],4.)";
61 else if (sigmode==3) tmpl =
"%f*[0]*([4]/([4]+1.0)/[2]*exp(-0.5*((x-[1])/[2])^2)+1.0/([4]+1.0)/[3]*exp(-0.5*((x-[1])/[3])^2))/sqrt(2.0*pi)";
62 else if (sigmode==4) tmpl =
"%f*[0]*2./([2]+[3])/sqrt(2.0*pi)*exp(-0.5*(x-[1])^2/([2]*(x<[1])+[3]*(x>=[1]))^2)";
63 else if (sigmode==5) tmpl =
"[0]*(([3]>0)*((x-[1])*[3]/[2]<1)*exp( -0.5*(log(1-((x-[1])*[3]/[2]<1)*(x-[1])*[3]/[2]))^2/(2./2.3548*sinh(0.5*[3]*2.3548))^2 - 0.5*[2]^2)+([3]<=0)*(1./[2]/sqrt(2.0*pi)*exp(-0.5*((x-[1])/[2])^2)))";
65 if (sigmode==2 || sigmode==4 || sigmode==5) paroff = 4;
66 if (sigmode==3) paroff = 5;
70 TString degs = type(type.Length()-1,1);
72 if (nums.Contains(degs)) deg = degs.Atoi();
76 int partot = paroff+deg+1;
77 if (deg==8) partot-=5;
80 TString fnc = TString::Format(tmpl.Data(), w);
81 if (deg>=0&°<8) fnc+=TString::Format(
"+pol%d(%d)",deg, paroff);
84 fnc+=TString::Format(
"+(x<[%d])*[%d]*x*(abs(1-(x/[%d])^2))^[%d]*exp([%d]*(1-(x/[%d])^2))", paroff+1, paroff, paroff+1, paroff+2, paroff+3, paroff+1);
87 cout<<
"\nFit fcn: " <<fnc<<endl<<endl;
94 if (parms!=
"") parms=parms+
",";
97 prm[0] =
h->GetEntries()/3.;
98 prm[1] =
h->GetBinCenter(
h->GetMaximumBin());
99 prm[2] =
h->GetRMS()/2;
100 if (sigmode>1) prm[3] = prm[2]*2.;
101 if (sigmode==3) prm[4] = 1.0;
105 for (i=paroff;i<partot;++
i) prm[i] = 1.0;
109 prm[paroff] =
h->GetMaximum()/5.;
111 prm[paroff+2] = prm[paroff+3] = 0.5;
117 if (A<0) {prm[0] = -A; fixparm[0]=
true;}
122 TString sparm = parms(0,parms.Index(
","));
126 if (sparm.BeginsWith(
"f"))
129 fixparm[1+pcnt] =
true;
132 if (sparm.BeginsWith(
"r"))
135 TString sparm2 = sparm(sparm.Index(
"|")+1,1000);
136 sparm = sparm(1,sparm.Index(
"|"));
137 prmr[1+pcnt]=sparm2.Atof();
140 prm[1+pcnt++] = sparm.Atof();
141 parms = parms(parms.Index(
",")+1,1000);
147 ff1.SetLineColor(4); ff1.SetNpx(500);
150 if (sigmode==0) ff1.SetParNames(
"N",
"#mu",
"#sigma",
"a_{0}",
"a_{1}",
"a_{2}",
"a_{3}",
"a_{4}",
"a_{5}");
151 else if (sigmode==1) ff1.SetParNames(
"N",
"#mu",
"#Gamma",
"a_{0}",
"a_{1}",
"a_{2}",
"a_{3}",
"a_{4}",
"a_{5}");
152 else if (sigmode==2) ff1.SetParNames(
"N",
"#mu",
"#sigma",
"#Gamma",
"a_{0}",
"a_{1}",
"a_{2}",
"a_{3}",
"a_{4}",
"a_{5}");
153 else if (sigmode==3) ff1.SetParNames(
"N",
"#mu",
"#sigma_{1}",
"#sigma_{2}",
"R",
"a_{0}",
"a_{1}",
"a_{2}",
"a_{3}",
"a_{4}",
"a_{5}");
154 else if (sigmode==4) ff1.SetParNames(
"N",
"#mu",
"#sigma_{1}",
"#sigma_{2}",
"a_{0}",
"a_{1}",
"a_{2}",
"a_{3}",
"a_{4}",
"a_{5}");
155 else if (sigmode==5) ff1.SetParNames(
"A",
"#mu",
"#sigma",
"#tau",
"a_{0}",
"a_{1}",
"a_{2}",
"a_{3}",
"a_{4}",
"a_{5}");
159 ff1.SetParName(paroff ,
"a");
160 ff1.SetParName(paroff+1,
"m_{0}");
161 ff1.SetParName(paroff+2,
"p");
162 ff1.SetParName(paroff+3,
"c");
166 for (i=0;i<partot;++
i)
169 ff1.FixParameter(i,prm[i]);
171 ff1.SetParLimits(i,prm[i],prmr[i]);
173 ff1.SetParameter(i,prm[i]);
181 int integral = ff1.Integral(
min,
max)/w;
185 if (deg>=0 && deg<=
maxdeg)
188 TF1 *ff2=
new TF1(
"ff2",TString::Format(
"pol%d",deg));
189 ff2->SetLineColor(kRed+1); ff2->SetLineStyle(2); ff2->SetNpx(500);
193 for (i=0;i<deg+1;++
i) ff2->SetParameter(i,ff1.GetParameter(paroff+i));
196 h->GetListOfFunctions()->Add(ff2);
199 bkg = ff2->Integral(
min,
max)/w;
202 if (bkg>0) integral -= bkg;
209 TF1 *ff2=
new TF1(
"ff2",
"(x<[1])*[0]*x*(abs(1-(x/[1])^2))^[2]*exp([3]*(1-(x/[1])^2))");
210 ff2->SetLineColor(kRed+1); ff2->SetLineStyle(2); ff2->SetNpx(500);
214 for (i=0;i<4;++
i) ff2->SetParameter(i,ff1.GetParameter(paroff+i));
217 h->GetListOfFunctions()->Add(ff2);
220 bkg = ff2->Integral(
min,
max)/w;
223 if (bkg>0) integral -= bkg;
227 TPaveStats *
s = (TPaveStats*) gPad->GetPrimitive(
"stats");
231 s->SetY1NDC(gStyle->GetStatX()-0.032*(partot+4));
232 s->SetTextSize(0.025);
237 double xmin =
h->GetXaxis()->GetXmin(),
xmax =
h->GetXaxis()->GetXmax();
238 ls.SetTextSize(0.045); ls.SetTextColor(4);
239 ls.DrawLatex(xmin+(
xmax-xmin)*0.03,
h->GetMaximum()*0.95,TString::Format(
"S_{int} = %d",integral));
242 lb.SetTextSize(0.045); lb.SetTextColor(kRed+1);
243 lb.DrawLatex(xmin+(
xmax-xmin)*0.03,
h->GetMaximum()*0.87,TString::Format(
"B_{int} = %d",bkg));
247 double StoN = (double)integral/(
double)bkg;
248 double Sign = (double)integral/
sqrt((
double)bkg+(double)integral);
251 cout <<endl<<
"Var-list: \"";
252 for (
int i=1;i<partot;++
i)
254 if (fixparm[i]) cout<<
"f";
255 cout << ff1.GetParameter(i);
256 if (i<partot-1) cout<<
",";
261 printf(
"\n\n[%.3f ... %.3f] : S = %d B = %d S/B = %.3f S/sqrt(S+B) = %.4f\n",
min,
max, integral, bkg, StoN, Sign);
printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime)
friend F32vec4 sqrt(const F32vec4 &a)
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
int fitsb(TH1 *h=0, TString type="", TString parms="", double A=0., double min=-999., double max=-999.)
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)