]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG2/FLOW/AliFlowCommon/AliFlowAnalysisWithFittingQDistribution.cxx
allow for rebinning phi weights
[u/mrichter/AliRoot.git] / PWG2 / FLOW / AliFlowCommon / AliFlowAnalysisWithFittingQDistribution.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  * 
14 **************************************************************************/
15
16 /******************************** 
17  * estimating reference flow by *
18  *   fitting q-distribution     * 
19  *                              *
20  * author: Ante Bilandzic       * 
21  *       (abilandzic@gmail.com) *
22  *                              *  
23  *  based on the macro written  *
24  *     by Sergei Voloshin       *
25  *******************************/  
26
27 #define AliFlowAnalysisWithFittingQDistribution_cxx
28
29 #include "Riostream.h"
30 #include "AliFlowCommonConstants.h"
31 #include "AliFlowCommonHist.h"
32 #include "AliFlowCommonHistResults.h"
33 #include "TChain.h"
34 #include "TFile.h"
35 #include "TList.h" 
36 #include "TF1.h"
37 #include "TParticle.h"
38 #include "TProfile.h"
39 #include "AliFlowEventSimple.h"
40 #include "AliFlowTrackSimple.h"
41 #include "AliFlowAnalysisWithFittingQDistribution.h"
42
43 class TH1;
44 class TGraph;
45 class TPave;
46 class TLatex;
47 class TMarker;
48 class TObjArray;
49 class TList;
50 class TSystem;
51 class TROOT;
52 class AliFlowVector;
53 class TVector;
54
55 //================================================================================================================
56
57 ClassImp(AliFlowAnalysisWithFittingQDistribution)
58
59 AliFlowAnalysisWithFittingQDistribution::AliFlowAnalysisWithFittingQDistribution():  
60  fHistList(NULL),
61  fCommonHists(NULL),
62  fCommonHistsResults(NULL),
63  fnBinsPhi(0),
64  fPhiMin(0),
65  fPhiMax(0),
66  fPhiBinWidth(0),
67  fnBinsPt(0),
68  fPtMin(0),
69  fPtMax(0),
70  fPtBinWidth(0),
71  fnBinsEta(0),
72  fEtaMin(0),
73  fEtaMax(0),
74  fEtaBinWidth(0),
75  fHarmonic(2),
76  fAnalysisLabel(NULL),
77  fWeightsList(NULL),
78  fUsePhiWeights(kFALSE),
79  fUsePtWeights(kFALSE),
80  fUseEtaWeights(kFALSE),
81  fUseParticleWeights(NULL),
82  fPhiWeights(NULL),
83  fPtWeights(NULL),
84  fEtaWeights(NULL),
85  fSumOfParticleWeights(NULL),
86  fqDistribution(NULL),
87  fqMin(0.),
88  fqMax(1000.),
89  fqNbins(10000),
90  fFittingParameters(NULL), 
91  fTreshold(5.),
92  fvStart(0.05),
93  fvMin(0.0),
94  fvMax(0.25),
95  fSigma2Start(0.75),
96  fSigma2Min(0.5), 
97  fSigma2Max(2.5),
98  fFinalResultIsFromSigma2Fitted(kTRUE),
99  fPrintOnTheScreen(kTRUE)
100  {
101   // constructor 
102   
103   // base list to hold all output objects:
104   fHistList = new TList();
105   fHistList->SetName("cobjFQD");
106   fHistList->SetOwner(kTRUE);
107   
108   // analysis label;
109   fAnalysisLabel = new TString();
110  
111   // list to hold histograms with phi, pt and eta weights:      
112   fWeightsList = new TList();
113
114   // initialize all arrays:  
115   this->InitializeArrays();
116
117  } // end of constructor
118  
119 //================================================================================================================
120  
121 AliFlowAnalysisWithFittingQDistribution::~AliFlowAnalysisWithFittingQDistribution()
122 {
123  // destructor
124  
125  delete fHistList; 
126  
127 } // end of destructor
128
129 //================================================================================================================
130
131
132 void AliFlowAnalysisWithFittingQDistribution::Init()
133 {
134  // Access constants and book everything.
135  
136  //save old value and prevent histograms from being added to directory
137  //to avoid name clashes in case multiple analaysis objects are used
138  //in an analysis
139  Bool_t oldHistAddStatus = TH1::AddDirectoryStatus();
140  TH1::AddDirectory(kFALSE);
141  
142  // access constants:
143  this->AccessConstants();
144  
145  // booking:
146  this->BookCommonHistograms();
147  this->BookAndFillWeightsHistograms();
148  this->BookEverythingForDistributions();
149  
150  // store fitting parameters:  
151  this->StoreFittingParameters();
152  
153  // nest lists:
154  fWeightsList->SetName("Weights");
155  fWeightsList->SetOwner(kTRUE);   
156  fHistList->Add(fWeightsList);
157  
158  // set harmonic in common control histograms (to be improved (should I do this somewhere else?)):
159  (fCommonHists->GetHarmonic())->Fill(0.5,fHarmonic); 
160  
161  //restore old status
162  TH1::AddDirectory(oldHistAddStatus);
163 } // end of void AliFlowAnalysisWithFittingQDistribution::Init()
164
165 //================================================================================================================
166
167 void AliFlowAnalysisWithFittingQDistribution::Make(AliFlowEventSimple* anEvent)
168 {
169  // Loop over data only in this method.
170  
171  // a) Check all pointers used in this method;
172  // b) Fill the common control histograms;
173  // c) Loop over data and calculate Q-vector and sum of particle weights;
174  // d) Fill the histogram for q-distribution and sum of particle weights.
175  
176  // a) Check all pointers used in this method:
177  this->CheckPointersUsedInMake();
178  
179  // b) fill the common control histograms:
180  fCommonHists->FillControlHistograms(anEvent);                                         
181  
182  // c) Loop over data and fill histogram for q-distribution:                                          
183  Double_t dPhi = 0.; // azimuthal angle in the laboratory frame
184  Double_t dPt  = 0.; // transverse momentum
185  Double_t dEta = 0.; // pseudorapidity
186  Double_t wPhi = 1.; // phi weight
187  Double_t wPt  = 1.; // pt weight
188  Double_t wEta = 1.; // eta weight 
189  Double_t dReQ = 0.; // real part of Q-vector 
190  Double_t dImQ = 0.; // imaginary part of Q-vector
191  Int_t n = fHarmonic; // shortcut for the harmonic 
192  Double_t dSumOfParticleWeights = 0.; // when particle weights are not used dSumOfParticleWeights is equal to multiplicity
193  AliFlowTrackSimple *aftsTrack = NULL;  
194  Int_t nPrim = anEvent->NumberOfTracks(); // nPrim = total number of primary tracks, i.e. nPrim = nRP + nPOI + rest, where:
195                                           // nRP   = # of particles used to determine the reaction plane;
196                                           // nPOI  = # of particles of interest for a detailed flow analysis;
197                                           // rest  = # of particles which are not niether RPs nor POIs.   
198  // Start loop over particles:
199  for(Int_t i=0;i<nPrim;i++) 
200  { 
201   aftsTrack=anEvent->GetTrack(i);
202   if(aftsTrack)
203   {
204    if(!(aftsTrack->InRPSelection())) continue; // consider only tracks which are RPs    
205    dPhi = aftsTrack->Phi();
206    dPt  = aftsTrack->Pt();
207    dEta = aftsTrack->Eta();
208    if(fUsePhiWeights && fPhiWeights && fnBinsPhi) // determine phi weight for this particle:
209    {
210     wPhi = fPhiWeights->GetBinContent(1+(Int_t)(TMath::Floor(dPhi*fnBinsPhi/TMath::TwoPi())));
211    }
212    if(fUsePtWeights && fPtWeights && fPtBinWidth) // determine pt weight for this particle:
213    {
214     wPt = fPtWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-fPtMin)/fPtBinWidth))); 
215    }            
216    if(fUseEtaWeights && fEtaWeights && fEtaBinWidth) // determine eta weight for this particle: 
217    {
218     wEta = fEtaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-fEtaMin)/fEtaBinWidth))); 
219    }   
220    // Calculate real and imaginary part of Q-vector and sum of particle weights for this event:
221    // Q-vector:
222    dReQ += wPhi*wPt*wEta*TMath::Cos(n*dPhi); 
223    dImQ += wPhi*wPt*wEta*TMath::Sin(n*dPhi);
224    // sum of particle weights:
225    dSumOfParticleWeights += wPhi*wPt*wEta; // when particle weights are not used this sum gives # of RPs, i.e. multiplicity   
226   } // end of if(aftsTrack)
227  } // end of for(Int_t i=0;i<nPrim;i++)                                      
228                                            
229  // d) Fill the histogram for q-distribution and sum of particle weights:
230  Double_t q = 0.; // q = Q\sqrt{sum of particle weights}                                         
231  if(dSumOfParticleWeights)
232  {
233   q = pow(dReQ*dReQ+dImQ*dImQ,0.5)/pow(dSumOfParticleWeights,0.5);
234   fqDistribution->Fill(q,1.);
235   fSumOfParticleWeights->Fill(dSumOfParticleWeights,1.);
236  } else
237    {
238     cout<<endl;
239     cout<<" WARNING (FQD::Make()): dSumOfParticleWeights == 0. !!!!"<<endl;
240     cout<<endl;
241    }
242
243 } // end of Make()
244
245 //================================================================================================================
246
247 void AliFlowAnalysisWithFittingQDistribution::Finish(Bool_t doFit)
248 {
249  // Calculate the final results.
250  
251  // a) Check all pointers used in this method;
252  // b) Acces common constants;
253  // c) Access fitting paremeters;
254  // d) Do the final fit of q-distribution;
255  // e) Fill common hist results;
256  // f) Print on the screen the final results.
257  
258  // a) Check all pointers used in this method:
259  this->CheckPointersUsedInFinish(); 
260  
261  // b) Access common constants:
262  this->AccessConstants();
263  
264  // c) Access fitting paremeters:
265  this->AccessFittingParameters();
266  
267  // d) Do the final fit of q-distribution:             
268  if(doFit) 
269  {
270   this->DoFit(kFALSE); // sigma^2 not fitted (fixed to 0.5)
271   this->DoFit(kTRUE); // sigma^2 fitted
272  } 
273    
274  // e) Fill common hist results (by default fill with results obtained with sigma^2 fitted,
275  //    alternatively use a setter SetFinalResultIsFromSigma2Fitted(kFALSE)):
276  this->FillCommonHistResults(fFinalResultIsFromSigma2Fitted); 
277   
278  // f) Print on the screen the final results:
279  if(fPrintOnTheScreen) this->PrintOnTheScreen();  
280   
281 } // end of void AliFlowAnalysisWithFittingQDistribution::Finish(Bool_t doFit)
282  
283 //================================================================================================================
284
285 void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInMake()
286 {
287  // Check all pointers used in method Make().
288  
289  if(!fCommonHists)
290  {
291   cout<<endl;
292   cout<<" WARNING (FQD::Make()): fCommonHists is NULL !!!!"<<endl;
293   cout<<endl;
294   exit(0); 
295  } 
296  if(!fqDistribution)
297  {
298   cout<<endl;
299   cout<<" WARNING (FQD::Make()): fqDistribution is NULL !!!!"<<endl;
300   cout<<endl;
301   exit(0); 
302  }
303  if(!fSumOfParticleWeights)
304  {
305   cout<<endl;
306   cout<<" WARNING (FQD::Make()): fSumOfParticleWeights is NULL !!!!"<<endl;
307   cout<<endl;
308   exit(0); 
309  }
310  if(fUsePhiWeights && !fPhiWeights)
311  {
312   cout<<endl;
313   cout<<" WARNING (FQD::Make()): fPhiWeights is NULL !!!!"<<endl;
314   cout<<endl;
315   exit(0); 
316  }
317  if(fUsePtWeights && !fPtWeights)
318  {
319   cout<<endl;
320   cout<<" WARNING (FQD::Make()): fPtWeights is NULL !!!!"<<endl;
321   cout<<endl;
322   exit(0); 
323  } 
324  if(fUseEtaWeights && !fEtaWeights)
325  {
326   cout<<endl;
327   cout<<" WARNING (FQD::Make()): fEtaWeights is NULL !!!!"<<endl;
328   cout<<endl;
329   exit(0); 
330  } 
331
332 } // end of void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInMake()
333
334 //================================================================================================================
335
336 void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInFinish()
337 {
338  // Check all pointers used in method Finish().
339  
340  if(!fFittingParameters)
341  {
342   cout<<endl;
343   cout<<" WARNING (FQD::Finish()): fFittingParameters is NULL !!!!"<<endl;
344   cout<<endl;
345   exit(0); 
346  } 
347  if(!fqDistribution)
348  {
349   cout<<endl;
350   cout<<" WARNING (FQD::Finish()): fqDistribution is NULL !!!!"<<endl;
351   cout<<endl;
352   exit(0); 
353  } 
354  if(!fSumOfParticleWeights)
355  {
356   cout<<endl;
357   cout<<" WARNING (FQD::Finish()): fSumOfParticleWeights is NULL !!!!"<<endl;
358   cout<<endl;
359   exit(0); 
360  } 
361  for(Int_t s2F=0;s2F<2;s2F++)
362  {
363   if(!fIntFlow[s2F])
364   {
365    cout<<endl;
366    cout<<" WARNING (FQD::Finish()): "<<Form("fIntFlow[%d] is NULL !!!!",s2F)<<endl;
367    cout<<endl;
368    exit(0); 
369   }
370   if(!fSigma2[s2F])
371   {
372    cout<<endl;
373    cout<<" WARNING (FQD::Finish()): "<<Form("fSigma2[%d] is NULL !!!!",s2F)<<endl;
374    cout<<endl;
375    exit(0); 
376   }
377   if(!fChi2[s2F])
378   {
379    cout<<endl;
380    cout<<" WARNING (FQD::Finish()): "<<Form("fChi2[%d] is NULL !!!!",s2F)<<endl;
381    cout<<endl;
382    exit(0); 
383   }
384  } // end of for(Int_t s2F=0;s2F<2;s2F++)
385  if(!fCommonHistsResults)
386  {
387   cout<<endl;
388   cout<<"WARNING (FQD::Finish()): fCommonHistsResults is NULL !!!!"<<endl; 
389   cout<<endl;
390   exit(0);
391  }
392  if(!fCommonHists)
393  {
394   cout<<endl;
395   cout<<"WARNING (FQD::Finish()): fCommonHists is NULL !!!!"<<endl; 
396   cout<<endl;
397   exit(0);
398  }
399   
400 } // end of void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInFinish()
401  
402 //================================================================================================================
403
404 void AliFlowAnalysisWithFittingQDistribution::GetOutputHistograms(TList *outputListHistos) 
405 {
406  // Get pointers to all output histograms (called before Finish()). 
407  
408  if(outputListHistos)   
409  {   
410   // 1.) common control histograms and common histograms for final results:
411   TString commonHistName = "AliFlowCommonHistFQD";
412   commonHistName += fAnalysisLabel->Data();
413   AliFlowCommonHist *commonHist = dynamic_cast<AliFlowCommonHist*>(outputListHistos->FindObject(commonHistName.Data()));
414   if(commonHist) this->SetCommonHists(commonHist); 
415   
416   TString commonHistResName = "AliFlowCommonHistResultsFQD";
417   commonHistResName += fAnalysisLabel->Data();
418   AliFlowCommonHistResults *commonHistRes = dynamic_cast<AliFlowCommonHistResults*>
419                                             (outputListHistos->FindObject(commonHistResName.Data()));
420   if(commonHistRes) this->SetCommonHistsResults(commonHistRes); 
421   
422   // 2.) weights: 
423   TList *weightsList = dynamic_cast<TList*>(outputListHistos->FindObject("Weights"));
424   if(weightsList) this->SetWeightsList(weightsList);
425   Bool_t bUsePhiWeights = kFALSE;
426   Bool_t bUsePtWeights = kFALSE;
427   Bool_t bUseEtaWeights = kFALSE;
428   TString fUseParticleWeightsName = "fUseParticleWeightsFQD";
429   fUseParticleWeightsName += fAnalysisLabel->Data();
430   TProfile *useParticleWeights = dynamic_cast<TProfile*>(weightsList->FindObject(fUseParticleWeightsName.Data()));
431   if(useParticleWeights)
432   {
433    this->SetUseParticleWeights(useParticleWeights);  
434    bUsePhiWeights = (Int_t)useParticleWeights->GetBinContent(1);
435    this->SetUsePhiWeights(bUsePhiWeights);
436    bUsePtWeights = (Int_t)useParticleWeights->GetBinContent(2);
437    this->SetUsePtWeights(bUsePtWeights);
438    bUseEtaWeights = (Int_t)useParticleWeights->GetBinContent(3);
439    this->SetUseEtaWeights(bUseEtaWeights);
440   }
441   
442   // 3.) distributions and 4.) final results of fitting:
443   TString sigmaFlag[2] = {"#sigma^{2} not fitted","#sigma^{2} fitted"};  
444   // q-distribution:
445   TString qDistributionName = "fqDistribution";
446   qDistributionName += fAnalysisLabel->Data();
447   // sum of particle weights:
448   TString sumOfParticleWeightsName = "fSumOfParticleWeights"; 
449   sumOfParticleWeightsName += fAnalysisLabel->Data();
450   // final results for reference flow:
451   TString intFlowName = "fIntFlowFQD";
452   intFlowName += fAnalysisLabel->Data();
453   // sigma^2:
454   TString sigma2Name = "fSigma2";
455   sigma2Name += fAnalysisLabel->Data();
456   // chi^2:
457   TString chi2Name = "fChi2";
458   chi2Name += fAnalysisLabel->Data();
459   // fitting function:
460   TString fittingFunctionName = "fFittingFunction";
461   fittingFunctionName += fAnalysisLabel->Data();
462   
463   TH1D *qDistribution = NULL;
464   TH1D *sumOfParticleWeights = NULL;
465   TH1D *intFlow[2] = {NULL};
466   TH1D *sigma2[2] = {NULL};
467   TH1D *chi2[2] = {NULL};
468   TF1 *fittingFunction[2] = {NULL};
469    
470   // q-distribution:
471   qDistribution = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s",qDistributionName.Data())));
472   if(qDistribution)
473   {
474    this->SetqDistribution(qDistribution);
475   } else
476     {
477      cout<<"WARNING: qDistribution is NULL in AFAWFQD::GOH() !!!!"<<endl;
478     }
479   // sum of particle weights:
480   sumOfParticleWeights = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s",sumOfParticleWeightsName.Data())));
481   if(sumOfParticleWeights)
482   {
483    this->SetSumOfParticleWeights(sumOfParticleWeights);
484   } else
485     {
486      cout<<"WARNING: sumOfParticleWeights is NULL in AFAWFQD::GOH() !!!!"<<endl;
487     }
488   // final results:
489   for(Int_t f=0;f<2;f++)
490   {
491    // final results for reference flow:
492    intFlow[f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",intFlowName.Data(),sigmaFlag[f].Data())));
493    if(intFlow[f])
494    {
495     this->SetIntFlow(intFlow[f],f);
496    } else 
497      {
498       cout<<"WARNING: intFlow[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
499       cout<<"f  = "<<f<<endl;
500      }
501    // sigma^2:
502    sigma2[f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",sigma2Name.Data(),sigmaFlag[f].Data())));
503    if(sigma2[f])
504    {
505     this->SetSigma2(sigma2[f],f);
506    } else 
507      { 
508       cout<<"WARNING: sigma2[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
509       cout<<"f  = "<<f<<endl;
510      } 
511    // chi^2:
512    chi2[f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",chi2Name.Data(),sigmaFlag[f].Data())));
513    if(chi2[f])
514    {
515     this->SetChi2(chi2[f],f);
516    } else 
517      {
518       cout<<"WARNING: chi2[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
519       cout<<"f  = "<<f<<endl;
520      }   
521    // fitting functions:
522    fittingFunction[f] = dynamic_cast<TF1*>(outputListHistos->FindObject(Form("%s, %s",fittingFunctionName.Data(),sigmaFlag[f].Data())));
523    if(fittingFunction[f])
524    {
525     this->SetFittingFunction(fittingFunction[f],f);
526    } else 
527      {
528       cout<<"WARNING: fittingFunction[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
529       cout<<"f  = "<<f<<endl;
530      }       
531   } // end of for(Int_t f=0;f<2;f++)
532  
533   // 5.) fitting parameters:
534   // q-distribution:
535   TString fittingParametersName = "fFittingParameters";
536   fittingParametersName += fAnalysisLabel->Data();
537   TProfile *fittingParameters = NULL;
538   fittingParameters = dynamic_cast<TProfile*>(outputListHistos->FindObject(fittingParametersName.Data()));
539   if(fittingParameters)
540   {
541    this->SetFittingParameters(fittingParameters);
542   } else
543     {
544      cout<<"WARNING:fittingParameters is NULL in AFAWFQD::GOH() !!!!"<<endl;
545     }
546   
547  } else // to if(outputListHistos)
548    {
549     cout<<"WARNING: outputListHistos is NULL in AFAWFQD::GOH() !!!!"<<endl;
550     exit(0);
551    } 
552    
553 } // end of void AliFlowAnalysisWithFittingQDistribution::GetOutputHistograms(TList *outputListHistos) 
554
555 //================================================================================================================
556
557 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TString* outputFileName)
558 {
559  //store the final results in output .root file
560  TFile *output = new TFile(outputFileName->Data(),"RECREATE");
561  //output->WriteObject(fHistList, "cobjFQD","SingleKey");
562  fHistList->SetName("cobjFQD");
563  fHistList->SetOwner(kTRUE);
564  fHistList->Write(fHistList->GetName(), TObject::kSingleKey);
565  delete output;
566 }
567
568 //================================================================================================================
569
570 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TString outputFileName)
571 {
572  //store the final results in output .root file
573  TFile *output = new TFile(outputFileName.Data(),"RECREATE");
574  //output->WriteObject(fHistList, "cobjFQD","SingleKey");
575  fHistList->SetName("cobjFQD");
576  fHistList->SetOwner(kTRUE);
577  fHistList->Write(fHistList->GetName(), TObject::kSingleKey); 
578  delete output;
579 }
580
581 //================================================================================================================
582
583 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TDirectoryFile *outputFileName)
584 {
585  //store the final results in output .root file
586  fHistList->SetName("cobjFQD");
587  fHistList->SetOwner(kTRUE);
588  outputFileName->Add(fHistList);
589  outputFileName->Write(outputFileName->GetName(), TObject::kSingleKey);
590 }
591
592 //================================================================================================================
593
594 void AliFlowAnalysisWithFittingQDistribution::InitializeArrays()
595 {
596  // Initialize all arrays.
597  
598  for(Int_t s2F=0;s2F<2;s2F++) // sigma^2 not fitted (0) or fitted (1)
599  {
600   fIntFlow[s2F] = NULL;
601   fSigma2[s2F] = NULL;
602   fChi2[s2F] = NULL;
603   fFittingFunction[s2F] = NULL;
604  } 
605
606 } // end of void AliFlowAnalysisWithFittingQDistribution::InitializeArrays()
607
608 //================================================================================================================
609
610 void AliFlowAnalysisWithFittingQDistribution::BookCommonHistograms()
611 {
612  // Book common histograms.
613  
614  // common control histogram: 
615  TString commonHistName = "AliFlowCommonHistFQD";
616  commonHistName += fAnalysisLabel->Data();
617  fCommonHists = new AliFlowCommonHist(commonHistName.Data());
618  fHistList->Add(fCommonHists);  
619
620  // common histograms for final results:
621  TString commonHistResName = "AliFlowCommonHistResultsFQD";
622  commonHistResName += fAnalysisLabel->Data();
623  fCommonHistsResults = new AliFlowCommonHistResults(commonHistResName.Data());
624  fHistList->Add(fCommonHistsResults); 
625
626 } // end of void AliFlowAnalysisWithFittingQDistribution::BookCommonHistograms()
627
628 //================================================================================================================
629
630 void AliFlowAnalysisWithFittingQDistribution::BookAndFillWeightsHistograms()
631 {
632  // Book and fill histograms which hold phi, pt and eta weights.
633
634  if(!fWeightsList)
635  {
636   cout<<"WARNING: fWeightsList is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
637   exit(0);  
638  }
639     
640  TString fUseParticleWeightsName = "fUseParticleWeightsFQD";
641  fUseParticleWeightsName += fAnalysisLabel->Data();
642  fUseParticleWeights = new TProfile(fUseParticleWeightsName.Data(),"0 = particle weight not used, 1 = particle weight used ",3,0,3);
643  fUseParticleWeights->SetLabelSize(0.08);
644  (fUseParticleWeights->GetXaxis())->SetBinLabel(1,"w_{#phi}");
645  (fUseParticleWeights->GetXaxis())->SetBinLabel(2,"w_{p_{T}}");
646  (fUseParticleWeights->GetXaxis())->SetBinLabel(3,"w_{#eta}");
647  fUseParticleWeights->Fill(0.5,(Int_t)fUsePhiWeights);
648  fUseParticleWeights->Fill(1.5,(Int_t)fUsePtWeights);
649  fUseParticleWeights->Fill(2.5,(Int_t)fUseEtaWeights);
650  fWeightsList->Add(fUseParticleWeights); 
651  // phi weights:
652  if(fUsePhiWeights)
653  {
654   if(fWeightsList->FindObject("phi_weights"))
655   {
656    fPhiWeights = dynamic_cast<TH1F*>(fWeightsList->FindObject("phi_weights"));
657    if(TMath::Abs(fPhiWeights->GetBinWidth(1)-fPhiBinWidth)>pow(10.,-6.))
658    {
659     cout<<endl;
660     cout<<"WARNING (FQD): Inconsistent binning in histograms for phi-weights throughout the code."<<endl;
661     cout<<endl;
662     //exit(0);
663    }
664   } else 
665     {
666      cout<<"WARNING: fWeightsList->FindObject(\"phi_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
667      exit(0);
668     }
669  } // end of if(fUsePhiWeights)
670  // pt weights:
671  if(fUsePtWeights) 
672  {
673   if(fWeightsList->FindObject("pt_weights"))
674   {
675    fPtWeights = dynamic_cast<TH1D*>(fWeightsList->FindObject("pt_weights"));
676    if(TMath::Abs(fPtWeights->GetBinWidth(1)-fPtBinWidth)>pow(10.,-6.))
677    {
678     cout<<endl;
679     cout<<"WARNING (FQD): Inconsistent binning in histograms for pt-weights throughout the code."<<endl;
680     cout<<endl;
681     //exit(0);
682    }
683   } else 
684     {
685      cout<<"WARNING: fWeightsList->FindObject(\"pt_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
686      exit(0);
687     }
688  } // end of if(fUsePtWeights)    
689  // eta weights:
690  if(fUseEtaWeights) 
691  {
692   if(fWeightsList->FindObject("eta_weights"))
693   {
694    fEtaWeights = dynamic_cast<TH1D*>(fWeightsList->FindObject("eta_weights"));
695    if(TMath::Abs(fEtaWeights->GetBinWidth(1)-fEtaBinWidth)>pow(10.,-6.))
696    {
697     cout<<endl;
698     cout<<"WARNING (FQD): Inconsistent binning in histograms for eta-weights throughout the code."<<endl;
699     cout<<endl;
700     //exit(0);
701    }
702   } else 
703     {
704      cout<<"WARNING: fUseEtaWeights && fWeightsList->FindObject(\"eta_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
705      exit(0);
706     }
707  } // end of if(fUseEtaWeights)
708  
709 } // end of AliFlowAnalysisWithFittingQDistribution::BookAndFillWeightsHistograms()
710
711 //================================================================================================================================
712
713 void AliFlowAnalysisWithFittingQDistribution::AccessConstants()
714 {
715  // access needed common constants from AliFlowCommonConstants
716  
717  fnBinsPhi = AliFlowCommonConstants::GetMaster()->GetNbinsPhi();
718  fPhiMin = AliFlowCommonConstants::GetMaster()->GetPhiMin();         
719  fPhiMax = AliFlowCommonConstants::GetMaster()->GetPhiMax();
720  if(fnBinsPhi) fPhiBinWidth = (fPhiMax-fPhiMin)/fnBinsPhi;  
721  fnBinsPt = AliFlowCommonConstants::GetMaster()->GetNbinsPt();
722  fPtMin = AliFlowCommonConstants::GetMaster()->GetPtMin();           
723  fPtMax = AliFlowCommonConstants::GetMaster()->GetPtMax();
724  if(fnBinsPt) fPtBinWidth = (fPtMax-fPtMin)/fnBinsPt;  
725  fnBinsEta = AliFlowCommonConstants::GetMaster()->GetNbinsEta();
726  fEtaMin = AliFlowCommonConstants::GetMaster()->GetEtaMin();         
727  fEtaMax = AliFlowCommonConstants::GetMaster()->GetEtaMax();
728  if(fnBinsEta) fEtaBinWidth = (fEtaMax-fEtaMin)/fnBinsEta;  
729  
730 } // end of void AliFlowAnalysisWithFittingQDistribution::AccessConstants()
731
732 //================================================================================================================================
733
734 void AliFlowAnalysisWithFittingQDistribution::BookEverythingForDistributions()
735 {
736  // Book all objects relevant for fitting of q-distributions.
737  
738  // Flags:
739  TString sigmaFlag[2] = {"#sigma^{2} not fitted","#sigma^{2} fitted"};
740  // q-distribution:
741  TString fqDistributionName = "fqDistribution";
742  fqDistributionName += fAnalysisLabel->Data();
743  fqDistribution = new TH1D(Form("%s",fqDistributionName.Data()),"q-distribution",fqNbins,fqMin,fqMax);  
744  fqDistribution->SetXTitle("q_{n}=|Q_{n}|/#sqrt{M}");
745  fqDistribution->SetYTitle("Counts");
746  fHistList->Add(fqDistribution);
747  // Sum of particle weights: 
748  TString fSumOfParticleWeightsName = "fSumOfParticleWeights";
749  fSumOfParticleWeightsName += fAnalysisLabel->Data();
750  fSumOfParticleWeights = new TH1D(Form("%s",fSumOfParticleWeightsName.Data()),"Sum of particle weights",10000,0,100000); // (to be improved - harwired limits and number of bins)
751  fSumOfParticleWeights->SetXTitle("#sum_{i=1}^{N} w_{i}");
752  fSumOfParticleWeights->GetXaxis()->SetTitleSize(0.03);
753  fSumOfParticleWeights->SetYTitle("Counts");
754  fHistList->Add(fSumOfParticleWeights); 
755  // Final results for integrated flow:
756  TString fIntFlowName = "fIntFlowFQD";
757  fIntFlowName += fAnalysisLabel->Data();
758  // sigma^2:
759  TString fSigma2Name = "fSigma2";
760  fSigma2Name += fAnalysisLabel->Data();
761  // chi^2:
762  TString fChi2Name = "fChi2";
763  fChi2Name += fAnalysisLabel->Data();
764  // fitting function: 
765  TString fittingFunctionName = "fFittingFunction";
766  fittingFunctionName += fAnalysisLabel->Data();
767  
768  for(Int_t f=0;f<2;f++) // sigma^2 not fitted (0) or fitted (1)
769  {
770   // final results for integrated flow:
771   fIntFlow[f] = new TH1D(Form("%s, %s",fIntFlowName.Data(),sigmaFlag[f].Data()),Form("Reference Flow (%s)",sigmaFlag[f].Data()),1,0,1);
772   fIntFlow[f]->SetLabelSize(0.08);
773   (fIntFlow[f]->GetXaxis())->SetBinLabel(1,"v_{n}");
774   fHistList->Add(fIntFlow[f]);
775   // sigma^2:
776   fSigma2[f] = new TH1D(Form("%s, %s",fSigma2Name.Data(),sigmaFlag[f].Data()),Form("#sigma^{2} (%s)",sigmaFlag[f].Data()),1,0,1);
777   fSigma2[f]->SetLabelSize(0.08);
778   (fSigma2[f]->GetXaxis())->SetBinLabel(1,"#sigma^{2}");
779   fHistList->Add(fSigma2[f]);
780   // chi^2:
781   fChi2[f] = new TH1D(Form("%s, %s",fChi2Name.Data(),sigmaFlag[f].Data()),Form("#chi^{2} (%s)",sigmaFlag[f].Data()),1,0,1);
782   fChi2[f]->SetLabelSize(0.08);
783   (fChi2[f]->GetXaxis())->SetLabelOffset(0.01);
784   (fChi2[f]->GetXaxis())->SetBinLabel(1,"#chi^{2}");
785   fHistList->Add(fChi2[f]);
786   // fitting functions:
787   fFittingFunction[f] = new TF1(Form("%s, %s",fittingFunctionName.Data(),sigmaFlag[f].Data()),"[2]*(x/[1])*exp(-(x*x+[0]*[0])/(2.*[1]))*TMath::BesselI0(x*[0]/[1])");
788   fHistList->Add(fFittingFunction[f]);
789  } // end of for(Int_t f=0;f<2;f++) // sigma^2 not fitted or fitted 
790  // Book profile fFittingParameters which will hold all fitting parameters:
791  TString fFittingParametersName = "fFittingParameters";
792  fFittingParametersName += fAnalysisLabel->Data(); 
793  fFittingParameters = new TProfile(fFittingParametersName.Data(),"Parameters for fitting q-distribution",9,0,9);
794  fFittingParameters->SetLabelSize(0.05);
795  (fFittingParameters->GetXaxis())->SetBinLabel(1,"treshold");
796  (fFittingParameters->GetXaxis())->SetBinLabel(2,"starting v_{n}");
797  (fFittingParameters->GetXaxis())->SetBinLabel(3,"min. v_{n}");
798  (fFittingParameters->GetXaxis())->SetBinLabel(4,"max. v_{n}");
799  (fFittingParameters->GetXaxis())->SetBinLabel(5,"starting #sigma^{2}");
800  (fFittingParameters->GetXaxis())->SetBinLabel(6,"min. #sigma^{2}");
801  (fFittingParameters->GetXaxis())->SetBinLabel(7,"max. #sigma^{2}");
802  (fFittingParameters->GetXaxis())->SetBinLabel(8,"Final result is from #sigma^{2} fitted?"); 
803  (fFittingParameters->GetXaxis())->SetBinLabel(9,"Print results on the screen?"); 
804  fHistList->Add(fFittingParameters);
805  
806 } // end of void AliFlowAnalysisWithFittingQDistribution::BookEverythingForDistributions()
807
808 //================================================================================================================================
809
810 void AliFlowAnalysisWithFittingQDistribution::DoFit(Bool_t sigma2Fitted)
811 {
812  // Do the final fit of q-distribution.
813  
814  Int_t s2F = (Int_t)(sigma2Fitted); // shortcut
815  Double_t AvM = fSumOfParticleWeights->GetMean(1); // average multiplicity
816  //Int_t nEvts = (Int_t)fSumOfParticleWeights->GetEntries(); // number of events:
817  
818  // Start fitting from the bin with at least fTreshold entries, 
819  // finish fitting at the bin with at least fTreshold entries:
820  Int_t binMin = fqDistribution->FindFirstBinAbove(fTreshold);  
821  Int_t binMax = fqDistribution->FindLastBinAbove(fTreshold);
822  Double_t binWidth = fqDistribution->GetBinWidth(4); // assuming that all bins have the same width 
823  if(TMath::Abs(binWidth) < 1.e-44) 
824  {
825   cout<<endl;
826   cout<<"WARNING (FQD): binWidth == 0 in AFAWFQD::DoFit()"<<endl;
827   cout<<endl;
828   exit(0);
829  }
830  Double_t qmin = (binMin-1)*binWidth; 
831  Double_t qmax = (binMax)*binWidth;
832  Double_t ent = 0.; // number of entries between binMin and binMax:
833  for(Int_t b=binMin;b<=binMax;b++)
834  {
835   ent += fqDistribution->GetBinContent(b);
836  }
837  Double_t norm = binWidth*ent; // norm (assuming that all bins have the same width)
838  // Fitting function:
839  fFittingFunction[s2F]->SetRange(qmin,qmax); 
840  fFittingFunction[s2F]->SetParNames("v*sqrt{sum of particle weights}","sigma^2","norm");
841  fFittingFunction[s2F]->SetParameters(fvStart*pow(AvM,0.5),fSigma2Start,norm);         
842  fFittingFunction[s2F]->SetParLimits(0,fvMin*pow(AvM,0.5),fvMax*pow(AvM,0.5)); 
843  if(s2F == 0)
844  {
845   fFittingFunction[s2F]->FixParameter(1,0.5);
846  } else
847    {
848     fFittingFunction[s2F]->SetParLimits(1,fSigma2Min,fSigma2Max);          
849    }
850  fFittingFunction[s2F]->FixParameter(2,norm);  
851  // Fitting is done here:
852  // Remark: do fit only if # of entries > 50 - this is only a pragmatics fix to avoid TMinuit crash (to be improved)
853  if(ent > 50)
854  {
855   fqDistribution->Fit(fFittingFunction[s2F]->GetName(),"NQ","",qmin,qmax);
856  }
857  // Final results:
858  Double_t v = 0.; // reference flow
859  Double_t vError = 0.; // error of reference flow 
860  Double_t sigma2 = 0.; // sigma^2
861  Double_t sigma2Error = 0.; // error of sigma^2
862  Double_t chi2 = 0; // chi^2 from Minuit
863  // Reference flow:
864  if(AvM)
865  { 
866   v = fFittingFunction[s2F]->GetParameter(0)/pow(AvM,0.5);
867   vError = fFittingFunction[s2F]->GetParError(0)/pow(AvM,0.5);
868   fIntFlow[s2F]->SetBinContent(1,v); // s2F is shortcut for "sigma^2 fitted"
869   fIntFlow[s2F]->SetBinError(1,vError); // s2F is shortcut for "sigma^2 fitted"
870  } else
871    {
872     cout<<endl;
873     cout<<"WARNING (FQD): AvM == 0 in AFAWFQD::DoFit()"<<endl;
874     cout<<endl;
875    }    
876  // sigma^2:: 
877  if(s2F == 0) // sigma^2 not fitted, but fixed to 0.5
878  {
879   sigma2 = 0.5;
880   fSigma2[0]->SetBinContent(1,sigma2);  
881   fSigma2[0]->SetBinError(1,0.);
882  } else // sigma^2 fitted
883    {
884     sigma2 = fFittingFunction[s2F]->GetParameter(1);
885     sigma2Error = fFittingFunction[s2F]->GetParError(1);
886     fSigma2[1]->SetBinContent(1,sigma2);  
887     fSigma2[1]->SetBinError(1,sigma2Error);    
888    }
889  // chi^2:
890  chi2 = fFittingFunction[s2F]->GetChisquare();
891  fChi2[s2F]->SetBinContent(1,chi2);     
892  
893 } // end of void AliFlowAnalysisWithFittingQDistribution::DoFit()
894
895 //================================================================================================================================ 
896
897 void AliFlowAnalysisWithFittingQDistribution::FillCommonHistResults(Bool_t sigma2Fitted)
898 {
899  // Fill common result histogram for reference flow and resolution.
900   
901  // Remark: by default the result obtained with sigma^2 fitted is being stored. 
902  // In order to store the result obtained with sigma^2 fixed use a setter SetFinalResultIsFromSigma2Fitted(kFALSE).
903   
904  Int_t s2F = (Int_t)sigma2Fitted; // shortcut
905   
906  // Reference flow:
907  Double_t v = fIntFlow[s2F]->GetBinContent(1); 
908  Double_t vError = fIntFlow[s2F]->GetBinError(1);
909  fCommonHistsResults->FillIntegratedFlow(v,vError);   
910  // Resolution:
911  Double_t AvM = fSumOfParticleWeights->GetMean(1);
912  Double_t chi2 = AvM*pow(v,2.); // chi^2
913  if(chi2>=0.)
914  {
915   fCommonHistsResults->FillChi(pow(chi2,0.5));   
916  }
917    
918 } // end of void AliFlowAnalysisWithFittingQDistribution::FillCommonHistResultsIntFlow(Bool_t useParticleWeights, Bool_t sigma2NotFixed) 
919
920 //================================================================================================================================ 
921
922 void AliFlowAnalysisWithFittingQDistribution::PrintOnTheScreen()
923 {
924  // Print the final results on the screen.
925  
926  // shortcut for the harmonic:
927  Int_t n = 0;
928  if(fCommonHists->GetHarmonic())
929  {
930   n = (Int_t)(fCommonHists->GetHarmonic())->GetBinContent(1); 
931  }
932  
933  // printing:
934  cout<<endl;
935  cout<<"***************************************"<<endl;
936  cout<<"***************************************"<<endl;
937  cout<<"      reference flow by fitting "<<endl;
938  cout<<"           q-distribution:      "<<endl;
939  if(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)
940  {
941   cout<<"           (with weights)       "<<endl;
942  } else
943    {
944     cout<<"          (without weights)       "<<endl;
945    }   
946  cout<<endl;
947  cout<<"1.) sigma^2 not fitted: "<<endl;
948  cout<<"  v_"<<n<<"{FQD} = "<<fIntFlow[0]->GetBinContent(1)<<" +/- "<<fIntFlow[0]->GetBinError(1)<<endl;
949  cout<<"  sigma^2 = 0.5 +/- 0 "<<endl; 
950  cout<<"  chi^2 = "<<fChi2[0]->GetBinContent(1)<<" (Minuit)"<<endl; 
951  cout<<endl;   
952  if(TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMin)<1.e-10 || 
953     TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMax)<1.e-10)
954  {
955   cout<<"  WARNING: value of v_"<<n<<"{FQD}"<<" is on the boundary"<<endl;
956   cout<<"           of fitting interval. Redo the fit."<< endl;
957   cout<<endl;
958  }
959  cout<<"2.) sigma^2 fitted: "<<endl;
960  cout<<"  v_"<<n<<"{FQD} = "<<fIntFlow[1]->GetBinContent(1)<<" +/- "<<fIntFlow[1]->GetBinError(1)<<endl;
961  cout<<"  sigma^2 = "<<fSigma2[1]->GetBinContent(1)<<" +/- "<<fSigma2[1]->GetBinError(1)<<endl; 
962  cout<<"  chi^2 = "<<fChi2[1]->GetBinContent(1)<<" (Minuit)"<<endl; 
963  cout<<endl; 
964  if(TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMin)<1.e-10 || 
965     TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMax)<1.e-10)
966  {
967   cout<<"  WARNING: value of v_"<<n<<"{FQD}"<<" is on the boundary"<<endl;
968   cout<<"           of fitting interval. Redo the fit."<< endl;
969   cout<<endl;
970  }     
971  if(TMath::Abs(fSigma2[1]->GetBinContent(1)-fSigma2Min)<1.e-10 || 
972     TMath::Abs(fSigma2[1]->GetBinContent(1)-fSigma2Max)<1.e-10)
973  {
974   cout<<"  WARNING: value of sigma^2 is on the boundary"<<endl;
975   cout<<"           of fitting interval. Redo the fit."<< endl;
976   cout<<endl;
977  }     
978  cout<<"      nEvts = "<<fSumOfParticleWeights->GetEntries()<<", AvM = "<<fSumOfParticleWeights->GetMean()<<endl;
979  cout<<endl;
980  cout<<"***************************************"<<endl;
981  cout<<"***************************************"<<endl; 
982  cout<<endl;
983   
984 } // end of void AliFlowAnalysisWithFittingQDistribution::PrintOnTheScreen()
985
986 //================================================================================================================================ 
987
988 void AliFlowAnalysisWithFittingQDistribution::StoreFittingParameters()
989 {
990  // Store fitting parameters for the fit of q-distribution in profile fFittingParameters.
991  
992  if(!fFittingParameters)
993  {
994   cout<<endl;
995   cout<<"WARNING (FQD): fFittingParameters is NULL in AFAWFQD::SFP() !!!!"<<endl;
996   cout<<endl;
997   exit(0);
998  }
999  fFittingParameters->Reset();
1000  fFittingParameters->Fill(0.5,fTreshold);
1001  fFittingParameters->Fill(1.5,fvStart);
1002  fFittingParameters->Fill(2.5,fvMin);
1003  fFittingParameters->Fill(3.5,fvMax);
1004  fFittingParameters->Fill(4.5,fSigma2Start);
1005  fFittingParameters->Fill(5.5,fSigma2Min);
1006  fFittingParameters->Fill(6.5,fSigma2Max);
1007  fFittingParameters->Fill(7.5,fFinalResultIsFromSigma2Fitted); 
1008  fFittingParameters->Fill(8.5,fPrintOnTheScreen); 
1009  
1010 } // end of void AliFlowAnalysisWithFittingQDistribution::StoreFittingParameters()
1011
1012 //================================================================================================================================ 
1013
1014 void AliFlowAnalysisWithFittingQDistribution::AccessFittingParameters()
1015 {
1016  // Access fitting parameters for the fit of q-distribution.
1017
1018  fTreshold = fFittingParameters->GetBinContent(1);
1019  fvStart = fFittingParameters->GetBinContent(2);
1020  fvMin = fFittingParameters->GetBinContent(3);
1021  fvMax = fFittingParameters->GetBinContent(4);
1022  fSigma2Start = fFittingParameters->GetBinContent(5);
1023  fSigma2Min = fFittingParameters->GetBinContent(6);
1024  fSigma2Max = fFittingParameters->GetBinContent(7);
1025  fFinalResultIsFromSigma2Fitted = (Bool_t)fFittingParameters->GetBinContent(8);
1026  fPrintOnTheScreen = (Bool_t)fFittingParameters->GetBinContent(9);
1027  
1028 } // end of void AliFlowAnalysisWithFittingQDistribution::AccessFittingParameters()