1 /*************************************************************************
2 * Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /********************************
17 * integrated flow estimate by *
18 * fitting q-distribution *
20 * author: Ante Bilandzic *
23 * based on the macro written *
24 * by Sergei Voloshin *
25 *******************************/
27 #define AliFlowAnalysisWithFittingQDistribution_cxx
29 #include "Riostream.h"
30 #include "AliFlowCommonConstants.h"
31 #include "AliFlowCommonHist.h"
32 #include "AliFlowCommonHistResults.h"
38 #include "TParticle.h"
40 #include "AliFlowEventSimple.h"
41 #include "AliFlowTrackSimple.h"
42 #include "AliFlowAnalysisWithFittingQDistribution.h"
56 //================================================================================================================
58 ClassImp(AliFlowAnalysisWithFittingQDistribution)
60 AliFlowAnalysisWithFittingQDistribution::AliFlowAnalysisWithFittingQDistribution():
63 fCommonHistsResults(NULL),
79 fUsePhiWeights(kFALSE),
80 fUsePtWeights(kFALSE),
81 fUseEtaWeights(kFALSE),
82 fUseParticleWeights(NULL),
86 // fitting parameters with default values harwired here (use dedicated macro fqd.C to change them):
87 fFittingParameters(NULL),
101 // base list to hold all output objects:
102 fHistList = new TList();
103 fHistList->SetName("cobjFQD");
104 fHistList->SetOwner(kTRUE);
107 fAnalysisLabel = new TString();
109 // list to hold histograms with phi, pt and eta weights:
110 fWeightsList = new TList();
112 // initialize all arrays:
113 this->InitializeArrays();
115 } // end of constructor
118 //================================================================================================================
121 AliFlowAnalysisWithFittingQDistribution::~AliFlowAnalysisWithFittingQDistribution()
128 //================================================================================================================
131 void AliFlowAnalysisWithFittingQDistribution::Init()
133 // access constants and book everything
135 //save old value and prevent histograms from being added to directory
136 //to avoid name clashes in case multiple analaysis objects are used
138 Bool_t oldHistAddStatus = TH1::AddDirectoryStatus();
139 TH1::AddDirectory(kFALSE);
142 this->AccessConstants();
145 this->BookCommonHistograms();
146 this->BookAndFillWeightsHistograms();
147 this->BookEverythingForDistributions();
149 // store fitting parameters:
150 this->StoreFittingParameters();
153 fWeightsList->SetName("Weights");
154 fWeightsList->SetOwner(kTRUE);
155 fHistList->Add(fWeightsList);
157 // set harmonic in common control histograms (to be improved (should I do this somewhere else?)):
158 (fCommonHists->GetHarmonic())->Fill(0.5,fHarmonic);
161 TH1::AddDirectory(oldHistAddStatus);
162 } // end of void AliFlowAnalysisWithFittingQDistribution::Init()
165 //================================================================================================================
168 void AliFlowAnalysisWithFittingQDistribution::Make(AliFlowEventSimple* anEvent)
172 // a) fill the common control histograms;
173 // b) loop over data and calculate non-weighted and weighted Q-vector and sum of particle weights;
174 // c) fill histograms for q-distribution;
175 // d) reset e-b-e quantities.
177 // a) fill the common control histograms:
178 fCommonHists->FillControlHistograms(anEvent);
180 Double_t dPhi = 0.; // azimuthal angle in the laboratory frame
181 Double_t dPt = 0.; // transverse momentum
182 Double_t dEta = 0.; // pseudorapidity
184 Double_t wPhi = 1.; // phi weight
185 Double_t wPt = 1.; // pt weight
186 Double_t wEta = 1.; // eta weight
188 Int_t nPrim = anEvent->NumberOfTracks(); // nPrim = total number of primary tracks, i.e. nPrim = nRP + nPOI + rest, where:
189 // nRP = # of particles used to determine the reaction plane;
190 // nPOI = # of particles of interest for a detailed flow analysis;
191 // rest = # of particles which are not niether RPs nor POIs.
193 Int_t n = fHarmonic; // shortcut for the harmonic
195 Double_t dReQ[2] = {0.}; // real part of Q-vector [0=particle weights not used, 1=particle weights used]
196 Double_t dImQ[2] = {0.}; // imaginary part of Q-vector [0=particle weights not used, 1=particle weights used]
197 Double_t dSumOfParticleWeights[2] = {0.}; // [0=particle weights not used, 1=particle weights used]
199 AliFlowTrackSimple *aftsTrack = NULL;
201 // b) loop over data and calculate non-weighted and weighted Q-vector and sum of particle weights:
202 for(Int_t i=0;i<nPrim;i++)
204 aftsTrack=anEvent->GetTrack(i);
207 if(!(aftsTrack->InRPSelection())) continue; // consider only tracks which are RPs
209 dPhi = aftsTrack->Phi();
210 dPt = aftsTrack->Pt();
211 dEta = aftsTrack->Eta();
213 if(fUsePhiWeights && fPhiWeights && fnBinsPhi) // determine phi weight for this particle:
215 wPhi = fPhiWeights->GetBinContent(1+(Int_t)(TMath::Floor(dPhi*fnBinsPhi/TMath::TwoPi())));
217 if(fUsePtWeights && fPtWeights && fnBinsPt) // determine pt weight for this particle:
219 wPt = fPtWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-fPtMin)/fPtBinWidth)));
221 if(fUseEtaWeights && fEtaWeights && fEtaBinWidth) // determine eta weight for this particle:
223 wEta = fEtaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-fEtaMin)/fEtaBinWidth)));
226 // calculate real and imaginary part of non-weighted and weighted Q-vector and sum of particle weights for this event:
227 for(Int_t pW=0;pW<1+(Int_t)(fUsePhiWeights||fUsePtWeights||fUseEtaWeights);pW++) // particle weights not used (0) or used (1)
230 dReQ[pW]+=pow(wPhi*wPt*wEta,pW)*TMath::Cos(n*dPhi);
231 dImQ[pW]+=pow(wPhi*wPt*wEta,pW)*TMath::Sin(n*dPhi);
232 // sum of particle weights:
233 dSumOfParticleWeights[pW] += pow(wPhi*wPt*wEta,pW); // if pW = 0, this sum gives # of RPs, i.e. multiplicity
236 } // end of if(aftsTrack)
237 } // end of for(Int_t i=0;i<nPrim;i++)
239 // c) fill histograms for q-distribution:
240 // calculating first q = Q\sqrt{sum of particle weights} (Remark: if particle weights are unit than sum of particle weights = multiplicity)
242 for(Int_t pW=0;pW<1+(Int_t)(fUsePhiWeights||fUsePtWeights||fUseEtaWeights);pW++) // particle weights not used (0) or used (1)
244 if(dSumOfParticleWeights[pW])
246 q = pow(dReQ[pW]*dReQ[pW]+dImQ[pW]*dImQ[pW],0.5)/pow(dSumOfParticleWeights[pW],0.5);
248 fqDistribution[pW]->Fill(q,1.);
249 fSumOfParticleWeights[pW]->Fill(dSumOfParticleWeights[pW],1.);
253 // d) reset e-b-e quantities:
254 for(Int_t pW=0;pW<1+(Int_t)(fUsePhiWeights||fUsePtWeights||fUseEtaWeights);pW++) // particle weights not used (0) or used (1)
258 dSumOfParticleWeights[pW] = 0.;
264 //================================================================================================================
267 void AliFlowAnalysisWithFittingQDistribution::Finish(Bool_t doFit)
269 // calculate the final results
271 // a) acces the constants and all fitting paremeters;
272 // b) access the flags for particle weights;
274 // d) fill common hist results;
275 // e) print on the screen the final results.
277 // a) access the constants and all fitting paremeters:
278 this->AccessConstants();
279 this->AccessFittingParameters();
281 // b) access the flags for particle weights:
282 fUsePhiWeights = (Bool_t)fUseParticleWeights->GetBinContent(1);
283 fUsePtWeights = (Bool_t)fUseParticleWeights->GetBinContent(2);
284 fUseEtaWeights = (Bool_t)fUseParticleWeights->GetBinContent(3);
286 // to be improved (moved somewhere else):
289 fLegend = new TLegend(0.6,0.55,0.85,0.7);
295 // particle weights not used:
296 // 1) sigma^2 not fitted (fixed to 0.5):
297 this->DoFit(kFALSE,kFALSE);
298 // 2) sigma^2 fitted:
299 this->DoFit(kFALSE,kTRUE);
300 // particle weights used:
301 if(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)
303 // 1) sigma^2 not fitted (fixed to 0.5):
304 this->DoFit(kTRUE,kFALSE);
305 // 2) sigma^2 fitted:
306 this->DoFit(kTRUE,kTRUE);
309 // d) fill common hist results (by default fill results obtained with sigma^2 fitted):
310 if(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)
312 this->FillCommonHistResultsIntFlow(kTRUE,kTRUE);
315 this->FillCommonHistResultsIntFlow(kFALSE,kTRUE);
318 // e) print on the screen the final results:
319 this->PrintFinalResultsForIntegratedFlow();
321 } // end of if(doFit)
323 } // end of void AliFlowAnalysisWithFittingQDistribution::Finish(Bool_t doFit)
326 //================================================================================================================
329 void AliFlowAnalysisWithFittingQDistribution::GetOutputHistograms(TList *outputListHistos)
331 // get pointers to all output histograms (called before Finish())
335 // 1.) common control histograms and common histograms for final results:
336 TString commonHistName = "AliFlowCommonHistFQD";
337 commonHistName += fAnalysisLabel->Data();
338 AliFlowCommonHist *commonHist = dynamic_cast<AliFlowCommonHist*>(outputListHistos->FindObject(commonHistName.Data()));
339 if(commonHist) this->SetCommonHists(commonHist);
341 TString commonHistResName = "AliFlowCommonHistResultsFQD";
342 commonHistResName += fAnalysisLabel->Data();
343 AliFlowCommonHistResults *commonHistRes = dynamic_cast<AliFlowCommonHistResults*>
344 (outputListHistos->FindObject(commonHistResName.Data()));
345 if(commonHistRes) this->SetCommonHistsResults(commonHistRes);
348 TList *weightsList = dynamic_cast<TList*>(outputListHistos->FindObject("Weights"));
349 if(weightsList) this->SetWeightsList(weightsList);
350 Bool_t bUsePhiWeights = kFALSE;
351 Bool_t bUsePtWeights = kFALSE;
352 Bool_t bUseEtaWeights = kFALSE;
353 TString fUseParticleWeightsName = "fUseParticleWeightsFQD";
354 fUseParticleWeightsName += fAnalysisLabel->Data();
355 TProfile *useParticleWeights = dynamic_cast<TProfile*>(weightsList->FindObject(fUseParticleWeightsName.Data()));
356 if(useParticleWeights)
358 this->SetUseParticleWeights(useParticleWeights);
359 bUsePhiWeights = (Int_t)useParticleWeights->GetBinContent(1);
360 bUsePtWeights = (Int_t)useParticleWeights->GetBinContent(2);
361 bUseEtaWeights = (Int_t)useParticleWeights->GetBinContent(3);
364 // 3.) distributions and 4.) final results of fitting:
365 TString pWeightsFlag[2] = {"pWeights not used","pWeights used"};
366 TString sigmaFlag[2] = {"#sigma^{2} not fitted","#sigma^{2} fitted"};
369 TString qDistributionName = "fqDistribution";
370 qDistributionName += fAnalysisLabel->Data();
371 // sum of particle weights:
372 TString sumOfParticleWeightsName = "fSumOfParticleWeightsName";
373 sumOfParticleWeightsName += fAnalysisLabel->Data();
374 // final results for integrated flow:
375 TString intFlowName = "fIntFlowFQD";
376 intFlowName += fAnalysisLabel->Data();
378 TString sigma2Name = "fSigma2";
379 sigma2Name += fAnalysisLabel->Data();
381 TString chi2Name = "fChi2";
382 chi2Name += fAnalysisLabel->Data();
384 TH1D *qDistribution[2] = {NULL};
385 TH1D *sumOfParticleWeights[2] = {NULL};
386 TH1D *intFlow[2][2] = {{NULL}};
387 TH1D *sigma2[2][2] = {{NULL}};
388 TH1D *chi2[2][2] = {{NULL}};
390 for(Int_t pW=0;pW<1+(Int_t)(bUsePhiWeights||bUsePtWeights||bUseEtaWeights);pW++)
393 qDistribution[pW] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",qDistributionName.Data(),pWeightsFlag[pW].Data())));
394 if(qDistribution[pW])
396 this->SetqDistribution(qDistribution[pW],pW);
399 cout<<"WARNING: qDistribution[pW] is NULL in AFAWFQD::GOH() !!!!"<<endl;
400 cout<<"pW = "<<pW<<endl;
402 // sum of particle weights:
403 sumOfParticleWeights[pW] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",sumOfParticleWeightsName.Data(),pWeightsFlag[pW].Data())));
404 if(sumOfParticleWeights[pW])
406 this->SetSumOfParticleWeights(sumOfParticleWeights[pW],pW);
409 cout<<"WARNING: sumOfParticleWeights[pW] is NULL in AFAWFQD::GOH() !!!!"<<endl;
410 cout<<"pW = "<<pW<<endl;
413 for(Int_t f=0;f<2;f++)
415 // final results for integrated flow:
416 intFlow[pW][f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s, %s",intFlowName.Data(),pWeightsFlag[pW].Data(),sigmaFlag[f].Data())));
419 this->SetIntFlow(intFlow[pW][f],pW,f);
422 cout<<"WARNING: intFlow[pW][f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
423 cout<<"pW = "<<pW<<endl;
424 cout<<"f = "<<f<<endl;
427 sigma2[pW][f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s, %s",sigma2Name.Data(),pWeightsFlag[pW].Data(),sigmaFlag[f].Data())));
430 this->SetSigma2(sigma2[pW][f],pW,f);
433 cout<<"WARNING: sigma2[pW][f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
434 cout<<"pW = "<<pW<<endl;
435 cout<<"f = "<<f<<endl;
438 chi2[pW][f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s, %s",chi2Name.Data(),pWeightsFlag[pW].Data(),sigmaFlag[f].Data())));
441 this->SetChi2(chi2[pW][f],pW,f);
444 cout<<"WARNING: chi2[pW][f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
445 cout<<"pW = "<<pW<<endl;
446 cout<<"f = "<<f<<endl;
449 } // end of for(Int_t f=0;f<2;f++)
450 } // end of for(Int_t pW=0;pW<1+(Int_t)(bUsePhiWeights||bUsePtWeights||bUseEtaWeights);pW++)
452 // 5.) fitting parameters:
454 TString fittingParametersName = "fFittingParameters";
455 fittingParametersName += fAnalysisLabel->Data();
456 TProfile *fittingParameters = NULL;
457 fittingParameters = dynamic_cast<TProfile*>(outputListHistos->FindObject(fittingParametersName.Data()));
458 if(fittingParameters)
460 this->SetFittingParameters(fittingParameters);
463 cout<<"WARNING:fittingParameters is NULL in AFAWFQD::GOH() !!!!"<<endl;
466 } else // to if(outputListHistos)
468 cout<<"WARNING: outputListHistos is NULL in AFAWFQD::GOH() !!!!"<<endl;
473 } // end of void AliFlowAnalysisWithFittingQDistribution::GetOutputHistograms(TList *outputListHistos)
476 //================================================================================================================
479 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TString* outputFileName)
481 //store the final results in output .root file
482 TFile *output = new TFile(outputFileName->Data(),"RECREATE");
483 //output->WriteObject(fHistList, "cobjFQD","SingleKey");
484 fHistList->SetName("cobjFQD");
485 fHistList->SetOwner(kTRUE);
486 fHistList->Write(fHistList->GetName(), TObject::kSingleKey);
490 //================================================================================================================
492 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TString outputFileName)
494 //store the final results in output .root file
495 TFile *output = new TFile(outputFileName.Data(),"RECREATE");
496 //output->WriteObject(fHistList, "cobjFQD","SingleKey");
497 fHistList->SetName("cobjFQD");
498 fHistList->SetOwner(kTRUE);
499 fHistList->Write(fHistList->GetName(), TObject::kSingleKey);
504 //================================================================================================================
507 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TDirectoryFile *outputFileName)
509 //store the final results in output .root file
510 fHistList->SetName("cobjFQD");
511 fHistList->SetOwner(kTRUE);
512 outputFileName->Add(fHistList);
513 outputFileName->Write(outputFileName->GetName(), TObject::kSingleKey);
517 //================================================================================================================
520 void AliFlowAnalysisWithFittingQDistribution::InitializeArrays()
522 // initialize all arrays
524 for(Int_t pW=0;pW<2;pW++) // particle weights not used (0) or used (1)
526 fSumOfParticleWeights[pW] = NULL;
527 fqDistribution[pW] = NULL;
528 for(Int_t f=0;f<2;f++) // sigma^2 not fitted (0) or fitted (1)
530 fIntFlow[pW][f] = NULL;
531 fSigma2[pW][f] = NULL;
536 } // end of void AliFlowAnalysisWithFittingQDistribution::InitializeArrays()
539 //================================================================================================================
542 void AliFlowAnalysisWithFittingQDistribution::BookCommonHistograms()
544 // book common histograms
546 // common control histogram:
547 TString commonHistName = "AliFlowCommonHistFQD";
548 commonHistName += fAnalysisLabel->Data();
549 fCommonHists = new AliFlowCommonHist(commonHistName.Data());
550 fHistList->Add(fCommonHists);
552 // common histograms for final results:
553 TString commonHistResName = "AliFlowCommonHistResultsFQD";
554 commonHistResName += fAnalysisLabel->Data();
555 fCommonHistsResults = new AliFlowCommonHistResults(commonHistResName.Data());
556 fHistList->Add(fCommonHistsResults);
558 } // end of void AliFlowAnalysisWithFittingQDistribution::BookCommonHistograms()
561 //================================================================================================================
564 void AliFlowAnalysisWithFittingQDistribution::BookAndFillWeightsHistograms()
566 // book and fill histograms which hold phi, pt and eta weights
570 cout<<"WARNING: fWeightsList is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
574 TString fUseParticleWeightsName = "fUseParticleWeightsFQD";
575 fUseParticleWeightsName += fAnalysisLabel->Data();
576 fUseParticleWeights = new TProfile(fUseParticleWeightsName.Data(),"0 = particle weight not used, 1 = particle weight used ",3,0,3);
577 fUseParticleWeights->SetLabelSize(0.08);
578 (fUseParticleWeights->GetXaxis())->SetBinLabel(1,"w_{#phi}");
579 (fUseParticleWeights->GetXaxis())->SetBinLabel(2,"w_{p_{T}}");
580 (fUseParticleWeights->GetXaxis())->SetBinLabel(3,"w_{#eta}");
581 fUseParticleWeights->Fill(0.5,(Int_t)fUsePhiWeights);
582 fUseParticleWeights->Fill(1.5,(Int_t)fUsePtWeights);
583 fUseParticleWeights->Fill(2.5,(Int_t)fUseEtaWeights);
584 fWeightsList->Add(fUseParticleWeights);
588 if(fWeightsList->FindObject("phi_weights"))
590 fPhiWeights = dynamic_cast<TH1F*>(fWeightsList->FindObject("phi_weights"));
591 if(fPhiWeights->GetBinWidth(1) != fPhiBinWidth)
593 cout<<"WARNING: fPhiWeights->GetBinWidth(1) != fPhiBinWidth in AFAWFQD::BAFWH() !!!! "<<endl;
594 cout<<" This indicates inconsistent binning in phi histograms throughout the code."<<endl;
599 cout<<"WARNING: fWeightsList->FindObject(\"phi_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
602 } // end of if(fUsePhiWeights)
606 if(fWeightsList->FindObject("pt_weights"))
608 fPtWeights = dynamic_cast<TH1D*>(fWeightsList->FindObject("pt_weights"));
609 if(fPtWeights->GetBinWidth(1) != fPtBinWidth)
611 cout<<"WARNING: fPtWeights->GetBinWidth(1) != fPtBinWidth in AFAWFQD::BAFWH() !!!! "<<endl;
612 cout<<" This indicates insconsistent binning in pt histograms throughout the code."<<endl;
617 cout<<"WARNING: fWeightsList->FindObject(\"pt_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
620 } // end of if(fUsePtWeights)
624 if(fWeightsList->FindObject("eta_weights"))
626 fEtaWeights = dynamic_cast<TH1D*>(fWeightsList->FindObject("eta_weights"));
627 if(fEtaWeights->GetBinWidth(1) != fEtaBinWidth)
629 cout<<"WARNING: fEtaWeights->GetBinWidth(1) != fEtaBinWidth in AFAWFQD::BAFWH() !!!! "<<endl;
630 cout<<" This indicates insconsistent binning in eta histograms throughout the code."<<endl;
635 cout<<"WARNING: fUseEtaWeights && fWeightsList->FindObject(\"eta_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
638 } // end of if(fUseEtaWeights)
640 } // end of AliFlowAnalysisWithFittingQDistribution::BookAndFillWeightsHistograms()
643 //================================================================================================================================
646 void AliFlowAnalysisWithFittingQDistribution::AccessConstants()
648 // access needed common constants from AliFlowCommonConstants
650 fnBinsPhi = AliFlowCommonConstants::GetMaster()->GetNbinsPhi();
651 fPhiMin = AliFlowCommonConstants::GetMaster()->GetPhiMin();
652 fPhiMax = AliFlowCommonConstants::GetMaster()->GetPhiMax();
653 if(fnBinsPhi) fPhiBinWidth = (fPhiMax-fPhiMin)/fnBinsPhi;
654 fnBinsPt = AliFlowCommonConstants::GetMaster()->GetNbinsPt();
655 fPtMin = AliFlowCommonConstants::GetMaster()->GetPtMin();
656 fPtMax = AliFlowCommonConstants::GetMaster()->GetPtMax();
657 if(fnBinsPt) fPtBinWidth = (fPtMax-fPtMin)/fnBinsPt;
658 fnBinsEta = AliFlowCommonConstants::GetMaster()->GetNbinsEta();
659 fEtaMin = AliFlowCommonConstants::GetMaster()->GetEtaMin();
660 fEtaMax = AliFlowCommonConstants::GetMaster()->GetEtaMax();
661 if(fnBinsEta) fEtaBinWidth = (fEtaMax-fEtaMin)/fnBinsEta;
663 } // end of void AliFlowAnalysisWithFittingQDistribution::AccessConstants()
666 //================================================================================================================================
669 void AliFlowAnalysisWithFittingQDistribution::BookEverythingForDistributions()
671 // book histograms for distributions
673 TString pWeightsFlag[2] = {"pWeights not used","pWeights used"};
674 TString sigmaFlag[2] = {"#sigma^{2} not fitted","#sigma^{2} fitted"};
676 TString fqDistributionName = "fqDistribution";
677 fqDistributionName += fAnalysisLabel->Data();
678 // sum of particle weights:
679 TString fSumOfParticleWeightsName = "fSumOfParticleWeightsName";
680 fSumOfParticleWeightsName += fAnalysisLabel->Data();
681 // final results for integrated flow:
682 TString fIntFlowName = "fIntFlowFQD";
683 fIntFlowName += fAnalysisLabel->Data();
685 TString fSigma2Name = "fSigma2";
686 fSigma2Name += fAnalysisLabel->Data();
688 TString fChi2Name = "fChi2";
689 fChi2Name += fAnalysisLabel->Data();
691 for(Int_t pW=0;pW<1+(Int_t)(fUsePhiWeights||fUsePtWeights||fUseEtaWeights);pW++) // particle weights not used (0) or used (1)
694 fqDistribution[pW] = new TH1D(Form("%s, %s",fqDistributionName.Data(),pWeightsFlag[pW].Data()),"q-distribution",10000,0,1000);
695 fqDistribution[pW]->SetXTitle("q_{n}=Q_{n}/#sqrt{M}");
696 fqDistribution[pW]->SetYTitle("Counts");
697 fHistList->Add(fqDistribution[pW]);
698 // sum of particle weights:
699 fSumOfParticleWeights[pW] = new TH1D(Form("%s, %s",fSumOfParticleWeightsName.Data(),pWeightsFlag[pW].Data()),"Sum of particle weights",10000,0,10000);
700 fSumOfParticleWeights[pW]->SetXTitle("#sum_{i=1}^{N} w_{i}");
701 fSumOfParticleWeights[pW]->SetYTitle("Counts");
702 fHistList->Add(fSumOfParticleWeights[pW]);
704 for(Int_t f=0;f<2;f++) // sigma^2 not fitted (0) or fitted (1)
706 // final results for integrated flow:
707 fIntFlow[pW][f] = new TH1D(Form("%s, %s, %s",fIntFlowName.Data(),pWeightsFlag[pW].Data(),sigmaFlag[f].Data()),"Integrated Flow",1,0,1);
708 fIntFlow[pW][f]->SetLabelSize(0.08);
709 (fIntFlow[pW][f]->GetXaxis())->SetBinLabel(1,"v_{n}");
710 fHistList->Add(fIntFlow[pW][f]);
712 fSigma2[pW][f] = new TH1D(Form("%s, %s, %s",fSigma2Name.Data(),pWeightsFlag[pW].Data(),sigmaFlag[f].Data()),"#sigma^{2}",1,0,1);
713 fSigma2[pW][f]->SetLabelSize(0.08);
714 (fSigma2[pW][f]->GetXaxis())->SetBinLabel(1,"#sigma^{2}");
715 fHistList->Add(fSigma2[pW][f]);
717 fChi2[pW][f] = new TH1D(Form("%s, %s, %s",fChi2Name.Data(),pWeightsFlag[pW].Data(),sigmaFlag[f].Data()),"#chi^{2} (Minuit)",1,0,1);
718 fChi2[pW][f]->SetLabelSize(0.08);
719 (fChi2[pW][f]->GetXaxis())->SetLabelOffset(0.01);
720 (fChi2[pW][f]->GetXaxis())->SetBinLabel(1,"#chi^{2}");
721 fHistList->Add(fChi2[pW][f]);
722 } // end of for(Int_t f=0;f<2;f++) // sigma^2 not fitted or fitted
724 } // end of for(Int_t pW=0;pW<1+(Int_t)(fUsePhiWeights||fUsePtWeights||fUseEtaWeights);pW++) // particle weights not used (0) or used (1)
726 // book profile fFittingParameters which will hold all fitting parameters:
727 TString fFittingParametersName = "fFittingParameters";
728 fFittingParametersName += fAnalysisLabel->Data();
729 fFittingParameters = new TProfile(fFittingParametersName.Data(),"Parameters for fitting q-distribution",8,0,8);
730 fFittingParameters->SetLabelSize(0.05);
731 (fFittingParameters->GetXaxis())->SetBinLabel(1,"treshold");
732 (fFittingParameters->GetXaxis())->SetBinLabel(2,"starting v_{n}");
733 (fFittingParameters->GetXaxis())->SetBinLabel(3,"min. v_{n}");
734 (fFittingParameters->GetXaxis())->SetBinLabel(4,"max. v_{n}");
735 (fFittingParameters->GetXaxis())->SetBinLabel(5,"starting #sigma^{2}");
736 (fFittingParameters->GetXaxis())->SetBinLabel(6,"min. #sigma^{2}");
737 (fFittingParameters->GetXaxis())->SetBinLabel(7,"max. #sigma^{2}");
738 (fFittingParameters->GetXaxis())->SetBinLabel(8,"plot or not?");
739 fHistList->Add(fFittingParameters);
741 } // end of void AliFlowAnalysisWithFittingQDistribution::BookEverythingForDistributions()
744 //================================================================================================================================
747 void AliFlowAnalysisWithFittingQDistribution::DoFit(Bool_t useParticleWeights, Bool_t sigma2Fitted)
749 // do final fit for q-distribution
751 // shortcuts for flags:
752 Int_t pW = (Int_t)(useParticleWeights);
753 Int_t s2F = (Int_t)(sigma2Fitted);
755 if(!(fqDistribution[pW] && fSumOfParticleWeights[pW] && fIntFlow[pW][s2F] && fSigma2[pW][s2F] && fChi2[pW][s2F]))
757 cout<<"WARNING: fqDistribution[pW] && fSumOfParticleWeights[pW] && fIntFlow[pW][s2F] && fSigma2[pW][s2F] && fChi2[pW][s2F] is NULL in AFAWFQD::DoFit() !!!!"<<endl;
758 cout<<"pW = "<<pW<<endl;
759 cout<<"s2F = "<<s2F<<endl;
763 // average multiplicity and number of events:
764 Double_t AvM = fSumOfParticleWeights[pW]->GetMean(1);
765 //Int_t nEvts = (Int_t)fSumOfParticleWeights[pW]->GetEntries();
767 // start fitting from the bin with at least fTreshold entries,
768 // finish fitting at the bin with at least fTreshold entries:
769 Int_t binMin = fqDistribution[pW]->FindFirstBinAbove(fTreshold);
770 Int_t binMax = fqDistribution[pW]->FindLastBinAbove(fTreshold);
771 Double_t binWidth = fqDistribution[pW]->GetBinWidth(4); // assuming that all bins have the same width
774 cout<<"WARNING: binWidth == 0 in AFAWFQD::DoFit()"<<endl;
777 Double_t qmin = (binMin-1)*binWidth;
778 Double_t qmax = (binMax)*binWidth;
779 Double_t ent = 0.; // number of entries between binMin and binMax:
780 for(Int_t b=binMin;b<=binMax;b++)
782 ent += fqDistribution[pW]->GetBinContent(b);
784 Double_t norm = binWidth*ent; // norm (assuming that all bins have the same width)
787 TF1 *fittingFun = new TF1("fittingFun","[2]*(x/[1])*exp(-(x*x+[0]*[0])/(2.*[1]))*TMath::BesselI0(x*[0]/[1])",qmin,qmax);
789 fittingFun->SetParNames("v*sqrt{sum of particle weights}","sigma^2","norm");
790 fittingFun->SetParameters(fvStart*pow(AvM,0.5),fSigma2Start,norm);
791 fittingFun->SetParLimits(0,fvMin*pow(AvM,0.5),fvMax*pow(AvM,0.5));
795 fittingFun->FixParameter(1,0.5);
798 fittingFun->SetParLimits(1,fSigma2Min,fSigma2Max);
800 fittingFun->FixParameter(2,norm);
802 // fitting (do it only if # of entries >50): // to be improved (this is only a pragmatics fix to avoid TMinuit crash)
805 fqDistribution[pW]->Fit("fittingFun","NQ","",qmin,qmax);
808 Double_t v = 0.; // integrated flow
809 Double_t vError = 0.; // error of integrated flow
810 Double_t sigma2 = 0.; // sigma^2
811 Double_t sigma2Error = 0.; // error of sigma^2
812 Double_t chi2 = 0; // chi^2 from Minuit
817 v = fittingFun->GetParameter(0)/pow(AvM,0.5);
818 vError = fittingFun->GetParError(0)/pow(AvM,0.5);
819 fIntFlow[pW][s2F]->SetBinContent(1,v); // s2F is shortcut for "sigma^2 fitted"
820 fIntFlow[pW][s2F]->SetBinError(1,vError); // s2F is shortcut for "sigma^2 fitted"
823 if(s2F == 0) // sigma^2 not fitted, but fixed to 0.5
827 fSigma2[pW][0]->SetBinContent(1,sigma2);
828 fSigma2[pW][0]->SetBinError(1,0.);
830 chi2 = fittingFun->GetChisquare();
831 fChi2[pW][0]->SetBinContent(1,chi2);
832 //fChi2[pW][0]->SetBinError(1,0.);
833 } else // sigma^2 fitted
836 sigma2 = fittingFun->GetParameter(1);
837 sigma2Error = fittingFun->GetParError(1);
838 fSigma2[pW][1]->SetBinContent(1,sigma2);
839 fSigma2[pW][1]->SetBinError(1,sigma2Error);
841 chi2 = fittingFun->GetChisquare();
842 fChi2[pW][1]->SetBinContent(1,chi2);
843 //fChi2[pW][1]->SetBinError(1,0.);
846 if(fPlotResults && !(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)) // to be improved (plot also the plot when particle weights are used)
848 // set ranges: // to be improved (there is certainly a better way to implement this)
849 Int_t firstNonEmptyBin = fqDistribution[pW]->FindFirstBinAbove(0);
850 Double_t lowRange = fqDistribution[pW]->GetBinLowEdge(firstNonEmptyBin);
851 Int_t lastNonEmptyBin = fqDistribution[pW]->FindLastBinAbove(0);
852 Double_t upperRange = fqDistribution[pW]->GetBinLowEdge(lastNonEmptyBin+10);
853 (fqDistribution[pW]->GetXaxis())->SetRangeUser(lowRange,upperRange);
857 // to be improved (there is certainly a better way to implement this)
858 fqDistribution[pW]->SetFillColor(16);
859 fqDistribution[pW]->SetTitle("Fitted q-distribution");
860 fqDistribution[pW]->Draw("");
861 fLegend->AddEntry(fqDistribution[pW],"q-distribution","f");
862 TF1 *fittingFunTemp = (TF1*)fittingFun->Clone("fittingFunTemp");
863 fittingFunTemp->SetLineColor(4); // 4 = blue color
864 fittingFunTemp->Draw("SAME");
865 fLegend->AddEntry("fittingFunTemp","#sigma^{2} fixed","l");
866 fLegend->Draw("SAME");
869 fittingFun->SetLineColor(2); // 2 = red color
870 fittingFun->Draw("SAME");
871 fLegend->AddEntry("fittingFun","#sigma^{2} fitted","l");
873 } // end of if(fPlotResults)
875 } // end of void AliFlowAnalysisWithFittingQDistribution::DoFit(Bool_t useParticleWeights)
878 //================================================================================================================================
881 void AliFlowAnalysisWithFittingQDistribution::FillCommonHistResultsIntFlow(Bool_t useParticleWeights, Bool_t sigma2Fitted)
883 // fill in AliFlowCommonHistResults histograms relevant for 'NONAME' integrated flow (to be improved (name))
885 // shortcuts for the flags:
886 Int_t pW = (Int_t)(useParticleWeights); // particle weights not used (0) or used (1)
887 Int_t s2F = (Int_t)(sigma2Fitted); // 0 = sigma^2 not fitted (but fixed to 0.5), 1 = sigma^2 fitted
889 if(!fIntFlow[pW][s2F])
891 cout<<"WARNING: fIntFlow[pW][s2F] is NULL in AFAWFQD::FCHRIF() !!!!"<<endl;
892 cout<<"pW = "<<pW<<endl;
893 cout<<"s2F = "<<s2F<<endl;
897 if(!fSumOfParticleWeights[pW])
899 cout<<"WARNING: fSumOfParticleWeights[pW] is NULL in AFAWFQD::FCHRIF() !!!!"<<endl;
900 cout<<"pW = "<<pW<<endl;
904 if(!(fCommonHistsResults))
906 cout<<"WARNING: fCommonHistsResults is NULL in AFAWFQD::FCHRIF() !!!!"<<endl;
910 // fill integrated flow:
911 Double_t v = fIntFlow[pW][s2F]->GetBinContent(1);
912 Double_t vError = fIntFlow[pW][s2F]->GetBinError(1);
914 fCommonHistsResults->FillIntegratedFlow(v,vError);
916 // fill chi (this chi stands for resolution, not to be confused with chi2 used before):
917 Double_t AvM = fSumOfParticleWeights[pW]->GetMean(1);
918 Double_t chi = AvM*pow(v,2);
921 fCommonHistsResults->FillChi(pow(chi,0.5));
922 fCommonHistsResults->FillChiRP(pow(chi,0.5));
925 } // end of void AliFlowAnalysisWithFittingQDistribution::FillCommonHistResultsIntFlow(Bool_t useParticleWeights, Bool_t sigma2NotFixed)
928 //================================================================================================================================
931 void AliFlowAnalysisWithFittingQDistribution::PrintFinalResultsForIntegratedFlow()
933 // print the final results for integrated flow on the screen
935 // shortcuts: pW = particle weights
936 // s2F = sigma^2 fitted
938 for(Int_t pW=0;pW<1+(Int_t)(fUsePhiWeights||fUsePtWeights||fUseEtaWeights);pW++)
940 if(!fSumOfParticleWeights[pW])
942 cout<<"WARNING: fSumOfParticleWeights[pW] is NULL in AFAWFQD::FCHRIF() !!!!"<<endl;
943 cout<<"pW = "<<pW<<endl;
946 for(Int_t s2F=0;s2F<2;s2F++)
948 if(!fIntFlow[pW][s2F])
950 cout<<"WARNING: fIntFlow[pW][s2F] is NULL in AFAWFQD::FCHRIF() !!!!"<<endl;
951 cout<<"pW = "<<pW<<endl;
952 cout<<"s2F = "<<s2F<<endl;
958 if(!(fCommonHistsResults))
960 cout<<"WARNING: fCommonHistsResults is NULL in AFAWFQD::FCHRIF() !!!!"<<endl;
964 // shortcut for the harmonic:
966 if(fCommonHists->GetHarmonic())
968 n = (Int_t)(fCommonHists->GetHarmonic())->GetBinContent(1);
973 cout<<"***************************************"<<endl;
974 cout<<"***************************************"<<endl;
975 cout<<" integrated flow by fitting "<<endl;
976 cout<<" q-distribution: "<<endl;
977 if(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)
979 cout<<" (with weights) "<<endl;
982 cout<<" (without weights) "<<endl;
986 if(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)
988 cout<<"1.) sigma^2 not fitted: "<<endl;
989 cout<<" v_"<<n<<"{FQD} = "<<fIntFlow[1][0]->GetBinContent(1)<<" +/- "<<fIntFlow[1][0]->GetBinError(1)<<endl;
990 cout<<" sigma^2 = 0.5 +/- 0 "<<endl;
991 cout<<" chi^2 = "<<fChi2[1][0]->GetBinContent(1)<<" (Minuit)"<<endl;
993 cout<<"2.) sigma^2 fitted: "<<endl;
994 cout<<" v_"<<n<<"{FQD} = "<<fIntFlow[1][1]->GetBinContent(1)<<" +/- "<<fIntFlow[1][1]->GetBinError(1)<<endl;
995 cout<<" sigma^2 = "<<fSigma2[1][1]->GetBinContent(1)<<" +/- "<<fSigma2[1][1]->GetBinError(1)<<endl;
996 cout<<" chi^2 = "<<fChi2[1][1]->GetBinContent(1)<<" (Minuit)"<<endl;
998 cout<<" nEvts = "<<fSumOfParticleWeights[1]->GetEntries()<<", AvM = "<<fSumOfParticleWeights[1]->GetMean()<<endl;
1002 cout<<"1.) sigma^2 not fitted: "<<endl;
1004 cout<<" v_"<<n<<"{FQD} = "<<fIntFlow[0][0]->GetBinContent(1)<<" +/- "<<fIntFlow[0][0]->GetBinError(1)<<endl;
1005 cout<<" sigma^2 = 0.5 +/- 0 "<<endl;
1006 cout<<" chi^2 = "<<fChi2[0][0]->GetBinContent(1)<<" (Minuit)"<<endl;
1008 cout<<"2.) sigma^2 fitted: "<<endl;
1010 cout<<" v_"<<n<<"{FQD} = "<<fIntFlow[0][1]->GetBinContent(1)<<" +/- "<<fIntFlow[0][1]->GetBinError(1)<<endl;
1011 cout<<" sigma^2 = "<<fSigma2[0][1]->GetBinContent(1)<<" +/- "<<fSigma2[0][1]->GetBinError(1)<<endl;
1012 cout<<" chi^2 = "<<fChi2[0][1]->GetBinContent(1)<<" (Minuit)"<<endl;
1014 cout<<" nEvts = "<<fSumOfParticleWeights[0]->GetEntries()<<", AvM = "<<fSumOfParticleWeights[0]->GetMean()<<endl;
1018 cout<<"***************************************"<<endl;
1019 cout<<"***************************************"<<endl;
1022 } // end of void AliFlowAnalysisWithFittingQDistribution::PrintFinalResultsForIntegratedFlow()
1025 //================================================================================================================================
1028 void AliFlowAnalysisWithFittingQDistribution::StoreFittingParameters()
1030 // store fitting parameters in profile fFittingParameters
1032 // Binning of fFittingParameters is organized as follows:
1033 // 1st bin: fTreshold
1037 // 5th bin: fSigma2Start
1038 // 6th bin: fSigma2Min
1039 // 7th bin: fSigma2Max
1040 // 8th bin: fPlotResults
1042 if(!fFittingParameters)
1044 cout<<"WARNING: fFittingParameters is NULL in AFAWFQD::SFP() !!!!"<<endl;
1048 fFittingParameters->Reset();
1049 fFittingParameters->Fill(0.5,fTreshold);
1050 fFittingParameters->Fill(1.5,fvStart);
1051 fFittingParameters->Fill(2.5,fvMin);
1052 fFittingParameters->Fill(3.5,fvMax);
1053 fFittingParameters->Fill(4.5,fSigma2Start);
1054 fFittingParameters->Fill(5.5,fSigma2Min);
1055 fFittingParameters->Fill(6.5,fSigma2Max);
1056 fFittingParameters->Fill(7.5,(Int_t)fPlotResults);
1058 } // end of void AliFlowAnalysisWithFittingQDistribution::StoreFittingParameters()
1061 //================================================================================================================================
1064 void AliFlowAnalysisWithFittingQDistribution::AccessFittingParameters()
1066 // access fitting parameters:
1068 if(!fFittingParameters)
1070 cout<<"WARNING: fFittingParameters is NULL in AFAWFQD::AFP() !!!!"<<endl;
1074 fTreshold = fFittingParameters->GetBinContent(1);
1075 fvStart = fFittingParameters->GetBinContent(2);
1076 fvMin = fFittingParameters->GetBinContent(3);
1077 fvMax = fFittingParameters->GetBinContent(4);
1078 fSigma2Start = fFittingParameters->GetBinContent(5);
1079 fSigma2Min = fFittingParameters->GetBinContent(6);
1080 fSigma2Max = fFittingParameters->GetBinContent(7);
1081 fPlotResults = (Bool_t) fFittingParameters->GetBinContent(8);
1083 } // end of void AliFlowAnalysisWithFittingQDistribution::AccessFittingParameters()