]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGCF/FLOW/blastwave/AliBlastwaveFitter.cxx
Add new classes to perform blastwave fit
[u/mrichter/AliRoot.git] / PWGCF / FLOW / blastwave / AliBlastwaveFitter.cxx
CommitLineData
3416bb60 1#include<stdio.h>
2
3#include"AliBlastwaveFitter.h"
4
5#include"TMath.h"
6#include"TH1.h"
7#include"TGraphErrors.h"
8#include"TGraphAsymmErrors.h"
9
10ClassImp(AliBlastwaveFitter);
11
12AliBlastwaveFitter::AliBlastwaveFitter(const char *name) :
13 TNamed(name,name),
14 fNfunction(0),
15 fMinuit(new TMinuit()),
16 fMinos(kFALSE)
17{
18}
19//------------------------------------------------------------------------------
20AliBlastwaveFitter::AliBlastwaveFitter() :
21 TNamed("BlastwaveFitter","BlastwaveFitter"),
22 fNfunction(0),
23 fMinuit(new TMinuit()),
24 fMinos(kFALSE)
25{
26}
27//------------------------------------------------------------------------------
28AliBlastwaveFitter::~AliBlastwaveFitter(){
29}
30//------------------------------------------------------------------------------
31Int_t AliBlastwaveFitter::CheckAvailability(){
32 Int_t something = 2;
33 Int_t consistency = 0;
34 Int_t nparameters = -1;
35 for(Int_t i=0;i < fNfunction;i++){
36 if(!fFunc[i]){
37 fSpectraFlag[i] = 0;
38 fV2Flag[i] = 0;
39 continue;
40 }
41 if(fFunc[i]->GetSpectraFit() && fFunc[i]->GetSpectrumObj()){
42 TString classe(fFunc[i]->GetSpectrumObj()->ClassName());
43 if(classe.Contains("TH1")) fSpectraFlag[i] = 1;
44 else if(classe.Contains("TGraphE")) fSpectraFlag[i] = 2;
45 else fSpectraFlag[i] = 0;
46 }
47 else fSpectraFlag[i] = 0;
48 if(fFunc[i]->GetV2Fit() && fFunc[i]->GetV2Obj()){
49 TString classe(fFunc[i]->GetV2Obj()->ClassName());
50 if(classe.Contains("TH1")) fV2Flag[i] = 1;
51 else if(classe.Contains("TGraphErr")) fV2Flag[i] = 2;
52 else if(classe.Contains("TGraphAsymmErr")) fV2Flag[i] = 3;
53 else fV2Flag[i] = 0;
54 }
55 else fV2Flag[i] = 0;
56
57 if(fSpectraFlag[i] || fV2Flag[i]) something = 0;
58 else continue;
59
60 Int_t npar = fFunc[i]->GetNpar();
61 if(nparameters == -1) nparameters = npar;
62 else if(npar != nparameters) consistency = 1;
63 }
64
65 return (consistency + something);
66}
67//------------------------------------------------------------------------------
68Int_t AliBlastwaveFitter::PrepareToFit(){
69 Int_t check = CheckAvailability();
70
71 Int_t npar=0;
72
73 if(check%2){
74 printf("Some problems with number of parameters are found\n");
75 return check;
76 }
77 if((check/2)%2){
78 printf("Nothing to fit\n");
79 return check;
80 }
81 printf("Summary of fit functions and histos\n");
82
83 Bool_t kFlowAvailable=kFALSE;
84
85 for(Int_t i=0;i < fNfunction;i++){
86 if(!fFunc[i]) continue;
87 printf("------------------------------------------------------------------\n");
88 printf("%2i) SpectraFlag = %i -- V2Flag = %i for \"%s\" (class:%s) with mass = %6.3f GeV/c^2\n",i,fSpectraFlag[i],fV2Flag[i],fFunc[i]->GetName(),fFunc[i]->ClassName(),fFunc[i]->GetMass());
89 if(fSpectraFlag[i]){
90 printf(" data spectra:\"%s\" (class:%s)\n",fFunc[i]->GetSpectrumObj()->GetName(),fFunc[i]->GetSpectrumObj()->ClassName());
91 npar = fFunc[i]->GetNpar();
92 }
93 if(fV2Flag[i]){
94 printf(" data v2 :\"%s\" (class:%s)\n",fFunc[i]->GetV2Obj()->GetName(),fFunc[i]->GetV2Obj()->ClassName());
95 npar = fFunc[i]->GetNpar();
96 kFlowAvailable=kTRUE;
97 }
98 }
99 printf("------------------------------------------------------------------\n");
100
101 fgNparReal = npar;
102
103 fgNDGF = 0;
104 fgNfunctionCurrent = fNfunction;
105 for(Int_t i=0;i < fNfunction;i++){
106 fgFuncC[i] = fFunc[i];
107 fgSpectraFlagC[i] = fSpectraFlag[i];
108 fgV2FlagC[i] = fV2Flag[i];
109 }
110 // prepare minuit
111 if(fgNparReal >= 25){
112 fMinuit->BuildArrays(fgNparReal);
113 }
114 fMinuit->SetFCN(AliBlastwaveFitter::FCN);
115 Double_t arglist[3];
116 Int_t ierflg = 0;
117 arglist[0] = 1;
118 fMinuit->mnexcm("SET ERR", arglist, 1, ierflg);
119
120 // par limits of the medium
121 for(Int_t i=0;i < npar;i++){
122 fMinuit->mnparm(i/*#par*/, fFunc[0]->GetParName(i)/*name*/, fFunc[0]->GetParStart(i)/*startvalue*/, fFunc[0]->GetParStep(i)/*step*/, fFunc[0]->GetParMin(i)/*min*/,fFunc[0]->GetParMax(i)/*max*/, ierflg);
123 }
124
125 if(!kFlowAvailable){ // if there is no flow histos
126 for(Int_t i=0;i < fNfunction;i++){
127 if(fSpectraFlag[i]){
128 fFunc[i]->SwitchOffFlow(fMinuit);
129 i = fNfunction;
130 }
131 }
132 }
133
134 // set strategy
135 arglist[0] = 1; // !!!
136 fMinuit->mnexcm("SET STRATEGY", arglist, 1, ierflg);
137
138 return 0;
139}
140//------------------------------------------------------------------------------
141Int_t AliBlastwaveFitter::Fit(){
142 Int_t npar = fFunc[0]->GetNpar();
143 /* start MIGRAD minimization */
144 Double_t arglist[20];
145 Int_t ierflg = 0;
146 arglist[0] = 500000;
147 arglist[1] = 1.;
148 fMinuit->mnexcm("MIGRAD", arglist, 2, ierflg);
149
150 /* set strategy */
151 arglist[0] = 2;
152 fMinuit->mnexcm("SET STRATEGY", arglist, 1, ierflg);
153
154 /* start MIGRAD minimization */
155 arglist[0] = 500000;
156 arglist[1] = 1.;
157 fMinuit->mnexcm("MIGRAD", arglist, 2, ierflg);
158
159 /* start IMPROVE minimization */
160 arglist[0] = 500000;
161 fMinuit->mnexcm("IMPROVE", arglist, 1, ierflg);
162
163 /* start MINOS */
164 if(fMinos){
165 arglist[0] = 500000;
166 for(Int_t i=0;i < npar;i++){
167 arglist[i+1] = i;
168 }
169 fMinuit->mnexcm("MINOS", arglist, npar+1, ierflg);
170 }
171
172 /* print results */
173 Double_t amin,edm,errdef;
174 Int_t nvpar,nparx,icstat;
175 fMinuit->mnstat(amin, edm, errdef, nvpar, nparx, icstat);
176 fMinuit->mnprin(4, amin);
177
178 for(Int_t i=0;i < fgNfunctionCurrent;i++){
179 fgFuncC[i]->Terminate();
180 }
181
182 return 0;
183}
184//------------------------------------------------------------------------------
185void AliBlastwaveFitter::FCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag){
186 Double_t chi = 0., val, vale, pull,pt;
187 Int_t iNorm = 0,nparFunc;
188
189 if(gin[0]==1){}
190
191// printf("%i) %f %f %f %f %f %f %f\n",npar,par[0],par[1],par[2],par[3],par[4],par[5],par[6]);
192
193
194 fgNDGF=0;
195
196 for(Int_t i=0;i < fgNfunctionCurrent;i++){
197 if(!fgFuncC[i]) continue;
198
199 // Set parameter in the current function
200 nparFunc = fgFuncC[i]->GetNpar();
201 for(Int_t j=0;j<nparFunc;j++)
202 fgFuncC[i]->SetParameter(j,par[j]);
203
204 // Set normalization in the current function
205 if(fgSpectraFlagC[i]){// && nparFunc+iNorm < npar){
206 fgFuncC[i]->SetNormalization();//par[nparFunc+iNorm]);
207 iNorm++;
208 }
209
210 if(fgSpectraFlagC[i]){
211 // spectra comparison
212 TH1 *hForFit = (TH1 *) fgFuncC[i]->GetSpectrumObj();
213 TGraphErrors *gForFit = (TGraphErrors *) fgFuncC[i]->GetSpectrumObj();
214
215 if(fgSpectraFlagC[i]==1){
216 for (Int_t ibin = 1; ibin <= hForFit->GetNbinsX(); ibin++) {
217 pt = hForFit->GetBinCenter(ibin);
218 if(pt < fgFuncC[i]->GetMaxPt() && pt > fgFuncC[i]->GetMinPt()){
219 val = hForFit->GetBinContent(ibin);
220 vale = hForFit->GetBinError(ibin);
221 if(vale>0 && TMath::Abs(val) > vale+0.00001){
222 pull = (val - fgFuncC[i]->EvalYield(pt))/vale;
223 chi += pull * pull;
224 fgNDGF++;
225 }
226 }
227 }
228 }
229 else if(fgSpectraFlagC[i]==2){
230 for (Int_t ibin = 0; ibin < gForFit->GetN(); ibin++) {
231 pt = gForFit->GetX()[ibin];
232 if(pt < fgFuncC[i]->GetMaxPt() && pt > fgFuncC[i]->GetMinPt()){
233 val = gForFit->GetY()[ibin];
234 vale = gForFit->GetEY()[ibin];
235 if(vale>0){
236 pull = (val - fgFuncC[i]->EvalYield(pt))/vale;
237 chi += pull * pull;
238 fgNDGF++;
239 }
240 }
241 }
242 }
243 }
244 if(fgV2FlagC[i]){
245 // v2 comparison
246 TH1 *hForFit = (TH1 *) fgFuncC[i]->GetV2Obj();
247 TGraphErrors *gForFit = (TGraphErrors *) fgFuncC[i]->GetV2Obj();
248 TGraphAsymmErrors *gForFitA = (TGraphAsymmErrors *) fgFuncC[i]->GetV2Obj();
249
250 if(fgV2FlagC[i]==1){
251 for (Int_t ibin = 1; ibin <= hForFit->GetNbinsX(); ibin++) {
252 pt = hForFit->GetBinCenter(ibin);
253 if(pt < fgFuncC[i]->GetMaxPt() && pt > fgFuncC[i]->GetMinPt()){
254 val = hForFit->GetBinContent(ibin);
255 vale = hForFit->GetBinError(ibin);
256 if(vale>0 && TMath::Abs(val) > vale+0.00001){
257 pull = (val - fgFuncC[i]->EvalV2(pt))/vale;
258 chi += pull * pull;
259 fgNDGF++;
260 }
261 }
262 }
263 }
264 else if(fgV2FlagC[i]==2){
265 for (Int_t ibin = 0; ibin < gForFit->GetN(); ibin++) {
266 pt = gForFit->GetX()[ibin];
267 if(pt < fgFuncC[i]->GetMaxPt() && pt > fgFuncC[i]->GetMinPt()){
268 val = gForFit->GetY()[ibin];
269 vale = gForFit->GetEY()[ibin];
270 if(vale>0){
271 pull = (val - fgFuncC[i]->EvalV2(pt))/vale;
272 chi += pull * pull;
273 fgNDGF++;
274 }
275 }
276 }
277 }
278 else if(fgV2FlagC[i]==3){
279 for (Int_t ibin = 0; ibin < gForFitA->GetN(); ibin++) {
280 pt = gForFit->GetX()[ibin];
281 if(pt < fgFuncC[i]->GetMaxPt() && pt > fgFuncC[i]->GetMinPt()){
282 val = gForFit->GetY()[ibin];
283 if(val - fgFuncC[i]->EvalV2(pt) > 0) vale = gForFit->GetEYlow()[ibin];
284 else vale = gForFit->GetEYhigh()[ibin];
285 if(vale>0){
286 pull = (val - fgFuncC[i]->EvalV2(pt))/vale;
287 chi += pull * pull;
288 fgNDGF++;
289 }
290 }
291 }
292 }
293 }
294 }
295
296 fgNDGF -= npar + iNorm;
297
298 if(fgNDGF > 0) fgChi2 = chi/fgNDGF;
299
300 f = chi;
301 iflag = 0;
302}
303//------------------------------------------------------------------------------
304TGraph* AliBlastwaveFitter::DoContour(Int_t np,Int_t ip1,Int_t ip2,Float_t nsigma){
305
306 TGraph *gCorr=NULL;
307
308 Double_t par1,par2,err;
309 fMinuit->GetParameter(ip1, par1,err);
310 fMinuit->GetParameter(ip2, par2,err);
311
312 Int_t trial = 0;
313 Double_t scale = 1;
314 while((! gCorr || gCorr->GetN() < np/4+5) && trial < 10){
315 fMinuit->SetErrorDef(nsigma*nsigma*scale); //3 sigma contour
316 gCorr = (TGraph *) fMinuit->Contour(np,ip1,ip2);
317 scale *= 0.5;
318 trial++;
319 }
320 scale *= 2;
321 scale = TMath::Sqrt(scale);
322
323 if(scale < 0.7 && gCorr){
324 Double_t *x = gCorr->GetX();
325 Double_t *y = gCorr->GetY();
326 for(Int_t i=0;i < gCorr->GetN();i++){
327 gCorr->SetPoint(i,par1+(x[i]-par1)/scale,par2+(y[i]-par2)/scale);
328 }
329 }
330
331 if(trial > 1) printf("Contour realized with %3.1f sigma instead of %3.1f and then rescaled\n",nsigma*TMath::Sqrt(scale),nsigma);
332
333 if(gCorr) gCorr->SetMarkerStyle(20);
334
335 return gCorr;
336
337}
338 //------------------------------------------------------------------------------
339TGraph* AliBlastwaveFitter::DoContourBetaT(Int_t np,Int_t iBoostOrBeta,Int_t iT,Float_t nsigma){
340
341
342 TGraph *gCorr=NULL;
343
344 Double_t par1,par2,err;
345 fMinuit->GetParameter(iBoostOrBeta, par1,err);
346 fMinuit->GetParameter(iT, par2,err);
347
348 const Int_t maxnpar = 20;
349 Double_t par[maxnpar];
350
351 Int_t npar = fMinuit->GetNumPars();
352 for(Int_t i=0;i < TMath::Min(npar,maxnpar);i++){
353 fMinuit->GetParameter(i, par[i],err);
354 }
355
356 Int_t trial = 0;
357 Double_t scale = 1;
358 while((! gCorr || gCorr->GetN() < np/4+5) && trial < 10){
359 fMinuit->SetErrorDef(nsigma*nsigma*scale); //3 sigma contour
360 gCorr = (TGraph *) fMinuit->Contour(np,iBoostOrBeta,iT);
361 scale *= 0.5;
362 trial++;
363 }
364 scale *= 2;
365 scale = TMath::Sqrt(scale);
366
367 if(gCorr){
368 Double_t *x = gCorr->GetX();
369 Double_t *y = gCorr->GetY();
370 for(Int_t i=0;i < gCorr->GetN();i++){
371 Float_t meanboost = par1+(x[i]-par1)/scale;
372 par[iBoostOrBeta] = meanboost;
373 par[iT] = y[i];
374 Float_t meanbeta = fgFuncC[0]->GetMeanBeta(par);
375 gCorr->SetPoint(i,meanbeta,par2+(y[i]-par2)/scale);
376 }
377 }
378
379 if(trial > 1) printf("Contour realized with %3.1f sigma instead of %3.1f and then rescaled\n",nsigma*TMath::Sqrt(scale),nsigma);
380
381 if(gCorr) gCorr->SetMarkerStyle(20);
382
383 return gCorr;
384
385}
386 //------------------------------------------------------------------------------
387TGraph* AliBlastwaveFitter::ConvertContourFromBoostToBeta(TGraph *g,Int_t iBoostOrBeta,Int_t iT){
388
389 if(!g) return NULL;
390
391 TGraph *gCorr=new TGraph(g->GetN());
392
393 const Int_t maxnpar = 20;
394 Double_t par[maxnpar],err;
395
396 Int_t npar = fMinuit->GetNumPars();
397 for(Int_t i=0;i < TMath::Min(npar,maxnpar);i++){
398 fMinuit->GetParameter(i, par[i],err);
399 }
400
401 if(gCorr){
402 Double_t *x = g->GetX();
403 Double_t *y = g->GetY();
404 for(Int_t i=0;i < gCorr->GetN();i++){
405 par[iBoostOrBeta] = x[i];
406 par[iT] = y[i];
407 Float_t meanbeta = fgFuncC[0]->GetMeanBeta(par);
408 gCorr->SetPoint(i,meanbeta,y[i]);
409 }
410 }
411
412 if(gCorr) gCorr->SetMarkerStyle(20);
413
414 return gCorr;
415
416}