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 * estimating reference flow by *
18 * fitting q-distribution *
20 * author: Ante Bilandzic *
21 * (abilandzic@gmail.com) *
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"
37 #include "TParticle.h"
39 #include "AliFlowEventSimple.h"
40 #include "AliFlowTrackSimple.h"
41 #include "AliFlowAnalysisWithFittingQDistribution.h"
55 //================================================================================================================
57 ClassImp(AliFlowAnalysisWithFittingQDistribution)
59 AliFlowAnalysisWithFittingQDistribution::AliFlowAnalysisWithFittingQDistribution():
62 fCommonHistsResults(NULL),
78 fUsePhiWeights(kFALSE),
79 fUsePtWeights(kFALSE),
80 fUseEtaWeights(kFALSE),
81 fUseParticleWeights(NULL),
85 fSumOfParticleWeights(NULL),
90 fFittingParameters(NULL),
98 fFinalResultIsFromSigma2Fitted(kTRUE),
99 fPrintOnTheScreen(kTRUE)
103 // base list to hold all output objects:
104 fHistList = new TList();
105 fHistList->SetName("cobjFQD");
106 fHistList->SetOwner(kTRUE);
109 fAnalysisLabel = new TString();
111 // list to hold histograms with phi, pt and eta weights:
112 fWeightsList = new TList();
114 // initialize all arrays:
115 this->InitializeArrays();
117 } // end of constructor
119 //================================================================================================================
121 AliFlowAnalysisWithFittingQDistribution::~AliFlowAnalysisWithFittingQDistribution()
127 } // end of destructor
129 //================================================================================================================
132 void AliFlowAnalysisWithFittingQDistribution::Init()
134 // Access constants and book everything.
136 //save old value and prevent histograms from being added to directory
137 //to avoid name clashes in case multiple analaysis objects are used
139 Bool_t oldHistAddStatus = TH1::AddDirectoryStatus();
140 TH1::AddDirectory(kFALSE);
143 this->AccessConstants();
146 this->BookCommonHistograms();
147 this->BookAndFillWeightsHistograms();
148 this->BookEverythingForDistributions();
150 // store fitting parameters:
151 this->StoreFittingParameters();
154 fWeightsList->SetName("Weights");
155 fWeightsList->SetOwner(kTRUE);
156 fHistList->Add(fWeightsList);
158 // set harmonic in common control histograms (to be improved (should I do this somewhere else?)):
159 (fCommonHists->GetHarmonic())->Fill(0.5,fHarmonic);
162 TH1::AddDirectory(oldHistAddStatus);
163 } // end of void AliFlowAnalysisWithFittingQDistribution::Init()
165 //================================================================================================================
167 void AliFlowAnalysisWithFittingQDistribution::Make(AliFlowEventSimple* anEvent)
169 // Loop over data only in this method.
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.
176 // a) Check all pointers used in this method:
177 this->CheckPointersUsedInMake();
179 // b) fill the common control histograms:
180 fCommonHists->FillControlHistograms(anEvent);
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++)
201 aftsTrack=anEvent->GetTrack(i);
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:
210 wPhi = fPhiWeights->GetBinContent(1+(Int_t)(TMath::Floor(dPhi*fnBinsPhi/TMath::TwoPi())));
212 if(fUsePtWeights && fPtWeights && fPtBinWidth) // determine pt weight for this particle:
214 wPt = fPtWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-fPtMin)/fPtBinWidth)));
216 if(fUseEtaWeights && fEtaWeights && fEtaBinWidth) // determine eta weight for this particle:
218 wEta = fEtaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-fEtaMin)/fEtaBinWidth)));
220 // Calculate real and imaginary part of Q-vector and sum of particle weights for this event:
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++)
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)
233 q = pow(dReQ*dReQ+dImQ*dImQ,0.5)/pow(dSumOfParticleWeights,0.5);
234 fqDistribution->Fill(q,1.);
235 fSumOfParticleWeights->Fill(dSumOfParticleWeights,1.);
239 cout<<" WARNING (FQD::Make()): dSumOfParticleWeights == 0. !!!!"<<endl;
245 //================================================================================================================
247 void AliFlowAnalysisWithFittingQDistribution::Finish(Bool_t doFit)
249 // Calculate the final results.
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.
258 // a) Check all pointers used in this method:
259 this->CheckPointersUsedInFinish();
261 // b) Access common constants:
262 this->AccessConstants();
264 // c) Access fitting paremeters:
265 this->AccessFittingParameters();
267 // d) Do the final fit of q-distribution:
270 this->DoFit(kFALSE); // sigma^2 not fitted (fixed to 0.5)
271 this->DoFit(kTRUE); // sigma^2 fitted
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);
278 // f) Print on the screen the final results:
279 if(fPrintOnTheScreen) this->PrintOnTheScreen();
281 } // end of void AliFlowAnalysisWithFittingQDistribution::Finish(Bool_t doFit)
283 //================================================================================================================
285 void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInMake()
287 // Check all pointers used in method Make().
292 cout<<" WARNING (FQD::Make()): fCommonHists is NULL !!!!"<<endl;
299 cout<<" WARNING (FQD::Make()): fqDistribution is NULL !!!!"<<endl;
303 if(!fSumOfParticleWeights)
306 cout<<" WARNING (FQD::Make()): fSumOfParticleWeights is NULL !!!!"<<endl;
310 if(fUsePhiWeights && !fPhiWeights)
313 cout<<" WARNING (FQD::Make()): fPhiWeights is NULL !!!!"<<endl;
317 if(fUsePtWeights && !fPtWeights)
320 cout<<" WARNING (FQD::Make()): fPtWeights is NULL !!!!"<<endl;
324 if(fUseEtaWeights && !fEtaWeights)
327 cout<<" WARNING (FQD::Make()): fEtaWeights is NULL !!!!"<<endl;
332 } // end of void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInMake()
334 //================================================================================================================
336 void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInFinish()
338 // Check all pointers used in method Finish().
340 if(!fFittingParameters)
343 cout<<" WARNING (FQD::Finish()): fFittingParameters is NULL !!!!"<<endl;
350 cout<<" WARNING (FQD::Finish()): fqDistribution is NULL !!!!"<<endl;
354 if(!fSumOfParticleWeights)
357 cout<<" WARNING (FQD::Finish()): fSumOfParticleWeights is NULL !!!!"<<endl;
361 for(Int_t s2F=0;s2F<2;s2F++)
366 cout<<" WARNING (FQD::Finish()): "<<Form("fIntFlow[%d] is NULL !!!!",s2F)<<endl;
373 cout<<" WARNING (FQD::Finish()): "<<Form("fSigma2[%d] is NULL !!!!",s2F)<<endl;
380 cout<<" WARNING (FQD::Finish()): "<<Form("fChi2[%d] is NULL !!!!",s2F)<<endl;
384 } // end of for(Int_t s2F=0;s2F<2;s2F++)
385 if(!fCommonHistsResults)
388 cout<<"WARNING (FQD::Finish()): fCommonHistsResults is NULL !!!!"<<endl;
395 cout<<"WARNING (FQD::Finish()): fCommonHists is NULL !!!!"<<endl;
400 } // end of void AliFlowAnalysisWithFittingQDistribution::CheckPointersUsedInFinish()
402 //================================================================================================================
404 void AliFlowAnalysisWithFittingQDistribution::GetOutputHistograms(TList *outputListHistos)
406 // Get pointers to all output histograms (called before Finish()).
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);
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);
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)
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);
442 // 3.) distributions and 4.) final results of fitting:
443 TString sigmaFlag[2] = {"#sigma^{2} not fitted","#sigma^{2} fitted"};
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();
454 TString sigma2Name = "fSigma2";
455 sigma2Name += fAnalysisLabel->Data();
457 TString chi2Name = "fChi2";
458 chi2Name += fAnalysisLabel->Data();
460 TString fittingFunctionName = "fFittingFunction";
461 fittingFunctionName += fAnalysisLabel->Data();
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};
471 qDistribution = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s",qDistributionName.Data())));
474 this->SetqDistribution(qDistribution);
477 cout<<"WARNING: qDistribution is NULL in AFAWFQD::GOH() !!!!"<<endl;
479 // sum of particle weights:
480 sumOfParticleWeights = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s",sumOfParticleWeightsName.Data())));
481 if(sumOfParticleWeights)
483 this->SetSumOfParticleWeights(sumOfParticleWeights);
486 cout<<"WARNING: sumOfParticleWeights is NULL in AFAWFQD::GOH() !!!!"<<endl;
489 for(Int_t f=0;f<2;f++)
491 // final results for reference flow:
492 intFlow[f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",intFlowName.Data(),sigmaFlag[f].Data())));
495 this->SetIntFlow(intFlow[f],f);
498 cout<<"WARNING: intFlow[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
499 cout<<"f = "<<f<<endl;
502 sigma2[f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",sigma2Name.Data(),sigmaFlag[f].Data())));
505 this->SetSigma2(sigma2[f],f);
508 cout<<"WARNING: sigma2[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
509 cout<<"f = "<<f<<endl;
512 chi2[f] = dynamic_cast<TH1D*>(outputListHistos->FindObject(Form("%s, %s",chi2Name.Data(),sigmaFlag[f].Data())));
515 this->SetChi2(chi2[f],f);
518 cout<<"WARNING: chi2[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
519 cout<<"f = "<<f<<endl;
521 // fitting functions:
522 fittingFunction[f] = dynamic_cast<TF1*>(outputListHistos->FindObject(Form("%s, %s",fittingFunctionName.Data(),sigmaFlag[f].Data())));
523 if(fittingFunction[f])
525 this->SetFittingFunction(fittingFunction[f],f);
528 cout<<"WARNING: fittingFunction[f] is NULL in AFAWFQD::GOH() !!!!"<<endl;
529 cout<<"f = "<<f<<endl;
531 } // end of for(Int_t f=0;f<2;f++)
533 // 5.) fitting parameters:
535 TString fittingParametersName = "fFittingParameters";
536 fittingParametersName += fAnalysisLabel->Data();
537 TProfile *fittingParameters = NULL;
538 fittingParameters = dynamic_cast<TProfile*>(outputListHistos->FindObject(fittingParametersName.Data()));
539 if(fittingParameters)
541 this->SetFittingParameters(fittingParameters);
544 cout<<"WARNING:fittingParameters is NULL in AFAWFQD::GOH() !!!!"<<endl;
547 } else // to if(outputListHistos)
549 cout<<"WARNING: outputListHistos is NULL in AFAWFQD::GOH() !!!!"<<endl;
553 } // end of void AliFlowAnalysisWithFittingQDistribution::GetOutputHistograms(TList *outputListHistos)
555 //================================================================================================================
557 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TString* outputFileName)
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);
568 //================================================================================================================
570 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TString outputFileName)
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);
581 //================================================================================================================
583 void AliFlowAnalysisWithFittingQDistribution::WriteHistograms(TDirectoryFile *outputFileName)
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);
592 //================================================================================================================
594 void AliFlowAnalysisWithFittingQDistribution::InitializeArrays()
596 // Initialize all arrays.
598 for(Int_t s2F=0;s2F<2;s2F++) // sigma^2 not fitted (0) or fitted (1)
600 fIntFlow[s2F] = NULL;
603 fFittingFunction[s2F] = NULL;
606 } // end of void AliFlowAnalysisWithFittingQDistribution::InitializeArrays()
608 //================================================================================================================
610 void AliFlowAnalysisWithFittingQDistribution::BookCommonHistograms()
612 // Book common histograms.
614 // common control histogram:
615 TString commonHistName = "AliFlowCommonHistFQD";
616 commonHistName += fAnalysisLabel->Data();
617 fCommonHists = new AliFlowCommonHist(commonHistName.Data());
618 fHistList->Add(fCommonHists);
620 // common histograms for final results:
621 TString commonHistResName = "AliFlowCommonHistResultsFQD";
622 commonHistResName += fAnalysisLabel->Data();
623 fCommonHistsResults = new AliFlowCommonHistResults(commonHistResName.Data());
624 fHistList->Add(fCommonHistsResults);
626 } // end of void AliFlowAnalysisWithFittingQDistribution::BookCommonHistograms()
628 //================================================================================================================
630 void AliFlowAnalysisWithFittingQDistribution::BookAndFillWeightsHistograms()
632 // Book and fill histograms which hold phi, pt and eta weights.
636 cout<<"WARNING: fWeightsList is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
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);
654 if(fWeightsList->FindObject("phi_weights"))
656 fPhiWeights = dynamic_cast<TH1F*>(fWeightsList->FindObject("phi_weights"));
657 if(TMath::Abs(fPhiWeights->GetBinWidth(1)-fPhiBinWidth)>pow(10.,-6.))
660 cout<<"WARNING (FQD): Inconsistent binning in histograms for phi-weights throughout the code."<<endl;
666 cout<<"WARNING: fWeightsList->FindObject(\"phi_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
669 } // end of if(fUsePhiWeights)
673 if(fWeightsList->FindObject("pt_weights"))
675 fPtWeights = dynamic_cast<TH1D*>(fWeightsList->FindObject("pt_weights"));
676 if(TMath::Abs(fPtWeights->GetBinWidth(1)-fPtBinWidth)>pow(10.,-6.))
679 cout<<"WARNING (FQD): Inconsistent binning in histograms for pt-weights throughout the code."<<endl;
685 cout<<"WARNING: fWeightsList->FindObject(\"pt_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
688 } // end of if(fUsePtWeights)
692 if(fWeightsList->FindObject("eta_weights"))
694 fEtaWeights = dynamic_cast<TH1D*>(fWeightsList->FindObject("eta_weights"));
695 if(TMath::Abs(fEtaWeights->GetBinWidth(1)-fEtaBinWidth)>pow(10.,-6.))
698 cout<<"WARNING (FQD): Inconsistent binning in histograms for eta-weights throughout the code."<<endl;
704 cout<<"WARNING: fUseEtaWeights && fWeightsList->FindObject(\"eta_weights\") is NULL in AFAWFQD::BAFWH() !!!!"<<endl;
707 } // end of if(fUseEtaWeights)
709 } // end of AliFlowAnalysisWithFittingQDistribution::BookAndFillWeightsHistograms()
711 //================================================================================================================================
713 void AliFlowAnalysisWithFittingQDistribution::AccessConstants()
715 // access needed common constants from AliFlowCommonConstants
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;
730 } // end of void AliFlowAnalysisWithFittingQDistribution::AccessConstants()
732 //================================================================================================================================
734 void AliFlowAnalysisWithFittingQDistribution::BookEverythingForDistributions()
736 // Book all objects relevant for fitting of q-distributions.
739 TString sigmaFlag[2] = {"#sigma^{2} not fitted","#sigma^{2} fitted"};
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();
759 TString fSigma2Name = "fSigma2";
760 fSigma2Name += fAnalysisLabel->Data();
762 TString fChi2Name = "fChi2";
763 fChi2Name += fAnalysisLabel->Data();
765 TString fittingFunctionName = "fFittingFunction";
766 fittingFunctionName += fAnalysisLabel->Data();
768 for(Int_t f=0;f<2;f++) // sigma^2 not fitted (0) or fitted (1)
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]);
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]);
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);
806 } // end of void AliFlowAnalysisWithFittingQDistribution::BookEverythingForDistributions()
808 //================================================================================================================================
810 void AliFlowAnalysisWithFittingQDistribution::DoFit(Bool_t sigma2Fitted)
812 // Do the final fit of q-distribution.
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:
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)
826 cout<<"WARNING (FQD): binWidth == 0 in AFAWFQD::DoFit()"<<endl;
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++)
835 ent += fqDistribution->GetBinContent(b);
837 Double_t norm = binWidth*ent; // norm (assuming that all bins have the same width)
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));
845 fFittingFunction[s2F]->FixParameter(1,0.5);
848 fFittingFunction[s2F]->SetParLimits(1,fSigma2Min,fSigma2Max);
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)
855 fqDistribution->Fit(fFittingFunction[s2F]->GetName(),"NQ","",qmin,qmax);
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
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"
873 cout<<"WARNING (FQD): AvM == 0 in AFAWFQD::DoFit()"<<endl;
877 if(s2F == 0) // sigma^2 not fitted, but fixed to 0.5
880 fSigma2[0]->SetBinContent(1,sigma2);
881 fSigma2[0]->SetBinError(1,0.);
882 } else // sigma^2 fitted
884 sigma2 = fFittingFunction[s2F]->GetParameter(1);
885 sigma2Error = fFittingFunction[s2F]->GetParError(1);
886 fSigma2[1]->SetBinContent(1,sigma2);
887 fSigma2[1]->SetBinError(1,sigma2Error);
890 chi2 = fFittingFunction[s2F]->GetChisquare();
891 fChi2[s2F]->SetBinContent(1,chi2);
893 } // end of void AliFlowAnalysisWithFittingQDistribution::DoFit()
895 //================================================================================================================================
897 void AliFlowAnalysisWithFittingQDistribution::FillCommonHistResults(Bool_t sigma2Fitted)
899 // Fill common result histogram for reference flow and resolution.
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).
904 Int_t s2F = (Int_t)sigma2Fitted; // shortcut
907 Double_t v = fIntFlow[s2F]->GetBinContent(1);
908 Double_t vError = fIntFlow[s2F]->GetBinError(1);
909 fCommonHistsResults->FillIntegratedFlow(v,vError);
911 Double_t AvM = fSumOfParticleWeights->GetMean(1);
912 Double_t chi2 = AvM*pow(v,2.); // chi^2
915 fCommonHistsResults->FillChi(pow(chi2,0.5));
918 } // end of void AliFlowAnalysisWithFittingQDistribution::FillCommonHistResultsIntFlow(Bool_t useParticleWeights, Bool_t sigma2NotFixed)
920 //================================================================================================================================
922 void AliFlowAnalysisWithFittingQDistribution::PrintOnTheScreen()
924 // Print the final results on the screen.
926 // shortcut for the harmonic:
928 if(fCommonHists->GetHarmonic())
930 n = (Int_t)(fCommonHists->GetHarmonic())->GetBinContent(1);
935 cout<<"***************************************"<<endl;
936 cout<<"***************************************"<<endl;
937 cout<<" reference flow by fitting "<<endl;
938 cout<<" q-distribution: "<<endl;
939 if(fUsePhiWeights||fUsePtWeights||fUseEtaWeights)
941 cout<<" (with weights) "<<endl;
944 cout<<" (without weights) "<<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;
952 if(TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMin)<1.e-10 ||
953 TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMax)<1.e-10)
955 cout<<" WARNING: value of v_"<<n<<"{FQD}"<<" is on the boundary"<<endl;
956 cout<<" of fitting interval. Redo the fit."<< endl;
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;
964 if(TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMin)<1.e-10 ||
965 TMath::Abs(fIntFlow[0]->GetBinContent(1)-fvMax)<1.e-10)
967 cout<<" WARNING: value of v_"<<n<<"{FQD}"<<" is on the boundary"<<endl;
968 cout<<" of fitting interval. Redo the fit."<< endl;
971 if(TMath::Abs(fSigma2[1]->GetBinContent(1)-fSigma2Min)<1.e-10 ||
972 TMath::Abs(fSigma2[1]->GetBinContent(1)-fSigma2Max)<1.e-10)
974 cout<<" WARNING: value of sigma^2 is on the boundary"<<endl;
975 cout<<" of fitting interval. Redo the fit."<< endl;
978 cout<<" nEvts = "<<fSumOfParticleWeights->GetEntries()<<", AvM = "<<fSumOfParticleWeights->GetMean()<<endl;
980 cout<<"***************************************"<<endl;
981 cout<<"***************************************"<<endl;
984 } // end of void AliFlowAnalysisWithFittingQDistribution::PrintOnTheScreen()
986 //================================================================================================================================
988 void AliFlowAnalysisWithFittingQDistribution::StoreFittingParameters()
990 // Store fitting parameters for the fit of q-distribution in profile fFittingParameters.
992 if(!fFittingParameters)
995 cout<<"WARNING (FQD): fFittingParameters is NULL in AFAWFQD::SFP() !!!!"<<endl;
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);
1010 } // end of void AliFlowAnalysisWithFittingQDistribution::StoreFittingParameters()
1012 //================================================================================================================================
1014 void AliFlowAnalysisWithFittingQDistribution::AccessFittingParameters()
1016 // Access fitting parameters for the fit of q-distribution.
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);
1028 } // end of void AliFlowAnalysisWithFittingQDistribution::AccessFittingParameters()