10 #include <AliRsnFitResult.h>
12 ClassImp(AliRsnFitResult)
14 //__________________________________________________________________________________________________
15 AliRsnFitResult::AliRsnFitResult(const char *name, ESignalType sType, EBackgroundType bType) :
18 fBackgroundType(bType)
21 // Default constructor
27 //__________________________________________________________________________________________________
28 Double_t AliRsnFitResult::NormSquareRoot(Double_t *x, Double_t *par)
31 // Computes a square-root like function normalized
32 // to the integral in the background range specified
34 // This is obtained by dividing the function value by
35 // its integral analytically computed in that range.
36 // Returns 0 in all cases where a floating point exception
37 // could be raised by computing square root of a negative number.
40 if (x[0] < par[1]) return 0.0;
42 Double_t fcnVal = TMath::Sqrt(x[0] - par[1]);
44 Double_t fcnMax = fPeakRange[1] - par[1];
45 Double_t fcnMin = fPeakRange[0] - par[1];
46 Double_t fcnInt = (2.0 / 3.0) * ((fcnMax*TMath::Sqrt(fcnMax) - fcnMin*TMath::Sqrt(fcnMin)));
48 return par[0] * fcnVal / fcnInt;
51 //__________________________________________________________________________________________________
52 Double_t AliRsnFitResult::NormLinear(Double_t *x, Double_t *par)
55 // Computes a 1st order polynomial function normalized
56 // to the integral in the background range specified
58 // This is obtained by dividing the function value by
59 // its integral analytically computed in that range.
60 // Returns 0 in all cases where a floating point exception
61 // could be raised by computing square root of a negative number.
64 Double_t fcnVal = 1.0 + x[0] * par[1];
65 Double_t fcnInt = (fPeakRange[1] - fPeakRange[0]) + 0.5*par[1]*(fPeakRange[1]*fPeakRange[1] - fPeakRange[0]*fPeakRange[0]);
67 return par[0] * fcnVal / fcnInt;
70 //__________________________________________________________________________________________________
71 Double_t AliRsnFitResult::NormPoly2(Double_t *x, Double_t *par)
74 // Computes a 2nd order polynomial function normalized
75 // to the integral in the background range specified
77 // This is obtained by dividing the function value by
78 // its integral analytically computed in that range.
79 // Returns 0 in all cases where a floating point exception
80 // could be raised by computing square root of a negative number.
83 Double_t fcnVal = 1.0 + x[0] * par[1] + x[0]*x[0] * par[2];
84 Double_t fcnInt = (fPeakRange[1] - fPeakRange[0]) + par[1]*(fPeakRange[1]*fPeakRange[1] - fPeakRange[0]*fPeakRange[0])/2.0 + par[2]*(fPeakRange[1]*fPeakRange[1]*fPeakRange[1] - fPeakRange[0]*fPeakRange[0]*fPeakRange[0])/3.0;
86 return par[0] * fcnVal / fcnInt;
89 //__________________________________________________________________________________________________
90 Double_t AliRsnFitResult::NormBreitWigner(Double_t *x, Double_t *par)
93 // Computes a Breit-Wigner function normalized
94 // to the integral in the background range specified
96 // This is obtained by dividing the function value by
97 // its integral analytically computed in that range.
98 // Returns 0 in all cases where a floating point exception
99 // could be raised by computing square root of a negative number.
102 Double_t fcnVal = 1.0 / ((x[0] - par[1])*(x[0] - par[1]) + 0.25*par[2]*par[2]);
103 Double_t fcnInt = 2.0 / par[2] * (TMath::ATan((fPeakRange[1] - par[1]) / (0.5 * par[2])) - TMath::ATan((fPeakRange[0] - par[1]) / (0.5 * par[2])));
105 return par[0] * fcnVal / fcnInt;
108 //__________________________________________________________________________________________________
109 Double_t AliRsnFitResult::NormGaus(Double_t *x, Double_t *par)
112 // Computes a Gaussian function normalized
113 // to the integral in the background range specified
115 // This is obtained by dividing the function value by
116 // its integral analytically computed in that range.
117 // Returns 0 in all cases where a floating point exception
118 // could be raised by computing square root of a negative number.
121 Double_t fcnVal = TMath::Gaus(x[0], par[1], par[2], kTRUE);
122 Double_t fcnIntLeft = 0.5 * TMath::Erf(((par[1] - fPeakRange[0]) / par[2]) / TMath::Sqrt(2.0));
123 Double_t fcnIntRight = 0.5 * TMath::Erf(((fPeakRange[1] - par[1]) / par[2]) / TMath::Sqrt(2.0));
124 Double_t fcnInt = fcnIntLeft + fcnIntRight;
126 return par[0] * fcnVal / fcnInt;
129 //__________________________________________________________________________________________________
130 Double_t AliRsnFitResult::Signal(Double_t *x, Double_t *par)
133 // Computes the signal function according to chosen option
139 return NormBreitWigner(x, par);
141 return NormGaus(x, par);
143 AliError("Invalid signal function");
148 //__________________________________________________________________________________________________
149 Double_t AliRsnFitResult::Background(Double_t *x, Double_t *par)
152 // Computes the background function according to chosen option
155 switch (fBackgroundType)
158 return NormSquareRoot(x, par);
160 return NormLinear(x, par);
162 return NormPoly2(x, par);
164 AliError("Invalid background function");
169 //__________________________________________________________________________________________________
170 Double_t AliRsnFitResult::Sum(Double_t *x, Double_t *par)
173 // Computes the sum of the signal and the background chosen.
174 // First 3 parameters are for the signal (they are always 3),
175 // and other parameters, up to the necessary amount, are for
179 Double_t signal = Signal(x, par);
180 Double_t background = Background(x, &par[3]);
182 return signal + background;
185 //__________________________________________________________________________________________________
186 Int_t AliRsnFitResult::GetNParBackground()
189 // Tells how many parameters has the background function
192 switch (fBackgroundType)
194 case kSquareRoot: return 2;
195 case kLinear : return 2;
196 case kPoly2 : return 3;
201 //__________________________________________________________________________________________________
202 Bool_t AliRsnFitResult::InitFunctions()
205 // Initialize functions
208 //if (!fSignalFcn) fSignalFcn = new TF1(Form("sg%s", GetName()), Signal, fFullRange[0], fFullRange[1], 3);
209 //if (!fBackgroundFcn) fBackgroundFcn = new TF1(Form("bg%s", GetName()), Background, fFullRange[0], fFullRange[1], GetNParBackground());
210 //if (!fSumFcn) fSumFcn = new TF1(Form("sum%s", GetName()), Sum, fFullRange[0], fFullRange[1], 3+GetNParBackground());
213 //__________________________________________________________________________________________________
214 void AliRsnFitResult::SetHistogram(TH1F *histogram)
217 // Clones the passed histogram to proceed with fits
220 if (fHistogram) delete fHistogram;
222 fHistogram = (TH1D*)histogram->Clone();
223 fHistogram->SetName(Form("h_%s_%s", GetName(), histogram->GetName()));
224 fHistogram->SetTitle(histogram->GetTitle());
227 //__________________________________________________________________________________________________
228 Bool_t AliRsnFitResult::SingleFit(const char *opt, Double_t mass, Double_t width)
231 // Executes a single fit of the function
237 AliError("Require an initialized histogram!");
241 // if necessary, initialize functions
242 if (!fSignalFcn || !fBackgroundFcn || !fSumFcn) InitFunctions();
244 // step #0: know how many parameter we have
245 Int_t npar = GetNParBackground();
248 // fit outside peak to roughly initialize the background
249 for (Int_t i = 0; i < npar; i++) fBackgroundFcn->SetParameter(i, 0.5);
250 status = (Int_t)h->Fit(fcnOut, opt);
251 if (status) return kFALSE;
254 // estimate signal/background in the peak
255 Int_t imax = h->GetMaximumBin();
256 Double_t xmax = h->GetBinCenter(imax);
257 Double_t ymax = h->GetMaximum() - fBackgroundFcn->Eval(xmax);
260 // fit whole range with signal + background
261 // which is initialized to the reference values for mass and width
262 fSignalFcn->SetParameter(0, ymax);
263 fSignalFcn->SetParameter(1, mass);
264 fSignalFcn->SetParameter(2, width);
265 for (Int_t i = 0; i < npar; i++) fcnSum->SetParameter(i + 3, fBackgroundFcn->GetParameter(i));
266 status = (Int_t)h->Fit(fcnSum, opt);
267 if (status) return kFALSE;
269 // get integral and its error here
270 fValue[kSumIntegralError] = fSumFcn->IntegralError(fitPeakRangeMin, fitPeakRangeMax);
271 fValue[kSumIntegral] = fSumFcn->Integral (fitPeakRangeMin, fitPeakRangeMax);
272 fValue[kChi2] = fSumFcn->GetChisquare();
273 fValue[kNDF] = fSumFcn->GetNDF();